summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/CMakeLists.txt59
-rw-r--r--indra/newview/VIEWER_VERSION.txt2
-rw-r--r--indra/newview/app_settings/high_graphics.xml41
-rw-r--r--indra/newview/app_settings/keywords.ini1
-rw-r--r--indra/newview/app_settings/keywords_lsl_default.xml9
-rw-r--r--indra/newview/app_settings/low_graphics.xml41
-rw-r--r--indra/newview/app_settings/mid_graphics.xml41
-rw-r--r--indra/newview/app_settings/settings.xml881
-rw-r--r--indra/newview/app_settings/settings_per_account.xml11
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl22
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl112
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl53
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/cofF.glsl20
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl511
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl26
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl)50
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl106
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl141
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl)14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/indirect.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl45
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialF.glsl423
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/materialV.glsl55
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/moonV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl145
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl284
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaBlendF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl)47
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl (renamed from indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl)28
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl)68
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl (renamed from indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl159
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl)62
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl153
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl139
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl132
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl158
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl)18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl99
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl (renamed from indra/newview/app_settings/shaders/class1/transform/binormalV.glsl)25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl15
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyF.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/skyV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl170
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl45
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl279
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/starsV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl31
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl122
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl13
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl82
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl184
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterV.glsl99
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowF.glsl30
-rw-r--r--indra/newview/app_settings/shaders/class1/effects/glowV.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/srgbF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainF.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainV.glsl88
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl84
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterF.glsl146
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/environment/waterV.glsl28
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/clipV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/copyF.glsl (renamed from indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl)23
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/copyV.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl)15
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/debugF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/debugV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl65
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl69
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl59
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl)43
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl16
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl17
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl7
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/highlightV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl2
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl167
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl (renamed from indra/newview/app_settings/shaders/class1/transform/normalV.glsl)18
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl (renamed from indra/newview/app_settings/shaders/class1/objects/shinyF.glsl)13
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl41
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/uiF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/interface/uiV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl21
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl55
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl53
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl54
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/bumpV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl53
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/impostorF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/impostorV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewF.glsl12
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl8
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl6
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/previewV.glsl34
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyV.glsl78
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl33
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl77
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/simpleV.glsl87
-rw-r--r--indra/newview/app_settings/shaders/class1/objects/treeV.glsl59
-rw-r--r--indra/newview/app_settings/shaders/class1/transform/positionV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl36
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl96
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl29
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl39
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl72
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl127
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl27
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonF.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/moonV.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class1/windlight/transportF.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl)113
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/indirect.glsl32
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl299
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl312
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl80
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl158
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl293
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl19
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl214
-rw-r--r--indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl)33
-rw-r--r--indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl60
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl56
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl48
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl84
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl81
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl131
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl193
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl58
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyF.glsl55
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/skyV.glsl149
-rw-r--r--indra/newview/app_settings/shaders/class2/windlight/transportF.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl134
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl49
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl52
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl68
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl119
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl63
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl166
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl79
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl202
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl93
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl70
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl40
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl111
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/indirect.glsl44
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/materialF.glsl425
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl181
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl)20
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl291
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl149
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl)12
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl853
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl93
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostV.glsl (renamed from indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl)31
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl394
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl66
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl74
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl50
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl157
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl62
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyF.glsl126
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/skyV.glsl37
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl334
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl38
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl352
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl57
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl61
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl115
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterF.glsl174
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/waterV.glsl95
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl (renamed from indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl)44
-rw-r--r--indra/newview/app_settings/shaders/class3/environment/waterF.glsl291
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/lightV.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl67
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl73
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl43
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl46
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl51
-rw-r--r--indra/newview/app_settings/shaders/class3/windlight/transportF.glsl68
-rw-r--r--indra/newview/app_settings/shaders/errorF.glsl (renamed from indra/newview/app_settings/shaders/class1/transform/colorV.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/errorV.glsl (renamed from indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl)16
-rw-r--r--indra/newview/app_settings/shaders/shader_hierarchy.txt177
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml42
-rw-r--r--indra/newview/featuretable.txt149
-rw-r--r--indra/newview/featuretable_linux.txt1
-rw-r--r--indra/newview/featuretable_mac.txt131
-rw-r--r--indra/newview/installers/windows/installer_template.nsi1
-rw-r--r--indra/newview/licenses-mac.txt52
-rw-r--r--indra/newview/licenses-win32.txt49
-rw-r--r--indra/newview/llagent.cpp14
-rw-r--r--indra/newview/llagentcamera.cpp13
-rw-r--r--indra/newview/llaisapi.cpp27
-rw-r--r--indra/newview/llaisapi.h7
-rw-r--r--indra/newview/llappviewer.cpp214
-rw-r--r--indra/newview/llappviewer.h7
-rw-r--r--indra/newview/llappviewerwin32.cpp6
-rw-r--r--indra/newview/llcompilequeue.cpp2
-rw-r--r--indra/newview/llcontrolavatar.cpp11
-rw-r--r--indra/newview/llcontrolavatar.h1
-rw-r--r--indra/newview/lldrawable.cpp54
-rw-r--r--indra/newview/lldrawable.h9
-rw-r--r--indra/newview/lldrawpool.cpp437
-rw-r--r--indra/newview/lldrawpool.h228
-rw-r--r--indra/newview/lldrawpoolalpha.cpp707
-rw-r--r--indra/newview/lldrawpoolalpha.h30
-rw-r--r--indra/newview/lldrawpoolavatar.cpp116
-rw-r--r--indra/newview/lldrawpoolavatar.h6
-rw-r--r--indra/newview/lldrawpoolbump.cpp357
-rw-r--r--indra/newview/lldrawpoolbump.h34
-rw-r--r--indra/newview/lldrawpoolground.cpp76
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp247
-rw-r--r--indra/newview/lldrawpoolmaterials.h5
-rw-r--r--indra/newview/lldrawpoolpbropaque.cpp87
-rw-r--r--indra/newview/lldrawpoolpbropaque.h (renamed from indra/newview/lldrawpoolground.h)32
-rw-r--r--indra/newview/lldrawpoolsimple.cpp370
-rw-r--r--indra/newview/lldrawpoolsimple.h81
-rw-r--r--indra/newview/lldrawpoolsky.cpp80
-rw-r--r--indra/newview/lldrawpoolterrain.cpp105
-rw-r--r--indra/newview/lldrawpoolterrain.h19
-rw-r--r--indra/newview/lldrawpooltree.cpp135
-rw-r--r--indra/newview/lldrawpooltree.h6
-rw-r--r--indra/newview/lldrawpoolwater.cpp501
-rw-r--r--indra/newview/lldrawpoolwater.h26
-rw-r--r--indra/newview/lldrawpoolwlsky.cpp226
-rw-r--r--indra/newview/lldrawpoolwlsky.h10
-rw-r--r--indra/newview/lldynamictexture.cpp35
-rw-r--r--indra/newview/llenvironment.cpp106
-rw-r--r--indra/newview/llenvironment.h3
-rw-r--r--indra/newview/llface.cpp788
-rw-r--r--indra/newview/llface.h27
-rw-r--r--indra/newview/llfasttimerview.cpp2
-rw-r--r--indra/newview/llfeaturemanager.cpp72
-rw-r--r--indra/newview/llfetchedgltfmaterial.cpp254
-rw-r--r--indra/newview/llfetchedgltfmaterial.h77
-rw-r--r--indra/newview/llfilepicker.cpp51
-rw-r--r--indra/newview/llfilepicker.h6
-rw-r--r--indra/newview/llflexibleobject.cpp9
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp4
-rw-r--r--indra/newview/llfloaterbulkpermission.cpp6
-rw-r--r--indra/newview/llfloaterbulkpermission.h2
-rw-r--r--indra/newview/llfloaterbvhpreview.cpp13
-rw-r--r--indra/newview/llfloaterbvhpreview.h1
-rw-r--r--indra/newview/llfloaterchangeitemthumbnail.cpp3
-rw-r--r--indra/newview/llfloatereditenvironmentbase.cpp4
-rw-r--r--indra/newview/llfloatereditextdaycycle.cpp26
-rw-r--r--indra/newview/llfloatereditextdaycycle.h2
-rw-r--r--indra/newview/llfloaterenvironmentadjust.cpp39
-rw-r--r--indra/newview/llfloaterenvironmentadjust.h2
-rw-r--r--indra/newview/llfloaterfixedenvironment.cpp12
-rw-r--r--indra/newview/llfloaterimagepreview.cpp9
-rw-r--r--indra/newview/llfloaterimcontainer.cpp3
-rw-r--r--indra/newview/llfloaterimsessiontab.cpp2
-rw-r--r--indra/newview/llfloaterlagmeter.cpp2
-rw-r--r--indra/newview/llfloaterland.cpp1
-rw-r--r--indra/newview/llfloatermodelpreview.cpp6
-rw-r--r--indra/newview/llfloaternewfeaturenotification.cpp7
-rw-r--r--indra/newview/llfloaterperformance.cpp259
-rw-r--r--indra/newview/llfloaterperformance.h4
-rw-r--r--indra/newview/llfloaterperms.cpp3
-rw-r--r--indra/newview/llfloaterperms.h1
-rw-r--r--indra/newview/llfloaterpreference.cpp39
-rw-r--r--indra/newview/llfloaterpreference.h5
-rw-r--r--indra/newview/llfloaterpreferencesgraphicsadvanced.cpp35
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp2
-rw-r--r--indra/newview/llfloatertexturefetchdebugger.cpp480
-rw-r--r--indra/newview/llfloatertexturefetchdebugger.h77
-rw-r--r--indra/newview/llfloatertools.cpp3
-rw-r--r--indra/newview/llfloateruipreview.cpp4
-rw-r--r--indra/newview/llglsandbox.cpp137
-rw-r--r--indra/newview/llgltfmateriallist.cpp870
-rw-r--r--indra/newview/llgltfmateriallist.h161
-rw-r--r--indra/newview/llhudeffectlookat.cpp2
-rw-r--r--indra/newview/llhudeffectpointat.cpp2
-rw-r--r--indra/newview/llhudicon.cpp54
-rw-r--r--indra/newview/llhudicon.h5
-rw-r--r--indra/newview/llhudnametag.cpp3
-rw-r--r--indra/newview/llhudobject.cpp8
-rw-r--r--indra/newview/llhudtext.cpp10
-rw-r--r--indra/newview/llinspectobject.cpp14
-rw-r--r--indra/newview/llinventorybridge.cpp98
-rw-r--r--indra/newview/llinventorybridge.h11
-rw-r--r--indra/newview/llinventoryfilter.cpp12
-rw-r--r--indra/newview/llinventorygallery.cpp39
-rw-r--r--indra/newview/llinventorygallery.h4
-rw-r--r--indra/newview/llinventoryicon.cpp5
-rw-r--r--indra/newview/llinventorymodel.cpp32
-rw-r--r--indra/newview/llinventorymodel.h2
-rw-r--r--indra/newview/llinventorypanel.cpp68
-rw-r--r--indra/newview/llinventorypanel.h7
-rw-r--r--indra/newview/lllocalbitmaps.cpp225
-rw-r--r--indra/newview/lllocalbitmaps.h42
-rw-r--r--indra/newview/lllocalgltfmaterials.cpp497
-rw-r--r--indra/newview/lllocalgltfmaterials.h119
-rw-r--r--indra/newview/lllogchat.cpp2
-rw-r--r--indra/newview/llmanip.cpp4
-rw-r--r--indra/newview/llmaniprotate.cpp10
-rw-r--r--indra/newview/llmanipscale.cpp7
-rw-r--r--indra/newview/llmaniptranslate.cpp29
-rw-r--r--indra/newview/llmaterialeditor.cpp3708
-rw-r--r--indra/newview/llmaterialeditor.h323
-rw-r--r--indra/newview/llmaterialmgr.cpp7
-rw-r--r--indra/newview/llmaterialmgr.h1
-rw-r--r--indra/newview/llmediadataclient.cpp2
-rw-r--r--indra/newview/llmeshrepository.cpp231
-rw-r--r--indra/newview/llmeshrepository.h77
-rw-r--r--indra/newview/llmodelpreview.cpp214
-rw-r--r--indra/newview/llpaneleditsky.cpp40
-rw-r--r--indra/newview/llpaneleditsky.h2
-rw-r--r--indra/newview/llpaneleditwearable.cpp1
-rw-r--r--indra/newview/llpanelface.cpp1259
-rw-r--r--indra/newview/llpanelface.h86
-rw-r--r--indra/newview/llpanelgroupnotices.cpp1
-rw-r--r--indra/newview/llpanellandmedia.cpp1
-rw-r--r--indra/newview/llpanelmaininventory.cpp18
-rw-r--r--indra/newview/llpanelmaininventory.h1
-rw-r--r--indra/newview/llpanelobject.cpp2
-rw-r--r--indra/newview/llpanelobjectinventory.cpp59
-rw-r--r--indra/newview/llpanelprofile.cpp6
-rw-r--r--indra/newview/llpanelvolume.cpp217
-rw-r--r--indra/newview/llpanelvolume.h10
-rw-r--r--indra/newview/llperfstats.cpp68
-rw-r--r--indra/newview/llperfstats.h169
-rw-r--r--indra/newview/llplacesinventorypanel.h2
-rw-r--r--indra/newview/llpreview.cpp27
-rw-r--r--indra/newview/llpreview.h4
-rw-r--r--indra/newview/llpreviewgesture.cpp8
-rw-r--r--indra/newview/llpreviewnotecard.cpp6
-rw-r--r--indra/newview/llpreviewscript.cpp36
-rw-r--r--indra/newview/llpreviewscript.h1
-rw-r--r--indra/newview/llpreviewtexture.cpp2
-rw-r--r--indra/newview/llreflectionmap.cpp368
-rw-r--r--indra/newview/llreflectionmap.h131
-rw-r--r--indra/newview/llreflectionmapmanager.cpp1376
-rw-r--r--indra/newview/llreflectionmapmanager.h204
-rw-r--r--indra/newview/llscenemonitor.cpp14
-rw-r--r--indra/newview/llsculptidsize.cpp25
-rw-r--r--indra/newview/llselectmgr.cpp399
-rw-r--r--indra/newview/llselectmgr.h32
-rw-r--r--indra/newview/llsettingsvo.cpp145
-rw-r--r--indra/newview/llsidepaneltaskinfo.cpp7
-rw-r--r--indra/newview/llsidepaneltaskinfo.h2
-rw-r--r--indra/newview/llsky.cpp12
-rw-r--r--indra/newview/llsky.h2
-rw-r--r--indra/newview/llspatialpartition.cpp911
-rw-r--r--indra/newview/llspatialpartition.h178
-rw-r--r--indra/newview/llsprite.cpp7
-rw-r--r--indra/newview/llstartup.cpp100
-rw-r--r--indra/newview/llstartup.h3
-rw-r--r--indra/newview/llsurface.cpp7
-rw-r--r--indra/newview/lltexturecache.cpp110
-rw-r--r--indra/newview/lltexturecache.h6
-rw-r--r--indra/newview/lltexturectrl.cpp837
-rw-r--r--indra/newview/lltexturectrl.h62
-rw-r--r--indra/newview/lltexturefetch.cpp1417
-rw-r--r--indra/newview/lltexturefetch.h235
-rw-r--r--indra/newview/lltextureview.cpp56
-rw-r--r--indra/newview/llthumbnailctrl.cpp84
-rw-r--r--indra/newview/llthumbnailctrl.h9
-rw-r--r--indra/newview/lltinygltfhelper.cpp331
-rw-r--r--indra/newview/lltinygltfhelper.h66
-rw-r--r--indra/newview/lltoastalertpanel.cpp3
-rw-r--r--indra/newview/lltoolcomp.cpp3
-rw-r--r--indra/newview/lltooldraganddrop.cpp400
-rw-r--r--indra/newview/lltooldraganddrop.h29
-rw-r--r--indra/newview/lltoolpie.cpp41
-rw-r--r--indra/newview/lltoolselect.cpp11
-rw-r--r--indra/newview/lltracker.cpp2
-rw-r--r--indra/newview/llviewerassettype.cpp1
-rw-r--r--indra/newview/llviewerassetupload.cpp114
-rw-r--r--indra/newview/llviewerassetupload.h53
-rw-r--r--indra/newview/llviewercamera.cpp9
-rw-r--r--indra/newview/llviewercamera.h17
-rw-r--r--indra/newview/llviewercontrol.cpp125
-rw-r--r--indra/newview/llviewerdisplay.cpp420
-rw-r--r--indra/newview/llviewerfloaterreg.cpp9
-rw-r--r--indra/newview/llviewerfoldertype.cpp1
-rw-r--r--indra/newview/llviewergenericmessage.cpp15
-rw-r--r--indra/newview/llviewerinventory.cpp94
-rw-r--r--indra/newview/llviewerinventory.h4
-rw-r--r--indra/newview/llviewerjointmesh.cpp30
-rw-r--r--indra/newview/llviewermedia.cpp49
-rw-r--r--indra/newview/llviewermenu.cpp312
-rw-r--r--indra/newview/llviewermenu.h5
-rw-r--r--indra/newview/llviewermenufile.cpp139
-rw-r--r--indra/newview/llviewermenufile.h12
-rw-r--r--indra/newview/llviewermessage.cpp14
-rw-r--r--indra/newview/llviewerobject.cpp660
-rw-r--r--indra/newview/llviewerobject.h78
-rw-r--r--indra/newview/llviewerobjectlist.cpp239
-rw-r--r--indra/newview/llviewerobjectlist.h8
-rw-r--r--indra/newview/llvieweroctree.cpp70
-rw-r--r--indra/newview/llvieweroctree.h1
-rw-r--r--indra/newview/llviewerpartsim.cpp6
-rwxr-xr-xindra/newview/llviewerregion.cpp115
-rw-r--r--indra/newview/llviewerregion.h18
-rw-r--r--indra/newview/llviewershadermgr.cpp2801
-rw-r--r--indra/newview/llviewershadermgr.h112
-rw-r--r--indra/newview/llviewerstats.cpp161
-rw-r--r--indra/newview/llviewerstats.h8
-rw-r--r--indra/newview/llviewertexteditor.cpp26
-rw-r--r--indra/newview/llviewertexteditor.h1
-rw-r--r--indra/newview/llviewertexture.cpp825
-rw-r--r--indra/newview/llviewertexture.h77
-rw-r--r--indra/newview/llviewertexturelist.cpp650
-rw-r--r--indra/newview/llviewertexturelist.h30
-rw-r--r--indra/newview/llviewerwindow.cpp369
-rw-r--r--indra/newview/llviewerwindow.h25
-rw-r--r--indra/newview/llvlcomposition.cpp2
-rw-r--r--indra/newview/llvoavatar.cpp615
-rw-r--r--indra/newview/llvoavatar.h56
-rw-r--r--indra/newview/llvoavatarself.cpp12
-rw-r--r--indra/newview/llvocache.cpp256
-rw-r--r--indra/newview/llvocache.h31
-rw-r--r--indra/newview/llvograss.cpp37
-rw-r--r--indra/newview/llvograss.h1
-rw-r--r--indra/newview/llvoground.cpp166
-rw-r--r--indra/newview/llvoground.h54
-rw-r--r--indra/newview/llvoicevisualizer.cpp2
-rw-r--r--indra/newview/llvopartgroup.cpp207
-rw-r--r--indra/newview/llvopartgroup.h10
-rw-r--r--indra/newview/llvosky.cpp33
-rw-r--r--indra/newview/llvosurfacepatch.cpp35
-rw-r--r--indra/newview/llvosurfacepatch.h1
-rw-r--r--indra/newview/llvotree.cpp28
-rw-r--r--indra/newview/llvotree.h1
-rw-r--r--indra/newview/llvovolume.cpp1727
-rw-r--r--indra/newview/llvovolume.h225
-rw-r--r--indra/newview/llvowater.cpp63
-rw-r--r--indra/newview/llvowlsky.cpp36
-rw-r--r--indra/newview/llworld.cpp20
-rw-r--r--indra/newview/llworld.h4
-rwxr-xr-xindra/newview/llworldmapview.cpp64
-rw-r--r--indra/newview/llxmlrpctransaction.cpp8
-rw-r--r--indra/newview/pipeline.cpp5983
-rw-r--r--indra/newview/pipeline.h282
-rw-r--r--indra/newview/skins/default/textures/default_irradiance.pngbin0 -> 48853 bytes
-rw-r--r--indra/newview/skins/default/textures/icons/Inv_Material.pngbin0 -> 684 bytes
-rw-r--r--indra/newview/skins/default/textures/textures.xml1
-rw-r--r--indra/newview/skins/default/xui/en/floater_adjust_environment.xml25
-rw-r--r--indra/newview/skins/default/xui/en/floater_build_options.xml4
-rw-r--r--indra/newview/skins/default/xui/en/floater_bulk_perms.xml14
-rw-r--r--indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml48
-rw-r--r--indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml43
-rw-r--r--indra/newview/skins/default/xui/en/floater_live_material_editor.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_material_editor.xml123
-rw-r--r--indra/newview/skins/default/xui/en/floater_my_environments.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_new_feature_notification.xml11
-rw-r--r--indra/newview/skins/default/xui/en/floater_perms_default.xml68
-rw-r--r--indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml352
-rw-r--r--indra/newview/skins/default/xui/en/floater_settings_picker.xml2
-rw-r--r--indra/newview/skins/default/xui/en/floater_stats.xml6
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_ctrl.xml39
-rw-r--r--indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml440
-rw-r--r--indra/newview/skins/default/xui/en/floater_tools.xml71
-rw-r--r--indra/newview/skins/default/xui/en/menu_attachment_self.xml8
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory.xml244
-rw-r--r--indra/newview/skins/default/xui/en/menu_inventory_add.xml34
-rw-r--r--indra/newview/skins/default/xui/en/menu_object.xml31
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml238
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml176
-rw-r--r--indra/newview/skins/default/xui/en/panel_gltf_material.xml392
-rw-r--r--indra/newview/skins/default/xui/en/panel_performance_preferences.xml79
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml47
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_uploads.xml25
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml74
-rw-r--r--indra/newview/skins/default/xui/en/panel_settings_water.xml4
-rw-r--r--indra/newview/skins/default/xui/en/panel_tools_texture.xml201
-rw-r--r--indra/newview/skins/default/xui/en/strings.xml24
-rw-r--r--indra/newview/tests/lldir_stub.cpp30
-rw-r--r--indra/newview/tests/llviewercontrollistener_test.cpp173
-rw-r--r--indra/newview/tests/llvieweroctree_stub.cpp86
-rw-r--r--indra/newview/tests/llvocache_test.cpp147
626 files changed, 33951 insertions, 32444 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index fd029c9f81..7a70d0b6e6 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -43,6 +43,7 @@ include(UI)
include(ViewerMiscLibs)
include(ViewerManager)
include(VisualLeakDetector)
+include(VulkanGltf)
include(ZLIBNG)
include(URIPARSER)
include(LLPrimitive)
@@ -145,8 +146,8 @@ set(viewer_SOURCE_FILES
lldrawpoolalpha.cpp
lldrawpoolavatar.cpp
lldrawpoolbump.cpp
- lldrawpoolground.cpp
lldrawpoolmaterials.cpp
+ lldrawpoolpbropaque.cpp
lldrawpoolsimple.cpp
lldrawpoolsky.cpp
lldrawpoolterrain.cpp
@@ -166,6 +167,7 @@ set(viewer_SOURCE_FILES
llfasttimerview.cpp
llfavoritesbar.cpp
llfeaturemanager.cpp
+ llfetchedgltfmaterial.cpp
llfilepicker.cpp
llfilteredwearablelist.cpp
llfirstuse.cpp
@@ -286,7 +288,6 @@ set(viewer_SOURCE_FILES
llfloatertelehub.cpp
llfloatertestinspectors.cpp
llfloatertestlistview.cpp
- llfloatertexturefetchdebugger.cpp
llfloatertools.cpp
llfloatertopobjects.cpp
llfloatertos.cpp
@@ -308,6 +309,7 @@ set(viewer_SOURCE_FILES
llgesturemgr.cpp
llgiveinventory.cpp
llglsandbox.cpp
+ llgltfmateriallist.cpp
llgroupactions.cpp
llgroupiconctrl.cpp
llgrouplist.cpp
@@ -360,6 +362,7 @@ set(viewer_SOURCE_FILES
lllistcontextmenu.cpp
lllistview.cpp
lllocalbitmaps.cpp
+ lllocalgltfmaterials.cpp
lllocationhistory.cpp
lllocationinputctrl.cpp
lllogchat.cpp
@@ -372,6 +375,7 @@ set(viewer_SOURCE_FILES
llmaniptranslate.cpp
llmarketplacefunctions.cpp
llmarketplacenotifications.cpp
+ llmaterialeditor.cpp
llmaterialmgr.cpp
llmediactrl.cpp
llmediadataclient.cpp
@@ -513,6 +517,8 @@ set(viewer_SOURCE_FILES
llproductinforequest.cpp
llprogressview.cpp
llrecentpeople.cpp
+ llreflectionmap.cpp
+ llreflectionmapmanager.cpp
llregioninfomodel.cpp
llregionposition.cpp
llremoteparcelrequest.cpp
@@ -570,6 +576,7 @@ set(viewer_SOURCE_FILES
lltexturestats.cpp
lltextureview.cpp
llthumbnailctrl.cpp
+ lltinygltfhelper.cpp
lltoast.cpp
lltoastalertpanel.cpp
lltoastgroupnotifypanel.cpp
@@ -677,7 +684,6 @@ set(viewer_SOURCE_FILES
llvoavatarself.cpp
llvocache.cpp
llvograss.cpp
- llvoground.cpp
llvoicecallhandler.cpp
llvoicechannel.cpp
llvoiceclient.cpp
@@ -792,7 +798,7 @@ set(viewer_HEADER_FILES
lldrawpoolavatar.h
lldrawpoolbump.h
lldrawpoolmaterials.h
- lldrawpoolground.h
+ lldrawpoolpbropaque.h
lldrawpoolsimple.h
lldrawpoolsky.h
lldrawpoolterrain.h
@@ -812,6 +818,7 @@ set(viewer_HEADER_FILES
llfasttimerview.h
llfavoritesbar.h
llfeaturemanager.h
+ llfetchedgltfmaterial.h
llfilepicker.h
llfilteredwearablelist.h
llfirstuse.h
@@ -935,7 +942,6 @@ set(viewer_HEADER_FILES
llfloatertelehub.h
llfloatertestinspectors.h
llfloatertestlistview.h
- llfloatertexturefetchdebugger.h
llfloatertools.h
llfloatertopobjects.h
llfloatertos.h
@@ -956,6 +962,7 @@ set(viewer_HEADER_FILES
llgesturelistener.h
llgesturemgr.h
llgiveinventory.h
+ llgltfmateriallist.h
llgroupactions.h
llgroupiconctrl.h
llgrouplist.h
@@ -1007,6 +1014,7 @@ set(viewer_HEADER_FILES
lllistcontextmenu.h
lllistview.h
lllocalbitmaps.h
+ lllocalgltfmaterials.h
lllocationhistory.h
lllocationinputctrl.h
lllogchat.h
@@ -1019,6 +1027,7 @@ set(viewer_HEADER_FILES
llmaniptranslate.h
llmarketplacefunctions.h
llmarketplacenotifications.h
+ llmaterialeditor.h
llmaterialmgr.h
llmediactrl.h
llmediadataclient.h
@@ -1147,6 +1156,8 @@ set(viewer_HEADER_FILES
llproductinforequest.h
llprogressview.h
llrecentpeople.h
+ llreflectionmap.h
+ llreflectionmapmanager.h
llregioninfomodel.h
llregionposition.h
llremoteparcelrequest.h
@@ -1208,6 +1219,7 @@ set(viewer_HEADER_FILES
lltexturestats.h
lltextureview.h
llthumbnailctrl.h
+ lltinygltfhelper.h
lltoast.h
lltoastalertpanel.h
lltoastgroupnotifypanel.h
@@ -1317,7 +1329,6 @@ set(viewer_HEADER_FILES
llvoavatarself.h
llvocache.h
llvograss.h
- llvoground.h
llvoicechannel.h
llvoiceclient.h
llvoicevisualizer.h
@@ -1589,18 +1600,23 @@ set_source_files_properties(${viewer_XUI_FILES}
list(APPEND viewer_SOURCE_FILES ${viewer_XUI_FILES})
+file(GLOB_RECURSE viewer_SHADER_FILES LIST_DIRECTORIES TRUE
+ ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders/*.glsl)
+source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}/app_settings/shaders PREFIX "Shaders" FILES ${viewer_SHADER_FILES})
+set_source_files_properties(${viewer_SHADER_FILES}
+ PROPERTIES HEADER_FILE_ONLY TRUE)
+list(APPEND viewer_SOURCE_FILES ${viewer_SHADER_FILES})
+
+
set(viewer_APPSETTINGS_FILES
app_settings/anim.ini
app_settings/cmd_line.xml
app_settings/commands.xml
app_settings/grass.xml
- app_settings/high_graphics.xml
app_settings/ignorable_dialogs.xml
app_settings/key_bindings.xml
app_settings/keywords_lsl_default.xml
app_settings/logcontrol.xml
- app_settings/low_graphics.xml
- app_settings/mid_graphics.xml
app_settings/settings.xml
app_settings/settings_crash_behavior.xml
app_settings/settings_files.xml
@@ -1608,7 +1624,6 @@ set(viewer_APPSETTINGS_FILES
app_settings/std_bump.ini
app_settings/toolbars.xml
app_settings/trees.xml
- app_settings/ultra_graphics.xml
app_settings/viewerart.xml
${CMAKE_SOURCE_DIR}/../etc/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
@@ -1684,6 +1699,7 @@ if (WINDOWS)
LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO /LARGEADDRESSAWARE"
LINK_FLAGS_RELEASE "/FORCE:MULTIPLE /MAP\"secondlife-bin.MAP\" /OPT:REF /LARGEADDRESSAWARE"
)
+ target_compile_options(${VIEWER_BINARY_NAME} PRIVATE /bigobj)
if(USE_PRECOMPILED_HEADERS)
target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h )
@@ -2198,6 +2214,7 @@ if (LL_TESTS)
# llremoteparcelrequest.cpp
llviewerhelputil.cpp
llversioninfo.cpp
+# llvocache.cpp
llworldmap.cpp
llworldmipmap.cpp
)
@@ -2211,6 +2228,13 @@ if (LL_TESTS)
#llviewertexturelist.cpp
)
+# set_source_files_properties(
+# llvocache.cpp
+# PROPERTIES
+# LL_TEST_ADDITIONAL_SOURCE_FILES ../llmessage/lldatapacker.cpp
+# LL_TEST_ADDITIONAL_PROJECTS "llprimitive"
+# )
+
set(test_libs
llcommon
llfilesystem
@@ -2229,7 +2253,6 @@ if (LL_TESTS)
LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
)
-
set_source_files_properties(
llworldmap.cpp
llworldmipmap.cpp
@@ -2249,6 +2272,7 @@ if (LL_TESTS)
PROPERTIES
LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp
)
+
set_property( SOURCE
${viewer_TEST_SOURCE_FILES}
PROPERTY
@@ -2299,6 +2323,19 @@ if (LL_TESTS)
"${test_libs}"
)
+ set(llviewercontrollistener_test_sources
+ llviewercontrollistener.cpp
+ ../llxml/llcontrol.cpp
+ ../llxml/llxmltree.cpp
+ ../llxml/llxmlparser.cpp
+ ../llcommon/commoncontrol.cpp
+ )
+
+ LL_ADD_INTEGRATION_TEST(llviewercontrollistener
+ "${llviewercontrollistener_test_sources}"
+ "${test_libs}"
+ )
+
LL_ADD_INTEGRATION_TEST(llviewernetwork
llviewernetwork.cpp
"${test_libs}"
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 93409ff0c2..9fe9ff9d99 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.6.17
+7.0.1
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
deleted file mode 100644
index f64937f443..0000000000
--- a/indra/newview/app_settings/high_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.9"/>
- <!--Short Range-->
- <RenderFarClip value="128"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="2"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="20"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1250.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--Sun Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index 9699eda96b..4e177ab518 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -274,6 +274,7 @@ INVENTORY_NOTECARD Passed to task inventory library functions to reference notec
INVENTORY_BODYPART Passed to task inventory library functions to reference body parts
INVENTORY_ANIMATION Passed to task inventory library functions to reference animations
INVENTORY_GESTURE Passed to task inventory library functions to reference gestures
+INVENTORY_MATERIAL Passed to task inventory library functions to reference materials
INVENTORY_ALL Passed to task inventory library functions to reference all inventory items
INVENTORY_NONE Returned by llGetInventoryType when no item is found
diff --git a/indra/newview/app_settings/keywords_lsl_default.xml b/indra/newview/app_settings/keywords_lsl_default.xml
index d641883d5a..893b017367 100644
--- a/indra/newview/app_settings/keywords_lsl_default.xml
+++ b/indra/newview/app_settings/keywords_lsl_default.xml
@@ -1963,6 +1963,15 @@
<key>tooltip</key>
<string/>
</map>
+ <key>INVENTORY_MATERIAL</key>
+ <map>
+ <key>type</key>
+ <string>integer</string>
+ <key>value</key>
+ <integer>57</integer>
+ <key>tooltip</key>
+ <string/>
+ </map>
<key>JSON_APPEND</key>
<map>
<key>type</key>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
deleted file mode 100644
index b31a040d67..0000000000
--- a/indra/newview/app_settings/low_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.0"/>
- <!--Short Range-->
- <RenderFarClip value="64"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="0.5"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="1024"/>
- <!--bump okay-->
- <RenderObjectBump value="FALSE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="0"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="12"/>
- <RenderAvatarMaxComplexity value="80000"/>
- <RenderAutoMuteSurfaceAreaLimit value="750.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
deleted file mode 100644
index 9c2c17fc60..0000000000
--- a/indra/newview/app_settings/mid_graphics.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="FALSE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="0.5"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="0.75"/>
- <!--Short Range-->
- <RenderFarClip value="96"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="8"/>
- <!--Low number-->
- <RenderMaxPartCount value="2048"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="0"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="0.5"/>
- <!--Avater Impostors and Visual Muting Limits-->
- <RenderAvatarMaxNonImpostors value="18"/>
- <RenderAvatarMaxComplexity value="150000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1000.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="1.125"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="FALSE"/>
- <!--No Deferred Shading-->
- <RenderDeferred value="FALSE"/>
- <!--SSAO Disabled-->
- <RenderDeferredSSAO value="FALSE"/>
- <!--No Shadows-->
- <RenderShadowDetail value="0"/>
-</settings>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 28d84aba21..b9025ef7cd 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -250,7 +250,7 @@
<key>TextureLivePreview</key>
<map>
<key>Comment</key>
- <string>Preview selections in texture picker immediately</string>
+ <string>Preview selections in texture picker or material picker immediately</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -1241,6 +1241,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>BulkChangeIncludeMaterials</key>
+ <map>
+ <key>Comment</key>
+ <string>Bulk permission changes affect materials</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>BulkChangeEveryoneCopy</key>
<map>
<key>Comment</key>
@@ -3902,7 +3913,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.1</real>
+ <real>1.0</real>
</map>
<key>QueueInventoryFetchTimeout</key>
<map>
@@ -8756,7 +8767,7 @@
<string>Vector3</string>
<key>Value</key>
<array>
- <real>0.01</real>
+ <real>0.25</real>
<real>0.0</real>
<real>0.0</real>
</array>
@@ -8831,24 +8842,35 @@
<key>RenderAvatarCloth</key>
<map>
<key>Comment</key>
- <string>Controls if avatars use wavy cloth</string>
+ <string>DEPRECATED - only false supported - Controls if avatars use wavy cloth</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
- <key>RenderClass0MemoryBandwidth</key>
+ <key>RenderClass1MemoryBandwidth</key>
+ <map>
+ <key>Comment</key>
+ <string>Memory bandwidth at which to default to Class 1 in gigabytes per second. Used as basis for higher classes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>32.0</real>
+ </map>
+ <key>RenderCloudShadowAmbianceFactor</key>
<map>
<key>Comment</key>
- <string>Memory bandwidth at which to default to Class 0 in gigabytes per second. Used as basis for other classes.</string>
+ <string>Amount that cloud shadow (aka cloud coverage) contributes to reflection probe ambiance</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>16.0</real>
+ <real>0.1</real>
</map>
<key>RenderCPUBasis</key>
<map>
@@ -8964,6 +8986,17 @@
<key>Value</key>
<real>1.0</real>
</map>
+ <key>RenderBufferVisualization</key>
+ <map>
+ <key>Comment</key>
+ <string>Outputs a selected buffer to the screen. -1 = final render buffer. 0 = Albedo, 1 = Specular/ORM, 2 = Normal, 3 = Emissive, 4 = Eye luminance</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>-1</integer>
+ </map>
<key>RenderCompressTextures</key>
<map>
<key>Comment</key>
@@ -8984,7 +9017,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <integer>0</integer>
</map>
<key>RenderPerformanceTest</key>
<map>
@@ -9013,47 +9046,16 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderLocalLights</key>
+ <key>RenderLocalLightCount</key>
<map>
<key>Comment</key>
- <string>Whether or not to render local lights.</string>
+ <string>Number of local lights to render.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
-
- <key>RenderShadowNearDist</key>
- <map>
- <key>Comment</key>
- <string>Near clip plane of shadow camera (affects precision of depth shadows).</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>256</real>
- <real>256</real>
- <real>256</real>
- </array>
- </map>
- <key>RenderShadowClipPlanes</key>
- <map>
- <key>Comment</key>
- <string>Near clip plane split distances for shadow map frusta.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
+ <string>S32</string>
<key>Value</key>
- <array>
- <real>1.0</real>
- <real>12.0</real>
- <real>32.0</real>
- </array>
+ <integer>256</integer>
</map>
<key>RenderShadowSplitExponent</key>
<map>
@@ -9070,21 +9072,6 @@
<real>2.0</real>
</array>
</map>
- <key>RenderShadowOrthoClipPlanes</key>
- <map>
- <key>Comment</key>
- <string>Near clip plane split distances for orthographic shadow map frusta.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Vector3</string>
- <key>Value</key>
- <array>
- <real>4.0</real>
- <real>8.0</real>
- <real>24.0</real>
- </array>
- </map>
<key>RenderShadowProjOffset</key>
<map>
<key>Comment</key>
@@ -9140,6 +9127,28 @@
<key>Value</key>
<real>500.0</real>
</map>
+ <key>RenderSSAOIrradianceScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Scaling factor for irradiance input to SSAO</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.6</real>
+ </map>
+ <key>RenderSSAOIrradianceMax</key>
+ <map>
+ <key>Comment</key>
+ <string>Max factor for irradiance input to SSAO</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.18</real>
+ </map>
<key>RenderSSAOMaxScale</key>
<map>
<key>Comment</key>
@@ -9177,6 +9186,83 @@
<real>0.00</real>
</array>
</map>
+ <key>RenderScreenSpaceReflections</key>
+ <map>
+ <key>Comment</key>
+ <string>Renders screen space reflections to better account for dynamic objects with reflection probes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderScreenSpaceReflectionIterations</key>
+ <map>
+ <key>Comment</key>
+ <string>Number of times the ray march algorithm runs to find a potential hit.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>25</integer>
+ </map>
+ <key>RenderScreenSpaceReflectionRayStep</key>
+ <map>
+ <key>Comment</key>
+ <string>How big the step is between each run.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.1</real>
+ </map>
+ <key>RenderScreenSpaceReflectionDistanceBias</key>
+ <map>
+ <key>Comment</key>
+ <string>Distance bias to apply when rejecting a potential sample.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.015</real>
+ </map>
+ <key>RenderScreenSpaceReflectionDepthRejectBias</key>
+ <map>
+ <key>Comment</key>
+ <string>Bias against the depth buffer before rejecting a sample.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.001</real>
+ </map>
+ <key>RenderScreenSpaceReflectionAdaptiveStepMultiplier</key>
+ <map>
+ <key>Comment</key>
+ <string>Multiplier to scale adaptive stepping.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.6</real>
+ </map>
+ <key>RenderScreenSpaceReflectionGlossySamples</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of samples to apply for glossy SSR.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>4</integer>
+ </map>
<key>RenderBumpmapMinDistanceSquared</key>
<map>
<key>Comment</key>
@@ -9254,6 +9340,50 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderDisablePostProcessing</key>
+ <map>
+ <key>Comment</key>
+ <string>Disable tone mapping and exposure correction when build floater is open (for artists developing materials)</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderPostProcessingHDR</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable HDR for post processing buffer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderMaxOpenGLVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum OpenGL version to attempt use (minimum 3.2 maximum 4.6). Requires restart.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>4.6</real>
+ </map>
+ <key>RenderMaxVRAMBudget</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum amount of texture memory to budget for (in MB), or 0 for autodetect. Requires restart.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxTextureIndex</key>
<map>
<key>Comment</key>
@@ -9413,7 +9543,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>-0.004</real>
+ <real>-0.002</real>
</map>
<key>RenderShadowOffset</key>
<map>
@@ -9518,7 +9648,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>-0.001</real>
+ <real>-0.0002</real>
</map>
<key>RenderSpotShadowOffset</key>
<map>
@@ -9569,7 +9699,7 @@
<key>RenderHoverGlowEnable</key>
<map>
<key>Comment</key>
- <string>Show glow effect when hovering on interactive objects.</string>
+ <string>DEPRECATED --- Show glow effect when hovering on interactive objects.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9682,13 +9812,13 @@
<key>RenderDeferred</key>
<map>
<key>Comment</key>
- <string>Use deferred rendering pipeline (Advanced Lighting Model).</string>
+ <string>DEPRECATED (only true supported) - Use deferred rendering pipeline (Advanced Lighting Model).</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderDeferredSun</key>
@@ -9903,7 +10033,7 @@
<key>RenderFogRatio</key>
<map>
<key>Comment</key>
- <string>Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
+ <string>DEPRECATED - Distance from camera where fog reaches maximum density (fraction or multiple of far clip distance)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9914,7 +10044,7 @@
<key>RenderGamma</key>
<map>
<key>Comment</key>
- <string>Sets gamma exponent for renderer</string>
+ <string>DEPRECATED - Sets gamma exponent for renderer</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9947,7 +10077,7 @@
<key>RenderGLContextCoreProfile</key>
<map>
<key>Comment</key>
- <string>Don't use a compatibility profile OpenGL context. Requires restart. Basic shaders MUST be enabled.</string>
+ <string>Don't use a compatibility profile OpenGL context. Requires restart.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -9955,10 +10085,21 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderGLMultiThreaded</key>
+ <key>RenderGLMultiThreadedTextures</key>
<map>
<key>Comment</key>
- <string>Allow OpenGL to use multiple render contexts (reduces frame stutters from loading textures, doesn't play nice with Intel drivers).</string>
+ <string>Allow OpenGL to use multiple render contexts for loading textures (may reduce frame stutters, doesn't play nice with Intel drivers).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>RenderGLMultiThreadedMedia</key>
+ <map>
+ <key>Comment</key>
+ <string>Allow OpenGL to use multiple render contexts for playing media (may reduce frame stutters, doesn't play nice with Intel drivers)</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10036,6 +10177,17 @@
<key>Value</key>
<integer>9</integer>
</map>
+ <key>RenderGlowHDR</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable HDR for glow map</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderGlowStrength</key>
<map>
<key>Comment</key>
@@ -10045,7 +10197,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>0.35</real>
+ <real>0.325</real>
</map>
<key>RenderGlowWarmthAmount</key>
<map>
@@ -10084,16 +10236,16 @@
<key>Value</key>
<real>1.3</real>
</map>
- <key>RenderGround</key>
+ <key>RenderGlowNoise</key>
<map>
<key>Comment</key>
- <string>Determines whether we can render the ground pool or not</string>
+ <string>Enables glow noise (dithering). Reduces banding from glow in certain cases.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>1</integer>
+ <real>1</real>
</map>
<key>DisableAllRenderTypes</key>
<map>
@@ -10238,6 +10390,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderReflectionProbeVolumes</key>
+ <map>
+ <key>Comment</key>
+ <string>Render influence volumes of Reflection Probes</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>RenderMaxPartCount</key>
<map>
<key>Comment</key>
@@ -10307,7 +10470,7 @@
<key>RenderObjectBump</key>
<map>
<key>Comment</key>
- <string>Show bumpmapping on primitives</string>
+ <string>DEPRECATED (only TRUE supported) Show bumpmapping on primitives</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10326,10 +10489,11 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>RenderReflectionDetail</key>
+
+ <key>RenderReflectionDetail</key>
<map>
<key>Comment</key>
- <string>Detail of reflection render pass.</string>
+ <string>DEPRECATED -- use RenderTransparentWater and RenderReflectionProbeDetail -- Detail of reflection render pass.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10348,8 +10512,96 @@
<key>Value</key>
<integer>2</integer>
</map>
-
- <key>RenderReflectionRes</key>
+ <key>RenderReflectionsEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable/disable reflection probes</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderReflectionProbeDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail of reflections. (-1 - Disabled, 0 - Static Only, 1 - Static + Dynamic, 2 - Realtime)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderReflectionProbeResolution</key>
+ <map>
+ <key>Comment</key>
+ <string>Resolution of reflection probe radiance maps (requires restart). Will be set to the next highest power of two clamped to [64, 512]. Note that changing this value may consume a massive amount of video memory.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>128</integer>
+ </map>
+ <key>RenderExposure</key>
+ <map>
+ <key>Comment</key>
+ <string>Exposure value to send to tonemapper.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1</real>
+ </map>
+
+ <key>RenderReflectionProbeDrawDistance</key>
+ <map>
+ <key>Comment</key>
+ <string>Camera far clip to use when updating reflection probes.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <integer>64</integer>
+ </map>
+ <key>RenderReflectionProbeAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount reflection probes contribute to ambient light.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+ <key>RenderDefaultProbeUpdatePeriod</key>
+ <map>
+ <key>Comment</key>
+ <string>When RenderReflectionProbeLevel is 0, amount of time in seconds to wait between updates to reflection map.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.0</real>
+ </map>
+ <key>RenderReflectionProbeLevel</key>
+ <map>
+ <key>Comment</key>
+ <string>Reflection probes control. 0 - disable (one probe to rule them all), 1 - manual probes only, 2 - manual + terrain/water, 3 - Manual + Terrain/water + objects.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>3</integer>
+ </map>
+ <key>RenderReflectionRes</key>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
@@ -10382,6 +10634,128 @@
<key>Value</key>
<integer>3</integer>
</map>
+ <key>RenderSkyAutoAdjustLegacy</key>
+ <map>
+ <key>Comment</key>
+ <string>If true, automatically adjust legacy skies (those without a probe ambiance value) to take advantage of probes and HDR. This is the "opt-out" button for HDR and tonemapping when coupled with a sky setting that predates PBR.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderSkyAutoAdjustAmbientScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Amount to scale ambient when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderSkyAutoAdjustHDRScale</key>
+ <map>
+ <key>Comment</key>
+ <string>HDR Scale value to use when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>2.0</real>
+ </map>
+ <key>RendeSkyAutoAdjustBlueHorizonScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Blue Horizon Scale value to use when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RendeSkyAutoAdjustBlueDensityScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Blue Horizon Scale value to use when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderSkyAutoAdjustSunColorScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Sun color scalar when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderSkyAutoAdjustProbeAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Probe ambiance value when auto-adjusting legacy skies</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.001</real>
+ </map>
+ <key>RenderSkySunlightScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Sunlight scale fudge factor for matching with pre-PBR viewer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>1.0</real>
+ </map>
+ <key>RenderSkyAmbientScale</key>
+ <map>
+ <key>Comment</key>
+ <string>Ambient scale fudge factor for matching with pre-PBR viewer</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.7</real>
+ </map>
+
+ <key>RenderReflectionProbeMaxLocalLightAmbiance</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum effective probe ambiance for local lights</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>4.0</real>
+ </map>
+ <key>RenderDynamicExposureCoefficient</key>
+ <map>
+ <key>Comment</key>
+ <string>Luminance coefficient for dynamic exposure</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.5</real>
+ </map>
<key>RenderShaderLODThreshold</key>
<map>
<key>Comment</key>
@@ -10448,17 +10822,6 @@
<key>Value</key>
<real>12.0</real>
</map>
- <key>RenderTextureMemoryMultiple</key>
- <map>
- <key>Comment</key>
- <string>Multiple of texture memory value to use (should fit: 0 &lt; value &lt;= 1.0)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>1.0</real>
- </map>
<key>RenderTrackerBeacon</key>
<map>
<key>Comment</key>
@@ -10539,7 +10902,7 @@
<key>RenderUseTriStrips</key>
<map>
<key>Comment</key>
- <string>Use triangle strips for rendering prims.</string>
+ <string>DEPRECATED - now always assumed to be false - Use triangle strips for rendering prims.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -10569,17 +10932,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderAutoMuteByteLimit</key>
- <map>
- <key>Comment</key>
- <string>If avatar attachment size exceed this value (in bytes) attachment will not be rendered. Excludes attachments worn by own avatar.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>U32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>RenderAvatarMaxNonImpostors</key>
<map>
<key>Comment</key>
@@ -10751,18 +11103,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderUseTransformFeedback</key>
- <map>
- <key>Comment</key>
- <string>[EXPERIMENTAL] Use transform feedback shaders for LoD updates</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
-
<key>RenderVBOMappingDisable</key>
<map>
<key>Comment</key>
@@ -10862,6 +11202,28 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderShaderCacheEnabled</key>
+ <map>
+ <key>Comment</key>
+ <string>Enable binary shader cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>RenderShaderCacheVersion</key>
+ <map>
+ <key>Comment</key>
+ <string>Current version hash for shader cache</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string>00000000-0000-0000-0000-000000000000</string>
+ </map>
<key>ReplaySession</key>
<map>
<key>Comment</key>
@@ -11225,6 +11587,28 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>SelectInvisibleObjects</key>
+ <map>
+ <key>Comment</key>
+ <string>Select invisible objects</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>SelectReflectionProbes</key>
+ <map>
+ <key>Comment</key>
+ <string>Select reflection probes</string>
+ <key>Persist</key>
+ <integer>0</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>SelectOwnedOnly</key>
<map>
<key>Comment</key>
@@ -12527,38 +12911,16 @@
<key>Value</key>
<real>20.0</real>
</map>
- <key>TexelPixelRatio</key>
+ <key>TextureBiasDistanceScale</key>
<map>
<key>Comment</key>
- <string>texel pixel ratio = texel / pixel</string>
+ <string>When biasing textures to lower resolution due to lack of vram, weight to put on distance factor.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>1.0</real>
- </map>
- <key>TextureCameraMotionThreshold</key>
- <map>
- <key>Comment</key>
- <string>If the overall motion is lower than this value, textures will be loaded faster</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.2</real>
- </map>
- <key>TextureCameraMotionBoost</key>
- <map>
- <key>Comment</key>
- <string>Progressive discard level decrement when the camera is still</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>3</integer>
+ <real>8.0</real>
</map>
<key>TextureDecodeDisabled</key>
<map>
@@ -12582,39 +12944,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>AmbientDisable</key>
- <map>
- <key>Comment</key>
- <string>If TRUE, ambient light has no effect</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>SunlightDisable</key>
- <map>
- <key>Comment</key>
- <string>If TRUE, sunlight has no effect</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>LocalLightDisable</key>
- <map>
- <key>Comment</key>
- <string>If TRUE, local lights have no effect</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>TextureDiscardLevel</key>
<map>
<key>Comment</key>
@@ -12637,17 +12966,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>TextureFetchDebuggerEnabled</key>
- <map>
- <key>Comment</key>
- <string>Enable the texture fetching debugger if set</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>TextureFetchMinTimeToLog</key>
<map>
<key>Comment</key>
@@ -12670,43 +12988,10 @@
<key>Value</key>
<real>0.0</real>
</map>
- <key>TextureFetchSource</key>
- <map>
- <key>Comment</key>
- <string>Debug use: Source to fetch textures</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>TextureFetchUpdateHighPriority</key>
- <map>
- <key>Comment</key>
- <string>Number of high priority textures to update per frame</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>32</integer>
- </map>
- <key>TextureFetchUpdateMaxMediumPriority</key>
+ <key>TextureFetchUpdateMinCount</key>
<map>
<key>Comment</key>
- <string>Maximum number of medium priority textures to update per frame</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>256</integer>
- </map>
- <key>TextureFetchUpdateMinMediumPriority</key>
- <map>
- <key>Comment</key>
- <string>Minimum number of medium priority textures to update per frame</string>
+ <string>Minimum number of textures to update per frame</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -12714,69 +12999,14 @@
<key>Value</key>
<integer>32</integer>
</map>
- <key>TextureFetchUpdatePriorityThreshold</key>
- <map>
- <key>Comment</key>
- <string>Threshold under which textures will be considered too low priority and skipped for update</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.0</real>
- </map>
- <key>TextureFetchUpdateSkipLowPriority</key>
- <map>
- <key>Comment</key>
- <string>Flag indicating if we want to skip textures with too low of a priority</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>TextureFetchUpdatePriorities</key>
- <map>
- <key>Comment</key>
- <string>Number of priority texture to update per frame</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>32</integer>
- </map>
- <key>TextureListFetchingThreshold</key>
- <map>
- <key>Comment</key>
- <string>If the ratio between fetched and all textures in the list is greater than this threshold, which we assume that almost all textures are fetched</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>F32</string>
- <key>Value</key>
- <real>0.97</real>
- </map>
<key>TextureLoadFullRes</key>
<map>
<key>Comment</key>
<string>If TRUE, always load textures at full resolution (discard = 0)</string>
<key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
- <key>TextureMemory</key>
- <map>
- <key>Comment</key>
- <string>Amount of memory to use for textures in MB (0 = autodetect)</string>
- <key>Persist</key>
<integer>1</integer>
<key>Type</key>
- <string>S32</string>
+ <string>Boolean</string>
<key>Value</key>
<integer>0</integer>
</map>
@@ -12846,7 +13076,9 @@
<key>Value</key>
<map>
<key>General</key>
- <integer>4</integer>
+ <integer>1</integer>
+ <key>ImageDecode</key>
+ <integer>9</integer>
</map>
</map>
<key>ThrottleBandwidthKBPS</key>
@@ -14302,6 +14534,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderOcclusionTimeout</key>
+ <map>
+ <key>Comment</key>
+ <string>Maximum number of frames to wait on an occlusion query before forcibly reading it back</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>8</integer>
+ </map>
<key>UseObjectCacheOcclusion</key>
<map>
<key>Comment</key>
@@ -14313,17 +14556,6 @@
<key>Value</key>
<integer>1</integer>
</map>
- <key>RenderDelayVBUpdate</key>
- <map>
- <key>Comment</key>
- <string>Delay vertex buffer updates until just before rendering</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>SocialPhotoResolution</key>
<map>
<key>Comment</key>
@@ -14967,7 +15199,7 @@
<key>WindLightUseAtmosShaders</key>
<map>
<key>Comment</key>
- <string>Whether to enable or disable WindLight atmospheric shaders.</string>
+ <string>DEPRECATED (only true supported) - Whether to enable or disable WindLight atmospheric shaders.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -16267,6 +16499,61 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>MaterialsNextOwnerCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be copied by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsNextOwnerModify</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be modified by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsNextOwnerTransfer</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF material can be resold or given away by next owner</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
+ <key>MaterialsEveryoneCopy</key>
+ <map>
+ <key>Comment</key>
+ <string>Everyone can copy the newly created GLTF material</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
+ <key>MaterialsShareWithGroup</key>
+ <map>
+ <key>Comment</key>
+ <string>Newly created GLTF materials are shared with the currently active group</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DefaultUploadPermissionsConverted</key>
<map>
<key>Comment</key>
@@ -16898,17 +17185,6 @@
<key>Value</key>
<real>256.0</real>
</map>
- <key>UserTargetReflections</key>
- <map>
- <key>Comment</key>
- <string>Set by auto tune floater on build</string>
- <key>Persist</key>
- <integer>0</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>4</integer>
- </map>
<key>PerfStatsCaptureEnabled</key>
<map>
<key>Comment</key>
@@ -17107,6 +17383,17 @@
<key>Value</key>
<string></string>
</map>
+ <key>EmulateCoreCount</key>
+ <map>
+ <key>Comment</key>
+ <string>For debugging -- number of cores to restrict the main process to, or 0 for no limit. Requires restart.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>U32</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>DebugSettingsHideDefault</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index e89d1cbda4..6b788dd78f 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -381,6 +381,17 @@
<key>Value</key>
<string></string>
</map>
+ <key>PBRUploadFolder</key>
+ <map>
+ <key>Comment</key>
+ <string>All pbr uploads will be stored in this directory (UUID)</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>String</string>
+ <key>Value</key>
+ <string></string>
+ </map>
<key>TextureUploadFolder</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
index 767fad016c..374469ce2f 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarSkinV.glsl
@@ -24,7 +24,7 @@
*/
-ATTRIBUTE vec4 weight;
+in vec4 weight;
uniform vec4 matrixPalette[45];
diff --git a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
index 0543a26642..9adc68e62b 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/avatarV.glsl
@@ -25,12 +25,12 @@
uniform mat4 projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
uniform vec4 color;
diff --git a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
index fac1599c6b..837074f08c 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/eyeballV.glsl
@@ -28,13 +28,13 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
void calcAtmospherics(vec3 inPositionEye);
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 90bf2851c9..0817076dd5 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -22,7 +22,7 @@
* $/LicenseInfo$
*/
-ATTRIBUTE vec4 weight4;
+in vec4 weight4;
uniform mat3x4 matrixPalette[MAX_JOINTS_PER_MESH_OBJECT];
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl b/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
deleted file mode 100644
index 78b5328c9a..0000000000
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarV.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file pickAvatarV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-mat4 getSkinnedTransform();
-
-void main()
-{
- vec4 pos;
- vec4 pos_in = vec4(position, 1.0);
- mat4 trans = getSkinnedTransform();
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- vertex_color = diffuse_color;
- vary_texcoord0 = texcoord0;
- gl_Position = projection_matrix * pos;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index 6a93bc2fd2..4c9d813c9c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -33,19 +33,19 @@ uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
#ifdef USE_INDEXED_TEX
void passTextureIndex();
#endif
-ATTRIBUTE vec3 normal;
+in vec3 normal;
#ifdef USE_VERTEX_COLOR
-ATTRIBUTE vec4 diffuse_color;
+in vec4 diffuse_color;
#endif
-ATTRIBUTE vec2 texcoord0;
+in vec2 texcoord0;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
@@ -55,15 +55,15 @@ mat4 getSkinnedTransform();
#endif
#endif
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
+out vec3 vary_fragcoord;
+out vec3 vary_position;
#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color;
+out vec4 vertex_color;
#endif
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
+out vec2 vary_texcoord0;
+out vec3 vary_norm;
uniform float near_clip;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
index 23adbded5e..da467cd5da 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/aoUtil.glsl
@@ -24,8 +24,8 @@
*/
uniform sampler2D noiseMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
+uniform sampler2D normalMap;
+uniform sampler2D depthMap;
uniform float ssao_radius;
uniform float ssao_max_radius;
@@ -38,16 +38,12 @@ uniform vec2 screen_res;
vec2 getScreenCoordinateAo(vec2 screenpos)
{
vec2 sc = screenpos.xy * 2.0;
- if (screen_res.x > 0 && screen_res.y > 0)
- {
- sc /= screen_res;
- }
return sc - vec2(1.0, 1.0);
}
float getDepthAo(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen).r;
+ float depth = texture(depthMap, pos_screen).r;
return depth;
}
@@ -75,7 +71,7 @@ vec2 getKern(int i)
kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
- return kern[i];
+ return kern[i] / screen_res;
}
//calculate decreases in ambient lighting when crowded out (SSAO)
@@ -83,8 +79,8 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
{
float ret = 1.0;
vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, pos_screen.xy/128.0).xy;
-
+ vec2 noise_reflect = texture(noiseMap, pos_screen.xy * (screen_res / 128)).xy;
+
float angle_hidden = 0.0;
float points = 0;
@@ -95,7 +91,7 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen)
{
vec2 samppos_screen = pos_screen + scale * reflect(getKern(i), noise_reflect);
vec3 samppos_world = getPositionAo(samppos_screen).xyz;
-
+
vec3 diff = pos_world - samppos_world;
float dist2 = dot(diff, diff);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
deleted file mode 100644
index c64b6ba240..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaMaskShadowF.glsl
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file attachmentAlphaMaskShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < minimum_alpha) // treat as semi-transparent
- {
- //if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = vec4(1,1,1,1);
-
-#if !DEPTH_CLAMP
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
deleted file mode 100644
index b54c580ce9..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowF.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file attachmentAlphaShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-uniform sampler2D diffuseMap;
-
-VARYING float pos_w;
-VARYING float target_pos_x;
-
-#if !DEPTH_CLAMP
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void main()
-{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * vertex_color.a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < minimum_alpha)
- {
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = vec4(1,1,1,1);
-
-#if !DEPTH_CLAMP
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
deleted file mode 100644
index 31b93dc36a..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentAlphaShadowV.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file attachmentShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-void passTextureIndex();
-
-#if !DEPTH_CLAMP
-VARYING vec4 post_pos;
-#endif
-VARYING vec2 vary_texcoord0;
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
- vec4 p = projection_matrix * vec4(pos, 1.0);
-
- pos_w = p.w;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vertex_color = diffuse_color;
-
-#if !DEPTH_CLAMP
- p.z = max(p.z, -p.w+0.01);
- post_pos = p;
- gl_Position = p;
-#else
- gl_Position = p;
-#endif
-
- passTextureIndex();
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
deleted file mode 100644
index 0fa0edfd67..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowV.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file attachmentShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- vec3 pos = (mat*vec4(position.xyz, 1.0)).xyz;
-
-
- vec4 p = projection_matrix * vec4(pos, 1.0);
-#if !defined(DEPTH_CLAMP)
- p.z = max(p.z, -p.w+0.01);
- gl_Position = p;
-#else
- gl_Position = p;
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
index b8ce54bcb1..f1dc1159d0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaMaskShadowF.glsl
@@ -1,5 +1,5 @@
/**
- * @file treeShadowF.glsl
+ * @file avatarAlphaMaskShadowF.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,26 +23,18 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
-VARYING vec4 post_pos;
-#endif
-
-VARYING float target_pos_x;
-VARYING float pos_w;
-VARYING vec2 vary_texcoord0;
+in float target_pos_x;
+in float pos_w;
+in vec2 vary_texcoord0;
void main()
{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+ float alpha = texture(diffuseMap, vary_texcoord0.xy).a;
if (alpha < 0.05) // treat as totally transparent
{
@@ -58,8 +50,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
-#if !DEPTH_CLAMP
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
deleted file mode 100644
index bbdc8fdd1c..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaNoColorV.glsl
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * @file avatarAlphaNoColorV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-float calcDirectionalLight(vec3 n, vec3 l);
-
-vec3 atmosAmbient();
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-
-VARYING vec3 vary_position;
-VARYING vec3 vary_ambient;
-VARYING vec3 vary_directional;
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_pointlight_col;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
-
-
-uniform float near_clip;
-
-uniform vec4 color;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- vec3 norm;
-
- mat4 trans = getSkinnedTransform();
- vec4 pos_in = vec4(position.xyz, 1.0);
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
- vary_norm = norm;
-
- vec4 frag_pos = projection_matrix * pos;
- gl_Position = frag_pos;
-
- vary_position = pos.xyz;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = vec4(0.0, 0.0, 0.0, 1.0);
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
-
- vary_pointlight_col = col.rgb*color.rgb;
-
- col.rgb = vec3(0,0,0);
-
- // Add windlight lights
- col.rgb = atmosAmbient();
-
- vary_ambient = col.rgb*color.rgb;
- vary_directional = color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, light_position[0].xyz), 0.0));
-
- col.rgb = col.rgb * color.rgb;
-
- vary_fragcoord.xyz = frag_pos.xyz + vec3(0,0,near_clip);
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
index 1b16e4eb09..097e28aa0c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowF.glsl
@@ -23,28 +23,20 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-#if !DEPTH_CLAMP
-VARYING vec4 post_pos;
-#endif
-
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
+in float pos_w;
+in float target_pos_x;
+in vec2 vary_texcoord0;
uniform vec4 color;
void main()
{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a * color.a;
+ float alpha = texture(diffuseMap, vary_texcoord0.xy).a * color.a;
if (alpha < 0.05) // treat as totally transparent
{
@@ -60,9 +52,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
-#if !DEPTH_CLAMP
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
index 1c5b142ebd..57e0b2b59f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaShadowV.glsl
@@ -1,5 +1,5 @@
/**
- * @file avatarShadowV.glsl
+ * @file avatarAlphaShadowV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -30,16 +30,13 @@ uniform float shadow_target_width;
mat4 getSkinnedTransform();
void passTextureIndex();
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
-#if !DEPTH_CLAMP
-VARYING vec4 post_pos;
-#endif
-VARYING float pos_w;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
+out float pos_w;
+out float target_pos_x;
+out vec2 vary_texcoord0;
void main()
{
@@ -66,13 +63,7 @@ void main()
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-#if !DEPTH_CLAMP
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
passTextureIndex();
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
index 01ffb862f7..83b0ba096c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarEyesV.glsl
@@ -27,14 +27,14 @@ uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec3 vary_normal;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 60d83cc623..6ebe4ce251 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -25,24 +25,20 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
uniform sampler2D diffuseMap;
uniform float minimum_alpha;
-VARYING vec3 vary_normal;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_normal;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void main()
{
- vec4 diff = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 diff = texture(diffuseMap, vary_texcoord0.xy);
if (diff.a < minimum_alpha)
{
@@ -52,6 +48,6 @@ void main()
frag_data[0] = vec4(diff.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index 50020a50d8..0c386ade6c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -25,24 +25,12 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
void main()
{
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
index 91b25613e0..5c64d48399 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl
@@ -27,13 +27,9 @@ uniform mat4 projection_matrix;
mat4 getSkinnedTransform();
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
void main()
{
@@ -53,13 +49,7 @@ void main()
norm = normalize(norm);
pos = projection_matrix * pos;
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
index 1bd8fee7c9..bc0c11ec46 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl
@@ -25,16 +25,16 @@
uniform mat4 projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
mat4 getSkinnedTransform();
-ATTRIBUTE vec4 weight;
+in vec4 weight;
-VARYING vec3 vary_normal;
-VARYING vec2 vary_texcoord0;
+out vec3 vary_normal;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index 596d0274af..08baf98686 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -23,26 +23,21 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
+uniform sampler2D normalMap;
+uniform sampler2D lightMap;
uniform float dist_factor;
uniform float blur_size;
uniform vec2 delta;
+uniform vec2 screen_res;
uniform vec3 kern[4];
uniform float kern_scale;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
vec4 getPosition(vec2 pos_screen);
vec3 getNorm(vec2 pos_screen);
@@ -52,8 +47,8 @@ void main()
vec2 tc = vary_fragcoord.xy;
vec3 norm = getNorm(tc);
vec3 pos = getPosition(tc).xyz;
- vec4 ccol = texture2DRect(lightMap, tc).rgba;
-
+ vec4 ccol = texture(lightMap, tc).rgba;
+
vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
@@ -64,43 +59,57 @@ void main()
float pointplanedist_tolerance_pow2 = pos.z*pos.z*0.00005;
// perturb sampling origin slightly in screen-space to hide edge-ghosting artifacts where smoothing radius is quite large
- float tc_mod = 0.5*(tc.x + tc.y); // mod(tc.x+tc.y,2)
+ tc *= screen_res;
+ float tc_mod = 0.5*(tc.x + tc.y);
tc_mod -= floor(tc_mod);
tc_mod *= 2.0;
tc += ( (tc_mod - 0.5) * kern[1].z * dlt * 0.5 );
- for (int i = 1; i < 4; i++)
+ // TODO: move this to kern instead of building kernel per pixel
+ vec3 k[7];
+ k[0] = kern[0];
+ k[2] = kern[1];
+ k[4] = kern[2];
+ k[6] = kern[3];
+
+ k[1] = (k[0]+k[2])*0.5f;
+ k[3] = (k[2]+k[4])*0.5f;
+ k[5] = (k[4]+k[6])*0.5f;
+
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc + kern[i].z*dlt;
+ vec2 samptc = tc + k[i].z*dlt*2.0;
+ samptc /= screen_res;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
- for (int i = 1; i < 4; i++)
+ for (int i = 1; i < 7; i++)
{
- vec2 samptc = tc - kern[i].z*dlt;
+ vec2 samptc = tc - k[i].z*dlt*2.0;
+ samptc /= screen_res;
vec3 samppos = getPosition(samptc).xyz;
float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
if (d*d <= pointplanedist_tolerance_pow2)
{
- col += texture2DRect(lightMap, samptc)*kern[i].xyxx;
- defined_weight += kern[i].xy;
+ col += texture(lightMap, samptc)*k[i].xyxx;
+ defined_weight += k[i].xy;
}
}
col /= defined_weight.xyxx;
- col.y *= col.y;
+ //col.y *= col.y;
- frag_color = col;
+ frag_color = max(col, vec4(0));
#ifdef IS_AMD_CARD
// If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts.
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
index 212f7e56ad..5abaa1f2a6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightV.glsl
@@ -23,17 +23,15 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
+in vec3 position;
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
+out vec2 vary_fragcoord;
uniform vec2 screen_res;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vary_fragcoord = (pos.xy*0.5+0.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index b5677a07ee..35f483f633 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -25,28 +25,24 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
uniform sampler2D bumpMap;
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
+in vec3 vary_mat0;
+in vec3 vary_mat1;
+in vec3 vary_mat2;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void main()
{
- vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if(col.a < minimum_alpha)
{
@@ -54,7 +50,7 @@ void main()
}
col *= vertex_color;
- vec3 norm = texture2D(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
+ vec3 norm = texture(bumpMap, vary_texcoord0.xy).rgb * 2.0 - 1.0;
vec3 tnorm = vec3(dot(norm,vary_mat0),
dot(norm,vary_mat1),
@@ -64,5 +60,6 @@ void main()
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(tnorm);
- frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
index d90891aa20..3af2eab1e4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl
@@ -27,17 +27,17 @@ uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 tangent;
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec2 texcoord0;
+in vec4 tangent;
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec3 vary_mat0;
+out vec3 vary_mat1;
+out vec3 vary_mat2;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
deleted file mode 100644
index 0157d166e0..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale >= 0.0001)
- {
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
index ae1ac5de7f..f6870c3ff0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsF.glsl
@@ -24,41 +24,34 @@
*/
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
+in vec3 vary_CloudColorSun;
+in vec3 vary_CloudColorAmbient;
+in float vary_CloudDensity;
uniform sampler2D cloud_noise_texture;
uniform sampler2D cloud_noise_texture_next;
uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
+uniform vec3 cloud_pos_density1;
+uniform vec3 cloud_pos_density2;
uniform float cloud_scale;
uniform float cloud_variance;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING float altitude_blend_factor;
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
+in vec2 vary_texcoord0;
+in vec2 vary_texcoord1;
+in vec2 vary_texcoord2;
+in vec2 vary_texcoord3;
+in float altitude_blend_factor;
vec4 cloudNoise(vec2 uv)
{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
+ vec4 a = texture(cloud_noise_texture, uv);
+ vec4 b = texture(cloud_noise_texture_next, uv);
vec4 cloud_noise_sample = mix(a, b, blend_factor);
return cloud_noise_sample;
}
@@ -69,8 +62,8 @@ void main()
vec2 uv1 = vary_texcoord0.xy;
vec2 uv2 = vary_texcoord1.xy;
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
+ vec3 cloudColorSun = vary_CloudColorSun;
+ vec3 cloudColorAmbient = vary_CloudColorAmbient;
float cloudDensity = vary_CloudDensity;
vec2 uv3 = vary_texcoord2.xy;
vec2 uv4 = vary_texcoord3.xy;
@@ -115,17 +108,15 @@ void main()
alpha2 = 1. - alpha2 * alpha2;
// Combine
- vec4 color;
+ vec3 color;
color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color.rgb= max(vec3(0), color.rgb);
+ color.rgb = clamp(color.rgb, vec3(0), vec3(1));
color.rgb *= 2.0;
- color.rgb = scaleSoftClip(color.rgb);
/// Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, alpha1);
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0,0,0,1);
-
- gl_FragDepth = 0.99995f;
+ frag_data[2] = vec4(0,0,0,GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = vec4(color.rgb, alpha1);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index 8e0a001403..98314d39d3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -25,34 +25,34 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
//////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
+out vec3 vary_CloudColorSun;
+out vec3 vary_CloudColorAmbient;
+out float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING float altitude_blend_factor;
+out vec2 vary_texcoord0;
+out vec2 vary_texcoord1;
+out vec2 vary_texcoord2;
+out vec2 vary_texcoord3;
+out float altitude_blend_factor;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -60,10 +60,10 @@ uniform float cloud_shadow;
uniform float density_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform vec3 cloud_color;
uniform float cloud_scale;
@@ -114,17 +114,17 @@ void main()
float rel_pos_len = length(rel_pos);
// Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
+ vec3 sunlight = sunlight_color;
+ vec3 light_atten;
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -155,18 +155,18 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
// Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
+ vec3 tmpAmbient = ambient_color;
tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= (1. - cloud_shadow);
// Haze color below cloud
- vec4 additiveColorBelowCloud =
+ vec3 additiveColorBelowCloud =
(blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
// CLOUDS
- sunlight = sunlight_color; // SL-14707 reset color -- Clouds are unusually dim in EEP
+ sunlight = sunlight_color;
off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
sunlight *= exp(-light_atten * off_axis);
@@ -178,7 +178,7 @@ void main()
combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
vary_CloudColorSun *= combined_haze;
vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
+ vec3 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
// Make a nice cloud density based on the cloud_shadow value that was passed in.
vary_CloudDensity = 2. * (cloud_shadow - 0.25);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
index 079d8458c9..d95a33a6be 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cofF.glsl
@@ -23,19 +23,12 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect depthMap;
-uniform sampler2D bloomMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D depthMap;
uniform float depth_cutoff;
uniform float norm_cutoff;
@@ -48,7 +41,7 @@ uniform float max_cof;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
float calc_cof(float depth)
{
@@ -69,19 +62,18 @@ void main()
{
vec2 tc = vary_fragcoord.xy;
- float z = texture2DRect(depthMap, tc).r;
+ float z = texture(depthMap, tc).r;
z = z*2.0-1.0;
vec4 ndc = vec4(0.0, 0.0, z, 1.0);
vec4 p = inv_proj*ndc;
float depth = p.z/p.w;
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
+ vec4 diff = texture(diffuseRect, vary_fragcoord.xy);
float sc = calc_cof(depth);
sc = min(sc, max_cof);
sc = max(sc, -max_cof);
- vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
- frag_color.rgb = diff.rgb + bloom.rgb;
+ frag_color.rgb = diff.rgb;
frag_color.a = sc/max_cof*0.5+0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
index e27bbce094..f9ebf33b4a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl
@@ -23,25 +23,128 @@
* $/LicenseInfo$
*/
-uniform sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
+
+/* Parts of this file are taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+uniform sampler2D normalMap;
+uniform sampler2D depthMap;
+uniform sampler2D projectionMap; // rgba
+uniform sampler2D brdfLut;
+
+// projected lighted params
+uniform mat4 proj_mat; //screen space to light space projector
+uniform vec3 proj_n; // projector normal
+uniform vec3 proj_p; //plane projection is emitting from (in screen space)
+uniform float proj_focus; // distance from plane to begin blurring
+uniform float proj_lod ; // (number of mips in proj map)
+uniform float proj_range; // range between near clip and far clip plane of projection
+uniform float proj_ambiance;
+
+// light params
+uniform vec3 color; // light_color
+uniform float size; // light_size
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec2 getScreenCoordinate(vec2 screenpos)
+const float M_PI = 3.14159265;
+const float ONE_OVER_PI = 0.3183098861;
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+
+float calcLegacyDistanceAttenuation(float distance, float falloff)
{
- vec2 sc = screenpos.xy * 2.0;
- if (screen_res.x > 0 && screen_res.y > 0)
+ float dist_atten = 1.0 - clamp((distance + falloff)/(1.0 + falloff), 0.0, 1.0);
+ dist_atten *= dist_atten;
+
+ // Tweak falloff slightly to match pre-EEP attenuation
+ // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
+ dist_atten *= 2.0;
+ return dist_atten;
+}
+
+// In:
+// lv unnormalized surface to light vector
+// n normal of the surface
+// pos unnormalized camera to surface vector
+// Out:
+// l normalized surace to light vector
+// nl diffuse angle
+// nh specular angle
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v,
+ out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist)
+{
+ l = normalize(lv);
+ h = normalize(l + v);
+ nh = clamp(dot(n, h), 0.0, 1.0);
+ nl = clamp(dot(n, l), 0.0, 1.0);
+ nv = clamp(dot(n, v), 0.0, 1.0);
+ vh = clamp(dot(v, h), 0.0, 1.0);
+
+ lightDist = length(lv);
+}
+
+// In:
+// light_center
+// pos
+// Out:
+// dist
+// l_dist
+// lv
+// proj_tc Projector Textue Coordinates
+bool clipProjectedLightVars(vec3 light_center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc )
+{
+ lv = light_center - pos.xyz;
+ dist = length(lv);
+ bool clipped = (dist >= size);
+ if ( !clipped )
{
- sc /= screen_res;
+ dist /= size;
+
+ l_dist = -dot(lv, proj_n);
+ vec4 projected_point = (proj_mat * vec4(pos.xyz, 1.0));
+ clipped = (projected_point.z < 0.0);
+ projected_point.xyz /= projected_point.w;
+ proj_tc = projected_point;
}
+
+ return clipped;
+}
+
+vec2 getScreenCoordinate(vec2 screenpos)
+{
+ vec2 sc = screenpos.xy * 2.0;
return sc - vec2(1.0, 1.0);
}
+// See: https://aras-p.info/texts/CompactNormalStorage.html
+// Method #4: Spheremap Transform, Lambert Azimuthal Equal-Area projection
vec3 getNorm(vec2 screenpos)
{
- vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
+ vec2 enc = texture(normalMap, screenpos.xy).xy;
vec2 fenc = enc*4-2;
float f = dot(fenc,fenc);
float g = sqrt(1-f/4);
@@ -51,12 +154,160 @@ vec3 getNorm(vec2 screenpos)
return n;
}
+vec3 getNormalFromPacked(vec4 packedNormalEnvIntensityFlags)
+{
+ vec2 enc = packedNormalEnvIntensityFlags.xy;
+ vec2 fenc = enc*4-2;
+ float f = dot(fenc,fenc);
+ float g = sqrt(1-f/4);
+ vec3 n;
+ n.xy = fenc*g;
+ n.z = 1-f/2;
+ return normalize(n); // TODO: Is this normalize redundant?
+}
+
+// return packedNormalEnvIntensityFlags since GBUFFER_FLAG_HAS_PBR needs .w
+// See: C++: addDeferredAttachments(), GLSL: softenLightF
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity)
+{
+ vec4 packedNormalEnvIntensityFlags = texture(normalMap, screenpos.xy);
+ n = getNormalFromPacked( packedNormalEnvIntensityFlags );
+ envIntensity = packedNormalEnvIntensityFlags.z;
+ return packedNormalEnvIntensityFlags;
+}
+
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar)
+{
+ d = d * 2.0 - 1.0;
+ return znear * 2.0 * zfar / (zfar + znear - d * (zfar - znear));
+}
+
+float linearDepth01(float d, float znear, float zfar)
+{
+ return linearDepth(d, znear, zfar) / zfar;
+}
+
float getDepth(vec2 pos_screen)
{
- float depth = texture2DRect(depthMap, pos_screen).r;
+ float depth = texture(depthMap, pos_screen).r;
return depth;
}
+vec4 getTexture2DLodAmbient(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = tc-vec2(0.5);
+ float d = dot(dist,dist);
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+vec4 getTexture2DLodDiffuse(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// lit This is set by the caller: if (nl > 0.0) { lit = attenuation * nl * noise; }
+// Uses:
+// color Projected spotlight color
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv)
+{
+ vec4 amb_plcol = getTexture2DLodAmbient(projected_uv, proj_lod);
+ vec3 amb_rgb = amb_plcol.rgb * amb_plcol.a;
+
+ amb_da += proj_ambiance;
+ amb_da += (nl*nl*0.5+0.5) * proj_ambiance;
+ amb_da *= attenuation * noise;
+ amb_da = min(amb_da, 1.0-lit);
+
+ return (amb_da * color.rgb * amb_rgb);
+}
+
+// Returns projected light in Linear
+// Uses global spotlight color:
+// color
+// NOTE: projected.a will be pre-multiplied with projected.rgb
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod);
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
+vec4 texture2DLodSpecular(vec2 tc, float lod)
+{
+#ifndef FXAA_GLSL_120
+ vec4 ret = textureLod(projectionMap, tc, lod);
+#else
+ vec4 ret = texture(projectionMap, tc);
+#endif
+ ret.rgb = srgb_to_linear(ret.rgb);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+ float det = min(lod/(proj_lod*0.5), 1.0);
+ float d = min(dist.x, dist.y);
+ d *= min(1, d * (proj_lod - lod)); // BUG? extra factor compared to diffuse causes N repeats
+ float edge = 0.25*det;
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+// See: clipProjectedLightVars()
+vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n )
+{
+ vec3 slit = vec3(0);
+ vec3 ref = reflect(normalize(pos), n);
+
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float l_dist = length(pdelta);
+ float ds = dot(ref, proj_n);
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ if (stc.z > 0.0)
+ {
+ stc /= stc.w;
+ slit = getProjectedLightDiffuseColor( l_dist, stc.xy ); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+ }
+ }
+ return slit; // specular light
+}
+
+vec3 getProjectedLightSpecularColor(float light_distance, vec2 projected_uv)
+{
+ float diff = clamp((light_distance - proj_focus)/proj_range, 0.0, 1.0);
+ float lod = diff * proj_lod;
+ vec4 plcol = getTexture2DLodDiffuse(projected_uv.xy, lod); // NOTE: Using diffuse due to texture2DLodSpecular() has extra: d *= min(1, d * (proj_lod - lod));
+
+ return color.rgb * plcol.rgb * plcol.a;
+}
+
vec4 getPosition(vec2 pos_screen)
{
float depth = getDepth(pos_screen);
@@ -68,12 +319,246 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+// get position given a normalized device coordinate
+vec3 getPositionWithNDC(vec3 ndc)
+{
+ vec4 pos = inv_proj * vec4(ndc, 1.0);
+ return pos.xyz / pos.w;
+}
+
vec4 getPositionWithDepth(vec2 pos_screen, float depth)
{
vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
+ vec3 ndc = vec3(sc.x, sc.y, 2.0*depth-1.0);
+ return vec4(getPositionWithNDC(ndc), 1.0);
+}
+
+vec2 getScreenCoord(vec4 clip)
+{
+ vec4 ndc = clip;
+ ndc.xyz /= clip.w;
+ vec2 screen = vec2( ndc.xy * 0.5 );
+ screen += 0.5;
+ return screen;
+}
+
+vec2 getScreenXY(vec4 clip)
+{
+ vec4 ndc = clip;
+ ndc.xyz /= clip.w;
+ vec2 screen = vec2( ndc.xy * 0.5 );
+ screen += 0.5;
+ screen *= screen_res;
+ return screen;
+}
+
+// Color utils
+
+vec3 colorize_dot(float x)
+{
+ if (x > 0.0) return vec3( 0, x, 0 );
+ if (x < 0.0) return vec3(-x, 0, 0 );
+ return vec3( 0, 0, 1 );
}
+
+vec3 hue_to_rgb(float hue)
+{
+ if (hue > 1.0) return vec3(0.5);
+ vec3 rgb = abs(hue * 6. - vec3(3, 2, 4)) * vec3(1, -1, -1) + vec3(-1, 2, 2);
+ return clamp(rgb, 0.0, 1.0);
+}
+
+// PBR Utils
+
+vec2 BRDF(float NoV, float roughness)
+{
+ return texture(brdfLut, vec2(NoV, roughness)).rg;
+}
+
+// set colorDiffuse and colorSpec to the results of GLTF PBR style IBL
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRough)
+{
+ // retrieve a scale and bias to F0. See [1], Figure 3
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0-perceptualRough);
+ vec3 diffuseLight = irradiance;
+ vec3 specularLight = radiance;
+
+ vec3 diffuse = diffuseLight * diffuseColor;
+ vec3 specular = specularLight * (specularColor * brdf.x + brdf.y);
+
+ return (diffuse + specular) * ao;
+}
+
+
+// Encapsulate the various inputs used by the various functions in the shading equation
+// We store values in this struct to simplify the integration of alternative implementations
+// of the shading terms, outlined in the Readme.MD Appendix.
+struct PBRInfo
+{
+ float NdotL; // cos angle between normal and light direction
+ float NdotV; // cos angle between normal and view direction
+ float NdotH; // cos angle between normal and half vector
+ float LdotH; // cos angle between light direction and half vector
+ float VdotH; // cos angle between view direction and half vector
+ float perceptualRoughness; // roughness value, as authored by the model creator (input to shader)
+ float metalness; // metallic value at the surface
+ vec3 reflectance0; // full reflectance color (normal incidence angle)
+ vec3 reflectance90; // reflectance color at grazing angle
+ float alphaRoughness; // roughness mapped to a more linear change in the roughness (proposed by [2])
+ vec3 diffuseColor; // color contribution from diffuse lighting
+ vec3 specularColor; // color contribution from specular lighting
+};
+
+// Basic Lambertian diffuse
+// Implementation from Lambert's Photometria https://archive.org/details/lambertsphotome00lambgoog
+// See also [1], Equation 1
+vec3 diffuse(PBRInfo pbrInputs)
+{
+ return pbrInputs.diffuseColor / M_PI;
+}
+
+// The following equation models the Fresnel reflectance term of the spec equation (aka F())
+// Implementation of fresnel from [4], Equation 15
+vec3 specularReflection(PBRInfo pbrInputs)
+{
+ return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0);
+}
+
+// This calculates the specular geometric attenuation (aka G()),
+// where rougher material will reflect less light back to the viewer.
+// This implementation is based on [1] Equation 4, and we adopt their modifications to
+// alphaRoughness as input as originally proposed in [2].
+float geometricOcclusion(PBRInfo pbrInputs)
+{
+ float NdotL = pbrInputs.NdotL;
+ float NdotV = pbrInputs.NdotV;
+ float r = pbrInputs.alphaRoughness;
+
+ float attenuationL = 2.0 * NdotL / (NdotL + sqrt(r * r + (1.0 - r * r) * (NdotL * NdotL)));
+ float attenuationV = 2.0 * NdotV / (NdotV + sqrt(r * r + (1.0 - r * r) * (NdotV * NdotV)));
+ return attenuationL * attenuationV;
+}
+
+// The following equation(s) model the distribution of microfacet normals across the area being drawn (aka D())
+// Implementation from "Average Irregularity Representation of a Roughened Surface for Ray Reflection" by T. S. Trowbridge, and K. P. Reitz
+// Follows the distribution function recommended in the SIGGRAPH 2013 course notes from EPIC Games [1], Equation 3.
+float microfacetDistribution(PBRInfo pbrInputs)
+{
+ float roughnessSq = pbrInputs.alphaRoughness * pbrInputs.alphaRoughness;
+ float f = (pbrInputs.NdotH * roughnessSq - pbrInputs.NdotH) * pbrInputs.NdotH + 1.0;
+ return roughnessSq / (M_PI * f * f);
+}
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l) //surface point to light
+{
+ // make sure specular highlights from punctual lights don't fall off of polished surfaces
+ perceptualRoughness = max(perceptualRoughness, 8.0/255.0);
+
+ float alphaRoughness = perceptualRoughness * perceptualRoughness;
+
+ // Compute reflectance.
+ float reflectance = max(max(specularColor.r, specularColor.g), specularColor.b);
+
+ // For typical incident reflectance range (between 4% to 100%) set the grazing reflectance to 100% for typical fresnel effect.
+ // For very low reflectance range on highly diffuse objects (below 4%), incrementally reduce grazing reflecance to 0%.
+ float reflectance90 = clamp(reflectance * 25.0, 0.0, 1.0);
+ vec3 specularEnvironmentR0 = specularColor.rgb;
+ vec3 specularEnvironmentR90 = vec3(1.0, 1.0, 1.0) * reflectance90;
+
+ vec3 h = normalize(l+v); // Half vector between both l and v
+ vec3 reflection = -normalize(reflect(v, n));
+ reflection.y *= -1.0f;
+
+ float NdotL = clamp(dot(n, l), 0.001, 1.0);
+ float NdotV = clamp(abs(dot(n, v)), 0.001, 1.0);
+ float NdotH = clamp(dot(n, h), 0.0, 1.0);
+ float LdotH = clamp(dot(l, h), 0.0, 1.0);
+ float VdotH = clamp(dot(v, h), 0.0, 1.0);
+
+ PBRInfo pbrInputs = PBRInfo(
+ NdotL,
+ NdotV,
+ NdotH,
+ LdotH,
+ VdotH,
+ perceptualRoughness,
+ metallic,
+ specularEnvironmentR0,
+ specularEnvironmentR90,
+ alphaRoughness,
+ diffuseColor,
+ specularColor
+ );
+
+ // Calculate the shading terms for the microfacet specular shading model
+ vec3 F = specularReflection(pbrInputs);
+ float G = geometricOcclusion(pbrInputs);
+ float D = microfacetDistribution(pbrInputs);
+
+ // Calculation of analytical lighting contribution
+ vec3 diffuseContrib = (1.0 - F) * diffuse(pbrInputs);
+ vec3 specContrib = F * G * D / (4.0 * NdotL * NdotV);
+ // Obtain final intensity as reflectance (BRDF) scaled by the energy of the light (cosine law)
+ vec3 color = NdotL * (diffuseContrib + specContrib);
+
+ return clamp(color, vec3(0), vec3(10));
+}
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor)
+{
+ vec3 f0 = vec3(0.04);
+ diffuseColor = baseColor*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+ specularColor = mix(f0, baseColor, metallic);
+}
+
+vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, vec3 norm, float perceptualRoughness, vec3 light_dir, vec3 sunlit, float scol, vec3 radiance, vec3 irradiance, vec3 colorEmissive, float ao, vec3 additive, vec3 atten)
+{
+ vec3 color = vec3(0);
+
+ float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
+
+ color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness);
+
+ color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir)) * sunlit * 3.0 * scol; //magic number to balance with legacy materials
+
+ color += colorEmissive;
+
+ return color;
+}
+
+uniform vec4 waterPlane;
+uniform float waterSign;
+
+// discard if given position in eye space is on the wrong side of the waterPlane according to waterSign
+void waterClip(vec3 pos)
+{
+ // TODO: make this less branchy
+ if (waterSign > 0)
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) < 0.0)
+ {
+ discard;
+ }
+ }
+ else
+ {
+ if ((dot(pos.xyz, waterPlane.xyz) + waterPlane.w) > 0.0)
+ {
+ discard;
+ }
+ }
+
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
index b328ee9483..6f3b94f734 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskF.glsl
@@ -25,25 +25,21 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_normal;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void main()
{
- vec4 col = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy) * vertex_color;
if (col.a < minimum_alpha)
{
@@ -53,6 +49,7 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
index fc5c86b4d6..e5f2af2c53 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskIndexedF.glsl
@@ -25,18 +25,14 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
-VARYING vec3 vary_normal;
+in vec3 vary_normal;
uniform float minimum_alpha;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
@@ -52,5 +48,6 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
index 1bb8eb8bd0..234f096ed5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseAlphaMaskNoColorF.glsl
@@ -25,24 +25,20 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec3 vary_normal;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_normal;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void main()
{
- vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if (col.a < minimum_alpha)
{
@@ -52,6 +48,7 @@ void main()
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 8319e61242..68fb8bf499 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -25,27 +25,24 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform sampler2D diffuseMap;
-VARYING vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_normal;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
void main()
{
- vec3 col = vertex_color.rgb * texture2D(diffuseMap, vary_texcoord0.xy).rgb;
+ vec3 col = vertex_color.rgb * texture(diffuseMap, vary_texcoord0.xy).rgb;
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vertex_color.aaaa; // spec
//frag_data[1] = vec4(vec3(vertex_color.a), vertex_color.a+(1.0-vertex_color.a)*vertex_color.a); // spec - from former class3 - maybe better, but not so well tested
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
index ccd1df84f9..93d561504e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseIndexedF.glsl
@@ -25,15 +25,11 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
-VARYING vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_normal;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec2 encode_normal(vec3 n);
vec3 linear_to_srgb(vec3 c);
@@ -48,5 +44,6 @@ void main()
frag_data[0] = vec4(col, 0.0);
frag_data[1] = vec4(spec, vertex_color.a); // spec
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), vertex_color.a, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
index 9461e3e32e..13cc612fab 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseNoColorV.glsl
@@ -27,13 +27,13 @@ uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec3 vary_normal;
+out vec3 vary_normal;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
index d64bcefade..2402cc3b70 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl
@@ -27,15 +27,15 @@ uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec3 vary_normal;
+out vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
index 8d48bb016b..3b9b8ae696 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/dofCombineF.glsl
@@ -23,18 +23,12 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect lightMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D lightMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -44,14 +38,14 @@ uniform float res_scale;
uniform float dof_width;
uniform float dof_height;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
-vec4 dofSample(sampler2DRect tex, vec2 tc)
+vec4 dofSample(sampler2D tex, vec2 tc)
{
tc.x = min(tc.x, dof_width);
tc.y = min(tc.y, dof_height);
- return texture2DRect(tex, tc);
+ return texture(tex, tc);
}
void main()
@@ -60,7 +54,7 @@ void main()
vec4 dof = dofSample(diffuseRect, vary_fragcoord.xy*res_scale);
- vec4 diff = texture2DRect(lightMap, vary_fragcoord.xy);
+ vec4 diff = texture(lightMap, vary_fragcoord.xy);
float a = min(abs(diff.a*2.0-1.0) * max_cof*res_scale*res_scale, 1.0);
@@ -69,10 +63,10 @@ void main()
float sc = a/res_scale;
vec4 col;
- col = texture2DRect(lightMap, vary_fragcoord.xy+vec2(sc,sc));
- col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(-sc,sc));
- col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(sc,-sc));
- col += texture2DRect(lightMap, vary_fragcoord.xy+vec2(-sc,-sc));
+ col = texture(lightMap, vary_fragcoord.xy+vec2(sc,sc)/screen_res);
+ col += texture(lightMap, vary_fragcoord.xy+vec2(-sc,sc)/screen_res);
+ col += texture(lightMap, vary_fragcoord.xy+vec2(sc,-sc)/screen_res);
+ col += texture(lightMap, vary_fragcoord.xy+vec2(-sc,-sc)/screen_res);
diff = mix(diff, col*0.25, a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
index f0522850de..9e61b6b894 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveF.glsl
@@ -23,31 +23,17 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void main()
{
- float shadow = 1.0;
-
- vec4 color = diffuseLookup(vary_texcoord0.xy)*vertex_color;
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
-
- frag_color = color;
+ // NOTE: when this shader is used, only alpha is being written to
+ float a = diffuseLookup(vary_texcoord0.xy).a*vertex_color.a;
+ frag_color = vec4(0, 0, 0, a);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
index 08b1147ab0..5a0913a970 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/emissiveV.glsl
@@ -27,18 +27,18 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
void passTextureIndex();
-ATTRIBUTE vec4 emissive;
-ATTRIBUTE vec2 texcoord0;
+in vec4 emissive;
+in vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
index 44f2a73e1f..9ac4ceb37e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl
@@ -1,9 +1,9 @@
/**
- * @file shadowAlphaMaskF.glsl
+ * @file exposureF.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,34 +22,40 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2D diffuseMap;
+uniform sampler2D emissiveRect;
+uniform sampler2D exposureMap;
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
+uniform float dt;
+uniform vec2 noiseVec;
-VARYING float pos_w;
+uniform vec3 dynamic_exposure_params;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+float lum(vec3 col)
+{
+ vec3 l = vec3(0.2126, 0.7152, 0.0722);
+ return dot(l, col);
+}
void main()
{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+ vec2 tc = vec2(0.5,0.5);
- frag_color = vec4(alpha, alpha, alpha, 1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
+ float L = textureLod(emissiveRect, tc, 8).r;
+ float max_L = dynamic_exposure_params.x;
+ L = clamp(L, 0.0, max_L);
+ L /= max_L;
+ L = pow(L, 2.0);
+ float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L);
+
+ float prev = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ s = mix(prev, s, min(dt*2.0*abs(prev-s), 0.04));
+
+ frag_color = max(vec4(s, s, s, dt), vec4(0.0));
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index 57420158ca..5d58cc91cd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -23,23 +23,17 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
#if !defined(HAS_DIFFUSE_LOOKUP)
uniform sampler2D diffuseMap;
#endif
-VARYING vec3 vary_position;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec3 vary_position;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
#ifdef WATER_FOG
vec4 applyWaterFogView(vec3 pos, vec4 color);
@@ -47,42 +41,65 @@ vec4 applyWaterFogView(vec3 pos, vec4 color);
vec3 srgb_to_linear(vec3 cs);
vec3 linear_to_srgb(vec3 cl);
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
#ifdef HAS_ALPHA_MASK
uniform float minimum_alpha;
#endif
+#ifdef IS_ALPHA
+void waterClip(vec3 pos);
+#endif
+
void main()
{
+
+#ifdef IS_ALPHA
+ waterClip(vary_position.xyz);
+#endif
+
#ifdef HAS_DIFFUSE_LOOKUP
- vec4 color = diffuseLookup(vary_texcoord0.xy);
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
#else
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 color = texture(diffuseMap, vary_texcoord0.xy);
#endif
- float final_alpha = color.a * vertex_color.a;
+ float final_alpha = color.a * vertex_color.a;
#ifdef HAS_ALPHA_MASK
- if (color.a < minimum_alpha)
- {
- discard;
- }
+ if (color.a < minimum_alpha)
+ {
+ discard;
+ }
#endif
- color.rgb *= vertex_color.rgb;
+ color.rgb *= vertex_color.rgb;
+
+ vec3 pos = vary_position;
+
+#ifndef IS_HUD
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
+#endif
#ifdef WATER_FOG
- vec3 pos = vary_position;
- vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
- color.rgb = fogged.rgb;
- color.a = fogged.a;
+
+ vec4 fogged = applyWaterFogView(pos, vec4(color.rgb, final_alpha));
+ color.rgb = fogged.rgb;
+ color.a = fogged.a;
#else
color.a = final_alpha;
#endif
- frag_color.rgb = color.rgb;
- frag_color.a = color.a;
+#ifndef IS_HUD
+ color.rgb = srgb_to_linear(color.rgb);
+ color.rgb = atmosFragLighting(color.rgb, additive, atten);
+#endif
+
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
deleted file mode 100644
index 9fcee04c32..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ /dev/null
@@ -1,106 +0,0 @@
-/**
- * @file fullbrightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-#ifndef HAS_DIFFUSE_LOOKUP
-uniform sampler2D diffuseMap;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
-
-uniform samplerCube environmentMap;
-
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
-uniform int no_atmo;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-vec3 linear_to_srgb(vec3 c);
-vec3 srgb_to_linear(vec3 c);
-
-// See:
-// class1\deferred\fullbrightShinyF.glsl
-// class1\lighting\lightFullbrightShinyF.glsl
-void main()
-{
-#ifdef HAS_DIFFUSE_LOOKUP
- vec4 color = diffuseLookup(vary_texcoord0.xy);
-#else
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
-#endif
-
- color.rgb *= vertex_color.rgb;
-
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 0)
- {
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
- vec3 pos = vary_position.xyz/vary_position.w;
-
- calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- float env_intensity = vertex_color.a;
-
- //color.rgb = srgb_to_linear(color.rgb);
- color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
- color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- }
-
-/*
- // NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
- else
- {
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- float env_intensity = vertex_color.a;
- color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
- }
-*/
-
- color.a = 1.0;
-
- //color.rgb = linear_to_srgb(color.rgb);
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
index 3bd6b693fa..5795384b47 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyV.glsl
@@ -36,16 +36,16 @@ uniform vec4 origin;
-ATTRIBUTE vec3 position;
+in vec3 position;
void passTextureIndex();
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 normal;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-VARYING vec4 vary_position;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
+out vec3 vary_texcoord1;
+out vec3 vary_position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
@@ -62,17 +62,18 @@ void main()
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
vec4 pos = mat * vert;
- vary_position = gl_Position = projection_matrix * pos;
+ gl_Position = projection_matrix * pos;
vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#else
vec4 pos = (modelview_matrix * vert);
- vary_position = gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vec3 norm = normalize(normal_matrix * normal);
#endif
- vec3 ref = reflect(pos.xyz, -norm);
+ vary_position = pos.xyz;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz;
+
+ vary_texcoord1 = norm;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
index e71636f2c9..77e63e6360 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl
@@ -28,22 +28,20 @@ uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
void passTextureIndex();
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec4 diffuse_color;
+in vec2 texcoord0;
void calcAtmospherics(vec3 inPositionEye);
vec3 atmosAmbient();
vec3 atmosAffectDirectionalLight(float lightIntensity);
-#ifdef WATER_FOG
-VARYING vec3 vary_position;
-#endif
+out vec3 vary_position;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
@@ -66,9 +64,7 @@ void main()
gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
#endif
-#ifdef WATER_FOG
vary_position = pos.xyz;
-#endif
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
index 226e63cdda..cd56ed0adf 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fxaaF.glsl
@@ -28,11 +28,7 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
#define FXAA_PC 1
//#define FXAA_GLSL_130 1
@@ -2092,12 +2088,13 @@ half4 FxaaPixelShader(
#endif
uniform sampler2D diffuseMap;
+uniform sampler2D depthMap;
uniform vec2 rcp_screen_res;
uniform vec4 rcp_frame_opt;
uniform vec4 rcp_frame_opt2;
-VARYING vec2 vary_fragcoord;
-VARYING vec2 vary_tc;
+in vec2 vary_fragcoord;
+in vec2 vary_tc;
void main()
{
@@ -2120,8 +2117,7 @@ void main()
- //diff = texture2D(diffuseMap, vary_tc);
-
- frag_color = diff;
-
+ frag_color = diff;
+
+ gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
new file mode 100644
index 0000000000..e40d070268
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutF.glsl
@@ -0,0 +1,141 @@
+/**
+ * @file class1/deferred/genbrdflut.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/* Taken from Sascha Willem's Vulkan GLTF refernce implementation
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+in vec2 vary_uv;
+
+out vec4 outColor;
+
+#define NUM_SAMPLES 1024u
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Geometric Shadowing function
+float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
+{
+ float k = (roughness * roughness) / 2.0;
+ float GL = dotNL / (dotNL * (1.0 - k) + k);
+ float GV = dotNV / (dotNV * (1.0 - k) + k);
+ return GL * GV;
+}
+
+vec2 BRDF(float NoV, float roughness)
+{
+ // Normal always points along z-axis for the 2D lookup
+ const vec3 N = vec3(0.0, 0.0, 1.0);
+ vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
+
+ vec2 LUT = vec2(0.0);
+ for(uint i = 0u; i < NUM_SAMPLES; i++) {
+ vec2 Xi = hammersley2d(i, NUM_SAMPLES);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+
+ float dotNL = max(dot(N, L), 0.0);
+ float dotNV = max(dot(N, V), 0.0);
+ float dotVH = max(dot(V, H), 0.0);
+ float dotNH = max(dot(H, N), 0.0);
+
+ if (dotNL > 0.0) {
+ float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
+ float G_Vis = (G * dotVH) / (dotNH * dotNV);
+ float Fc = pow(1.0 - dotVH, 5.0);
+ LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
+ }
+ }
+ return LUT / float(NUM_SAMPLES);
+}
+
+void main()
+{
+ outColor = vec4(BRDF(vary_uv.s, 1.0-vary_uv.t), 0.0, 1.0);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
index eefefa640d..3a1572996f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/genbrdflutV.glsl
@@ -1,9 +1,9 @@
/**
- * @file multiPointLightV.glsl
+ * @file class3\deferred\genbrdflutV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,15 +25,15 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
-VARYING vec4 vary_fragcoord;
+out vec2 vary_uv;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_fragcoord = pos;
+ vary_uv = position.xy*0.5+0.5;
- gl_Position = pos;
+ gl_Position = vec4(position.xyz, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
index 90566393d2..748fcbed80 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/highlightF.glsl
@@ -23,20 +23,17 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform vec4 color;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- frag_data[0] = color*texture2D(diffuseMap, vary_texcoord0.xy);
+ frag_data[0] = color*texture(diffuseMap, vary_texcoord0.xy);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index a58cc3d12d..aae595f619 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -25,11 +25,7 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform float minimum_alpha;
@@ -38,23 +34,25 @@ uniform sampler2D diffuseMap;
uniform sampler2D normalMap;
uniform sampler2D specularMap;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
vec3 linear_to_srgb(vec3 c);
+vec2 encode_normal (vec3 n);
void main()
{
- vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if (col.a < minimum_alpha)
{
discard;
}
- vec4 norm = texture2D(normalMap, vary_texcoord0.xy);
- vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
+ vec4 norm = texture(normalMap, vary_texcoord0.xy);
+ vec4 spec = texture(specularMap, vary_texcoord0.xy);
frag_data[0] = vec4(col.rgb, 0.0);
frag_data[1] = spec;
- frag_data[2] = norm;
+ frag_data[2] = vec4(encode_normal(norm.xyz),0,GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
index 42266e9378..444c54a31e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorV.glsl
@@ -26,10 +26,10 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
deleted file mode 100644
index 49bfa660f8..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/indirect.glsl
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * @file class1/deferred/indirect.glsl
- *
- * $LicenseInfo:firstyear=2018&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-vec3 getIndirect(vec3 ambient, vec3 norm, vec3 pos, vec2 pos_screen)
-{
- return ambient;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
index be1003a7e0..c8afacf9bb 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl
@@ -1,9 +1,9 @@
/**
* @file luminanceF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,19 +22,31 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
+// take a luminance sample of diffuseRect and emissiveRect
+
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseMap;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
+
+uniform sampler2D diffuseRect;
+uniform sampler2D emissiveRect;
+
+float lum(vec3 col)
+{
+ vec3 l = vec3(0.2126, 0.7152, 0.0722);
+ return dot(l, col);
+}
void main()
{
- frag_color = texture2DRect(diffuseMap, vary_fragcoord.xy);
+ vec2 tc = vary_fragcoord*0.6+0.2;
+ tc.y -= 0.1; // HACK - nudge exposure sample down a little bit to favor ground over sky
+ vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb;
+ float L = lum(c);
+ frag_color = vec4(max(L, 0.0));
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
deleted file mode 100644
index f2dc60aa5d..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file giV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-
-VARYING vec2 vary_fragcoord;
-VARYING vec4 vertex_color;
-
-uniform vec2 screen_res;
-
-void main()
-{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
-
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
-
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index b30d7655db..4dee23372f 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -1,9 +1,9 @@
/**
* @file materialF.glsl
*
-* $LicenseInfo:firstyear=2007&license=viewerlgpl$
+* $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
-* Copyright (C) 2007, Linden Research, Inc.
+* Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -25,429 +25,26 @@
/*[EXTRA_CODE_HERE]*/
-//class1/deferred/materialF.glsl
+// debug stub
-// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
-
-#define DIFFUSE_ALPHA_MODE_NONE 0
#define DIFFUSE_ALPHA_MODE_BLEND 1
-#define DIFFUSE_ALPHA_MODE_MASK 2
-#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
-
-uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
-uniform int sun_up_factor;
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-vec3 srgb_to_linear(vec3 cs);
-vec3 linear_to_srgb(vec3 cs);
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
#else
-#define frag_color gl_FragColor
-#endif
-
-#ifdef HAS_SUN_SHADOW
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+out vec4 frag_data[4];
#endif
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-VARYING vec2 vary_fragcoord;
-
-VARYING vec3 vary_position;
-
-uniform mat4 proj_mat;
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-float getAmbientClamp();
-
-vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
-{
- // SL-14895 inverted attenuation work-around
- // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
- // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
- // to recover the `adjusted_radius` value previously being sent as la.
- float falloff_factor = (12.0 * fa) - 9.0;
- float inverted_la = falloff_factor / la;
- // Yes, it makes me want to cry as well. DJH
-
- vec3 col = vec3(0);
-
- //get light vector
- vec3 lv = lp.xyz - v;
-
- //get distance
- float dist = length(lv);
- float da = 1.0;
-
- dist /= inverted_la;
-
- if (dist > 0.0 && inverted_la > 0.0)
- {
- //normalize light vector
- lv = normalize(lv);
-
- //distance attenuation
- float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0f;
-
- if (dist_atten <= 0.0)
- {
- return col;
- }
-
- // spotlight coefficient.
- float spot = max(dot(-ln, lv), is_pointlight);
- da *= spot*spot; // GL_SPOT_EXPONENT=2
-
- //angular attenuation
- da *= dot(n, lv);
-
- float lit = 0.0f;
-
- float amb_da = ambiance;
- if (da >= 0)
- {
- lit = max(da * dist_atten, 0.0);
- col = lit * light_col * diffuse;
- amb_da += (da*0.5 + 0.5) * ambiance;
- }
- amb_da += (da*da*0.5 + 0.5) * ambiance;
- amb_da *= dist_atten;
- amb_da = min(amb_da, 1.0f - lit);
-
- // SL-10969 need to see why these are blown out
- //col.rgb += amb_da * light_col * diffuse;
-
- if (spec.a > 0.0)
- {
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv + npos);
- float nh = dot(n, h);
- float nv = dot(n, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
- vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
- speccol = clamp(speccol, vec3(0), vec3(1));
- col += speccol;
-
- float cur_glare = max(speccol.r, speccol.g);
- cur_glare = max(cur_glare, speccol.b);
- glare = max(glare, speccol.r);
- glare += max(cur_glare, 0.0);
- }
- }
- }
-
- return max(col, vec3(0.0, 0.0, 0.0));
-}
-
-#else
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-#endif
-
-uniform sampler2D diffuseMap; //always in sRGB space
-
-#ifdef HAS_NORMAL_MAP
-uniform sampler2D bumpMap;
-#endif
-
-#ifdef HAS_SPECULAR_MAP
-uniform sampler2D specularMap;
-
-VARYING vec2 vary_texcoord2;
-#endif
-
-uniform float env_intensity;
-uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-uniform float minimum_alpha;
-#endif
-
-#ifdef HAS_NORMAL_MAP
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
-VARYING vec2 vary_texcoord1;
-#else
-VARYING vec3 vary_normal;
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec2 encode_normal(vec3 n);
-
void main()
{
- vec2 pos_screen = vary_texcoord0.xy;
-
- vec4 diffcol = texture2D(diffuseMap, vary_texcoord0.xy);
- diffcol.rgb *= vertex_color.rgb;
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
-
- // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
- float bias = 0.001953125; // 1/512, or half an 8-bit quantization (SL-18637)
- if (diffcol.a < minimum_alpha-bias)
- {
- discard;
- }
-#endif
-
-#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
- vec3 gamma_diff = diffcol.rgb;
- diffcol.rgb = srgb_to_linear(diffcol.rgb);
-#endif
-
-#ifdef HAS_SPECULAR_MAP
- vec4 spec = texture2D(specularMap, vary_texcoord2.xy);
- spec.rgb *= specular_color.rgb;
-#else
- vec4 spec = vec4(specular_color.rgb, 1.0);
-#endif
-
-#ifdef HAS_NORMAL_MAP
- vec4 norm = texture2D(bumpMap, vary_texcoord1.xy);
-
- norm.xyz = norm.xyz * 2 - 1;
-
- vec3 tnorm = vec3(dot(norm.xyz,vary_mat0),
- dot(norm.xyz,vary_mat1),
- dot(norm.xyz,vary_mat2));
-#else
- vec4 norm = vec4(0,0,0,1.0);
- vec3 tnorm = vary_normal;
-#endif
-
- norm.xyz = normalize(tnorm.xyz);
-
- vec2 abnormal = encode_normal(norm.xyz);
-
- vec4 final_color = diffcol;
-
-#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
- final_color.a = emissive_brightness;
-#else
- final_color.a = max(final_color.a, emissive_brightness);
-#endif
-
- vec4 final_specular = spec;
-
-#ifdef HAS_SPECULAR_MAP
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity * spec.a, 0.0);
- final_specular.a = specular_color.a * norm.a;
-#else
- vec4 final_normal = vec4(encode_normal(normalize(tnorm)), env_intensity, 0.0);
- final_specular.a = specular_color.a;
-#endif
-
#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
-
- //forward rendering, output just lit sRGBA
- vec3 pos = vary_position;
-
- float shadow = 1.0f;
-
-#ifdef HAS_SUN_SHADOW
- shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, pos_screen);
-#endif
-
- spec = final_specular;
- vec4 diffuse = final_color;
- float envIntensity = final_normal.z;
-
- vec3 color = vec3(0,0,0);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
-
- float bloom = 0.0;
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
-
- // This call breaks the Mac GLSL compiler/linker for unknown reasons (17Mar2020)
- // The call is either a no-op or a pure (pow) gamma adjustment, depending on GPU level
- // TODO: determine if we want to re-apply the gamma adjustment, and if so understand & fix Mac breakage
- //color = fullbrightScaleSoftClip(color);
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- //we're in sRGB space, so gamma correct this dot product so
- // lighting from the sun stays sharp
- float da = clamp(dot(normalize(norm.xyz), light_dir.xyz), 0.0, 1.0);
- da = pow(da, 1.0 / 1.3);
-
- color = amblit;
-
- //darken ambient for normals perpendicular to light vector so surfaces in shadow
- // and facing away from light still have some definition to them.
- // do NOT gamma correct this dot product so ambient lighting stays soft
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(da, shadow) * sunlit;
-
- color *= ambient;
-
- color += sun_contrib;
-
- color *= gamma_diff.rgb;
-
- float glare = 0.0;
-
- if (spec.a > 0.0) // specular reflection
- {
- /* // Reverting this specular calculation to previous 'dumbshiny' version - DJH 6/17/2020
- // Preserving the refactored version as a comment for potential reconsideration,
- // overriding the general rule to avoid pollutiong the source with commented code.
- //
- // If you're reading this in 2021+, feel free to obliterate.
-
- vec3 npos = -normalize(pos.xyz);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(light_dir.xyz + npos);
- float nh = dot(norm.xyz, h);
- float nv = dot(norm.xyz, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
- vec3 sp = sun_contrib*scol / 6.0f;
- sp = clamp(sp, vec3(0), vec3(1));
- bloom = dot(sp, sp) / 4.0;
- color += sp * spec.rgb;
- }
- */
-
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
-
- glare = max(spec_contrib.r, spec_contrib.g);
- glare = max(glare, spec_contrib.b);
-
- color += spec_contrib;
- }
-
- color = mix(color.rgb, diffcol.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- {
- //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
-
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
-
- color = mix(color, reflected_color, envIntensity);
-
- float cur_glare = max(reflected_color.r, reflected_color.g);
- cur_glare = max(cur_glare, reflected_color.b);
- cur_glare *= envIntensity*4.0;
- glare += cur_glare;
- }
-
- color = atmosFragLighting(color, additive, atten);
- color = scaleSoftClipFrag(color);
-
- //convert to linear before adding local lights
- color = srgb_to_linear(color);
-
- vec3 npos = normalize(-pos.xyz);
-
- vec3 light = vec3(0, 0, 0);
-
- final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035
-
-#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
-
- LIGHT_LOOP(1)
- LIGHT_LOOP(2)
- LIGHT_LOOP(3)
- LIGHT_LOOP(4)
- LIGHT_LOOP(5)
- LIGHT_LOOP(6)
- LIGHT_LOOP(7)
-
- color += light;
-
- glare = min(glare, 1.0);
- float al = max(diffcol.a, glare)*vertex_color.a;
-
- //convert to srgb as this color is being written post gamma correction
- color = linear_to_srgb(color);
-
-#ifdef WATER_FOG
- vec4 temp = applyWaterFogView(pos, vec4(color, al));
- color = temp.rgb;
- al = temp.a;
-#endif
-
- frag_color = vec4(color, al);
-
+ frag_color = vec4(0.5, 0, 1, 0.5);
#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
-
- // deferred path
- frag_data[0] = final_color; //gbuffer is sRGB
- frag_data[1] = final_specular; // XYZ = Specular color. W = Specular exponent.
- frag_data[2] = final_normal; // XY = Normal. Z = Env. intensity.
+ // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+ frag_data[0] = vec4(0.5, 0, 1, 0); // gbuffer is sRGB for legacy materials
+ frag_data[1] = vec4(0); // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = vec4(0); // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+ frag_data[3] = vec4(0);
#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
index 7e29ada205..7cdddfe8db 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialV.glsl
@@ -1,5 +1,5 @@
/**
- * @file bumpV.glsl
+ * @file materialV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -43,38 +43,38 @@ uniform mat4 modelview_projection_matrix;
uniform mat4 modelview_matrix;
#endif
-VARYING vec3 vary_position;
+out vec3 vary_position;
#endif
uniform mat4 texture_matrix0;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec2 texcoord0;
#ifdef HAS_NORMAL_MAP
-ATTRIBUTE vec4 tangent;
-ATTRIBUTE vec2 texcoord1;
+in vec4 tangent;
+in vec2 texcoord1;
-VARYING vec3 vary_mat0;
-VARYING vec3 vary_mat1;
-VARYING vec3 vary_mat2;
+out vec3 vary_tangent;
+flat out float vary_sign;
+out vec3 vary_normal;
-VARYING vec2 vary_texcoord1;
+out vec2 vary_texcoord1;
#else
-VARYING vec3 vary_normal;
+out vec3 vary_normal;
#endif
#ifdef HAS_SPECULAR_MAP
-ATTRIBUTE vec2 texcoord2;
-VARYING vec2 vary_texcoord2;
+in vec2 texcoord2;
+out vec2 vary_texcoord2;
#endif
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void main()
{
@@ -111,24 +111,21 @@ void main()
vec3 n = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
#ifdef HAS_NORMAL_MAP
vec3 t = normalize((mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz);
- vec3 b = cross(n, t)*tangent.w;
-
- vary_mat0 = vec3(t.x, b.x, n.x);
- vary_mat1 = vec3(t.y, b.y, n.y);
- vary_mat2 = vec3(t.z, b.z, n.z);
+
+ vary_tangent = t;
+ vary_sign = tangent.w;
+ vary_normal = n;
#else //HAS_NORMAL_MAP
-vary_normal = n;
+ vary_normal = n;
#endif //HAS_NORMAL_MAP
#else //HAS_SKIN
vec3 n = normalize(normal_matrix * normal);
#ifdef HAS_NORMAL_MAP
vec3 t = normalize(normal_matrix * tangent.xyz);
- vec3 b = cross(n,t)*tangent.w;
- //vec3 t = cross(b,n) * binormal.w;
-
- vary_mat0 = vec3(t.x, b.x, n.x);
- vary_mat1 = vec3(t.y, b.y, n.y);
- vary_mat2 = vec3(t.z, b.z, n.z);
+
+ vary_tangent = t;
+ vary_sign = tangent.w;
+ vary_normal = n;
#else //HAS_NORMAL_MAP
vary_normal = n;
#endif //HAS_NORMAL_MAP
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
index 35068899ee..183354b9bd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonF.glsl
@@ -23,29 +23,16 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
uniform vec3 moon_dir;
uniform float moon_brightness;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
-
-vec3 srgb_to_linear(vec3 c);
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
+in vec2 vary_texcoord0;
void main()
{
@@ -54,20 +41,24 @@ void main()
if( moon_dir.z > 0 )
fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
- vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
-// c.rgb = srgb_to_linear(c.rgb);
- c.rgb *= moonlight_color.rgb;
- c.rgb *= moon_brightness;
+ vec4 c = texture(diffuseMap, vary_texcoord0.xy);
- c.rgb *= fade;
- c.a *= fade;
+ // SL-14113 Don't write to depth; prevent moon's quad from hiding stars which should be visible
+ // Moon texture has transparent pixels <0x55,0x55,0x55,0x00>
+ if (c.a <= 2./255.) // 0.00784
+ {
+ discard;
+ }
- c.rgb = scaleSoftClip(c.rgb);
+ c.rgb *= moon_brightness;
+ c.a *= fade;
- frag_data[0] = vec4(c.rgb, c.a);
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0f);
+ frag_data[2] = vec4(0.0, 0.0, 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(c.rgb, c.a);
- gl_FragDepth = 0.999985f;
+ // Added and commented out for a ground truth. Do not uncomment - Geenz
+ //gl_FragDepth = 0.999985f;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
index c4922afd7d..c2a1dccb33 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/moonV.glsl
@@ -27,18 +27,21 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
//transform vertex
vec4 vert = vec4(position.xyz, 1.0);
- vec4 pos = (modelview_matrix * vert);
+ vec4 pos = (modelview_projection_matrix * vert);
- gl_Position = modelview_projection_matrix*vert;
+ // smash to *almost* far clip plane -- stars are still behind
+ // SL-19283 - finagle the moon position to be between clouds and stars.
+ pos.z = pos.w*0.999991;
+ gl_Position = pos;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
deleted file mode 100644
index 09c47165dd..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * @file class1/deferred/multiPointLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-
-uniform vec3 env_mat[3];
-uniform float sun_wash;
-uniform int light_count;
-uniform vec4 light[LIGHT_COUNT];
-uniform vec4 light_col[LIGHT_COUNT];
-
-uniform vec2 screen_res;
-uniform float far_z;
-uniform mat4 inv_proj;
-
-VARYING vec4 vary_fragcoord;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-vec3 srgb_to_linear(vec3 c);
-
-void main()
-{
-#if defined(LOCAL_LIGHT_KILL)
- discard; // Bail immediately
-#endif
-
- vec3 out_col = vec3(0, 0, 0);
- vec2 frag = (vary_fragcoord.xy * 0.5 + 0.5) * screen_res;
- vec3 pos = getPosition(frag.xy).xyz;
- if (pos.z < far_z)
- {
- discard;
- }
-
- vec3 norm = getNorm(frag.xy);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
- vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
-
- float noise = texture2D(noiseMap, frag.xy / 128.0).b;
- vec3 npos = normalize(-pos);
-
- // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
- for (int i = 0; i < LIGHT_COUNT; ++i)
- {
- vec3 lv = light[i].xyz - pos;
- float dist = length(lv);
- dist /= light[i].w;
- if (dist <= 1.0)
- {
- float da = dot(norm, lv);
- if (da > 0.0)
- {
- lv = normalize(lv);
- da = dot(norm, lv);
-
- float fa = light_col[i].a + 1.0;
- float dist_atten = clamp(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 0.0, 1.0);
- dist_atten *= dist_atten;
-
- // Tweak falloff slightly to match pre-EEP attenuation
- // NOTE: this magic number also shows up in a great many other places, search for dist_atten *= to audit
- dist_atten *= 2.0;
-
- dist_atten *= noise;
-
- float lit = da * dist_atten;
-
- vec3 col = light_col[i].rgb * lit * diff;
-
- if (spec.a > 0.0)
- {
- lit = min(da * 6.0, 1.0) * dist_atten;
- vec3 h = normalize(lv + npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5) * 0.4 + 0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres * texture2D(lightFunc, vec2(nh, spec.a)).r * gt / (nh * da);
- col += lit * scol * light_col[i].rgb * spec.rgb;
- }
- }
-
- out_col += col;
- }
- }
- }
-
- frag_color.rgb = out_col;
- frag_color.a = 0.0;
-
-#ifdef IS_AMD_CARD
- // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage
- // awawy which leads to unfun crashes and artifacts.
- vec4 dummy1 = light[0];
- vec4 dummy2 = light_col[0];
- vec4 dummy3 = light[LIGHT_COUNT - 1];
- vec4 dummy4 = light_col[LIGHT_COUNT - 1];
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
deleted file mode 100644
index ec3fb9c543..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ /dev/null
@@ -1,284 +0,0 @@
-/**
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-//class 1 -- no shadows
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
-uniform sampler2D lightFunc;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod; //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-
-uniform vec3 center;
-uniform vec3 color;
-uniform float falloff;
-uniform float size;
-
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
-vec3 srgb_to_linear(vec3 c);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
- vec3 col = vec3(0,0,0);
-
-#if defined(LOCAL_LIGHT_KILL)
- discard;
-#else
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- float envIntensity = texture2DRect(normalMap, frag.xy).z;
- vec3 norm = getNorm(frag.xy);
-
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
-
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- dist_atten *= noise;
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec3 dlit = vec3(0, 0, 0);
-
-
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float lit = 0.0;
- float amb_da = proj_ambiance;
-
- if (da > 0.0)
- {
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- lit = da * dist_atten;
-
- col = dlit*lit*diff_tex;
- amb_da += (da*0.5)*proj_ambiance;
- }
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
- col += amb_da*color.rgb*diff_tex*amb_plcol.rgb*amb_plcol.a;
- }
-
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
-
- if (spec.a > 0.0)
- {
- dlit *= min(da*6.0, 1.0) * dist_atten;
-
- vec3 npos = -normalize(pos);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb;
- //col += spec.rgb;
- }
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
- }
- }
- }
- }
-#endif
-
- //output linear, sum of lights will be gamma corrected later
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
index 7a941674b8..05dced0026 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenF.glsl
@@ -23,19 +23,13 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D alphaMap;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
uniform float stepX;
uniform float stepY;
@@ -43,12 +37,12 @@ uniform float norm_scale;
void main()
{
- float c = texture2D(alphaMap, vary_texcoord0).r;
+ float c = texture(alphaMap, vary_texcoord0).r;
- vec3 right = vec3(norm_scale, 0, (texture2D(alphaMap, vary_texcoord0+vec2(stepX, 0)).r-c)*255);
- vec3 left = vec3(-norm_scale, 0, (texture2D(alphaMap, vary_texcoord0-vec2(stepX, 0)).r-c)*255);
- vec3 up = vec3(0, -norm_scale, (texture2D(alphaMap, vary_texcoord0-vec2(0, stepY)).r-c)*255);
- vec3 down = vec3(0, norm_scale, (texture2D(alphaMap, vary_texcoord0+vec2(0, stepY)).r-c)*255);
+ vec3 right = vec3(norm_scale, 0, (texture(alphaMap, vary_texcoord0+vec2(stepX, 0)).r-c)*255);
+ vec3 left = vec3(-norm_scale, 0, (texture(alphaMap, vary_texcoord0-vec2(stepX, 0)).r-c)*255);
+ vec3 up = vec3(0, -norm_scale, (texture(alphaMap, vary_texcoord0-vec2(0, stepY)).r-c)*255);
+ vec3 down = vec3(0, norm_scale, (texture(alphaMap, vary_texcoord0+vec2(0, stepY)).r-c)*255);
vec3 norm = cross(right, down) + cross(down, left) + cross(left,up) + cross(up, right);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
index 9bceae05b7..7896659ad3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/normgenV.glsl
@@ -23,11 +23,11 @@
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_fragcoord;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_fragcoord;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaBlendF.glsl
index 41673d1669..79425ad716 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaBlendF.glsl
@@ -1,9 +1,9 @@
/**
- * @file treeShadowF.glsl
+ * @file pbrShadowAlphaBlendF.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,37 +23,34 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float d, float a);
+in vec4 post_pos;
+in float target_pos_x;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+uniform float minimum_alpha;
void main()
{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+ float alpha = texture(diffuseMap,vary_texcoord0.xy).a;
- if (alpha < minimum_alpha)
- {
- discard;
- }
+ alpha *= vertex_color.a;
- frag_color = computeMoments(length(pos), 1.0);
+ if (alpha < 0.05) // treat as totally transparent
+ {
+ discard;
+ }
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos.z/pos.w*0.5+0.5, 0.0);
-#endif
+ if (alpha < 0.88) // treat as semi-transparent
+ {
+ if (fract(0.5*floor(target_pos_x / post_pos.w )) < 0.25)
+ {
+ discard;
+ }
+ }
+ frag_color = vec4(1,1,1,1);
}
-
diff --git a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl
index 7a35905280..1d1545be7e 100644
--- a/indra/newview/app_settings/shaders/class1/avatar/pickAvatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskF.glsl
@@ -1,9 +1,9 @@
/**
- * @file pickAvatarF.glsl
+ * @file pbrShadowAlphaMaskF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,18 +23,24 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
uniform sampler2D diffuseMap;
+in vec4 post_pos;
+in float target_pos_x;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+uniform float minimum_alpha;
+
void main()
{
- frag_color = vec4(vertex_color.rgb, texture2D(diffuseMap, vary_texcoord0.xy).a);
+ float alpha = texture(diffuseMap,vary_texcoord0.xy).a;
+
+ if (alpha < minimum_alpha)
+ {
+ discard;
+ }
+
+ frag_color = vec4(1,1,1,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskV.glsl
index 5af42f1fcf..4fb5fbcf06 100644
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrShadowAlphaMaskV.glsl
@@ -1,9 +1,9 @@
-/**
- * @file fullbrightV.glsl
+/**
+ * @file pbrShadowAlphaMaskV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,42 +24,52 @@
*/
uniform mat4 texture_matrix0;
+#if defined(HAS_SKIN)
uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
+#endif
-void calcAtmospherics(vec3 inPositionEye);
+uniform vec4[2] texture_base_color_transform;
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+uniform float shadow_target_width;
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-uniform mat4 projection_matrix;
-#endif
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
+
+out vec4 post_pos;
+out float target_pos_x;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
+
+void passTextureIndex();
void main()
{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
- passTextureIndex();
-#ifdef HAS_SKIN
+ //transform vertex
+#if defined(HAS_SKIN)
+ vec4 pre_pos = vec4(position.xyz, 1.0);
mat4 mat = getObjectSkinnedTransform();
mat = modelview_matrix * mat;
- vec4 pos = mat * vert;
- gl_Position = projection_matrix * pos;
+ vec4 pos = mat * pre_pos;
+ pos = projection_matrix * pos;
#else
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ vec4 pos = modelview_projection_matrix * pre_pos;
#endif
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- calcAtmospherics(pos.xyz);
- vertex_color = diffuse_color;
+ target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
+
+ post_pos = pos;
+
+ gl_Position = pos;
+
+ passTextureIndex();
+
+ vary_texcoord0 = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ vertex_color = diffuse_color;
}
diff --git a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
index 0e074f3cec..2ccd3fd962 100644
--- a/indra/newview/app_settings/shaders/class1/transform/texcoordV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaF.glsl
@@ -1,9 +1,9 @@
-/**
- * @file texcoordV.glsl
+/**
+ * @file pbralphaF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,13 +23,11 @@
* $/LicenseInfo$
*/
+ // debug stub
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 texcoord_out;
+out vec4 frag_color;
void main()
{
- texcoord_out = texcoord0;
+ frag_color = vec4(1.0, 0, 0.5, 0.5);
}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
new file mode 100644
index 0000000000..6b960fae33
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl
@@ -0,0 +1,159 @@
+/**
+ * @file class1\deferred\pbralphaV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef IS_HUD
+
+// default alpha implementation
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+uniform mat4 texture_matrix0;
+
+#if !defined(HAS_SKIN)
+uniform mat4 modelview_matrix;
+#endif
+
+out vec3 vary_position;
+
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_normal_transform;
+uniform vec4[2] texture_metallic_roughness_transform;
+uniform vec4[2] texture_emissive_transform;
+
+out vec3 vary_fragcoord;
+
+uniform float near_clip;
+
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec4 tangent;
+in vec2 texcoord0;
+
+out vec2 base_color_texcoord;
+out vec2 normal_texcoord;
+out vec2 metallic_roughness_texcoord;
+out vec2 emissive_texcoord;
+
+out vec4 vertex_color;
+
+out vec3 vary_tangent;
+flat out float vary_sign;
+out vec3 vary_normal;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+ vary_position = pos;
+ vec4 vert = projection_matrix * vec4(pos,1.0);
+#else
+ //transform vertex
+ vec4 vert = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+ gl_Position = vert;
+
+ vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip);
+
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
+ metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
+
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif //HAS_SKIN
+
+ n = normalize(n);
+
+ vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_normal_transform, texture_matrix0));
+ vary_sign = tangent.w;
+ vary_normal = n;
+
+ vertex_color = diffuse_color;
+
+#if !defined(HAS_SKIN)
+ vary_position = (modelview_matrix*vec4(position.xyz, 1.0)).xyz;
+#endif
+}
+
+#else
+
+// fullbright HUD alpha implementation
+
+uniform mat4 modelview_projection_matrix;
+
+uniform mat4 texture_matrix0;
+
+uniform mat4 modelview_matrix;
+
+out vec3 vary_position;
+
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_emissive_transform;
+
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
+
+out vec2 base_color_texcoord;
+out vec2 emissive_texcoord;
+
+out vec4 vertex_color;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+
+
+void main()
+{
+ //transform vertex
+ vec4 vert = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ gl_Position = vert;
+ vary_position = vert.xyz;
+
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
+
+ vertex_color = diffuse_color;
+}
+
+#endif
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl
new file mode 100644
index 0000000000..b74b2e6a83
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowF.glsl
@@ -0,0 +1,67 @@
+/**
+ * @file pbrglowF.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+// forward fullbright implementation for HUDs
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+uniform vec3 emissiveColor;
+uniform sampler2D emissiveMap;
+
+out vec4 frag_color;
+
+in vec3 vary_position;
+in vec4 vertex_emissive;
+
+in vec2 base_color_texcoord;
+in vec2 emissive_texcoord;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+void main()
+{
+ vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+
+ if (basecolor.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ vec3 emissive = emissiveColor;
+ emissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
+
+ float lum = max(max(emissive.r, emissive.g), emissive.b);
+ lum *= vertex_emissive.a;
+
+ // HUDs are rendered after gamma correction, output in sRGB space
+ frag_color.rgb = vec3(0);
+ frag_color.a = lum;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
index d762239e51..82a50a115c 100644
--- a/indra/newview/app_settings/shaders/class1/objects/emissiveV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl
@@ -1,9 +1,9 @@
-/**
- * @file emissiveV.glsl
+/**
+ * @file pbgglowV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,44 +23,50 @@
* $/LicenseInfo$
*/
-uniform mat4 texture_matrix0;
+
+#ifdef HAS_SKIN
uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
uniform mat4 modelview_projection_matrix;
+#endif
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec4 emissive;
-ATTRIBUTE vec2 texcoord0;
+uniform mat4 texture_matrix0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_emissive_transform;
-void calcAtmospherics(vec3 inPositionEye);
+in vec3 position;
+in vec4 emissive;
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-uniform mat4 projection_matrix;
-#endif
+in vec2 texcoord0;
+
+out vec2 base_color_texcoord;
+out vec2 emissive_texcoord;
+
+out vec4 vertex_emissive;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
void main()
{
- //transform vertex
- passTextureIndex();
-
#ifdef HAS_SKIN
mat4 mat = getObjectSkinnedTransform();
+
mat = modelview_matrix * mat;
- vec4 pos = mat * vec4(position.xyz, 1.0);
- gl_Position = projection_matrix * pos;
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+ gl_Position = projection_matrix*vec4(pos,1.0);
#else
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
#endif
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
-
- calcAtmospherics(pos.xyz);
- vertex_color = emissive;
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
+
+ vertex_emissive = emissive;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
new file mode 100644
index 0000000000..faa273b834
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl
@@ -0,0 +1,153 @@
+/**
+ * @file pbropaqueF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+
+#ifndef IS_HUD
+
+// deferred opaque implementation
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness
+
+out vec4 frag_data[4];
+
+in vec3 vary_position;
+in vec4 vertex_color;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+flat in float vary_sign;
+
+in vec2 base_color_texcoord;
+in vec2 normal_texcoord;
+in vec2 metallic_roughness_texcoord;
+in vec2 emissive_texcoord;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec2 encode_normal(vec3 n);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform mat3 normal_matrix;
+
+void main()
+{
+ vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+ if (basecolor.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb);
+
+ // from mikktspace.com
+ vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ // RGB = Occlusion, Roughness, Metal
+ // default values, see LLViewerTexture::sDefaultPBRORMImagep
+ // occlusion 1.0
+ // roughness 0.0
+ // metal 0.0
+ vec3 spec = texture(specularMap, metallic_roughness_texcoord.xy).rgb;
+
+ spec.g *= roughnessFactor;
+ spec.b *= metallicFactor;
+
+ vec3 emissive = emissiveColor;
+ emissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
+
+ tnorm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ //spec.rgb = vec3(1,1,0);
+ //col = vec3(0,0,0);
+ //emissive = vary_tangent.xyz*0.5+0.5;
+ //emissive = vec3(sign*0.5+0.5);
+ //emissive = vNt * 0.5 + 0.5;
+ //emissive = tnorm*0.5+0.5;
+ // See: C++: addDeferredAttachments(), GLSL: softenLightF
+ frag_data[0] = max(vec4(col, 0.0), vec4(0)); // Diffuse
+ frag_data[1] = max(vec4(spec.rgb,vertex_color.a), vec4(0)); // PBR linear packed Occlusion, Roughness, Metal.
+ frag_data[2] = max(vec4(encode_normal(tnorm), vertex_color.a, GBUFFER_FLAG_HAS_PBR), vec4(0)); // normal, environment intensity, flags
+ frag_data[3] = max(vec4(emissive,0), vec4(0)); // PBR sRGB Emissive
+}
+
+#else
+
+// forward fullbright implementation for HUDs
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+uniform vec3 emissiveColor;
+uniform sampler2D emissiveMap;
+
+out vec4 frag_color;
+
+in vec3 vary_position;
+in vec4 vertex_color;
+
+in vec2 base_color_texcoord;
+in vec2 emissive_texcoord;
+
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+void main()
+{
+ vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+ if (basecolor.a < minimum_alpha)
+ {
+ discard;
+ }
+
+ vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb);
+
+ vec3 emissive = emissiveColor;
+ emissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
+
+ col += emissive;
+
+ // HUDs are rendered after gamma correction, output in sRGB space
+ frag_color.rgb = linear_to_srgb(col);
+ frag_color.a = 0.0;
+}
+
+#endif
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
new file mode 100644
index 0000000000..160ae7a215
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl
@@ -0,0 +1,139 @@
+/**
+ * @file pbropaqueV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef IS_HUD
+
+//deferred opaque implementation
+
+#ifdef HAS_SKIN
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
+uniform mat3 normal_matrix;
+uniform mat4 modelview_projection_matrix;
+#endif
+uniform mat4 texture_matrix0;
+
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_normal_transform;
+uniform vec4[2] texture_metallic_roughness_transform;
+uniform vec4[2] texture_emissive_transform;
+
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
+in vec4 tangent;
+in vec2 texcoord0;
+
+out vec2 base_color_texcoord;
+out vec2 normal_texcoord;
+out vec2 metallic_roughness_texcoord;
+out vec2 emissive_texcoord;
+
+out vec4 vertex_color;
+
+out vec3 vary_tangent;
+flat out float vary_sign;
+out vec3 vary_normal;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+
+void main()
+{
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+
+ mat = modelview_matrix * mat;
+
+ vec3 pos = (mat*vec4(position.xyz,1.0)).xyz;
+
+ gl_Position = projection_matrix*vec4(pos,1.0);
+
+#else
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+#endif
+
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0);
+ metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
+
+#ifdef HAS_SKIN
+ vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz;
+ vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz;
+#else //HAS_SKIN
+ vec3 n = normal_matrix * normal;
+ vec3 t = normal_matrix * tangent.xyz;
+#endif
+
+ n = normalize(n);
+
+ vary_tangent = normalize(tangent_space_transform(vec4(t, tangent.w), n, texture_normal_transform, texture_matrix0));
+ vary_sign = tangent.w;
+ vary_normal = n;
+
+ vertex_color = diffuse_color;
+}
+
+#else
+
+// fullbright HUD implementation
+
+uniform mat4 modelview_projection_matrix;
+
+uniform mat4 texture_matrix0;
+
+uniform vec4[2] texture_base_color_transform;
+uniform vec4[2] texture_emissive_transform;
+
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
+
+out vec2 base_color_texcoord;
+out vec2 emissive_texcoord;
+
+out vec4 vertex_color;
+
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform);
+
+void main()
+{
+ //transform vertex
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+
+ base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0);
+ emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0);
+
+ vertex_color = diffuse_color;
+}
+
+#endif
+
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
deleted file mode 100644
index 18616a9bb3..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ /dev/null
@@ -1,132 +0,0 @@
-/**
- * @file pointLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D lightFunc;
-uniform sampler2DRect depthMap;
-
-uniform vec3 env_mat[3];
-uniform float sun_wash;
-
-uniform vec3 color;
-uniform float falloff;
-uniform float size;
-
-VARYING vec4 vary_fragcoord;
-VARYING vec3 trans_center;
-
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-uniform vec4 viewport;
-
-vec3 getNorm(vec2 pos_screen);
-vec4 getPosition(vec2 pos_screen);
-vec3 srgb_to_linear(vec3 c);
-
-void main()
-{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- vec3 norm = getNorm(frag.xy);
-
- float da = dot(norm, lv);
- if (da < 0.0)
- {
- discard;
- }
-
- lv = normalize(lv);
- da = dot(norm, lv);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
-
- vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
-
- float fa = falloff+1.0;
- float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- float lit = da * dist_atten * noise;
-
- col = color.rgb*lit*col;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
- if (spec.a > 0.0)
- {
- lit = min(da*6.0, 1.0) * dist_atten;
-
- vec3 npos = -normalize(pos);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5) * 0.4+0.5;
- float gtdenom = 2 * nh;
- float gt = max(0,(min(gtdenom * nv / vh, gtdenom * da / vh)));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += lit*scol*color.rgb*spec.rgb;
- }
- }
-
- if (dot(col, col) <= 0.0)
- {
- discard;
- }
-
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
index f06f8c870b..86e3f1acda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl
@@ -23,28 +23,22 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
+uniform sampler2D diffuseRect;
uniform mat4 inv_proj;
uniform vec2 screen_res;
uniform float max_cof;
uniform float res_scale;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{
- vec4 s = texture2DRect(diffuseRect, tc);
+ vec4 s = texture(diffuseRect, tc);
float sc = abs(s.a*2.0-1.0)*max_cof;
@@ -63,7 +57,7 @@ void dofSample(inout vec4 diff, inout float w, float min_sc, vec2 tc)
void dofSampleNear(inout vec4 diff, inout float w, float min_sc, vec2 tc)
{
- vec4 s = texture2DRect(diffuseRect, tc);
+ vec4 s = texture(diffuseRect, tc);
float wg = 0.25;
@@ -79,7 +73,7 @@ void main()
{
vec2 tc = vary_fragcoord.xy;
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
+ vec4 diff = texture(diffuseRect, vary_fragcoord.xy);
{
float w = 1.0;
@@ -93,14 +87,14 @@ void main()
{
while (sc > 0.5)
{
- int its = int(max(1.0,(sc*3.7)));
+ int its = int(max(1.0,(sc*3.7)));
for (int i=0; i<its; ++i)
{
float ang = sc+i*2*PI/its; // sc is added for rotary perturbance
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
// you could test sample coords against an interesting non-circular aperture shape here, if desired.
- dofSampleNear(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
+ dofSampleNear(diff, w, sc, vary_fragcoord.xy + (vec2(samp_x,samp_y) / screen_res));
}
sc -= 1.0;
}
@@ -117,7 +111,7 @@ void main()
float samp_x = sc*sin(ang);
float samp_y = sc*cos(ang);
// you could test sample coords against an interesting non-circular aperture shape here, if desired.
- dofSample(diff, w, sc, vary_fragcoord.xy + vec2(samp_x,samp_y));
+ dofSample(diff, w, sc, vary_fragcoord.xy + (vec2(samp_x,samp_y) / screen_res));
}
sc -= 1.0;
}
@@ -125,6 +119,6 @@ void main()
diff /= w;
}
-
+
frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
index cd37a34e0d..64e6bc9da2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl
@@ -23,30 +23,164 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
+uniform sampler2D diffuseRect;
+uniform sampler2D exposureMap;
uniform vec2 screen_res;
-VARYING vec2 vary_fragcoord;
-uniform float display_gamma;
+in vec2 vary_fragcoord;
vec3 linear_to_srgb(vec3 cl);
+//===============================================================
+// tone mapping taken from Khronos sample implementation
+//===============================================================
+
+// sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT
+const mat3 ACESInputMat = mat3
+(
+ 0.59719, 0.07600, 0.02840,
+ 0.35458, 0.90834, 0.13383,
+ 0.04823, 0.01566, 0.83777
+);
+
+
+// ODT_SAT => XYZ => D60_2_D65 => sRGB
+const mat3 ACESOutputMat = mat3
+(
+ 1.60475, -0.10208, -0.00327,
+ -0.53108, 1.10813, -0.07276,
+ -0.07367, -0.00605, 1.07602
+);
+
+// ACES tone map (faster approximation)
+// see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/
+vec3 toneMapACES_Narkowicz(vec3 color)
+{
+ const float A = 2.51;
+ const float B = 0.03;
+ const float C = 2.43;
+ const float D = 0.59;
+ const float E = 0.14;
+ return clamp((color * (A * color + B)) / (color * (C * color + D) + E), 0.0, 1.0);
+}
+
+
+// ACES filmic tone map approximation
+// see https://github.com/TheRealMJP/BakingLab/blob/master/BakingLab/ACES.hlsl
+vec3 RRTAndODTFit(vec3 color)
+{
+ vec3 a = color * (color + 0.0245786) - 0.000090537;
+ vec3 b = color * (0.983729 * color + 0.4329510) + 0.238081;
+ return a / b;
+}
+
+
+// tone mapping
+vec3 toneMapACES_Hill(vec3 color)
+{
+ color = ACESInputMat * color;
+
+ // Apply RRT and ODT
+ color = RRTAndODTFit(color);
+
+ color = ACESOutputMat * color;
+
+ // Clamp to [0, 1]
+ color = clamp(color, 0.0, 1.0);
+
+ return color;
+}
+
+uniform float exposure;
+uniform float gamma;
+
+vec3 toneMap(vec3 color)
+{
+#ifndef NO_POST
+ float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r;
+
+ color *= exposure * exp_scale;
+
+ // mix ACES and Linear here as a compromise to avoid over-darkening legacy content
+ color = mix(toneMapACES_Hill(color), color, 0.333);
+#endif
+
+ return color;
+}
+
+//===============================================================
+
+//=================================
+// borrowed noise from:
+// <https://www.shadertoy.com/view/4dS3Wd>
+// By Morgan McGuire @morgan3d, http://graphicscodex.com
+//
+float hash(float n) { return fract(sin(n) * 1e4); }
+float hash(vec2 p) { return fract(1e4 * sin(17.0 * p.x + p.y * 0.1) * (0.1 + abs(sin(p.y * 13.0 + p.x)))); }
+
+float noise(float x) {
+ float i = floor(x);
+ float f = fract(x);
+ float u = f * f * (3.0 - 2.0 * f);
+ return mix(hash(i), hash(i + 1.0), u);
+}
+
+float noise(vec2 x) {
+ vec2 i = floor(x);
+ vec2 f = fract(x);
+
+ // Four corners in 2D of a tile
+ float a = hash(i);
+ float b = hash(i + vec2(1.0, 0.0));
+ float c = hash(i + vec2(0.0, 1.0));
+ float d = hash(i + vec2(1.0, 1.0));
+
+ // Simple 2D lerp using smoothstep envelope between the values.
+ // return vec3(mix(mix(a, b, smoothstep(0.0, 1.0, f.x)),
+ // mix(c, d, smoothstep(0.0, 1.0, f.x)),
+ // smoothstep(0.0, 1.0, f.y)));
+
+ // Same code, with the clamps in smoothstep and common subexpressions
+ // optimized away.
+ vec2 u = f * f * (3.0 - 2.0 * f);
+ return mix(a, b, u.x) + (c - a) * u.y * (1.0 - u.x) + (d - b) * u.x * u.y;
+}
+
+//=============================
+
+
+vec3 legacyGamma(vec3 color)
+{
+ vec3 c = 1. - clamp(color, vec3(0.), vec3(1.));
+ c = 1. - pow(c, vec3(gamma)); // s/b inverted already CPU-side
+
+ return c;
+}
+
void main()
{
//this is the one of the rare spots where diffuseRect contains linear color values (not sRGB)
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord);
- //diff.rgb = pow(diff.rgb, vec3(display_gamma));
+ vec4 diff = texture(diffuseRect, vary_fragcoord);
+
+#ifdef LEGACY_GAMMA
+ diff.rgb = linear_to_srgb(diff.rgb);
+ diff.rgb = legacyGamma(diff.rgb);
+#else
+#ifndef NO_POST
+ diff.rgb = toneMap(diff.rgb);
+#endif
diff.rgb = linear_to_srgb(diff.rgb);
- frag_color = diff;
+#endif
+
+ vec2 tc = vary_fragcoord.xy*screen_res*4.0;
+ vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y);
+ vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb));
+ diff.rgb += nz*0.003;
+
+ frag_color = max(diff, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
index 058941bfb2..bace9b8c90 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoDoFF.glsl
@@ -23,27 +23,22 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
-uniform sampler2D bloomMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D depthMap;
uniform vec2 screen_res;
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
void main()
{
- vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy);
+ vec4 diff = texture(diffuseRect, vary_fragcoord.xy);
- vec4 bloom = texture2D(bloomMap, vary_fragcoord.xy/screen_res);
- frag_color = diff + bloom;
+ frag_color = diff;
+
+ gl_FragDepth = texture(depthMap, vary_fragcoord.xy).r;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
index bd0cb50464..7e8a5d68d4 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredNoTCV.glsl
@@ -23,18 +23,16 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
+in vec3 position;
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
+out vec2 vary_fragcoord;
uniform vec2 screen_res;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vec4 pos = vec4(position.xyz, 1.0);
+ gl_Position = pos;
+ vary_fragcoord = (pos.xy*0.5+0.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
index 8edf5b2723..10b4b3e76c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl
@@ -23,12 +23,10 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
+in vec3 position;
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
-VARYING vec2 vary_tc;
+out vec2 vary_fragcoord;
+out vec2 vary_tc;
uniform vec2 tc_scale;
@@ -37,8 +35,8 @@ uniform vec2 screen_res;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
vary_tc = (pos.xy*0.5+0.5)*tc_scale;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vary_fragcoord = (pos.xy*0.5+0.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl
index 8e9a5fcd41..2c17de311c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/attachmentShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredVisualizeBuffers.glsl
@@ -1,5 +1,6 @@
/**
- * @file avatarShadowF.glsl
+ * @file postDeferredNoDoFF.glsl
+ *
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
@@ -21,21 +22,20 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2D diffuseMap;
+uniform sampler2D diffuseRect;
+uniform float mipLevel;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_fragcoord;
void main()
{
- frag_color = vec4(1,1,1,1);
+ vec4 diff = textureLod(diffuseRect, vary_fragcoord.xy, mipLevel);
+
+ frag_color = diff;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
deleted file mode 100644
index cf994d3547..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @file postgiF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
- #ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect giLightMap;
-uniform sampler2D noiseMap;
-
-uniform vec2 kern[32];
-uniform float dist_factor;
-uniform float blur_size;
-uniform vec2 delta;
-uniform int kern_length;
-uniform float kern_scale;
-uniform vec3 blur_quad;
-
-VARYING vec2 vary_fragcoord;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
- norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
- vec3 pos = getPosition(vary_fragcoord.xy).xyz;
-
- vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
- vec2 dlt = kern_scale * delta/(1.0+norm.xy*norm.xy);
- dlt /= max(-pos.z*dist_factor, 1.0);
- float defined_weight = kern[0].x;
- vec3 col = vec3(0.0);
-
- for (int i = 0; i < kern_length; i++)
- {
- vec2 tc = vary_fragcoord.xy + kern[i].y*dlt;
- vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz;
- sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm
-
- float d = dot(norm.xyz, sampNorm);
-
- if (d > 0.8)
- {
- vec3 samppos = getPosition(tc.xy).xyz;
- samppos -= pos;
- if (dot(samppos,samppos) < -0.05*pos.z)
- {
- col += texture2DRect(giLightMap, tc).rgb*kern[i].x;
- defined_weight += kern[i].x;
- }
- }
- }
-
- col /= defined_weight;
-
- //col = ccol;
-
- col = col*col*blur_quad.x + col*blur_quad.y + blur_quad.z;
-
- frag_color.rgb = col;
-
-#ifdef IS_AMD_CARD
- // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage awawy which leads to unfun crashes and artifacts.
- vec2 dummy1 = kern[0];
- vec2 dummy2 = kern[31];
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl
index 449d8d8b4e..1a85d70256 100644
--- a/indra/newview/app_settings/shaders/class1/transform/binormalV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/screenSpaceReflUtil.glsl
@@ -1,36 +1,37 @@
/**
- * @file binormalV.glsl
+ * @file class3/deferred/screenSpaceReflUtil.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-uniform mat3 normal_matrix;
+// debug stub
-ATTRIBUTE vec4 tangent;
-
-VARYING vec4 tangent_out;
-
-void main()
+float random (vec2 uv)
{
- tangent_out = vec4(normal_matrix * tangent.xyz), tangent.w);
+ return 0;
}
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)
+{
+ collectedColor = vec4(0);
+ return 0;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
deleted file mode 100644
index f45c343066..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaBlendV.glsl
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- pos_w = pos.w;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
index 9b8df0a5a4..a8febabcc6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl
@@ -25,26 +25,21 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-VARYING vec4 post_pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 post_pos;
+in float target_pos_x;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
uniform float minimum_alpha;
void main()
{
float alpha = diffuseLookup(vary_texcoord0.xy).a;
- // mask cutoff 0 -> no shadow SL-11051
- if (minimum_alpha == 0)
+ if (alpha < minimum_alpha)
{
discard;
}
@@ -53,22 +48,18 @@ void main()
alpha *= vertex_color.a;
#endif
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
+ if (alpha < 0.05) // treat as totally transparent
+ {
+ discard;
+ }
- if (alpha < 0.88) // treat as semi-transparent
- {
- if (fract(0.5*floor(target_pos_x / post_pos.w )) < 0.25)
- {
- discard;
- }
- }
+ if (alpha < 0.88) // treat as semi-transparent
+ {
+ if (fract(0.5*floor(target_pos_x / post_pos.w )) < 0.25)
+ {
+ discard;
+ }
+ }
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
deleted file mode 100644
index 2b17aea75a..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskSkinnedV.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file shadowAlphaMaskSkinnedV.glsl
- *
- * $LicenseInfo:firstyear=2021&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 post_pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-mat4 getObjectSkinnedTransform();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
-
- vec4 pos = mat * pre_pos;
- pos = projection_matrix * pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- post_pos = pos;
-
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
index b6a0f0b165..26db1a5d4d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl
@@ -24,34 +24,46 @@
*/
uniform mat4 texture_matrix0;
+#if defined(HAS_SKIN)
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+mat4 getObjectSkinnedTransform();
+#else
uniform mat4 modelview_projection_matrix;
+#endif
+
uniform float shadow_target_width;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec4 post_pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 post_pos;
+out float target_pos_x;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void passTextureIndex();
void main()
{
//transform vertex
+#if defined(HAS_SKIN)
+ vec4 pre_pos = vec4(position.xyz, 1.0);
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * pre_pos;
+ pos = projection_matrix * pos;
+#else
vec4 pre_pos = vec4(position.xyz, 1.0);
vec4 pos = modelview_projection_matrix * pre_pos;
+#endif
+
target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
post_pos = pos;
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
passTextureIndex();
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
index 0e74d2eb8a..0f5f9ed289 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowCubeV.glsl
@@ -25,11 +25,7 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
+in vec3 position;
uniform vec3 box_center;
uniform vec3 box_size;
@@ -40,11 +36,5 @@ void main()
vec3 p = position*box_size+box_center;
vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
index 1ea96918bb..370aa75d04 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl
@@ -23,22 +23,9 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 post_pos;
void main()
{
frag_color = vec4(1,1,1,1);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
index bdf8e0854d..9bbc63bce1 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowSkinnedV.glsl
@@ -26,9 +26,7 @@
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
-ATTRIBUTE vec3 position;
-
-VARYING vec4 post_pos;
+in vec3 position;
mat4 getObjectSkinnedTransform();
@@ -41,12 +39,5 @@ void main()
vec4 pos = (mat*vec4(position.xyz, 1.0));
pos = projection_matrix*pos;
- post_pos = pos;
-
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
gl_Position = pos;
-#endif
-
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
index 4134220306..ee3a5f1f31 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowUtil.glsl
@@ -23,14 +23,20 @@
* $/LicenseInfo$
*/
-uniform sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
+uniform sampler2D normalMap;
+uniform sampler2D depthMap;
+
+#if defined(SUN_SHADOW)
uniform sampler2DShadow shadowMap0;
uniform sampler2DShadow shadowMap1;
uniform sampler2DShadow shadowMap2;
uniform sampler2DShadow shadowMap3;
+#endif
+
+#if defined(SPOT_SHADOW)
uniform sampler2DShadow shadowMap4;
uniform sampler2DShadow shadowMap5;
+#endif
uniform vec3 sun_dir;
uniform vec3 moon_dir;
@@ -48,40 +54,49 @@ uniform int sun_up_factor;
float pcfShadow(sampler2DShadow shadowMap, vec3 norm, vec4 stc, float bias_mul, vec2 pos_screen, vec3 light_dir)
{
+#if defined(SUN_SHADOW)
float offset = shadow_bias * bias_mul;
stc.xyz /= stc.w;
stc.z += offset * 2.0;
stc.x = floor(stc.x*shadow_res.x + fract(pos_screen.y*shadow_res.y))/shadow_res.x; // add some chaotic jitter to X sample pos according to Y to disguise the snapping going on here
- float cs = shadow2D(shadowMap, stc.xyz).x;
+ float cs = texture(shadowMap, stc.xyz);
float shadow = cs * 4.0;
- shadow += shadow2D(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0)).x;
+ shadow += texture(shadowMap, stc.xyz+vec3( 1.5/shadow_res.x, 0.5/shadow_res.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3( 0.5/shadow_res.x, -1.5/shadow_res.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3(-1.5/shadow_res.x, -0.5/shadow_res.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3(-0.5/shadow_res.x, 1.5/shadow_res.y, 0.0));
return clamp(shadow * 0.125, 0.0, 1.0);
+#else
+ return 1.0;
+#endif
}
float pcfSpotShadow(sampler2DShadow shadowMap, vec4 stc, float bias_scale, vec2 pos_screen)
{
+#if defined(SPOT_SHADOW)
stc.xyz /= stc.w;
stc.z += spot_shadow_bias * bias_scale;
stc.x = floor(proj_shadow_res.x * stc.x + fract(pos_screen.y*0.666666666)) / proj_shadow_res.x; // snap
- float cs = shadow2D(shadowMap, stc.xyz).x;
+ float cs = texture(shadowMap, stc.xyz);
float shadow = cs;
vec2 off = 1.0/proj_shadow_res;
off.y *= 1.5;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x;
- shadow += shadow2D(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0)).x;
+ shadow += texture(shadowMap, stc.xyz+vec3(off.x*2.0, off.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0));
+ shadow += texture(shadowMap, stc.xyz+vec3(-off.x*2.0, -off.y, 0.0));
return shadow*0.2;
+#else
+ return 1.0;
+#endif
}
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
{
+#if defined(SUN_SHADOW)
float shadow = 0.0f;
vec3 light_dir = normalize((sun_up_factor == 1) ? sun_dir : moon_dir);
@@ -175,10 +190,14 @@ float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
}
//shadow = min(dp_directional_light,shadow);
return shadow;
+#else
+ return 1.0;
+#endif
}
float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
{
+#if defined(SPOT_SHADOW)
float shadow = 0.0f;
pos += norm * spot_shadow_offset;
@@ -217,5 +236,8 @@ float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
shadow = 1.0f;
}
return shadow;
+#else
+ return 1.0;
+#endif
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
index 72bd0f0f34..bd62954ff8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl
@@ -25,21 +25,10 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-
-VARYING vec4 post_pos;
+in vec3 position;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- post_pos = pos;
-
-#if !defined(DEPTH_CLAMP)
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
index de22312d3c..9d9ba49d82 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyF.glsl
@@ -22,12 +22,10 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-/*[EXTRA_CODE_HERE]*/
// Inputs
-VARYING vec4 vary_HazeColor;
-VARYING float vary_LightNormPosDot;
+in vec3 vary_HazeColor;
+in float vary_LightNormPosDot;
uniform sampler2D rainbow_map;
uniform sampler2D halo_map;
@@ -36,16 +34,15 @@ uniform float moisture_level;
uniform float droplet_radius;
uniform float ice_level;
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
+
+vec3 srgb_to_linear(vec3 c);
/////////////////////////////////////////////////////////////////////////
// The fragment shader for the sky
/////////////////////////////////////////////////////////////////////////
+
vec3 rainbow(float d)
{
// 'Interesting' values of d are -0.75 .. -0.825, i.e. when view vec nearly opposite of sun vec
@@ -62,19 +59,16 @@ vec3 rainbow(float d)
d = clamp(d, 0.0, 0.25) + interior_coord;
float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
+ return pow(texture(rainbow_map, vec2(rad+0.5, d)).rgb, vec3(1.8)) * moisture_level;
}
vec3 halo22(float d)
{
d = clamp(d, 0.1, 1.0);
float v = sqrt(clamp(1 - (d * d), 0, 1));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
+ return texture(halo_map, vec2(0, v)).rgb * ice_level;
}
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
void main()
{
// Potential Fill-rate optimization. Add cloud calculation
@@ -82,7 +76,7 @@ void main()
// the fragment) if the sky wouldn't show up because the clouds
// are fully opaque.
- vec4 color = vary_HazeColor;
+ vec3 color = vary_HazeColor;
float rel_pos_lightnorm = vary_LightNormPosDot;
float optic_d = rel_pos_lightnorm;
@@ -90,13 +84,11 @@ void main()
color.rgb += rainbow(optic_d);
color.rgb += halo_22;
color.rgb *= 2.;
- color.rgb = scaleSoftClip(color.rgb);
-
- // Gamma correct for WL (soft clip effect).
- frag_data[0] = vec4(color.rgb, 1.0);
- frag_data[1] = vec4(0.0,0.0,0.0,0.0);
- frag_data[2] = vec4(0.0,0.0,0.0,1.0); //1.0 in norm.w masks off fog
+ color.rgb = clamp(color.rgb, vec3(0), vec3(5));
- gl_FragDepth = 0.99999f;
+ frag_data[0] = vec4(0);
+ frag_data[1] = vec4(0);
+ frag_data[2] = vec4(0.0,0.0,0.0,GBUFFER_FLAG_SKIP_ATMOS); //1.0 in norm.w masks off fog
+ frag_data[3] = vec4(color.rgb, 1.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
index 6db4690bff..17ce2dee5b 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl
@@ -25,26 +25,26 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
// SKY ////////////////////////////////////////////////////////////////////////
// The vertex shader for creating the atmospheric sky
///////////////////////////////////////////////////////////////////////////////
// Output parameters
-VARYING vec4 vary_HazeColor;
-VARYING float vary_LightNormPosDot;
+out vec3 vary_HazeColor;
+out float vary_LightNormPosDot;
// Inputs
uniform vec3 camPosLocal;
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
@@ -53,10 +53,10 @@ uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float sun_moon_glow_factor;
-uniform vec4 cloud_color;
+uniform int cube_snapshot;
// NOTE: Keep these in sync!
// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
@@ -91,16 +91,16 @@ void main()
vary_LightNormPosDot = rel_pos_lightnorm_dot;
// Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color * 0.7; //magic 0.7 to match legacy color
+
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
+ vec3 combined_haze = abs(blue_density) + vec3(abs(haze_density));
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = haze_density / combined_haze;
// Compute sunlight from rel_pos & lightnorm (for long rays like sky)
float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
@@ -129,20 +129,20 @@ void main()
haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (sun_moon_glow_factor * (haze_glow + 0.25));
// Haze color above cloud
- vec4 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ vec3 color = (blue_horizon * blue_weight * (sunlight + ambient_color)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
// Final atmosphere additive
color *= (1. - combined_haze);
// Increase ambient when there are more clouds
- vec4 ambient = ambient_color + max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
+ vec3 ambient = ambient_color + max(vec3(0), (1. - ambient_color)) * cloud_shadow * 0.5;
// Dim sunlight by cloud shadow percentage
sunlight *= max(0.0, (1. - cloud_shadow));
// Haze color below cloud
- vec4 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ vec3 add_below_cloud = (blue_horizon * blue_weight * (sunlight + ambient)
+ (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient));
// Attenuate cloud color by atmosphere
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
deleted file mode 100644
index 7f2c603f87..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * @file class1/deferred/softenLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DRect depthMap;
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform int sun_up_factor;
-VARYING vec2 vary_fragcoord;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec3 getNorm(vec2 pos_screen);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-float getAmbientClamp();
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-vec3 linear_to_srgb(vec3 c);
-vec3 srgb_to_linear(vec3 c);
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-void main()
-{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec4 pos = getPositionWithDepth(tc, depth);
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- float light_gamma = 1.0/1.3;
- da = pow(da, light_gamma);
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
-
- //convert to gamma space
- diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
-
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- vec3 color = vec3(0);
- float bloom = 0.0;
- {
- float ambocc = 1.0; // no AO...
-
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
-
- calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, false);
-
- color.rgb = amblit;
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- color.rgb *= ambient;
-
- vec3 sun_contrib = da * sunlit;
-
- color.rgb += sun_contrib;
-
- color.rgb *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- float sa = dot(refnormpersp, light_dir.xyz);
- vec3 dumbshiny = sunlit * (texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- color.rgb += spec_contrib;
- }
-
- color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
- color = mix(color.rgb, reflected_color, envIntensity);
- }
-
- if (norm.w < 0.5)
- {
- color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
- color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
- }
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos.xyz,vec4(color, bloom));
- color = fogged.rgb;
- bloom = fogged.a;
- #endif
-
- }
-
-// linear debuggables
-//color.rgb = vec3(final_da);
-//color.rgb = vec3(ambient);
-//color.rgb = vec3(scol);
-//color.rgb = diffuse_srgb.rgb;
-
- // convert to linear as fullscreen lights need to sum in linear colorspace
- // and will be gamma (re)corrected downstream...
-
- frag_color.rgb = srgb_to_linear(color.rgb);
- frag_color.a = bloom;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
deleted file mode 100644
index 8891315e15..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightV.glsl
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file softenLightV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-uniform vec2 screen_res;
-
-void setAtmosAttenuation(vec3 c);
-void setAdditiveColor(vec3 c);
-
-VARYING vec2 vary_fragcoord;
-void main()
-{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
- // appease OSX GLSL compiler/linker by touching all the varyings we said we would
- setAtmosAttenuation(vec3(1));
- setAdditiveColor(vec3(0));
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
deleted file mode 100644
index 694b19cdfb..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ /dev/null
@@ -1,279 +0,0 @@
-/**
- * @file spotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 1 -- no shadows
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
-uniform sampler2D lightFunc;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod; //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-
-uniform float size;
-uniform vec3 color;
-uniform float falloff;
-
-VARYING vec3 trans_center;
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec3 getNorm(vec2 pos_screen);
-vec3 srgb_to_linear(vec3 c);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
- vec3 col = vec3(0,0,0);
-
-#if defined(LOCAL_LIGHT_KILL)
- discard;
-#else
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
- //light shaders output linear and are gamma corrected later in postDeferredGammaCorrectF.glsl
- diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- vec3 dlit = vec3(0, 0, 0);
-
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
-
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
-
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex;
- //amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a*diff_tex.rgb;
- }
-
- if (spec.a > 0.0)
- {
- dlit *= min(da*6.0, 1.0) * dist_atten;
- vec3 npos = -normalize(pos);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
-
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb;
- //col += spec.rgb;
- }
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * envIntensity;
- }
- }
- }
- }
-#endif
-
- //col.r = 1.0;
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
index bac79a9fdc..b35d10c8a0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsF.glsl
@@ -25,18 +25,13 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 screenpos;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+in vec2 screenpos;
uniform sampler2D diffuseMap;
-uniform sampler2D altDiffuseMap;
uniform float blend_factor;
uniform float custom_alpha;
uniform float time;
@@ -46,10 +41,15 @@ float twinkle(){
return abs(d);
}
+// See:
+// ALM off: class1/environment/starsF.glsl
+// ALM on : class1/deferred/starsF.glsl
void main()
{
- vec4 col_a = texture2D(diffuseMap, vary_texcoord0.xy);
- vec4 col_b = texture2D(diffuseMap, vary_texcoord0.xy);
+ // camera above water: class1\deferred\starsF.glsl
+ // camera below water: class1\environment\starsF.glsl
+ vec4 col_a = texture(diffuseMap, vary_texcoord0.xy);
+ vec4 col_b = texture(diffuseMap, vary_texcoord0.xy);
vec4 col = mix(col_b, col_a, blend_factor);
col.rgb *= vertex_color.rgb;
@@ -58,10 +58,9 @@ void main()
col.a = (col.a * factor) * 32.0f;
col.a *= twinkle();
- frag_data[0] = col;
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
-
- gl_FragDepth = 0.99995f;
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = col;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
index bb2a2ee72b..726508607d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/starsV.glsl
@@ -27,21 +27,23 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
uniform float time;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 screenpos;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
+out vec2 screenpos;
void main()
{
//transform vertex
vec4 pos = modelview_projection_matrix * vec4(position, 1.0);
-// bias z to fix SL-9806 and get stars to depth test against clouds
- pos.z += 0.001f;
+
+ // smash to far clip plane to
+ // avoid rendering on top of moon (do NOT write to gl_FragDepth, it's slow)
+ pos.z = pos.w;
gl_Position = pos;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index b2fa5d8a25..fd343ed2dc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -23,42 +23,31 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
vec3 srgb_to_linear(vec3 c);
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
uniform sampler2D diffuseMap;
uniform sampler2D altDiffuseMap;
uniform float blend_factor; // interp factor between sunDisc A/B
-VARYING vec2 vary_texcoord0;
-VARYING float sun_fade;
+in vec2 vary_texcoord0;
+in float sun_fade;
void main()
{
- vec4 sunDiscA = texture2D(diffuseMap, vary_texcoord0.xy);
- vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscA = texture(diffuseMap, vary_texcoord0.xy);
+ vec4 sunDiscB = texture(altDiffuseMap, vary_texcoord0.xy);
vec4 c = mix(sunDiscA, sunDiscB, blend_factor);
- //c.rgb = fullbrightAtmosTransport(c.rgb);
- c.rgb = fullbrightScaleSoftClip(c.rgb);
// SL-9806 stars poke through
//c.a *= sun_fade;
- frag_data[0] = c;
+ frag_data[0] = vec4(0);
frag_data[1] = vec4(0.0f);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
-
- gl_FragDepth = 0.999988f;
+ frag_data[2] = vec4(0.0, 1.0, 0.0, GBUFFER_FLAG_SKIP_ATMOS);
+ frag_data[3] = c;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
index 0d117c6bc7..9a8d791a1d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscV.glsl
@@ -27,11 +27,11 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
-VARYING float sun_fade;
+out vec2 vary_texcoord0;
+out float sun_fade;
void calcAtmospherics(vec3 eye_pos);
@@ -44,6 +44,8 @@ void main()
sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
+ // smash to *almost* far clip plane -- behind clouds but in front of stars
+ pos.z = pos.w*0.999999;
gl_Position = pos;
calcAtmospherics(pos.xyz);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
deleted file mode 100644
index 7329efe3f7..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file sunLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//class 1, no shadow, no SSAO, should never be called
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-void main()
-{
- frag_color = vec4(0,0,0,0);
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
deleted file mode 100644
index 15f141cbe5..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file sunLightSSAOF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 1 -- no shadow, SSAO only
-
-uniform sampler2DRect normalMap;
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-vec3 getNorm(vec2 pos_screen);
-vec4 getPosition(vec2 pos_screen);
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color[0] = 1.0;
- frag_color[1] = calcAmbientOcclusion(pos, norm, pos_screen);
- frag_color[2] = 1.0;
- frag_color[3] = 1.0;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
deleted file mode 100644
index 473d6df8fa..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightV.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file sunLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
-
-uniform vec2 screen_res;
-
-void main()
-{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
-
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 6b6eed9db8..f6d509e2c6 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -25,11 +25,7 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform sampler2D detail_0;
uniform sampler2D detail_1;
@@ -37,10 +33,10 @@ uniform sampler2D detail_2;
uniform sampler2D detail_3;
uniform sampler2D alpha_ramp;
-VARYING vec3 pos;
-VARYING vec3 vary_normal;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
+in vec3 pos;
+in vec3 vary_normal;
+in vec4 vary_texcoord0;
+in vec4 vary_texcoord1;
vec2 encode_normal(vec3 n);
@@ -48,14 +44,14 @@ void main()
{
/// Note: This should duplicate the blending functionality currently used for the terrain rendering.
- vec4 color0 = texture2D(detail_0, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
+ vec4 color0 = texture(detail_0, vary_texcoord0.xy);
+ vec4 color1 = texture(detail_1, vary_texcoord0.xy);
+ vec4 color2 = texture(detail_2, vary_texcoord0.xy);
+ vec4 color3 = texture(detail_3, vary_texcoord0.xy);
- float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
- float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
- float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
+ float alpha1 = texture(alpha_ramp, vary_texcoord0.zw).a;
+ float alpha2 = texture(alpha_ramp,vary_texcoord1.xy).a;
+ float alphaFinal = texture(alpha_ramp, vary_texcoord1.zw).a;
vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
outColor.a = 0.0; // yes, downstream atmospherics
@@ -63,6 +59,7 @@ void main()
frag_data[0] = outColor;
frag_data[1] = vec4(0.0,0.0,0.0,-1.0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
index f42cb6ff6d..f6d3b59e85 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl
@@ -27,16 +27,16 @@ uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
+in vec3 position;
+in vec3 normal;
+in vec4 diffuse_color;
+in vec2 texcoord0;
+in vec2 texcoord1;
-VARYING vec3 pos;
-VARYING vec3 vary_normal;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
+out vec3 pos;
+out vec3 vary_normal;
+out vec4 vary_texcoord0;
+out vec4 vary_texcoord1;
uniform vec4 object_plane_s;
uniform vec4 object_plane_t;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
new file mode 100644
index 0000000000..636dfed4ba
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl
@@ -0,0 +1,122 @@
+/**
+ * @file class1/deferred/textureUtilV.glsl
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2023, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// This shader code is taken from the sample code on the KHR_texture_transform
+// spec page page, plus or minus some sign error corrections (I think because the GLSL
+// matrix constructor is backwards?):
+// https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_texture_transform
+// Previously (6494eed242b1), we passed in a single, precalculated matrix
+// uniform per transform into the shaders. However, that was found to produce
+// small-but-noticeable discrepancies with the GLTF sample model
+// "TextureTransformTest", likely due to numerical precision differences. In
+// the interest of parity with other renderers, calculate the transform
+// directly in the shader. -Cosmic,2023-02-24
+vec2 khr_texture_transform(vec2 texcoord, vec2 scale, float rotation, vec2 offset)
+{
+ mat3 scale_mat = mat3(scale.x,0,0, 0,scale.y,0, 0,0,1);
+ mat3 offset_mat = mat3(1,0,0, 0,1,0, offset.x, offset.y, 1);
+ mat3 rotation_mat = mat3(
+ cos(rotation),-sin(rotation), 0,
+ sin(rotation), cos(rotation), 0,
+ 0, 0, 1
+ );
+
+ mat3 transform = offset_mat * rotation_mat * scale_mat;
+
+ return (transform * vec3(texcoord, 1)).xy;
+}
+
+// vertex_texcoord - The UV texture coordinates sampled from the vertex at
+// runtime. Per SL convention, this is in a right-handed UV coordinate
+// system. Collada models also have right-handed UVs.
+// khr_gltf_transform - The texture transform matrix as defined in the
+// KHR_texture_transform GLTF extension spec. It assumes a left-handed UV
+// coordinate system. GLTF models also have left-handed UVs.
+// sl_animation_transform - The texture transform matrix for texture
+// animations, available through LSL script functions such as
+// LlSetTextureAnim. It assumes a right-handed UV coordinate system.
+// texcoord - The final texcoord to use for image sampling
+vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform)
+{
+ vec2 texcoord = vertex_texcoord;
+
+ // Apply texture animation first to avoid shearing and other artifacts
+ texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy;
+ // Convert to left-handed coordinate system. The offset of 1 is necessary
+ // for rotations to be applied correctly.
+ texcoord.y = 1.0 - texcoord.y;
+ texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy);
+ // Convert back to right-handed coordinate system
+ texcoord.y = 1.0 - texcoord.y;
+
+ // To make things more confusing, all SL image assets are upside-down
+ // We may need an additional sign flip here when we implement a Vulkan backend
+
+ return texcoord;
+}
+
+// Take the rotation only from both transforms and apply to the tangent. This
+// accounts for the change of the topology of the normal texture when a texture
+// rotation is applied to it.
+// *HACK: Assume the imported GLTF model did not have both normal texture
+// transforms and tangent vertices. The use of this function is inconsistent
+// with the GLTF sample viewer when that is the case. See getNormalInfo in
+// https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Viewer/47a191931461a6f2e14de48d6da0f0eb6ec2d147/source/Renderer/shaders/material_info.glsl
+// We may want to account for this case during GLTF model import.
+// -Cosmic,2023-06-06
+vec3 tangent_space_transform(vec4 vertex_tangent, vec3 vertex_normal, vec4[2] khr_gltf_transform, mat4 sl_animation_transform)
+{
+ vec2 weights = vec2(0, 1);
+
+ // Apply texture animation first to avoid shearing and other artifacts (rotation only)
+ mat2 sl_rot_scale;
+ sl_rot_scale[0][0] = sl_animation_transform[0][0];
+ sl_rot_scale[0][1] = sl_animation_transform[0][1];
+ sl_rot_scale[1][0] = sl_animation_transform[1][0];
+ sl_rot_scale[1][1] = sl_animation_transform[1][1];
+ weights = sl_rot_scale * weights;
+ // Remove scale
+ weights = normalize(weights);
+
+ // Convert to left-handed coordinate system
+ weights.y = -weights.y;
+
+ // Apply KHR_texture_transform (rotation only)
+ float khr_rotation = khr_gltf_transform[0].z;
+ mat2 khr_rotation_mat = mat2(
+ cos(khr_rotation),-sin(khr_rotation),
+ sin(khr_rotation), cos(khr_rotation)
+ );
+ weights = khr_rotation_mat * weights;
+
+ // Convert back to right-handed coordinate system
+ weights.y = -weights.y;
+
+ // Similar to the MikkTSpace-compatible method of extracting the binormal
+ // from the normal and tangent, as seen in the fragment shader
+ vec3 vertex_binormal = vertex_tangent.w * cross(vertex_normal, vertex_tangent.xyz);
+
+ return (weights.x * vertex_binormal.xyz) + (weights.y * vertex_tangent.xyz);
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 89e354558a..e2d87e68fa 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -25,17 +25,13 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
+out vec4 frag_data[4];
uniform sampler2D diffuseMap;
-VARYING vec4 vertex_color;
-VARYING vec3 vary_normal;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec3 vary_normal;
+in vec2 vary_texcoord0;
uniform float minimum_alpha;
@@ -43,7 +39,7 @@ vec2 encode_normal(vec3 n);
void main()
{
- vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
if (col.a < minimum_alpha)
{
discard;
@@ -52,5 +48,6 @@ void main()
frag_data[0] = vec4(vertex_color.rgb*col.rgb, 0.0);
frag_data[1] = vec4(0,0,0,0);
vec3 nvn = normalize(vary_normal);
- frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, 0.0);
+ frag_data[2] = vec4(encode_normal(nvn.xyz), 0.0, GBUFFER_FLAG_HAS_ATMOS);
+ frag_data[3] = vec4(0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
index e34d75ba1d..7dcab640f2 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowF.glsl
@@ -25,22 +25,18 @@
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
+
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- float alpha = texture2D(diffuseMap, vary_texcoord0.xy).a;
+ float alpha = texture(diffuseMap, vary_texcoord0.xy).a;
if (alpha < minimum_alpha)
{
@@ -48,6 +44,4 @@ void main()
}
frag_color = vec4(1,1,1,1);
-
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
index d9ca6d3a46..f5192c3009 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowSkinnedV.glsl
@@ -27,11 +27,10 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
mat4 getObjectSkinnedTransform();
@@ -43,11 +42,7 @@ void main()
mat = modelview_matrix * mat;
vec4 pos = mat * vec4(position.xyz, 1.0);
- pos = projection_matrix * pos;
-
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+ gl_Position = projection_matrix * pos;
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
index e472a75304..3102c870fc 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeShadowV.glsl
@@ -26,20 +26,15 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec4 post_pos;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
+ gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
index 3b6571a24a..ce8a10712c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl
@@ -27,13 +27,13 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
uniform mat3 normal_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec3 vary_normal;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec3 vary_normal;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
deleted file mode 100644
index 9a5debb3c1..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/underWaterF.glsl
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * @file underWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform sampler2D screenDepth;
-
-uniform vec4 fogCol;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform vec2 fbScale;
-uniform float refScale;
-uniform float znear;
-uniform float zfar;
-uniform float kd;
-uniform vec4 waterPlane;
-uniform vec3 eyeVec;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec2 encode_normal(vec3 n);
-
-void main()
-{
- vec4 color;
-
- //get detail normals
- vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wavef = normalize(wave1+wave2+wave3);
-
- //figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
-
- vec4 fb = texture2D(screenTex, distort);
-
- frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
- frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, env intens, atmo kill
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
deleted file mode 100644
index a157e9c017..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ /dev/null
@@ -1,184 +0,0 @@
-/**
- * @file class1/deferred/waterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
-uniform int water_edge;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec2 encode_normal(vec3 n);
-vec3 scaleSoftClip(vec3 l);
-vec3 srgb_to_linear(vec3 c);
-vec3 linear_to_srgb(vec3 c);
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
-{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
-}
-
-void main()
-{
- vec4 color;
- float dist = length(view.xyz);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
-
- refcol = mix(baseCol*df2, refcol, dweight);
-
- //get specular component
- float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999f);
-
- vec4 pos = vary_position;
-
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
-
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
-
- //frag_data[0] = color;
-
- // TODO: The non-obvious assignment below is copied from the pre-EEP WL shader code
- // Unfortunately, fixing it causes a mismatch for EEP, and so it remains... for now
- // SL-12975 (unfix pre-EEP broken alpha)
- frag_data[0] = vec4(color.rgb, color); // Effectively, color.rgbr
-
-
- frag_data[1] = vec4(0); // speccolor, spec
- frag_data[2] = vec4(encode_normal(screenspacewavef.xyz), 0.05, 0);// normalxy, 0, 0
-}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
deleted file mode 100644
index 8863869e44..0000000000
--- a/indra/newview/app_settings/shaders/class1/deferred/waterV.glsl
+++ /dev/null
@@ -1,99 +0,0 @@
-/**
- * @file waterV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec2 waveDir1;
-uniform vec2 waveDir2;
-uniform float time;
-uniform vec3 eyeVec;
-uniform float waterHeight;
-
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-VARYING vec4 vary_position;
-
-float wave(vec2 v, float t, float f, vec2 d, float s)
-{
- return (dot(d, v)*f + t*s)*f;
-}
-
-void main()
-{
- //transform vertex
- vec4 pos = vec4(position.xyz, 1.0);
- mat4 modelViewProj = modelview_projection_matrix;
-
- vec4 oPosition;
-
- //get view vector
- vec3 oEyeVec;
- oEyeVec.xyz = pos.xyz-eyeVec;
-
- float d = length(oEyeVec.xy);
- float ld = min(d, 2560.0);
-
- pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
- view.xyz = oEyeVec;
-
- d = clamp(ld/1536.0-0.5, 0.0, 1.0);
- d *= d;
-
- oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
- vary_position = modelview_matrix * oPosition;
- oPosition = modelViewProj * oPosition;
-
- refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
-
- //get wave position parameter (create sweeping horizontal waves)
- vec3 v = pos.xyz;
- v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
-
- //push position for further horizon effect.
- pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
- pos.w = 1.0;
- pos = modelview_matrix*pos;
-
- calcAtmospherics(pos.xyz);
-
- //pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
- //get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + waveDir2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + waveDir1 * time * 0.1;
- view.w = bigWave.y;
- refCoord.w = bigWave.x;
-
- gl_Position = oPosition;
-}
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
index 36563982ba..b5437d43d2 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractF.glsl
@@ -23,34 +23,41 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseMap;
+uniform sampler2D diffuseMap;
+#if HAS_NOISE
+uniform sampler2D glowNoiseMap;
+uniform vec2 screen_res;
+#endif
uniform float minLuminance;
uniform float maxExtractAlpha;
uniform vec3 lumWeights;
uniform vec3 warmthWeights;
uniform float warmthAmount;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- vec4 col = texture2DRect(diffuseMap, vary_texcoord0.xy);
+ vec4 col = texture(diffuseMap, vary_texcoord0.xy);
/// CALCULATING LUMINANCE (Using NTSC lum weights)
/// http://en.wikipedia.org/wiki/Luma_%28video%29
float lum = smoothstep(minLuminance, minLuminance+1.0, dot(col.rgb, lumWeights ) );
float warmth = smoothstep(minLuminance, minLuminance+1.0, max(col.r * warmthWeights.r, max(col.g * warmthWeights.g, col.b * warmthWeights.b)) );
- frag_color.rgb = col.rgb;
+#if HAS_NOISE
+ float TRUE_NOISE_RES = 128; // See mTrueNoiseMap
+ // *NOTE: Usually this is vary_fragcoord not vary_texcoord0, but glow extraction is in screen space
+ vec3 glow_noise = texture(glowNoiseMap, vary_texcoord0.xy * (screen_res / TRUE_NOISE_RES)).xyz;
+ // Dithering. Reduces banding effects in the reduced precision glow buffer.
+ float NOISE_DEPTH = 64.0;
+ col.rgb += glow_noise / NOISE_DEPTH;
+ col.rgb = max(col.rgb, vec3(0));
+#endif
+ frag_color.rgb = col.rgb;
frag_color.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
index 1396dc6973..ccda75596d 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowExtractV.glsl
@@ -25,14 +25,13 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
- gl_Position = modelview_projection_matrix * vec4(position, 1.0);
+ gl_Position = vec4(position, 1.0);
- vary_texcoord0.xy = texcoord0;
+ vary_texcoord0.xy = position.xy * 0.5 + 0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
index c1f6af9f57..8718dd8b52 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowF.glsl
@@ -23,19 +23,15 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
uniform float glowStrength;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-VARYING vec4 vary_texcoord2;
-VARYING vec4 vary_texcoord3;
+in vec4 vary_texcoord0;
+in vec4 vary_texcoord1;
+in vec4 vary_texcoord2;
+in vec4 vary_texcoord3;
void main()
{
@@ -47,14 +43,14 @@ void main()
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, vary_texcoord0.xy);
- col += kern[1] * texture2D(diffuseMap, vary_texcoord1.xy);
- col += kern[2] * texture2D(diffuseMap, vary_texcoord2.xy);
- col += kern[3] * texture2D(diffuseMap, vary_texcoord3.xy);
- col += kern[4] * texture2D(diffuseMap, vary_texcoord0.zw);
- col += kern[5] * texture2D(diffuseMap, vary_texcoord1.zw);
- col += kern[6] * texture2D(diffuseMap, vary_texcoord2.zw);
- col += kern[7] * texture2D(diffuseMap, vary_texcoord3.zw);
+ col += kern[0] * texture(diffuseMap, vary_texcoord0.xy);
+ col += kern[1] * texture(diffuseMap, vary_texcoord1.xy);
+ col += kern[2] * texture(diffuseMap, vary_texcoord2.xy);
+ col += kern[3] * texture(diffuseMap, vary_texcoord3.xy);
+ col += kern[4] * texture(diffuseMap, vary_texcoord0.zw);
+ col += kern[5] * texture(diffuseMap, vary_texcoord1.zw);
+ col += kern[6] * texture(diffuseMap, vary_texcoord2.zw);
+ col += kern[7] * texture(diffuseMap, vary_texcoord3.zw);
- frag_color = vec4(col.rgb * glowStrength, col.a);
+ frag_color = max(vec4(col.rgb * glowStrength, col.a), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
index cdb2281578..60ec4e6f3b 100644
--- a/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
+++ b/indra/newview/app_settings/shaders/class1/effects/glowV.glsl
@@ -25,26 +25,28 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
uniform vec2 glowDelta;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-VARYING vec4 vary_texcoord2;
-VARYING vec4 vary_texcoord3;
+out vec4 vary_texcoord0;
+out vec4 vary_texcoord1;
+out vec4 vary_texcoord2;
+out vec4 vary_texcoord3;
void main()
{
- gl_Position = modelview_projection_matrix * vec4(position, 1.0);
+ gl_Position = vec4(position, 1.0);
- vary_texcoord0.xy = texcoord0 + glowDelta*(-3.5);
- vary_texcoord1.xy = texcoord0 + glowDelta*(-2.5);
- vary_texcoord2.xy = texcoord0 + glowDelta*(-1.5);
- vary_texcoord3.xy = texcoord0 + glowDelta*(-0.5);
- vary_texcoord0.zw = texcoord0 + glowDelta*(0.5);
- vary_texcoord1.zw = texcoord0 + glowDelta*(1.5);
- vary_texcoord2.zw = texcoord0 + glowDelta*(2.5);
- vary_texcoord3.zw = texcoord0 + glowDelta*(3.5);
+ vec2 texcoord = position.xy * 0.5 + 0.5;
+
+
+ vary_texcoord0.xy = texcoord + glowDelta*(-3.5);
+ vary_texcoord1.xy = texcoord + glowDelta*(-2.5);
+ vary_texcoord2.xy = texcoord + glowDelta*(-1.5);
+ vary_texcoord3.xy = texcoord + glowDelta*(-0.5);
+ vary_texcoord0.zw = texcoord + glowDelta*(0.5);
+ vary_texcoord1.zw = texcoord + glowDelta*(1.5);
+ vary_texcoord2.zw = texcoord + glowDelta*(2.5);
+ vary_texcoord3.zw = texcoord + glowDelta*(3.5);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
index 4a8b892c3a..e3fd10447e 100644
--- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl
@@ -23,6 +23,8 @@
* $/LicenseInfo$
*/
+ uniform sampler2D exposureMap;
+
vec3 srgb_to_linear(vec3 cs)
{
vec3 low_range = cs / vec3(12.92);
@@ -72,7 +74,7 @@ vec3 rgb2hsv(vec3 c)
vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
float d = q.x - min(q.w, q.y);
- float e = 1.0e-10;
+ float e = 1.0e-3;
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
@@ -82,3 +84,32 @@ vec3 hsv2rgb(vec3 c)
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
+
+const mat3 inv_ACESOutputMat = mat3(0.643038, 0.0592687, 0.0059619, 0.311187, 0.931436, 0.063929, 0.0457755, 0.00929492, 0.930118 );
+
+const mat3 inv_ACESInputMat = mat3( 1.76474, -0.147028, -0.0363368, -0.675778, 1.16025, -0.162436, -0.0889633, -0.0132237, 1.19877 );
+
+vec3 inv_RRTAndODTFit(vec3 x)
+{
+ float A = 0.0245786;
+ float B = 0.000090537;
+ float C = 0.983729;
+ float D = 0.4329510;
+ float E = 0.238081;
+
+ return (A - D * x)/(2.0 * (C * x - 1.0)) - sqrt(pow(D * x - A, vec3(2.0)) - 4.0 * (C * x - 1.0) * (B + E * x))/(2.0 * (C * x - 1.0));
+}
+
+// experimental inverse of ACES Hill tonemapping
+vec3 inv_toneMapACES_Hill(vec3 color)
+{
+ color = inv_ACESOutputMat * color;
+
+ // Apply RRT and ODT
+ color = inv_RRTAndODTFit(color);
+
+ color = inv_ACESInputMat * color;
+
+ return color;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
deleted file mode 100644
index 6b68ed4169..0000000000
--- a/indra/newview/app_settings/shaders/class1/environment/terrainF.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file class1\environment\terrainF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-
-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, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
-
- float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
- float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
- float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- /// Add WL Components
- outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb);
-
- frag_color = vec4(scaleSoftClip(outColor.rgb), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
deleted file mode 100644
index ef27848d37..0000000000
--- a/indra/newview/app_settings/shaders/class1/environment/terrainV.glsl
+++ /dev/null
@@ -1,88 +0,0 @@
-/**
- * @file class1\environment\terrainV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-uniform vec4 object_plane_t;
-uniform vec4 object_plane_s;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
-ATTRIBUTE vec4 diffuse_color;
-
-VARYING vec4 vertex_color;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-
-void calcAtmospherics(vec3 inPositionEye);
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-
-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 = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- vec4 pos = modelview_matrix * vec4(position.xyz, 1.0);
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- /// Potentially better without it for water.
- pos /= pos.w;
-
- vec4 color = calcLighting(pos.xyz, norm, /*diffuse_color*/vec4(1));
-
- vertex_color = color;
-
- // Transform and pass tex coords
- vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
- vec4 t = vec4(texcoord1,0,1);
-
- vary_texcoord0.zw = t.xy;
- vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
- vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
deleted file mode 100644
index e53bb46177..0000000000
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterF.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file class1\environment\terrainWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-
-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, vary_texcoord0.xy);
- vec4 color1 = texture2D(detail_1, vary_texcoord0.xy);
- vec4 color2 = texture2D(detail_2, vary_texcoord0.xy);
- vec4 color3 = texture2D(detail_3, vary_texcoord0.xy);
-
- float alpha1 = texture2D(alpha_ramp, vary_texcoord0.zw).a;
- float alpha2 = texture2D(alpha_ramp,vary_texcoord1.xy).a;
- float alphaFinal = texture2D(alpha_ramp, vary_texcoord1.zw).a;
- vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal );
-
- /// Add WL Components
- outColor.rgb = atmosLighting(outColor.rgb * vertex_color.rgb);
-
- outColor = applyWaterFog(outColor);
- frag_color = outColor;
-}
diff --git a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl b/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
deleted file mode 100644
index a075cfeef2..0000000000
--- a/indra/newview/app_settings/shaders/class1/environment/terrainWaterV.glsl
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file class1\environment\terrainV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-uniform vec4 object_plane_t;
-uniform vec4 object_plane_s;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
-ATTRIBUTE vec4 diffuse_color;
-
-VARYING vec4 vertex_color;
-VARYING vec4 vary_texcoord0;
-VARYING vec4 vary_texcoord1;
-
-void calcAtmospherics(vec3 inPositionEye);
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-
-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 = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- vec4 pos = modelview_matrix * vec4(position.xyz, 1.0);
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm, vec4(1.0));
-
- vertex_color.rgb = color.rgb;
-
- // Transform and pass tex coords
- vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
- vec4 t = vec4(texcoord1,0,1);
-
- vary_texcoord0.zw = t.xy;
- vary_texcoord1.xy = t.xy-vec2(2.0, 0.0);
- vary_texcoord1.zw = t.xy-vec2(1.0, 0.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
index d370997123..075397d96c 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterF.glsl
@@ -1,9 +1,9 @@
/**
* @file waterF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,147 +22,13 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-vec3 scaleSoftClip(vec3 inColor);
-vec3 atmosTransport(vec3 inColor);
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
-{
- vec3 n = mix(bump1, bump2, blend_factor);
- return n;
-}
+ // error fallback on compilation failure
+out vec4 frag_color;
-void main()
+void main()
{
- vec4 color;
-
- float dist = length(view.xy);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec2 bigwave = vec2(refCoord.w, view.w);
- vec3 wave1_a = texture2D(bumpMap, bigwave ).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, bigwave ).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
-
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
- refcol = mix(baseCol*df2, refcol, dweight);
-
- //get specular component
- float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
- color.rgb += spec * specular;
-
- color.rgb = atmosTransport(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
- color.a = spec * sunAngle2;
-
- frag_color = color;
-
-#if defined(WATER_EDGE)
- gl_FragDepth = 0.9999847f;
-#endif
-
+ frag_color = vec4(1,0,1,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
index df640cba05..cfdb393b34 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl
@@ -32,6 +32,9 @@ uniform float waterFogKS;
vec3 getPositionEye();
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
vec4 applyWaterFogView(vec3 pos, vec4 color)
{
vec3 view = normalize(pos);
@@ -66,14 +69,36 @@ vec4 applyWaterFogView(vec3 pos, vec4 color)
float D = pow(0.98, l*kd);
color.rgb = color.rgb * D + kc.rgb * L;
- color.a = kc.a + color.a;
return color;
}
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit)
+{
+ color.rgb = linear_to_srgb(color.rgb);
+ color = applyWaterFogView(pos, color);
+ color.rgb = srgb_to_linear(color.rgb);
+ return color;
+}
+
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit)
+{
+ if (dot(pos, waterPlane.xyz) + waterPlane.w > 0.0)
+ {
+ return color;
+ }
+
+ return applyWaterFogViewLinearNoClip(pos, color, sunlit);
+}
+
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color)
+{
+ return applyWaterFogViewLinear(pos, color, vec3(1));
+}
+
vec4 applyWaterFog(vec4 color)
{
//normalize view vector
- return applyWaterFogView(getPositionEye(), color);
+ return applyWaterFogViewLinear(getPositionEye(), color);
}
diff --git a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
index cc41e3f740..5a3845b1a3 100644
--- a/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/environment/waterV.glsl
@@ -24,9 +24,10 @@
*/
uniform mat4 modelview_matrix;
+uniform mat3 normal_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
void calcAtmospherics(vec3 inPositionEye);
@@ -36,10 +37,16 @@ uniform vec2 waveDir2;
uniform float time;
uniform vec3 eyeVec;
uniform float waterHeight;
+uniform vec3 lightDir;
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
+out vec4 refCoord;
+out vec4 littleWave;
+out vec4 view;
+out vec3 vary_position;
+out vec3 vary_light_dir;
+out vec3 vary_tangent;
+out vec3 vary_normal;
+out vec2 vary_fragcoord;
float wave(vec2 v, float t, float f, vec2 d, float s)
{
@@ -52,6 +59,11 @@ void main()
vec4 pos = vec4(position.xyz, 1.0);
mat4 modelViewProj = modelview_projection_matrix;
+ vary_position = (modelview_matrix * pos).xyz;
+ vary_light_dir = normal_matrix * lightDir;
+ vary_normal = normal_matrix * vec3(0, 0, 1);
+ vary_tangent = normal_matrix * vec3(1, 0, 0);
+
vec4 oPosition;
//get view vector
@@ -63,12 +75,13 @@ void main()
pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
view.xyz = oEyeVec;
-
+
d = clamp(ld/1536.0-0.5, 0.0, 1.0);
d *= d;
oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
+// oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); // SL-11589 remove "U" shaped horizon
+
oPosition = modelViewProj * oPosition;
refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
@@ -83,8 +96,7 @@ void main()
pos = modelview_matrix*pos;
calcAtmospherics(pos.xyz);
-
-
+
//pass wave parameters to pixel shader
vec2 bigWave = (v.xy) * vec2(0.04,0.04) + waveDir1 * time * 0.055;
//get two normal map (detail map) texture coordinates
diff --git a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
index f520f301d9..a46e91c394 100644
--- a/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskF.glsl
@@ -23,26 +23,22 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
uniform float minimum_alpha;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
+in vec2 vary_texcoord0;
+in vec4 vertex_color;
void main()
{
- vec4 col = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
+ vec4 col = vertex_color*texture(diffuseMap, vary_texcoord0.xy);
if (col.a < minimum_alpha)
{
discard;
}
- frag_color = col;
+ frag_color = max(col, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
index 3580d1f27b..a8dac55130 100644
--- a/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/alphamaskV.glsl
@@ -26,12 +26,12 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl
index 1936e0dcaa..06b19c22c9 100644
--- a/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkF.glsl
@@ -23,17 +23,13 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-VARYING vec2 tc0;
+in vec2 tc0;
void main()
{
- frag_color = texture2D(diffuseMap, tc0);
+ frag_color = texture(diffuseMap, tc0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl
index 7beb20ede4..cbcc6bef97 100644
--- a/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/benchmarkV.glsl
@@ -25,9 +25,9 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
-VARYING vec2 tc0;
+out vec2 tc0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
index ac2bc8703b..ee2d652f32 100644
--- a/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/clipF.glsl
@@ -23,16 +23,12 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform vec4 color;
uniform vec4 clip_plane;
-VARYING vec3 vary_position;
+in vec3 vary_position;
void main()
@@ -42,5 +38,5 @@ void main()
discard;
}
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
index e376b25a71..7dd2ef593f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/clipV.glsl
@@ -26,9 +26,9 @@
uniform mat4 modelview_projection_matrix;
uniform mat4 modelview_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
-VARYING vec3 vary_position;
+out vec3 vary_position;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl
index 415181126b..65d3c20091 100644
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/copyF.glsl
@@ -1,9 +1,9 @@
/**
- * @file onetexturenocolorF.glsl
+ * @file copyF.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,17 +23,18 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+in vec2 tc;
-uniform sampler2D tex0;
+uniform sampler2D depthMap;
+uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
+out vec4 frag_color;
void main()
{
- frag_color = texture2D(tex0, vary_texcoord0.xy);
+ frag_color = texture(diffuseMap, tc);
+#if defined(COPY_DEPTH)
+ gl_FragDepth = texture(depthMap, tc).r;
+#endif
}
+
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl
index 254c1d4fc2..ace5da6578 100644
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/copyV.glsl
@@ -1,9 +1,9 @@
/**
- * @file fullbrightF.glsl
+ * @file copyV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,13 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-
+in vec3 position;
+out vec2 tc;
+
void main()
{
- fullbright_lighting();
+ tc = position.xy * 0.5 + 0.5;
+ gl_Position = vec4(position, 1.0);
}
-
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
deleted file mode 100644
index f6b31a5956..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file customalphaF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-uniform float custom_alpha;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
- color.rgb = pow(color.rgb, vec3(0.45));
- color.rgb *= vertex_color.rgb;
- color.a *= max(custom_alpha, vertex_color.a);
- frag_color = color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl b/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
deleted file mode 100644
index 890474d6d8..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/customalphaV.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file customalphaV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
- vertex_color = diffuse_color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
index 67c6baddbb..cefa429639 100644
--- a/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/debugF.glsl
@@ -23,15 +23,11 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform vec4 color;
void main()
{
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
index 153998f1d5..2e32863109 100644
--- a/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/debugV.glsl
@@ -25,7 +25,7 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
deleted file mode 100644
index f8efd7cb4a..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthF.glsl
+++ /dev/null
@@ -1,65 +0,0 @@
-/**
- * @file debugF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D depthMap;
-
-VARYING vec2 tc0;
-VARYING vec2 tc1;
-VARYING vec2 tc2;
-VARYING vec2 tc3;
-VARYING vec2 tc4;
-VARYING vec2 tc5;
-VARYING vec2 tc6;
-VARYING vec2 tc7;
-VARYING vec2 tc8;
-
-void main()
-{
- vec4 depth1 =
- vec4(texture2D(depthMap, tc0).r,
- texture2D(depthMap, tc1).r,
- texture2D(depthMap, tc2).r,
- texture2D(depthMap, tc3).r);
-
- vec4 depth2 =
- vec4(texture2D(depthMap, tc4).r,
- texture2D(depthMap, tc5).r,
- texture2D(depthMap, tc6).r,
- texture2D(depthMap, tc7).r);
-
- depth1 = min(depth1, depth2);
- float depth = min(depth1.x, depth1.y);
- depth = min(depth, depth1.z);
- depth = min(depth, depth1.w);
- depth = min(depth, texture2D(depthMap, tc8).r);
-
- gl_FragDepth = depth;
-}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
deleted file mode 100644
index cff8d9d50f..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthRectF.glsl
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file debugF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect depthMap;
-
-VARYING vec2 tc0;
-VARYING vec2 tc1;
-VARYING vec2 tc2;
-VARYING vec2 tc3;
-VARYING vec2 tc4;
-VARYING vec2 tc5;
-VARYING vec2 tc6;
-VARYING vec2 tc7;
-VARYING vec2 tc8;
-
-void main()
-{
- vec4 depth1 =
- vec4(texture2DRect(depthMap, tc0).r,
- texture2DRect(depthMap, tc1).r,
- texture2DRect(depthMap, tc2).r,
- texture2DRect(depthMap, tc3).r);
-
- vec4 depth2 =
- vec4(texture2DRect(depthMap, tc4).r,
- texture2DRect(depthMap, tc5).r,
- texture2DRect(depthMap, tc6).r,
- texture2DRect(depthMap, tc7).r);
-
- depth1 = min(depth1, depth2);
- float depth = min(depth1.x, depth1.y);
- depth = min(depth, depth1.z);
- depth = min(depth, depth1.w);
- depth = min(depth, texture2DRect(depthMap, tc8).r);
-
- gl_FragDepth = depth;
-}
diff --git a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl b/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
deleted file mode 100644
index 71d80911d6..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/downsampleDepthV.glsl
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file debugV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-uniform vec2 screen_res;
-
-uniform vec2 delta;
-
-VARYING vec2 tc0;
-VARYING vec2 tc1;
-VARYING vec2 tc2;
-VARYING vec2 tc3;
-VARYING vec2 tc4;
-VARYING vec2 tc5;
-VARYING vec2 tc6;
-VARYING vec2 tc7;
-VARYING vec2 tc8;
-
-void main()
-{
- gl_Position = vec4(position, 1.0);
-
- vec2 tc = (position.xy*0.5+0.5)*screen_res;
- tc0 = tc+vec2(-delta.x,-delta.y);
- tc1 = tc+vec2(0,-delta.y);
- tc2 = tc+vec2(delta.x,-delta.y);
- tc3 = tc+vec2(-delta.x,0);
- tc4 = tc+vec2(0,0);
- tc5 = tc+vec2(delta.x,0);
- tc6 = tc+vec2(-delta.x,delta.y);
- tc7 = tc+vec2(0,delta.y);
- tc8 = tc+vec2(delta.x,delta.y);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl
index 345c07a354..eca591d387 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/gaussianF.glsl
@@ -1,9 +1,9 @@
/**
- * @file shadowAlphaMaskF.glsl
+ * @file gaussianF.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,36 +23,31 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2D diffuseMap;
+uniform sampler2D diffuseRect;
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
+uniform float resScale;
-VARYING float pos_w;
+// texture direction, will be <1, 0> or <0, 1>
+uniform vec2 direction;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 pos;
+in vec2 vary_texcoord0;
-vec4 computeMoments(float depth, float a);
+// get linear depth value given a depth buffer sample d and znear and zfar values
+float linearDepth(float d, float znear, float zfar);
void main()
{
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
+ vec3 col = vec3(0,0,0);
- frag_color = computeMoments(length(pos), float a);
+ float w[9] = float[9]( 0.0002, 0.0060, 0.0606, 0.2417, 0.3829, 0.2417, 0.0606, 0.0060, 0.0002 );
+
+ for (int i = 0; i < 9; ++i)
+ {
+ vec2 tc = vary_texcoord0 + (i-4)*direction*resScale;
+ col += texture(diffuseRect, tc).rgb * w[i];
+ }
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
+ frag_color = max(vec4(col, 0.0), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
index b5bbbb5c73..fa8aa5c7fe 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineF.glsl
@@ -23,24 +23,16 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2D glowMap;
-uniform sampler2DRect screenMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D emissiveRect;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+in vec2 tc;
void main()
{
- frag_color = texture2D(glowMap, vary_texcoord0.xy) +
- texture2DRect(screenMap, vary_texcoord1.xy);
+ frag_color = texture(diffuseRect, tc) + texture(emissiveRect, tc);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
index a9e7ea1de8..3d4035620f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAF.glsl
@@ -23,24 +23,19 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
+uniform sampler2D diffuseRect;
uniform vec2 screen_res;
-VARYING vec2 vary_tc;
+
+in vec2 vary_tc;
void main()
{
- vec3 col = texture2DRect(diffuseRect, vary_tc*screen_res).rgb;
-
- frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
+ vec3 col = texture(diffuseRect, vary_tc).rgb;
+
+ frag_color = vec4(col.rgb, dot(col.rgb, vec3(0.299, 0.587, 0.144)));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
index 058f3b1b82..fa67b13e4d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineFXAAV.glsl
@@ -23,15 +23,14 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
-VARYING vec2 vary_tc;
+out vec2 vary_tc;
void main()
{
- vec4 pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
vary_tc = pos.xy*0.5+0.5;
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
index f7970b7f78..8fa08a18c3 100644
--- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl
@@ -25,17 +25,13 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
+in vec3 position;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+out vec2 tc;
void main()
{
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
- vary_texcoord1 = texcoord1;
+ gl_Position = vec4(position.xyz, 1.0);
+ tc = position.xy * 0.5 + 0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
index 6cc9bbbea2..9bba1b2e18 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightF.glsl
@@ -23,18 +23,14 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform vec4 color;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- frag_color = color*texture2D(diffuseMap, vary_texcoord0.xy);
+ frag_color = max(color*texture(diffuseMap, vary_texcoord0.xy), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
index 947c2b0065..0253c7236d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightNormV.glsl
@@ -26,12 +26,12 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
-ATTRIBUTE vec2 texcoord2;
+in vec3 position;
+in vec2 texcoord0;
+in vec2 texcoord1;
+in vec2 texcoord2;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
index c5d102b739..9f7ff8337a 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightSpecV.glsl
@@ -26,12 +26,12 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
-ATTRIBUTE vec2 texcoord2;
+in vec3 position;
+in vec2 texcoord0;
+in vec2 texcoord1;
+in vec2 texcoord2;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
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 0b362cf46c..481b7a3b1d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/highlightV.glsl
@@ -26,10 +26,10 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
new file mode 100644
index 0000000000..633c928e6b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file irradianceGenV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform mat4 modelview_matrix;
+
+in vec3 position;
+
+out vec3 vary_dir;
+
+void main()
+{
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
+}
+
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
index 5c479d27a9..75ff19e470 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionCubeV.glsl
@@ -25,7 +25,7 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
uniform vec3 box_center;
uniform vec3 box_size;
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
index db130e456c..f5d2804c7f 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionF.glsl
@@ -23,13 +23,13 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
+out vec4 frag_data[4];
void main()
{
- frag_color = vec4(1,1,1,1);
+ // emissive red PBR material for debugging
+ frag_data[0] = vec4(0, 0, 0, 0);
+ frag_data[1] = vec4(0, 0, 0, 0);
+ frag_data[2] = vec4(1, 0, 0, GBUFFER_FLAG_HAS_PBR);
+ frag_data[3] = vec4(1, 0, 0, 0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl
index 7305065a05..1ff9c347b6 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionSkinnedV.glsl
@@ -26,7 +26,7 @@
uniform mat4 projection_matrix;
uniform mat4 modelview_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
index c26fa08ddc..b44c746fa7 100644
--- a/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/occlusionV.glsl
@@ -25,7 +25,7 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl
index f1400c9b44..a85d055a5b 100644
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterF.glsl
@@ -23,20 +23,16 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D tex0;
uniform float tolerance;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- frag_color = texture2D(tex0, vary_texcoord0.xy);
+ frag_color = texture(tex0, vary_texcoord0.xy);
if(frag_color[0] + frag_color[1] + frag_color[2] < tolerance)
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl
index a33ef7e92c..1b8411603a 100644
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/onetexturefilterV.glsl
@@ -25,10 +25,10 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
deleted file mode 100644
index 6b9986c8d7..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/onetexturenocolorV.glsl
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file onetexturenocolorV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- gl_Position = modelview_projection_matrix * vec4(position, 1);
- vary_texcoord0 = texcoord0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
index 7379360e17..fac22be6de 100644
--- a/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingF.glsl
@@ -23,13 +23,9 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-VARYING vec4 vertex_color;
+in vec4 vertex_color;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl
index 19fa607307..4f08df839d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingNoNormalV.glsl
@@ -25,10 +25,10 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
+in vec3 position;
+in vec4 diffuse_color;
-VARYING vec4 vertex_color;
+out vec4 vertex_color;
uniform float tint;
uniform float alpha_scale;
diff --git a/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl
index 91f252cf1e..9e77927cb8 100644
--- a/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/pathfindingV.glsl
@@ -25,11 +25,11 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
+in vec3 position;
+in vec4 diffuse_color;
+in vec3 normal;
-VARYING vec4 vertex_color;
+out vec4 vertex_color;
uniform float tint;
uniform float ambiance;
diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
new file mode 100644
index 0000000000..9ecdf0bf77
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl
@@ -0,0 +1,167 @@
+/**
+ * @file radianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+in vec3 vary_dir;
+
+//uniform float roughness;
+
+uniform float mipLevel;
+uniform int u_width;
+uniform float max_probe_lod;
+
+
+// =============================================================================================================
+// Parts of this file are (c) 2018 Sascha Willems
+// SNIPPED FROM https://github.com/SaschaWillems/Vulkan-glTF-PBR/blob/master/data/shaders/prefilterenvmap.frag
+/*
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+// =============================================================================================================
+
+const float PI = 3.1415926536;
+
+// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
+float random(vec2 co)
+{
+ float a = 12.9898;
+ float b = 78.233;
+ float c = 43758.5453;
+ float dt= dot(co.xy ,vec2(a,b));
+ float sn= mod(dt,3.14);
+ return fract(sin(sn) * c);
+}
+
+vec2 hammersley2d(uint i, uint N)
+{
+ // Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+ uint bits = (i << 16u) | (i >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ float rdi = float(bits) * 2.3283064365386963e-10;
+ return vec2(float(i) /float(N), rdi);
+}
+
+// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
+vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
+{
+ // Maps a 2D point to a hemisphere with spread based on roughness
+ float alpha = roughness * roughness;
+ float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
+ float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
+ float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
+ vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
+
+ // Tangent space
+ vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
+ vec3 tangentX = normalize(cross(up, normal));
+ vec3 tangentY = normalize(cross(normal, tangentX));
+
+ // Convert to world Space
+ return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
+}
+
+// Normal Distribution function
+float D_GGX(float dotNH, float roughness)
+{
+ float alpha = roughness * roughness;
+ float alpha2 = alpha * alpha;
+ float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
+ return (alpha2)/(PI * denom*denom);
+}
+
+vec4 prefilterEnvMap(vec3 R)
+{
+ vec3 N = R;
+ vec3 V = R;
+ vec4 color = vec4(0.0);
+ float totalWeight = 0.0;
+ float envMapDim = float(textureSize(reflectionProbes, 0).s);
+ float roughness = mipLevel/max_probe_lod;
+ int numSamples = max(int(32*roughness), 1);
+
+ float numMips = max_probe_lod+1;
+
+ for(uint i = 0u; i < numSamples; i++) {
+ vec2 Xi = hammersley2d(i, numSamples);
+ vec3 H = importanceSample_GGX(Xi, roughness, N);
+ vec3 L = 2.0 * dot(V, H) * H - V;
+ float dotNL = clamp(dot(N, L), 0.0, 1.0);
+ if(dotNL > 0.0) {
+ // Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
+
+ float dotNH = clamp(dot(N, H), 0.0, 1.0);
+ float dotVH = clamp(dot(V, H), 0.0, 1.0);
+
+ // Probability Distribution Function
+ float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
+ // Slid angle of current smple
+ float omegaS = 1.0 / (float(numSamples) * pdf);
+ // Solid angle of 1 pixel across all cube faces
+ float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
+ // Biased (+1.0) mip level for better result
+ float mipLevel = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, max_probe_lod);
+ color += textureLod(reflectionProbes, vec4(L, sourceIdx), mipLevel) * dotNL;
+ totalWeight += dotNL;
+ }
+ }
+ return (color / totalWeight);
+}
+
+void main()
+{
+ vec3 N = normalize(vary_dir);
+ frag_color = max(prefilterEnvMap(N), vec4(0));
+}
+// =============================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
index a213aa0ae8..2c31e98838 100644
--- a/indra/newview/app_settings/shaders/class1/transform/normalV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenV.glsl
@@ -1,9 +1,9 @@
-/**
- * @file normalV.glsl
+/**
+ * @file radianceGenV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2011, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,14 +23,16 @@
* $/LicenseInfo$
*/
-uniform mat3 normal_matrix;
+uniform mat4 modelview_matrix;
-ATTRIBUTE vec3 normal;
+in vec3 position;
-VARYING vec4 normal_out;
+out vec3 vary_dir;
void main()
{
- normal_out = vec4(normalize(normal_matrix * normal), 0.0);
+ gl_Position = vec4(position, 1.0);
+
+ vary_dir = vec3(modelview_matrix * vec4(position, 1.0)).xyz;
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
index f8f88e2577..45267e4403 100644
--- a/indra/newview/app_settings/shaders/class1/objects/shinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/reflectionmipF.glsl
@@ -1,9 +1,9 @@
/**
- * @file shinyF.glsl
+ * @file reflectionmipF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,11 +23,14 @@
* $/LicenseInfo$
*/
+out vec4 frag_color;
+uniform sampler2D diffuseRect;
-void shiny_lighting();
+in vec2 vary_texcoord0;
void main()
{
- shiny_lighting();
+ vec3 col = texture(diffuseRect, vary_texcoord0.xy).rgb;
+ frag_color = vec4(col, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
index da02534dbb..a14334fd01 100644
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorF.glsl
@@ -23,21 +23,17 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D tex0;
uniform vec4 color;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- float alpha = texture2D(tex0, vary_texcoord0.xy).a * color.a;
+ float alpha = texture(tex0, vary_texcoord0.xy).a * color.a;
frag_color = vec4(color.rgb, alpha);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
index f33115d78d..b280fcdc15 100644
--- a/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/solidcolorV.glsl
@@ -25,10 +25,10 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
deleted file mode 100644
index 7614075cfd..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectF.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file splattexturerectF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect screenMap;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- frag_color = texture2DRect(screenMap, vary_texcoord0.xy) * vertex_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
index 641d670c26..7af7f20f85 100644
--- a/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/splattexturerectV.glsl
@@ -25,17 +25,13 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 diffuse_color;
+in vec3 position;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
- vertex_color = diffuse_color;
+ vary_texcoord0 = position.xy*0.5+0.5;
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
deleted file mode 100644
index 95679e93e7..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddF.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file twotextureaddF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D tex0;
-uniform sampler2D tex1;
-
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-
-void main()
-{
- frag_color = texture2D(tex0, vary_texcoord0.xy)+texture2D(tex1, vary_texcoord1.xy);
-}
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
deleted file mode 100644
index 3c2f297f7f..0000000000
--- a/indra/newview/app_settings/shaders/class1/interface/twotextureaddV.glsl
+++ /dev/null
@@ -1,41 +0,0 @@
-/**
- * @file twotextureaddV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
-
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-
-void main()
-{
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = texcoord0;
- vary_texcoord1 = texcoord1;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl
index 6eeb2596b2..6d51b898b7 100644
--- a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareF.glsl
@@ -23,11 +23,7 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D tex0;
uniform sampler2D tex1;
@@ -36,12 +32,12 @@ uniform float dither_scale;
uniform float dither_scale_s;
uniform float dither_scale_t;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+in vec2 vary_texcoord0;
+in vec2 vary_texcoord1;
void main()
{
- frag_color = abs(texture2D(tex0, vary_texcoord0.xy) - texture2D(tex1, vary_texcoord0.xy));
+ frag_color = abs(texture(tex0, vary_texcoord0.xy) - texture(tex1, vary_texcoord0.xy));
vec2 dither_coord;
dither_coord[0] = vary_texcoord0[0] * dither_scale_s;
diff --git a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl
index 67c6674f0c..a103bff12d 100644
--- a/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/twotexturecompareV.glsl
@@ -25,12 +25,12 @@
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
+in vec3 position;
+in vec2 texcoord0;
+in vec2 texcoord1;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+out vec2 vary_texcoord0;
+out vec2 vary_texcoord1;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
index 299bfb72aa..a29b848253 100644
--- a/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiF.glsl
@@ -23,18 +23,14 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
+in vec2 vary_texcoord0;
+in vec4 vertex_color;
void main()
{
- frag_color = vertex_color*texture2D(diffuseMap, vary_texcoord0.xy);
+ frag_color = vertex_color*texture(diffuseMap, vary_texcoord0.xy);
}
diff --git a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
index 220dafef25..91a846b9fa 100644
--- a/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
+++ b/indra/newview/app_settings/shaders/class1/interface/uiV.glsl
@@ -26,12 +26,12 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec4 diffuse_color;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
index 0bb48061e0..6535c0835e 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskF.glsl
@@ -23,22 +23,15 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
-uniform int no_atmo;
-
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void default_lighting()
{
@@ -51,13 +44,9 @@ void default_lighting()
color *= vertex_color;
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 0)
- {
- color.rgb = atmosLighting(color.rgb);
- color.rgb = scaleSoftClip(color.rgb);
- }
+ color.rgb = atmosLighting(color.rgb);
+ color.rgb = scaleSoftClip(color.rgb);
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
index d87403c78f..4dc67028d5 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightAlphaMaskNonIndexedF.glsl
@@ -23,11 +23,7 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
@@ -36,12 +32,12 @@ uniform sampler2D diffuseMap;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void default_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
@@ -54,6 +50,6 @@ void default_lighting()
color.rgb = scaleSoftClip(color.rgb);
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
index 9fd189358b..2d1c7dadb0 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightF.glsl
@@ -23,14 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec3 atmosLighting(vec3 light);
vec3 scaleSoftClip(vec3 light);
@@ -43,6 +39,6 @@ void default_lighting()
color.rgb = scaleSoftClip(color.rgb);
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
deleted file mode 100644
index ad2170bbd3..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightAlphaMaskF.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-uniform float texture_gamma; // either 1.0 or 2.2; see: "::TEXTURE_GAMMA"
-
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
-uniform int no_atmo;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void fullbright_lighting()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
-
- if (color.a < minimum_alpha)
- {
- discard;
- }
-
- color *= vertex_color;
-
- color.rgb = pow(color.rgb, vec3(texture_gamma));
-
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 0)
- {
- color.rgb = fullbrightAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- }
-
- //*TODO: Are we missing an inverse pow() here?
- // class1\lighting\lightFullbrightF.glsl has:
- // color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
deleted file mode 100644
index 89be8195f0..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightF.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-uniform float texture_gamma;
-
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO;
-uniform int no_atmo;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void fullbright_lighting()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
-
- color.rgb = pow(color.rgb, vec3(texture_gamma));
-
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 0)
- {
- color.rgb = fullbrightAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- }
-
- color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
-
- frag_color = color;
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
deleted file mode 100644
index e8e71beb44..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedAlphaMaskF.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightNonIndexedAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-uniform float texture_gamma;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void fullbright_lighting()
-{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
-
- if (color.a < minimum_alpha)
- {
- discard;
- }
-
- color.rgb *= vertex_color.rgb;
-
- color.rgb = pow(color.rgb, vec3(texture_gamma));
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
-
- color.rgb = pow(color.rgb, vec3(1.0/texture_gamma));
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
deleted file mode 100644
index 11a0919086..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightNonIndexedF.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-uniform sampler2D diffuseMap;
-
-void fullbright_lighting()
-{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
deleted file mode 100644
index 5e966293c6..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
-uniform int no_atmo;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-// See:
-// class1\deferred\fullbrightShinyF.glsl
-// class1\lighting\lightFullbrightShinyF.glsl
-void fullbright_shiny_lighting()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 0)
- {
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
-
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- }
-/*
- // NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
- else
- {
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
- }
-*/
-
- color.a = 1.0;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
deleted file mode 100644
index 3118453342..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyNonIndexedF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-uniform sampler2D diffuseMap;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-void fullbright_shiny_lighting()
-{
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
-
- color.rgb = fullbrightScaleSoftClip(color.rgb);
-
- color.a = 1.0;
-
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
deleted file mode 100644
index f78e5e0e8a..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterF.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightShinyWaterF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_shiny_lighting_water()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = 1.0;
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
deleted file mode 100644
index 90668bd2b6..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyWaterNonIndexedF.glsl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightShinyWaterF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-uniform sampler2D diffuseMap;
-
-vec3 fullbrightShinyAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_shiny_lighting_water()
-{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = fullbrightShinyAtmosTransport(color.rgb);
- color.rgb = fullbrightScaleSoftClip(color.rgb);
- color.a = 1.0;
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
deleted file mode 100644
index 37cac5f437..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightWaterAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-/* vec4 diffuseLookup(vec2 texcoord); */
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void fullbright_lighting_water()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
-
- if (color.a < minimum_alpha)
- {
- discard;
- }
-
- color.rgb *= vertex_color.rgb;
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
deleted file mode 100644
index 27880b720c..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-/* vec4 diffuseLookup(vec2 texcoord); */
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_lighting_water()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy) * vertex_color;
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
deleted file mode 100644
index c98db4795c..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightWaterNonIndexedAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform float minimum_alpha;
-
-uniform sampler2D diffuseMap;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void fullbright_lighting_water()
-{
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
-
- if (color.a < minimum_alpha)
- {
- discard;
- }
-
- color.rgb *= vertex_color.rgb;
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
deleted file mode 100644
index e9fd8ac820..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterNonIndexedF.glsl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file class1\lighting\lightFullbrightWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-uniform sampler2D diffuseMap;
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void fullbright_lighting_water()
-{
- vec4 color = texture2D(diffuseMap, vary_texcoord0.xy) * vertex_color;
-
- color.rgb = fullbrightAtmosTransport(color.rgb);
-
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
index f9c7ad2ab3..cea08ecffd 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightNonIndexedF.glsl
@@ -23,14 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
uniform sampler2D diffuseMap;
@@ -39,12 +35,12 @@ vec3 scaleSoftClip(vec3 light);
void default_lighting()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy) * vertex_color;
color.rgb = atmosLighting(color.rgb);
color.rgb = scaleSoftClip(color.rgb);
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
deleted file mode 100644
index f621a00785..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyF.glsl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file class1\lighting\lightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-
-vec3 scaleSoftClip(vec3 light);
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
- color.a = 1.0;
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
deleted file mode 100644
index 2b6f414005..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyNonIndexedF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class1\lighting\lightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-uniform sampler2D diffuseMap;
-
-vec3 scaleSoftClip(vec3 light);
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting()
-{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = atmosLighting(color.rgb);
-
- color.rgb = scaleSoftClip(color.rgb);
- color.a = 1.0;
- frag_color = color;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
deleted file mode 100644
index 0f3371eba9..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterF.glsl
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @file class1\lighting\lightShinyWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform samplerCube environmentMap;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting_water()
-{
- vec4 color = diffuseLookup(vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = atmosLighting(color.rgb);
- color.a = 1.0;
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
deleted file mode 100644
index c607fa64cb..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightShinyWaterNonIndexedF.glsl
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * @file class1\lighting\lightShinyWaterNonIndexedF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-uniform sampler2D diffuseMap;
-uniform samplerCube environmentMap;
-
-vec3 atmosLighting(vec3 light);
-vec4 applyWaterFog(vec4 color);
-
-void shiny_lighting_water()
-{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
- color.rgb *= vertex_color.rgb;
-
- vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
- color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a);
-
- color.rgb = atmosLighting(color.rgb);
- color.a = 1.0;
- frag_color = applyWaterFog(color);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
deleted file mode 100644
index 5e39d1629d..0000000000
--- a/indra/newview/app_settings/shaders/class1/lighting/lightV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file class1\lighting\lightV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-// All lights, no specular highlights
-vec3 atmosAmbient();
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
-float getAmbientClamp();
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
-{
- vec4 c = sumLights(pos, norm, color);
-
-#if !defined(AMBIENT_KILL)
- c.rgb += atmosAmbient() * color.rgb * 0.5 * getAmbientClamp();
-#endif
-
- return c;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
index 9c89c09573..670b3ddaf1 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskF.glsl
@@ -23,19 +23,15 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
vec3 atmosLighting(vec3 light);
vec4 applyWaterFog(vec4 color);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void default_lighting_water()
{
@@ -50,6 +46,6 @@ void default_lighting_water()
color.rgb = atmosLighting(color.rgb);
- frag_color = applyWaterFog(color);
+ frag_color = max(applyWaterFog(color), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
index 9de7a03180..2e5ed57014 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterAlphaMaskNonIndexedF.glsl
@@ -23,11 +23,7 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
@@ -36,12 +32,12 @@ uniform sampler2D diffuseMap;
vec3 atmosLighting(vec3 light);
vec4 applyWaterFog(vec4 color);
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void default_lighting_water()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
@@ -54,6 +50,6 @@ void default_lighting_water()
color = applyWaterFog(color);
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
index 57ed993a66..09b4a6e317 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterF.glsl
@@ -23,14 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
vec3 atmosLighting(vec3 light);
vec4 applyWaterFog(vec4 color);
@@ -41,6 +37,6 @@ void default_lighting_water()
color.rgb = atmosLighting(color.rgb);
- frag_color = applyWaterFog(color);
+ frag_color = max(applyWaterFog(color), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
index af5da1411b..4888fa547c 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightWaterNonIndexedF.glsl
@@ -23,14 +23,10 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
uniform sampler2D diffuseMap;
@@ -39,10 +35,10 @@ vec4 applyWaterFog(vec4 color);
void default_lighting_water()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy) * vertex_color;
color.rgb = atmosLighting(color.rgb);
- frag_color = applyWaterFog(color);
+ frag_color = max(applyWaterFog(color), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
index 0c3ea4231e..75a327d3d7 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/sumLightsV.glsl
@@ -38,15 +38,7 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
col.a = color.a;
col.rgb = light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb = scaleDownLight(col.rgb);
-
-#if defined(LOCAL_LIGHT_KILL)
- col.rgb = vec3(0);
-#endif
-
-#if !defined(SUNLIGHT_KILL)
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-#endif
+ col.rgb += light_diffuse[1].rgb * sqrt(calcDirectionalLight(norm, -light_position[1].xyz)*0.5+0.25);
col.rgb = min(col.rgb*color.rgb, 1.0);
return col;
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
index d55f0db530..67c99530e3 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpF.glsl
@@ -23,22 +23,18 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D texture0;
uniform sampler2D texture1;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+in vec2 vary_texcoord0;
+in vec2 vary_texcoord1;
void main()
{
- float tex0 = texture2D(texture0, vary_texcoord0.xy).a;
- float tex1 = texture2D(texture1, vary_texcoord1.xy).a;
+ float tex0 = texture(texture0, vary_texcoord0.xy).a;
+ float tex1 = texture(texture1, vary_texcoord1.xy).a;
- frag_color = vec4(tex0+(1.0-tex1)-0.5);
+ frag_color = max(vec4(tex0+(1.0-tex1)-0.5), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
index ee9970bc70..7d5417919e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/bumpV.glsl
@@ -26,12 +26,12 @@
uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec2 texcoord1;
+in vec3 position;
+in vec2 texcoord0;
+in vec2 texcoord1;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
+out vec2 vary_texcoord0;
+out vec2 vary_texcoord1;
#ifdef HAS_SKIN
mat4 getObjectSkinnedTransform();
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
deleted file mode 100644
index 31a262f1db..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightF.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file objects/fullbrightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$F
- */
-
-
-
-void fullbright_lighting();
-
-void main()
-{
- fullbright_lighting();
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
deleted file mode 100644
index 5d6f14230c..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightNoColorV.glsl
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- * @file fullbrightNoColorV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-void calcAtmospherics(vec3 inPositionEye);
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = vec4(1,1,1,1);
-
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
deleted file mode 100644
index b312665032..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyF.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file fullbrightShinyF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-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
deleted file mode 100644
index 891515ab1e..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyV.glsl
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file fullbrightShinyV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec4 origin;
-
-
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-uniform mat4 projection_matrix;
-#endif
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
- passTextureIndex();
-
-#ifdef HAS_SKIN
- mat4 mat = getObjectSkinnedTransform();
- mat = modelview_matrix * mat;
- vec4 pos = mat * vert;
- gl_Position = projection_matrix * pos;
- vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
-#else
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
- vec3 norm = normalize(normal_matrix * normal);
-#endif
- vec3 ref = reflect(pos.xyz, -norm);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz;
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl
deleted file mode 100644
index e1f3919907..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightShinyWaterF.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file fullbrightShinyWaterF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-void fullbright_shiny_lighting_water();
-
-void main()
-{
- fullbright_shiny_lighting_water();
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
deleted file mode 100644
index 5d0ea0a8dd..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/fullbrightWaterF.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file fullbrightWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-void fullbright_lighting_water();
-
-void main()
-{
- fullbright_lighting_water();
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
index add437d144..ff9aaf3357 100644
--- a/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorF.glsl
@@ -23,26 +23,22 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform float minimum_alpha;
uniform sampler2D diffuseMap;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
void main()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy);
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy);
if (color.a < minimum_alpha)
{
discard;
}
- frag_color = color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
index e90dbb115a..cf3162f5f1 100644
--- a/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/impostorV.glsl
@@ -27,10 +27,10 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
index ca29bf3143..d90f9271dc 100644
--- a/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/indexedTextureV.glsl
@@ -23,9 +23,9 @@
* $/LicenseInfo$
*/
-ATTRIBUTE int texture_index;
+in int texture_index;
-VARYING_FLAT int vary_texture_index;
+flat out int vary_texture_index;
void passTextureIndex()
{
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewF.glsl b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl
index 284da3d0ac..ec785cd1c0 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewF.glsl
@@ -23,19 +23,15 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
void main()
{
- vec4 color = texture2D(diffuseMap,vary_texcoord0.xy) * vertex_color;
- frag_color = color;
+ vec4 color = texture(diffuseMap,vary_texcoord0.xy) * vertex_color;
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl
index 3a5e6fdf7c..e3e71202ae 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsF.glsl
@@ -23,20 +23,16 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
uniform vec4 color;
-VARYING vec2 vary_texcoord0;
+in vec2 vary_texcoord0;
//====================================================================================================
void main()
{
- frag_color = texture2D(diffuseMap,vary_texcoord0.xy) * color;
+ frag_color = max(texture(diffuseMap,vary_texcoord0.xy) * color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl
index 913dec83bd..d8c74e8537 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewPhysicsV.glsl
@@ -27,10 +27,10 @@ uniform mat4 texture_matrix0;
uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec2 texcoord0;
-VARYING vec2 vary_texcoord0;
+out vec2 vary_texcoord0;
//====================================================================================================
diff --git a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
index 5886f47cbc..f51b0f4d9e 100644
--- a/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/previewV.glsl
@@ -25,17 +25,16 @@
uniform mat3 normal_matrix;
uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
uniform mat4 modelview_projection_matrix;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
uniform vec4 color;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
uniform vec4 light_position[8];
uniform vec3 light_direction[8];
@@ -54,14 +53,27 @@ float calcDirectionalLight(vec3 n, vec3 l)
//====================================================================================================
+#ifdef HAS_SKIN
+mat4 getObjectSkinnedTransform();
+uniform mat4 modelview_matrix;
+uniform mat4 projection_matrix;
+#endif
+
void main()
{
- //transform vertex
- vec4 pos = (modelview_matrix * vec4(position.xyz, 1.0));
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec3 norm;
+#ifdef HAS_SKIN
+ mat4 mat = getObjectSkinnedTransform();
+ mat = modelview_matrix * mat;
+ vec4 pos = mat * vec4(position.xyz, 1.0);
+ gl_Position = projection_matrix * pos;
+ norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
+#else
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ norm = normalize(normal_matrix * normal);
+#endif
+
vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
vec4 col = vec4(0,0,0,1);
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
deleted file mode 100644
index 3ad7bcaa50..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/shinyV.glsl
+++ /dev/null
@@ -1,78 +0,0 @@
-/**
- * @file shinyV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 texture_matrix1;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_texcoord1;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec4 origin;
-
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-uniform mat4 projection_matrix;
-#endif
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
- passTextureIndex();
-
-#ifdef HAS_SKIN
- mat4 mat = getObjectSkinnedTransform();
- mat = modelview_matrix * mat;
- vec4 pos = mat * vert;
- gl_Position = projection_matrix * pos;
- vec3 norm = normalize((mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz);
-#else
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
- vec3 norm = normalize(normal_matrix * normal);
-#endif
- vec3 ref = reflect(pos.xyz, -norm);
-
- vary_texcoord0 = (texture_matrix0*vec4(texcoord0,0,1)).xy;
- vary_texcoord1 = (texture_matrix1 * vec4(ref,1.0)).xyz;
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl b/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
deleted file mode 100644
index 1e72e23eef..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/shinyWaterF.glsl
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * @file shinyWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-void shiny_lighting_water();
-
-void main()
-{
- shiny_lighting_water();
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
index 22821a2f76..07f5d250cf 100644
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
+++ b/indra/newview/app_settings/shaders/class1/objects/simpleNoColorV.glsl
@@ -30,12 +30,12 @@ uniform mat4 modelview_projection_matrix;
uniform vec4 color;
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
+in vec3 position;
+in vec3 normal;
+in vec2 texcoord0;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
+out vec4 vertex_color;
+out vec2 vary_texcoord0;
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
deleted file mode 100644
index e605676819..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/simpleNonIndexedV.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file simpleNonIndexedV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
-
- gl_Position = modelview_projection_matrix*vert;
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
-
- vec4 pos = (modelview_matrix * vert);
-
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
- vertex_color = color;
-
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
deleted file mode 100644
index 945f80f31e..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/simpleTexGenV.glsl
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file simpleV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-
-uniform vec4 color;
-uniform vec4 object_plane_t;
-uniform vec4 object_plane_s;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-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
- vec4 vert = vec4(position.xyz,1.0);
- passTextureIndex();
- vec4 pos = (modelview_matrix * vert);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
- vary_texcoord0.xy = texgen_object(vec4(position.xyz, 1.0), vec4(texcoord0,0,1), texture_matrix0, object_plane_s, object_plane_t).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm, color);
- vertex_color = color;
-
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl b/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
deleted file mode 100644
index 2025174f7d..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/simpleV.glsl
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * @file simpleV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-// render_hud_attachments() -> HUD objects set LLShaderMgr::NO_ATMO; used in LLDrawPoolAlpha::beginRenderPass()
-uniform int no_atmo;
-
-ATTRIBUTE vec3 position;
-void passTextureIndex();
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
-
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-#ifdef HAS_SKIN
-mat4 getObjectSkinnedTransform();
-uniform mat4 projection_matrix;
-#endif
-
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
-
- passTextureIndex();
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
-
- // SL-9632 HUDs are affected by Atmosphere
- if (no_atmo == 1)
- {
- vertex_color = diffuse_color;
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
- }
- else
- {
-#ifdef HAS_SKIN
- mat4 mat = getObjectSkinnedTransform();
- mat = modelview_matrix * mat;
-
- vec4 pos = mat * vert;
- vec3 norm = normalize((mat*vec4(normal.xyz+vert.xyz,1.0)).xyz-pos.xyz);
-
- gl_Position = projection_matrix * pos;
-#else
- vec4 pos = (modelview_matrix * vert);
- vec3 norm = normalize(normal_matrix * normal);
- gl_Position = modelview_projection_matrix*vec4(position.xyz, 1.0);
-#endif
-
- calcAtmospherics(pos.xyz);
-
- vertex_color = calcLighting(pos.xyz, norm, diffuse_color);
- }
-}
diff --git a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl b/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
deleted file mode 100644
index 0227e6e3b8..0000000000
--- a/indra/newview/app_settings/shaders/class1/objects/treeV.glsl
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- * @file treeV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec4 diffuse_color;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-void calcAtmospherics(vec3 inPositionEye);
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz,1.0);
-
- gl_Position = modelview_projection_matrix*vert;
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0, 0, 1)).xy;
-
- vec4 pos = (modelview_matrix * vert);
-
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- vec4 color = calcLighting(pos.xyz, norm, diffuse_color);
- vertex_color = color;
-}
diff --git a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl b/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
deleted file mode 100644
index 01eed18de4..0000000000
--- a/indra/newview/app_settings/shaders/class1/transform/positionV.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file positionV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_matrix;
-
-uniform int texture_index_in;
-
-ATTRIBUTE vec3 position;
-
-VARYING vec3 position_out;
-VARYING int texture_index_out;
-
-void main()
-{
- texture_index_out = texture_index_in;
- position_out = (modelview_matrix*vec4(position, 1.0)).xyz;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
index 4e0618e276..41a848a14f 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsF.glsl
@@ -1,9 +1,9 @@
/**
- * @file class1\windlight\atmosphericsF.glsl
+ * @file class2\wl\atmosphericsF.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
+ * Copyright (C) 2007, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,27 +22,31 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-vec3 atmosFragAmbient(vec3 light, vec3 sunlit)
-{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
-}
+
+vec3 getAdditiveColor();
+vec3 getAtmosAttenuation();
+vec3 scaleSoftClipFrag(vec3 light);
+
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
+uniform float sky_hdr_scale;
vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
- /* stub function for fallback compatibility on class1 hardware */
+{
+ light *= atten.r;
+ additive = srgb_to_linear(additive*2.0);
+ additive *= sky_hdr_scale;
+ light += additive;
return light;
}
-vec3 atmosFragAffectDirectionalLight(float light, vec3 sunlit)
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten)
{
- return light * sunlit;
+ return atmosFragLighting(light, additive, atten);
}
vec3 atmosLighting(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
index ea2690ba09..a1da4b1f9a 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsFuncs.glsl
@@ -1,9 +1,9 @@
/**
- * @file class1\windlight\atmosphericsFuncs.glsl
+ * @file class2\windlight\atmosphericsFuncs.glsl
*
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2019, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,29 +22,33 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
+
+uniform vec3 lightnorm;
+uniform vec3 sunlight_color;
+uniform vec3 moonlight_color;
uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
+uniform vec3 ambient_color;
+uniform vec3 blue_horizon;
+uniform vec3 blue_density;
uniform float haze_horizon;
uniform float haze_density;
uniform float cloud_shadow;
uniform float density_multiplier;
uniform float distance_multiplier;
uniform float max_y;
-uniform vec4 glow;
+uniform vec3 glow;
uniform float scene_light_strength;
-uniform mat3 ssao_effect_mat;
-uniform int no_atmo;
uniform float sun_moon_glow_factor;
+uniform float sky_sunlight_scale;
+uniform float sky_ambient_scale;
float getAmbientClamp() { return 1.0f; }
+vec3 srgb_to_linear(vec3 col);
+
+// return colors in sRGB space
void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive,
- out vec3 atten, bool use_ao)
+ out vec3 atten)
{
vec3 rel_pos = inPositionEye;
@@ -53,17 +57,18 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
vec3 rel_pos_norm = normalize(rel_pos);
float rel_pos_len = length(rel_pos);
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
-
+
+ vec3 sunlight = (sun_up_factor == 1) ? sunlight_color: moonlight_color;
+
// sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
- vec4 light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
+ vec3 light_atten = (blue_density + vec3(haze_density * 0.25)) * (density_multiplier * max_y);
// I had thought blue_density and haze_density should have equal weighting,
// but attenuation due to haze_density tends to seem too strong
- vec4 combined_haze = blue_density + vec4(haze_density);
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = vec4(haze_density) / combined_haze;
+ vec3 combined_haze = blue_density + vec3(haze_density);
+ vec3 blue_weight = blue_density / combined_haze;
+ vec3 haze_weight = vec3(haze_density) / combined_haze;
//(TERRAIN) compute sunlight from lightnorm y component. Factor is roughly cosecant(sun elevation) (for short rays like terrain)
float above_horizon_factor = 1.0 / max(1e-6, lightnorm.y);
@@ -101,24 +106,10 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
haze_glow *= sun_moon_glow_factor;
- vec4 amb_color = ambient_color;
+ vec3 amb_color = ambient_color;
// increase ambient when there are more clouds
- vec4 tmpAmbient = amb_color + (vec4(1.) - amb_color) * cloud_shadow * 0.5;
-
- /* decrease value and saturation (that in HSV, not HSL) for occluded areas
- * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
- * // The following line of code performs the equivalent of:
- * float ambAlpha = tmpAmbient.a;
- * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
- * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
- * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat,
- * ambAlpha);
- */
- if (use_ao)
- {
- tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
- }
+ vec3 tmpAmbient = amb_color + (vec3(1.) - amb_color) * cloud_shadow * 0.5;
// Similar/Shared Algorithms:
// indra\llinventory\llsettingssky.cpp -- LLSettingsSky::calculateLightSettings()
@@ -128,7 +119,38 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou
additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb);
// brightness of surface both sunlight and ambient
- sunlit = sunlight.rgb * 0.5;
- amblit = tmpAmbient.rgb * .25;
+
+ sunlit = sunlight.rgb;
+ amblit = tmpAmbient;
+
additive *= vec3(1.0 - combined_haze);
}
+
+vec3 srgb_to_linear(vec3 col);
+
+// provide a touch of lighting in the opposite direction of the sun light
+ // so areas in shadow don't lose all detail
+float ambientLighting(vec3 norm, vec3 light_dir)
+{
+ float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0);
+ ambient *= 0.5;
+ ambient *= ambient;
+ ambient = (1.0 - ambient);
+ return ambient;
+}
+
+
+// return lit amblit in linear space, leave sunlit and additive in sRGB space
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive,
+ out vec3 atten)
+{
+ calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten);
+
+ // multiply to get similar colors as when the "scaleSoftClip" implementation was doubling color values
+ // (allows for mixing of light sources other than sunlight e.g. reflection probes)
+ sunlit *= sky_sunlight_scale;
+ amblit *= sky_ambient_scale;
+
+ amblit = srgb_to_linear(amblit);
+ amblit *= ambientLighting(norm, light_dir);
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
index 206a51db27..800d08047a 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersF.glsl
@@ -1,5 +1,5 @@
-/**
- * @file class1\windlight\atmosphericsHelpersF.glsl
+/**
+ * @file class2\wl\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,30 +22,23 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-uniform vec4 sunlight_color;
-uniform vec4 light_ambient;
-uniform int no_atmo;
-vec3 atmosAmbient()
-{
- if (no_atmo == 1) return vec3(0.16);
- return light_ambient.rgb;
-}
+// Output variables
+
+uniform float scene_light_strength;
-vec3 atmosAffectDirectionalLight(float lightIntensity)
+vec3 atmosFragAmbient(vec3 light, vec3 amblit)
{
- return sunlight_color.rgb * lightIntensity;
+ return amblit + light / 2.0;
}
-vec3 atmosGetDiffuseSunlightColor()
+vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit)
{
- return sunlight_color.rgb;
+ return sunlit * lightIntensity;
}
-vec3 scaleDownLight(vec3 light)
+vec3 scaleDownLightFrag(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ return (light / scene_light_strength );
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
index c266f9732f..6ecbfaecb1 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsHelpersV.glsl
@@ -1,5 +1,5 @@
-/**
- * @file class1\windlight\atmosphericsHelpersV.glsl
+/**
+ * @file class2\wl\atmosphericsHelpersV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,35 +23,35 @@
* $/LicenseInfo$
*/
-uniform vec4 sunlight_color;
-uniform vec4 light_ambient;
-uniform int no_atmo;
+
+
+// Output variables
+vec3 getSunlitColor();
+vec3 getAmblitColor();
+vec3 getAdditiveColor();
+vec3 getAtmosAttenuation();
+vec3 getPositionEye();
+
+uniform float scene_light_strength;
vec3 atmosAmbient()
{
- if (no_atmo == 1) return vec3(0.66);
- return light_ambient.rgb;
+ return getAmblitColor();
}
vec3 atmosAffectDirectionalLight(float lightIntensity)
{
- return sunlight_color.rgb * lightIntensity;
+ return getSunlitColor() * lightIntensity;
}
vec3 atmosGetDiffuseSunlightColor()
{
- return sunlight_color.rgb;
+ return getSunlitColor();
}
vec3 scaleDownLight(vec3 light)
{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
+ return (light / scene_light_strength );
}
-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
index 20457ad125..cc3617ba61 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsV.glsl
@@ -1,5 +1,5 @@
-/**
- * @file class1\windlight\atmosphericsV.glsl
+/**
+ * @file class2\wl\atmosphericsV.glsl
*
* $LicenseInfo:firstyear=2005&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,14 +22,35 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
+// out param funcs
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
+
+void setSunlitColor(vec3 v);
+void setAmblitColor(vec3 v);
+void setAdditiveColor(vec3 v);
+void setAtmosAttenuation(vec3 v);
void setPositionEye(vec3 v);
-void calcAtmospherics(vec3 inPositionEye)
-{
- /* stub function for fallback compatibility on class1 hardware */
- setPositionEye(inPositionEye);
-}
+vec3 getAdditiveColor();
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
+
+void calcAtmospherics(vec3 inPositionEye) {
+ vec3 P = inPositionEye;
+ setPositionEye(P);
+ vec3 tmpsunlit = vec3(1);
+ vec3 tmpamblit = vec3(1);
+ vec3 tmpaddlit = vec3(1);
+ vec3 tmpattenlit = vec3(1);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ calcAtmosphericVars(inPositionEye, light_dir, 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit);
+ setSunlitColor(tmpsunlit);
+ setAmblitColor(tmpamblit);
+ setAdditiveColor(tmpaddlit);
+ setAtmosAttenuation(tmpattenlit);
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index 3b4d358cfa..34669a6796 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -1,37 +1,48 @@
-/**
- * @file class1\windlight\atmosphericVarsF.glsl
+/**
+ * @file class2\wl\atmosphericVarsF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 getAmblitColor() { return vec3(0, 0, 0); }
+in vec3 vary_AdditiveColor;
+in vec3 vary_AtmosAttenuation;
-vec3 getAdditiveColor() { return vary_AdditiveColor; }
+vec3 getSunlitColor()
+{
+ return vec3(0,0,0);
+}
-vec3 getAtmosAttenuation() { return vec3(vary_AtmosAttenuation); }
+vec3 getAmblitColor()
+{
+ return vec3(0,0,0);
+}
-vec3 getSunlitColor() { return vec3(0, 0, 0); }
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
-vec3 getPositionEye() { return vec3(0, 0, 0); }
+vec3 getAtmosAttenuation()
+{
+ return vec3(vary_AtmosAttenuation);
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index 1fea2c3628..1b854d80b3 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -1,30 +1,31 @@
-/**
- * @file class1\windlight\atmosphericVarsV.glsl
+/**
+ * @file class2\wl\atmosphericVars.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
+out vec3 vary_AdditiveColor;
+out vec3 vary_AtmosAttenuation;
vec3 additive_color;
vec3 atmos_attenuation;
@@ -32,25 +33,52 @@ vec3 sunlit_color;
vec3 amblit_color;
vec3 position_eye;
-vec3 getSunlitColor() { return sunlit_color; }
-void setSunlitColor(vec3 v) { sunlit_color = v; }
+vec3 getSunlitColor()
+{
+ return sunlit_color;
+}
+vec3 getAmblitColor()
+{
+ return amblit_color;
+}
-vec3 getAdditiveColor() { return additive_color; }
-void setAdditiveColor(vec3 v)
+vec3 getAdditiveColor()
+{
+ return additive_color;
+}
+vec3 getAtmosAttenuation()
{
- additive_color = v;
- vary_AdditiveColor = v;
+ return atmos_attenuation;
}
-vec3 getAmblitColor() { return amblit_color; }
-void setAmblitColor(vec3 v) { amblit_color = v; }
+vec3 getPositionEye()
+{
+ return position_eye;
+}
-vec3 getAtmosAttenuation() { return atmos_attenuation; }
-void setAtmosAttenuation(vec3 v)
+void setPositionEye(vec3 v)
{
- atmos_attenuation = v;
- vary_AtmosAttenuation = v;
+ position_eye = v;
}
-vec3 getPositionEye() { return position_eye; }
-void setPositionEye(vec3 v) { position_eye = v; }
+void setSunlitColor(vec3 v)
+{
+ sunlit_color = v;
+}
+
+void setAmblitColor(vec3 v)
+{
+ amblit_color = v;
+}
+
+void setAdditiveColor(vec3 v)
+{
+ additive_color = v;
+ vary_AdditiveColor = v;
+}
+
+void setAtmosAttenuation(vec3 v)
+{
+ atmos_attenuation = v;
+ vary_AtmosAttenuation = v;
+}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index f83434b7ec..7a6741fe0e 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
@@ -1,38 +1,50 @@
-/**
- * @file class1\windlight\atmosphericVarsWaterF.glsl
+/**
+ * @file class2\wl\atmosphericVarsWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
+
+in vec3 vary_PositionEye;
+in vec3 vary_AdditiveColor;
+in vec3 vary_AtmosAttenuation;
-VARYING vec3 vary_PositionEye;
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 getSunlitColor() { return vec3(0, 0, 0); }
-
-vec3 getAmblitColor() { return vec3(0, 0, 0); }
-
-vec3 getAdditiveColor() { return vary_AdditiveColor; }
-
-vec3 getAtmosAttenuation() { return vary_AtmosAttenuation; }
+vec3 getSunlitColor()
+{
+ return vec3(0,0,0);
+}
+vec3 getAmblitColor()
+{
+ return vec3(0,0,0);
+}
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return vary_AtmosAttenuation;
+}
+vec3 getPositionEye()
+{
+ return vary_PositionEye;
+}
-vec3 getPositionEye() { return vary_PositionEye; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index 65d1176777..23c3aed4d8 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
@@ -1,51 +1,81 @@
-/**
- * @file class1\windlight\atmosphericVarsWaterV.glsl
+/**
+ * @file class2\wl\atmosphericVarsWaterV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-VARYING vec3 vary_PositionEye;
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
+
+out vec3 vary_PositionEye;
+out vec3 vary_AdditiveColor;
+out vec3 vary_AtmosAttenuation;
vec3 atmos_attenuation;
vec3 sunlit_color;
vec3 amblit_color;
-vec3 getSunlitColor() { return sunlit_color; }
-void setSunlitColor(vec3 v) { sunlit_color = v; }
+vec3 getSunlitColor()
+{
+ return sunlit_color;
+}
+vec3 getAmblitColor()
+{
+ return amblit_color;
+}
+
+vec3 getAdditiveColor()
+{
+ return vary_AdditiveColor;
+}
+vec3 getAtmosAttenuation()
+{
+ return atmos_attenuation;
+}
+
+vec3 getPositionEye()
+{
+ return vary_PositionEye;
+}
+
+void setPositionEye(vec3 v)
+{
+ vary_PositionEye = v;
+}
+
+void setSunlitColor(vec3 v)
+{
+ sunlit_color = v;
+}
-vec3 getAmblitColor() { return amblit_color; }
-void setAmblitColor(vec3 v) { amblit_color = v; }
+void setAmblitColor(vec3 v)
+{
+ amblit_color = v;
+}
-vec3 getAdditiveColor() { return vary_AdditiveColor; }
-void setAdditiveColor(vec3 v) { vary_AdditiveColor = v; }
+void setAdditiveColor(vec3 v)
+{
+ vary_AdditiveColor = v;
+}
-vec3 getAtmosAttenuation() { return atmos_attenuation; }
void setAtmosAttenuation(vec3 v)
{
- atmos_attenuation = v;
- vary_AtmosAttenuation = v;
+ atmos_attenuation = v;
+ vary_AtmosAttenuation = v;
}
-
-vec3 getPositionEye() { return vary_PositionEye; }
-void setPositionEye(vec3 v) { vary_PositionEye = v; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
deleted file mode 100644
index 82fad4db5a..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowF.glsl
+++ /dev/null
@@ -1,127 +0,0 @@
-/**
- * @file class1/windlight/cloudShadowF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 sunlight_color;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-void main()
-{
- if (cloud_scale >= 0.0001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = vec4(alpha1, alpha1, alpha1, 1);
- }
- else
- {
- frag_color = vec4(1);
- }
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
deleted file mode 100644
index 09b6004481..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/cloudShadowV.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class1\windlight\cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
index fc51e81177..027bfb866f 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/gammaF.glsl
@@ -1,5 +1,5 @@
/**
- * @file class1\windlight\gammaF.glsl
+ * @file class2\wl\gammaF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -22,31 +22,34 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-uniform int no_atmo;
+
+ // DEPRECATED
+
+//soft clip effect has been moved to postDeferredGammaCorrect legacyGamma, this file is effectively dead
+// but these functions need to be removed from all existing shaders before removing this file
vec3 scaleSoftClipFrag(vec3 light)
{
- // For compatibility with lower cards. Do nothing.
- return light;
+ return light;
+}
+
+vec3 scaleSoftClipFragLinear(vec3 light)
+{ // identical to non-linear version and that's probably close enough
+ return light;
}
-/// Soft clips the light with a gamma correction
vec3 scaleSoftClip(vec3 light)
{
- // For compatibility with lower cards. Do nothing
- return light;
+ return light;
}
-vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 additive, vec3 atten)
+vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)
{
- // For compatibility with lower cards. Do nothing
- return light;
+ return light;
}
vec3 fullbrightScaleSoftClip(vec3 light)
{
- // For compatibility with lower cards. Do nothing
return light;
}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
deleted file mode 100644
index 2425a2ad04..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/moonF.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file class1\wl\moonF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, 2020 Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform vec4 color;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform vec3 moon_dir;
-uniform float moon_brightness;
-uniform sampler2D diffuseMap;
-
-VARYING vec2 vary_texcoord0;
-
-vec3 scaleSoftClip(vec3 light);
-
-void main()
-{
- // Restore Pre-EEP alpha fade moon near horizon
- float fade = 1.0;
- if( moon_dir.z > 0 )
- fade = clamp( moon_dir.z*moon_dir.z*4.0, 0.0, 1.0 );
-
- vec4 c = texture2D(diffuseMap, vary_texcoord0.xy);
-// c.rgb = pow(c.rgb, vec3(0.7f)); // can't use "srgb_to_linear(color.rgb)" as that is a deferred only function
- c.rgb *= moonlight_color.rgb;
- c.rgb *= moon_brightness;
-
- c.rgb *= fade;
- c.a *= fade;
-
- c.rgb = scaleSoftClip(c.rgb);
-
- frag_color = vec4(c.rgb, c.a);
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl b/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
deleted file mode 100644
index 2fceb5f743..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/moonV.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file class1\wl\moonV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, 2020 Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- //transform vertex
- vec4 vert = vec4(position.xyz, 1.0);
- vec4 pos = (modelview_matrix * vert);
-
- gl_Position = modelview_projection_matrix*vert;
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
deleted file mode 100644
index 5a41dc644a..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file class1\wl\sunDiscF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-vec3 fullbrightAtmosTransport(vec3 light);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-uniform sampler2D diffuseMap;
-uniform sampler2D altDiffuseMap;
-uniform float blend_factor; // interp factor between sun A/B
-VARYING vec2 vary_texcoord0;
-VARYING float sun_fade;
-
-void main()
-{
- vec4 sunA = texture2D(diffuseMap, vary_texcoord0.xy);
- vec4 sunB = texture2D(altDiffuseMap, vary_texcoord0.xy);
- vec4 c = mix(sunA, sunB, blend_factor);
-
-// SL-9806 stars poke through
-// c.a *= sun_fade;
-
- c.rgb = fullbrightAtmosTransport(c.rgb);
- c.rgb = fullbrightScaleSoftClip(c.rgb);
- frag_color = c;
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
deleted file mode 100644
index 6c0e795f6b..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/sunDiscV.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file class1\wl\sunDiscV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_texcoord0;
-VARYING float sun_fade;
-
-void calcAtmospherics(vec3 eye_pos);
-
-void main()
-{
- //transform vertex
- vec3 offset = vec3(0, 0, 50);
- vec4 vert = vec4(position.xyz - offset, 1.0);
- vec4 pos = modelview_projection_matrix*vert;
-
- sun_fade = smoothstep(0.3, 1.0, (position.z + 50) / 512.0f);
- gl_Position = pos;
-
- calcAtmospherics(pos.xyz);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
deleted file mode 100644
index a937d9fa99..0000000000
--- a/indra/newview/app_settings/shaders/class1/windlight/transportF.glsl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file class1/windlight/transportF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform int no_atmo;
-
-vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
-}
-
-vec3 atmosTransport(vec3 light)
-{
- /* stub function for fallback compatibility on class1 hardware */
- return light;
-}
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- /* 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
deleted file mode 100644
index 563c5f562b..0000000000
--- a/indra/newview/app_settings/shaders/class2/avatar/eyeballV.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file eyeballV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat3 normal_matrix;
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-
-vec4 calcLightingSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor);
-void calcAtmospherics(vec3 inPositionEye);
-
-void main()
-{
- //transform vertex
- vec3 pos = (modelview_matrix * vec4(position.xyz, 1.0)).xyz;
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vec3 norm = normalize(normal_matrix * normal);
-
- calcAtmospherics(pos.xyz);
-
- // vec4 specular = specularColor;
- vec4 specular = vec4(1.0);
- vec4 color = calcLightingSpecular(pos, norm, diffuse_color, specular);
-
- vertex_color = color;
-
-
-}
-
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index 02b2daf0ac..b63f3b60f9 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -23,9 +23,7 @@
* $/LicenseInfo$
*/
-//class1/deferred/alphaF.glsl
-
-#extension GL_ARB_texture_rectangle : enable
+//class2/deferred/alphaF.glsl
/*[EXTRA_CODE_HERE]*/
@@ -33,11 +31,7 @@
#define NON_INDEXED 2
#define NON_INDEXED_NO_COLOR 3
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform mat3 env_mat;
uniform vec3 sun_dir;
@@ -47,13 +41,13 @@ uniform vec3 moon_dir;
uniform sampler2D diffuseMap;
#endif
-VARYING vec3 vary_fragcoord;
-VARYING vec3 vary_position;
-VARYING vec2 vary_texcoord0;
-VARYING vec3 vary_norm;
+in vec3 vary_fragcoord;
+in vec3 vary_position;
+in vec2 vary_texcoord0;
+in vec3 vary_norm;
#ifdef USE_VERTEX_COLOR
-VARYING vec4 vertex_color; //vertex color should be treated as sRGB
+in vec4 vertex_color; //vertex color should be treated as sRGB
#endif
#ifdef HAS_ALPHA_MASK
@@ -69,25 +63,29 @@ uniform vec3 light_direction[8];
uniform vec4 light_attenuation[8];
uniform vec3 light_diffuse[8];
+void waterClip(vec3 pos);
+
#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
#endif
vec3 srgb_to_linear(vec3 c);
vec3 linear_to_srgb(vec3 c);
vec2 encode_normal (vec3 n);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive, bool use_ao);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
-#ifdef HAS_SHADOW
+#ifdef HAS_SUN_SHADOW
float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
#endif
float getAmbientClamp();
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
+
vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, float ambiance)
{
// SL-14895 inverted attenuation work-around
@@ -175,19 +173,22 @@ vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 diffuse, vec3 v, vec3 n, vec
void main()
{
vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
- frag *= screen_res;
vec4 pos = vec4(vary_position, 1.0);
+#ifndef IS_AVATAR_SKIN
+ // clip against water plane unless this is a legacy avatar skin
+ waterClip(pos.xyz);
+#endif
vec3 norm = vary_norm;
float shadow = 1.0f;
-#ifdef HAS_SHADOW
+#ifdef HAS_SUN_SHADOW
shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
#endif
#ifdef USE_DIFFUSE_TEX
- vec4 diffuse_tap = texture2D(diffuseMap,vary_texcoord0.xy);
+ vec4 diffuse_tap = texture(diffuseMap,vary_texcoord0.xy);
#endif
#ifdef USE_INDEXED_TEX
@@ -218,7 +219,7 @@ void main()
vec4 diffuse_linear = vec4(srgb_to_linear(diffuse_srgb.rgb), diffuse_srgb.a);
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir;
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir: moon_dir; // TODO -- factor out "sun_up_factor" and just send in the appropriate light vector
float final_alpha = diffuse_linear.a;
@@ -240,13 +241,19 @@ void main()
vec3 additive;
vec3 atten;
- calcAtmosphericVars(pos.xyz, light_dir, 1.0, sunlit, amblit, additive, atten, false);
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 amblit_linear = amblit;
- vec2 abnormal = encode_normal(norm.xyz);
+ vec3 irradiance;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, frag, pos.xyz, norm.xyz, 0.0, 0.0, true, amblit_linear);
+
float da = dot(norm.xyz, light_dir.xyz);
da = clamp(da, -1.0, 1.0);
- da = pow(da, 1.0/1.3);
float final_da = da;
final_da = clamp(final_da, 0.0f, 1.0f);
@@ -255,41 +262,22 @@ void main()
color.a = final_alpha;
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
-
- vec3 sun_contrib = min(final_da, shadow) * sunlit;
-
-#if !defined(AMBIENT_KILL)
- color.rgb = amblit;
- color.rgb *= ambient;
-#endif // !defined(AMBIENT_KILL)
+ vec3 sun_contrib = min(final_da, shadow) * sunlit_linear;
-vec3 post_ambient = color.rgb;
+ color.rgb = irradiance;
-#if !defined(SUNLIGHT_KILL)
color.rgb += sun_contrib;
-#endif // !defined(SUNLIGHT_KILL)
-vec3 post_sunlight = color.rgb;
+ color.rgb *= diffuse_linear.rgb;
- color.rgb *= diffuse_srgb.rgb;
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
-vec3 post_diffuse = color.rgb;
-
- color.rgb = atmosFragLighting(color.rgb, additive, atten);
-
-vec3 post_atmo = color.rgb;
+#ifdef WATER_FOG
+ color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear);
+#endif // WATER_FOG
vec4 light = vec4(0,0,0,0);
- color.rgb = scaleSoftClipFrag(color.rgb);
-
- //convert to linear before applying local lights
- color.rgb = srgb_to_linear(color.rgb);
-
#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, diffuse_linear.rgb, pos.xyz, norm, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
LIGHT_LOOP(1)
@@ -301,29 +289,14 @@ vec3 post_atmo = color.rgb;
LIGHT_LOOP(7)
// sum local light contrib in linear colorspace
-#if !defined(LOCAL_LIGHT_KILL)
color.rgb += light.rgb;
-#endif // !defined(LOCAL_LIGHT_KILL)
- // back to sRGB as we're going directly to the final RT post-deferred gamma correction
- color.rgb = linear_to_srgb(color.rgb);
-
-//color.rgb = amblit;
-//color.rgb = vec3(ambient);
-//color.rgb = sunlit;
-//color.rgb = vec3(final_da);
-//color.rgb = post_ambient;
-//color.rgb = post_sunlight;
-//color.rgb = sun_contrib;
-//color.rgb = diffuse_srgb.rgb;
-//color.rgb = post_diffuse;
-//color.rgb = post_atmo;
-
-#ifdef WATER_FOG
- color = applyWaterFogView(pos.xyz, color);
-#endif // WATER_FOG
#endif // #else // FOR_IMPOSTOR
- frag_color = color;
+#ifdef IS_HUD
+ color.rgb = linear_to_srgb(color.rgb);
+#endif
+
+ frag_color = max(color, vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
deleted file mode 100644
index 67b98e0fb1..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/indirect.glsl
+++ /dev/null
@@ -1,32 +0,0 @@
-/**
- * @file class2/deferred/indirect.glsl
- *
- * $LicenseInfo:firstyear=2018&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-
-vec3 getIndirect(vec3 ambient, vec3 norm, vec4 pos, vec2 pos_screen)
-{
- return ambient * calcAmbientOcclusion(pos, norm, pos_screen);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
deleted file mode 100644
index 1b7a1cc6ec..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ /dev/null
@@ -1,299 +0,0 @@
-/**
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
-uniform sampler2D lightFunc;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod; //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-uniform vec3 center;
-uniform float size;
-uniform vec3 color;
-uniform float falloff;
-
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec3 srgb_to_linear(vec3 cs);
-vec3 getNorm(vec2 pos_screen);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
-
- vec3 col = vec3(0,0,0);
-
-#if defined(LOCAL_LIGHT_KILL)
- discard;
-#else
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
-
- if (dist >= size)
- {
- discard;
- }
- dist /= size;
-
- float shadow = 1.0;
-
- if (proj_shadow_idx >= 0)
- {
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx==0)?shd.b:shd.a;
- shadow += shadow_fade;
- shadow = clamp(shadow, 0.0, 1.0);
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
-
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
-
- vec3 dlit = vec3(0, 0, 0);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
-
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
-
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
-
- // unshadowed for consistency between forward and deferred?
- amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- // use unshadowed for consistency between forward and deferred?
- amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
- amb_da *= dist_atten * noise;
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
-
- if (spec.a > 0.0)
- {
- vec3 npos = -normalize(pos);
- dlit *= min(da*6.0, 1.0) * dist_atten;
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- vec3 speccol = dlit*scol*spec.rgb*shadow;
- speccol = clamp(speccol, vec3(0), vec3(1));
- col += speccol;
- }
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
- }
- }
- }
- }
-#endif
-
- //not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
-
- //output linear
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
new file mode 100644
index 0000000000..35d752be02
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl
@@ -0,0 +1,312 @@
+/**
+ * @file class1\deferred\pbralphaF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+#ifndef IS_HUD
+
+uniform sampler2D diffuseMap; //always in sRGB space
+uniform sampler2D bumpMap;
+uniform sampler2D emissiveMap;
+uniform sampler2D specularMap; // PBR: Packed: Occlusion, Metal, Roughness
+
+uniform float metallicFactor;
+uniform float roughnessFactor;
+uniform vec3 emissiveColor;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+uniform sampler2D lightMap;
+#endif
+
+uniform int sun_up_factor;
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+
+out vec4 frag_color;
+
+in vec3 vary_fragcoord;
+
+#ifdef HAS_SUN_SHADOW
+ uniform vec2 screen_res;
+#endif
+
+in vec3 vary_position;
+
+in vec2 base_color_texcoord;
+in vec2 normal_texcoord;
+in vec2 metallic_roughness_texcoord;
+in vec2 emissive_texcoord;
+
+in vec4 vertex_color;
+
+in vec3 vary_normal;
+in vec3 vary_tangent;
+flat in float vary_sign;
+
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+#endif
+
+// Lights
+// See: LLRender::syncLightState()
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8]; // spot direction
+uniform vec4 light_attenuation[8]; // linear, quadratic, is omni, unused, See: LLPipeline::setupHWLights() and syncLightState()
+uniform vec3 light_diffuse[8];
+uniform vec2 light_deferred_attenuation[8]; // light size and falloff
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten);
+
+#ifdef WATER_FOG
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
+#endif
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
+
+void waterClip(vec3 pos);
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+vec3 calcPointLightOrSpotLight(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 p, // pixel position
+ vec3 v, // view vector (negative normalized pixel position)
+ vec3 lp, // light position
+ vec3 ld, // light direction (for spotlights)
+ vec3 lightColor,
+ float lightSize, float falloff, float is_pointlight, float ambiance)
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 lv = lp.xyz - p;
+
+ float lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ // spotlight coefficient.
+ float spot = max(dot(-ld, lv), is_pointlight);
+ // spot*spot => GL_SPOT_EXPONENT=2
+ float spot_atten = spot*spot;
+
+ vec3 intensity = spot_atten * dist_atten * lightColor * 3.0; //magic number to balance with legacy materials
+
+ color = intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+
+ return color;
+}
+
+void main()
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+ vec3 pos = vary_position;
+
+ waterClip(pos);
+
+ vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+ basecolor.rgb = srgb_to_linear(basecolor.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (basecolor.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ vec3 col = vertex_color.rgb * basecolor.rgb;
+
+ vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 norm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ norm *= gl_FrontFacing ? 1.0 : -1.0;
+
+ float scol = 1.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+
+ vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5;
+
+#ifdef HAS_SUN_SHADOW
+ scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag);
+#endif
+
+ vec3 orm = texture(specularMap, metallic_roughness_texcoord.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space
+
+ float perceptualRoughness = orm.g * roughnessFactor;
+ float metallic = orm.b * metallicFactor;
+ float ao = orm.r;
+
+ // emissiveColor is the emissive color factor from GLTF and is already in linear space
+ vec3 colorEmissive = emissiveColor;
+ // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
+ colorEmissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
+
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbes(irradiance, radiance, vary_position.xy*0.5+0.5, pos.xyz, norm.xyz, gloss, true, amblit);
+
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor);
+
+ vec3 v = -normalize(pos.xyz);
+
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
+ color = temp.rgb;
+#endif
+
+ vec3 light = vec3(0);
+
+ // Punctual lights
+#define LIGHT_LOOP(i) light += calcPointLightOrSpotLight(diffuseColor, specularColor, perceptualRoughness, metallic, norm.xyz, pos.xyz, v, light_position[i].xyz, light_direction[i].xyz, light_diffuse[i].rgb, light_deferred_attenuation[i].x, light_deferred_attenuation[i].y, light_attenuation[i].z, light_attenuation[i].w);
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color.rgb += light.rgb;
+
+
+ float a = basecolor.a*vertex_color.a;
+
+ frag_color = max(vec4(color.rgb,a), vec4(0));
+}
+
+#else
+
+uniform sampler2D diffuseMap; //always in sRGB space
+uniform sampler2D emissiveMap;
+
+uniform vec3 emissiveColor;
+
+out vec4 frag_color;
+
+in vec3 vary_position;
+
+in vec2 base_color_texcoord;
+in vec2 emissive_texcoord;
+
+in vec4 vertex_color;
+
+#ifdef HAS_ALPHA_MASK
+uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff()
+#endif
+
+vec3 srgb_to_linear(vec3 c);
+vec3 linear_to_srgb(vec3 c);
+
+
+void main()
+{
+ vec3 color = vec3(0,0,0);
+
+ vec3 pos = vary_position;
+
+ vec4 basecolor = texture(diffuseMap, base_color_texcoord.xy).rgba;
+ basecolor.rgb = srgb_to_linear(basecolor.rgb);
+#ifdef HAS_ALPHA_MASK
+ if (basecolor.a < minimum_alpha)
+ {
+ discard;
+ }
+#endif
+
+ color = vertex_color.rgb * basecolor.rgb;
+
+ // emissiveColor is the emissive color factor from GLTF and is already in linear space
+ vec3 colorEmissive = emissiveColor;
+ // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear
+ colorEmissive *= srgb_to_linear(texture(emissiveMap, emissive_texcoord.xy).rgb);
+
+
+ float a = basecolor.a*vertex_color.a;
+ color += colorEmissive;
+ color = linear_to_srgb(color);
+ frag_color = max(vec4(color.rgb,a), vec4(0));
+}
+
+#endif
diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..52e71edcac
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl
@@ -0,0 +1,80 @@
+/**
+ * @file class2/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// Implementation for when reflection probes are disabled
+
+uniform float reflection_probe_ambiance;
+
+uniform samplerCube environmentMap;
+
+uniform mat3 env_mat;
+
+vec3 srgb_to_linear(vec3 c);
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+ glossenv = srgb_to_linear(texture(environmentMap, env_vec).rgb);
+}
+
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear)
+{
+ sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit_linear);
+}
+
+vec4 sampleReflectionProbesDebug(vec3 pos)
+{
+ // show nothing in debug display
+ return vec4(0, 0, 0, 0);
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear)
+{
+ ambenv = vec3(reflection_probe_ambiance * 0.25);
+
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 env_vec = env_mat * refnormpersp;
+
+ legacyenv = srgb_to_linear(texture(environmentMap, env_vec).rgb);
+
+ glossenv = legacyenv;
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+
+}
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+{
+ color = mix(color.rgb, legacyenv*1.5, envIntensity);
+}
+
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
deleted file mode 100644
index 7700d16007..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ /dev/null
@@ -1,158 +0,0 @@
-/**
- * @file class2/deferred/softenLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DRect depthMap;
-uniform samplerCube environmentMap;
-uniform sampler2D lightFunc;
-
-uniform float blur_size;
-uniform float blur_fidelity;
-
-// Inputs
-uniform mat3 env_mat;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform int sun_up_factor;
-VARYING vec2 vary_fragcoord;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec3 getNorm(vec2 pos_screen);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-float getAmbientClamp();
-vec3 atmosFragLighting(vec3 l, vec3 additive, vec3 atten);
-vec3 scaleSoftClipFrag(vec3 l);
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten);
-vec3 fullbrightScaleSoftClip(vec3 light);
-
-vec3 linear_to_srgb(vec3 c);
-vec3 srgb_to_linear(vec3 c);
-
-#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
-#endif
-
-void main()
-{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec4 pos = getPositionWithDepth(tc, depth);
- vec4 norm = texture2DRect(normalMap, tc);
- float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
-
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- float light_gamma = 1.0 / 1.3;
- da = pow(da, light_gamma);
-
- vec4 diffuse = texture2DRect(diffuseRect, tc);
- diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
- scol_ambocc = pow(scol_ambocc, vec2(light_gamma));
- float scol = max(scol_ambocc.r, diffuse.a);
- float ambocc = scol_ambocc.g;
-
- vec3 color = vec3(0);
- float bloom = 0.0;
-
- vec3 sunlit;
- vec3 amblit;
- vec3 additive;
- vec3 atten;
- calcAtmosphericVars(pos.xyz, light_dir, ambocc, sunlit, amblit, additive, atten, true);
-
- color.rgb = amblit;
-
- float ambient = min(abs(dot(norm.xyz, sun_dir.xyz)), 1.0);
- ambient *= 0.5;
- ambient *= ambient;
- ambient = (1.0 - ambient);
- color.rgb *= ambient;
-
- vec3 sun_contrib = min(da, scol) * sunlit;
- color.rgb += sun_contrib;
- color.rgb *= diffuse.rgb;
-
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
-
- if (spec.a > 0.0) // specular reflection
- {
- float sa = dot(refnormpersp, light_dir.xyz);
- vec3 dumbshiny = sunlit * scol * (texture2D(lightFunc, vec2(sa, spec.a)).r);
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb;
- bloom = dot(spec_contrib, spec_contrib) / 6;
- color.rgb += spec_contrib;
- }
-
- color.rgb = mix(color.rgb, diffuse.rgb, diffuse.a);
-
- if (envIntensity > 0.0)
- { // add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 reflected_color = textureCube(environmentMap, env_vec).rgb;
- color = mix(color.rgb, reflected_color, envIntensity);
- }
-
- if (norm.w < 0.5)
- {
- color = mix(atmosFragLighting(color, additive, atten), fullbrightAtmosTransportFrag(color, additive, atten), diffuse.a);
- color = mix(scaleSoftClipFrag(color), fullbrightScaleSoftClip(color), diffuse.a);
- }
-
-#ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos.xyz, vec4(color, bloom));
- color = fogged.rgb;
- bloom = fogged.a;
-#endif
-
- // convert to linear as fullscreen lights need to sum in linear colorspace
- // and will be gamma (re)corrected downstream...
- frag_color.rgb = srgb_to_linear(color.rgb);
- frag_color.a = bloom;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
index bd11aa3f05..d1db6dd943 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl
@@ -23,13 +23,11 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
+in vec3 position;
uniform vec2 screen_res;
-VARYING vec2 vary_fragcoord;
+out vec2 vary_fragcoord;
// forwards
void setAtmosAttenuation(vec3 c);
@@ -38,12 +36,12 @@ void setAdditiveColor(vec3 c);
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
// appease OSX GLSL compiler/linker by touching all the varyings we said we would
setAtmosAttenuation(vec3(1));
setAdditiveColor(vec3(0));
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
+ vary_fragcoord = (pos.xy*0.5+0.5);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
deleted file mode 100644
index 774f537821..0000000000
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- * @file spotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
-uniform sampler2D lightFunc;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod; //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-uniform float size;
-uniform vec3 color;
-uniform float falloff;
-
-VARYING vec3 trans_center;
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec3 getNorm(vec2 pos_screen);
-vec3 srgb_to_linear(vec3 c);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
- ret.rgb = srgb_to_linear(ret.rgb);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
- vec3 col = vec3(0,0,0);
-
-#if defined(LOCAL_LIGHT_KILL)
- discard;
-#else
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos.xyz;
- float dist = length(lv);
-
- if (dist >= size)
- {
- discard;
- }
- dist /= size;
-
- float shadow = 1.0;
-
- if (proj_shadow_idx >= 0)
- {
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
- shadow += shadow_fade;
- shadow = clamp(shadow, 0.0, 1.0);
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = falloff+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
-
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
- vec4 spec = texture2DRect(specularRect, frag.xy);
- vec3 dlit = vec3(0, 0, 0);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
-
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
-
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
-
- amb_da += (da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
- amb_da *= dist_atten * noise;
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
- if (spec.a > 0.0)
- {
- dlit *= min(da*6.0, 1.0) * dist_atten;
- vec3 npos = -normalize(pos);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- vec3 speccol = dlit*scol*spec.rgb*shadow;
- speccol = clamp(speccol, vec3(0), vec3(1));
- col += speccol;
- }
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
- }
- }
- }
- }
-#endif
-
- //not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
-
- //output linear colors as gamma correction happens down stream
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index 8abdeae5ae..1ea57516a4 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -23,20 +23,14 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
//class 2, shadows, no SSAO
// Inputs
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
uniform vec3 sun_dir;
uniform float shadow_bias;
@@ -53,8 +47,11 @@ void main()
vec4 pos = getPosition(pos_screen);
vec3 norm = getNorm(pos_screen);
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.g = 1.0f;
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+ vec4 col;
+ col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ col.g = 1.0f;
+ col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+
+ frag_color = clamp(col, vec4(0), vec4(1));
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
index 64d99bae2c..0126e09d4c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -22,20 +22,14 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
//class 2 -- shadows and SSAO
// Inputs
-VARYING vec2 vary_fragcoord;
+in vec2 vary_fragcoord;
vec4 getPosition(vec2 pos_screen);
vec3 getNorm(vec2 pos_screen);
@@ -50,8 +44,11 @@ void main()
vec4 pos = getPosition(pos_screen);
vec3 norm = getNorm(pos_screen);
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.g = calcAmbientOcclusion(pos, norm, pos_screen);
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+ vec4 col;
+ col.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
+ col.g = calcAmbientOcclusion(pos, norm, pos_screen);
+ col.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
+ col.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
+
+ frag_color = clamp(col, vec4(0), vec4(1));
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
index bc5eb5181d..5ae7f2c571 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl
@@ -23,19 +23,17 @@
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
+in vec3 position;
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
+out vec2 vary_fragcoord;
uniform vec2 screen_res;
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
+ vary_fragcoord = (pos.xy * 0.5 + 0.5);
}
diff --git a/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl
new file mode 100644
index 0000000000..0753e73dc8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl
@@ -0,0 +1,214 @@
+/**
+ * @file irradianceGenF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform samplerCubeArray reflectionProbes;
+uniform int sourceIdx;
+
+uniform float max_probe_lod;
+
+in vec3 vary_dir;
+
+// Code below is derived from the Khronos GLTF Sample viewer:
+// https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/source/shaders/ibl_filtering.frag
+
+
+#define MATH_PI 3.1415926535897932384626433832795
+
+float u_roughness = 1.0;
+int u_sampleCount = 32;
+float u_lodBias = 2.0;
+int u_width = 64;
+
+// Hammersley Points on the Hemisphere
+// CC BY 3.0 (Holger Dammertz)
+// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
+// with adapted interface
+float radicalInverse_VdC(uint bits)
+{
+ bits = (bits << 16u) | (bits >> 16u);
+ bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
+ bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
+ bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
+ bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
+ return float(bits) * 2.3283064365386963e-10; // / 0x100000000
+}
+
+// hammersley2d describes a sequence of points in the 2d unit square [0,1)^2
+// that can be used for quasi Monte Carlo integration
+vec2 hammersley2d(int i, int N) {
+ return vec2(float(i)/float(N), radicalInverse_VdC(uint(i)));
+}
+
+// Hemisphere Sample
+
+// TBN generates a tangent bitangent normal coordinate frame from the normal
+// (the normal must be normalized)
+mat3 generateTBN(vec3 normal)
+{
+ vec3 bitangent = vec3(0.0, 1.0, 0.0);
+
+ float NdotUp = dot(normal, vec3(0.0, 1.0, 0.0));
+ float epsilon = 0.0000001;
+ /*if (1.0 - abs(NdotUp) <= epsilon)
+ {
+ // Sampling +Y or -Y, so we need a more robust bitangent.
+ if (NdotUp > 0.0)
+ {
+ bitangent = vec3(0.0, 0.0, 1.0);
+ }
+ else
+ {
+ bitangent = vec3(0.0, 0.0, -1.0);
+ }
+ }*/
+
+ vec3 tangent = normalize(cross(bitangent, normal));
+ bitangent = cross(normal, tangent);
+
+ return mat3(tangent, bitangent, normal);
+}
+
+struct MicrofacetDistributionSample
+{
+ float pdf;
+ float cosTheta;
+ float sinTheta;
+ float phi;
+};
+
+MicrofacetDistributionSample Lambertian(vec2 xi, float roughness)
+{
+ MicrofacetDistributionSample lambertian;
+
+ // Cosine weighted hemisphere sampling
+ // http://www.pbr-book.org/3ed-2018/Monte_Carlo_Integration/2D_Sampling_with_Multidimensional_Transformations.html#Cosine-WeightedHemisphereSampling
+ lambertian.cosTheta = sqrt(1.0 - xi.y);
+ lambertian.sinTheta = sqrt(xi.y); // equivalent to `sqrt(1.0 - cosTheta*cosTheta)`;
+ lambertian.phi = 2.0 * MATH_PI * xi.x;
+
+ lambertian.pdf = lambertian.cosTheta / MATH_PI; // evaluation for solid angle, therefore drop the sinTheta
+
+ return lambertian;
+}
+
+
+// getImportanceSample returns an importance sample direction with pdf in the .w component
+vec4 getImportanceSample(int sampleIndex, vec3 N, float roughness)
+{
+ // generate a quasi monte carlo point in the unit square [0.1)^2
+ vec2 xi = hammersley2d(sampleIndex, u_sampleCount);
+
+ MicrofacetDistributionSample importanceSample;
+
+ // generate the points on the hemisphere with a fitting mapping for
+ // the distribution (e.g. lambertian uses a cosine importance)
+ importanceSample = Lambertian(xi, roughness);
+
+ // transform the hemisphere sample to the normal coordinate frame
+ // i.e. rotate the hemisphere to the normal direction
+ vec3 localSpaceDirection = normalize(vec3(
+ importanceSample.sinTheta * cos(importanceSample.phi),
+ importanceSample.sinTheta * sin(importanceSample.phi),
+ importanceSample.cosTheta
+ ));
+ mat3 TBN = generateTBN(N);
+ vec3 direction = TBN * localSpaceDirection;
+
+ return vec4(direction, importanceSample.pdf);
+}
+
+// Mipmap Filtered Samples (GPU Gems 3, 20.4)
+// https://developer.nvidia.com/gpugems/gpugems3/part-iii-rendering/chapter-20-gpu-based-importance-sampling
+// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+float computeLod(float pdf)
+{
+ // // Solid angle of current sample -- bigger for less likely samples
+ // float omegaS = 1.0 / (float(u_sampleCount) * pdf);
+ // // Solid angle of texel
+ // // note: the factor of 4.0 * MATH_PI
+ // float omegaP = 4.0 * MATH_PI / (6.0 * float(u_width) * float(u_width));
+ // // Mip level is determined by the ratio of our sample's solid angle to a texel's solid angle
+ // // note that 0.5 * log2 is equivalent to log4
+ // float lod = 0.5 * log2(omegaS / omegaP);
+
+ // babylon introduces a factor of K (=4) to the solid angle ratio
+ // this helps to avoid undersampling the environment map
+ // this does not appear in the original formulation by Jaroslav Krivanek and Mark Colbert
+ // log4(4) == 1
+ // lod += 1.0;
+
+ // We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps
+
+ // https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
+ float lod = 0.5 * log2( 6.0 * float(u_width) * float(u_width) / (float(u_sampleCount) * pdf));
+
+
+ return lod;
+}
+
+vec4 filterColor(vec3 N)
+{
+ vec4 color = vec4(0.f);
+
+ for(int i = 0; i < u_sampleCount; ++i)
+ {
+ vec4 importanceSample = getImportanceSample(i, N, 1.0);
+
+ vec3 H = vec3(importanceSample.xyz);
+ float pdf = importanceSample.w;
+
+ // mipmap filtered samples (GPU Gems 3, 20.4)
+ float lod = computeLod(pdf);
+
+ // apply the bias to the lod
+ lod += u_lodBias;
+
+ lod = clamp(lod, 0, max_probe_lod);
+ // sample lambertian at a lower resolution to avoid fireflies
+ vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod);
+
+ color += lambertian;
+ }
+
+ color /= float(u_sampleCount);
+
+ return color;
+}
+
+// entry point
+void main()
+{
+ vec4 color = vec4(0);
+
+ color = filterColor(vary_dir);
+
+ frag_color = max(color, vec4(0));
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl
index 3350267130..c858531998 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowF.glsl
+++ b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeF.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shadowF.glsl
+ * @file reflectionprobeF.glsl
*
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,27 +23,20 @@
* $/LicenseInfo$
*/
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
+in vec2 vary_fragcoord;
-VARYING vec4 pos;
-VARYING float target_pos_x;
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+float getDepth(vec2 pos_screen);
-vec4 computeMoments(float depth, float a);
+vec4 sampleReflectionProbesDebug(vec3 pos);
-void main()
+void main()
{
- frag_color = computeMoments(length(pos), 1.0);
-}
+ vec2 tc = vary_fragcoord.xy;
+ float depth = getDepth(tc.xy);
+ vec4 pos = getPositionWithDepth(tc, depth);
+ frag_color = max(sampleReflectionProbesDebug(pos.xyz), vec4(0));
+}
diff --git a/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl
new file mode 100644
index 0000000000..e45b1c288b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/interface/reflectionprobeV.glsl
@@ -0,0 +1,38 @@
+/**
+ * @file reflectionprobeV.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+in vec3 position;
+
+out vec2 vary_fragcoord;
+
+void main()
+{
+ //transform vertex
+ vec4 pos = vec4(position.xyz, 1.0);
+ gl_Position = pos;
+
+ vary_fragcoord = (pos.xy*0.5+0.5);
+}
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
deleted file mode 100644
index 89d9d1bde3..0000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsSpecularV.glsl
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * @file class2\lighting\sumLightsSpecularV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-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 atmosAffectDirectionalLight(float lightIntensity);
-vec3 atmosGetDiffuseSunlightColor();
-vec3 scaleDownLight(vec3 light);
-
-uniform vec4 light_position[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-vec4 sumLightsSpecular(vec3 pos, vec3 norm, vec4 color, inout vec4 specularColor)
-{
- 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 += light_diffuse[1].rgb * calcDirectionalLightSpecular(specularColor, view, norm, light_position[1].xyz,light_diffuse[1].rgb, 1.0);
- col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[2].xyz, light_attenuation[2].x, light_attenuation[2].y, light_diffuse[2].rgb);
- col.rgb += calcPointLightSpecular(specularSum, view, pos, norm, light_position[3].xyz, light_attenuation[3].x, light_attenuation[3].y, light_diffuse[3].rgb);
- col.rgb = scaleDownLight(col.rgb);
-
- // Add windlight lights
- col.rgb += atmosAmbient();
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLightSpecular(specularSum, view, norm, light_position[0].xyz, atmosGetDiffuseSunlightColor(), 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
deleted file mode 100644
index 30ca88afd2..0000000000
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ /dev/null
@@ -1,60 +0,0 @@
-/**
- * @file class2\lighting\sumLightsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec3 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
-{
- 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 += light_diffuse[1].rgb * calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb = scaleDownLight(col.rgb);
-
-#if defined(LOCAL_LIGHT_KILL)
- col.rgb = vec3(0);
-i#endif
-
- // Add windlight lights
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-
-#if !defined(SUNLIGHT_KILL)
- col.rgb = min(col.rgb*color.rgb, 1.0);
-#endif
-
- return col;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
deleted file mode 100644
index ee9c990b12..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file class2\wl\atmosphericsF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-vec3 scaleSoftClipFrag(vec3 light);
-
-uniform int no_atmo;
-
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- light *= atten.r;
- light += additive;
- return light * 2.0;
-}
-
-vec3 atmosLighting(vec3 light)
-{
- return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
deleted file mode 100644
index 5788871744..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file class2\wl\atmosphericsHelpersV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// Output variables
-
-uniform float scene_light_strength;
-uniform int no_atmo;
-
-vec3 atmosFragAmbient(vec3 light, vec3 amblit)
-{
- if (no_atmo == 1) return light;
- return amblit + light / 2.0;
-}
-
-vec3 atmosFragAffectDirectionalLight(float lightIntensity, vec3 sunlit)
-{
- return sunlit * lightIntensity;
-}
-
-vec3 scaleDownLightFrag(vec3 light)
-{
- return (light / scene_light_strength );
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
deleted file mode 100644
index 9c42b84eca..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsHelpersV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file class2\wl\atmosphericsHelpersV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-
-// Output variables
-vec3 getSunlitColor();
-vec3 getAmblitColor();
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-vec3 getPositionEye();
-
-uniform float scene_light_strength;
-uniform int no_atmo;
-
-vec3 atmosAmbient()
-{
- if (no_atmo == 1) return vec3(0.16);
- return getAmblitColor();
-}
-
-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
deleted file mode 100644
index 4c418e414f..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsV.glsl
+++ /dev/null
@@ -1,56 +0,0 @@
-/**
- * @file class2\wl\atmosphericsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// VARYING param funcs
-
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform int sun_up_factor;
-
-void setSunlitColor(vec3 v);
-void setAmblitColor(vec3 v);
-void setAdditiveColor(vec3 v);
-void setAtmosAttenuation(vec3 v);
-void setPositionEye(vec3 v);
-
-vec3 getAdditiveColor();
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-void calcAtmospherics(vec3 inPositionEye) {
- vec3 P = inPositionEye;
- setPositionEye(P);
- vec3 tmpsunlit = vec3(1);
- vec3 tmpamblit = vec3(1);
- vec3 tmpaddlit = vec3(1);
- vec3 tmpattenlit = vec3(1);
- vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- calcAtmosphericVars(inPositionEye, light_dir, 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, false);
- setSunlitColor(tmpsunlit);
- setAmblitColor(tmpamblit);
- setAdditiveColor(tmpaddlit);
- setAtmosAttenuation(tmpattenlit);
-}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
deleted file mode 100644
index 07733bda18..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ /dev/null
@@ -1,48 +0,0 @@
-/**
- * @file class2\wl\atmosphericVarsF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 getSunlitColor()
-{
- return vec3(0,0,0);
-}
-
-vec3 getAmblitColor()
-{
- return vec3(0,0,0);
-}
-
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-
-vec3 getAtmosAttenuation()
-{
- return vec3(vary_AtmosAttenuation);
-}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
deleted file mode 100644
index 31109aed31..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsV.glsl
+++ /dev/null
@@ -1,84 +0,0 @@
-/**
- * @file class2\wl\atmosphericVars.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 additive_color;
-vec3 atmos_attenuation;
-vec3 sunlit_color;
-vec3 amblit_color;
-vec3 position_eye;
-
-vec3 getSunlitColor()
-{
- return sunlit_color;
-}
-vec3 getAmblitColor()
-{
- return amblit_color;
-}
-
-vec3 getAdditiveColor()
-{
- return additive_color;
-}
-vec3 getAtmosAttenuation()
-{
- return atmos_attenuation;
-}
-
-vec3 getPositionEye()
-{
- return position_eye;
-}
-
-void setPositionEye(vec3 v)
-{
- position_eye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- sunlit_color = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- amblit_color = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- additive_color = v;
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- atmos_attenuation = v;
- vary_AtmosAttenuation = v;
-}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
deleted file mode 100644
index 22e16b7e0f..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterF.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file class2\wl\atmosphericVarsWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-VARYING vec3 vary_PositionEye;
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 getSunlitColor()
-{
- return vec3(0,0,0);
-}
-vec3 getAmblitColor()
-{
- return vec3(0,0,0);
-}
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return vary_AtmosAttenuation;
-}
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
deleted file mode 100644
index 0f2a3ee527..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsWaterV.glsl
+++ /dev/null
@@ -1,81 +0,0 @@
-/**
- * @file class2\wl\atmosphericVarsWaterV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-VARYING vec3 vary_PositionEye;
-VARYING vec3 vary_AdditiveColor;
-VARYING vec3 vary_AtmosAttenuation;
-
-vec3 atmos_attenuation;
-vec3 sunlit_color;
-vec3 amblit_color;
-
-vec3 getSunlitColor()
-{
- return sunlit_color;
-}
-vec3 getAmblitColor()
-{
- return amblit_color;
-}
-
-vec3 getAdditiveColor()
-{
- return vary_AdditiveColor;
-}
-vec3 getAtmosAttenuation()
-{
- return atmos_attenuation;
-}
-
-vec3 getPositionEye()
-{
- return vary_PositionEye;
-}
-
-void setPositionEye(vec3 v)
-{
- vary_PositionEye = v;
-}
-
-void setSunlitColor(vec3 v)
-{
- sunlit_color = v;
-}
-
-void setAmblitColor(vec3 v)
-{
- amblit_color = v;
-}
-
-void setAdditiveColor(vec3 v)
-{
- vary_AdditiveColor = v;
-}
-
-void setAtmosAttenuation(vec3 v)
-{
- atmos_attenuation = 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
deleted file mode 100644
index fa928d993e..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ /dev/null
@@ -1,131 +0,0 @@
-/**
- * @file class2\wl\cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform float cloud_scale;
-uniform float cloud_variance;
-
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING float altitude_blend_factor;
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return cloud_noise_sample;
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
-
- vec4 cloudColorSun = vary_CloudColorSun;
- vec4 cloudColorAmbient = vary_CloudColorAmbient;
- float cloudDensity = vary_CloudDensity;
- vec2 uv3 = vary_texcoord2.xy;
- vec2 uv4 = vary_texcoord3.xy;
-
- if (cloud_scale < 0.001)
- {
- discard;
- }
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
-
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- alpha1 *= altitude_blend_factor;
-
- //if (alpha1 < 0.001f)
- //{
- // discard;
- //}
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- // Combine
- vec4 color;
- color = (cloudColorSun*(1.-alpha2) + cloudColorAmbient);
- color.rgb *= 2.;
- color.rgb = scaleSoftClip(color.rgb);
-
- /// Gamma correct for WL (soft clip effect).
- frag_color = vec4(color.rgb, alpha1);
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
deleted file mode 100644
index 97ffa9feef..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ /dev/null
@@ -1,193 +0,0 @@
-/**
- * @file class2\wl\cloudsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-//////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-// Output parameters
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
-
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING float altitude_blend_factor;
-
-// Inputs
-uniform vec3 camPosLocal;
-
-uniform vec4 lightnorm;
-uniform vec4 sunlight_color;
-uniform vec4 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float max_y;
-
-uniform vec4 glow;
-uniform float sun_moon_glow_factor;
-
-uniform vec4 cloud_color;
-
-uniform float cloud_scale;
-
-// NOTE: Keep these in sync!
-// indra\newview\app_settings\shaders\class1\deferred\skyV.glsl
-// indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
-// indra\newview\app-settings\shaders\class2\windlight\cloudsV.glsl
-// indra\newview\lllegacyatmospherics.cpp
-// indra\newview\llsettingsvo.cpp
-void main()
-{
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Texture coords
- // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
- vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y); // See: LLSettingsVOSky::applySpecial
-
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= cloud_scale;
- vary_texcoord0.xy += 0.5;
-
- vary_texcoord1 = vary_texcoord0;
- vary_texcoord1.x += lightnorm.x * 0.0125;
- vary_texcoord1.y += lightnorm.z * 0.0125;
-
- vary_texcoord2 = vary_texcoord0 * 16.;
- vary_texcoord3 = vary_texcoord1 * 16.;
-
- // Get relative position
- vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
-
- // fade clouds beyond a certain point so the bottom of the sky dome doesn't look silly at high altitude
- altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
-
- // Adj position vector to clamp altitude
- if (rel_pos.y > 0.)
- {
- rel_pos *= (max_y / rel_pos.y);
- }
- if (rel_pos.y < 0.)
- {
- rel_pos *= (-32000. / rel_pos.y);
- }
-
- // Can normalize then
- vec3 rel_pos_norm = normalize(rel_pos);
- float rel_pos_len = length(rel_pos);
-
- // Initialize temp variables
- vec4 sunlight = sunlight_color;
- vec4 light_atten;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
-
- // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
- float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
- sunlight *= exp(-light_atten * off_axis);
-
- // Distance
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist);
-
- // Compute haze glow
- float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- haze_glow *= sun_moon_glow_factor;
-
- // Add "minimum anti-solar illumination"
- // For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
-
- // Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= (1. - cloud_shadow);
-
- // Haze color below cloud
- vec4 additiveColorBelowCloud =
- (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
-
- // CLOUDS
- sunlight = sunlight_color; // SL-14707 reset color -- Clouds are unusually dim in EEP
- off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
- sunlight *= exp(-light_atten * off_axis);
-
- // Cloud color out
- vary_CloudColorSun = (sunlight * haze_glow) * cloud_color;
- vary_CloudColorAmbient = tmpAmbient * cloud_color;
-
- // Attenuate cloud color by atmosphere
- combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
- vary_CloudColorSun *= combined_haze;
- vary_CloudColorAmbient *= combined_haze;
- vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
-
- // Make a nice cloud density based on the cloud_shadow value that was passed in.
- vary_CloudDensity = 2. * (cloud_shadow - 0.25);
-
- // 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
deleted file mode 100644
index 68db7fcbb1..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * @file class2\wl\gammaF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-uniform float gamma;
-uniform int no_atmo;
-
-vec3 getAtmosAttenuation();
-vec3 getAdditiveColor();
-
-vec3 scaleSoftClipFrag(vec3 light)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- //soft clip effect:
- light = 1. - clamp(light, vec3(0.), vec3(1.));
- light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side
- return light;
-}
-
-vec3 scaleSoftClip(vec3 light)
-{
- return scaleSoftClipFrag(light);
-}
-
-vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten)
-{
- //return mix(scaleSoftClipFrag(light.rgb), add, atten);
- return scaleSoftClipFrag(light.rgb);
-}
-
-vec3 fullbrightScaleSoftClip(vec3 light)
-{
- return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
diff --git a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl b/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
deleted file mode 100644
index 7146349453..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/skyF.glsl
+++ /dev/null
@@ -1,55 +0,0 @@
-/**
- * @file class2/windlight/skyF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-VARYING vec4 vary_HazeColor;
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 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.rgb *= 2.;
- /// Gamma correct for WL (soft clip effect).
- frag_color.rgb = scaleSoftClip(color.rgb);
- frag_color.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
deleted file mode 100644
index a0a33b8642..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/skyV.glsl
+++ /dev/null
@@ -1,149 +0,0 @@
-/**
- * @file class2\wl\skyV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-// 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 moonlight_color;
-uniform int sun_up_factor;
-uniform vec4 ambient_color;
-uniform vec4 blue_horizon;
-uniform vec4 blue_density;
-uniform float haze_horizon;
-uniform float haze_density;
-
-uniform float cloud_shadow;
-uniform float density_multiplier;
-uniform float distance_multiplier;
-uniform float max_y;
-
-uniform vec4 glow;
-uniform float sun_moon_glow_factor;
-
-uniform vec4 cloud_color;
-
-void main()
-{
- // World / view / projection
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- gl_Position = pos;
-
- // Get relative position
- vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
-
- // Adj position vector to clamp altitude
- if (rel_pos.y > 0.)
- {
- rel_pos *= (max_y / rel_pos.y);
- }
- if (rel_pos.y < 0.)
- {
- rel_pos *= (-32000. / rel_pos.y);
- }
-
- // Can normalize then
- vec3 rel_pos_norm = normalize(rel_pos);
-
- float rel_pos_len = length(rel_pos);
-
- // Initialize temp variables
- vec4 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color;
- vec4 light_atten;
-
- // Sunlight attenuation effect (hue and brightness) due to atmosphere
- // this is used later for sunlight modulation at various altitudes
- light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
-
- // Calculate relative weights
- vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
- vec4 blue_weight = blue_density / combined_haze;
- vec4 haze_weight = haze_density / combined_haze;
-
- // Compute sunlight from rel_pos & lightnorm (for long rays like sky)
- float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
- sunlight *= exp(-light_atten * off_axis);
-
- // Distance
- float density_dist = rel_pos_len * density_multiplier;
-
- // Transparency (-> combined_haze)
- // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
- // compiler gets confused.
- combined_haze = exp(-combined_haze * density_dist);
-
- // Compute haze glow
- float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
- // haze_glow is 0 at the sun and increases away from sun
- haze_glow = max(haze_glow, .001);
- // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
- haze_glow *= glow.x;
- // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
- haze_glow = pow(haze_glow, glow.z);
- // glow.z should be negative, so we're doing a sort of (1 / "angle") function
-
- // Add "minimum anti-solar illumination"
- // For sun, add to glow. For moon, remove glow entirely. SL-13768
- haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
-
- vec4 color =
- (blue_horizon * blue_weight * (sunlight + ambient_color) + (haze_horizon * haze_weight) * (sunlight * haze_glow + ambient_color));
-
- // Final atmosphere additive
- color *= (1. - combined_haze);
-
- // Increase ambient when there are more clouds
- vec4 tmpAmbient = ambient_color;
- tmpAmbient += max(vec4(0), (1. - ambient_color)) * cloud_shadow * 0.5;
-
- // Dim sunlight by cloud shadow percentage
- sunlight *= max(0.0, (1. - cloud_shadow));
-
- // Haze color below cloud
- vec4 additiveColorBelowCloud =
- (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
-
- // Attenuate cloud color by atmosphere
- combined_haze = sqrt(combined_haze); // less atmos opacity (more transparency) below clouds
-
- // At horizon, blend high altitude sky color towards the darker color below the clouds
- color += (additiveColorBelowCloud - color) * (1. - sqrt(combined_haze));
-
- // Haze color above cloud
- vary_HazeColor = color;
-}
diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
deleted file mode 100644
index b53a2e237f..0000000000
--- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file class2\wl\transportF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-
-uniform int no_atmo;
-
-vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- light *= atten.r;
- light += additive * 2.0;
- return light;
-}
-
-vec3 atmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1;
- return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness);
-}
-
-vec3 fullbrightAtmosTransport(vec3 light)
-{
- return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-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
deleted file mode 100644
index df9704ec25..0000000000
--- a/indra/newview/app_settings/shaders/class3/avatar/avatarV.glsl
+++ /dev/null
@@ -1,134 +0,0 @@
-/**
- * @file avatarV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-ATTRIBUTE vec4 clothing;
-
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 calcLighting(vec3 pos, vec3 norm, vec4 color);
-mat4 getSkinnedTransform();
-void calcAtmospherics(vec3 inPositionEye);
-
-uniform vec4 color;
-
-uniform vec4 gWindDir;
-uniform vec4 gSinWaveParams;
-uniform vec4 gGravity;
-
-const vec4 gMinMaxConstants = vec4(1.0, 0.166666, 0.0083143, .00018542); // #minimax-generated coefficients
-const vec4 gPiConstants = vec4(0.159154943, 6.28318530, 3.141592653, 1.5707963); // # {1/2PI, 2PI, PI, PI/2}
-
-void main()
-{
- vary_texcoord0 = texcoord0;
-
- vec4 pos;
- mat4 trans = getSkinnedTransform();
-
- vec3 norm;
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- //wind
- vec4 windEffect;
- windEffect = vec4(dot(norm, gWindDir.xyz));
- pos.x = dot(trans[2].xyz, position.xyz);
- windEffect.xyz = pos.x * vec3(0.015, 0.015, 0.015)
- + windEffect.xyz;
- windEffect.w = windEffect.w * 2.0 + 1.0; // move wind offset value to [-1, 3]
- windEffect.w = windEffect.w*gWindDir.w; // modulate wind strength
-
- windEffect.xyz = windEffect.xyz*gSinWaveParams.xyz
- +vec3(gSinWaveParams.w); // use sin wave params to scale and offset input
-
-
- //reduce to period of 2 PI
- vec4 temp1, temp0, temp2, offsetPos;
- temp1.xyz = windEffect.xyz * gPiConstants.x; // change input as multiple of [0-2PI] to [0-1]
- temp0.y = mod(temp1.x,1.0);
- windEffect.x = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- temp1.z = temp1.z - gPiConstants.w; // shift normal oscillation by PI/2
- temp0.y = mod(temp1.z,1.0);
-
- windEffect.z = temp0.y * gPiConstants.y; // scale from [0,1] to [0, 2PI]
- windEffect.xyz = windEffect.xyz + vec3(-3.141592); // offset to [-PI, PI]
-
-
- //calculate sinusoid
- vec4 sinWave;
- temp1 = windEffect*windEffect;
- sinWave = -temp1 * gMinMaxConstants.w
- + vec4(gMinMaxConstants.z); // y = -(x^2)/7! + 1/5!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.y); // y = -(x^2) * (-(x^2)/7! + 1/5!) + 1/3!
- sinWave = sinWave * -temp1 + vec4(gMinMaxConstants.x); // y = -(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1
- sinWave = sinWave * windEffect; // y = x * (-(x^2) * (-(x^2) * (-(x^2)/7! + 1/5!) + 1/3!) + 1)
-
- // sinWave.x holds sin(norm . wind_direction) with primary frequency
- // sinWave.y holds sin(norm . wind_direction) with secondary frequency
- // sinWave.z hold cos(norm . wind_direction) with primary frequency
- sinWave.xyz = sinWave.xyz * gWindDir.w
- + vec3(windEffect.w); // multiply by wind strength in gWindDir.w [-wind, wind]
-
- // add normal facing bias offset [-wind,wind] -> [-wind - .25, wind + 1]
- temp1 = vec4(dot(norm, gGravity.xyz)); // how much is this normal facing in direction of gGravity?
- temp1 = min(temp1, vec4(0.2,0.0,0.0,0.0)); // clamp [-1, 1] to [-1, 0.2]
- temp1 = temp1*vec4(1.5,0.0,0.0,0.0); // scale from [-1,0.2] to [-1.5, 0.3]
- sinWave.x = sinWave.x + temp1.x; // add gGravity effect to sinwave (only primary frequency)
- sinWave.xyz = sinWave.xyz * clothing.w; // modulate by clothing coverage
-
- sinWave.xyz = max(sinWave.xyz, vec3(-1.0, -1.0, -1.0)); // clamp to underlying body shape
- offsetPos = clothing * sinWave.x; // multiply wind effect times clothing displacement
- temp2 = gWindDir*sinWave.z + vec4(norm,0); // calculate normal offset due to wind oscillation
- offsetPos = vec4(1.0,1.0,1.0,0.0)*offsetPos+vec4(position.xyz, 1.0); // add to offset vertex position, and zero out effect from w
- norm += temp2.xyz*2.0; // add sin wave effect on normals (exaggerated)
-
- //add "backlighting" effect
- float colorAcc;
- colorAcc = 1.0 - clothing.w;
- norm.z -= colorAcc * 0.2;
-
- //renormalize normal (again)
- norm = normalize(norm);
-
- pos.x = dot(trans[0], offsetPos);
- pos.y = dot(trans[1], offsetPos);
- pos.z = dot(trans[2], offsetPos);
- pos.w = 1.0;
-
- calcAtmospherics(pos.xyz);
-
- vec4 col = calcLighting(pos.xyz, norm, color);
- vertex_color = col;
-
- gl_Position = projection_matrix * pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
deleted file mode 100644
index d973326f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowF.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file avatarShadowF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
deleted file mode 100644
index 1a655e6467..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/attachmentShadowV.glsl
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * @file attachmentShadowV.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-uniform mat4 modelview_matrix;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-mat4 getObjectSkinnedTransform();
-
-VARYING vec4 pos;
-
-void main()
-{
- //transform vertex
- mat4 mat = getObjectSkinnedTransform();
-
- mat = modelview_matrix * mat;
- pos = (mat*vec4(position.xyz, 1.0));
- pos = projection_matrix * vec4(pos.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- pos.z = max(pos.z, -pos.w+0.01);
-#endif
- gl_Position = pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
deleted file mode 100644
index 48eefc7a73..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowF.glsl
+++ /dev/null
@@ -1,52 +0,0 @@
-/**
- * @file avatarShadowF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- frag_color = computeMoments(length(pos), 1.0);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0);
-#endif
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
deleted file mode 100644
index 164b355f20..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/avatarShadowV.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file avatarShadowV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 projection_matrix;
-
-mat4 getSkinnedTransform();
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec3 normal;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-VARYING vec4 pos;
-
-void main()
-{
- vec3 norm;
-
- vec4 pos_in = vec4(position.xyz, 1.0);
- mat4 trans = getSkinnedTransform();
-
- pos.x = dot(trans[0], pos_in);
- pos.y = dot(trans[1], pos_in);
- pos.z = dot(trans[2], pos_in);
- pos.w = 1.0;
-
- norm.x = dot(trans[0].xyz, normal);
- norm.y = dot(trans[1].xyz, normal);
- norm.z = dot(trans[2].xyz, normal);
- norm = normalize(norm);
-
- pos = projection_matrix * pos;
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
-}
-
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
deleted file mode 100644
index 32210f60dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowF.glsl
+++ /dev/null
@@ -1,119 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return normalize(cloud_noise_sample);
-}
-
-vec4 computeMoments(float depth, float alpha);
-
-void main()
-{
- if (cloud_scale >= 0.001)
- {
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 8.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
- vec2 disturbance2 = vec2(cloudNoise((uv1 + uv3) / 4.0f).x, cloudNoise((uv4 + uv2) / 8.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0 + disturbance2.x + disturbance2.y) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- frag_color = computeMoments(length(pos), alpha1);
- }
- else
- {
- frag_color = vec4(0);
- }
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
deleted file mode 100644
index effb070f93..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudShadowV.glsl
+++ /dev/null
@@ -1,63 +0,0 @@
-/**
- * @file cloudShadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec2 vary_texcoord0;
-VARYING vec4 vertex_color;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
deleted file mode 100644
index e40d7e7c75..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsF.glsl
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file class3/deferred/cloudsF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// The fragment shader for the sky
-/////////////////////////////////////////////////////////////////////////
-
-VARYING vec4 vary_CloudColorSun;
-VARYING vec4 vary_CloudColorAmbient;
-VARYING float vary_CloudDensity;
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-uniform sampler2D cloud_noise_texture;
-uniform sampler2D cloud_noise_texture_next;
-uniform float blend_factor;
-uniform vec4 cloud_pos_density1;
-uniform vec4 cloud_pos_density2;
-uniform vec4 cloud_color;
-uniform float cloud_shadow;
-uniform float cloud_scale;
-uniform float cloud_variance;
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-/// Soft clips the light with a gamma correction
-vec3 scaleSoftClip(vec3 light);
-
-vec4 cloudNoise(vec2 uv)
-{
- vec4 a = texture2D(cloud_noise_texture, uv);
- vec4 b = texture2D(cloud_noise_texture_next, uv);
- vec4 cloud_noise_sample = mix(a, b, blend_factor);
- return cloud_noise_sample;
-}
-
-void main()
-{
- // Set variables
- vec2 uv1 = vary_texcoord0.xy;
- vec2 uv2 = vary_texcoord1.xy;
- vec2 uv3 = vary_texcoord2.xy;
- float cloudDensity = 2.0 * (cloud_shadow - 0.25);
-
- if (cloud_scale < 0.001)
- {
- discard;
- }
-
- vec2 uv4 = vary_texcoord3.xy;
-
- vec2 disturbance = vec2(cloudNoise(uv1 / 16.0f).x, cloudNoise((uv3 + uv1) / 16.0f).x) * cloud_variance * (1.0f - cloud_scale * 0.25f);
-
- // Offset texture coords
- uv1 += cloud_pos_density1.xy + (disturbance * 0.2); //large texture, visible density
- uv2 += cloud_pos_density1.xy; //large texture, self shadow
- uv3 += cloud_pos_density2.xy; //small texture, visible density
- uv4 += cloud_pos_density2.xy; //small texture, self shadow
-
- float density_variance = min(1.0, (disturbance.x* 2.0 + disturbance.y* 2.0) * 4.0);
-
- cloudDensity *= 1.0 - (density_variance * density_variance);
-
- // Compute alpha1, the main cloud opacity
- float alpha1 = (cloudNoise(uv1).x - 0.5) + (cloudNoise(uv3).x - 0.5) * cloud_pos_density2.z;
- alpha1 = min(max(alpha1 + cloudDensity, 0.) * 10 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha1 = 1. - alpha1 * alpha1;
- alpha1 = 1. - alpha1 * alpha1;
-
- if (alpha1 < 0.001f)
- {
- discard;
- }
-
- // Compute alpha2, for self shadowing effect
- // (1 - alpha2) will later be used as percentage of incoming sunlight
- float alpha2 = (cloudNoise(uv2).x - 0.5);
- alpha2 = min(max(alpha2 + cloudDensity, 0.) * 2.5 * cloud_pos_density1.z, 1.);
-
- // And smooth
- alpha2 = 1. - alpha2;
- alpha2 = 1. - alpha2 * alpha2;
-
- vec3 view_ray = vary_pos.xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 1.0 - alpha1, sun_direction, transmittance);
-
- vec3 sun_color = vec3(1.0) - exp(-radiance_sun * 0.0001);
-
- // Combine
- vec4 color;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
-
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
-
- vec3 sun_indir = vec3(-view_direction.xy, view_direction.z);
- vec3 amb = vec3(dot(l1r, l1tap * vec4(1, sun_indir)),
- dot(l1g, l1tap * vec4(1, sun_indir)),
- dot(l1b, l1tap * vec4(1, sun_indir)));
-
-
- amb = max(vec3(0), amb);
-
- color.rgb = sun_color * cloud_color.rgb * (1. - alpha2);
- color.rgb = pow(color.rgb, vec3(1.0 / 2.2));
- color.rgb += amb;
-
- frag_data[0] = vec4(color.rgb, alpha1);
- frag_data[1] = vec4(0);
- frag_data[2] = vec4(0,1,0,1);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
deleted file mode 100644
index 71e422ddf0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/cloudsV.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file WLCloudsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-uniform mat4 modelview_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-//////////////////////////////////////////////////////////////////////////
-// The vertex shader for creating the atmospheric sky
-///////////////////////////////////////////////////////////////////////////////
-
-// Output parameters
-VARYING vec2 vary_texcoord0;
-VARYING vec2 vary_texcoord1;
-VARYING vec2 vary_texcoord2;
-VARYING vec2 vary_texcoord3;
-VARYING vec3 vary_pos;
-
-// Inputs
-uniform float cloud_scale;
-uniform vec4 lightnorm;
-uniform vec3 camPosLocal;
-
-void main()
-{
- vary_pos = position;
-
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // Texture coords
- vary_texcoord0 = texcoord0;
- vary_texcoord0.xy -= 0.5;
- vary_texcoord0.xy /= max(0.001, cloud_scale);
- vary_texcoord0.xy += 0.5;
-
- vary_texcoord1 = vary_texcoord0;
- vary_texcoord1.x += lightnorm.x * 0.0125;
- vary_texcoord1.y += lightnorm.z * 0.0125;
-
- vary_texcoord2 = vary_texcoord0 * 16.;
- vary_texcoord3 = vary_texcoord1 * 16.;
-
- // END CLOUDS
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
deleted file mode 100644
index e27bbce094..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/deferredUtil.glsl
+++ /dev/null
@@ -1,79 +0,0 @@
-/**
- * @file class1/deferred/deferredUtil.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform sampler2DRect normalMap;
-uniform sampler2DRect depthMap;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-vec2 getScreenCoordinate(vec2 screenpos)
-{
- vec2 sc = screenpos.xy * 2.0;
- if (screen_res.x > 0 && screen_res.y > 0)
- {
- sc /= screen_res;
- }
- return sc - vec2(1.0, 1.0);
-}
-
-vec3 getNorm(vec2 screenpos)
-{
- vec2 enc = texture2DRect(normalMap, screenpos.xy).xy;
- vec2 fenc = enc*4-2;
- float f = dot(fenc,fenc);
- float g = sqrt(1-f/4);
- vec3 n;
- n.xy = fenc*g;
- n.z = 1-f/2;
- return n;
-}
-
-float getDepth(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen).r;
- return depth;
-}
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = getDepth(pos_screen);
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
-
-vec4 getPositionWithDepth(vec2 pos_screen, float depth)
-{
- vec2 sc = getScreenCoordinate(pos_screen);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl b/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
deleted file mode 100644
index cdaff4b09f..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/depthToShadowVolumeG.glsl
+++ /dev/null
@@ -1,202 +0,0 @@
-/**
- * @file depthToShadowVolumeG.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-#extension GL_ARB_geometry_shader4 : enable
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-layout (triangles) in;
-layout (triangle_strip, max_vertices = 128) out;
-
-uniform sampler2DRect depthMap;
-uniform mat4 shadowMatrix[6];
-uniform vec4 lightpos;
-
-VARYING vec2 vary_texcoord0;
-
-out vec3 to_vec;
-
-void cross_products(out vec4 ns[3], int a, int b, int c)
-{
- ns[0] = cross(gl_PositionIn[b].xyz - gl_PositionIn[a].xyz, gl_PositionIn[c].xyz - gl_PositionIn[a].xyz);
- ns[1] = cross(gl_PositionIn[c].xyz - gl_PositionIn[b].xyz, gl_PositionIn[a].xyz - gl_PositionIn[b].xyz);
- ns[2] = cross(gl_PositionIn[a].xyz - gl_PositionIn[c].xyz, gl_PositionIn[b].xyz - gl_PositionIn[c].xyz);
-}
-
-vec3 getLightDirection(vec4 lightpos, vec3 pos)
-{
-
- vec3 lightdir = lightpos.xyz - lightpos.w * pos;
- return lightdir;
-}
-
-void emitTri(vec4 v[3])
-{
- gl_Position = proj_matrix * v[0];
- EmitVertex();
-
- gl_Position = proj_matrix * v[1];
- EmitVertex();
-
- gl_Position = proj_matrix * v[2];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitQuad(vec4 v[4]
-{
- // Emit a quad as a triangle strip.
- gl_Position = proj_matrix*v[0];
- EmitVertex();
-
- gl_Position = proj_matrix*v[1];
- EmitVertex();
-
- gl_Position = proj_matrix*v[2];
- EmitVertex();
-
- gl_Position = proj_matrix*v[3];
- EmitVertex();
-
- EndPrimitive();
-}
-
-void emitPrimitives(int layer)
-{
- int i = layer;
- gl_Layer = i;
-
- vec4 depth1 = vec4(texture2DRect(depthMap, tc0).rg, texture2DRect(depthMap, tc1).rg));
- vec3 depth2 = vec4(texture2DRect(depthMap, tc2).rg, texture2DRect(depthMap, tc3).rg));
- vec3 depth3 = vec4(texture2DRect(depthMap, tc4).rg, texture2DRect(depthMap, tc5).rg));
- vec3 depth4 = vec4(texture2DRect(depthMap, tc6).rg, texture2DRect(depthMap, tc7).rg));
-
- depth1 = min(depth1, depth2);
- depth1 = min(depth1, depth3);
- depth1 = min(depth1, depth4);
-
- vec2 depth = min(depth1.xy, depth1.zw);
-
- int side = sqrt(gl_VerticesIn);
-
- for (int j = 0; j < side; j++)
- {
- for (int k = 0; k < side; ++k)
- {
- vec3 pos = gl_PositionIn[(j * side) + k].xyz;
- vec4 v = shadowMatrix[i] * vec4(pos, 1.0);
- gl_Position = v;
- to_vec = pos - light_position.xyz * depth;
- EmitVertex();
- }
-
- EndPrimitive();
- }
-
- vec3 norms[3]; // Normals
- vec3 lightdir3]; // Directions toward light
-
- vec4 v[4]; // Temporary vertices
-
- vec4 or_pos[3] =
- { // Triangle oriented toward light source
- gl_PositionIn[0],
- gl_PositionIn[2],
- gl_PositionIn[4]
- };
-
- // Compute normal at each vertex.
- cross_products(n, 0, 2, 4);
-
- // Compute direction from vertices to light.
- lightdir[0] = getLightDirection(lightpos, gl_PositionIn[0].xyz);
- lightdir[1] = getLightDirection(lightpos, gl_PositionIn[2].xyz);
- lightdir[2] = getLightDirection(lightpos, gl_PositionIn[4].xyz);
-
- // Check if the main triangle faces the light.
- bool faces_light = true;
- if (!(dot(ns[0],d[0]) > 0
- |dot(ns[1],d[1]) > 0
- |dot(ns[2],d[2]) > 0))
- {
- // Flip vertex winding order in or_pos.
- or_pos[1] = gl_PositionIn[4];
- or_pos[2] = gl_PositionIn[2];
- faces_light = false;
- }
-
- // Near cap: simply render triangle.
- emitTri(or_pos);
-
- // Far cap: extrude positions to infinity.
- v[0] =vec4(lightpos.w * or_pos[0].xyz - lightpos.xyz,0);
- v[1] =vec4(lightpos.w * or_pos[2].xyz - lightpos.xyz,0);
- v[2] =vec4(lightpos.w * or_pos[1].xyz - lightpos.xyz,0);
-
- emitTri(v);
-
- // Loop over all edges and extrude if needed.
- for ( int i=0; i<3; i++ )
- {
- // Compute indices of neighbor triangle.
- int v0 = i*2;
- int nb = (i*2+1);
- int v1 = (i*2+2) % 6;
- cross_products(n, v0, nb, v1);
-
- // Compute direction to light, again as above.
- d[0] =lightpos.xyz-lightpos.w*gl_PositionIn[v0].xyz;
- d[1] =lightpos.xyz-lightpos.w*gl_PositionIn[nb].xyz;
- d[2] =lightpos.xyz-lightpos.w*gl_PositionIn[v1].xyz;
-
- bool is_parallel = gl_PositionIn[nb].w < 1e-5;
-
- // Extrude the edge if it does not have a
- // neighbor, or if it's a possible silhouette.
- if (is_parallel ||
- ( faces_light != (dot(ns[0],d[0])>0 ||
- dot(ns[1],d[1])>0 ||
- dot(ns[2],d[2])>0) ))
- {
- // Make sure sides are oriented correctly.
- int i0 = faces_light ? v0 : v1;
- int i1 = faces_light ? v1 : v0;
-
- v[0] = gl_PositionIn[i0];
- v[1] = vec4(lightpos.w*gl_PositionIn[i0].xyz - lightpos.xyz, 0);
- v[2] = gl_PositionIn[i1];
- v[3] = vec4(lightpos.w*gl_PositionIn[i1].xyz - lightpos.xyz, 0);
-
- emitQuad(v);
- }
- }
-}
-
-void main()
-{
- // Output
- emitPrimitives(0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
new file mode 100644
index 0000000000..5483a4e29c
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl
@@ -0,0 +1,93 @@
+/**
+ * @file fullbrightShinyF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+#ifndef HAS_DIFFUSE_LOOKUP
+uniform sampler2D diffuseMap;
+#endif
+
+
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+in vec3 vary_texcoord1;
+in vec3 vary_position;
+
+uniform samplerCube environmentMap;
+
+vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten);
+
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+// reflection probe interface
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
+
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+void main()
+{
+#ifdef HAS_DIFFUSE_LOOKUP
+ vec4 color = diffuseLookup(vary_texcoord0.xy);
+#else
+ vec4 color = texture(diffuseMap, vary_texcoord0.xy);
+#endif
+
+ color.rgb *= vertex_color.rgb;
+
+ // SL-9632 HUDs are affected by Atmosphere
+#ifndef IS_HUD
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ vec3 pos = vary_position;
+ calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten);
+
+ float env_intensity = vertex_color.a;
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ vec3 norm = normalize(vary_texcoord1.xyz);
+ vec4 spec = vec4(0,0,0,0);
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, vec2(0), pos.xyz, norm.xyz, spec.a, env_intensity, false, amblit);
+
+ color.rgb = srgb_to_linear(color.rgb);
+
+ applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity);
+ color.rgb = atmosFragLighting(color.rgb, additive, atten);
+#endif
+
+ color.a = 1.0;
+
+ frag_color = max(color, vec4(0));
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
deleted file mode 100644
index 34d26cddea..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShF.glsl
+++ /dev/null
@@ -1,70 +0,0 @@
-/**
- * @file class3/deferred/gatherSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec2 screen_res;
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-void main()
-{
- vec2 offset = vec2(2.0) / screen_res;
-
- vec4 r = vec4(0);
- vec4 g = vec4(0);
- vec4 b = vec4(0);
-
- vec2 tc = vary_frag * 2.0;
-
- r += texture2D(sh_input_r, tc + vec2(0, 0));
- r += texture2D(sh_input_r, tc + vec2(offset.x, 0));
- r += texture2D(sh_input_r, tc + vec2(0, offset.y));
- r += texture2D(sh_input_r, tc + vec2(offset.x, offset.y));
- r /= 4.0f;
-
- g += texture2D(sh_input_g, tc + vec2(0, 0));
- g += texture2D(sh_input_g, tc + vec2(offset.x, 0));
- g += texture2D(sh_input_g, tc + vec2(0, offset.y));
- g += texture2D(sh_input_g, tc + vec2(offset.x, offset.y));
- g /= 4.0f;
-
- b += texture2D(sh_input_b, tc + vec2(0, 0));
- b += texture2D(sh_input_b, tc + vec2(offset.x, 0));
- b += texture2D(sh_input_b, tc + vec2(0, offset.y));
- b += texture2D(sh_input_b, tc + vec2(offset.x, offset.y));
- b /= 4.0f;
-
- frag_data[0] = r;
- frag_data[1] = g;
- frag_data[2] = b;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
deleted file mode 100644
index 337c8a50fe..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/gatherSkyShV.glsl
+++ /dev/null
@@ -1,40 +0,0 @@
-/**
- * @file gatherSkyShV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_frag;
-uniform vec2 screen_res;
-
-void main()
-{
- // pass through untransformed fullscreen pos
- float oo_divisor = screen_res.x / 64.0;
- vec3 pos = (position.xyz * oo_divisor) + vec3(oo_divisor - 1, oo_divisor - 1, 0);
- gl_Position = vec4(pos.xyz, 1.0);
- vary_frag = texcoord0 * oo_divisor;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
deleted file mode 100644
index d5d91c88f0..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShF.glsl
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * @file class3/deferred/genSkyShF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec3 sun_dir;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 calcDirection(vec2 tc)
-{
- float phi = tc.y * 2.0 * 3.14159265;
- float cosTheta = sqrt(1.0 - tc.x);
- float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
- return vec3(cos(phi) * sinTheta, sin(phi) * sinTheta, cosTheta);
-}
-
-// reverse mapping above to convert a hemisphere direction into phi/theta values
-void getPhiAndThetaFromDirection(vec3 dir, out float phi, out float theta)
-{
- float sin_theta;
- float cos_theta;
- cos_theta = dir.z;
- theta = acos(cos_theta);
- sin_theta = sin(theta);
- phi = abs(sin_theta) > 0.0001 ? acos(dir.x / sin_theta) : 1.0;
-}
-
-// reverse mapping above to convert a hemisphere direction into an SH texture sample pos
-vec2 calcShUvFromDirection(vec3 dir)
-{
- vec2 uv;
- float phi;
- float theta;
- getPhiAndThetaFromDirection(dir, phi, theta);
- uv.y = phi / 2.0 * 3.14159265;
- uv.x = theta / 2.0 * 3.14159265;
- return uv;
-}
-
-void projectToL1(vec3 n, vec3 c, vec4 basis, out vec4 coeffs[3])
-{
- coeffs[0] = vec4(basis.x, n * basis.yzw * c.r);
- coeffs[1] = vec4(basis.x, n * basis.yzw * c.g);
- coeffs[2] = vec4(basis.x, n * basis.yzw * c.b);
-}
-
-void main()
-{
- float Y00 = sqrt(1.0 / 3.14159265) * 0.5;
- float Y1x = sqrt(3.0 / 3.14159265) * 0.5;
- float Y1y = Y1x;
- float Y1z = Y1x;
-
- vec4 L1 = vec4(Y00, Y1x, Y1y, Y1z);
-
- vec3 view_direction = calcDirection(vary_frag);
- vec3 sun_direction = normalize(sun_dir);
- vec3 cam_pos = vec3(0, 0, 6360);
-
- vec3 transmittance;
- vec3 radiance = GetSkyLuminance(cam_pos, view_direction, 0.0f, sun_direction, transmittance);
-
- vec3 color = vec3(1.0) - exp(-radiance * 0.0001);
-
- color = pow(color, vec3(1.0/2.2));
-
- vec4 coeffs[3];
- coeffs[0] = vec4(0);
- coeffs[1] = vec4(0);
- coeffs[2] = vec4(0);
-
- projectToL1(view_direction, color.rgb, L1, coeffs);
-
- frag_data[0] = coeffs[0];
- frag_data[1] = coeffs[1];
- frag_data[2] = coeffs[2];
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl b/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
deleted file mode 100644
index b466883dc7..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/genSkyShV.glsl
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file genSkyShV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_frag;
-
-void main()
-{
- // pass through untransformed fullscreen pos
- gl_Position = vec4(position.xyz, 1.0);
- vary_frag = texcoord0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl b/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
deleted file mode 100644
index 33c5667cae..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/indirect.glsl
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * @file class3/deferred/indirect.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-vec3 GetIndirect(vec3 norm)
-{
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
- indirect = clamp(indirect, vec3(0), vec3(1.0));
- return indirect;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
new file mode 100644
index 0000000000..acff03ec4b
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl
@@ -0,0 +1,425 @@
+/**
+* @file materialF.glsl
+*
+* $LicenseInfo:firstyear=2007&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2007, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+/*[EXTRA_CODE_HERE]*/
+
+//class1/deferred/materialF.glsl
+
+// This shader is used for both writing opaque/masked content to the gbuffer and writing blended content to the framebuffer during the alpha pass.
+
+#define DIFFUSE_ALPHA_MODE_NONE 0
+#define DIFFUSE_ALPHA_MODE_BLEND 1
+#define DIFFUSE_ALPHA_MODE_MASK 2
+#define DIFFUSE_ALPHA_MODE_EMISSIVE 3
+
+uniform float emissive_brightness; // fullbright flag, 1.0 == fullbright, 0.0 otherwise
+uniform int sun_up_factor;
+
+#ifdef WATER_FOG
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
+#endif
+
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+
+vec3 srgb_to_linear(vec3 cs);
+vec3 linear_to_srgb(vec3 cs);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+
+out vec4 frag_color;
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+
+uniform samplerCube environmentMap;
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform vec4 morphFactor;
+uniform vec3 camPosLocal;
+uniform mat3 env_mat;
+
+uniform vec3 sun_dir;
+uniform vec3 moon_dir;
+in vec2 vary_fragcoord;
+
+in vec3 vary_position;
+
+uniform mat4 proj_mat;
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform vec4 light_position[8];
+uniform vec3 light_direction[8];
+uniform vec4 light_attenuation[8];
+uniform vec3 light_diffuse[8];
+
+float getAmbientClamp();
+void waterClip(vec3 pos);
+
+vec3 calcPointLightOrSpotLight(vec3 light_col, vec3 npos, vec3 diffuse, vec4 spec, vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight, inout float glare, float ambiance)
+{
+ // SL-14895 inverted attenuation work-around
+ // This routine is tweaked to match deferred lighting, but previously used an inverted la value. To reconstruct
+ // that previous value now that the inversion is corrected, we reverse the calculations in LLPipeline::setupHWLights()
+ // to recover the `adjusted_radius` value previously being sent as la.
+ float falloff_factor = (12.0 * fa) - 9.0;
+ float inverted_la = falloff_factor / la;
+ // Yes, it makes me want to cry as well. DJH
+
+ vec3 col = vec3(0);
+
+ //get light vector
+ vec3 lv = lp.xyz - v;
+
+ //get distance
+ float dist = length(lv);
+ float da = 1.0;
+
+ dist /= inverted_la;
+
+ if (dist > 0.0 && inverted_la > 0.0)
+ {
+ //normalize light vector
+ lv = normalize(lv);
+
+ //distance attenuation
+ float dist_atten = clamp(1.0 - (dist - 1.0*(1.0 - fa)) / fa, 0.0, 1.0);
+ dist_atten *= dist_atten;
+ dist_atten *= 2.0f;
+
+ if (dist_atten <= 0.0)
+ {
+ return col;
+ }
+
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
+ //angular attenuation
+ da *= dot(n, lv);
+
+ float lit = 0.0f;
+
+ float amb_da = ambiance;
+ if (da >= 0)
+ {
+ lit = max(da * dist_atten, 0.0);
+ col = lit * light_col * diffuse;
+ amb_da += (da*0.5 + 0.5) * ambiance;
+ }
+ amb_da += (da*da*0.5 + 0.5) * ambiance;
+ amb_da *= dist_atten;
+ amb_da = min(amb_da, 1.0f - lit);
+
+ // SL-10969 need to see why these are blown out
+ //col.rgb += amb_da * light_col * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ //vec3 ref = dot(pos+lv, norm);
+ vec3 h = normalize(lv + npos);
+ float nh = dot(n, h);
+ float nv = dot(n, npos);
+ float vh = dot(npos, h);
+ float sa = nh;
+ float fres = pow(1 - dot(h, npos), 5)*0.4 + 0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture(lightFunc, vec2(nh, spec.a)).r*gt / (nh*da);
+ vec3 speccol = lit*scol*light_col.rgb*spec.rgb;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ col += speccol;
+
+ float cur_glare = max(speccol.r, speccol.g);
+ cur_glare = max(cur_glare, speccol.b);
+ glare = max(glare, speccol.r);
+ glare += max(cur_glare, 0.0);
+ }
+ }
+ }
+
+ return max(col, vec3(0.0, 0.0, 0.0));
+}
+
+#else
+out vec4 frag_data[4];
+#endif
+
+uniform sampler2D diffuseMap; //always in sRGB space
+
+#ifdef HAS_NORMAL_MAP
+uniform sampler2D bumpMap;
+#endif
+
+#ifdef HAS_SPECULAR_MAP
+uniform sampler2D specularMap;
+
+in vec2 vary_texcoord2;
+#endif
+
+uniform float env_intensity;
+uniform vec4 specular_color; // specular color RGB and specular exponent (glossiness) in alpha
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+uniform float minimum_alpha;
+#endif
+
+#ifdef HAS_NORMAL_MAP
+in vec3 vary_normal;
+in vec3 vary_tangent;
+flat in float vary_sign;
+in vec2 vary_texcoord1;
+#else
+in vec3 vary_normal;
+#endif
+
+in vec4 vertex_color;
+in vec2 vary_texcoord0;
+
+vec2 encode_normal(vec3 n);
+
+// get the transformed normal and apply glossiness component from normal map
+vec3 getNormal(inout float glossiness)
+{
+#ifdef HAS_NORMAL_MAP
+ vec4 vNt = texture(bumpMap, vary_texcoord1.xy);
+ glossiness *= vNt.a;
+ vNt.xyz = vNt.xyz * 2 - 1;
+ float sign = vary_sign;
+ vec3 vN = vary_normal;
+ vec3 vT = vary_tangent.xyz;
+
+ vec3 vB = sign * cross(vN, vT);
+ vec3 tnorm = normalize( vNt.x * vT + vNt.y * vB + vNt.z * vN );
+
+ return tnorm;
+#else
+ return normalize(vary_normal);
+#endif
+}
+
+vec4 getSpecular()
+{
+#ifdef HAS_SPECULAR_MAP
+ vec4 spec = texture(specularMap, vary_texcoord2.xy);
+ spec.rgb *= specular_color.rgb;
+#else
+ vec4 spec = vec4(specular_color.rgb, 1.0);
+#endif
+ return spec;
+}
+
+void alphaMask(float alpha)
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_MASK)
+ // Comparing floats cast from 8-bit values, produces acne right at the 8-bit transition points
+ float bias = 0.001953125; // 1/512, or half an 8-bit quantization
+ if (alpha < minimum_alpha-bias)
+ {
+ discard;
+ }
+#endif
+}
+
+void waterClip()
+{
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ waterClip(vary_position.xyz);
+#endif
+}
+
+float getEmissive(vec4 diffcol)
+{
+#if (DIFFUSE_ALPHA_MODE != DIFFUSE_ALPHA_MODE_EMISSIVE)
+ return emissive_brightness;
+#else
+ return max(diffcol.a, emissive_brightness);
+#endif
+}
+
+float getShadow(vec3 pos, vec3 norm)
+{
+#ifdef HAS_SUN_SHADOW
+ #if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ return sampleDirectionalShadow(pos, norm, vary_texcoord0.xy);
+ #else
+ return 1;
+ #endif
+#else
+ return 1;
+#endif
+}
+
+void main()
+{
+ waterClip();
+
+ // diffcol == diffuse map combined with vertex color
+ vec4 diffcol = texture(diffuseMap, vary_texcoord0.xy);
+ diffcol.rgb *= vertex_color.rgb;
+
+ alphaMask(diffcol.a);
+
+ // spec == specular map combined with specular color
+ vec4 spec = getSpecular();
+ float env = env_intensity * spec.a;
+ float glossiness = specular_color.a;
+ vec3 norm = getNormal(glossiness);
+
+ vec2 abnormal = encode_normal(norm.xyz);
+
+ float emissive = getEmissive(diffcol);
+
+#if (DIFFUSE_ALPHA_MODE == DIFFUSE_ALPHA_MODE_BLEND)
+ //forward rendering, output lit linear color
+ diffcol.rgb = srgb_to_linear(diffcol.rgb);
+ spec.rgb = srgb_to_linear(spec.rgb);
+ spec.a = glossiness; // pack glossiness into spec alpha for lighting functions
+
+ vec3 pos = vary_position;
+
+ float shadow = getShadow(pos, norm);
+
+ vec4 diffuse = diffcol;
+
+ vec3 color = vec3(0,0,0);
+
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
+
+ float bloom = 0.0;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
+
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 amblit_linear = amblit;
+
+ vec3 ambenv;
+ vec3 glossenv;
+ vec3 legacyenv;
+ sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env, true, amblit_linear);
+
+ color = ambenv;
+
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
+ vec3 sun_contrib = min(da, shadow) * sunlit_linear;
+ color.rgb += sun_contrib;
+ color *= diffcol.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ float glare = 0.0;
+
+ if (glossiness > 0.0)
+ {
+ vec3 lv = light_dir.xyz;
+ vec3 h, l, v = -normalize(pos.xyz);
+ float nh, nl, nv, vh, lightDist;
+ vec3 n = norm.xyz;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ if (nl > 0.0 && nh > 0.0)
+ {
+ float lit = min(nl*6.0, 1.0);
+
+ float sa = nh;
+ float fres = pow(1 - vh, 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
+
+ float scol = shadow*fres*texture(lightFunc, vec2(nh, glossiness)).r*gt/(nh*nl);
+ color.rgb += lit*scol*sunlit_linear.rgb*spec.rgb;
+ }
+
+ // add radiance map
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
+ }
+
+ color = mix(color.rgb, diffcol.rgb, emissive);
+
+ if (env > 0.0)
+ { // add environmentmap
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, env);
+
+ float cur_glare = max(max(legacyenv.r, legacyenv.g), legacyenv.b);
+ cur_glare = clamp(cur_glare, 0, 1);
+ cur_glare *= env;
+ glare += cur_glare;
+ }
+
+ color.rgb = atmosFragLightingLinear(color.rgb, additive, atten);
+
+#ifdef WATER_FOG
+ vec4 temp = applyWaterFogViewLinear(pos, vec4(color, 0.0), sunlit_linear);
+ color = temp.rgb;
+#endif
+
+ vec3 npos = normalize(-pos.xyz);
+ vec3 light = vec3(0, 0, 0);
+
+#define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, spec, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
+
+ LIGHT_LOOP(1)
+ LIGHT_LOOP(2)
+ LIGHT_LOOP(3)
+ LIGHT_LOOP(4)
+ LIGHT_LOOP(5)
+ LIGHT_LOOP(6)
+ LIGHT_LOOP(7)
+
+ color += light;
+
+ glare *= 1.0-emissive;
+ glare = min(glare, 1.0);
+ float al = max(diffcol.a, glare) * vertex_color.a;
+
+ frag_color = max(vec4(color, al), vec4(0));
+
+#else // mode is not DIFFUSE_ALPHA_MODE_BLEND, encode to gbuffer
+ // deferred path // See: C++: addDeferredAttachment(), shader: softenLightF.glsl
+ frag_data[0] = vec4(diffcol.rgb, emissive); // gbuffer is sRGB for legacy materials
+ frag_data[1] = vec4(spec.rgb, glossiness); // XYZ = Specular color. W = Specular exponent.
+ frag_data[2] = vec4(encode_normal(norm), env, GBUFFER_FLAG_HAS_ATMOS);; // XY = Normal. Z = Env. intensity. W = 1 skip atmos (mask off fog)
+ frag_data[3] = vec4(0);
+#endif
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
new file mode 100644
index 0000000000..ec8168465e
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl
@@ -0,0 +1,181 @@
+/**
+ * @file class3\deferred\multiPointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform sampler2D depthMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D specularRect;
+uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D lightFunc;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+uniform int light_count;
+uniform vec4 light[LIGHT_COUNT]; // .w = size; see C++ fullscreen_lights.push_back()
+uniform vec4 light_col[LIGHT_COUNT]; // .a = falloff
+
+uniform vec2 screen_res;
+uniform float far_z;
+uniform mat4 inv_proj;
+
+in vec4 vary_fragcoord;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getPosition(vec2 pos_screen);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec2 getScreenXY(vec4 clip);
+vec2 getScreenCoord(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+
+// Util
+vec3 hue_to_rgb(float hue);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void main()
+{
+ vec3 final_color = vec3(0, 0, 0);
+ vec2 tc = getScreenCoord(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+ if (pos.z < far_z)
+ {
+ discard;
+ }
+
+ float envIntensity; // not used for this shader
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec4 spec = texture(specularRect, tc);
+ vec3 diffuse = texture(diffuseRect, tc).rgb;
+
+ vec3 h, l, v = -normalize(pos);
+ float nh, nv, vh, lightDist;
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ for (int light_idx = 0; light_idx < LIGHT_COUNT; ++light_idx)
+ {
+ vec3 lightColor = light_col[ light_idx ].rgb; // Already in linear, see pipeline.cpp: volume->getLightLinearColor();
+ float falloff = light_col[ light_idx ].a;
+ float lightSize = light[ light_idx ].w;
+ vec3 lv = light[ light_idx ].xyz - pos;
+
+ lightDist = length(lv);
+
+ float dist = lightDist / lightSize;
+ if (dist <= 1.0)
+ {
+ lv /= lightDist;
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ vec3 intensity = dist_atten * lightColor * 3.25;
+
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+ }
+ }
+ else
+ {
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ // As of OSX 10.6.7 ATI Apple's crash when using a variable size loop
+ for (int i = 0; i < LIGHT_COUNT; ++i)
+ {
+ vec3 lv = light[i].xyz - pos;
+ float dist = length(lv);
+ dist /= light[i].w;
+ if (dist <= 1.0)
+ {
+ float nl = dot(n, lv);
+ if (nl > 0.0)
+ {
+ float lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ float fa = light_col[i].a;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, fa);
+
+ float lit = nl * dist_atten;
+
+ vec3 col = light_col[i].rgb * lit * diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl * 6.0, 1.0) * dist_atten;
+ float fres = pow(1 - vh, 5) * 0.4 + 0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres * texture(lightFunc, vec2(nh, spec.a)).r * gt / (nh * nl);
+ col += lit * scol * light_col[i].rgb * spec.rgb;
+ }
+ }
+
+ final_color += col;
+ }
+ }
+ }
+ }
+
+ frag_color.rgb = max(final_color, vec3(0));
+ frag_color.a = 0.0;
+
+#ifdef IS_AMD_CARD
+ // If it's AMD make sure the GLSL compiler sees the arrays referenced once by static index. Otherwise it seems to optimise the storage
+ // away which leads to unfun crashes and artifacts.
+ vec4 dummy1 = light[0];
+ vec4 dummy2 = light_col[0];
+ vec4 dummy3 = light[LIGHT_COUNT - 1];
+ vec4 dummy4 = light_col[LIGHT_COUNT - 1];
+#endif
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
index 8f32dfde79..c2b9ed3d96 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file class3/deferred/shVisV.glsl
+ * @file class3\deferred\multiPointLightV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -22,12 +22,16 @@
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-ATTRIBUTE vec3 position;
-VARYING vec4 vary_pos;
+
+in vec3 position;
+
+out vec4 vary_fragcoord;
void main()
{
- // Output
- vary_pos = vec4(position, 1);
- gl_Position = vary_pos;
+ //transform vertex
+ vec4 pos = vec4(position.xyz, 1.0);
+ vary_fragcoord = pos;
+
+ gl_Position = pos;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
deleted file mode 100644
index 9d62b9d180..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl
+++ /dev/null
@@ -1,291 +0,0 @@
-/**
- * @file multiSpotLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform samplerCube environmentMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
-uniform sampler2D lightFunc;
-
-uniform mat4 proj_mat; //screen space to light space
-uniform float proj_near; //near clip for projection
-uniform vec3 proj_p; //plane projection is emitting from (in screen space)
-uniform vec3 proj_n;
-uniform float proj_focus; //distance from plane to begin blurring
-uniform float proj_lod; //(number of mips in proj map)
-uniform float proj_range; //range between near clip and far clip plane of projection
-uniform float proj_ambient_lod;
-uniform float proj_ambiance;
-uniform float near_clip;
-uniform float far_clip;
-
-uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
-uniform float sun_wash;
-uniform int proj_shadow_idx;
-uniform float shadow_fade;
-
-uniform vec3 center;
-uniform float size;
-uniform vec3 color;
-uniform float falloff;
-
-VARYING vec4 vary_fragcoord;
-uniform vec2 screen_res;
-
-uniform mat4 inv_proj;
-
-vec3 getNorm(vec2 pos_screen);
-
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
-
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
-
-
-vec4 getPosition(vec2 pos_screen);
-
-void main()
-{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
- {
- discard;
- }
-
- float shadow = 1.0;
-
- if (proj_shadow_idx >= 0)
- {
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
- shadow += shadow_fade;
- shadow = clamp(shadow, 0.0, 1.0);
- }
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
-
- float envIntensity = norm.z;
-
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5)+1.0;
- float dist_atten = min(1.0-(dist-1.0*(1.0-fa))/fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
- if (dist_atten <= 0.0)
- {
- discard;
- }
-
- lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
-
- vec3 dlit = vec3(0, 0, 0);
-
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
- {
- float amb_da = proj_ambiance;
- float lit = 0.0;
-
- if (da > 0.0)
- {
- lit = da * dist_atten * noise;
-
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
-
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
-
- if (spec.a > 0.0)
- {
- vec3 npos = -normalize(pos);
- dlit *= min(da*6.0, 1.0) * dist_atten;
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
- {
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
- //col += spec.rgb;
- }
- }
-
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
-
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
-
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
-
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
-
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
- {
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
- }
- }
- }
- }
-
- //not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
-
- col = scaleDownLight(col);
-
- //output linear space color as gamma correction happens down stream
- frag_color.rgb = col;
- frag_color.a = 0.0;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
new file mode 100644
index 0000000000..31af1208bd
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl
@@ -0,0 +1,149 @@
+/**
+ * @file class3\deferred\pointLightF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform sampler2D diffuseRect;
+uniform sampler2D specularRect;
+uniform sampler2D normalMap;
+uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+uniform sampler2D lightFunc;
+uniform sampler2D depthMap;
+
+uniform vec3 env_mat[3];
+uniform float sun_wash;
+
+// light params
+uniform vec3 color;
+uniform float falloff;
+uniform float size;
+
+in vec4 vary_fragcoord;
+in vec3 trans_center;
+
+uniform vec2 screen_res;
+
+uniform mat4 inv_proj;
+uniform vec4 viewport;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec4 getPosition(vec2 pos_screen);
+vec2 getScreenXY(vec4 clip);
+vec2 getScreenCoord(vec4 clip);
+vec3 srgb_to_linear(vec3 c);
+float getDepth(vec2 tc);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+void main()
+{
+ vec3 final_color = vec3(0);
+ vec2 tc = getScreenCoord(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
+
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+
+ vec3 diffuse = texture(diffuseRect, tc).rgb;
+ vec4 spec = texture(specularRect, tc);
+
+ // Common half vectors calcs
+ vec3 lv = trans_center.xyz-pos;
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ if (lightDist >= size)
+ {
+ discard;
+ }
+ float dist = lightDist / size;
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ vec3 intensity = dist_atten * color * 3.25; // Legacy attenuation, magic number to balance with legacy materials
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, normalize(lv));
+ }
+ else
+ {
+ if (nl < 0.0)
+ {
+ discard;
+ }
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ float lit = nl * dist_atten;
+
+ final_color = color.rgb*lit*diffuse;
+
+ if (spec.a > 0.0)
+ {
+ lit = min(nl*6.0, 1.0) * dist_atten;
+
+ float sa = nh;
+ float fres = pow(1 - vh, 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ final_color += lit*scol*color.rgb*spec.rgb;
+ }
+ }
+
+ if (dot(final_color, final_color) <= 0.0)
+ {
+ discard;
+ }
+ }
+
+ frag_color.rgb = max(final_color, vec3(0));
+ frag_color.a = 0.0;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
index 3da8531442..8d23f1b427 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightV.glsl
@@ -1,9 +1,9 @@
/**
- * @file pointLightV.glsl
+ * @file class3\deferred\pointLightV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,13 +26,13 @@
uniform mat4 modelview_projection_matrix;
uniform mat4 modelview_matrix;
-ATTRIBUTE vec3 position;
+in vec3 position;
uniform vec3 center;
uniform float size;
-VARYING vec4 vary_fragcoord;
-VARYING vec3 trans_center;
+out vec4 vary_fragcoord;
+out vec3 trans_center;
void main()
{
diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
deleted file mode 100644
index ca9ce3a2e1..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/pointShadowBlurF.glsl
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file pointShadowBlur.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform samplerCube cube_map;
-
-in vec3 to_vec;
-
-out vec4 fragColor;
-
-void main()
-{
- vec4 vcol = texture(cube_map, to_vec);
- fragColor = vec4(vcol.rgb, 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
new file mode 100644
index 0000000000..906e66ecc8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl
@@ -0,0 +1,853 @@
+/**
+ * @file class3/deferred/reflectionProbeF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#define FLT_MAX 3.402823466e+38
+
+#if defined(SSR)
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
+#endif
+
+uniform samplerCubeArray reflectionProbes;
+uniform samplerCubeArray irradianceProbes;
+uniform sampler2D sceneMap;
+uniform int cube_snapshot;
+uniform float max_probe_lod;
+
+uniform bool transparent_surface;
+
+#define MAX_REFMAP_COUNT 256 // must match LL_MAX_REFLECTION_PROBE_COUNT
+
+layout (std140) uniform ReflectionProbes
+{
+ // list of OBBs for user override probes
+ // box is a set of 3 planes outward facing planes and the depth of the box along that plane
+ // for each box refBox[i]...
+ /// box[0..2] - plane 0 .. 2 in [A,B,C,D] notation
+ // box[3][0..2] - plane thickness
+ mat4 refBox[MAX_REFMAP_COUNT];
+ // list of bounding spheres for reflection probes sorted by distance to camera (closest first)
+ vec4 refSphere[MAX_REFMAP_COUNT];
+ // extra parameters
+ // x - irradiance scale
+ // y - radiance scale
+ // z - fade in
+ // w - znear
+ vec4 refParams[MAX_REFMAP_COUNT];
+ // index of cube map in reflectionProbes for a corresponding reflection probe
+ // e.g. cube map channel of refSphere[2] is stored in refIndex[2]
+ // refIndex.x - cubemap channel in reflectionProbes
+ // refIndex.y - index in refNeighbor of neighbor list (index is ivec4 index, not int index)
+ // refIndex.z - number of neighbors
+ // refIndex.w - priority, if negative, this probe has a box influence
+ ivec4 refIndex[MAX_REFMAP_COUNT];
+
+ // neighbor list data (refSphere indices, not cubemap array layer)
+ ivec4 refNeighbor[1024];
+
+ ivec4 refBucket[256];
+
+ // number of reflection probes present in refSphere
+ int refmapCount;
+};
+
+// Inputs
+uniform mat3 env_mat;
+
+// list of probeIndexes shader will actually use after "getRefIndex" is called
+// (stores refIndex/refSphere indices, NOT rerflectionProbes layer)
+int probeIndex[REF_SAMPLE_COUNT];
+
+// number of probes stored in probeIndex
+int probeInfluences = 0;
+
+bool isAbove(vec3 pos, vec4 plane)
+{
+ return (dot(plane.xyz, pos) + plane.w) > 0;
+}
+
+bool sample_automatic = true;
+
+// return true if probe at index i influences position pos
+bool shouldSampleProbe(int i, vec3 pos)
+{
+ if (refIndex[i].w < 0)
+ {
+ vec4 v = refBox[i] * vec4(pos, 1.0);
+ if (abs(v.x) > 1 ||
+ abs(v.y) > 1 ||
+ abs(v.z) > 1)
+ {
+ return false;
+ }
+
+ // never allow automatic probes to encroach on box probes
+ sample_automatic = false;
+ }
+ else
+ {
+ if (refIndex[i].w == 0 && !sample_automatic)
+ {
+ return false;
+ }
+
+ vec3 delta = pos.xyz - refSphere[i].xyz;
+ float d = dot(delta, delta);
+ float r2 = refSphere[i].w;
+ r2 *= r2;
+
+ if (d > r2)
+ { // outside bounding sphere
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int getStartIndex(vec3 pos)
+{
+#if 1
+ int idx = clamp(int(floor(-pos.z)), 0, 255);
+ return clamp(refBucket[idx].x, 1, refmapCount+1);
+#else
+ return 1;
+#endif
+}
+
+// call before sampleRef
+// populate "probeIndex" with N probe indices that influence pos where N is REF_SAMPLE_COUNT
+void preProbeSample(vec3 pos)
+{
+#if REFMAP_LEVEL > 0
+
+ int start = getStartIndex(pos);
+
+ // TODO: make some sort of structure that reduces the number of distance checks
+ for (int i = start; i < refmapCount; ++i)
+ {
+ // found an influencing probe
+ if (shouldSampleProbe(i, pos))
+ {
+ probeIndex[probeInfluences] = i;
+ ++probeInfluences;
+
+ int neighborIdx = refIndex[i].y;
+ if (neighborIdx != -1)
+ {
+ int neighborCount = refIndex[i].z;
+
+ int count = 0;
+ while (count < neighborCount)
+ {
+ // check up to REF_SAMPLE_COUNT-1 neighbors (neighborIdx is ivec4 index)
+
+ // sample refNeighbor[neighborIdx].x
+ int idx = refNeighbor[neighborIdx].x;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ break;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ break;
+ }
+
+ // sample refNeighbor[neighborIdx].y
+ idx = refNeighbor[neighborIdx].y;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ break;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ break;
+ }
+
+ // sample refNeighbor[neighborIdx].z
+ idx = refNeighbor[neighborIdx].z;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ break;
+ }
+ }
+ count++;
+ if (count == neighborCount)
+ {
+ break;
+ }
+
+ // sample refNeighbor[neighborIdx].w
+ idx = refNeighbor[neighborIdx].w;
+ if (shouldSampleProbe(idx, pos))
+ {
+ probeIndex[probeInfluences++] = idx;
+ if (probeInfluences == REF_SAMPLE_COUNT)
+ {
+ break;
+ }
+ }
+ count++;
+
+ ++neighborIdx;
+ }
+
+ break;
+ }
+ }
+ }
+
+ if (sample_automatic)
+ { // probe at index 0 is a special probe for smoothing out automatic probes
+ probeIndex[probeInfluences++] = 0;
+ }
+#else
+ probeIndex[probeInfluences++] = 0;
+#endif
+}
+
+// from https://www.scratchapixel.com/lessons/3d-basic-rendering/minimal-ray-tracer-rendering-simple-shapes/ray-sphere-intersection
+
+// original reference implementation:
+/*
+bool intersect(const Ray &ray) const
+{
+ float t0, t1; // solutions for t if the ray intersects
+#if 0
+ // geometric solution
+ Vec3f L = center - orig;
+ float tca = L.dotProduct(dir);
+ // if (tca < 0) return false;
+ float d2 = L.dotProduct(L) - tca * tca;
+ if (d2 > radius2) return false;
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+#else
+ // analytic solution
+ Vec3f L = orig - center;
+ float a = dir.dotProduct(dir);
+ float b = 2 * dir.dotProduct(L);
+ float c = L.dotProduct(L) - radius2;
+ if (!solveQuadratic(a, b, c, t0, t1)) return false;
+#endif
+ if (t0 > t1) std::swap(t0, t1);
+
+ if (t0 < 0) {
+ t0 = t1; // if t0 is negative, let's use t1 instead
+ if (t0 < 0) return false; // both t0 and t1 are negative
+ }
+
+ t = t0;
+
+ return true;
+} */
+
+// adapted -- assume that origin is inside sphere, return intersection of ray with edge of sphere
+vec3 sphereIntersect(vec3 origin, vec3 dir, vec3 center, float radius2)
+{
+ float t0, t1; // solutions for t if the ray intersects
+
+ vec3 L = center - origin;
+ float tca = dot(L,dir);
+
+ float d2 = dot(L,L) - tca * tca;
+
+ float thc = sqrt(radius2 - d2);
+ t0 = tca - thc;
+ t1 = tca + thc;
+
+ vec3 v = origin + dir * t1;
+ return v;
+}
+
+void swap(inout float a, inout float b)
+{
+ float t = a;
+ a = b;
+ b = a;
+}
+
+// debug implementation, make no assumptions about origin
+void sphereIntersectDebug(vec3 origin, vec3 dir, vec3 center, float radius2, float depth, inout vec4 col)
+{
+ float t[2]; // solutions for t if the ray intersects
+
+ // geometric solution
+ vec3 L = center - origin;
+ float tca = dot(L, dir);
+ // if (tca < 0) return false;
+ float d2 = dot(L, L) - tca * tca;
+ if (d2 > radius2) return;
+ float thc = sqrt(radius2 - d2);
+ t[0] = tca - thc;
+ t[1] = tca + thc;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (t[i] > 0)
+ {
+ if (t[i] > depth)
+ {
+ float w = 0.125/((t[i]-depth)*0.125 + 1.0);
+ col += vec4(0, 0, w, w)*(1.0-min(col.a, 1.0));
+ }
+ else
+ {
+ float w = 0.25;
+ col += vec4(w,w,0,w)*(1.0-min(col.a, 1.0));
+ }
+ }
+ }
+
+}
+
+// from https://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/
+/*
+vec3 DirectionWS = normalize(PositionWS - CameraWS);
+vec3 ReflDirectionWS = reflect(DirectionWS, NormalWS);
+
+// Intersection with OBB convertto unit box space
+// Transform in local unit parallax cube space (scaled and rotated)
+vec3 RayLS = MulMatrix( float(3x3)WorldToLocal, ReflDirectionWS);
+vec3 PositionLS = MulMatrix( WorldToLocal, PositionWS);
+
+vec3 Unitary = vec3(1.0f, 1.0f, 1.0f);
+vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+// Use Distance in WS directly to recover intersection
+vec3 IntersectPositionWS = PositionWS + ReflDirectionWS * Distance;
+vec3 ReflDirectionWS = IntersectPositionWS - CubemapPositionWS;
+
+return texCUBE(envMap, ReflDirectionWS);
+*/
+
+// get point of intersection with given probe's box influence volume
+// origin - ray origin in clip space
+// dir - ray direction in clip space
+// i - probe index in refBox/refSphere
+// d - distance to nearest wall in clip space
+// scale - scale of box, default 1.0
+vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d, float scale)
+{
+ // Intersection with OBB convert to unit box space
+ // Transform in local unit parallax cube space (scaled and rotated)
+ mat4 clipToLocal = refBox[i];
+
+ vec3 RayLS = mat3(clipToLocal) * dir;
+ vec3 PositionLS = (clipToLocal * vec4(origin, 1.0)).xyz;
+
+ d = 1.0-max(max(abs(PositionLS.x), abs(PositionLS.y)), abs(PositionLS.z));
+
+ vec3 Unitary = vec3(scale);
+ vec3 FirstPlaneIntersect = (Unitary - PositionLS) / RayLS;
+ vec3 SecondPlaneIntersect = (-Unitary - PositionLS) / RayLS;
+ vec3 FurthestPlane = max(FirstPlaneIntersect, SecondPlaneIntersect);
+ float Distance = min(FurthestPlane.x, min(FurthestPlane.y, FurthestPlane.z));
+
+ // Use Distance in CS directly to recover intersection
+ vec3 IntersectPositionCS = origin + dir * Distance;
+
+ return IntersectPositionCS;
+}
+
+vec3 boxIntersect(vec3 origin, vec3 dir, int i, out float d)
+{
+ return boxIntersect(origin, dir, i, d, 1.0);
+}
+
+void debugBoxCol(vec3 ro, vec3 rd, float t, vec3 p, inout vec4 col)
+{
+ vec3 v = ro + rd * t;
+
+ v -= ro;
+ vec3 pos = p - ro;
+
+
+ bool behind = dot(v,v) > dot(pos,pos);
+
+ float w = 0.25;
+
+ if (behind)
+ {
+ w *= 0.5;
+ w /= (length(v)-length(pos))*0.5+1.0;
+ col += vec4(0,0,w,w)*(1.0-min(col.a, 1.0));
+ }
+ else
+ {
+ col += vec4(w,w,0,w)*(1.0-min(col.a, 1.0));
+ }
+}
+
+// cribbed from https://iquilezles.org/articles/intersectors/
+// axis aligned box centered at the origin, with size boxSize
+void boxIntersectionDebug( in vec3 ro, in vec3 p, vec3 boxSize, inout vec4 col)
+{
+ vec3 rd = normalize(p-ro);
+
+ vec3 m = 1.0/rd; // can precompute if traversing a set of aligned boxes
+ vec3 n = m*ro; // can precompute if traversing a set of aligned boxes
+ vec3 k = abs(m)*boxSize;
+ vec3 t1 = -n - k;
+ vec3 t2 = -n + k;
+ float tN = max( max( t1.x, t1.y ), t1.z );
+ float tF = min( min( t2.x, t2.y ), t2.z );
+ if( tN>tF || tF<0.0) return ; // no intersection
+
+ float t = tN < 0 ? tF : tN;
+
+ debugBoxCol(ro, rd, t, p, col);
+
+ if (tN > 0) // eye is outside box, check backside, too
+ {
+ debugBoxCol(ro, rd, tF, p, col);
+ }
+}
+
+
+void boxIntersectDebug(vec3 origin, vec3 pos, int i, inout vec4 col)
+{
+ mat4 clipToLocal = refBox[i];
+
+ // transform into unit cube space
+ origin = (clipToLocal * vec4(origin, 1.0)).xyz;
+ pos = (clipToLocal * vec4(pos, 1.0)).xyz;
+
+ boxIntersectionDebug(origin, pos, vec3(1), col);
+}
+
+
+// get the weight of a sphere probe
+// pos - position to be weighted
+// dir - normal to be weighted
+// origin - center of sphere probe
+// r - radius of probe influence volume
+// i - index of probe in refSphere
+// dw - distance weight
+float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, int i, out float dw)
+{
+ float r1 = r * 0.5; // 50% of radius (outer sphere to start interpolating down)
+ vec3 delta = pos.xyz - origin;
+ float d2 = max(length(delta), 0.001);
+
+ float atten = 1.0 - max(d2 - r1, 0.0) / max((r - r1), 0.001);
+ float w = 1.0 / d2;
+
+ w *= refParams[i].z;
+
+ dw = w * atten * max(r, 1.0)*4;
+
+ w *= atten;
+
+ return w;
+}
+
+// Tap a reflection probe
+// pos - position of pixel
+// dir - pixel normal
+// w - weight of sample (distance and angular attenuation)
+// dw - weight of sample (distance only)
+// lod - which mip to sample (lower is higher res, sharper reflections)
+// c - center of probe
+// r2 - radius of probe squared
+// i - index of probe
+vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i)
+{
+ // parallax adjustment
+ vec3 v;
+
+ if (refIndex[i].w < 0)
+ { // box probe
+ float d = 0;
+ v = boxIntersect(pos, dir, i, d);
+
+ w = max(d, 0.001);
+ }
+ else
+ { // sphere probe
+ float r = refSphere[i].w;
+
+ float rr = r * r;
+
+ v = sphereIntersect(pos, dir, c,
+ refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ rr);
+
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
+ }
+
+ v -= c;
+ vec3 d = normalize(v);
+
+ v = env_mat * v;
+
+ vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y;
+
+ return ret.rgb;
+}
+
+// Tap an irradiance map
+// pos - position of pixel
+// dir - pixel normal
+// w - weight of sample (distance and angular attenuation)
+// dw - weight of sample (distance only)
+// i - index of probe
+vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, out float dw, vec3 c, int i, vec3 amblit)
+{
+ // parallax adjustment
+ vec3 v;
+ if (refIndex[i].w < 0)
+ {
+ float d = 0.0;
+ v = boxIntersect(pos, dir, i, d, 3.0);
+ w = max(d, 0.001);
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+
+ // pad sphere for manual probe extending into automatic probe space
+ float rr = r * r;
+
+ v = sphereIntersect(pos, dir, c,
+ refIndex[i].w < 1 ? 4096.0*4096.0 : // <== effectively disable parallax correction for automatically placed probes to keep from bombing the world with obvious spheres
+ rr);
+
+ w = sphereWeight(pos, dir, refSphere[i].xyz, r, i, dw);
+ }
+
+ v -= c;
+ v = env_mat * v;
+
+ vec3 col = textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x;
+
+ col = mix(amblit, col, min(refParams[i].x, 1.0));
+
+ return col;
+}
+
+vec3 sampleProbes(vec3 pos, vec3 dir, float lod)
+{
+ float wsum[2];
+ wsum[0] = 0;
+ wsum[1] = 0;
+
+ float dwsum[2];
+ dwsum[0] = 0;
+ dwsum[1] = 0;
+
+ vec3 col[2];
+ col[0] = vec3(0);
+ col[1] = vec3(0);
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ int p = clamp(abs(refIndex[i].w), 0, 1);
+
+ if (p == 0 && !sample_automatic)
+ {
+ continue;
+ }
+
+ float w = 0;
+ float dw = 0;
+ vec3 refcol;
+
+ {
+ refcol = tapRefMap(pos, dir, w, dw, lod, refSphere[i].xyz, i);
+
+ col[p] += refcol.rgb*w;
+ wsum[p] += w;
+ dwsum[p] += dw;
+ }
+ }
+
+ // mix automatic and manual probes
+ if (sample_automatic && wsum[0] > 0.0)
+ { // some automatic probes were sampled
+ col[0] *= 1.0/wsum[0];
+ if (wsum[1] > 0.0)
+ { //some manual probes were sampled, mix between the two
+ col[1] *= 1.0/wsum[1];
+ col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
+ col[0] = vec3(0);
+ }
+ }
+ else if (wsum[1] > 0.0)
+ {
+ // manual probes were sampled but no automatic probes were
+ col[1] *= 1.0/wsum[1];
+ col[0] = vec3(0);
+ }
+
+ return col[1]+col[0];
+}
+
+vec3 sampleProbeAmbient(vec3 pos, vec3 dir, vec3 amblit)
+{
+ // modified copy/paste of sampleProbes follows, will likely diverge from sampleProbes further
+ // as irradiance map mixing is tuned independently of radiance map mixing
+ float wsum[2];
+ wsum[0] = 0;
+ wsum[1] = 0;
+
+ float dwsum[2];
+ dwsum[0] = 0;
+ dwsum[1] = 0;
+
+ vec3 col[2];
+ col[0] = vec3(0);
+ col[1] = vec3(0);
+
+ for (int idx = 0; idx < probeInfluences; ++idx)
+ {
+ int i = probeIndex[idx];
+ int p = clamp(abs(refIndex[i].w), 0, 1);
+
+ if (p == 0 && !sample_automatic)
+ {
+ continue;
+ }
+
+ {
+ float w = 0;
+ float dw = 0;
+
+ vec3 refcol = tapIrradianceMap(pos, dir, w, dw, refSphere[i].xyz, i, amblit);
+
+ col[p] += refcol*w;
+ wsum[p] += w;
+ dwsum[p] += dw;
+ }
+ }
+
+ // mix automatic and manual probes
+ if (sample_automatic && wsum[0] > 0.0)
+ { // some automatic probes were sampled
+ col[0] *= 1.0/wsum[0];
+ if (wsum[1] > 0.0)
+ { //some manual probes were sampled, mix between the two
+ col[1] *= 1.0/wsum[1];
+ col[1] = mix(col[0], col[1], min(dwsum[1], 1.0));
+ col[0] = vec3(0);
+ }
+ }
+ else if (wsum[1] > 0.0)
+ {
+ // manual probes were sampled but no automatic probes were
+ col[1] *= 1.0/wsum[1];
+ col[0] = vec3(0);
+ }
+
+ return col[1]+col[0];
+}
+
+void doProbeSample(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)
+{
+ // TODO - don't hard code lods
+ float reflection_lods = max_probe_lod;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
+
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
+
+#if defined(SSR)
+ if (cube_snapshot != 1 && glossiness >= 0.9)
+ {
+ vec4 ssr = vec4(0);
+ if (transparent)
+ {
+ tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap, 1);
+ ssr.a *= glossiness;
+ }
+ else
+ {
+ tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap, glossiness);
+ }
+
+
+ glossenv = mix(glossenv, ssr.rgb, ssr.a);
+ }
+#endif
+}
+
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit)
+{
+ preProbeSample(pos);
+ doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, transparent, amblit);
+}
+
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit)
+{
+ // don't sample automatic probes for water
+ sample_automatic = false;
+ preProbeSample(pos);
+ sample_automatic = true;
+ // always include void probe on water
+ probeIndex[probeInfluences++] = 0;
+
+ doProbeSample(ambenv, glossenv, tc, pos, norm, glossiness, false, amblit);
+
+ // fudge factor to get PBR water at a similar luminance ot legacy water
+ glossenv *= 0.4;
+}
+
+void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col)
+{
+ vec3 origin = vec3(0,0,0);
+
+ bool manual_probe = abs(refIndex[i].w) > 0;
+
+ if (manual_probe)
+ {
+ if (refIndex[i].w < 0)
+ {
+ boxIntersectDebug(origin, pos, i, col);
+ }
+ else
+ {
+ float r = refSphere[i].w; // radius of sphere volume
+ float rr = r * r; // radius squared
+
+ float t = 0.0;
+
+ sphereIntersectDebug(origin, dir, refSphere[i].xyz, rr, depth, col);
+ }
+ }
+}
+
+vec4 sampleReflectionProbesDebug(vec3 pos)
+{
+ vec4 col = vec4(0,0,0,0);
+
+ vec3 dir = normalize(pos);
+
+ float d = length(pos);
+
+ for (int i = 1; i < refmapCount; ++i)
+ {
+ debugTapRefMap(pos, dir, d, i, col);
+ }
+
+#if 0 //debug getStartIndex
+ col.g = float(getStartIndex(pos));
+
+ col.g /= 255.0;
+ col.rb = vec2(0);
+ col.a = 1.0;
+#endif
+
+ return col;
+}
+
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit)
+{
+ float reflection_lods = max_probe_lod;
+ preProbeSample(pos);
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
+
+ ambenv = sampleProbeAmbient(pos, norm, amblit);
+
+ if (glossiness > 0.0)
+ {
+ float lod = (1.0-glossiness)*reflection_lods;
+ glossenv = sampleProbes(pos, normalize(refnormpersp), lod);
+ }
+
+ if (envIntensity > 0.0)
+ {
+ legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0);
+ }
+
+#if defined(SSR)
+ if (cube_snapshot != 1)
+ {
+ vec4 ssr = vec4(0);
+
+ if (transparent)
+ {
+ tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap, 1);
+ ssr.a *= glossiness;
+ }
+ else
+ {
+ tapScreenSpaceReflection(1, tc, pos, norm, ssr, sceneMap, glossiness);
+ }
+
+ glossenv = mix(glossenv, ssr.rgb, ssr.a);
+ legacyenv = mix(legacyenv, ssr.rgb, ssr.a);
+ }
+#endif
+
+ glossenv = clamp(glossenv, vec3(0), vec3(10));
+}
+
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm)
+{
+ glossenv *= 0.5; // fudge darker
+ float fresnel = clamp(1.0+dot(normalize(pos.xyz), norm.xyz), 0.3, 1.0);
+ fresnel *= fresnel;
+ fresnel *= spec.a;
+ glossenv *= spec.rgb*fresnel;
+ glossenv *= vec3(1.0) - color; // fake energy conservation
+ color.rgb += glossenv*0.5;
+}
+
+ void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity)
+ {
+ vec3 reflected_color = legacyenv;
+ vec3 lookAt = normalize(pos);
+ float fresnel = 1.0+dot(lookAt, norm.xyz);
+ fresnel *= fresnel;
+ fresnel = min(fresnel+envIntensity, 1.0);
+ reflected_color *= (envIntensity*fresnel);
+ color = mix(color.rgb, reflected_color*0.5, envIntensity);
+ }
+
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
new file mode 100644
index 0000000000..dbf20fe2d8
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostF.glsl
@@ -0,0 +1,93 @@
+/**
+ * @file class3/deferred/screenSpaceReflPostF.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/*[EXTRA_CODE_HERE]*/
+
+out vec4 frag_color;
+
+uniform vec2 screen_res;
+uniform mat4 projection_matrix;
+uniform mat4 inv_proj;
+uniform float zNear;
+uniform float zFar;
+
+in vec2 vary_fragcoord;
+in vec3 camera_ray;
+
+uniform sampler2D specularRect;
+uniform sampler2D diffuseRect;
+uniform sampler2D diffuseMap;
+
+vec3 getNorm(vec2 screenpos);
+float getDepth(vec2 pos_screen);
+float linearDepth(float d, float znear, float zfar);
+float linearDepth01(float d, float znear, float zfar);
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+vec4 getPosition(vec2 pos_screen);
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+
+float random (vec2 uv);
+
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness);
+
+void main()
+{
+ vec2 tc = vary_fragcoord.xy;
+ float depth = linearDepth01(getDepth(tc), zNear, zFar);
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity); // need `norm.w` for GET_GBUFFER_FLAG()
+ vec3 pos = getPositionWithDepth(tc, getDepth(tc)).xyz;
+ vec4 spec = texture(specularRect, tc);
+ vec2 hitpixel;
+
+ vec4 diffuse = texture(diffuseRect, tc);
+ vec3 specCol = spec.rgb;
+
+ vec4 fcol = texture(diffuseMap, tc);
+
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 orm = specCol.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
+
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+
+ specCol = mix(f0, baseColor.rgb, metallic);
+ }
+
+ vec4 collectedColor = vec4(0);
+
+ float w = tapScreenSpaceReflection(4, tc, pos, n, collectedColor, diffuseMap, 0);
+
+ collectedColor.rgb *= specCol.rgb;
+
+ fcol += collectedColor * w;
+ frag_color = max(fcol, vec4(0));
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostV.glsl
index bc5eb5181d..f7e7268cc3 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightV.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflPostV.glsl
@@ -1,41 +1,48 @@
-/**
- * @file sunLightV.glsl
+/**
+ * @file class3/deferred/screenSpaceReflPostV.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
+uniform mat4 projection_matrix;
+uniform mat4 inv_proj;
-VARYING vec2 vary_fragcoord;
+in vec3 position;
uniform vec2 screen_res;
+out vec2 vary_fragcoord;
+out vec3 camera_ray;
+
+
void main()
{
//transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
+ vec4 pos = vec4(position.xyz, 1.0);
gl_Position = pos;
- vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res;
+ vary_fragcoord = pos.xy * 0.5 + 0.5;
+
+ vec4 rayOrig = inv_proj * vec4(pos.xy, 1, 1);
+ camera_ray = rayOrig.xyz / rayOrig.w;
+
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
new file mode 100644
index 0000000000..f14f7eac8d
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/deferred/screenSpaceReflUtil.glsl
@@ -0,0 +1,394 @@
+/**
+ * @file class3/deferred/screenSpaceReflUtil.glsl
+ *
+ * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2007, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+uniform sampler2D sceneMap;
+uniform sampler2D sceneDepth;
+
+uniform vec2 screen_res;
+uniform mat4 projection_matrix;
+//uniform float zNear;
+//uniform float zFar;
+uniform mat4 inv_proj;
+uniform mat4 modelview_delta; // should be transform from last camera space to current camera space
+uniform mat4 inv_modelview_delta;
+
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
+
+float random (vec2 uv)
+{
+ return fract(sin(dot(uv, vec2(12.9898, 78.233))) * 43758.5453123); //simple random function
+}
+
+// Based off of https://github.com/RoundedGlint585/ScreenSpaceReflection/
+// A few tweaks here and there to suit our needs.
+
+vec2 generateProjectedPosition(vec3 pos)
+{
+ vec4 samplePosition = projection_matrix * vec4(pos, 1.f);
+ samplePosition.xy = (samplePosition.xy / samplePosition.w) * 0.5 + 0.5;
+ return samplePosition.xy;
+}
+
+bool isBinarySearchEnabled = true;
+bool isAdaptiveStepEnabled = true;
+bool isExponentialStepEnabled = true;
+bool debugDraw = false;
+
+uniform float iterationCount;
+uniform float rayStep;
+uniform float distanceBias;
+uniform float depthRejectBias;
+uniform float glossySampleCount;
+uniform float adaptiveStepMultiplier;
+uniform float noiseSine;
+
+float epsilon = 0.1;
+
+float getLinearDepth(vec2 tc)
+{
+ float depth = texture(sceneDepth, tc).r;
+
+ vec4 pos = getPositionWithDepth(tc, depth);
+
+ return -pos.z;
+}
+
+bool traceScreenRay(vec3 position, vec3 reflection, out vec4 hitColor, out float hitDepth, float depth, sampler2D textureFrame)
+{
+ // transform position and reflection into same coordinate frame as the sceneMap and sceneDepth
+ reflection += position;
+ position = (inv_modelview_delta * vec4(position, 1)).xyz;
+ reflection = (inv_modelview_delta * vec4(reflection, 1)).xyz;
+ reflection -= position;
+
+ depth = -position.z;
+
+ vec3 step = rayStep * reflection;
+ vec3 marchingPosition = position + step;
+ float delta;
+ float depthFromScreen;
+ vec2 screenPosition;
+ bool hit = false;
+ hitColor = vec4(0);
+
+ int i = 0;
+ if (depth > depthRejectBias)
+ {
+ for (; i < iterationCount && !hit; i++)
+ {
+ screenPosition = generateProjectedPosition(marchingPosition);
+ if (screenPosition.x > 1 || screenPosition.x < 0 ||
+ screenPosition.y > 1 || screenPosition.y < 0)
+ {
+ hit = false;
+ break;
+ }
+ depthFromScreen = getLinearDepth(screenPosition);
+ delta = abs(marchingPosition.z) - depthFromScreen;
+
+ if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon)
+ {
+ break;
+ }
+
+ if (abs(delta) < distanceBias)
+ {
+ vec4 color = vec4(1);
+ if(debugDraw)
+ color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
+ hitColor = texture(sceneMap, screenPosition) * color;
+ hitDepth = depthFromScreen;
+ hit = true;
+ break;
+ }
+ if (isBinarySearchEnabled && delta > 0)
+ {
+ break;
+ }
+ if (isAdaptiveStepEnabled)
+ {
+ float directionSign = sign(abs(marchingPosition.z) - depthFromScreen);
+ //this is sort of adapting step, should prevent lining reflection by doing sort of iterative converging
+ //some implementation doing it by binary search, but I found this idea more cheaty and way easier to implement
+ step = step * (1.0 - rayStep * max(directionSign, 0.0));
+ marchingPosition += step * (-directionSign);
+ }
+ else
+ {
+ marchingPosition += step;
+ }
+
+ if (isExponentialStepEnabled)
+ {
+ step *= adaptiveStepMultiplier;
+ }
+ }
+ if(isBinarySearchEnabled)
+ {
+ for(; i < iterationCount && !hit; i++)
+ {
+ step *= 0.5;
+ marchingPosition = marchingPosition - step * sign(delta);
+
+ screenPosition = generateProjectedPosition(marchingPosition);
+ if (screenPosition.x > 1 || screenPosition.x < 0 ||
+ screenPosition.y > 1 || screenPosition.y < 0)
+ {
+ hit = false;
+ break;
+ }
+ depthFromScreen = getLinearDepth(screenPosition);
+ delta = abs(marchingPosition.z) - depthFromScreen;
+
+ if (depth < depthFromScreen + epsilon && depth > depthFromScreen - epsilon)
+ {
+ break;
+ }
+
+ if (abs(delta) < distanceBias && depthFromScreen != (depth - distanceBias))
+ {
+ vec4 color = vec4(1);
+ if(debugDraw)
+ color = vec4( 0.5+ sign(delta)/2,0.3,0.5- sign(delta)/2, 0);
+ hitColor = texture(sceneMap, screenPosition) * color;
+ hitDepth = depthFromScreen;
+ hit = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return hit;
+}
+
+uniform vec3 POISSON3D_SAMPLES[128] = vec3[128](
+ vec3(0.5433144, 0.1122154, 0.2501391),
+ vec3(0.6575254, 0.721409, 0.16286),
+ vec3(0.02888453, 0.05170321, 0.7573566),
+ vec3(0.06635678, 0.8286457, 0.07157445),
+ vec3(0.8957489, 0.4005505, 0.7916042),
+ vec3(0.3423355, 0.5053263, 0.9193521),
+ vec3(0.9694794, 0.9461077, 0.5406441),
+ vec3(0.9975473, 0.02789414, 0.7320132),
+ vec3(0.07781899, 0.3862341, 0.918594),
+ vec3(0.4439073, 0.9686955, 0.4055861),
+ vec3(0.9657035, 0.6624081, 0.7082613),
+ vec3(0.7712346, 0.07273269, 0.3292839),
+ vec3(0.2489169, 0.2550394, 0.1950516),
+ vec3(0.7249326, 0.9328285, 0.3352458),
+ vec3(0.6028461, 0.4424961, 0.5393377),
+ vec3(0.2879795, 0.7427881, 0.6619173),
+ vec3(0.3193627, 0.0486145, 0.08109283),
+ vec3(0.1233155, 0.602641, 0.4378719),
+ vec3(0.9800708, 0.211729, 0.6771586),
+ vec3(0.4894537, 0.3319927, 0.8087631),
+ vec3(0.4802743, 0.6358885, 0.814935),
+ vec3(0.2692913, 0.9911493, 0.9934899),
+ vec3(0.5648789, 0.8553897, 0.7784553),
+ vec3(0.8497344, 0.7870212, 0.02065313),
+ vec3(0.7503014, 0.2826185, 0.05412734),
+ vec3(0.8045461, 0.6167251, 0.9532926),
+ vec3(0.04225039, 0.2141281, 0.8678675),
+ vec3(0.07116079, 0.9971236, 0.3396397),
+ vec3(0.464099, 0.480959, 0.2775862),
+ vec3(0.6346927, 0.31871, 0.6588384),
+ vec3(0.449012, 0.8189669, 0.2736875),
+ vec3(0.452929, 0.2119148, 0.672004),
+ vec3(0.01506042, 0.7102436, 0.9800494),
+ vec3(0.1970513, 0.4713539, 0.4644522),
+ vec3(0.13715, 0.7253224, 0.5056525),
+ vec3(0.9006432, 0.5335414, 0.02206874),
+ vec3(0.9960898, 0.7961011, 0.01468861),
+ vec3(0.3386469, 0.6337739, 0.9310676),
+ vec3(0.1745718, 0.9114985, 0.1728188),
+ vec3(0.6342545, 0.5721557, 0.4553517),
+ vec3(0.1347412, 0.1137158, 0.7793725),
+ vec3(0.3574478, 0.3448052, 0.08741581),
+ vec3(0.7283059, 0.4753885, 0.2240275),
+ vec3(0.8293507, 0.9971212, 0.2747005),
+ vec3(0.6501846, 0.000688076, 0.7795712),
+ vec3(0.01149416, 0.4930083, 0.792608),
+ vec3(0.666189, 0.1875442, 0.7256873),
+ vec3(0.8538797, 0.2107637, 0.1547532),
+ vec3(0.5826825, 0.9750752, 0.9105834),
+ vec3(0.8914346, 0.08266425, 0.5484225),
+ vec3(0.4374518, 0.02987111, 0.7810078),
+ vec3(0.2287418, 0.1443802, 0.1176908),
+ vec3(0.2671157, 0.8929081, 0.8989366),
+ vec3(0.5425819, 0.5524959, 0.6963879),
+ vec3(0.3515188, 0.8304397, 0.0502702),
+ vec3(0.3354864, 0.2130747, 0.141169),
+ vec3(0.9729427, 0.3509927, 0.6098799),
+ vec3(0.7585629, 0.7115368, 0.9099342),
+ vec3(0.0140543, 0.6072157, 0.9436461),
+ vec3(0.9190664, 0.8497264, 0.1643751),
+ vec3(0.1538157, 0.3219983, 0.2984214),
+ vec3(0.8854713, 0.2968667, 0.8511457),
+ vec3(0.1910622, 0.03047311, 0.3571215),
+ vec3(0.2456353, 0.5568692, 0.3530164),
+ vec3(0.6927255, 0.8073994, 0.5808484),
+ vec3(0.8089353, 0.8969175, 0.3427134),
+ vec3(0.194477, 0.7985603, 0.8712182),
+ vec3(0.7256182, 0.5653068, 0.3985921),
+ vec3(0.9889427, 0.4584851, 0.8363391),
+ vec3(0.5718582, 0.2127113, 0.2950557),
+ vec3(0.5480209, 0.0193435, 0.2992659),
+ vec3(0.6598953, 0.09478426, 0.92187),
+ vec3(0.1385615, 0.2193868, 0.205245),
+ vec3(0.7623423, 0.1790726, 0.1508465),
+ vec3(0.7569032, 0.3773386, 0.4393887),
+ vec3(0.5842971, 0.6538072, 0.5224424),
+ vec3(0.9954313, 0.5763943, 0.9169143),
+ vec3(0.001311183, 0.340363, 0.1488652),
+ vec3(0.8167927, 0.4947158, 0.4454727),
+ vec3(0.3978434, 0.7106082, 0.002727509),
+ vec3(0.5459411, 0.7473233, 0.7062873),
+ vec3(0.4151598, 0.5614617, 0.4748358),
+ vec3(0.4440694, 0.1195122, 0.9624678),
+ vec3(0.1081301, 0.4813806, 0.07047641),
+ vec3(0.2402785, 0.3633997, 0.3898734),
+ vec3(0.2317942, 0.6488295, 0.4221864),
+ vec3(0.01145542, 0.9304277, 0.4105759),
+ vec3(0.3563728, 0.9228861, 0.3282344),
+ vec3(0.855314, 0.6949819, 0.3175117),
+ vec3(0.730832, 0.01478493, 0.5728671),
+ vec3(0.9304829, 0.02653277, 0.712552),
+ vec3(0.4132186, 0.4127623, 0.6084146),
+ vec3(0.7517329, 0.9978395, 0.1330464),
+ vec3(0.5210338, 0.4318751, 0.9721575),
+ vec3(0.02953994, 0.1375937, 0.9458942),
+ vec3(0.1835506, 0.9896691, 0.7919457),
+ vec3(0.3857062, 0.2682322, 0.1264563),
+ vec3(0.6319699, 0.8735335, 0.04390657),
+ vec3(0.5630485, 0.3339024, 0.993995),
+ vec3(0.90701, 0.1512893, 0.8970422),
+ vec3(0.3027443, 0.1144253, 0.1488708),
+ vec3(0.9149003, 0.7382028, 0.7914025),
+ vec3(0.07979286, 0.6892691, 0.2866171),
+ vec3(0.7743186, 0.8046008, 0.4399814),
+ vec3(0.3128662, 0.4362317, 0.6030678),
+ vec3(0.1133721, 0.01605821, 0.391872),
+ vec3(0.5185481, 0.9210006, 0.7889017),
+ vec3(0.8217013, 0.325305, 0.1668191),
+ vec3(0.8358996, 0.1449739, 0.3668382),
+ vec3(0.1778213, 0.5599256, 0.1327691),
+ vec3(0.06690693, 0.5508637, 0.07212365),
+ vec3(0.9750564, 0.284066, 0.5727578),
+ vec3(0.4350255, 0.8949825, 0.03574753),
+ vec3(0.8931149, 0.9177974, 0.8123496),
+ vec3(0.9055127, 0.989903, 0.813235),
+ vec3(0.2897243, 0.3123978, 0.5083504),
+ vec3(0.1519223, 0.3958645, 0.2640327),
+ vec3(0.6840154, 0.6463035, 0.2346607),
+ vec3(0.986473, 0.8714055, 0.3960275),
+ vec3(0.6819352, 0.4169535, 0.8379834),
+ vec3(0.9147297, 0.6144146, 0.7313942),
+ vec3(0.6554981, 0.5014008, 0.9748477),
+ vec3(0.9805915, 0.1318207, 0.2371372),
+ vec3(0.5980836, 0.06796348, 0.9941338),
+ vec3(0.6836596, 0.9917196, 0.2319056),
+ vec3(0.5276511, 0.2745509, 0.5422578),
+ vec3(0.829482, 0.03758276, 0.1240466),
+ vec3(0.2698198, 0.0002266169, 0.3449324)
+);
+
+vec3 getPoissonSample(int i) {
+ return POISSON3D_SAMPLES[i] * 2 - 1;
+}
+
+float tapScreenSpaceReflection(int totalSamples, vec2 tc, vec3 viewPos, vec3 n, inout vec4 collectedColor, sampler2D source, float glossiness)
+{
+#ifdef TRANSPARENT_SURFACE
+collectedColor = vec4(1, 0, 1, 1);
+ return 0;
+#endif
+ collectedColor = vec4(0);
+ int hits = 0;
+
+ float depth = -viewPos.z;
+
+ vec3 rayDirection = normalize(reflect(viewPos, normalize(n)));
+
+ vec2 uv2 = tc * screen_res;
+ float c = (uv2.x + uv2.y) * 0.125;
+ float jitter = mod( c, 1.0);
+
+ vec2 screenpos = 1 - abs(tc * 2 - 1);
+ float vignette = clamp((abs(screenpos.x) * abs(screenpos.y)) * 16,0, 1);
+ vignette *= clamp((dot(normalize(viewPos), n) * 0.5 + 0.5) * 5.5 - 0.8, 0, 1);
+
+ float zFar = 128.0;
+ vignette *= clamp(1.0+(viewPos.z/zFar), 0.0, 1.0);
+
+ vignette *= clamp(glossiness * 3 - 1.7, 0, 1);
+
+ vec4 hitpoint;
+
+ glossiness = 1 - glossiness;
+
+ totalSamples = int(max(glossySampleCount, glossySampleCount * glossiness * vignette));
+
+ totalSamples = max(totalSamples, 1);
+ if (glossiness < 0.35)
+ {
+ if (vignette > 0)
+ {
+ for (int i = 0; i < totalSamples; i++)
+ {
+ vec3 firstBasis = normalize(cross(getPoissonSample(i), rayDirection));
+ vec3 secondBasis = normalize(cross(rayDirection, firstBasis));
+ vec2 coeffs = vec2(random(tc + vec2(0, i)) + random(tc + vec2(i, 0)));
+ vec3 reflectionDirectionRandomized = rayDirection + ((firstBasis * coeffs.x + secondBasis * coeffs.y) * glossiness);
+
+ //float hitDepth;
+
+ bool hit = traceScreenRay(viewPos, normalize(reflectionDirectionRandomized), hitpoint, depth, depth, source);
+
+ hitpoint.a = 0;
+
+ if (hit)
+ {
+ ++hits;
+ collectedColor += hitpoint;
+ collectedColor.a += 1;
+ }
+ }
+
+ if (hits > 0)
+ {
+ collectedColor /= hits;
+ }
+ else
+ {
+ collectedColor = vec4(0);
+ }
+ }
+ }
+ float hitAlpha = hits;
+ hitAlpha /= totalSamples;
+ collectedColor.a = hitAlpha * vignette;
+ return hits;
+}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
deleted file mode 100644
index c8991f7a18..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shVisF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3/deferred/shVisF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
- out vec4 frag_color;
-#else
- #define frag_color gl_FragColor
-#endif
-
-/////////////////////////////////////////////////////////////////////////
-// Fragment shader for L1 SH debug rendering
-/////////////////////////////////////////////////////////////////////////
-
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
-
-uniform mat3 inv_modelviewprojection;
-
-VARYING vec4 vary_pos;
-
-void main(void)
-{
- vec2 coord = vary_pos.xy + vec2(0.5,0.5);
-
- coord.x *= (1.6/0.9);
-
- if (dot(coord, coord) > 0.25)
- {
- discard;
- }
-
- vec4 n = vec4(coord*2.0, 0.0, 1);
- //n.y = -n.y;
- n.z = sqrt(max(1.0-n.x*n.x-n.y*n.y, 0.0));
- //n.xyz = inv_modelviewprojection * n.xyz;
-
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
- vec3 indirect = vec3(
- dot(l1r, l1tap * n),
- dot(l1g, l1tap * n),
- dot(l1b, l1tap * n));
-
- //indirect = pow(indirect, vec3(0.45));
- indirect *= 3.0;
-
- frag_color = vec4(indirect, 1.0);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
deleted file mode 100644
index af1461c297..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaBlendV.glsl
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * @file shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float target_pos_x;
-VARYING vec4 pos;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
- vec4 pos = modelview_projection_matrix * pre_pos;
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
- pos_w = pos.w;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
deleted file mode 100644
index 50f1ffd626..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskF.glsl
+++ /dev/null
@@ -1,74 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskF.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-uniform sampler2D diffuseMap;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING float pos_w;
-
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-vec4 getPosition(vec2 screen_coord);
-vec4 computeMoments(float depth, float a);
-
-void main()
-{
- vec4 pos = getPosition(vary_texcoord0.xy);
-
- float alpha = diffuseLookup(vary_texcoord0.xy).a * vertex_color.a;
-
- if (alpha < 0.05) // treat as totally transparent
- {
- discard;
- }
-
- if (alpha < 0.88) // treat as semi-transparent
- {
- if (fract(0.5*floor(target_pos_x / pos_w )) < 0.25)
- {
- discard;
- }
- }
-
- frag_color = computeMoments(length(pos.xyz), alpha);
-
-#if !defined(DEPTH_CLAMP)
- gl_FragDepth = max(pos_zd2/pos_w+0.5, 0.0);
-#endif
-
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
deleted file mode 100644
index 6a646f5e9e..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowAlphaMaskV.glsl
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file class3/deferred/shadowAlphaMaskV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec4 diffuse_color;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- passTextureIndex();
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-
- vertex_color = diffuse_color;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
deleted file mode 100644
index db8c75fb8a..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowCubeV.glsl
+++ /dev/null
@@ -1,50 +0,0 @@
-/**
- * @file class3/deferred/shadowCubeV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-#if !defined(DEPTH_CLAMP)
-VARYING vec4 post_pos;
-#endif
-
-uniform vec3 box_center;
-uniform vec3 box_size;
-
-void main()
-{
- //transform vertex
- vec3 p = position*box_size+box_center;
- vec4 pos = modelview_projection_matrix*vec4(p.xyz, 1.0);
-
-#if !defined(DEPTH_CLAMP)
- post_pos = pos;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
deleted file mode 100644
index 2f69a353e8..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowUtil.glsl
+++ /dev/null
@@ -1,157 +0,0 @@
-/**
- * @file class3/deferred/shadowUtil.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform sampler2D shadowMap0;
-uniform sampler2D shadowMap1;
-uniform sampler2D shadowMap2;
-uniform sampler2D shadowMap3;
-uniform sampler2D shadowMap4;
-uniform sampler2D shadowMap5;
-
-uniform vec3 sun_dir;
-uniform vec3 moon_dir;
-uniform vec2 shadow_res;
-uniform vec2 proj_shadow_res;
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float shadow_bias;
-
-uniform float spot_shadow_bias;
-uniform float spot_shadow_offset;
-
-float getDepth(vec2 screenpos);
-vec3 getNorm(vec2 screenpos);
-vec4 getPosition(vec2 pos_screen);
-
-float ReduceLightBleeding(float p_max, float Amount)
-{
- return smoothstep(Amount, 1, p_max);
-}
-
-float ChebyshevUpperBound(vec2 m, float t, float min_v, float Amount)
-{
- float p = (t <= m.x) ? 1.0 : 0.0;
-
- float v = m.y - (m.x*m.x);
- v = max(v, min_v);
-
- float d = t - m.x;
-
- float p_max = v / (v + d*d);
-
- p_max = ReduceLightBleeding(p_max, Amount);
-
- return max(p, p_max);
-}
-
-vec4 computeMoments(float depth, float a)
-{
- float m1 = depth;
- float dx = dFdx(depth);
- float dy = dFdy(depth);
- float m2 = m1*m1 + 0.25 * a * (dx*dx + dy*dy);
- return vec4(m1, m2, a, max(dx, dy));
-}
-
-float vsmDirectionalSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- return ChebyshevUpperBound(moments.rg, depth - shadow_bias * 256.0f, 0.125, 0.9);
-}
-
-float vsmSpotSample(vec4 stc, float depth, sampler2D shadowMap, mat4 shadowMatrix)
-{
- vec4 lpos = shadowMatrix * stc;
- vec4 moments = texture2D(shadowMap, lpos.xy);
- lpos.xyz /= lpos.w;
- lpos.xy *= 0.5;
- lpos.xy += 0.5;
- return ChebyshevUpperBound(moments.rg, depth - spot_shadow_bias * 16.0f, 0.125, 0.9);
-}
-
-#if VSM_POINT_SHADOWS
-float vsmPointSample(float lightDistance, vec3 lightDirection, samplerCube shadow_cube_map)
-{
- vec4 moments = textureCube(shadow_cube_map, light_direction);
- return ChebyshevUpperBound(moments.rg, light_distance, 0.01, 0.25);
-}
-#endif
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- vec4 spos = vec4(pos,1.0);
- vec4 near_split = shadow_clip*-0.75;
- vec4 far_split = shadow_clip*-1.25;
-
- float shadow = 0.0f;
- float weight = 1.0;
-
- if (spos.z < near_split.z)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap3, shadow_matrix[3]);
- weight += 1.0f;
- }
- if (spos.z < near_split.y)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap2, shadow_matrix[2]);
- weight += 1.0f;
- }
- if (spos.z < near_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap1, shadow_matrix[1]);
- weight += 1.0f;
- }
- if (spos.z > far_split.x)
- {
- shadow += vsmDirectionalSample(spos, depth, shadowMap0, shadow_matrix[0]);
- weight += 1.0f;
- }
-
- shadow /= weight;
-
- return shadow;
-}
-
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen)
-{
- if (pos.z < -shadow_clip.w)
- {
- discard;
- }
-
- float depth = getDepth(pos_screen);
-
- pos += norm * spot_shadow_offset;
- return vsmSpotSample(vec4(pos, 1.0), depth, (index == 0) ? shadowMap4 : shadowMap5, shadow_matrix[4 + index]);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
deleted file mode 100644
index 6577fe0ecf..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/shadowV.glsl
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * @file class3/deferred/shadowV.glsl
- *
- * $LicenseInfo:firstyear=2011&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2011, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-uniform float shadow_target_width;
-uniform mat4 texture_matrix0;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-#if !defined(DEPTH_CLAMP)
-VARYING float pos_zd2;
-#endif
-
-VARYING vec4 pos;
-VARYING float target_pos_x;
-VARYING vec4 vertex_color;
-VARYING vec2 vary_texcoord0;
-
-void passTextureIndex();
-
-void main()
-{
- //transform vertex
- vec4 pre_pos = vec4(position.xyz, 1.0);
-
- pos = modelview_projection_matrix * pre_pos;
-
- target_pos_x = 0.5 * (shadow_target_width - 1.0) * pos.x;
-
-#if !defined(DEPTH_CLAMP)
- pos_zd2 = pos.z * 0.5;
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-#else
- gl_Position = pos;
-#endif
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
deleted file mode 100644
index a0b082ed7c..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
+++ /dev/null
@@ -1,126 +0,0 @@
-/**
- * @file class3/deferred/skyF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-VARYING vec2 vary_frag;
-
-uniform vec3 camPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-uniform float far_z;
-uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-uniform sampler2D rainbow_map;
-uniform sampler2D halo_map;
-
-uniform float moisture_level;
-uniform float droplet_radius;
-uniform float ice_level;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
-
-vec3 ColorFromRadiance(vec3 radiance);
-vec3 rainbow(float d)
-{
- // d is the dot product of view and sun directions, so ranging -1.0..1.0
- // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
- // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
-
- // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
- // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
- // interesting range, but in reversed order: i.e. d = (1 - d) - 1.575
- d = clamp(-0.575 - d, 0.0, 1.0);
-
- // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
- // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
- // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
- float interior_coord = max(0.0, d - 0.25) * 4.2857;
- d = clamp(d, 0.0, 0.25) + interior_coord;
-
- float rad = (droplet_radius - 5.0f) / 1024.0f;
- return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
-}
-
-vec3 halo22(float d)
-{
- float v = sqrt(max(0, 1 - (d*d)));
- return texture2D(halo_map, vec2(0, v)).rgb * ice_level;
-}
-
-void main()
-{
- vec3 pos = vec3((vary_frag * 2.0) - vec2(1.0, 1.0f), 1.0);
- vec4 view_pos = (inv_proj * vec4(pos, 1.0f));
-
- view_pos /= view_pos.w;
-
- vec3 view_ray = (inv_modelview * vec4(view_pos.xyz, 0.0f)).xyz + camPosLocal;
-
- vec3 view_direction = normalize(view_ray);
- vec3 sun_direction = normalize(sun_dir);
- vec3 earth_center = vec3(0, 0, -6360.0f);
- vec3 camPos = (camPosLocal / 1000.0f) - earth_center;
-
- vec3 transmittance;
- vec3 radiance_sun = GetSkyLuminance(camPos, view_direction, 0.0f, sun_direction, transmittance);
- vec3 solar_luminance = GetSolarLuminance();
-
- // If the view ray intersects the Sun, add the Sun radiance.
- float s = dot(view_direction, sun_direction);
-
- // cheesy solar disc...
- if (s >= (sun_size * 0.999))
- {
- radiance_sun += pow(smoothstep(0.0, 1.3, (s - (sun_size * 0.9))), 2.0) * solar_luminance * transmittance;
- }
- s = smoothstep(0.9, 1.0, s) * 16.0f;
-
- vec3 color = ColorFromRadiance(radiance_sun);
-
- float optic_d = dot(view_direction, sun_direction);
- vec3 halo_22 = halo22(optic_d);
-
- color.rgb += rainbow(optic_d) * optic_d;
- color.rgb += halo_22;
-
- color = pow(color, vec3(1.0/2.2));
-
- frag_data[0] = vec4(color, 1.0 + s);
- frag_data[1] = vec4(0.0);
- frag_data[2] = vec4(0.0, 1.0, 0.0, 1.0);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
deleted file mode 100644
index 2eb222ada4..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/skyV.glsl
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @file class3/deferred/skyV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec2 vary_frag;
-
-void main()
-{
- // pass through untransformed fullscreen pos at back of frustum for proper sky depth testing
- gl_Position = vec4(position.xy, 1.0f, 1.0);
- vary_frag = texcoord0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 7ed9e7b4fc..35e99c5bd2 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -1,177 +1,293 @@
-/**
+/**
* @file class3/deferred/softenLightF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2007, Linden Research, Inc.
- *
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
+ *
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
-
-#extension GL_ARB_texture_rectangle : enable
-/*[EXTRA_CODE_HERE]*/
+#define FLT_MAX 3.402823466e+38
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
+
+uniform sampler2D diffuseRect;
+uniform sampler2D specularRect;
+uniform sampler2D normalMap;
+uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
+
+const float M_PI = 3.14159265;
+
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+uniform sampler2D lightMap;
#endif
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect normalMap;
-uniform sampler2DRect lightMap;
-uniform sampler2DRect depthMap;
+uniform sampler2D depthMap;
uniform sampler2D lightFunc;
-uniform samplerCube environmentMap;
uniform float blur_size;
uniform float blur_fidelity;
+#if defined(HAS_SSAO)
+uniform float ssao_irradiance_scale;
+uniform float ssao_irradiance_max;
+#endif
+
// Inputs
-uniform vec4 morphFactor;
-uniform vec3 camPosLocal;
-uniform float cloud_shadow;
-uniform float max_y;
-uniform vec4 glow;
uniform mat3 env_mat;
-uniform vec4 shadow_clip;
-
+uniform mat3 ssao_effect_mat;
uniform vec3 sun_dir;
-VARYING vec2 vary_fragcoord;
+uniform vec3 moon_dir;
+uniform int sun_up_factor;
+in vec2 vary_fragcoord;
uniform mat4 inv_proj;
-uniform mat4 inv_modelview;
-
uniform vec2 screen_res;
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D single_mie_scattering_texture;
-uniform sampler2D irradiance_texture;
+vec3 getNorm(vec2 pos_screen);
+vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-uniform sampler2D sh_input_r;
-uniform sampler2D sh_input_g;
-uniform sampler2D sh_input_b;
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten);
+vec3 scaleSoftClipFragLinear(vec3 l);
-vec3 GetSunAndSkyIrradiance(vec3 camPos, vec3 norm, vec3 dir, out vec3 sky_irradiance);
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir, out vec3 transmittance);
+// reflection probe interface
+void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, bool transparent, vec3 amblit_linear);
+void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 legacyenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, float envIntensity, bool transparent, vec3 amblit_linear);
+void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 norm);
+void applyLegacyEnv(inout vec3 color, vec3 legacyenv, vec4 spec, vec3 pos, vec3 norm, float envIntensity);
+float getDepth(vec2 pos_screen);
-vec3 ColorFromRadiance(vec3 radiance);
-vec4 getPositionWithDepth(vec2 pos_screen, float depth);
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
+vec3 linear_to_srgb(vec3 c);
+vec3 srgb_to_linear(vec3 c);
+
+uniform vec4 waterPlane;
+
+uniform int cube_snapshot;
#ifdef WATER_FOG
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color);
+#endif
+
+uniform float sky_hdr_scale;
+
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+
+void adjustIrradiance(inout vec3 irradiance, float ambocc)
+{
+ // use sky settings ambient or irradiance map sample, whichever is brighter
+ //irradiance = max(amblit_linear, irradiance);
+
+#if defined(HAS_SSAO)
+ irradiance = mix(ssao_effect_mat * min(irradiance.rgb*ssao_irradiance_scale, vec3(ssao_irradiance_max)), irradiance.rgb, ambocc);
#endif
+}
-void main()
+void main()
{
- vec2 tc = vary_fragcoord.xy;
- float depth = texture2DRect(depthMap, tc.xy).r;
- vec3 pos = getPositionWithDepth(tc, depth).xyz;
- vec4 norm = texture2DRect(normalMap, tc);
+ vec2 tc = vary_fragcoord.xy;
+ float depth = getDepth(tc.xy);
+ vec4 pos = getPositionWithDepth(tc, depth);
+ vec4 norm = texture(normalMap, tc);
float envIntensity = norm.z;
- norm.xyz = getNorm(tc);
+ norm.xyz = getNorm(tc);
+ vec3 light_dir = (sun_up_factor == 1) ? sun_dir : moon_dir;
- float da = max(dot(norm.xyz, sun_dir.xyz), 0.0);
+ vec4 baseColor = texture(diffuseRect, tc);
+ vec4 spec = texture(specularRect, vary_fragcoord.xy); // NOTE: PBR linear Emissive
- vec4 diffuse = texture2DRect(diffuseRect, tc); // sRGB
- diffuse.rgb = srgb_to_linear(diffuse.rgb);
+#if defined(HAS_SUN_SHADOW) || defined(HAS_SSAO)
+ vec2 scol_ambocc = texture(lightMap, vary_fragcoord.xy).rg;
+#endif
- vec3 col;
+#if defined(HAS_SUN_SHADOW)
+ float scol = max(scol_ambocc.r, baseColor.a);
+#else
+ float scol = 1.0;
+#endif
+#if defined(HAS_SSAO)
+ float ambocc = scol_ambocc.g;
+#else
+ float ambocc = 1.0;
+#endif
+
+ vec3 color = vec3(0);
float bloom = 0.0;
- {
- vec3 camPos = (camPosLocal / 1000.0f) + vec3(0, 0, 6360.0f);
- vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
-
- vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten);
- float scol = max(scol_ambocc.r, diffuse.a);
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+ vec3 amblit_linear = amblit;
- float ambocc = scol_ambocc.g;
+ bool do_atmospherics = false;
+
+#ifndef WATER_FOG
+ // when above water, mask off atmospherics below water
+ if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0)
+ {
+ do_atmospherics = true;
+ }
+#else
+ do_atmospherics = true;
+#endif
- vec4 l1tap = vec4(1.0/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265), sqrt(3)/sqrt(4*3.14159265));
- vec4 l1r = texture2D(sh_input_r, vec2(0,0));
- vec4 l1g = texture2D(sh_input_g, vec2(0,0));
- vec4 l1b = texture2D(sh_input_b, vec2(0,0));
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
- vec3 indirect = vec3(dot(l1r, l1tap * vec4(1, norm.xyz)),
- dot(l1g, l1tap * vec4(1, norm.xyz)),
- dot(l1b, l1tap * vec4(1, norm.xyz)));
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
+ {
+ vec3 orm = texture(specularRect, tc).rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ float ao = orm.r;
+
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ // PBR IBL
+ float gloss = 1.0 - perceptualRoughness;
+
+ sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss, false, amblit_linear);
+
+ adjustIrradiance(irradiance, ambocc);
+
+ vec3 diffuseColor;
+ vec3 specularColor;
+ calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor);
+
+ vec3 v = -normalize(pos.xyz);
+ color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten);
+
+ if (do_atmospherics)
+ {
+ color = atmosFragLightingLinear(color, additive, atten);
+ }
+ }
+ else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS))
+ {
+ //should only be true of WL sky, just port over base color value
+ color = texture(emissiveRect, tc).rgb;
+ color = srgb_to_linear(color);
+ color *= sky_hdr_scale;
+ }
+ else
+ {
+ // legacy shaders are still writng sRGB to gbuffer
+ baseColor.rgb = srgb_to_linear(baseColor.rgb);
+
+ spec.rgb = srgb_to_linear(spec.rgb);
- indirect = clamp(indirect, vec3(0), vec3(1.0));
+ float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0);
- vec3 transmittance;
- vec3 sky_irradiance;
- vec3 sun_irradiance = GetSunAndSkyIrradiance(camPos, norm.xyz, sun_dir, sky_irradiance);
- vec3 inscatter = GetSkyLuminanceToPoint(camPos, (pos / 1000.f) + vec3(0, 0, 6360.0f), scol, sun_dir, transmittance);
+ vec3 irradiance = vec3(0);
+ vec3 glossenv = vec3(0);
+ vec3 legacyenv = vec3(0);
- vec3 radiance = scol * (sun_irradiance + sky_irradiance) + inscatter;
- vec3 atmo_color = ColorFromRadiance(radiance);
+ sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity, false, amblit_linear);
+
+ adjustIrradiance(irradiance, ambocc);
- col = atmo_color + indirect;
- col *= transmittance;
- col *= diffuse.rgb;
+ // apply lambertian IBL only (see pbrIbl)
+ color.rgb = irradiance;
- vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ vec3 sun_contrib = min(da, scol) * sunlit_linear;
+ color.rgb += sun_contrib;
+ color.rgb *= baseColor.rgb;
+
+ vec3 refnormpersp = reflect(pos.xyz, norm.xyz);
- if (spec.a > 0.0) // specular reflection
+ if (spec.a > 0.0)
{
- // the old infinite-sky shiny reflection
- //
- float sa = dot(refnormpersp, sun_dir.xyz);
- vec3 dumbshiny = scol * texture2D(lightFunc, vec2(sa, spec.a)).r * atmo_color;
-
- // add the two types of shiny together
- vec3 spec_contrib = dumbshiny * spec.rgb * 0.25;
- bloom = dot(spec_contrib, spec_contrib);
- col += spec_contrib;
+ vec3 lv = light_dir.xyz;
+ vec3 h, l, v = -normalize(pos.xyz);
+ float nh, nl, nv, vh, lightDist;
+ vec3 n = norm.xyz;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ if (nl > 0.0 && nh > 0.0)
+ {
+ float lit = min(nl*6.0, 1.0);
+
+ float sa = nh;
+ float fres = pow(1 - vh, 5) * 0.4+0.5;
+ float gtdenom = 2 * nh;
+ float gt = max(0,(min(gtdenom * nv / vh, gtdenom * nl / vh)));
+
+ scol *= fres*texture(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ color.rgb += lit*scol*sunlit_linear.rgb*spec.rgb;
+ }
+
+ // add radiance map
+ applyGlossEnv(color, glossenv, spec, pos.xyz, norm.xyz);
}
- col = mix(col, diffuse.rgb, diffuse.a);
-
+ color.rgb = mix(color.rgb, baseColor.rgb, baseColor.a);
+
if (envIntensity > 0.0)
- { //add environmentmap
- vec3 env_vec = env_mat * refnormpersp;
- vec3 sun_direction = (inv_modelview * vec4(sun_dir, 1.0)).xyz;
- vec3 radiance_sun = GetSkyLuminance(camPos, env_vec, 0.0f, sun_direction, transmittance);
- vec3 refcol = ColorFromRadiance(radiance_sun);
- col = mix(col.rgb, refcol, envIntensity);
+ { // add environment map
+ applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity);
}
-
- /*if (norm.w < 0.5)
+
+
+ if (do_atmospherics)
{
- col = scaleSoftClipFrag(col);
- }*/
-
- #ifdef WATER_FOG
- vec4 fogged = applyWaterFogView(pos,vec4(col, bloom));
- col = fogged.rgb;
- bloom = fogged.a;
- #endif
- }
+ color = atmosFragLightingLinear(color, additive, atten);
+ }
+ }
+
+
+
+ #ifdef WATER_FOG
+ vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom));
+ color = fogged.rgb;
+ #endif
- //output linear since gamma correction happens down stream
- frag_color.rgb = col;
- frag_color.a = bloom;
+ frag_color.rgb = max(color.rgb, vec3(0)); //output linear since local lights will be added to this shader's results
+ frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
deleted file mode 100644
index 9d872b8df8..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl
+++ /dev/null
@@ -1,38 +0,0 @@
-/**
- * @file class3/deferred/softenLightV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-ATTRIBUTE vec3 position;
-
-VARYING vec2 vary_fragcoord;
-
-uniform mat4 modelview_projection_matrix;
-uniform vec2 screen_res;
-
-void main()
-{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
- vary_fragcoord = (pos.xy*0.5+0.5)*screen_res;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
index 56b0f4e5ce..d31b37fb60 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl
@@ -1,9 +1,9 @@
/**
- * @file spotLightF.glsl
+ * @file class3\deferred\spotLightF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,25 +23,18 @@
* $/LicenseInfo$
*/
-#extension GL_ARB_texture_rectangle : enable
-#extension GL_ARB_shader_texture_lod : enable
-
/*[EXTRA_CODE_HERE]*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-uniform sampler2DRect diffuseRect;
-uniform sampler2DRect specularRect;
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
+uniform sampler2D diffuseRect;
+uniform sampler2D specularRect;
+uniform sampler2D depthMap;
+uniform sampler2D normalMap;
+uniform sampler2D emissiveRect; // PBR linear packed Occlusion, Roughness, Metal. See: pbropaqueF.glsl
uniform samplerCube environmentMap;
-uniform sampler2DRect lightMap;
-uniform sampler2D noiseMap;
-uniform sampler2D projectionMap;
+uniform sampler2D lightMap;
+uniform sampler2D projectionMap; // rgba
uniform sampler2D lightFunc;
uniform mat4 proj_mat; //screen space to light space
@@ -61,227 +54,214 @@ uniform float sun_wash;
uniform int proj_shadow_idx;
uniform float shadow_fade;
+// Light params
+#if defined(MULTI_SPOTLIGHT)
+uniform vec3 center;
+#else
+in vec3 trans_center;
+#endif
uniform float size;
uniform vec3 color;
uniform float falloff;
-VARYING vec3 trans_center;
-VARYING vec4 vary_fragcoord;
+in vec4 vary_fragcoord;
uniform vec2 screen_res;
uniform mat4 inv_proj;
-vec3 getNorm(vec2 pos_screen);
+void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist);
+float calcLegacyDistanceAttenuation(float distance, float falloff);
+bool clipProjectedLightVars(vec3 center, vec3 pos, out float dist, out float l_dist, out vec3 lv, out vec4 proj_tc );
+vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensity);
+vec3 getProjectedLightAmbiance(float amb_da, float attenuation, float lit, float nl, float noise, vec2 projected_uv);
+vec3 getProjectedLightDiffuseColor(float light_distance, vec2 projected_uv );
+vec2 getScreenCoord(vec4 clip);
+vec3 srgb_to_linear(vec3 cs);
+vec4 texture2DLodSpecular(vec2 tc, float lod);
-vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- d *= min(1, d * (proj_lod - lod));
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+vec4 getPosition(vec2 pos_screen);
-vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
-
- float det = min(lod/(proj_lod*0.5), 1.0);
-
- float d = min(dist.x, dist.y);
-
- float edge = 0.25*det;
-
- ret *= clamp(d/edge, 0.0, 1.0);
-
- return ret;
-}
+const float M_PI = 3.14159265;
-vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
-{
- vec4 ret = texture2DLod(projectionMap, tc, lod);
-
- vec2 dist = tc-vec2(0.5);
-
- float d = dot(dist,dist);
-
- ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
-
- return ret;
-}
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+void main()
+{
+ vec3 final_color = vec3(0,0,0);
+ vec2 tc = getScreenCoord(vary_fragcoord);
+ vec3 pos = getPosition(tc).xyz;
-vec4 getPosition(vec2 pos_screen);
+ vec3 lv;
+ vec4 proj_tc;
+ float dist, l_dist;
+ vec3 c;
+#if defined(MULTI_SPOTLIGHT)
+ c = center;
+#else
+ c = trans_center;
+#endif
-void main()
-{
- vec4 frag = vary_fragcoord;
- frag.xyz /= frag.w;
- frag.xyz = frag.xyz*0.5+0.5;
- frag.xy *= screen_res;
-
- vec3 pos = getPosition(frag.xy).xyz;
- vec3 lv = trans_center.xyz-pos.xyz;
- float dist = length(lv);
- dist /= size;
- if (dist > 1.0)
+ if (clipProjectedLightVars(c, pos, dist, l_dist, lv, proj_tc))
{
discard;
}
-
+
float shadow = 1.0;
if (proj_shadow_idx >= 0)
{
- vec4 shd = texture2DRect(lightMap, frag.xy);
- shadow = (proj_shadow_idx == 0) ? shd.b : shd.a;
+ vec4 shd = texture(lightMap, tc);
+ shadow = (proj_shadow_idx==0)?shd.b:shd.a;
shadow += shadow_fade;
- shadow = clamp(shadow, 0.0, 1.0);
+ shadow = clamp(shadow, 0.0, 1.0);
}
-
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
- float envIntensity = norm.z;
- norm = getNorm(frag.xy);
-
- norm = normalize(norm);
- float l_dist = -dot(lv, proj_n);
-
- vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0));
- if (proj_tc.z < 0.0)
- {
- discard;
- }
-
- proj_tc.xyz /= proj_tc.w;
-
- float fa = (falloff*0.5) + 1.0;
- float dist_atten = min(1.0 - (dist - 1.0 * (1.0 - fa)) / fa, 1.0);
- dist_atten *= dist_atten;
- dist_atten *= 2.0;
+ float envIntensity;
+ vec3 n;
+ vec4 norm = getNormalEnvIntensityFlags(tc, n, envIntensity);
+
+ float dist_atten = calcLegacyDistanceAttenuation(dist, falloff);
if (dist_atten <= 0.0)
{
discard;
}
-
+
lv = proj_origin-pos.xyz;
- lv = normalize(lv);
- float da = dot(norm, lv);
-
- vec3 col = vec3(0,0,0);
-
- vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
-
- vec4 spec = texture2DRect(specularRect, frag.xy);
+ vec3 h, l, v = -normalize(pos);
+ float nh, nl, nv, vh, lightDist;
+ calcHalfVectors(lv, n, v, h, l, nh, nl, nv, vh, lightDist);
+
+ vec3 diffuse = texture(diffuseRect, tc).rgb;
+ vec4 spec = texture(specularRect, tc);
+ vec3 dlit = vec3(0, 0, 0);
+ vec3 slit = vec3(0, 0, 0);
- vec3 dlit = vec3(0, 0, 0);
+ vec3 amb_rgb = vec3(0);
- float noise = texture2D(noiseMap, frag.xy/128.0).b;
- if (proj_tc.z > 0.0 &&
- proj_tc.x < 1.0 &&
- proj_tc.y < 1.0 &&
- proj_tc.x > 0.0 &&
- proj_tc.y > 0.0)
+ if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR))
{
- float amb_da = proj_ambiance;
- float lit = 0.0;
+ vec3 colorEmissive = texture(emissiveRect, tc).rgb;
+ vec3 orm = spec.rgb;
+ float perceptualRoughness = orm.g;
+ float metallic = orm.b;
+ vec3 f0 = vec3(0.04);
+ vec3 baseColor = diffuse.rgb;
- if (da > 0.0)
+ vec3 diffuseColor = baseColor.rgb*(vec3(1.0)-f0);
+ diffuseColor *= 1.0 - metallic;
+
+ vec3 specularColor = mix(f0, baseColor.rgb, metallic);
+
+ // We need this additional test inside a light's frustum since a spotlight's ambiance can be applied
+ if (proj_tc.x > 0.0 && proj_tc.x < 1.0
+ && proj_tc.y > 0.0 && proj_tc.y < 1.0)
{
- lit = da * dist_atten * noise;
+ float lit = 0.0;
+ float amb_da = 0.0;
- float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
-
- vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
-
- dlit = color.rgb * plcol.rgb * plcol.a;
-
- col = dlit*lit*diff_tex*shadow;
- amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance;
- }
-
- //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
-
- amb_da += (da*da*0.5+0.5)*(1.0-shadow)*proj_ambiance;
+ lv = normalize(lv);
+
+ if (nl > 0.0)
+ {
+ amb_da += (nl*0.5 + 0.5) * proj_ambiance;
- amb_da *= dist_atten * noise;
-
- amb_da = min(amb_da, 1.0-lit);
-
- col += amb_da*color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
- }
-
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
- if (spec.a > 0.0)
+ vec3 intensity = dist_atten * dlit * 3.25 * shadow; // Legacy attenuation, magic number to balance with legacy materials
+ final_color += intensity*pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, lv);
+ }
+
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy ) * 3.25; //magic number to balance with legacy ambiance
+ final_color += amb_rgb * pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, n.xyz, v, -lv);
+ }
+ }
+ else
{
- dlit *= min(da*6.0, 1.0) * dist_atten;
- vec3 npos = -normalize(pos);
-
- //vec3 ref = dot(pos+lv, norm);
- vec3 h = normalize(lv+npos);
- float nh = dot(norm, h);
- float nv = dot(norm, npos);
- float vh = dot(npos, h);
- float sa = nh;
- float fres = pow(1 - dot(h, npos), 5)*0.4+0.5;
-
- float gtdenom = 2 * nh;
- float gt = max(0, min(gtdenom * nv / vh, gtdenom * da / vh));
-
- if (nh > 0.0)
+ diffuse = srgb_to_linear(diffuse);
+ spec.rgb = srgb_to_linear(spec.rgb);
+
+ if (proj_tc.z > 0.0 &&
+ proj_tc.x < 1.0 &&
+ proj_tc.y < 1.0 &&
+ proj_tc.x > 0.0 &&
+ proj_tc.y > 0.0)
{
- float scol = fres*texture2D(lightFunc, vec2(nh, spec.a)).r*gt/(nh*da);
- col += dlit*scol*spec.rgb*shadow;
+ float amb_da = 0;
+ float lit = 0.0;
+
+ if (nl > 0.0)
+ {
+ lit = nl * dist_atten;
+
+ dlit = getProjectedLightDiffuseColor( l_dist, proj_tc.xy );
+
+ final_color = dlit*lit*diffuse*shadow;
+
+ // unshadowed for consistency between forward and deferred?
+ amb_da += (nl*0.5+0.5) /* * (1.0-shadow) */ * proj_ambiance;
+ }
+
+ amb_rgb = getProjectedLightAmbiance( amb_da, dist_atten, lit, nl, 1.0, proj_tc.xy );
+ final_color += diffuse.rgb * amb_rgb * max(dot(-normalize(lv), n), 0.0);
}
- }
+ if (spec.a > 0.0)
+ {
+ dlit *= min(nl*6.0, 1.0) * dist_atten;
- if (envIntensity > 0.0)
- {
- vec3 ref = reflect(normalize(pos), norm);
+ float fres = pow(1 - vh, 5)*0.4+0.5;
+
+ float gtdenom = 2 * nh;
+ float gt = max(0, min(gtdenom * nv / vh, gtdenom * nl / vh));
+
+ if (nh > 0.0)
+ {
+ float scol = fres*texture(lightFunc, vec2(nh, spec.a)).r*gt/(nh*nl);
+ vec3 speccol = dlit*scol*spec.rgb*shadow;
+ speccol = clamp(speccol, vec3(0), vec3(1));
+ final_color += speccol;
+ }
+ }
+
+ if (envIntensity > 0.0)
+ {
+ vec3 ref = reflect(normalize(pos), n);
- //project from point pos in direction ref to plane proj_p, proj_n
- vec3 pdelta = proj_p-pos;
- float ds = dot(ref, proj_n);
+ //project from point pos in direction ref to plane proj_p, proj_n
+ vec3 pdelta = proj_p-pos;
+ float ds = dot(ref, proj_n);
- if (ds < 0.0)
- {
- vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
+ if (ds < 0.0)
+ {
+ vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
- if (stc.z > 0.0)
- {
- stc /= stc.w;
-
- if (stc.x < 1.0 &&
- stc.y < 1.0 &&
- stc.x > 0.0 &&
- stc.y > 0.0)
+ if (stc.z > 0.0)
{
- col += color.rgb * texture2DLodSpecular(projectionMap, stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ stc /= stc.w;
+
+ if (stc.x < 1.0 &&
+ stc.y < 1.0 &&
+ stc.x > 0.0 &&
+ stc.y > 0.0)
+ {
+ final_color += color.rgb * texture2DLodSpecular(stc.xy, (1 - spec.a) * (proj_lod * 0.6)).rgb * shadow * envIntensity;
+ }
}
}
}
}
-
+
//not sure why, but this line prevents MATBUG-194
- col = max(col, vec3(0.0));
+ final_color = max(final_color, vec3(0.0));
- frag_color.rgb = col;
+ //output linear
+ frag_color.rgb = final_color;
frag_color.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
deleted file mode 100644
index 112b498c90..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightF.glsl
+++ /dev/null
@@ -1,57 +0,0 @@
-/**
- * @file class3\deferred\sunLightF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2, shadows, no SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.g = 1.0f;
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
deleted file mode 100644
index 342a2ff3ed..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/sunLightSSAOF.glsl
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * @file class3\deferred\sunLightSSAOF.glsl
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-//class 2 -- shadows and SSAO
-
-// Inputs
-VARYING vec2 vary_fragcoord;
-
-uniform vec3 sun_dir;
-
-vec4 getPosition(vec2 pos_screen);
-vec3 getNorm(vec2 pos_screen);
-
-float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
-float sampleSpotShadow(vec3 pos, vec3 norm, int index, vec2 pos_screen);
-
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm, vec2 pos_screen);
-
-void main()
-{
- vec2 pos_screen = vary_fragcoord.xy;
- vec4 pos = getPosition(pos_screen);
- vec3 norm = getNorm(pos_screen);
-
- frag_color.r = sampleDirectionalShadow(pos.xyz, norm, pos_screen);
- frag_color.b = calcAmbientOcclusion(pos, norm, pos_screen);
- frag_color.b = sampleSpotShadow(pos.xyz, norm, 0, pos_screen);
- frag_color.a = sampleSpotShadow(pos.xyz, norm, 1, pos_screen);
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
deleted file mode 100644
index 15e769ac10..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/treeShadowV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file treeShadowV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 texture_matrix0;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-ATTRIBUTE vec2 texcoord0;
-
-VARYING vec4 pos;
-VARYING vec2 vary_texcoord0;
-
-void main()
-{
- //transform vertex
- pos = modelview_projection_matrix*vec4(position.xyz, 1.0);
-
- gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w);
-
- vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
deleted file mode 100644
index 540226e672..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/underWaterF.glsl
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * @file underWaterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-uniform sampler2D screenDepth;
-
-uniform vec4 fogCol;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform vec2 fbScale;
-uniform float refScale;
-uniform float znear;
-uniform float zfar;
-uniform float kd;
-uniform vec4 waterPlane;
-uniform vec3 eyeVec;
-uniform vec4 waterFogColor;
-uniform float waterFogDensity;
-uniform float waterFogKS;
-uniform vec2 screenRes;
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-vec2 encode_normal(vec3 n);
-
-vec4 applyWaterFog(vec4 color, vec3 viewVec)
-{
- //normalize view vector
- vec3 view = normalize(viewVec);
- float es = -view.z;
-
- //find intersection point with water plane and eye vector
-
- //get eye depth
- float e0 = max(-waterPlane.w, 0.0);
-
- //get object depth
- float depth = length(viewVec);
-
- //get "thickness" of water
- float l = max(depth, 0.1);
-
- float kd = waterFogDensity;
- float ks = waterFogKS;
- vec4 kc = waterFogColor;
-
- float F = 0.98;
-
- float t1 = -kd * pow(F, ks * e0);
- float t2 = kd + ks * es;
- float t3 = pow(F, t2*l) - 1.0;
-
- float L = min(t1/t2*t3, 1.0);
-
- float D = pow(0.98, l*kd);
- return color * D + kc * L;
-}
-
-void main()
-{
- vec4 color;
-
- //get detail normals
- vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
- vec3 wavef = normalize(wave1+wave2+wave3);
-
- //figure out distortion vector (ripply)
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
- distort = distort+wavef.xy*refScale;
-
- vec4 fb = texture2D(screenTex, distort);
-
- frag_data[0] = vec4(fb.rgb, 1.0); // diffuse
- frag_data[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
- frag_data[2] = vec4(encode_normal(wavef), 0.0, 0.0); // normalxyz, displace
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
deleted file mode 100644
index c65cf48c67..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl
+++ /dev/null
@@ -1,174 +0,0 @@
-/**
- * @file waterF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#extension GL_ARB_texture_rectangle : enable
-
-/*[EXTRA_CODE_HERE]*/
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
-#else
-#define frag_data gl_FragData
-#endif
-
-uniform sampler2D bumpMap;
-uniform sampler2D bumpMap2;
-uniform float blend_factor;
-uniform sampler2D screenTex;
-uniform sampler2D refTex;
-
-uniform float sunAngle;
-uniform float sunAngle2;
-uniform vec3 lightDir;
-uniform vec3 specular;
-uniform float lightExp;
-uniform float refScale;
-uniform float kd;
-uniform vec2 screenRes;
-uniform vec3 normScale;
-uniform float fresnelScale;
-uniform float fresnelOffset;
-uniform float blurMultiplier;
-uniform vec2 screen_res;
-uniform mat4 norm_mat; //region space to screen space
-
-//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-VARYING vec4 vary_position;
-
-vec3 scaleSoftClip(vec3 c);
-vec2 encode_normal(vec3 n);
-
-vec3 BlendNormal(vec3 bump1, vec3 bump2)
-{
- //vec3 normal = bump1.xyz * vec3( 2.0, 2.0, 2.0) - vec3(1.0, 1.0, 0.0);
- //vec3 normal2 = bump2.xyz * vec3(-2.0, -2.0, 2.0) + vec3(1.0, 1.0, -1.0);
- //vec3 n = normalize(normal * dot(normal, normal2) - (normal2 * normal.z));
- vec3 n = normalize(mix(bump1, bump2, blend_factor));
- return n;
-}
-
-void main()
-{
- vec4 color;
- float dist = length(view.xy);
-
- //normalize view vector
- vec3 viewVec = normalize(view.xyz);
-
- //get wave normals
- vec3 wave1_a = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_a = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_a = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0;
-
-
- vec3 wave1_b = texture2D(bumpMap2, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
- vec3 wave2_b = texture2D(bumpMap2, littleWave.xy).xyz*2.0-1.0;
- vec3 wave3_b = texture2D(bumpMap2, littleWave.zw).xyz*2.0-1.0;
-
- vec3 wave1 = BlendNormal(wave1_a, wave1_b);
- vec3 wave2 = BlendNormal(wave2_a, wave2_b);
- vec3 wave3 = BlendNormal(wave3_a, wave3_b);
-
- //get base fresnel components
-
- vec3 df = vec3(
- dot(viewVec, wave1),
- dot(viewVec, (wave2 + wave3) * 0.5),
- dot(viewVec, wave3)
- ) * fresnelScale + fresnelOffset;
- df *= df;
-
- vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
-
- float dist2 = dist;
- dist = max(dist, 5.0);
-
- float dmod = sqrt(dist);
-
- vec2 dmod_scale = vec2(dmod*dmod, dmod);
-
- //get reflected color
- vec2 refdistort1 = wave1.xy*normScale.x;
- vec2 refvec1 = distort+refdistort1/dmod_scale;
- vec4 refcol1 = texture2D(refTex, refvec1);
-
- vec2 refdistort2 = wave2.xy*normScale.y;
- vec2 refvec2 = distort+refdistort2/dmod_scale;
- vec4 refcol2 = texture2D(refTex, refvec2);
-
- vec2 refdistort3 = wave3.xy*normScale.z;
- vec2 refvec3 = distort+refdistort3/dmod_scale;
- vec4 refcol3 = texture2D(refTex, refvec3);
-
- vec4 refcol = refcol1 + refcol2 + refcol3;
- float df1 = df.x + df.y + df.z;
- refcol *= df1 * 0.333;
-
- vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
- wavef.z *= max(-viewVec.z, 0.1);
- wavef = normalize(wavef);
-
- float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset;
-
- vec2 refdistort4 = wavef.xy*0.125;
- refdistort4.y -= abs(refdistort4.y);
- vec2 refvec4 = distort+refdistort4/dmod;
- float dweight = min(dist2*blurMultiplier, 1.0);
- vec4 baseCol = texture2D(refTex, refvec4);
-
- refcol = mix(baseCol*df2, refcol, dweight);
-
- //get specular component
- float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0);
-
- //harden specular
- spec = pow(spec, 128.0);
-
- //figure out distortion vector (ripply)
- vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0);
-
- vec4 fb = texture2D(screenTex, distort2);
-
- //mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
- color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
-
- color.rgb *= 2.0f;
- color.rgb = scaleSoftClip(color.rgb);
-
- vec4 pos = vary_position;
-
- color.rgb += spec * specular;
- color.a = spec * sunAngle2;
-
- vec3 screenspacewavef = normalize((norm_mat*vec4(wavef, 1.0)).xyz);
-
- frag_data[0] = vec4(color.rgb, color); // diffuse
- frag_data[1] = vec4(spec * specular, spec); // speccolor, spec
- frag_data[2] = vec4(encode_normal(wavef.xyz), 0.05, 0);// normalxy, 0, 0
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl b/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
deleted file mode 100644
index 02000d90ca..0000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/waterV.glsl
+++ /dev/null
@@ -1,95 +0,0 @@
-/**
- * @file waterV.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_matrix;
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-
-uniform vec2 d1;
-uniform vec2 d2;
-uniform float time;
-uniform vec3 eyeVec;
-uniform float waterHeight;
-
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
-
-VARYING vec4 vary_position;
-
-float wave(vec2 v, float t, float f, vec2 d, float s)
-{
- return (dot(d, v)*f + t*s)*f;
-}
-
-void main()
-{
- //transform vertex
- vec4 pos = vec4(position.xyz, 1.0);
- mat4 modelViewProj = modelview_projection_matrix;
-
- vec4 oPosition;
-
- //get view vector
- vec3 oEyeVec;
- oEyeVec.xyz = pos.xyz-eyeVec;
-
- float d = length(oEyeVec.xy);
- float ld = min(d, 2560.0);
-
- pos.xy = eyeVec.xy + oEyeVec.xy/d*ld;
- view.xyz = oEyeVec;
-
- d = clamp(ld/1536.0-0.5, 0.0, 1.0);
- d *= d;
-
- oPosition = vec4(position, 1.0);
- oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d);
- vary_position = modelview_matrix * oPosition;
- oPosition = modelViewProj * oPosition;
-
- refCoord.xyz = oPosition.xyz + vec3(0,0,0.2);
-
- //get wave position parameter (create sweeping horizontal waves)
- vec3 v = pos.xyz;
- v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0;
-
- //push position for further horizon effect.
- pos.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z);
- pos.w = 1.0;
- pos = modelview_matrix*pos;
-
- //pass wave parameters to pixel shader
- vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055;
- //get two normal map (detail map) texture coordinates
- littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13;
- littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1;
- view.w = bigWave.y;
- refCoord.w = bigWave.x;
-
- gl_Position = oPosition;
-}
diff --git a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
index 8c8bd6d0d5..e99ad5b474 100644
--- a/indra/newview/app_settings/shaders/class1/environment/underWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class3/environment/underWaterF.glsl
@@ -1,5 +1,5 @@
/**
- * @file class1\environment\underWaterF.glsl
+ * @file class3\environment\underWaterF.glsl
*
* $LicenseInfo:firstyear=2007&license=viewerlgpl$
* Second Life Viewer Source Code
@@ -23,17 +23,15 @@
* $/LicenseInfo$
*/
-#ifdef DEFINE_GL_FRAGCOLOR
out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
uniform sampler2D diffuseMap;
-uniform sampler2D bumpMap;
+uniform sampler2D bumpMap;
+
+#ifdef TRANSPARENT_WATER
uniform sampler2D screenTex;
-uniform sampler2D refTex;
uniform sampler2D screenDepth;
+#endif
uniform vec4 fogCol;
uniform vec3 lightDir;
@@ -47,31 +45,37 @@ uniform float kd;
uniform vec4 waterPlane;
uniform vec3 eyeVec;
uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
uniform float waterFogKS;
uniform vec2 screenRes;
//bigWave is (refCoord.w, view.w);
-VARYING vec4 refCoord;
-VARYING vec4 littleWave;
-VARYING vec4 view;
+in vec4 refCoord;
+in vec4 littleWave;
+in vec4 view;
+in vec3 vary_position;
-vec4 applyWaterFogView(vec3 pos, vec4 color);
+vec4 applyWaterFogViewLinearNoClip(vec3 pos, vec4 color, vec3 sunlit);
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;
+
+ //get detail normals
+ vec3 wave1 = texture(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0;
+ vec3 wave2 = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3 = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
vec3 wavef = normalize(wave1+wave2+wave3);
//figure out distortion vector (ripply)
vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
distort = distort+wavef.xy*refScale;
-
- vec4 fb = texture2D(screenTex, distort);
-
- frag_color = applyWaterFogView(view.xyz, fb);
+
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture(screenTex, distort);
+#else
+ vec4 fb = vec4(waterFogColorLinear, 0.0);
+#endif
+
+ frag_color = max(applyWaterFogViewLinearNoClip(vary_position, fb, vec3(1)), vec4(0));
}
diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
new file mode 100644
index 0000000000..ddade462be
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl
@@ -0,0 +1,291 @@
+/**
+ * @file waterF.glsl
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+// class3/environment/waterF.glsl
+
+out vec4 frag_color;
+
+#ifdef HAS_SUN_SHADOW
+float sampleDirectionalShadow(vec3 pos, vec3 norm, vec2 pos_screen);
+#endif
+
+vec3 scaleSoftClipFragLinear(vec3 l);
+vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten);
+void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive);
+vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit);
+
+// PBR interface
+vec2 BRDF(float NoV, float roughness);
+
+void calcDiffuseSpecular(vec3 baseColor, float metallic, inout vec3 diffuseColor, inout vec3 specularColor);
+
+vec3 pbrIbl(vec3 diffuseColor,
+ vec3 specularColor,
+ vec3 radiance, // radiance map sample
+ vec3 irradiance, // irradiance map sample
+ float ao, // ambient occlusion factor
+ float nv, // normal dot view vector
+ float perceptualRoughness);
+
+vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor,
+ float perceptualRoughness,
+ float metallic,
+ vec3 n, // normal
+ vec3 v, // surface point to camera
+ vec3 l); //surface point to light
+
+vec3 pbrBaseLight(vec3 diffuseColor,
+ vec3 specularColor,
+ float metallic,
+ vec3 pos,
+ vec3 norm,
+ float perceptualRoughness,
+ vec3 light_dir,
+ vec3 sunlit,
+ float scol,
+ vec3 radiance,
+ vec3 irradiance,
+ vec3 colorEmissive,
+ float ao,
+ vec3 additive,
+ vec3 atten);
+
+uniform sampler2D bumpMap;
+uniform sampler2D bumpMap2;
+uniform float blend_factor;
+#ifdef TRANSPARENT_WATER
+uniform sampler2D screenTex;
+uniform sampler2D screenDepth;
+#endif
+
+uniform sampler2D refTex;
+
+uniform float sunAngle;
+uniform float sunAngle2;
+uniform vec3 lightDir;
+uniform vec3 specular;
+uniform float lightExp;
+uniform float refScale;
+uniform float kd;
+uniform vec2 screenRes;
+uniform vec3 normScale;
+uniform float fresnelScale;
+uniform float fresnelOffset;
+uniform float blurMultiplier;
+uniform vec4 waterFogColor;
+uniform vec3 waterFogColorLinear;
+
+
+//bigWave is (refCoord.w, view.w);
+in vec4 refCoord;
+in vec4 littleWave;
+in vec4 view;
+in vec3 vary_position;
+in vec3 vary_normal;
+in vec3 vary_tangent;
+in vec3 vary_light_dir;
+
+vec3 BlendNormal(vec3 bump1, vec3 bump2)
+{
+ vec3 n = mix(bump1, bump2, blend_factor);
+ return n;
+}
+
+vec3 srgb_to_linear(vec3 col);
+vec3 linear_to_srgb(vec3 col);
+
+vec3 vN, vT, vB;
+
+vec3 transform_normal(vec3 vNt)
+{
+ return normalize(vNt.x * vT + vNt.y * vB + vNt.z * vN);
+}
+
+void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv,
+ vec2 tc, vec3 pos, vec3 norm, float glossiness, vec3 amblit_linear);
+
+vec3 getPositionWithNDC(vec3 ndc);
+
+void main()
+{
+ vN = vary_normal;
+ vT = vary_tangent;
+ vB = cross(vN, vT);
+
+ vec3 pos = vary_position.xyz;
+
+ float dist = length(pos.xyz);
+
+ //normalize view vector
+ vec3 viewVec = normalize(pos.xyz);
+
+ //get wave normals
+ vec2 bigwave = vec2(refCoord.w, view.w);
+ vec3 wave1_a = texture(bumpMap, bigwave, -2 ).xyz*2.0-1.0;
+ vec3 wave2_a = texture(bumpMap, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_a = texture(bumpMap, littleWave.zw).xyz*2.0-1.0;
+
+ vec3 wave1_b = texture(bumpMap2, bigwave ).xyz*2.0-1.0;
+ vec3 wave2_b = texture(bumpMap2, littleWave.xy).xyz*2.0-1.0;
+ vec3 wave3_b = texture(bumpMap2, littleWave.zw).xyz*2.0-1.0;
+
+ //wave1_a = wave2_a = wave3_a = wave1_b = wave2_b = wave3_b = vec3(0,0,1);
+
+ vec3 wave1 = BlendNormal(wave1_a, wave1_b);
+ vec3 wave2 = BlendNormal(wave2_a, wave2_b);
+ vec3 wave3 = BlendNormal(wave3_a, wave3_b);
+
+ vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5;
+
+ //wave1 = transform_normal(wave1);
+ //wave2 = transform_normal(wave2);
+ //wave3 = transform_normal(wave3);
+
+ vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5;
+
+ vec3 waver = wavef*3;
+
+ vec3 up = transform_normal(vec3(0,0,1));
+ float vdu = -dot(viewVec, up)*2;
+
+ vec3 wave_ibl = wavef;
+ wave_ibl.z *= 2.0;
+ wave_ibl = transform_normal(normalize(wave_ibl));
+
+ vec3 norm = transform_normal(normalize(wavef));
+
+ vdu = clamp(vdu, 0, 1);
+ wavef.z *= max(vdu*vdu*vdu, 0.1);
+
+ wavef = normalize(wavef);
+
+ //wavef = vec3(0, 0, 1);
+ wavef = transform_normal(wavef);
+
+ float dist2 = dist;
+ dist = max(dist, 5.0);
+
+ float dmod = sqrt(dist);
+
+ //figure out distortion vector (ripply)
+ vec2 distort2 = distort + waver.xy * refScale / max(dmod, 1.0);
+
+ distort2 = clamp(distort2, vec2(0), vec2(0.999));
+
+ vec3 sunlit;
+ vec3 amblit;
+ vec3 additive;
+ vec3 atten;
+
+ float shadow = 1.0f;
+
+#ifdef HAS_SUN_SHADOW
+ shadow = sampleDirectionalShadow(pos.xyz, norm.xyz, distort);
+#endif
+
+ calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten);
+
+ vec3 sunlit_linear = srgb_to_linear(sunlit);
+
+#ifdef TRANSPARENT_WATER
+ vec4 fb = texture(screenTex, distort2);
+ float depth = texture(screenDepth, distort2).r;
+ vec3 refPos = getPositionWithNDC(vec3(distort2*2.0-vec2(1.0), depth*2.0-1.0));
+
+ if (refPos.z > pos.z-0.05)
+ {
+ //we sampled an above water sample, don't distort
+ distort2 = distort;
+ fb = texture(screenTex, distort2);
+ depth = texture(screenDepth, distort2).r;
+ refPos = getPositionWithNDC(vec3(distort2 * 2.0 - vec2(1.0), depth * 2.0 - 1.0));
+ }
+
+ fb = applyWaterFogViewLinear(refPos, fb, sunlit);
+#else
+ vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear);
+#endif
+
+ // fudge sample on other side of water to be a tad darker
+ fb.rgb *= 0.75;
+
+ float metallic = 0.0;
+ float perceptualRoughness = 0.05;
+ float gloss = 1.0 - perceptualRoughness;
+
+ vec3 irradiance = vec3(0);
+ vec3 radiance = vec3(0);
+ sampleReflectionProbesWater(irradiance, radiance, distort2, pos.xyz, wave_ibl.xyz, gloss, amblit);
+
+ irradiance = vec3(0);
+
+ vec3 diffuseColor = vec3(0);
+ vec3 specularColor = vec3(0);
+ calcDiffuseSpecular(vec3(1), metallic, diffuseColor, specularColor);
+
+ vec3 v = -normalize(pos.xyz);
+
+ vec3 colorEmissive = vec3(0);
+ float ao = 1.0;
+ vec3 light_dir = transform_normal(lightDir);
+
+ perceptualRoughness = 0.0;
+ metallic = 1.0;
+
+ float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0);
+
+ vec3 punctual = pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir));
+
+ vec3 color = punctual * sunlit_linear * 2.75 * shadow;
+
+ vec3 ibl = pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0);
+
+ color += ibl;
+
+ float nv = clamp(abs(dot(norm.xyz, v)), 0.001, 1.0);
+ vec2 brdf = BRDF(clamp(nv, 0, 1), 1.0);
+ float f = 1.0-brdf.y; //1.0 - (brdf.x+brdf.y);
+ f *= 0.9;
+ f *= f;
+
+ // incoming scale is [0, 1] with 0.5 being default
+ // shift to 0.5 to 1.5
+ f *= (fresnelScale - 0.5)+1.0;
+
+ // incoming offset is [0, 1] with 0.5 being default
+ // shift from -1 to 1
+ f += (fresnelOffset - 0.5) * 2.0;
+
+ f = clamp(f, 0, 1);
+
+ color = ((1.0 - f) * color) + fb.rgb;
+
+ color = atmosFragLightingLinear(color, additive, atten);
+
+ float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05);
+
+ frag_color = max(vec4(color, spec), vec4(0));
+}
+
diff --git a/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
index 30ad493331..77bbbabfae 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/lightV.glsl
@@ -23,21 +23,13 @@
* $/LicenseInfo$
*/
-
-
-// All lights, no specular highlights
-vec3 atmosAmbient();
+// used for preview renders only
vec4 sumLights(vec3 pos, vec3 norm, vec4 color);
-float getAmbientClamp();
vec4 calcLighting(vec3 pos, vec3 norm, vec4 color)
{
vec4 c = sumLights(pos, norm, color);
-#if !defined(AMBIENT_KILL)
- c.rgb += atmosAmbient() * color.rgb * getAmbientClamp();
-#endif
-
return c;
}
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
deleted file mode 100644
index 4b663dd5b2..0000000000
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- * @file class3\lighting\sumLightsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-
-float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float fa, float is_pointlight);
-
-vec3 atmosAffectDirectionalLight(float lightIntensity);
-vec3 scaleDownLight(vec3 light);
-
-uniform vec4 light_position[8];
-uniform vec3 light_direction[8];
-uniform vec4 light_attenuation[8];
-uniform vec3 light_diffuse[8];
-
-vec4 sumLights(vec3 pos, vec3 norm, vec4 color)
-{
- 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)
-
- // Collect normal lights
- col.rgb += light_diffuse[2].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[2], light_direction[2], light_attenuation[2].x, light_attenuation[2].y, light_attenuation[2].z);
- col.rgb += light_diffuse[3].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[3], light_direction[3], light_attenuation[3].x, light_attenuation[3].y, light_attenuation[3].z);
- col.rgb += light_diffuse[4].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[4], light_direction[4], light_attenuation[4].x, light_attenuation[4].y, light_attenuation[4].z);
- col.rgb += light_diffuse[5].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[5], light_direction[5], light_attenuation[5].x, light_attenuation[5].y, light_attenuation[5].z);
- col.rgb += light_diffuse[6].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[6], light_direction[6], light_attenuation[6].x, light_attenuation[6].y, light_attenuation[6].z);
- col.rgb += light_diffuse[7].rgb*calcPointLightOrSpotLight(pos.xyz, norm, light_position[7], light_direction[7], light_attenuation[7].x, light_attenuation[7].y, light_attenuation[7].z);
- col.rgb += light_diffuse[1].rgb*calcDirectionalLight(norm, light_position[1].xyz);
- col.rgb = scaleDownLight(col.rgb);
-
-#if defined(LOCAL_LIGHT_KILL)
- col.rgb = vec3(0);
-#endif
-
- // Add windlight lights
-#if !defined(SUNLIGHT_KILL)
- col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, light_position[0].xyz));
-#endif
-
- col.rgb = min(col.rgb*color.rgb, 1.0);
-
- return col;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
deleted file mode 100644
index c6ea3ec9d4..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoF.glsl
+++ /dev/null
@@ -1,73 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoF.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_color;
-#else
-#define frag_color gl_FragColor
-#endif
-
-in vec3 view_dir;
-
-uniform vec3 cameraPosLocal;
-uniform vec3 sun_dir;
-uniform float sun_size;
-
-uniform sampler2D transmittance_texture;
-uniform sampler3D scattering_texture;
-uniform sampler3D mie_scattering_texture;
-uniform sampler2D irradiance_texture;
-
-vec3 GetSolarLuminance();
-vec3 GetSkyLuminance(vec3 camPos, vec3 view_dir, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 sun_dir, out vec3 transmittance);
-vec3 GetSunAndSkyIlluminance(vec3 pos, vec3 norm, vec3 sun_dir, out vec3 sky_irradiance);
-
-void main()
-{
- vec3 view_direction = normalize(view_dir);
-
- vec3 camPos = cameraPosLocal;
- vec3 transmittance;
- vec3 sky_illum;
- vec3 radiance = GetSkyLuminance(camPos, view_direction, 0.0f, sun_dir, transmittance);
- vec3 radiance2 = GetSunAndSkyIlluminance(camPos, view_direction, sun_dir, sky_illum);
-
- //radiance *= transmittance;
-
- // If the view ray intersects the Sun, add the Sun radiance.
- if (dot(view_direction, sun_dir) >= sun_size)
- {
- radiance = radiance + transmittance * GetSolarLuminance();
- }
-
- //vec3 color = vec3(1.0) - exp(-radiance);
- //color = pow(color, vec3(1.0 / 2.2));
-
- frag_color.rgb = radiance;
-
- frag_color.a = 1.0;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl b/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
deleted file mode 100644
index 65bb00b1f6..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/advancedAtmoV.glsl
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
- * @file class3\wl\advancedAtmoV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-
-// Inputs
-uniform vec3 camPosLocal;
-
-out vec3 view_dir;
-
-void main()
-{
- // World / view / projection
- gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
-
- // this will be normalized in the frag shader...
- view_dir = position.xyz - camPosLocal.xyz;
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
deleted file mode 100644
index 2b70ba76dc..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsF.glsl
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * @file class3\wl\atmosphericsF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-vec3 scaleSoftClipFrag(vec3 light);
-
-uniform int no_atmo;
-
-vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- light *= atten.r;
- light += additive;
- return light * 2.0;
-}
-
-vec3 atmosLighting(vec3 light)
-{
- return atmosFragLighting(light, getAdditiveColor(), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl b/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
deleted file mode 100644
index b76192d73f..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/atmosphericsV.glsl
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file class3\wl\atmosphericsV.glsl
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2005, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-// VARYING param funcs
-void setSunlitColor(vec3 v);
-void setAmblitColor(vec3 v);
-void setAdditiveColor(vec3 v);
-void setAtmosAttenuation(vec3 v);
-void setPositionEye(vec3 v);
-
-vec3 getAdditiveColor();
-
-void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao);
-
-void calcAtmospherics(vec3 inPositionEye) {
-
- vec3 P = inPositionEye;
- setPositionEye(P);
- vec3 tmpsunlit = vec3(1);
- vec3 tmpamblit = vec3(1);
- vec3 tmpaddlit = vec3(1);
- vec3 tmpattenlit = vec3(1);
- calcAtmosphericVars(inPositionEye, vec3(0), 1, tmpsunlit, tmpamblit, tmpaddlit, tmpattenlit, true);
- setSunlitColor(tmpsunlit);
- setAmblitColor(tmpamblit);
- setAdditiveColor(tmpaddlit);
- setAtmosAttenuation(tmpattenlit);
-}
-
diff --git a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
deleted file mode 100644
index 545a32a227..0000000000
--- a/indra/newview/app_settings/shaders/class3/windlight/transportF.glsl
+++ /dev/null
@@ -1,68 +0,0 @@
-/**
- * @file class3\wl\transportF.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-//////////////////////////////////////////////////////////
-// The fragment shader for the terrain atmospherics
-//////////////////////////////////////////////////////////
-
-vec3 getAdditiveColor();
-vec3 getAtmosAttenuation();
-
-uniform int no_atmo;
-
-vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- if (no_atmo == 1)
- {
- return light;
- }
- // fullbright responds minimally to atmos scatter effects
- light *= min(15.0 * atten.r, 1.0);
- light += (0.1 * additive);
- return light * 2.0;
-}
-
-vec3 atmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return vec3(1,0,1);
- //return atmosTransportFrag(light * 0.5, additive * (brightness * 0.5 + 0.5), atten);
-}
-
-vec3 fullbrightAtmosTransport(vec3 light)
-{
- return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation());
-}
-
-vec3 fullbrightShinyAtmosTransport(vec3 light)
-{
- float brightness = dot(light.rgb, vec3(0.33333));
- return atmosTransportFrag(light * 0.5, getAdditiveColor() * (brightness * brightness), getAtmosAttenuation());
-}
diff --git a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl b/indra/newview/app_settings/shaders/errorF.glsl
index 59c4a7d895..573bb5887b 100644
--- a/indra/newview/app_settings/shaders/class1/transform/colorV.glsl
+++ b/indra/newview/app_settings/shaders/errorF.glsl
@@ -1,9 +1,9 @@
-/**
- * @file colorV.glsl
+/**
+ * @file errorF.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,14 +23,12 @@
* $/LicenseInfo$
*/
-uniform int color_in;
+ // error fallback on compilation failure
-ATTRIBUTE vec3 position;
-
-VARYING int color_out;
+out vec4 frag_color;
void main()
{
- color_out = color_in;
+ frag_color = vec4(1,0,1,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl b/indra/newview/app_settings/shaders/errorV.glsl
index 47e9d15fbc..e4b362c8c8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightNoFragCoordV.glsl
+++ b/indra/newview/app_settings/shaders/errorV.glsl
@@ -1,9 +1,9 @@
/**
- * @file sunLightF.glsl
+ * @file errorV.glsl
*
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
+ * Copyright (C) 2023, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -23,15 +23,13 @@
* $/LicenseInfo$
*/
+ // fallback shader for whenever there is a compilation error
uniform mat4 modelview_projection_matrix;
-
-ATTRIBUTE vec3 position;
-uniform vec2 screen_res;
+in vec3 position;
void main()
{
- //transform vertex
- vec4 pos = modelview_projection_matrix * vec4(position.xyz, 1.0);
- gl_Position = pos;
+ gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
}
+
diff --git a/indra/newview/app_settings/shaders/shader_hierarchy.txt b/indra/newview/app_settings/shaders/shader_hierarchy.txt
deleted file mode 100644
index 8ef04d8e1f..0000000000
--- a/indra/newview/app_settings/shaders/shader_hierarchy.txt
+++ /dev/null
@@ -1,177 +0,0 @@
-Class 3 is highest quality / lowest performance
-Class 2 is medium quality / medium performance
-Class 1 is lowest quality / highest performance
-
-Shaders WILL fall back to "lower" classes for functionality.
-
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarV.glsl - gAvatarProgram, gAvatarWaterProgram
- main() - avatar/avatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/avatarF.glsl - gAvatarProgram
- main() - avatar/avatarF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballV.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLightingSpecular() - lighting/lightSpecularV.glsl
- sumLightsSpecular() - lighting/sumLightsSpecularV.glsl
- calcDirectionalLightSpecular() - lighting/lightFuncSpecularV.glsl
- calcPointLightSpecular() - lighting/lightFuncSpecularV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
- atmosGetDiffuseSunlightColor() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/eyeballF.glsl - gAvatarEyeballProgram
- main() - avatar/eyeballF.glsl
- default_lighting() - lighting/lightF.glsl
- calc_default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarV.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarV.glsl
- getSkinnedTransform() - avatarSkinV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-avatar/pickAvatarF.glsl - gAvatarPickProgram
- main() - avatar/pickAvatarF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainV.glsl - gTerrainProgram, gTerrainWaterProgram
- texgen_object() - environment/terrainV.glsl
- main() - environment/terrainV.glsl
- texgen_object() - environment/terrainV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainF.glsl - gTerrainProgram
- main() - environment/terrainF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/terrainWaterF.glsl - gTerrainWaterProgram
- main() - environment/terrainWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/underWaterF.glsl - gUnderWaterProgram
- applyWaterFog() - environment/underWaterF.glsl (NOTE: different than one in waterFogF.glsl)
- main() - environment/underWaterF.glsl
- applyWaterFog() - environment/underWaterF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterV.glsl - gWaterProgram, gUnderWaterProgram
- main() - environment/waterV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-environment/waterF.glsl - gWaterProgram
- main() - environment/waterF.glsl
- atmosTransport() - windlight/transportF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightV.glsl - gObjectFullbrightProgram, gObjectFullbrightWaterProgram
- main() - objects/fullbrightV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightF.glsl - gObjectFullbrightProgram
- main() - objects/fullbrightF.glsl
- fullbright_lighting() - lighting/lightFullbrightF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyV.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightShinyF.glsl - gObjectFullbrightShinyProgram
- main() - objects/fullbrightShinyF.glsl
- fullbright_shiny_lighting() - lighting/lightFullbrightShinyF.glsl
- fullbrightShinyAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- fullbrightScaleSoftClip() - windlight/gammaF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/fullbrightWaterF.glsl - gObjectFullbrightWaterProgram
- main() - objects/fullbrightWaterF.glsl
- fullbright_lighting_water() - lighting/lightFullbrightWaterF.glsl
- fullbrightAtmosTransport() - windlight/transportF.glsl
- atmosTransport() - windlight/transportF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyV.glsl - gObjectShinyProgram, gObjectShinyWaterProgram
- main() - objects/shinyV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- calcLighting(vec4) - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyF.glsl - gObjectShinyProgram
- main() - objects/shinyF.glsl
- shiny_lighting() - lighting/lightShinyF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/shinyWaterF.glsl - gObjectShinyWaterProgram
- main() - objects/shinyWaterF.glsl
- shiny_lighting_water() - lighting/lightShinyWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleV.glsl - gObjectSimpleProgram, gObjectSimpleWaterProgram
- main() - objects/simpleV.glsl
- calcAtmospherics() - windlight/atmosphericsV.glsl
- calcLighting() - lighting/lightV.glsl
- sumLights() - lighting/sumLightsV.glsl
- calcDirectionalLight() - lighting/lightFuncV.glsl
- calcPointLight() - lighting/lightFuncV.glsl
- atmosAmbient() - windlight/atmosphericsHelpersV.glsl
- atmosAffectDirectionalLight() - windlight/atmosphericsHelpersV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleF.glsl - gObjectSimpleProgram
- main() - objects/simpleF.glsl
- default_lighting() - lighting/lightF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-objects/simpleWaterF.glsl - gObjectSimpleWaterProgram, gAvatarWaterProgram
- main() - objects/simpleWaterF.glsl
- default_lighting_water() - lighting/lightWaterF.glsl
- atmosLighting() - windlight/atmosphericsF.glsl
- applyWaterFog() - environment/waterFogF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyV.glsl - gWLSkyProgram
- main() - windlight/skyV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/skyF.glsl - gWLSkyProgram
- main() - windlight/skyF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsV.glsl - gWLCloudProgram
- main() - windlight/cloudsV.glsl
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-windlight/cloudsF.glsl - gWLCloudProgram
- main() - windlight/cloudsF.glsl
- scaleSoftClip() - windlight/gammaF.glsl
-
-
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
deleted file mode 100644
index 8462df207b..0000000000
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ /dev/null
@@ -1,42 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<settings version = "101">
- <!--NO SHADERS-->
- <RenderAvatarCloth value="TRUE"/>
- <!--Default for now-->
- <RenderAvatarLODFactor value="1.0"/>
- <!--Default for now-->
- <RenderAvatarPhysicsLODFactor value="1.0"/>
- <!--Short Range-->
- <RenderFarClip value="256"/>
- <!--Default for now-->
- <RenderFlexTimeFactor value="1"/>
- <!--256... but they do not use this-->
- <RenderGlowResolutionPow value="9"/>
- <!--Low number-->
- <RenderMaxPartCount value="4096"/>
- <!--bump okay-->
- <RenderObjectBump value="TRUE"/>
- <!--NO SHADERS-->
- <RenderReflectionDetail value="4"/>
- <!--Simple-->
- <RenderTerrainDetail value="1"/>
- <!--Default for now-->
- <RenderTerrainLODFactor value="2.0"/>
- <!--Default for now-->
- <RenderTreeLODFactor value="1.0"/>
- <!--Avater Impostors and Visual Muting Limits (real defaults set
- based on default graphics setting -->
- <RenderAvatarMaxNonImpostors value="0"/>
- <RenderAvatarMaxComplexity value="350000"/>
- <RenderAutoMuteSurfaceAreaLimit value="1500.0"/>
- <!--Default for now-->
- <RenderVolumeLODFactor value="2.0"/>
- <!--NO SHADERS-->
- <WindLightUseAtmosShaders value="TRUE"/>
- <!--Deferred Shading-->
- <RenderDeferred value="TRUE"/>
- <!--SSAO Enabled-->
- <RenderDeferredSSAO value="TRUE"/>
- <!--Full Shadows-->
- <RenderShadowDetail value="2"/>
-</settings>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 7bb89441f2..f92d9a2a0e 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -1,4 +1,4 @@
-version 34
+version 59
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,27 +28,26 @@ version 34
//
list all
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
-RenderDelayVBUpdate 1 0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderFogRatio 1 4.0
RenderGamma 1 0
RenderGlowResolutionPow 1 9
-RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 4
+RenderLocalLightCount 1 4096
+RenderTransparentWater 1 1
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 2
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 1.0
RenderVBOEnable 1 1
RenderVBOMappingDisable 1 1
@@ -59,9 +58,9 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
-RenderTextureMemoryMultiple 1 1.0
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
+RenderReflectionProbeLevel 1 3
RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
@@ -70,7 +69,10 @@ RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLContextCoreProfile 1 1
-RenderGLMultiThreaded 1 1
+RenderGLMultiThreadedTextures 1 0
+RenderGLMultiThreadedMedia 1 1
+RenderReflectionProbeResolution 1 128
+RenderScreenSpaceReflections 1 1
//
@@ -78,7 +80,6 @@ RenderGLMultiThreaded 1 1
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -86,29 +87,28 @@ RenderAvatarMaxComplexity 1 35000
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
+RenderLocalLightCount 1 8
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
+RenderTransparentWater 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
-RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
// Medium Low Graphics Settings
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -117,28 +117,27 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 256
+RenderTransparentWater 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
// Medium Graphics Settings (standard)
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -147,28 +146,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 512
+RenderTransparentWater 1 0
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 1
//
-// Medium High Graphics Settings (deferred enabled)
+// Medium High Graphics Settings
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -177,28 +175,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 1024
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 2
//
-// High Graphics Settings (deferred + SSAO)
+// High Graphics Settings (SSAO + sun shadows)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -207,28 +204,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 2048
+RenderTransparentWater 1 1
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
-RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
+RenderShadowDetail 1 1
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
//
-// High Ultra Graphics Settings (deferred + SSAO + shadows)
+// High Ultra Graphics Settings (deferred + SSAO + all shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 350000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -237,38 +233,35 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarPhysicsLODFactor 1 1.0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
+RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -276,18 +269,20 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -302,29 +297,27 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
-RenderLocalLights 1 0
+RenderLocalLightCount 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
+RenderTransparentWater 1 0
RenderDeferredSSAO 0 0
RenderShadowDetail 0 0
+RenderReflectionProbeDetail 0 -1
list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
-RenderGLMultiThreaded 1 0
-RenderGLContextCoreProfile 1 0
+RenderGLContextCoreProfile 1 0
+RenderGLMultiThreadedMedia 1 0
-// AMD cards generally perform better when not using VBOs for streaming data
-// AMD cards also prefer an OpenGL Compatibility Profile Context
list AMD
-RenderUseStreamVBO 1 0
-RenderGLContextCoreProfile 1 0
+RenderGLMultiThreadedTextures 1 1
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionsEnabled 0 0
+RenderReflectionProbeDetail 0 0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 66197e6484..4bcefc1546 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -59,7 +59,6 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
-RenderTextureMemoryMultiple 1 1.0
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 1281b77e45..40aaccc8cb 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -1,4 +1,4 @@
-version 38
+version 56
// The version number above should be incremented IF AND ONLY IF some
// change has been made that is sufficiently important to justify
// resetting the graphics preferences of all users to the recommended
@@ -28,24 +28,21 @@ version 38
//
list all
RenderAnisotropic 1 0
-RenderAvatarCloth 1 1
+RenderAvatarCloth 0 0
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
RenderAutoMuteSurfaceAreaLimit 1 1000.0
RenderCubeMap 1 1
-RenderDelayVBUpdate 1 0
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderFogRatio 1 4.0
RenderGamma 1 0
RenderGlowResolutionPow 1 9
-RenderGround 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 4
+RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -59,7 +56,6 @@ WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
-RenderTextureMemoryMultiple 1 1.0
RenderCompressTextures 1 1
RenderShaderLightingMaxLevel 1 3
RenderDeferred 1 1
@@ -69,15 +65,19 @@ RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
-RenderGLContextCoreProfile 1 0
-RenderGLMultiThreaded 1 0
+RenderGLContextCoreProfile 1 1
+RenderGLMultiThreadedTextures 1 0
+RenderGLMultiThreadedMedia 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 2
+RenderScreenSpaceReflections 1 1
+RenderReflectionProbeLevel 1 3
//
// Low Graphics Settings
//
list Low
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0
RenderAvatarPhysicsLODFactor 1 0
RenderAvatarMaxNonImpostors 1 3
@@ -85,29 +85,28 @@ RenderAvatarMaxComplexity 1 35000
RenderFarClip 1 64
RenderFlexTimeFactor 1 0
RenderGlowResolutionPow 1 8
-RenderLocalLights 1 0
+RenderLocalLightCount 1 8
RenderMaxPartCount 1 0
-RenderObjectBump 1 0
-RenderReflectionDetail 1 0
RenderTerrainDetail 1 0
RenderTerrainLODFactor 1 1
RenderTransparentWater 1 0
RenderTreeLODFactor 1 0
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
// Medium Low Graphics Settings
//
list LowMid
RenderAnisotropic 1 0
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 0.5
RenderAvatarMaxComplexity 1 100000
RenderAvatarPhysicsLODFactor 1 0.75
@@ -116,28 +115,27 @@ RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
RenderMaxPartCount 1 2048
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 256
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 1.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.125
-WindLightUseAtmosShaders 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 0
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
// Medium Graphics Settings (standard)
//
list Mid
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 200000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -146,28 +144,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 512
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.25
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
-// Medium High Graphics Settings (deferred enabled)
+// Medium High Graphics Settings
//
list MidHigh
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 250000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -176,28 +173,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 1024
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.375
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 0
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 0
//
-// High Graphics Settings (deferred + SSAO)
+// High Graphics Settings (SSAO + sun shadows)
//
list High
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxComplexity 1 300000
RenderAvatarPhysicsLODFactor 1 1.0
@@ -206,28 +202,27 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 2048
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.5
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
-RenderShadowDetail 1 0
-WLSkyDetail 1 48
+RenderShadowDetail 1 1
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 1
//
-// High Ultra Graphics Settings (deferred + SSAO + shadows)
+// High Ultra Graphics Settings (SSAO + all shadows)
//
list HighUltra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 0
RenderAvatarLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 350000
@@ -236,38 +231,35 @@ RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
RenderMaxPartCount 1 4096
-RenderObjectBump 1 1
-RenderLocalLights 1 1
-RenderReflectionDetail 1 0
+RenderLocalLightCount 1 4096
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
RenderTreeLODFactor 1 0.5
RenderVolumeLODFactor 1 1.75
-WindLightUseAtmosShaders 1 1
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderShadowDetail 1 2
RenderUseAdvancedAtmospherics 1 0
-WLSkyDetail 1 48
+WLSkyDetail 1 96
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 2
//
// Ultra graphics (REALLY PURTY!)
//
list Ultra
RenderAnisotropic 1 1
-RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarPhysicsLODFactor 1 1.0
RenderAvatarMaxNonImpostors 1 16
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLocalLights 1 1
+RenderLocalLightCount 1 8192
RenderMaxPartCount 1 8192
-RenderObjectBump 1 1
-RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTransparentWater 1 1
@@ -275,18 +267,20 @@ RenderTreeLODFactor 1 1.0
RenderVolumeLODFactor 1 2.0
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
-RenderDeferred 1 1
RenderDeferredSSAO 1 1
RenderUseAdvancedAtmospherics 1 0
RenderShadowDetail 1 2
RenderFSAASamples 1 2
+RenderReflectionsEnabled 1 1
+RenderReflectionProbeDetail 1 1
+RenderScreenSpaceReflections 1 0
+RenderReflectionProbeLevel 1 3
//
// Class Unknown Hardware (unknown)
//
list Unknown
RenderShadowDetail 1 0
-RenderDeferred 1 0
RenderDeferredSSAO 1 0
RenderUseAdvancedAtmospherics 1 0
@@ -302,16 +296,11 @@ RenderCompressTextures 1 0
//
list safe
RenderAnisotropic 1 0
-RenderAvatarCloth 0 0
RenderAvatarMaxNonImpostors 1 16
RenderAvatarMaxComplexity 1 80000
-RenderObjectBump 0 0
-RenderLocalLights 1 0
+RenderLocalLightCount 1 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
-RenderReflectionDetail 0 0
-WindLightUseAtmosShaders 0 0
-RenderDeferred 0 0
RenderDeferredSSAO 0 0
RenderUseAdvancedAtmospherics 0 0
RenderShadowDetail 0 0
@@ -324,9 +313,9 @@ RenderDeferredSSAO 1 0
list Intel
RenderAnisotropic 1 0
-RenderLocalLights 1 0
RenderFSAASamples 1 0
-list OSX_10_6_8
-RenderDeferred 0 0
-
+list GL3
+RenderFSAASamples 0 0
+RenderReflectionProbeDetail 0 0
+RenderReflectionsEnabled 0 0
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index 962d6c060c..63608cdbf8 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -517,7 +517,6 @@ Function CheckIfAdministrator
Quit
lbl_is_admin:
Return
-
FunctionEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/indra/newview/licenses-mac.txt b/indra/newview/licenses-mac.txt
index fba6a55da3..29b5a919bd 100644
--- a/indra/newview/licenses-mac.txt
+++ b/indra/newview/licenses-mac.txt
@@ -719,3 +719,55 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+
+
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/indra/newview/licenses-win32.txt b/indra/newview/licenses-win32.txt
index 837d92139d..eddc9a4475 100644
--- a/indra/newview/licenses-win32.txt
+++ b/indra/newview/licenses-win32.txt
@@ -796,3 +796,52 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+============
+tinygltf
+============
+MIT License
+
+Copyright (c) 2017 Syoyo Fujita, Aurélien Chatelain and many contributors
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+==============
+Vulkan GLTF
+==============
+MIT License
+
+Copyright (c) 2018 Sascha Willems
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 47fbec30dd..3853aaa8fd 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -122,8 +122,7 @@ const F32 MAX_FIDGET_TIME = 20.f; // seconds
const S32 UI_FEATURE_VERSION = 1;
// For version 1: 1 - inventory, 2 - gltf
-// Will need to change to 3 once either inventory or gltf releases and cause a conflict
-const S32 UI_FEATURE_FLAGS = 1;
+const S32 UI_FEATURE_FLAGS = 3;
// The agent instance.
LLAgent gAgent;
@@ -1046,11 +1045,7 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
{
gSky.mVOSkyp->setRegion(regionp);
}
- if (gSky.mVOGroundp)
- {
- gSky.mVOGroundp->setRegion(regionp);
- }
-
+
if (regionp->capabilitiesReceived())
{
regionp->requestSimulatorFeatures();
@@ -4080,10 +4075,6 @@ bool LLAgent::teleportCore(bool is_local)
gTeleportDisplay = TRUE;
LL_INFOS("Teleport") << "Non-local, setting teleport state to TELEPORT_START" << LL_ENDL;
gAgent.setTeleportState( LLAgent::TELEPORT_START );
-
- //release geometry from old location
- gPipeline.resetVertexBuffers();
- LLSpatialPartition::sTeleportRequested = TRUE;
}
make_ui_sound("UISndTeleportOut");
@@ -4429,7 +4420,6 @@ void LLAgent::teleportCancel()
}
clearTeleportRequest();
gAgent.setTeleportState( LLAgent::TELEPORT_NONE );
- gPipeline.resetVertexBuffers();
}
void LLAgent::restoreCanceledTeleportRequest()
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 6d74249e80..8977b145d1 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1195,12 +1195,18 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Camera");
+extern BOOL gCubeSnapshot;
+
//-----------------------------------------------------------------------------
// updateCamera()
//-----------------------------------------------------------------------------
void LLAgentCamera::updateCamera()
{
LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
// - changed camera_skyward to the new global "mCameraUpVector"
mCameraUpVector = LLVector3::z_axis;
@@ -2052,6 +2058,13 @@ LLVector3d LLAgentCamera::getFocusOffsetInitial()
F32 LLAgentCamera::getCameraMaxZoomDistance()
{
+ // SL-14706 / SL-14885 TPV have relaxed camera constraints allowing you to mousewheeel zoom WAY out.
+ static LLCachedControl<bool> s_disable_camera_constraints(gSavedSettings, "DisableCameraConstraints", false);
+ if (s_disable_camera_constraints)
+ {
+ return (F32)INT_MAX;
+ }
+
// Ignore "DisableCameraConstraints", we don't want to be out of draw range when we focus onto objects or avatars
return llmin(MAX_CAMERA_DISTANCE_FROM_OBJECT,
mDrawDistance - 1, // convenience, don't hit draw limit when focusing on something
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index 087cfb8d48..17e1a27934 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -873,26 +873,9 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
LLSD httpResults;
LLCore::HttpStatus status;
- if (debugLoggingEnabled("Inventory"))
- {
- LLTimer ais_timer;
- ais_timer.start();
- result = invoke(httpAdapter , httpRequest , url , body , httpOptions , httpHeaders);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- F32MillisecondsImplicit elapsed_time = ais_timer.getElapsedTimeF32();
-
- LL_DEBUGS("Inventory") << "Request type: " << (S32)type
- << " \nRequest target: " << targetId
- << " \nElapsed time since request: " << elapsed_time
- << " \nstatus: " << status.toULong() << LL_ENDL;
- }
- else
- {
- result = invoke(httpAdapter , httpRequest , url , body , httpOptions , httpHeaders);
- httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
- status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
- }
+ result = invoke(httpAdapter , httpRequest , url , body , httpOptions , httpHeaders);
+ httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
if (!status || !result.isMap())
{
@@ -1053,7 +1036,7 @@ AISUpdate::AISUpdate(const LLSD& update, AISAPI::COMMAND_TYPE type, const LLSD&
mFetchDepth = request_body["depth"].asInteger();
}
- mTimer.setTimerExpirySec(debugLoggingEnabled("Inventory") ? EXPIRY_SECONDS_DEBUG : EXPIRY_SECONDS_LIVE);
+ mTimer.setTimerExpirySec(AIS_EXPIRY_SECONDS);
mTimer.start();
parseUpdate(update);
}
@@ -1079,7 +1062,7 @@ void AISUpdate::checkTimeout()
{
llcoro::suspend();
LLCoros::checkStop();
- mTimer.setTimerExpirySec(debugLoggingEnabled("Inventory") ? EXPIRY_SECONDS_DEBUG : EXPIRY_SECONDS_LIVE);
+ mTimer.setTimerExpirySec(AIS_EXPIRY_SECONDS);
}
}
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index 0fdf4a0b74..f254f21e42 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -130,10 +130,9 @@ private:
void clearParseResults();
void checkTimeout();
- // Debug is very log-heavy, give it more time or it will take forever to process
- // Todo: find a way to make throttle static isntead of per-request
- const F32 EXPIRY_SECONDS_DEBUG = 1.f;
- const F32 EXPIRY_SECONDS_LIVE = 0.008f;
+ // Fetch can return large packets of data, throttle it to not cause lags
+ // Todo: make throttle work over all fetch requests isntead of per-request
+ const F32 AIS_EXPIRY_SECONDS = 0.008f;
typedef std::map<LLUUID,S32> uuid_int_map_t;
uuid_int_map_t mCatDescendentDeltas;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 4bab51a1f5..4a43133ff6 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -36,6 +36,7 @@
#include "llenvironment.h"
#include "llerrorcontrol.h"
#include "lleventtimer.h"
+#include "llfile.h"
#include "llviewertexturelist.h"
#include "llgroupmgr.h"
#include "llagent.h"
@@ -103,12 +104,12 @@
#include "lldiskcache.h"
#include "llvopartgroup.h"
#include "llweb.h"
-#include "llfloatertexturefetchdebugger.h"
#include "llspellcheck.h"
#include "llscenemonitor.h"
#include "llavatarrenderinfoaccountant.h"
#include "lllocalbitmaps.h"
#include "llperfstats.h"
+#include "llgltfmateriallist.h"
// Linden library includes
#include "llavatarnamecache.h"
@@ -345,9 +346,6 @@ LLFrameTimer gRestoreGLTimer;
BOOL gRestoreGL = FALSE;
bool gUseWireframe = FALSE;
-//use for remember deferred mode in wireframe switch
-bool gInitialDeferredModeForWireframe = FALSE;
-
LLMemoryInfo gSysMemory;
U64Bytes gMemoryAllocated(0); // updated in display_stats() in llviewerdisplay.cpp
@@ -538,9 +536,12 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
- LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
+#if LL_DARWIN
+ LLRender::sGLCoreProfile = true;
+#else
+ LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
+#endif
LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
- LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic");
LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures");
LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR);
@@ -574,11 +575,10 @@ static void settings_to_globals()
static void settings_modify()
{
LLPipeline::sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
- LLPipeline::sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- LLPipeline::sRenderDeferred = LLPipeline::sRenderBump && gSavedSettings.getBOOL("RenderDeferred");
+ LLPipeline::sRenderDeferred = TRUE; // FALSE is deprecated
LLRenderTarget::sUseFBO = LLPipeline::sRenderDeferred;
LLVOSurfacePatch::sLODFactor = gSavedSettings.getF32("RenderTerrainLODFactor");
- LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; // square lod factor to get exponential range of [1,4]
+ LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4]
gDebugGL = gDebugGLSession || gDebugSession;
gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
}
@@ -1315,23 +1315,6 @@ void LLAppViewer::initMaxHeapSize()
LLMemory::initMaxHeapSizeGB(max_heap_size_gb);
}
-static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
-static LLTrace::BlockTimerStatHandle FTM_SLEEP1("Sleep1");
-static LLTrace::BlockTimerStatHandle FTM_SLEEP2("Sleep2");
-static LLTrace::BlockTimerStatHandle FTM_YIELD("Yield");
-
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_CACHE("Texture Cache");
-static LLTrace::BlockTimerStatHandle FTM_DECODE("Image Decode");
-static LLTrace::BlockTimerStatHandle FTM_FETCH("Image Fetch");
-
-static LLTrace::BlockTimerStatHandle FTM_LFS("LFS Thread");
-static LLTrace::BlockTimerStatHandle FTM_PAUSE_THREADS("Pause Threads");
-static LLTrace::BlockTimerStatHandle FTM_IDLE("Idle");
-static LLTrace::BlockTimerStatHandle FTM_PUMP("Pump");
-static LLTrace::BlockTimerStatHandle FTM_PUMP_SERVICE("Service");
-static LLTrace::BlockTimerStatHandle FTM_SERVICE_CALLBACK("Callback");
-static LLTrace::BlockTimerStatHandle FTM_AGENT_AUTOPILOT("Autopilot");
-static LLTrace::BlockTimerStatHandle FTM_AGENT_UPDATE("Update");
// externally visible timers
LLTrace::BlockTimerStatHandle FTM_FRAME("Frame");
@@ -1420,7 +1403,7 @@ bool LLAppViewer::doFrame()
if (gViewerWindow)
{
- LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("System Messages");
gViewerWindow->getWindow()->processMiscNativeEvents();
}
@@ -1431,7 +1414,7 @@ bool LLAppViewer::doFrame()
if (gViewerWindow)
{
- LL_RECORD_BLOCK_TIME(FTM_MESSAGES);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("System Messages");
if (!restoreErrorTrap())
{
LL_WARNS() << " Someone took over my signal/exception handler (post messagehandling)!" << LL_ENDL;
@@ -1461,6 +1444,8 @@ bool LLAppViewer::doFrame()
LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df suspend")
// give listeners a chance to run
llcoro::suspend();
+ // if one of our coroutines threw an uncaught exception, rethrow it now
+ LLCoros::instance().rethrow();
}
}
@@ -1495,7 +1480,7 @@ bool LLAppViewer::doFrame()
{
LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_IDLE);
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle"); //LL_RECORD_BLOCK_TIME(FTM_IDLE);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df idle");
idle();
}
@@ -1521,18 +1506,19 @@ bool LLAppViewer::doFrame()
// Render scene.
// *TODO: Should we run display() even during gHeadlessClient? DK 2011-02-18
- if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Display" )
- pingMainloopTimeout("Main:Display");
- gGLActive = TRUE;
+ if (!LLApp::isExiting() && !gHeadlessClient && gViewerWindow)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Display");
+ pingMainloopTimeout("Main:Display");
+ gGLActive = TRUE;
- display();
+ display();
{
LLPerfStats::RecordSceneTime T(LLPerfStats::StatType_t::RENDER_IDLE);
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df Snapshot" )
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("df Snapshot");
pingMainloopTimeout("Main:Snapshot");
+ gPipeline.mReflectionMapManager.update();
LLFloaterSnapshot::update(); // take snapshots
LLFloaterSimpleSnapshot::update();
gGLActive = FALSE;
@@ -1561,7 +1547,7 @@ bool LLAppViewer::doFrame()
static LLCachedControl<S32> yield_time(gSavedSettings, "YieldTime", -1);
if(yield_time >= 0)
{
- LL_RECORD_BLOCK_TIME(FTM_YIELD);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Yield");
LL_PROFILE_ZONE_NUM( yield_time )
ms_sleep(yield_time);
}
@@ -1570,7 +1556,6 @@ bool LLAppViewer::doFrame()
{
S32 non_interactive_ms_sleep_time = 100;
LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getImageDecodeThread()->pause();
ms_sleep(non_interactive_ms_sleep_time);
}
@@ -1591,7 +1576,6 @@ bool LLAppViewer::doFrame()
ms_sleep(milliseconds_to_sleep);
// also pause worker threads during this wait period
LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getImageDecodeThread()->pause();
}
}
@@ -1617,7 +1601,7 @@ bool LLAppViewer::doFrame()
work_pending += updateTextureThreads(max_time);
{
- LL_RECORD_BLOCK_TIME(FTM_LFS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("LFS Thread");
io_pending += LLLFSThread::updateClass(1);
}
@@ -1640,7 +1624,6 @@ bool LLAppViewer::doFrame()
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df getTextureCache" )
LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getImageDecodeThread()->pause();
LLAppViewer::getTextureFetch()->pause();
}
if(!total_io_pending) //pause file threads if nothing to process.
@@ -1649,21 +1632,9 @@ bool LLAppViewer::doFrame()
LLLFSThread::sLocal->pause();
}
- //texture fetching debugger
- if(LLTextureFetchDebugger::isEnabled())
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df tex_fetch_debugger_instance" )
- LLFloaterTextureFetchDebugger* tex_fetch_debugger_instance =
- LLFloaterReg::findTypedInstance<LLFloaterTextureFetchDebugger>("tex_fetch_debugger");
- if(tex_fetch_debugger_instance)
- {
- tex_fetch_debugger_instance->idle() ;
- }
- }
-
{
LL_PROFILE_ZONE_NAMED_CATEGORY_APP( "df resumeMainloopTimeout" )
- resumeMainloopTimeout();
+ resumeMainloopTimeout();
}
pingMainloopTimeout("Main:End");
}
@@ -1699,15 +1670,15 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
{
S32 work_pending = 0;
{
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_CACHE);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Texture Cache");
work_pending += LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
}
{
- LL_RECORD_BLOCK_TIME(FTM_DECODE);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Decode");
work_pending += LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
}
{
- LL_RECORD_BLOCK_TIME(FTM_FETCH);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Image Fetch");
work_pending += LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
}
return work_pending;
@@ -1715,16 +1686,20 @@ S32 LLAppViewer::updateTextureThreads(F32 max_time)
void LLAppViewer::flushLFSIO()
{
- while (1)
- {
- S32 pending = LLLFSThread::updateClass(0);
- if (!pending)
- {
- break;
- }
- LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL;
- ms_sleep(100);
- }
+ S32 pending = LLLFSThread::updateClass(0);
+ if (pending > 0)
+ {
+ LL_INFOS() << "Waiting for pending IO to finish: " << pending << LL_ENDL;
+ while (1)
+ {
+ pending = LLLFSThread::updateClass(0);
+ if (!pending)
+ {
+ break;
+ }
+ ms_sleep(100);
+ }
+ }
}
bool LLAppViewer::cleanup()
@@ -1882,8 +1857,6 @@ bool LLAppViewer::cleanup()
LL_INFOS() << "Cache files removed" << LL_ENDL;
- // Wait for any pending LFS IO
- flushLFSIO();
LL_INFOS() << "Shutting down Views" << LL_ENDL;
// Destroy the UI
@@ -2083,13 +2056,13 @@ bool LLAppViewer::cleanup()
sTextureCache->shutdown();
sImageDecodeThread->shutdown();
sPurgeDiskCacheThread->shutdown();
- if (mGeneralThreadPool)
- {
- mGeneralThreadPool->close();
- }
+ if (mGeneralThreadPool)
+ {
+ mGeneralThreadPool->close();
+ }
sTextureFetch->shutDownTextureCacheThread() ;
- sTextureFetch->shutDownImageDecodeThread() ;
+ LLLFSThread::sLocal->shutdown();
LL_INFOS() << "Shutting down message system" << LL_ENDL;
end_messaging_system();
@@ -2103,8 +2076,13 @@ bool LLAppViewer::cleanup()
//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
delete sTextureCache;
sTextureCache = NULL;
- delete sTextureFetch;
- sTextureFetch = NULL;
+ if (sTextureFetch)
+ {
+ sTextureFetch->shutdown();
+ sTextureFetch->waitOnPending();
+ delete sTextureFetch;
+ sTextureFetch = NULL;
+ }
delete sImageDecodeThread;
sImageDecodeThread = NULL;
delete mFastTimerLogThread;
@@ -2207,14 +2185,7 @@ void LLAppViewer::initGeneralThread()
return;
}
- LLSD poolSizes{ gSavedSettings.getLLSD("ThreadPoolSizes") };
- LLSD sizeSpec{ poolSizes["General"] };
- LLSD::Integer poolSize{ sizeSpec.isInteger() ? sizeSpec.asInteger() : 3 };
- LL_DEBUGS("ThreadPool") << "Instantiating General pool with "
- << poolSize << " threads" << LL_ENDL;
- // We don't want anyone, especially the main thread, to have to block
- // due to this ThreadPool being full.
- mGeneralThreadPool = new LL::ThreadPool("General", poolSize, 1024 * 1024);
+ mGeneralThreadPool = new LL::ThreadPool("General", 3);
mGeneralThreadPool->start();
}
@@ -2224,15 +2195,37 @@ bool LLAppViewer::initThreads()
LLImage::initClass(gSavedSettings.getBOOL("TextureNewByteRange"),gSavedSettings.getS32("TextureReverseByteRange"));
- LLLFSThread::initClass(enable_threads && false);
+ LLLFSThread::initClass(enable_threads && true); // TODO: fix crashes associated with this shutdo
+
+ //auto configure thread count
+ LLSD threadCounts = gSavedSettings.getLLSD("ThreadPoolSizes");
+
+ // get the number of concurrent threads that can run
+ S32 cores = std::thread::hardware_concurrency();
+
+ U32 max_cores = gSavedSettings.getU32("EmulateCoreCount");
+ if (max_cores != 0)
+ {
+ cores = llmin(cores, (S32) max_cores);
+ }
+
+ // The only configurable thread count right now is ImageDecode
+ // The viewer typically starts around 8 threads not including image decode,
+ // so try to leave at least one core free
+ S32 image_decode_count = llclamp(cores - 9, 1, 8);
+ threadCounts["ImageDecode"] = image_decode_count;
+ gSavedSettings.setLLSD("ThreadPoolSizes", threadCounts);
// Image decoding
LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
- sImageDecodeThread,
enable_threads && true,
app_metrics_qa_mode);
+
+ // general task background thread (LLPerfStats, etc)
+ LLAppViewer::instance()->initGeneralThread();
+
LLAppViewer::sPurgeDiskCacheThread = new LLPurgeDiskCacheThread();
if (LLTrace::BlockTimer::sLog || LLTrace::BlockTimer::sMetricLog)
@@ -2987,9 +2980,33 @@ void LLAppViewer::initStrings()
std::string strings_path_full = gDirUtilp->findSkinnedFilenameBaseLang(LLDir::XUI, strings_file);
if (strings_path_full.empty() || !LLFile::isfile(strings_path_full))
{
+ if (strings_path_full.empty())
+ {
+ LL_WARNS() << "The file '" << strings_file << "' is not found" << LL_ENDL;
+ }
+ else
+ {
+ llstat st;
+ int rc = LLFile::stat(strings_path_full, &st);
+ if (rc != 0)
+ {
+ LL_WARNS() << "The file '" << strings_path_full << "' failed to get status. Error code: " << rc << LL_ENDL;
+ }
+ else if (S_ISDIR(st.st_mode))
+ {
+ LL_WARNS() << "The filename '" << strings_path_full << "' is a directory name" << LL_ENDL;
+ }
+ else
+ {
+ LL_WARNS() << "The filename '" << strings_path_full << "' doesn't seem to be a regular file name" << LL_ENDL;
+ }
+ }
+
// initial check to make sure files are there failed
gDirUtilp->dumpCurrentDirectories(LLError::LEVEL_WARN);
- LL_ERRS() << "Viewer failed to find localization and UI files. Please reinstall viewer from https://secondlife.com/support/downloads/ and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
+ LL_ERRS() << "Viewer failed to find localization and UI files."
+ << " Please reinstall viewer from https://secondlife.com/support/downloads"
+ << " and contact https://support.secondlife.com if issue persists after reinstall." << LL_ENDL;
}
LLTransUtil::parseStrings(strings_file, default_trans_args);
LLTransUtil::parseLanguageStrings("language_settings.xml");
@@ -3312,7 +3329,7 @@ LLSD LLAppViewer::getViewerInfo() const
info["LOD_FACTOR"] = gSavedSettings.getF32("RenderVolumeLODFactor");
info["RENDER_QUALITY"] = (F32)gSavedSettings.getU32("RenderQualityPerformance");
info["GPU_SHADERS"] = gSavedSettings.getBOOL("RenderDeferred") ? "Enabled" : "Disabled";
- info["TEXTURE_MEMORY"] = gSavedSettings.getS32("TextureMemory");
+ info["TEXTURE_MEMORY"] = gGLManager.mVRAM;
#if LL_DARWIN
info["HIDPI"] = gHiDPISupport;
@@ -4154,7 +4171,7 @@ U32 LLAppViewer::getObjectCacheVersion()
{
// Viewer object cache version, change if object update
// format changes. JC
- const U32 INDRA_OBJECT_CACHE_VERSION = 15;
+ const U32 INDRA_OBJECT_CACHE_VERSION = 17;
return INDRA_OBJECT_CACHE_VERSION;
}
@@ -4304,6 +4321,7 @@ void LLAppViewer::purgeCache()
LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
LLAppViewer::getTextureCache()->purgeCache(LL_PATH_CACHE);
LLVOCache::getInstance()->removeCache(LL_PATH_CACHE);
+ LLViewerShaderMgr::instance()->clearShaderCache();
std::string browser_cache = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "cef_cache");
if (LLFile::isdir(browser_cache))
{
@@ -4532,7 +4550,6 @@ public:
static LLTrace::BlockTimerStatHandle FTM_AUDIO_UPDATE("Update Audio");
static LLTrace::BlockTimerStatHandle FTM_CLEANUP("Cleanup");
static LLTrace::BlockTimerStatHandle FTM_CLEANUP_DRAWABLES("Drawables");
-static LLTrace::BlockTimerStatHandle FTM_CLEANUP_OBJECTS("Objects");
static LLTrace::BlockTimerStatHandle FTM_IDLE_CB("Idle Callbacks");
static LLTrace::BlockTimerStatHandle FTM_LOD_UPDATE("Update LOD");
static LLTrace::BlockTimerStatHandle FTM_OBJECTLIST_UPDATE("Update Objectlist");
@@ -4561,6 +4578,8 @@ void LLAppViewer::idle()
LLFrameTimer::updateFrameTime();
LLFrameTimer::updateFrameCount();
LLEventTimer::updateClass();
+ LLPerfStats::updateClass();
+
// LLApp::stepFrame() performs the above three calls plus mRunner.run().
// Not sure why we don't call stepFrame() here, except that LLRunner seems
// completely redundant with LLEventTimer.
@@ -4571,6 +4590,8 @@ void LLAppViewer::idle()
LLDirPickerThread::clearDead();
F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
+ LLGLTFMaterialList::flushUpdates();
+
// Service the WorkQueue we use for replies from worker threads.
// Use function statics for the timeslice setting so we only have to fetch
// and convert MainWorkTime once.
@@ -4617,10 +4638,6 @@ void LLAppViewer::idle()
//
// Special case idle if still starting up
//
- if (LLStartUp::getStartupState() >= STATE_WORLD_INIT)
- {
- update_texture_time();
- }
if (LLStartUp::getStartupState() < STATE_STARTED)
{
// Skip rest if idle startup returns false (essentially, no world yet)
@@ -4654,7 +4671,7 @@ void LLAppViewer::idle()
}
{
- LL_RECORD_BLOCK_TIME(FTM_AGENT_AUTOPILOT);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_APP("Autopilot");
// Handle automatic walking towards points
gAgentPilot.updateTarget();
gAgent.autoPilot(&yaw);
@@ -4670,7 +4687,7 @@ void LLAppViewer::idle()
|| (agent_force_update_time > (1.0f / (F32) AGENT_FORCE_UPDATES_PER_SECOND));
if (force_update || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; //LL_RECORD_BLOCK_TIME(FTM_AGENT_UPDATE);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
// Send avatar and camera info
mLastAgentControlFlags = gAgent.getControlFlags();
mLastAgentForceUpdate = force_update ? 0 : agent_force_update_time;
@@ -4721,7 +4738,7 @@ void LLAppViewer::idle()
if (!gDisconnected)
{
- LL_RECORD_BLOCK_TIME(FTM_NETWORK);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Network");
////////////////////////////////////////////////
//
@@ -4829,7 +4846,6 @@ void LLAppViewer::idle()
{
LL_RECORD_BLOCK_TIME(FTM_CLEANUP);
{
- LL_RECORD_BLOCK_TIME(FTM_CLEANUP_OBJECTS);
gObjectList.cleanDeadObjects();
}
{
@@ -5495,6 +5511,8 @@ void LLAppViewer::pauseMainloopTimeout()
void LLAppViewer::pingMainloopTimeout(const std::string& state, F32 secs)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
+
if(mMainloopTimeout)
{
if(secs < 0.0f)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index bc4dec6bec..6d1496d517 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -49,6 +49,7 @@
#include "llsys.h" // for LLOSInfo
#include "lltimer.h"
#include "llappcorehttp.h"
+#include "threadpool_fwd.h"
#include <boost/signals2.hpp>
@@ -63,11 +64,6 @@ class LLViewerJoystick;
class LLPurgeDiskCacheThread;
class LLViewerRegion;
-namespace LL
-{
- class ThreadPool;
-}
-
extern LLTrace::BlockTimerStatHandle FTM_FRAME;
class LLAppViewer : public LLApp
@@ -391,7 +387,6 @@ extern BOOL gDisconnected;
extern LLFrameTimer gRestoreGLTimer;
extern BOOL gRestoreGL;
extern bool gUseWireframe;
-extern bool gInitialDeferredModeForWireframe;
extern LLMemoryInfo gSysMemory;
extern U64Bytes gMemoryAllocated;
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 298d841934..8cf80f388b 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -720,13 +720,15 @@ bool LLAppViewerWin32::init()
DWORD dwFlags = MDSF_NONINTERACTIVE | // automatically submit report without prompting
MDSF_PREVENTHIJACKING; // disallow swiping Exception filter
- bool needs_log_file = !isSecondInstance() && debugLoggingEnabled("BUGSPLAT");
+ bool needs_log_file = !isSecondInstance();
+ LL_DEBUGS("BUGSPLAT");
if (needs_log_file)
{
// Startup only!
LL_INFOS("BUGSPLAT") << "Engaged BugSplat logging to bugsplat.log" << LL_ENDL;
dwFlags |= MDSF_LOGFILE | MDSF_LOG_VERBOSE;
}
+ LL_ENDL;
// have to convert normal wide strings to strings of __wchar_t
sBugSplatSender = new MiniDmpSender(
@@ -737,12 +739,14 @@ bool LLAppViewerWin32::init()
dwFlags);
sBugSplatSender->setCallback(bugsplatSendLog);
+ LL_DEBUGS("BUGSPLAT");
if (needs_log_file)
{
// Log file will be created in %TEMP%, but it will be moved into logs folder in case of crash
std::string log_file = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "bugsplat.log");
sBugSplatSender->setLogFilePath(WCSTR(log_file));
}
+ LL_ENDL;
// engage stringize() overload that converts from wstring
LL_INFOS("BUGSPLAT") << "Engaged BugSplat(" << LL_TO_STRING(LL_VIEWER_CHANNEL)
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 9031ea5b1b..eb2c156ca5 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -124,7 +124,7 @@ public:
LLQueuedScriptAssetUpload(LLUUID taskId, LLUUID itemId, LLUUID assetId, TargetType_t targetType,
bool isRunning, std::string scriptName, LLUUID queueId, LLUUID exerienceId, taskUploadFinish_f finish) :
LLScriptAssetUpload(taskId, itemId, targetType, isRunning,
- exerienceId, std::string(), finish),
+ exerienceId, std::string(), finish, nullptr),
mScriptName(scriptName),
mQueueId(queueId)
{
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 91031034c6..7def9c045f 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -313,8 +313,8 @@ void LLControlAvatar::updateVolumeGeom()
}
}
- gPipeline.markRebuild(mRootVolp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
- mRootVolp->markForUpdate(TRUE);
+ gPipeline.markRebuild(mRootVolp->mDrawable, LLDrawable::REBUILD_ALL);
+ mRootVolp->markForUpdate();
// Note that attachment overrides aren't needed here, have already
// been applied at the time the mControlAvatar was created, in
@@ -604,7 +604,7 @@ void LLControlAvatar::updateAnimations()
//if (!mRootVolp->isAnySelected())
{
updateVolumeGeom();
- mRootVolp->recursiveMarkForUpdate(TRUE);
+ mRootVolp->recursiveMarkForUpdate();
}
}
@@ -617,6 +617,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -634,7 +635,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
{
LLVector4a local_end = end;
LLVector4a local_intersection;
- if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -651,7 +652,7 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
for (std::vector<LLVOVolume*>::iterator vol_it = volumes.begin(); vol_it != volumes.end(); ++vol_it)
{
LLVOVolume *volp = *vol_it;
- if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (mRootVolp != volp && volp->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 50e02d2d91..34db285514 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -71,6 +71,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index d8be4c3bd5..710bbf8f52 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -149,7 +149,7 @@ void LLDrawable::unload()
{
LLVOVolume *pVVol = getVOVolume();
pVVol->setNoLOD();
- pVVol->markForUpdate(TRUE);
+ pVVol->markForUpdate();
}
// static
@@ -249,12 +249,9 @@ void LLDrawable::cleanupReferences()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
mFaces.clear();
- gObjectList.removeDrawable(this);
-
gPipeline.unlinkDrawable(this);
removeFromOctree();
@@ -502,7 +499,6 @@ void LLDrawable::makeActive()
pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
pcode == LLViewerObject::LL_VO_PART_GROUP ||
pcode == LLViewerObject::LL_VO_HUD_PART_GROUP ||
- pcode == LLViewerObject::LL_VO_GROUND ||
pcode == LLViewerObject::LL_VO_SKY)
{
LL_ERRS() << "Static viewer object has active drawable!" << LL_ENDL;
@@ -539,7 +535,7 @@ void LLDrawable::makeActive()
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
{
- gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME);
}
updatePartition();
}
@@ -587,7 +583,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
if (mVObjp->getPCode() == LL_PCODE_VOLUME)
{
- gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME);
}
if (mSpatialBridge)
@@ -663,7 +659,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
- gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION);
}
}
}
@@ -687,7 +683,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
{ //scale change requires immediate rebuild
- gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION);
}
else if (!isRoot() &&
(!mVObjp->getAngularVelocity().isExactlyZero() ||
@@ -697,7 +693,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
if (!isState(LLDrawable::ANIMATED_CHILD))
{
setState(LLDrawable::ANIMATED_CHILD);
- gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL);
mVObjp->dirtySpatialGroup();
}
}
@@ -705,7 +701,8 @@ F32 LLDrawable::updateXform(BOOL undamped)
((dist_vec_squared(old_pos, target_pos) > 0.f)
|| (1.f - dot(old_rot, target_rot)) > 0.f))
{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
- gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ mVObjp->shrinkWrap();
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION);
}
else if (!getVOVolume() && !isAvatar())
{
@@ -816,7 +813,7 @@ void LLDrawable::updatePartition()
else
{
//a child prim moved and needs its verts regenerated
- gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION);
}
}
@@ -885,7 +882,7 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
{
LLFace* facep = getFace(i);
if (facep &&
- (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA))
+ (force_update || facep->isInAlphaPool()))
{
LLVector4a box;
box.setSub(facep->mExtents[1], facep->mExtents[0]);
@@ -911,12 +908,6 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
- LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname()
- << " pos (ignored) " << pos
- << " cam pos " << cam_pos_from_agent
- << " box " << av_box[0] << "," << av_box[1]
- << " -> dist " << mDistanceWRTCamera
- << LL_ENDL;
mVObjp->updateLOD();
return;
}
@@ -947,11 +938,11 @@ void LLDrawable::updateTexture()
if (getVOVolume())
{
- gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL);
}
}
-BOOL LLDrawable::updateGeometry(BOOL priority)
+BOOL LLDrawable::updateGeometry()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
@@ -986,12 +977,11 @@ void LLDrawable::shiftPos(const LLVector4a &shift_vector)
bool rebuild = (!volume &&
getRenderType() != LLPipeline::RENDER_TYPE_TREE &&
getRenderType() != LLPipeline::RENDER_TYPE_TERRAIN &&
- getRenderType() != LLPipeline::RENDER_TYPE_SKY &&
- getRenderType() != LLPipeline::RENDER_TYPE_GROUND);
+ getRenderType() != LLPipeline::RENDER_TYPE_SKY);
if (rebuild)
{
- gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(this, LLDrawable::REBUILD_ALL);
}
for (S32 i = 0; i < getNumFaces(); i++)
@@ -1098,11 +1088,11 @@ void LLDrawable::updateUVMinMax()
bool LLDrawable::isVisible() const
{
if (LLViewerOctreeEntryData::isVisible())
-{
- return true;
-}
+ {
+ return true;
+ }
-{
+ {
LLViewerOctreeGroup* group = mEntry->getGroup();
if (group && group->isVisible())
{
@@ -1256,10 +1246,10 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) :
LLDrawable(root->getVObj(), true),
- LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW_ARB, regionp)
+ LLSpatialPartition(data_mask, render_by_group, regionp)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
+ mOcclusionEnabled = false;
mBridge = this;
mDrawable = root;
root->setSpatialBridge(this);
@@ -1762,7 +1752,7 @@ LLDrawable* LLDrawable::getRoot()
}
LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, 0, regionp)
+: LLSpatialPartition(0, false, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index 2a0f4c93ac..970e8c8b2a 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -42,6 +42,7 @@
#include "llrect.h"
#include "llappviewer.h" // for gFrameTimeSeconds
#include "llvieweroctree.h"
+#include <unordered_set>
class LLCamera;
class LLDrawPool;
@@ -165,7 +166,7 @@ public:
void updateTexture();
void updateMaterial();
virtual void updateDistance(LLCamera& camera, bool force_update);
- BOOL updateGeometry(BOOL priority);
+ BOOL updateGeometry();
void updateFaceSize(S32 idx);
void updateSpecialHoverCursor(BOOL enabled);
@@ -223,7 +224,8 @@ public:
friend class LLDrawPool;
friend class LLSpatialBridge;
- typedef std::set<LLPointer<LLDrawable> > drawable_set_t;
+ typedef std::unordered_set<LLPointer<LLDrawable> > drawable_set_t;
+ typedef std::set<LLPointer<LLDrawable> > ordered_drawable_set_t;
typedef std::vector<LLPointer<LLDrawable> > drawable_vector_t;
typedef std::list<LLPointer<LLDrawable> > drawable_list_t;
typedef std::queue<LLPointer<LLDrawable> > drawable_queue_t;
@@ -255,8 +257,7 @@ public:
typedef enum e_drawable_flags
{
- IN_REBUILD_Q1 = 0x00000001,
- IN_REBUILD_Q2 = 0x00000002,
+ IN_REBUILD_Q = 0x00000001,
EARLY_MOVE = 0x00000004,
MOVE_UNDAMPED = 0x00000008,
ON_MOVE_LIST = 0x00000010,
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 3fd15d36df..fca0f1c978 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -36,7 +36,7 @@
#include "lldrawpoolavatar.h"
#include "lldrawpoolbump.h"
#include "lldrawpoolmaterials.h"
-#include "lldrawpoolground.h"
+#include "lldrawpoolpbropaque.h"
#include "lldrawpoolsimple.h"
#include "lldrawpoolsky.h"
#include "lldrawpooltree.h"
@@ -52,8 +52,6 @@
#include "llglcommonfunc.h"
#include "llvoavatar.h"
#include "llviewershadermgr.h"
-#include "llperfstats.h"
-
S32 LLDrawPool::sNumDrawPools = 0;
@@ -80,15 +78,15 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_FULLBRIGHT:
poolp = new LLDrawPoolFullbright();
break;
- case POOL_INVISIBLE:
- poolp = new LLDrawPoolInvisible();
- break;
case POOL_GLOW:
poolp = new LLDrawPoolGlow();
break;
- case POOL_ALPHA:
- poolp = new LLDrawPoolAlpha();
+ case POOL_ALPHA_PRE_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_PRE_WATER);
break;
+ case POOL_ALPHA_POST_WATER:
+ poolp = new LLDrawPoolAlpha(LLDrawPool::POOL_ALPHA_POST_WATER);
+ break;
case POOL_AVATAR:
case POOL_CONTROL_AV:
poolp = new LLDrawPoolAvatar(type);
@@ -106,9 +104,6 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_WATER:
poolp = new LLDrawPoolWater();
break;
- case POOL_GROUND:
- poolp = new LLDrawPoolGround();
- break;
case POOL_BUMP:
poolp = new LLDrawPoolBump();
break;
@@ -118,6 +113,12 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
case POOL_WL_SKY:
poolp = new LLDrawPoolWLSky();
break;
+ case POOL_GLTF_PBR:
+ poolp = new LLDrawPoolGLTFPBR();
+ break;
+ case POOL_GLTF_PBR_ALPHA_MASK:
+ poolp = new LLDrawPoolGLTFPBR(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
+ break;
default:
LL_ERRS() << "Unknown draw pool type!" << LL_ENDL;
return NULL;
@@ -208,15 +209,6 @@ void LLDrawPool::renderPostDeferred(S32 pass)
//virtual
void LLDrawPool::endRenderPass( S32 pass )
{
- /*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
- { //dummy cleanup of any currently bound textures
- if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
- {
- gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
- gGL.getTexUnit(i)->disable();
- }
- }*/
-
//make sure channel 0 is active channel
gGL.getTexUnit(0)->activate();
}
@@ -388,53 +380,33 @@ LLRenderPass::~LLRenderPass()
}
-void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
+void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo *pparams = *k;
if (pparams)
{
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments(vobj, false, &ratPtr);
- }
- }
- pushBatch(*pparams, mask, texture);
+ pushBatch(*pparams, texture);
}
}
}
-void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
+void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- mask |= LLVertexBuffer::MAP_WEIGHT4;
-
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
+
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo* pparams = *k;
if (pparams)
{
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, true ,&ratPtr);
- }
- }
-
if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
uploadMatrixPalette(*pparams);
@@ -442,53 +414,60 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask,
lastMeshId = pparams->mSkinInfo->mHash;
}
- pushBatch(*pparams, mask, texture);
+ pushBatch(*pparams, texture);
}
}
}
-void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
- {
- LLDrawInfo* pparams = *i;
- if (pparams)
- {
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, false, &ratPtr);
- }
- }
- pushBatch(*pparams, mask, texture, batch_textures);
- }
- }
+ if (texture)
+ {
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LLDrawInfo* pparams = *i;
+ LLCullResult::increment_iterator(i, end);
+
+ pushBatch(*pparams, texture, batch_textures);
+ }
+ }
+ else
+ {
+ pushUntexturedBatches(type);
+ }
}
-void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushUntexturedBatches(U32 type)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLVOAvatar* lastAvatar = nullptr;
- U64 lastMeshId = 0;
- mask |= LLVertexBuffer::MAP_WEIGHT4;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Perf stats
- for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
- if (pparams)
+ LLCullResult::increment_iterator(i, end);
+
+ pushUntexturedBatch(*pparams);
+ }
+}
+
+void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ if (texture)
+ {
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
- if(pparams->mFace)
- {
- LLViewerObject* vobj = pparams->mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, true, &ratPtr);
- }
- }
+ LLDrawInfo* pparams = *i;
+ LLCullResult::increment_iterator(i, end);
if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
{
@@ -497,71 +476,84 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc
lastMeshId = pparams->mSkinInfo->mHash;
}
- pushBatch(*pparams, mask, texture, batch_textures);
+ pushBatch(*pparams, texture, batch_textures);
}
}
+ else
+ {
+ pushUntexturedRiggedBatches(type);
+ }
}
-void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushUntexturedRiggedBatches(U32 type)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LLDrawInfo* pparams = *i;
+ LLCullResult::increment_iterator(i, end);
+
+ if (pparams->mAvatar.notNull() && (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash))
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushUntexturedBatch(*pparams);
+ }
+}
+
+void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
- LLDrawInfo* pparams = *i;
- if (pparams)
- {
- if((*pparams).mFace)
- {
- LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, false, &ratPtr);
- }
- }
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
- pushBatch(*pparams, mask, texture, batch_textures);
- }
+ LLDrawInfo* pparams = *i;
+ LLCullResult::increment_iterator(i, end);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
+ pushBatch(*pparams, texture, batch_textures);
}
}
-void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
- if (pparams)
- {
- if((*pparams).mFace)
- {
- LLViewerObject* vobj = (*pparams).mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, true, &ratPtr);
- }
- }
- if (LLGLSLShader::sCurBoundShaderPtr)
- {
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
- }
- else
- {
- gGL.flush();
- }
- if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
- {
- uploadMatrixPalette(*pparams);
- lastAvatar = pparams->mAvatar;
- lastMeshId = pparams->mSkinInfo->mHash;
- }
+ LLCullResult::increment_iterator(i, end);
- pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures);
+ llassert(pparams);
+
+ if (LLGLSLShader::sCurBoundShaderPtr)
+ {
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff);
}
+ else
+ {
+ gGL.flush();
+ }
+
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
+ {
+ uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
+ }
+
+ pushBatch(*pparams, texture, batch_textures);
}
}
@@ -580,9 +572,11 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params)
}
}
-void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ llassert(texture);
+
if (!params.mCount)
{
return;
@@ -592,7 +586,6 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
bool tex_setup = false;
- if (texture)
{
if (batch_textures && params.mTextureList.size() > 1)
{
@@ -625,15 +618,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
}
}
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
-
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
-
- params.mVertexBuffer->setBufferFast(mask);
- params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
if (tex_setup)
{
@@ -643,6 +629,21 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
}
}
+void LLRenderPass::pushUntexturedBatch(LLDrawInfo& params)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ if (!params.mCount)
+ {
+ return;
+ }
+
+ applyModelMatrix(params);
+
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+}
+
// static
bool LLRenderPass::uploadMatrixPalette(LLDrawInfo& params)
{
@@ -674,3 +675,169 @@ bool LLRenderPass::uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinI
return true;
}
+void setup_texture_matrix(LLDrawInfo& params)
+{
+ if (params.mTextureMatrix)
+ { //special case implementation of texture animation here because of special handling of textures for PBR batches
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+}
+
+void teardown_texture_matrix(LLDrawInfo& params)
+{
+ if (params.mTextureMatrix)
+ {
+ gGL.matrixMode(LLRender::MM_TEXTURE0);
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
+}
+
+void LLRenderPass::pushGLTFBatches(U32 type, bool textured)
+{
+ if (textured)
+ {
+ pushGLTFBatches(type);
+ }
+ else
+ {
+ pushRiggedGLTFBatches(type);
+ }
+}
+
+void LLRenderPass::pushGLTFBatches(U32 type)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
+ LLDrawInfo& params = **i;
+ LLCullResult::increment_iterator(i, end);
+
+ pushGLTFBatch(params);
+ }
+}
+
+void LLRenderPass::pushUntexturedGLTFBatches(U32 type)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushGLTFBatch");
+ LLDrawInfo& params = **i;
+ LLCullResult::increment_iterator(i, end);
+
+ pushUntexturedGLTFBatch(params);
+ }
+}
+
+void LLRenderPass::pushGLTFBatch(LLDrawInfo& params)
+{
+ auto& mat = params.mGLTFMaterial;
+
+ mat->bind(params.mTexture);
+
+ LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+ setup_texture_matrix(params);
+
+ applyModelMatrix(params);
+
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+
+ teardown_texture_matrix(params);
+}
+
+void LLRenderPass::pushUntexturedGLTFBatch(LLDrawInfo& params)
+{
+ auto& mat = params.mGLTFMaterial;
+
+ LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+ applyModelMatrix(params);
+
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
+}
+
+void LLRenderPass::pushRiggedGLTFBatches(U32 type, bool textured)
+{
+ if (textured)
+ {
+ pushRiggedGLTFBatches(type);
+ }
+ else
+ {
+ pushUntexturedRiggedGLTFBatches(type);
+ }
+}
+
+void LLRenderPass::pushRiggedGLTFBatches(U32 type)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
+ LLDrawInfo& params = **i;
+ LLCullResult::increment_iterator(i, end);
+
+ pushRiggedGLTFBatch(params, lastAvatar, lastMeshId);
+ }
+}
+
+void LLRenderPass::pushUntexturedRiggedGLTFBatches(U32 type)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pushRiggedGLTFBatch");
+ LLDrawInfo& params = **i;
+ LLCullResult::increment_iterator(i, end);
+
+ pushUntexturedRiggedGLTFBatch(params, lastAvatar, lastMeshId);
+ }
+}
+
+
+void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
+{
+ if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
+ {
+ uploadMatrixPalette(params);
+ lastAvatar = params.mAvatar;
+ lastMeshId = params.mSkinInfo->mHash;
+ }
+
+ pushGLTFBatch(params);
+}
+
+void LLRenderPass::pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId)
+{
+ if (params.mAvatar.notNull() && (lastAvatar != params.mAvatar || lastMeshId != params.mSkinInfo->mHash))
+ {
+ uploadMatrixPalette(params);
+ lastAvatar = params.mAvatar;
+ lastMeshId = params.mSkinInfo->mHash;
+ }
+
+ pushUntexturedGLTFBatch(params);
+}
+
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index fd1b022e5b..5414dba6bf 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -48,31 +48,33 @@ public:
enum
{
// Correspond to LLPipeline render type
+ // Also controls render order, so passes that don't use alpha masking/blending should come before
+ // other passes to preserve hierarchical Z for occlusion queries. Occlusion queries happen just
+ // before grass, so grass should be the first alpha masked pool. Other ordering should be done
+ // based on fill rate and likelihood to occlude future passes (faster, large occluders first).
+ //
POOL_SIMPLE = 1,
- POOL_GROUND,
POOL_FULLBRIGHT,
POOL_BUMP,
- POOL_MATERIALS,
- POOL_TERRAIN,
- POOL_SKY,
- POOL_WL_SKY,
+ POOL_TERRAIN,
+ POOL_MATERIALS,
+ POOL_GLTF_PBR,
+ POOL_GRASS,
+ POOL_GLTF_PBR_ALPHA_MASK,
POOL_TREE,
POOL_ALPHA_MASK,
POOL_FULLBRIGHT_ALPHA_MASK,
- POOL_GRASS,
- POOL_INVISIBLE, // see below *
+ POOL_SKY,
+ POOL_WL_SKY,
POOL_AVATAR,
POOL_CONTROL_AV, // Animesh
- POOL_VOIDWATER,
- POOL_WATER,
POOL_GLOW,
- POOL_ALPHA,
+ POOL_ALPHA_PRE_WATER,
+ POOL_VOIDWATER,
+ POOL_WATER,
+ POOL_ALPHA_POST_WATER,
+ POOL_ALPHA, // note there is no actual "POOL_ALPHA" but pre-water and post-water pools consume POOL_ALPHA faces
NUM_POOL_TYPES,
- // * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them
- // - and the LLDrawPool types enum controls what order things are rendered in
- // - so, it has absolute control over what invisprims block
- // ...invisiprims being rendered in pool_invisible
- // ...shiny/bump mapped objects in rendered in POOL_BUMP
};
LLDrawPool(const U32 type);
@@ -106,9 +108,9 @@ public:
virtual S32 getNumShadowPasses();
virtual void renderShadow(S32 pass = 0);
- virtual void render(S32 pass = 0) = 0;
- virtual void prerender() = 0;
- virtual U32 getVertexDataMask() = 0;
+ virtual void render(S32 pass = 0) {};
+ virtual void prerender() {};
+ virtual U32 getVertexDataMask() { return 0; } // DEPRECATED -- draw pool doesn't actually determine vertex data mask any more
virtual BOOL verify() const { return TRUE; } // Verify that all data in the draw pool is correct!
virtual S32 getShaderLevel() const { return mShaderLevel; }
@@ -129,6 +131,7 @@ class LLRenderPass : public LLDrawPool
public:
// list of possible LLRenderPass types to assign a render batch to
// NOTE: "rigged" variant MUST be non-rigged variant + 1
+ // see LLVolumeGeometryManager::registerFace()
enum
{
PASS_SIMPLE = NUM_POOL_TYPES,
@@ -182,6 +185,8 @@ public:
PASS_NORMSPEC_EMISSIVE_RIGGED,
PASS_GLOW,
PASS_GLOW_RIGGED,
+ PASS_GLTF_GLOW,
+ PASS_GLTF_GLOW_RIGGED,
PASS_ALPHA,
PASS_ALPHA_RIGGED,
PASS_ALPHA_MASK,
@@ -190,9 +195,152 @@ public:
PASS_FULLBRIGHT_ALPHA_MASK_RIGGED,
PASS_ALPHA_INVISIBLE,
PASS_ALPHA_INVISIBLE_RIGGED,
+ PASS_GLTF_PBR,
+ PASS_GLTF_PBR_RIGGED,
+ PASS_GLTF_PBR_ALPHA_MASK,
+ PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
NUM_RENDER_TYPES,
};
+ #ifdef LL_PROFILER_ENABLE_RENDER_DOC
+ static inline const char* lookupPassName(U32 pass)
+ {
+ switch (pass)
+ {
+ case PASS_SIMPLE:
+ return "PASS_SIMPLE";
+ case PASS_SIMPLE_RIGGED:
+ return "PASS_SIMPLE_RIGGED";
+ case PASS_GRASS:
+ return "PASS_GRASS";
+ case PASS_FULLBRIGHT:
+ return "PASS_FULLBRIGHT";
+ case PASS_FULLBRIGHT_RIGGED:
+ return "PASS_FULLBRIGHT_RIGGED";
+ case PASS_INVISIBLE:
+ return "PASS_INVISIBLE";
+ case PASS_INVISIBLE_RIGGED:
+ return "PASS_INVISIBLE_RIGGED";
+ case PASS_INVISI_SHINY:
+ return "PASS_INVISI_SHINY";
+ case PASS_INVISI_SHINY_RIGGED:
+ return "PASS_INVISI_SHINY_RIGGED";
+ case PASS_FULLBRIGHT_SHINY:
+ return "PASS_FULLBRIGHT_SHINY";
+ case PASS_FULLBRIGHT_SHINY_RIGGED:
+ return "PASS_FULLBRIGHT_SHINY_RIGGED";
+ case PASS_SHINY:
+ return "PASS_SHINY";
+ case PASS_SHINY_RIGGED:
+ return "PASS_SHINY_RIGGED";
+ case PASS_BUMP:
+ return "PASS_BUMP";
+ case PASS_BUMP_RIGGED:
+ return "PASS_BUMP_RIGGED";
+ case PASS_POST_BUMP:
+ return "PASS_POST_BUMP";
+ case PASS_POST_BUMP_RIGGED:
+ return "PASS_POST_BUMP_RIGGED";
+ case PASS_MATERIAL:
+ return "PASS_MATERIAL";
+ case PASS_MATERIAL_RIGGED:
+ return "PASS_MATERIAL_RIGGED";
+ case PASS_MATERIAL_ALPHA:
+ return "PASS_MATERIAL_ALPHA";
+ case PASS_MATERIAL_ALPHA_RIGGED:
+ return "PASS_MATERIAL_ALPHA_RIGGED";
+ case PASS_MATERIAL_ALPHA_MASK:
+ return "PASS_MATERIAL_ALPHA_MASK";
+ case PASS_MATERIAL_ALPHA_MASK_RIGGED:
+ return "PASS_MATERIAL_ALPHA_MASK_RIGGED";
+ case PASS_MATERIAL_ALPHA_EMISSIVE:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE";
+ case PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED:
+ return "PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED";
+ case PASS_SPECMAP:
+ return "PASS_SPECMAP";
+ case PASS_SPECMAP_RIGGED:
+ return "PASS_SPECMAP_RIGGED";
+ case PASS_SPECMAP_BLEND:
+ return "PASS_SPECMAP_BLEND";
+ case PASS_SPECMAP_BLEND_RIGGED:
+ return "PASS_SPECMAP_BLEND_RIGGED";
+ case PASS_SPECMAP_MASK:
+ return "PASS_SPECMAP_MASK";
+ case PASS_SPECMAP_MASK_RIGGED:
+ return "PASS_SPECMAP_MASK_RIGGED";
+ case PASS_SPECMAP_EMISSIVE:
+ return "PASS_SPECMAP_EMISSIVE";
+ case PASS_SPECMAP_EMISSIVE_RIGGED:
+ return "PASS_SPECMAP_EMISSIVE_RIGGED";
+ case PASS_NORMMAP:
+ return "PASS_NORMAMAP";
+ case PASS_NORMMAP_RIGGED:
+ return "PASS_NORMMAP_RIGGED";
+ case PASS_NORMMAP_BLEND:
+ return "PASS_NORMMAP_BLEND";
+ case PASS_NORMMAP_BLEND_RIGGED:
+ return "PASS_NORMMAP_BLEND_RIGGED";
+ case PASS_NORMMAP_MASK:
+ return "PASS_NORMMAP_MASK";
+ case PASS_NORMMAP_MASK_RIGGED:
+ return "PASS_NORMMAP_MASK_RIGGED";
+ case PASS_NORMMAP_EMISSIVE:
+ return "PASS_NORMMAP_EMISSIVE";
+ case PASS_NORMMAP_EMISSIVE_RIGGED:
+ return "PASS_NORMMAP_EMISSIVE_RIGGED";
+ case PASS_NORMSPEC:
+ return "PASS_NORMSPEC";
+ case PASS_NORMSPEC_RIGGED:
+ return "PASS_NORMSPEC_RIGGED";
+ case PASS_NORMSPEC_BLEND:
+ return "PASS_NORMSPEC_BLEND";
+ case PASS_NORMSPEC_BLEND_RIGGED:
+ return "PASS_NORMSPEC_BLEND_RIGGED";
+ case PASS_NORMSPEC_MASK:
+ return "PASS_NORMSPEC_MASK";
+ case PASS_NORMSPEC_MASK_RIGGED:
+ return "PASS_NORMSPEC_MASK_RIGGED";
+ case PASS_NORMSPEC_EMISSIVE:
+ return "PASS_NORMSPEC_EMISSIVE";
+ case PASS_NORMSPEC_EMISSIVE_RIGGED:
+ return "PASS_NORMSPEC_EMISSIVE_RIGGED";
+ case PASS_GLOW:
+ return "PASS_GLOW";
+ case PASS_GLOW_RIGGED:
+ return "PASS_GLOW_RIGGED";
+ case PASS_ALPHA:
+ return "PASS_ALPHA";
+ case PASS_ALPHA_RIGGED:
+ return "PASS_ALPHA_RIGGED";
+ case PASS_ALPHA_MASK:
+ return "PASS_ALPHA_MASK";
+ case PASS_ALPHA_MASK_RIGGED:
+ return "PASS_ALPHA_MASK_RIGGED";
+ case PASS_FULLBRIGHT_ALPHA_MASK:
+ return "PASS_FULLBRIGHT_ALPHA_MASK";
+ case PASS_FULLBRIGHT_ALPHA_MASK_RIGGED:
+ return "PASS_FULLBRIGHT_ALPHA_MASK_RIGGED";
+ case PASS_ALPHA_INVISIBLE:
+ return "PASS_ALPHA_INVISIBLE";
+ case PASS_ALPHA_INVISIBLE_RIGGED:
+ return "PASS_ALPHA_INVISIBLE_RIGGED";
+ case PASS_GLTF_PBR:
+ return "PASS_GLTF_PBR";
+ case PASS_GLTF_PBR_RIGGED:
+ return "PASS_GLTF_PBR_RIGGED";
+ case PASS_GLTF_PBR_ALPHA_MASK:
+ return "PASS_GLTF_PBR_ALPHA_MASK";
+ case PASS_GLTF_PBR_ALPHA_MASK_RIGGED:
+ return "PASS_GLTF_PBR_ALPHA_MASK_RIGGED";
+ default:
+ return "Unknown pass";
+ }
+ }
+ #else
+ static inline const char* lookupPass(U32 pass) { return ""; }
+ #endif
+
LLRenderPass(const U32 type);
virtual ~LLRenderPass();
/*virtual*/ LLViewerTexture* getDebugTexture() { return NULL; }
@@ -201,15 +349,45 @@ public:
void resetDrawOrders() { }
static void applyModelMatrix(const LLDrawInfo& params);
- virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
- virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
- virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
- virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE);
- virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE);
+ // Use before a non-GLTF batch if it is interleaved with GLTF batches that share the same shader
+ static void resetGLTFTextureTransform();
+ void pushBatches(U32 type, bool texture = true, bool batch_textures = false);
+ void pushUntexturedBatches(U32 type);
+
+ void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false);
+ void pushUntexturedRiggedBatches(U32 type);
+
+ // push full GLTF batches
+ // assumes draw infos of given type have valid GLTF materials
+ void pushGLTFBatches(U32 type);
+
+ // like pushGLTFBatches, but will not bind textures or set up texture transforms
+ void pushUntexturedGLTFBatches(U32 type);
+
+ // helper function for dispatching to textured or untextured pass based on bool
+ void pushGLTFBatches(U32 type, bool textured);
+
+
+ // rigged variants of above
+ void pushRiggedGLTFBatches(U32 type);
+ void pushRiggedGLTFBatches(U32 type, bool textured);
+ void pushUntexturedRiggedGLTFBatches(U32 type);
+
+ // push a single GLTF draw call
+ void pushGLTFBatch(LLDrawInfo& params);
+ void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+ void pushUntexturedGLTFBatch(LLDrawInfo& params);
+ void pushUntexturedRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId);
+
+ void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
+ void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false);
+ void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
+ void pushUntexturedBatch(LLDrawInfo& params);
+ void pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures = false);
static bool uploadMatrixPalette(LLDrawInfo& params);
static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo);
- virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
- virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
+ virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true);
+ virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture = true);
};
class LLFacePool : public LLDrawPool
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index ab1ac7e30c..052a1d796a 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -49,13 +49,14 @@
#include "llspatialpartition.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
-#include "llperfstats.h"
+
+#include "llenvironment.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
#define current_shader (LLGLSLShader::sCurBoundShaderPtr)
-static BOOL deferred_render = FALSE;
+LLVector4 LLDrawPoolAlpha::sWaterPlane;
// minimum alpha before discarding a fragment
static const F32 MINIMUM_ALPHA = 0.004f; // ~ 1/255
@@ -91,25 +92,36 @@ S32 LLDrawPoolAlpha::getNumPostDeferredPasses()
}
// set some common parameters on the given shader to prepare for alpha rendering
-static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment)
+static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool deferredEnvironment, F32 water_sign)
{
static LLCachedControl<F32> displayGamma(gSavedSettings, "RenderDeferredDisplayGamma");
F32 gamma = displayGamma;
+ static LLStaticHashedString waterSign("waterSign");
+
// Does this deferred shader need environment uniforms set such as sun_dir, etc. ?
// NOTE: We don't actually need a gbuffer since we are doing forward rendering (for transparency) post deferred rendering
// TODO: bindDeferredShader() probably should have the updating of the environment uniforms factored out into updateShaderEnvironmentUniforms()
// i.e. shaders\class1\deferred\alphaF.glsl
if (deferredEnvironment)
{
- gPipeline.bindDeferredShader( *shader );
+ shader->mCanBindFast = false;
+ }
+
+ shader->bind();
+ shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
+
+ if (LLPipeline::sRenderingHUDs)
+ { // for HUD attachments, only the pre-water pass is executed and we never want to clip anything
+ LLVector4 near_clip(0, 0, -1, 0);
+ shader->uniform1f(waterSign, 1.f);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, near_clip.mV);
}
else
{
- shader->bind();
+ shader->uniform1f(waterSign, water_sign);
+ shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
}
- shader->uniform1i(LLShaderMgr::NO_ATMO, (LLPipeline::sRenderingHUDs) ? 1 : 0);
- shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
if (LLPipeline::sImpostorRender)
{
@@ -127,48 +139,89 @@ static void prepare_alpha_shader(LLGLSLShader* shader, bool textureGamma, bool d
//also prepare rigged variant
if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
{
- prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment);
+ prepare_alpha_shader(shader->mRiggedVariant, textureGamma, deferredEnvironment, water_sign);
}
}
+extern BOOL gCubeSnapshot;
+
void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- deferred_render = TRUE;
+
+ if (LLPipeline::isWaterClip() && getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ { // don't render alpha objects on the other side of the water plane if water is opaque
+ return;
+ }
+
+ F32 water_sign = 1.f;
+
+ if (getType() == LLDrawPool::POOL_ALPHA_PRE_WATER)
+ {
+ water_sign = -1.f;
+ }
+
+ if (LLPipeline::sUnderWaterRender)
+ {
+ water_sign *= -1.f;
+ }
// prepare shaders
- emissive_shader = (LLPipeline::sRenderDeferred) ? &gDeferredEmissiveProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- prepare_alpha_shader(emissive_shader, true, false);
+ llassert(LLPipeline::sRenderDeferred);
+
+ emissive_shader = &gDeferredEmissiveProgram;
+ prepare_alpha_shader(emissive_shader, true, false, water_sign);
+
+ pbr_emissive_shader = &gPBRGlowProgram;
+ prepare_alpha_shader(pbr_emissive_shader, true, false, water_sign);
+
- fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
- (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightAlphaMaskProgram;
- prepare_alpha_shader(fullbright_shader, true, false);
+ fullbright_shader =
+ (LLPipeline::sImpostorRender) ? &gDeferredFullbrightAlphaMaskProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterAlphaProgram :
+ (LLPipeline::sRenderingHUDs) ? &gHUDFullbrightAlphaMaskAlphaProgram :
+ &gDeferredFullbrightAlphaMaskAlphaProgram;
+ prepare_alpha_shader(fullbright_shader, true, true, water_sign);
- simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
- (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
- prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
+ simple_shader =
+ (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
+ (LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram :
+ (LLPipeline::sRenderingHUDs) ? &gHUDAlphaProgram :
+ &gDeferredAlphaProgram;
- for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
+ prepare_alpha_shader(simple_shader, false, true, water_sign); //prime simple shader (loads shadow relevant uniforms)
+
+ LLGLSLShader* materialShader = LLPipeline::sUnderWaterRender ? gDeferredMaterialWaterProgram : gDeferredMaterialProgram;
+ for (int i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
- prepare_alpha_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], false, false); // note: bindDeferredShader will get called during render loop for materials
+ prepare_alpha_shader(&materialShader[i], false, true, water_sign);
}
- // first pass, render rigged objects only and render to depth buffer
- forwardRender(true);
+ pbr_shader =
+ (LLPipeline::sUnderWaterRender) ? &gDeferredPBRAlphaWaterProgram :
+ (LLPipeline::sRenderingHUDs) ? &gHUDPBRAlphaProgram :
+ &gDeferredPBRAlphaProgram;
+
+ prepare_alpha_shader(pbr_shader, false, true, water_sign);
+
+ // explicitly unbind here so render loop doesn't make assumptions about the last shader
+ // already being setup for rendering
+ LLGLSLShader::unbind();
+
+ if (!LLPipeline::sRenderingHUDs)
+ {
+ // first pass, render rigged objects only and render to depth buffer
+ forwardRender(true);
+ }
// second pass, regular forward alpha rendering
forwardRender();
// final pass, render to depth for depth of field effects
- if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
+ if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField") && !gCubeSnapshot && !LLPipeline::sRenderingHUDs && getType() == LLDrawPool::POOL_ALPHA_POST_WATER)
{
//update depth buffer sampler
- gPipeline.mScreen.flush();
- gPipeline.mDeferredDepth.copyContents(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(), gPipeline.mDeferredScreen.getHeight(),
- 0, 0, gPipeline.mDeferredDepth.getWidth(), gPipeline.mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
- gPipeline.mDeferredDepth.bindTarget();
- simple_shader = fullbright_shader = &gObjectFullbrightAlphaMaskProgram;
+ simple_shader = fullbright_shader = &gDeferredFullbrightAlphaMaskProgram;
simple_shader->bind();
simple_shader->setMinimumAlpha(0.33f);
@@ -181,60 +234,8 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2,
true); // <--- discard mostly transparent faces
- gPipeline.mDeferredDepth.flush();
- gPipeline.mScreen.bindTarget();
gGL.setColorMask(true, false);
}
-
- deferred_render = FALSE;
-}
-
-//set some generic parameters for forward (non-deferred) rendering
-static void prepare_forward_shader(LLGLSLShader* shader, F32 minimum_alpha)
-{
- shader->bind();
- shader->setMinimumAlpha(minimum_alpha);
- shader->uniform1i(LLShaderMgr::NO_ATMO, LLPipeline::sRenderingHUDs ? 1 : 0);
-
- //also prepare rigged variant
- if (shader->mRiggedVariant && shader->mRiggedVariant != shader)
- {
- prepare_forward_shader(shader->mRiggedVariant, minimum_alpha);
- }
-}
-
-void LLDrawPoolAlpha::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
-
- simple_shader = (LLPipeline::sImpostorRender) ? &gObjectSimpleImpostorProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectSimpleWaterProgram : &gObjectSimpleAlphaMaskProgram;
-
- fullbright_shader = (LLPipeline::sImpostorRender) ? &gObjectFullbrightAlphaMaskProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectFullbrightWaterProgram : &gObjectFullbrightAlphaMaskProgram;
-
- emissive_shader = (LLPipeline::sImpostorRender) ? &gObjectEmissiveProgram :
- (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
-
- F32 minimum_alpha = MINIMUM_ALPHA;
- if (LLPipeline::sImpostorRender)
- {
- minimum_alpha = MINIMUM_IMPOSTOR_ALPHA;
- }
-
- prepare_forward_shader(fullbright_shader, minimum_alpha);
- prepare_forward_shader(simple_shader, minimum_alpha);
-
- for (int i = 0; i < LLMaterial::SHADER_COUNT; ++i)
- {
- prepare_forward_shader(LLPipeline::sUnderWaterRender ? &gDeferredMaterialWaterProgram[i] : &gDeferredMaterialProgram[i], minimum_alpha);
- }
-
- //first pass -- rigged only and drawn to depth buffer
- forwardRender(true);
-
- //second pass -- non-rigged, no depth buffer writes
- forwardRender();
}
void LLDrawPoolAlpha::forwardRender(bool rigged)
@@ -246,11 +247,13 @@ void LLDrawPoolAlpha::forwardRender(bool rigged)
//enable writing to alpha for emissive effects
gGL.setColorMask(true, true);
- bool write_depth = rigged ||
+ bool write_depth = rigged ||
LLDrawPoolWater::sSkipScreenCopy
// we want depth written so that rendered alpha will
// contribute to the alpha mask used for impostors
- || LLPipeline::sImpostorRenderAlphaDepthPass;
+ || LLPipeline::sImpostorRenderAlphaDepthPass
+ || getType() == LLDrawPoolAlpha::POOL_ALPHA_PRE_WATER; // needed for accurate water fog
+
LLGLDepthTest depth(GL_TRUE, write_depth ? GL_TRUE : GL_FALSE);
@@ -281,49 +284,48 @@ void LLDrawPoolAlpha::renderDebugAlpha()
{
gHighlightProgram.bind();
gGL.diffuseColor4f(1, 0, 0, 1);
+ gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::getSmokeImage());
- LLViewerFetchedTexture::sSmokeImagep->addTextureStats(1024.f * 1024.f);
- gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sSmokeImagep);
-
- renderAlphaHighlight(LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0);
+ renderAlphaHighlight();
- pushBatches(LLRenderPass::PASS_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_ALPHA_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushUntexturedBatches(LLRenderPass::PASS_ALPHA_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE);
// Material alpha mask
gGL.diffuseColor4f(0, 0, 1, 1);
- pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_NORMMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_SPECMAP_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_NORMSPEC_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushUntexturedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_NORMMAP_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_SPECMAP_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_NORMSPEC_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
+ pushUntexturedBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK);
gGL.diffuseColor4f(0, 1, 0, 1);
- pushBatches(LLRenderPass::PASS_INVISIBLE, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushUntexturedBatches(LLRenderPass::PASS_INVISIBLE);
gHighlightProgram.mRiggedVariant->bind();
gGL.diffuseColor4f(1, 0, 0, 1);
- pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_ALPHA_INVISIBLE_RIGGED, false);
// Material alpha mask
gGL.diffuseColor4f(0, 0, 1, 1);
- pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
- pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, false);
+ pushRiggedBatches(LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED, false);
gGL.diffuseColor4f(0, 1, 0, 1);
- pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, FALSE);
+ pushRiggedBatches(LLRenderPass::PASS_INVISIBLE_RIGGED, false);
LLGLSLShader::sCurBoundShaderPtr->unbind();
}
}
-void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
+void LLDrawPoolAlpha::renderAlphaHighlight()
{
for (int pass = 0; pass < 2; ++pass)
{ //two passes, one rigged and one not
@@ -341,25 +343,10 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-
- if (params.mParticle)
- {
- continue;
- }
-
bool rigged = (params.mAvatar != nullptr);
gHighlightProgram.bind(rigged);
gGL.diffuseColor4f(1, 0, 0, 1);
@@ -379,12 +366,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
}
LLRenderPass::applyModelMatrix(params);
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
- params.mVertexBuffer->setBufferFast(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask);
- params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
}
@@ -411,71 +394,83 @@ inline bool IsEmissive(LLDrawInfo& params)
inline void Draw(LLDrawInfo* draw, U32 mask)
{
- draw->mVertexBuffer->setBufferFast(mask);
+ draw->mVertexBuffer->setBuffer();
LLRenderPass::applyModelMatrix(*draw);
- draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material)
{
bool tex_setup = false;
- if (deferred_render && use_material && current_shader)
+ if (draw->mGLTFMaterial)
{
- if (draw->mNormalMap)
- {
- draw->mNormalMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
- }
-
- if (draw->mSpecularMap)
- {
- draw->mSpecularMap->addTextureStats(draw->mVSize);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
- }
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
}
- else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ else
{
- current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
- current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
- }
- if (draw->mTextureList.size() > 1)
- {
- for (U32 i = 0; i < draw->mTextureList.size(); ++i)
- {
- if (draw->mTextureList[i].notNull())
- {
- gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
- }
- }
- }
- else
- { //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (draw->mTexture.notNull())
- {
- if (use_material)
- {
- current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
- }
- else
- {
- gGL.getTexUnit(0)->bindFast(draw->mTexture);
- }
+ if (!LLPipeline::sRenderingHUDs && use_material && current_shader)
+ {
+ if (draw->mNormalMap)
+ {
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, draw->mNormalMap);
+ }
- if (draw->mTextureMatrix)
- {
- tex_setup = true;
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadMatrix((GLfloat*) draw->mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
- }
- }
- else
- {
- gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
+ if (draw->mSpecularMap)
+ {
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, draw->mSpecularMap);
+ }
+ }
+ else if (current_shader == simple_shader || current_shader == simple_shader->mRiggedVariant)
+ {
+ current_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ current_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+ if (draw->mTextureList.size() > 1)
+ {
+ for (U32 i = 0; i < draw->mTextureList.size(); ++i)
+ {
+ if (draw->mTextureList[i].notNull())
+ {
+ gGL.getTexUnit(i)->bindFast(draw->mTextureList[i]);
+ }
+ }
+ }
+ else
+ { //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (draw->mTexture.notNull())
+ {
+ if (use_material)
+ {
+ current_shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, draw->mTexture);
+ }
+ else
+ {
+ gGL.getTexUnit(0)->bindFast(draw->mTexture);
+ }
+
+ if (draw->mTextureMatrix)
+ {
+ tex_setup = true;
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
+ gGL.loadMatrix((GLfloat*)draw->mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
+ }
+ else
+ {
+ gGL.getTexUnit(0)->unbindFast(LLTexUnit::TT_TEXTURE);
+ }
+ }
+ }
return tex_setup;
}
@@ -491,15 +486,15 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup)
}
}
-void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw)
+void LLDrawPoolAlpha::drawEmissive(LLDrawInfo* draw)
{
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
- draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE);
- draw->mVertexBuffer->drawRangeFast(draw->mDrawMode, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ draw->mVertexBuffer->setBuffer();
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
}
-void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+void LLDrawPoolAlpha::renderEmissives(std::vector<LLDrawInfo*>& emissives)
{
emissive_shader->bind();
emissive_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f);
@@ -507,12 +502,26 @@ void LLDrawPoolAlpha::renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissi
for (LLDrawInfo* draw : emissives)
{
bool tex_setup = TexSetup(draw, false);
- drawEmissive(mask, draw);
+ drawEmissive(draw);
RestoreTexSetup(tex_setup);
}
}
-void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives)
+void LLDrawPoolAlpha::renderPbrEmissives(std::vector<LLDrawInfo*>& emissives)
+{
+ pbr_emissive_shader->bind();
+
+ for (LLDrawInfo* draw : emissives)
+ {
+ llassert(draw->mGLTFMaterial);
+ LLGLDisable cull_face(draw->mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
+ draw->mGLTFMaterial->bind(draw->mTexture);
+ draw->mVertexBuffer->setBuffer();
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ }
+}
+
+void LLDrawPoolAlpha::renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives)
{
LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter
LLGLSLShader* shader = emissive_shader->mRiggedVariant;
@@ -522,17 +531,9 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- mask |= LLVertexBuffer::MAP_WEIGHT4;
-
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLDrawInfo* draw : emissives)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("Emissives");
- auto vobj = draw->mFace?draw->mFace->getViewerObject():nullptr;
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, draw->mFace->isState(LLFace::RIGGED), &ratPtr );
- }
bool tex_setup = TexSetup(draw, false);
if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
@@ -544,11 +545,38 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
lastAvatar = draw->mAvatar;
lastMeshId = draw->mSkinInfo->mHash;
}
- drawEmissive(mask, draw);
+ drawEmissive(draw);
RestoreTexSetup(tex_setup);
}
}
+void LLDrawPoolAlpha::renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissives)
+{
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE); //disable depth writes since "emissive" is additive so sorting doesn't matter
+ pbr_emissive_shader->bind(true);
+
+ LLVOAvatar* lastAvatar = nullptr;
+ U64 lastMeshId = 0;
+
+ for (LLDrawInfo* draw : emissives)
+ {
+ if (lastAvatar != draw->mAvatar || lastMeshId != draw->mSkinInfo->mHash)
+ {
+ if (!uploadMatrixPalette(*draw))
+ { // failed to upload matrix palette, skip rendering
+ continue;
+ }
+ lastAvatar = draw->mAvatar;
+ lastMeshId = draw->mSkinInfo->mHash;
+ }
+
+ LLGLDisable cull_face(draw->mGLTFMaterial->mDoubleSided ? GL_CULL_FACE : 0);
+ draw->mGLTFMaterial->bind(draw->mTexture);
+ draw->mVertexBuffer->setBuffer();
+ draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset);
+ }
+}
+
void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
@@ -572,6 +600,16 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
begin = gPipeline.beginAlphaGroups();
end = gPipeline.endAlphaGroups();
}
+
+ LLEnvironment& env = LLEnvironment::instance();
+ F32 water_height = env.getWaterHeight();
+
+ bool above_water = getType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+ if (LLPipeline::sUnderWaterRender)
+ {
+ above_water = !above_water;
+ }
+
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
@@ -583,22 +621,46 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
+
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
+ const LLVector4a* ext = bridge ? bridge->getSpatialExtents() : group->getExtents();
+
+ if (!LLPipeline::sRenderingHUDs) // ignore above/below water for HUD render
+ {
+ if (above_water)
+ { // reject any spatial groups that have no part above water
+ if (ext[1].getF32ptr()[2] < water_height)
+ {
+ continue;
+ }
+ }
+ else
+ { // reject any spatial groups that he no part below water
+ if (ext[0].getF32ptr()[2] > water_height)
+ {
+ continue;
+ }
+ }
+ }
+
static std::vector<LLDrawInfo*> emissives;
static std::vector<LLDrawInfo*> rigged_emissives;
+ static std::vector<LLDrawInfo*> pbr_emissives;
+ static std::vector<LLDrawInfo*> pbr_rigged_emissives;
+
emissives.resize(0);
rigged_emissives.resize(0);
+ pbr_emissives.resize(0);
+ pbr_rigged_emissives.resize(0);
bool is_particle_or_hud_particle = group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_PARTICLE
|| group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD_PARTICLE;
- bool draw_glow_for_this_partition = mShaderLevel > 0; // no shaders = no glow.
-
bool disable_cull = is_particle_or_hud_particle;
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{}; // Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
@@ -607,81 +669,78 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
continue;
}
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch")
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch");
- U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
- if (have_mask != mask)
- { //FIXME!
- LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask
- << " present: " << have_mask
- << ". Skipping render batch." << LL_ENDL;
- continue;
- }
+ LLRenderPass::applyModelMatrix(params);
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+ LLMaterial* mat = NULL;
+ LLGLTFMaterial *gltf_mat = params.mGLTFMaterial;
- if(vobj && vobj->isAttachment())
+ LLGLDisable cull_face(gltf_mat && gltf_mat->mDoubleSided ? GL_CULL_FACE : 0);
+
+ if (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ target_shader = pbr_shader;
+ if (params.mAvatar != nullptr)
{
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+ target_shader = target_shader->mRiggedVariant;
}
- }
- if(depth_only)
- {
- // when updating depth buffer, discard faces that are more than 90% transparent
- LLFace* face = params.mFace;
- if(face)
- {
- const LLTextureEntry* tep = face->getTextureEntry();
- if(tep)
- { // don't render faces that are more than 90% transparent
- if(tep->getColor().mV[3] < MINIMUM_IMPOSTOR_ALPHA)
- continue;
- }
- }
- }
+ // shader must be bound before LLGLTFMaterial::bind
+ if (current_shader != target_shader)
+ {
+ gPipeline.bindDeferredShaderFast(*target_shader);
+ }
- LLRenderPass::applyModelMatrix(params);
+ params.mGLTFMaterial->bind(params.mTexture);
+ }
+ else
+ {
+ mat = LLPipeline::sRenderingHUDs ? nullptr : params.mMaterial;
- LLMaterial* mat = NULL;
+ if (params.mFullbright)
+ {
+ // Turn off lighting if it hasn't already been so.
+ if (light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = fullbright_shader;
- if (deferred_render)
- {
- mat = params.mMaterial;
- }
-
- if (params.mFullbright)
- {
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = fullbright_shader;
-
- light_enabled = FALSE;
- }
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- target_shader = simple_shader;
- light_enabled = TRUE;
- }
+ light_enabled = FALSE;
+ }
+ }
+ // Turn on lighting if it isn't already.
+ else if (!light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ target_shader = simple_shader;
+ light_enabled = TRUE;
+ }
- if (deferred_render && mat)
- {
- U32 mask = params.mShaderMask;
+ if (LLPipeline::sRenderingHUDs)
+ {
+ target_shader = fullbright_shader;
+ }
+ else if (mat)
+ {
+ U32 mask = params.mShaderMask;
- llassert(mask < LLMaterial::SHADER_COUNT);
- target_shader = &(gDeferredMaterialProgram[mask]);
+ llassert(mask < LLMaterial::SHADER_COUNT);
+ target_shader = &(gDeferredMaterialProgram[mask]);
- if (LLPipeline::sUnderWaterRender)
- {
- target_shader = &(gDeferredMaterialWaterProgram[mask]);
- }
+ if (LLPipeline::sUnderWaterRender)
+ {
+ target_shader = &(gDeferredMaterialWaterProgram[mask]);
+ }
+ }
+ else if (!params.mFullbright)
+ {
+ target_shader = simple_shader;
+ }
+ else
+ {
+ target_shader = fullbright_shader;
+ }
if (params.mAvatar != nullptr)
{
@@ -689,55 +748,41 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
target_shader = target_shader->mRiggedVariant;
}
- if (current_shader != target_shader)
- {
- gPipeline.bindDeferredShader(*target_shader);
- }
- }
- else if (!params.mFullbright)
- {
- target_shader = simple_shader;
- }
- else
- {
- target_shader = fullbright_shader;
- }
-
- if (params.mAvatar != nullptr)
- {
- target_shader = target_shader->mRiggedVariant;
- }
+ if (current_shader != target_shader)
+ {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
+ // (this way we won't rebind shaders unnecessarily).
+ gPipeline.bindDeferredShaderFast(*target_shader);
- if (current_shader != target_shader)
- {// If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- target_shader->bind();
- }
+ if (params.mFullbright)
+ { // make sure the bind the exposure map for fullbright shaders so they can cancel out exposure
+ S32 channel = target_shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap);
+ }
+ }
+ }
- LLVector4 spec_color(1, 1, 1, 1);
- F32 env_intensity = 0.0f;
- F32 brightness = 1.0f;
+ LLVector4 spec_color(1, 1, 1, 1);
+ F32 env_intensity = 0.0f;
+ F32 brightness = 1.0f;
- // We have a material. Supply the appropriate data here.
- if (mat && deferred_render)
- {
- spec_color = params.mSpecColor;
- env_intensity = params.mEnvIntensity;
- brightness = params.mFullbright ? 1.f : 0.f;
- }
+ // We have a material. Supply the appropriate data here.
+ if (mat)
+ {
+ spec_color = params.mSpecColor;
+ env_intensity = params.mEnvIntensity;
+ brightness = params.mFullbright ? 1.f : 0.f;
+ }
- if (current_shader)
- {
- current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
- current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
- current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ if (current_shader)
+ {
+ current_shader->uniform4f(LLShaderMgr::SPECULAR_COLOR, spec_color.mV[0], spec_color.mV[1], spec_color.mV[2], spec_color.mV[3]);
+ current_shader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env_intensity);
+ current_shader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, brightness);
+ }
}
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
-
if (params.mAvatar != nullptr)
{
if (lastAvatar != params.mAvatar ||
@@ -757,8 +802,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
bool tex_setup = TexSetup(&params, (mat != nullptr));
{
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
-
gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
bool reset_minimum_alpha = false;
@@ -770,18 +813,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
reset_minimum_alpha = true;
}
- U32 drawMask = mask;
- if (params.mFullbright)
- {
- drawMask &= ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
- }
- if (params.mAvatar != nullptr)
- {
- drawMask |= LLVertexBuffer::MAP_WEIGHT4;
- }
-
- params.mVertexBuffer->setBufferFast(drawMask);
- params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
if (reset_minimum_alpha)
{
@@ -790,16 +823,30 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls is expensive, but glow must be drawn Z-sorted with alpha.
- if (draw_glow_for_this_partition &&
+ if (getType() != LLDrawPool::POOL_ALPHA_PRE_WATER &&
params.mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_EMISSIVE))
{
if (params.mAvatar != nullptr)
{
- rigged_emissives.push_back(&params);
+ if (params.mGLTFMaterial.isNull())
+ {
+ rigged_emissives.push_back(&params);
+ }
+ else
+ {
+ pbr_rigged_emissives.push_back(&params);
+ }
}
else
{
- emissives.push_back(&params);
+ if (params.mGLTFMaterial.isNull())
+ {
+ emissives.push_back(&params);
+ }
+ else
+ {
+ pbr_emissives.push_back(&params);
+ }
}
}
@@ -812,8 +859,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
}
}
- ratPtr.reset(); // force the final batch to terminate to avoid double counting on the subsidiary batches for FB and Emmissives
-
// render emissive faces into alpha channel for bloom effects
if (!depth_only)
{
@@ -828,14 +873,28 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
if (!emissives.empty())
{
light_enabled = true;
- renderEmissives(mask, emissives);
+ renderEmissives(emissives);
+ rebind = true;
+ }
+
+ if (!pbr_emissives.empty())
+ {
+ light_enabled = true;
+ renderPbrEmissives(pbr_emissives);
rebind = true;
}
if (!rigged_emissives.empty())
{
light_enabled = true;
- renderRiggedEmissives(mask, rigged_emissives);
+ renderRiggedEmissives(rigged_emissives);
+ rebind = true;
+ }
+
+ if (!pbr_rigged_emissives.empty())
+ {
+ light_enabled = true;
+ renderRiggedPbrEmissives(pbr_rigged_emissives);
rebind = true;
}
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index fa8ef0f227..820c4f4e68 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -35,9 +35,13 @@ class LLFace;
class LLColor4;
class LLGLSLShader;
-class LLDrawPoolAlpha: public LLRenderPass
+class LLDrawPoolAlpha final: public LLRenderPass
{
public:
+
+ // set by llsettingsvo so lldrawpoolalpha has quick access to the water plane in eye space
+ static LLVector4 sWaterPlane;
+
enum
{
VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
@@ -47,14 +51,13 @@ public:
};
virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
- LLDrawPoolAlpha(U32 type = LLDrawPool::POOL_ALPHA);
+ LLDrawPoolAlpha(U32 type);
/*virtual*/ ~LLDrawPoolAlpha();
/*virtual*/ S32 getNumPostDeferredPasses();
/*virtual*/ void renderPostDeferred(S32 pass);
/*virtual*/ S32 getNumPasses() { return 1; }
- virtual void render(S32 pass = 0);
void forwardRender(bool write_depth = false);
/*virtual*/ void prerender();
@@ -62,7 +65,7 @@ public:
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask, bool depth_only = false, bool rigged = false);
- void renderAlphaHighlight(U32 mask);
+ void renderAlphaHighlight();
bool uploadMatrixPalette(const LLDrawInfo& params);
static BOOL sShowDebugAlpha;
@@ -74,10 +77,14 @@ private:
LLGLSLShader* simple_shader = nullptr;
LLGLSLShader* fullbright_shader = nullptr;
LLGLSLShader* emissive_shader = nullptr;
-
- void drawEmissive(U32 mask, LLDrawInfo* draw);
- void renderEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
- void renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>& emissives);
+ LLGLSLShader* pbr_emissive_shader = nullptr;
+ LLGLSLShader* pbr_shader = nullptr;
+
+ void drawEmissive(LLDrawInfo* draw);
+ void renderEmissives(std::vector<LLDrawInfo*>& emissives);
+ void renderRiggedEmissives(std::vector<LLDrawInfo*>& emissives);
+ void renderPbrEmissives(std::vector<LLDrawInfo*>& emissives);
+ void renderRiggedPbrEmissives(std::vector<LLDrawInfo*>& emissives);
bool TexSetup(LLDrawInfo* draw, bool use_material);
void RestoreTexSetup(bool tex_setup);
@@ -91,11 +98,4 @@ private:
bool mRigged = false;
};
-class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
-{
-public:
- LLDrawPoolAlphaPostWater();
- virtual void render(S32 pass = 0);
-};
-
#endif // LL_LLDRAWPOOLALPHA_H
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 3160f693b2..342b76d93b 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -52,10 +52,7 @@
#include "llviewerpartsim.h"
#include "llviewercontrol.h" // for gSavedSettings
#include "llviewertexturelist.h"
-#include "llperfstats.h"
-static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK;
-static U32 sBufferUsage = GL_STREAM_DRAW_ARB;
static U32 sShaderLevel = 0;
LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL;
@@ -144,15 +141,6 @@ void LLDrawPoolAvatar::prerender()
mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR);
sShaderLevel = mShaderLevel;
-
- if (sShaderLevel > 0)
- {
- sBufferUsage = GL_DYNAMIC_DRAW_ARB;
- }
- else
- {
- sBufferUsage = GL_STREAM_DRAW_ARB;
- }
}
LLMatrix4& LLDrawPoolAvatar::getModelView()
@@ -381,10 +369,9 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
{
return;
}
- LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_SHADOWS);
- LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
- BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
+ LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+ BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
// no shadows if the shadows are causing this avatar to breach the limit.
if (avatarp->isTooSlow() || impostor || (oa == LLVOAvatar::AOA_INVISIBLE))
{
@@ -535,14 +522,6 @@ void LLDrawPoolAvatar::beginRigid()
{ //eyeballs render with the specular shader
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
}
}
else
@@ -601,14 +580,6 @@ void LLDrawPoolAvatar::beginDeferredRigid()
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
}
void LLDrawPoolAvatar::endDeferredRigid()
@@ -626,65 +597,14 @@ void LLDrawPoolAvatar::beginSkinned()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
- if (sShaderLevel > 0)
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gAvatarWaterProgram;
- sShaderLevel = llmin((U32) 1, sShaderLevel);
- }
- else
- {
- sVertexProgram = &gAvatarProgram;
- }
- }
- else
- {
- if (LLPipeline::sUnderWaterRender)
- {
- sVertexProgram = &gObjectAlphaMaskNoColorWaterProgram;
- }
- else
- {
- sVertexProgram = &gObjectAlphaMaskNoColorProgram;
- }
- }
+ // used for preview only
+
+ sVertexProgram = &gAvatarProgram;
- if (sShaderLevel > 0) // for hardware blending
- {
- sRenderingSkinned = TRUE;
-
- sVertexProgram->bind();
- sVertexProgram->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- gGL.getTexUnit(0)->activate();
- }
- else
- {
- if(gPipeline.shadersLoaded())
- {
- // software skinning, use a basic shader for windlight.
- // TODO: find a better fallback method for software skinning.
- sVertexProgram->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- }
+ sRenderingSkinned = TRUE;
- sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
+ sVertexProgram->bind();
+ sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
}
void LLDrawPoolAvatar::endSkinned()
@@ -723,15 +643,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
sVertexProgram->bind();
sVertexProgram->setMinimumAlpha(LLDrawPoolAvatar::sMinimumAlpha);
- if (LLPipeline::sRenderingHUDs)
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- sVertexProgram->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-
sDiffuseChannel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
gGL.getTexUnit(0)->activate();
}
@@ -758,7 +669,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
if (pass == -1)
{
for (S32 i = 1; i < getNumPasses(); i++)
- { //skip foot shadows
+ { //skip impostor pass
prerender();
beginRenderPass(i);
renderAvatars(single_avatar, i);
@@ -793,7 +704,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
{
return;
}
- LLPerfStats::RecordAvatarTime T(avatarp->getID(), LLPerfStats::StatType_t::RENDER_GEOMETRY);
if (!single_avatar && !avatarp->isFullyLoaded() )
{
@@ -937,11 +847,3 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
}
-LLVertexBufferAvatar::LLVertexBufferAvatar()
-: LLVertexBuffer(sDataMask,
- GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR
-}
-
-
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 21add39b21..ff78c6c60a 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -129,12 +129,6 @@ typedef enum
static LLGLSLShader* sVertexProgram;
};
-class LLVertexBufferAvatar : public LLVertexBuffer
-{
-public:
- LLVertexBufferAvatar();
-};
-
extern S32 AVATAR_OFFSET_POS;
extern S32 AVATAR_OFFSET_NORMAL;
extern S32 AVATAR_OFFSET_TEX0;
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index cc454417c6..a0ce0ef6cf 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -49,7 +49,6 @@
#include "llspatialpartition.h"
#include "llviewershadermgr.h"
#include "llmodel.h"
-#include "llperfstats.h"
//#include "llimagebmp.h"
//#include "../tools/imdebug/imdebug.h"
@@ -78,6 +77,7 @@ static LLGLSLShader* shader = NULL;
static S32 cube_channel = -1;
static S32 diffuse_channel = -1;
static S32 bump_channel = -1;
+static BOOL shiny = FALSE;
// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an
// LLAtomicBool; this should work just fine, now. HB
@@ -198,7 +198,7 @@ void LLStandardBumpmap::destroyGL()
LLDrawPoolBump::LLDrawPoolBump()
: LLRenderPass(LLDrawPool::POOL_BUMP)
{
- mShiny = FALSE;
+ shiny = FALSE;
}
@@ -213,96 +213,12 @@ S32 LLDrawPoolBump::numBumpPasses()
return 1;
}
-S32 LLDrawPoolBump::getNumPasses()
-{
- return numBumpPasses();
-}
-
-void LLDrawPoolBump::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
-
- if (!gPipeline.hasRenderType(LLDrawPool::POOL_SIMPLE))
- {
- return;
- }
-
- for (int i = 0; i < 2; ++i)
- {
- mRigged = i == 1;
-
- // first pass -- shiny
- beginShiny();
- renderShiny();
- endShiny();
-
- //second pass -- fullbright shiny
- if (mShaderLevel > 1)
- {
- beginFullbrightShiny();
- renderFullbrightShiny();
- endFullbrightShiny();
- }
-
- //third pass -- bump
- beginBump();
- renderBump(LLRenderPass::PASS_BUMP);
- endBump();
- }
-}
-
-
-//static
-void LLDrawPoolBump::beginShiny()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
-
- mShiny = TRUE;
- sVertexMask = VERTEX_MASK_SHINY;
- // Second pass: environment map
- if (mShaderLevel > 1)
- {
- sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
- }
-
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectShinyWaterProgram;
- }
- else
- {
- shader = &gObjectShinyProgram;
- }
-
- if (mRigged)
- {
- llassert(shader->mRiggedVariant);
- shader = shader->mRiggedVariant;
- }
-
- shader->bind();
- if (LLPipeline::sRenderingHUDs)
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-
- bindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
-
- if (mShaderLevel > 1)
- { //indexed texture rendering, channel 0 is always diffuse
- diffuse_channel = 0;
- }
-}
//static
void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map )
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled )
{
if (shader )
{
@@ -345,43 +261,11 @@ void LLDrawPoolBump::bindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& di
}
}
-void LLDrawPoolBump::renderShiny()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
-
- if( gSky.mVOSkyp->getCubeMap() )
- {
- LLGLEnable blend_enable(GL_BLEND);
- if (mShaderLevel > 1)
- {
- if (mRigged)
- {
- LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
- else
- {
- LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- }
- }
- else
- {
- if (mRigged)
- {
- gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE);
- }
- else
- {
- gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE);
- }
- }
- }
-}
-
//static
void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32& diffuse_channel, S32& cube_channel)
{
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map )
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled)
{
if (shader_level > 1)
{
@@ -402,21 +286,6 @@ void LLDrawPoolBump::unbindCubeMap(LLGLSLShader* shader, S32 shader_level, S32&
}
}
-void LLDrawPoolBump::endShiny()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
-
- unbindCubeMap(shader, mShaderLevel, diffuse_channel, cube_channel);
- if (shader)
- {
- shader->unbind();
- }
-
- diffuse_channel = -1;
- cube_channel = 0;
- mShiny = FALSE;
-}
-
void LLDrawPoolBump::beginFullbrightShiny()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
@@ -424,31 +293,40 @@ void LLDrawPoolBump::beginFullbrightShiny()
sVertexMask = VERTEX_MASK_SHINY | LLVertexBuffer::MAP_TEXCOORD0;
// Second pass: environment map
-
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectFullbrightShinyWaterProgram;
- }
- else
- {
- if (LLPipeline::sRenderDeferred)
- {
- shader = &gDeferredFullbrightShinyProgram;
- }
- else
- {
- shader = &gObjectFullbrightShinyProgram;
- }
- }
-
+ shader = &gDeferredFullbrightShinyProgram;
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader = &gHUDFullbrightShinyProgram;
+ }
+
if (mRigged)
{
llassert(shader->mRiggedVariant);
shader = shader->mRiggedVariant;
}
+ // bind exposure map so fullbright shader can cancel out exposure
+ S32 channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap);
+ }
+
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map )
+
+ if (cube_map && !LLPipeline::sReflectionProbesEnabled)
+ {
+ // Make sure that texture coord generation happens for tex unit 1, as that's the one we use for
+ // the cube map in the one pass shiny shaders
+ gGL.getTexUnit(1)->disable();
+ cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ cube_map->enableTexture(cube_channel);
+ diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+
+ gGL.getTexUnit(cube_channel)->bind(cube_map);
+ gGL.getTexUnit(0)->activate();
+ }
+
{
LLMatrix4 mat;
mat.initRows(LLVector4(gGLModelView+0),
@@ -456,29 +334,19 @@ void LLDrawPoolBump::beginFullbrightShiny()
LLVector4(gGLModelView+8),
LLVector4(gGLModelView+12));
shader->bind();
- if (LLPipeline::sRenderingHUDs)
+
+ LLVector3 vec = LLVector3(gShinyOrigin) * mat;
+ LLVector4 vec4(vec, gShinyOrigin.mV[3]);
+ shader->uniform4fv(LLViewerShaderMgr::SHINY_ORIGIN, 1, vec4.mV);
+
+ if (LLPipeline::sReflectionProbesEnabled)
{
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
+ gPipeline.bindReflectionProbes(*shader);
}
else
{
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
+ gPipeline.setEnvMat(*shader);
}
-
- LLVector3 vec = LLVector3(gShinyOrigin) * mat;
- LLVector4 vec4(vec, gShinyOrigin.mV[3]);
- shader->uniform4fv(LLViewerShaderMgr::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
- gGL.getTexUnit(1)->disable();
- cube_channel = shader->enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- cube_map->enableTexture(cube_channel);
- diffuse_channel = shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
-
- gGL.getTexUnit(cube_channel)->bind(cube_map);
- gGL.getTexUnit(0)->activate();
}
if (mShaderLevel > 1)
@@ -486,14 +354,13 @@ void LLDrawPoolBump::beginFullbrightShiny()
diffuse_channel = 0;
}
- mShiny = TRUE;
+ shiny = TRUE;
}
void LLDrawPoolBump::renderFullbrightShiny()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
- if( gSky.mVOSkyp->getCubeMap() )
{
LLGLEnable blend_enable(GL_BLEND);
@@ -501,22 +368,22 @@ void LLDrawPoolBump::renderFullbrightShiny()
{
if (mRigged)
{
- LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, true, true);
}
else
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, true, true);
}
}
else
{
if (mRigged)
{
- LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask);
+ LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED);
}
else
{
- LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask);
+ LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY);
}
}
}
@@ -527,43 +394,33 @@ void LLDrawPoolBump::endFullbrightShiny()
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SHINY);
LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if( cube_map )
+ if( cube_map && !LLPipeline::sReflectionProbesEnabled )
{
cube_map->disable();
- cube_map->restoreMatrix();
+ if (shader->mFeatures.hasReflectionProbes)
+ {
+ gPipeline.unbindReflectionProbes(*shader);
+ }
shader->unbind();
}
diffuse_channel = -1;
cube_channel = 0;
- mShiny = FALSE;
+ shiny = FALSE;
}
-void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE)
+void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true)
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
-
applyModelMatrix(params);
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
- params.mVertexBuffer->setBuffer(mask);
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
@@ -573,7 +430,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
{
U8 bump_code = params.mBump;
- return bindBumpMap(bump_code, params.mTexture, params.mVSize, channel);
+ return bindBumpMap(bump_code, params.mTexture, channel);
}
//static
@@ -583,14 +440,14 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel)
if (te)
{
U8 bump_code = te->getBumpmap();
- return bindBumpMap(bump_code, face->getTexture(), face->getVirtualSize(), channel);
+ return bindBumpMap(bump_code, face->getTexture(), channel);
}
return FALSE;
}
//static
-BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel)
+BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
//Note: texture atlas does not support bump texture now.
@@ -616,7 +473,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi
if( bump_code < LLStandardBumpmap::sStandardBumpmapCount )
{
bump = gStandardBumpmapList[bump_code].mImage;
- gBumpImageList.addTextureStats(bump_code, tex->getID(), vsize);
+ gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize());
}
break;
}
@@ -666,41 +523,33 @@ void LLDrawPoolBump::beginBump()
void LLDrawPoolBump::renderBump(U32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- LLGLDisable fog(GL_FOG);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
LLGLEnable blend(GL_BLEND);
gGL.diffuseColor4f(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(pass, sVertexMask);
+ pushBumpBatches(pass);
}
//static
void LLDrawPoolBump::endBump(U32 pass)
{
- gObjectBumpProgram.unbind();
+ LLGLSLShader::unbind();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
S32 LLDrawPoolBump::getNumDeferredPasses()
{
- if (gSavedSettings.getBOOL("RenderObjectBump"))
- {
- return 1;
- }
- else
- {
- return 0;
- }
+ return 1;
}
void LLDrawPoolBump::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_BUMP);
- mShiny = TRUE;
+ shiny = TRUE;
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
@@ -714,25 +563,14 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR;
-
LLVOAvatar* avatar = nullptr;
U64 skin = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo& params = **i;
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if(vobj && vobj->isAttachment())
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
+ LLCullResult::increment_iterator(i, end);
LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(params.mAlphaMaskCutoff);
LLDrawPoolBump::bindBumpMap(params, bump_channel);
@@ -745,11 +583,11 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
avatar = params.mAvatar;
skin = params.mSkinInfo->mHash;
}
- pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE);
+ pushBumpBatch(params, true, false);
}
else
{
- pushBatch(params, mask, TRUE, FALSE);
+ pushBumpBatch(params, true, false);
}
}
@@ -759,13 +597,17 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
gGL.getTexUnit(0)->activate();
}
- mShiny = FALSE;
+ shiny = FALSE;
}
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
- for (int i = 0; i < 2; ++i)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+
+ S32 num_passes = LLPipeline::sRenderingHUDs ? 1 : 2; // skip rigged pass when rendering HUDs
+
+ for (int i = 0; i < num_passes; ++i)
{ // two passes -- static and rigged
mRigged = (i == 1);
@@ -1208,7 +1050,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
bump->setExplicitFormat(GL_ALPHA8, GL_ALPHA);
#if LL_BUMPLIST_MULTITHREADED
- auto tex_queue = LLImageGLThread::sEnabled ? sTexUpdateQueue.lock() : nullptr;
+ auto tex_queue = LLImageGLThread::sEnabledTextures ? sTexUpdateQueue.lock() : nullptr;
if (tex_queue)
{ //dispatch creation to background thread
@@ -1320,7 +1162,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
};
#if LL_BUMPLIST_MULTITHREADED
- auto main_queue = LLImageGLThread::sEnabled ? sMainQueue.lock() : nullptr;
+ auto main_queue = LLImageGLThread::sEnabledTextures ? sMainQueue.lock() : nullptr;
if (main_queue)
{ //dispatch texture upload to background thread, issue GPU commands to generate normal map on main thread
@@ -1345,7 +1187,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI
}
}
-void LLDrawPoolBump::renderBump(U32 type, U32 mask)
+void LLDrawPoolBump::pushBumpBatches(U32 type)
{
LLVOAvatar* avatar = nullptr;
U64 skin = 0;
@@ -1353,27 +1195,15 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
if (mRigged)
{ // nudge type enum and include skinweights for rigged pass
type += 1;
- mask |= LLVertexBuffer::MAP_WEIGHT4;
}
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
{
LLDrawInfo& params = **i;
- if(params.mFace)
- {
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
-
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
- }
- }
-
if (LLDrawPoolBump::bindBumpMap(params))
{
if (mRigged)
@@ -1391,12 +1221,12 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask)
}
}
}
- pushBatch(params, mask, FALSE);
+ pushBumpBatch(params, false);
}
}
}
-void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
+void LLRenderPass::pushBumpBatch(LLDrawInfo& params, bool texture, bool batch_textures)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
applyModelMatrix(params);
@@ -1417,7 +1247,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
{ //not batching textures or batch has only 1 texture -- might need a texture matrix
if (params.mTextureMatrix)
{
- if (mShiny)
+ if (shiny)
{
gGL.getTexUnit(0)->activate();
gGL.matrixMode(LLRender::MM_TEXTURE);
@@ -1436,7 +1266,7 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
tex_setup = true;
}
- if (mShiny && mShaderLevel > 1 && texture)
+ if (shiny && mShaderLevel > 1 && texture)
{
if (params.mTexture.notNull())
{
@@ -1449,16 +1279,12 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
}
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
- params.mVertexBuffer->setBufferFast(mask);
- params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
if (tex_setup)
{
- if (mShiny)
+ if (shiny)
{
gGL.getTexUnit(0)->activate();
}
@@ -1472,24 +1298,3 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL
}
}
-void LLDrawPoolInvisible::render(S32 pass)
-{ //render invisiprims
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_INVISIBLE);
-
- if (gPipeline.shadersLoaded())
- {
- gOcclusionProgram.bind();
- }
-
- U32 invisi_mask = LLVertexBuffer::MAP_VERTEX;
- glStencilMask(0);
- gGL.setColorMask(false, false);
- pushBatches(LLRenderPass::PASS_INVISIBLE, invisi_mask, FALSE);
- gGL.setColorMask(true, false);
- glStencilMask(0xFFFFFFFF);
-
- if (gPipeline.shadersLoaded())
- {
- gOcclusionProgram.unbind();
- }
-}
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index cf463f4458..b1fe454c72 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -52,20 +52,13 @@ public:
LLDrawPoolBump();
- virtual void render(S32 pass = 0) override;
- virtual S32 getNumPasses() override;
/*virtual*/ void prerender() override;
- void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override;
- void renderBump(U32 type, U32 mask);
- void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) override;
+ void pushBumpBatches(U32 type);
+ void renderGroup(LLSpatialGroup* group, U32 type, bool texture) override;
S32 numBumpPasses();
- void beginShiny();
- void renderShiny();
- void endShiny();
-
void beginFullbrightShiny();
void renderFullbrightShiny();
void endFullbrightShiny();
@@ -87,7 +80,7 @@ public:
static BOOL bindBumpMap(LLFace* face, S32 channel = -2);
private:
- static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel);
+ static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, S32 channel);
bool mRigged = false; // if true, doing a rigged pass
};
@@ -167,25 +160,4 @@ private:
extern LLBumpImageList gBumpImageList;
-class LLDrawPoolInvisible : public LLRenderPass
-{
-public:
- LLDrawPoolInvisible() : LLRenderPass(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/lldrawpoolground.cpp b/indra/newview/lldrawpoolground.cpp
deleted file mode 100644
index 5b74264dab..0000000000
--- a/indra/newview/lldrawpoolground.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @file lldrawpoolground.cpp
- * @brief LLDrawPoolGround class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lldrawpoolground.h"
-
-#include "llviewercontrol.h"
-
-#include "lldrawable.h"
-#include "llface.h"
-#include "llsky.h"
-#include "llviewercamera.h"
-#include "llviewerwindow.h"
-#include "llworld.h"
-#include "pipeline.h"
-#include "llagent.h"
-#include "llviewerregion.h"
-#include "llviewershadermgr.h"
-
-LLDrawPoolGround::LLDrawPoolGround() :
- LLFacePool(POOL_GROUND)
-{
-}
-
-void LLDrawPoolGround::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
-}
-
-void LLDrawPoolGround::render(S32 pass)
-{
- if (mDrawFace.empty() || !gSavedSettings.getBOOL("RenderGround"))
- {
- return;
- }
-
- LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- F32 water_height = gAgent.getRegion()->getWaterHeight();
- gGL.pushMatrix();
- LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.translatef(origin.mV[0], origin.mV[1], llmax(origin.mV[2], water_height));
-
- LLFace *facep = mDrawFace[0];
-
- LLOverrideFaceColor col(this, gSky.mVOSkyp->getGLFogColor());
- facep->renderIndexed();
-
- gGL.popMatrix();
-}
-
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index f2408a3294..6a7e05ac74 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -32,9 +32,6 @@
#include "pipeline.h"
#include "llglcommonfunc.h"
#include "llvoavatar.h"
-#include "llperfstats.h"
-
-S32 diffuse_channel = -1;
LLDrawPoolMaterials::LLDrawPoolMaterials()
: LLRenderPass(LLDrawPool::POOL_MATERIALS)
@@ -99,18 +96,8 @@ void LLDrawPoolMaterials::beginDeferredPass(S32 pass)
llassert(mShader->mRiggedVariant != nullptr);
mShader = mShader->mRiggedVariant;
}
- mShader->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- mShader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- mShader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- diffuse_channel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ gPipeline.bindDeferredShader(*mShader);
}
void LLDrawPoolMaterials::endDeferredPass(S32 pass)
@@ -160,128 +147,160 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass)
type += 1;
}
- U32 mask = mShader->mAttributeMask;
-
LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type);
LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type);
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i)
+ F32 lastIntensity = 0.f;
+ F32 lastFullbright = 0.f;
+ F32 lastMinimumAlpha = 0.f;
+ LLVector4 lastSpecular = LLVector4(0, 0, 0, 0);
+
+ GLint intensity = mShader->getUniformLocation(LLShaderMgr::ENVIRONMENT_INTENSITY);
+ GLint brightness = mShader->getUniformLocation(LLShaderMgr::EMISSIVE_BRIGHTNESS);
+ GLint minAlpha = mShader->getUniformLocation(LLShaderMgr::MINIMUM_ALPHA);
+ GLint specular = mShader->getUniformLocation(LLShaderMgr::SPECULAR_COLOR);
+
+ GLint diffuseChannel = mShader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ GLint specChannel = mShader->enableTexture(LLShaderMgr::SPECULAR_MAP);
+ GLint normChannel = mShader->enableTexture(LLShaderMgr::BUMP_MAP);
+
+ LLTexture* lastNormalMap = nullptr;
+ LLTexture* lastSpecMap = nullptr;
+ LLTexture* lastDiffuse = nullptr;
+
+ gGL.getTexUnit(diffuseChannel)->unbindFast(LLTexUnit::TT_TEXTURE);
+
+ if (intensity > -1)
+ {
+ glUniform1f(intensity, lastIntensity);
+ }
+
+ if (brightness > -1)
+ {
+ glUniform1f(brightness, lastFullbright);
+ }
+
+ if (minAlpha > -1)
+ {
+ glUniform1f(minAlpha, lastMinimumAlpha);
+ }
+
+ if (specular > -1)
+ {
+ glUniform4fv(specular, 1, lastSpecular.mV);
+ }
+
+ LLVOAvatar* lastAvatar = nullptr;
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_MATERIAL("materials draw loop");
LLDrawInfo& params = **i;
+
+ LLCullResult::increment_iterator(i, end);
+
+ if (specular > -1 && params.mSpecColor != lastSpecular)
+ {
+ lastSpecular = params.mSpecColor;
+ glUniform4fv(specular, 1, lastSpecular.mV);
+ }
- if(params.mFace)
+ if (intensity != -1 && lastIntensity != params.mEnvIntensity)
{
- LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
+ lastIntensity = params.mEnvIntensity;
+ glUniform1f(intensity, lastIntensity);
+ }
+
+ if (minAlpha > -1 && lastMinimumAlpha != params.mAlphaMaskCutoff)
+ {
+ lastMinimumAlpha = params.mAlphaMaskCutoff;
+ glUniform1f(minAlpha, lastMinimumAlpha);
+ }
+
+ F32 fullbright = params.mFullbright ? 1.f : 0.f;
+ if (brightness > -1 && lastFullbright != fullbright)
+ {
+ lastFullbright = fullbright;
+ glUniform1f(brightness, lastFullbright);
+ }
- if( vobj && vobj->isAttachment() )
+ if (normChannel > -1 && params.mNormalMap != lastNormalMap)
+ {
+ lastNormalMap = params.mNormalMap;
+ llassert(lastNormalMap);
+ gGL.getTexUnit(normChannel)->bindFast(lastNormalMap);
+ }
+
+ if (specChannel > -1 && params.mSpecularMap != lastSpecMap)
+ {
+ lastSpecMap = params.mSpecularMap;
+ llassert(lastSpecMap);
+ gGL.getTexUnit(specChannel)->bindFast(lastSpecMap);
+ }
+
+ if (params.mTexture != lastDiffuse)
+ {
+ lastDiffuse = params.mTexture;
+ if (lastDiffuse)
+ {
+ gGL.getTexUnit(diffuseChannel)->bindFast(lastDiffuse);
+ }
+ else
{
- trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
+ gGL.getTexUnit(diffuseChannel)->unbindFast(LLTexUnit::TT_TEXTURE);
}
}
-
- mShader->uniform4f(LLShaderMgr::SPECULAR_COLOR, params.mSpecColor.mV[0], params.mSpecColor.mV[1], params.mSpecColor.mV[2], params.mSpecColor.mV[3]);
- mShader->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, params.mEnvIntensity);
-
- if (params.mNormalMap)
- {
- params.mNormalMap->addTextureStats(params.mVSize);
- bindNormalMap(params.mNormalMap);
- }
-
- if (params.mSpecularMap)
- {
- params.mSpecularMap->addTextureStats(params.mVSize);
- bindSpecularMap(params.mSpecularMap);
- }
-
- mShader->setMinimumAlpha(params.mAlphaMaskCutoff);
- mShader->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, params.mFullbright ? 1.f : 0.f);
+ // upload matrix palette to shader
+ if (rigged && params.mAvatar.notNull())
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL;
- pushMaterialsBatch(params, mask, rigged);
+ if (params.mAvatar != lastAvatar)
+ {
+ const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo);
+ U32 count = mpc.mMatrixPalette.size();
+
+ if (count == 0)
+ {
+ //skin info not loaded yet, don't render
+ return;
+ }
+
+ mShader->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
+ count,
+ FALSE,
+ (GLfloat*)&(mpc.mGLMp[0]));
+ }
}
- }
-}
-void LLDrawPoolMaterials::bindSpecularMap(LLViewerTexture* tex)
-{
- mShader->bindTexture(LLShaderMgr::SPECULAR_MAP, tex);
-}
+ applyModelMatrix(params);
-void LLDrawPoolMaterials::bindNormalMap(LLViewerTexture* tex)
-{
- mShader->bindTexture(LLShaderMgr::BUMP_MAP, tex);
-}
+ bool tex_setup = false;
-void LLDrawPoolMaterials::pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_MATERIAL;
- applyModelMatrix(params);
-
- bool tex_setup = false;
-
- //not batching textures or batch has only 1 texture -- might need a texture matrix
- if (params.mTextureMatrix)
- {
- //if (mShiny)
- {
- gGL.getTexUnit(0)->activate();
- gGL.matrixMode(LLRender::MM_TEXTURE);
- }
-
- gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
-
- tex_setup = true;
- }
-
- if (mShaderLevel > 1)
- {
- if (params.mTexture.notNull())
- {
- gGL.getTexUnit(diffuse_channel)->bindFast(params.mTexture);
- }
- else
- {
- gGL.getTexUnit(diffuse_channel)->unbindFast(LLTexUnit::TT_TEXTURE);
- }
- }
-
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
+ //not batching textures or batch has only 1 texture -- might need a texture matrix
+ if (params.mTextureMatrix)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.matrixMode(LLRender::MM_TEXTURE);
- // upload matrix palette to shader
- if (rigged && params.mAvatar.notNull())
- {
- const LLVOAvatar::MatrixPaletteCache& mpc = params.mAvatar->updateSkinInfoMatrixPalette(params.mSkinInfo);
- U32 count = mpc.mMatrixPalette.size();
+ gGL.loadMatrix((GLfloat*)params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
- if (count == 0)
- {
- //skin info not loaded yet, don't render
- return;
+ tex_setup = true;
}
- mShader->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX,
- count,
- FALSE,
- (GLfloat*)&(mpc.mGLMp[0]));
- }
-
- LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+ /*if (params.mGroup) // TOO LATE
+ {
+ params.mGroup->rebuildMesh();
+ }*/
- params.mVertexBuffer->setBufferFast(mask);
- params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ params.mVertexBuffer->setBuffer();
+ params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset);
- if (tex_setup)
- {
- gGL.getTexUnit(0)->activate();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ if (tex_setup)
+ {
+ gGL.getTexUnit(0)->activate();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ }
}
}
-
diff --git a/indra/newview/lldrawpoolmaterials.h b/indra/newview/lldrawpoolmaterials.h
index 8a3ad923df..c46c053bd0 100644
--- a/indra/newview/lldrawpoolmaterials.h
+++ b/indra/newview/lldrawpoolmaterials.h
@@ -65,11 +65,6 @@ public:
void beginDeferredPass(S32 pass) override;
void endDeferredPass(S32 pass) override;
void renderDeferred(S32 pass) override;
-
- void bindSpecularMap(LLViewerTexture* tex);
- void bindNormalMap(LLViewerTexture* tex);
-
- void pushMaterialsBatch(LLDrawInfo& params, U32 mask, bool rigged);
};
#endif //LL_LLDRAWPOOLMATERIALS_H
diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp
new file mode 100644
index 0000000000..86b790e2c5
--- /dev/null
+++ b/indra/newview/lldrawpoolpbropaque.cpp
@@ -0,0 +1,87 @@
+/**
+ * @file lldrawpoolpbropaque.cpp
+ * @brief LLDrawPoolGLTFPBR class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldrawpool.h"
+#include "lldrawpoolpbropaque.h"
+#include "llviewershadermgr.h"
+#include "pipeline.h"
+
+LLDrawPoolGLTFPBR::LLDrawPoolGLTFPBR(U32 type) :
+ LLRenderPass(type)
+{
+ if (type == LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK)
+ {
+ mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK;
+ }
+ else
+ {
+ mRenderType = LLPipeline::RENDER_TYPE_PASS_GLTF_PBR;
+ }
+}
+
+S32 LLDrawPoolGLTFPBR::getNumDeferredPasses()
+{
+ return 1;
+}
+
+void LLDrawPoolGLTFPBR::renderDeferred(S32 pass)
+{
+ llassert(!LLPipeline::sRenderingHUDs);
+
+ gDeferredPBROpaqueProgram.bind();
+ pushGLTFBatches(mRenderType);
+
+ gDeferredPBROpaqueProgram.bind(true);
+ pushRiggedGLTFBatches(mRenderType + 1);
+}
+
+S32 LLDrawPoolGLTFPBR::getNumPostDeferredPasses()
+{
+ return 1;
+}
+
+void LLDrawPoolGLTFPBR::renderPostDeferred(S32 pass)
+{
+ if (LLPipeline::sRenderingHUDs)
+ {
+ gHUDPBROpaqueProgram.bind();
+ pushGLTFBatches(mRenderType);
+ }
+ else if (mRenderType == LLPipeline::RENDER_TYPE_PASS_GLTF_PBR) // HACK -- don't render glow except for the non-alpha masked implementation
+ {
+ gGL.setColorMask(false, true);
+ gPBRGlowProgram.bind();
+ pushGLTFBatches(LLRenderPass::PASS_GLTF_GLOW);
+
+ gPBRGlowProgram.bind(true);
+ pushRiggedGLTFBatches(LLRenderPass::PASS_GLTF_GLOW_RIGGED);
+
+ gGL.setColorMask(true, false);
+ }
+}
+
diff --git a/indra/newview/lldrawpoolground.h b/indra/newview/lldrawpoolpbropaque.h
index 15b1dc60a2..c8a28461fa 100644
--- a/indra/newview/lldrawpoolground.h
+++ b/indra/newview/lldrawpoolpbropaque.h
@@ -1,10 +1,10 @@
/**
- * @file lldrawpoolground.h
- * @brief LLDrawPoolGround class definition
+ * @file lldrawpoolpbropaque.h
+ * @brief LLDrawPoolPBrOpaque class definition
*
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -24,27 +24,23 @@
* $/LicenseInfo$
*/
-#ifndef LL_LLDRAWPOOLGROUND_H
-#define LL_LLDRAWPOOLGROUND_H
+#ifndef LL_LLDRAWPOOLPBROPAQUE_H
+#define LL_LLDRAWPOOLPBROPAQUE_H
#include "lldrawpool.h"
-
-class LLDrawPoolGround : public LLFacePool
+class LLDrawPoolGLTFPBR final : public LLRenderPass
{
public:
- enum
- {
- VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0
- };
+ LLDrawPoolGLTFPBR(U32 type = LLDrawPool::POOL_GLTF_PBR);
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 mRenderType = 0;
- LLDrawPoolGround();
+ S32 getNumDeferredPasses() override;
+ void renderDeferred(S32 pass) override;
- /*virtual*/ void prerender();
- /*virtual*/ void render(S32 pass = 0);
+ S32 getNumPostDeferredPasses() override;
+ void renderPostDeferred(S32 pass) override;
};
-#endif // LL_LLDRAWPOOLGROUND_H
+#endif // LL_LLDRAWPOOLPBROPAQUE_H
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index e324a663f4..a89c9d4561 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -37,8 +37,6 @@
#include "llviewershadermgr.h"
#include "llrender.h"
-static LLGLSLShader* simple_shader = NULL;
-
static LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE_DEFERRED("Deferred Simple");
static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass");
@@ -46,15 +44,6 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS_DEFERRED("Deferred Grass")
static void setup_simple_shader(LLGLSLShader* shader)
{
shader->bind();
-
- if (LLPipeline::sRenderingHUDs)
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
}
static void setup_glow_shader(LLGLSLShader* shader)
@@ -73,21 +62,23 @@ static void setup_glow_shader(LLGLSLShader* shader)
static void setup_fullbright_shader(LLGLSLShader* shader)
{
setup_glow_shader(shader);
+
+ S32 channel = shader->enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&gPipeline.mExposureMap);
+ }
+
shader->uniform1f(LLViewerShaderMgr::FULLBRIGHT, 1.f);
}
void LLDrawPoolGlow::renderPostDeferred(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
- render(&gDeferredEmissiveProgram);
-}
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LLGLSLShader* shader = &gDeferredEmissiveProgram;
-void LLDrawPoolGlow::render(LLGLSLShader* shader)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GLOW);
LLGLEnable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
gGL.flush();
/// Get rid of z-fighting with non-glow pass.
LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
@@ -99,106 +90,22 @@ void LLDrawPoolGlow::render(LLGLSLShader* shader)
//first pass -- static objects
setup_glow_shader(shader);
- pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_GLOW, true, true);
// second pass -- rigged objects
shader = shader->mRiggedVariant;
setup_glow_shader(shader);
- pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, true, true);
gGL.setColorMask(true, false);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
-S32 LLDrawPoolGlow::getNumPasses()
-{
- return 1;
-}
-
-void LLDrawPoolGlow::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLGLSLShader* shader = LLPipeline::sUnderWaterRender ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
- render(shader);
-}
-
LLDrawPoolSimple::LLDrawPoolSimple() :
LLRenderPass(POOL_SIMPLE)
{
}
-void LLDrawPoolSimple::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-S32 LLDrawPoolSimple::getNumPasses()
-{
- return 1;
-}
-
-void LLDrawPoolSimple::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE);
-
- LLGLDisable blend(GL_BLEND);
-
- LLGLSLShader* shader = nullptr;
- if (LLPipeline::sImpostorRender)
- {
- shader = &gObjectSimpleImpostorProgram;
- }
- else if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleWaterProgram;
- }
- else
- {
- shader = &gObjectSimpleProgram;
- }
-
- { //render simple
-
- gPipeline.enableLightsDynamic();
-
- U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX;
-
- // first pass -- static objects
- {
- setup_simple_shader(shader);
- pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE);
-
- if (LLPipeline::sRenderDeferred)
- { //if deferred rendering is enabled, bump faces aren't registered as simple
- //render bump faces here as simple so bump faces will appear under water
- pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE);
- }
- }
-
- //second pass, rigged
- {
- shader = shader->mRiggedVariant;
- setup_simple_shader(shader);
- pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE);
-
- if (LLPipeline::sRenderDeferred)
- { //if deferred rendering is enabled, bump faces aren't registered as simple
- //render bump faces here as simple so bump faces will appear under water
- pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, mask, TRUE, TRUE);
- }
- }
- }
-}
-
-
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK("Alpha Mask");
LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
@@ -206,76 +113,11 @@ LLDrawPoolAlphaMask::LLDrawPoolAlphaMask() :
{
}
-void LLDrawPoolAlphaMask::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-void LLDrawPoolAlphaMask::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLGLDisable blend(GL_BLEND);
-
- LLGLSLShader* shader = nullptr;
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleWaterAlphaMaskProgram;
- }
- else
- {
- shader = &gObjectSimpleAlphaMaskProgram;
- }
-
- // render static
- setup_simple_shader(shader);
- pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-
- // render rigged
- setup_simple_shader(shader->mRiggedVariant);
- pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
- pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-}
-
LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() :
LLRenderPass(POOL_FULLBRIGHT_ALPHA_MASK)
{
}
-void LLDrawPoolFullbrightAlphaMask::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-void LLDrawPoolFullbrightAlphaMask::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK);
-
- LLGLSLShader* shader = nullptr;
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectFullbrightWaterAlphaMaskProgram;
- }
- else
- {
- shader = &gObjectFullbrightAlphaMaskProgram;
- }
-
- // render static
- setup_fullbright_shader(shader);
- pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-
- // render rigged
- setup_fullbright_shader(shader->mRiggedVariant);
- pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
-}
-
//===============================
//DEFERRED IMPLEMENTATION
//===============================
@@ -289,15 +131,14 @@ void LLDrawPoolSimple::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_SIMPLE_DEFERRED);
LLGLDisable blend(GL_BLEND);
- LLGLDisable alpha_test(GL_ALPHA_TEST);
//render static
setup_simple_shader(&gDeferredDiffuseProgram);
- pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_SIMPLE, true, true);
//render rigged
setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant);
- pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, true, true);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask");
@@ -310,11 +151,11 @@ void LLDrawPoolAlphaMask::renderDeferred(S32 pass)
//render static
setup_simple_shader(shader);
- pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, true, true);
//render rigged
setup_simple_shader(shader->mRiggedVariant);
- pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE);
+ pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, true, true);
}
// grass drawpool
@@ -324,102 +165,13 @@ LLDrawPoolGrass::LLDrawPoolGrass() :
}
-void LLDrawPoolGrass::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-
-void LLDrawPoolGrass::beginRenderPass(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);
- stop_glerror();
-
- if (LLPipeline::sUnderWaterRender)
- {
- simple_shader = &gObjectAlphaMaskNonIndexedWaterProgram;
- }
- else
- {
- simple_shader = &gObjectAlphaMaskNonIndexedProgram;
- }
-
- if (mShaderLevel > 0)
- {
- simple_shader->bind();
- simple_shader->setMinimumAlpha(0.5f);
- if (LLPipeline::sRenderingHUDs)
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- simple_shader->uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
- }
- else
- {
- gGL.flush();
- LLGLSLShader::bindNoShader();
- }
-}
-
-void LLDrawPoolGrass::endRenderPass(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);
- LLRenderPass::endRenderPass(pass);
-
- if (mShaderLevel > 0)
- {
- simple_shader->unbind();
- }
- else
- {
- gGL.flush();
- }
-}
-
-void LLDrawPoolGrass::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLGLDisable blend(GL_BLEND);
-
- {
- //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS);
- LLGLEnable test(GL_ALPHA_TEST);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- //render grass
- LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());
- }
-}
-
-void LLDrawPoolGrass::beginDeferredPass(S32 pass)
-{
-
-}
-
-void LLDrawPoolGrass::endDeferredPass(S32 pass)
-{
-
-}
-
void LLDrawPoolGrass::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
{
- //LL_RECORD_BLOCK_TIME(FTM_RENDER_GRASS_DEFERRED);
gDeferredNonIndexedDiffuseAlphaMaskProgram.bind();
gDeferredNonIndexedDiffuseAlphaMaskProgram.setMinimumAlpha(0.5f);
- if (LLPipeline::sRenderingHUDs)
- {
- gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 1);
- }
- else
- {
- gDeferredNonIndexedDiffuseAlphaMaskProgram.uniform1i(LLShaderMgr::NO_ATMO, 0);
- }
-
//render grass
LLRenderPass::pushBatches(LLRenderPass::PASS_GRASS, getVertexDataMask());
}
@@ -432,18 +184,16 @@ LLDrawPoolFullbright::LLDrawPoolFullbright() :
{
}
-void LLDrawPoolFullbright::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-
void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
LLGLSLShader* shader = nullptr;
- if (LLPipeline::sUnderWaterRender)
+ if (LLPipeline::sRenderingHUDs)
+ {
+ shader = &gHUDFullbrightProgram;
+ }
+ else if (LLPipeline::sUnderWaterRender)
{
shader = &gDeferredFullbrightWaterProgram;
}
@@ -453,56 +203,17 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass)
}
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
// render static
setup_fullbright_shader(shader);
- pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE);
+ pushBatches(LLRenderPass::PASS_FULLBRIGHT, true, true);
- // render rigged
- setup_fullbright_shader(shader->mRiggedVariant);
- pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE);
-}
-
-void LLDrawPoolFullbright::render(S32 pass)
-{ //render fullbright
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_FULLBRIGHT);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- stop_glerror();
- LLGLSLShader* shader = nullptr;
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectFullbrightWaterProgram;
- }
- else
+ if (!LLPipeline::sRenderingHUDs)
{
- shader = &gObjectFullbrightProgram;
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, true, true);
}
-
-
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
-
- // render static
- setup_fullbright_shader(shader);
- pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE);
- pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE);
-
- // render rigged
- setup_fullbright_shader(shader->mRiggedVariant);
- pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE);
- pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE);
-}
-
-S32 LLDrawPoolFullbright::getNumPasses()
-{
- return 1;
}
void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
@@ -512,33 +223,28 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass)
LLGLSLShader* shader = nullptr;
if (LLPipeline::sRenderingHUDs)
{
- shader = &gObjectFullbrightAlphaMaskProgram;
+ shader = &gHUDFullbrightAlphaMaskProgram;
}
- else if (LLPipeline::sRenderDeferred)
+ else if (LLPipeline::sUnderWaterRender)
{
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gDeferredFullbrightAlphaMaskWaterProgram;
- }
- else
- {
- shader = &gDeferredFullbrightAlphaMaskProgram;
- }
+ shader = &gDeferredFullbrightAlphaMaskWaterProgram;
}
else
{
- shader = &gObjectFullbrightAlphaMaskProgram;
+ shader = &gDeferredFullbrightAlphaMaskProgram;
}
- LLGLDisable blend(GL_BLEND);
- U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX;
-
+ LLGLDisable blend(GL_BLEND);
+
// render static
setup_fullbright_shader(shader);
- pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE);
+ pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true);
- // render rigged
- setup_fullbright_shader(shader->mRiggedVariant);
- pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE);
+ if (!LLPipeline::sRenderingHUDs)
+ {
+ // render rigged
+ setup_fullbright_shader(shader->mRiggedVariant);
+ pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, true, true);
+ }
}
diff --git a/indra/newview/lldrawpoolsimple.h b/indra/newview/lldrawpoolsimple.h
index cccbe5e495..a3b93c237e 100644
--- a/indra/newview/lldrawpoolsimple.h
+++ b/indra/newview/lldrawpoolsimple.h
@@ -31,7 +31,7 @@
class LLGLSLShader;
-class LLDrawPoolSimple : public LLRenderPass
+class LLDrawPoolSimple final : public LLRenderPass
{
public:
enum
@@ -41,20 +41,15 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolSimple();
S32 getNumDeferredPasses() override;
void renderDeferred(S32 pass) override;
-
- /// We need two passes so we can handle emissive materials separately.
- S32 getNumPasses() override;
- void render(S32 pass = 0) override;
- void prerender() override;
};
-class LLDrawPoolGrass : public LLRenderPass
+class LLDrawPoolGrass final : public LLRenderPass
{
public:
enum
@@ -64,24 +59,15 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolGrass();
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void beginDeferredPass(S32 pass);
- /*virtual*/ void endDeferredPass(S32 pass);
- /*virtual*/ void renderDeferred(S32 pass);
-
- /*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();
+ S32 getNumDeferredPasses() override { return 1; }
+ void renderDeferred(S32 pass) override;
};
-class LLDrawPoolAlphaMask : public LLRenderPass
+class LLDrawPoolAlphaMask final : public LLRenderPass
{
public:
enum
@@ -91,20 +77,15 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolAlphaMask();
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void renderDeferred(S32 pass);
-
- /*virtual*/ S32 getNumPasses() { return 1; }
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
-
+ S32 getNumDeferredPasses() override { return 1; }
+ void renderDeferred(S32 pass) override;
};
-class LLDrawPoolFullbrightAlphaMask : public LLRenderPass
+class LLDrawPoolFullbrightAlphaMask final : public LLRenderPass
{
public:
enum
@@ -113,20 +94,16 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolFullbrightAlphaMask();
- /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void renderPostDeferred(S32 pass);
-
- /*virtual*/ S32 getNumPasses() { return 1; }
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
+ S32 getNumPostDeferredPasses() override { return 1; }
+ void renderPostDeferred(S32 pass) override;
};
-class LLDrawPoolFullbright : public LLRenderPass
+class LLDrawPoolFullbright final : public LLRenderPass
{
public:
enum
@@ -135,20 +112,15 @@ public:
LLVertexBuffer::MAP_TEXCOORD0 |
LLVertexBuffer::MAP_COLOR
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolFullbright();
- /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void renderPostDeferred(S32 pass);
-
- /*virtual*/ S32 getNumPasses();
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
-
+ S32 getNumPostDeferredPasses() override { return 1; }
+ void renderPostDeferred(S32 pass) override;
};
-class LLDrawPoolGlow : public LLRenderPass
+class LLDrawPoolGlow final : public LLRenderPass
{
public:
LLDrawPoolGlow(): LLRenderPass(LLDrawPool::POOL_GLOW) { }
@@ -160,19 +132,10 @@ public:
LLVertexBuffer::MAP_EMISSIVE
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
-
- virtual void prerender() { }
-
- /*virtual*/ S32 getNumPostDeferredPasses() { return 1; }
- /*virtual*/ void renderPostDeferred(S32 pass);
-
- void render(LLGLSLShader* shader);
-
- /*virtual*/ S32 getNumPasses();
-
- void render(S32 pass = 0);
+ U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
+ S32 getNumPostDeferredPasses() override { return 1; }
+ void renderPostDeferred(S32 pass) override;
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/lldrawpoolsky.cpp b/indra/newview/lldrawpoolsky.cpp
index 3a1efec91b..3c5bfe4a1c 100644
--- a/indra/newview/lldrawpoolsky.cpp
+++ b/indra/newview/lldrawpoolsky.cpp
@@ -28,21 +28,10 @@
#include "lldrawpoolsky.h"
-#include "llagent.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llsky.h"
-#include "llviewercamera.h"
-#include "llviewertexturelist.h"
-#include "llviewerregion.h"
-#include "llvosky.h"
-#include "llworld.h" // To get water height
-#include "pipeline.h"
-#include "llviewershadermgr.h"
+// DEPRECATED
LLDrawPoolSky::LLDrawPoolSky()
: LLFacePool(POOL_SKY),
-
mSkyTex(NULL),
mShader(NULL)
{
@@ -50,83 +39,16 @@ LLDrawPoolSky::LLDrawPoolSky()
void LLDrawPoolSky::prerender()
{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
- gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
}
void LLDrawPoolSky::render(S32 pass)
{
- gGL.flush();
- if (mDrawFace.empty())
- {
- return;
- }
-
- // Don't draw the sky box if we can and are rendering the WL sky dome.
- if (gPipeline.canUseWindLightShaders())
- {
- return;
- }
-
- // don't render sky under water (background just gets cleared to fog color)
- if(mShaderLevel > 0 && LLPipeline::sUnderWaterRender)
- {
- return;
- }
-
-
- //just use the UI shader (generic single texture no lighting)
- gOneTextureNoColorProgram.bind();
-
- LLGLSPipelineDepthTestSkyBox gls_skybox(true, false);
-
- LLGLEnable fog_enable( (mShaderLevel < 1 && LLViewerCamera::getInstance()->cameraUnderWater()) ? GL_FOG : 0);
-
- gGL.pushMatrix();
- LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
-
- S32 face_count = (S32)mDrawFace.size();
-
- LLVertexBuffer::unbind();
- gGL.diffuseColor4f(1,1,1,1);
-
- for (S32 i = 0; i < face_count; ++i)
- {
- renderSkyFace(i);
- }
-
- gGL.popMatrix();
}
void LLDrawPoolSky::renderSkyFace(U8 index)
{
- LLFace* face = mDrawFace[index];
-
- if (!face || !face->getGeomCount())
- {
- return;
- }
-
- if (index < 6) // sky tex...interp
- {
- llassert(mSkyTex);
- mSkyTex[index].bindTexture(true); // bind the current tex
-
- face->renderIndexed();
- }
- else // heavenly body faces, no interp...
- {
- LLGLEnable blend(GL_BLEND);
- LLViewerTexture* tex = face->getTexture(LLRender::DIFFUSE_MAP);
- if (tex)
- {
- gGL.getTexUnit(0)->bind(tex, true);
- face->renderIndexed();
- }
- }
}
void LLDrawPoolSky::endRenderPass( S32 pass )
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index cc5cb667f0..77189dceae 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -105,35 +105,9 @@ U32 LLDrawPoolTerrain::getVertexDataMask()
void LLDrawPoolTerrain::prerender()
{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT);
sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
}
-void LLDrawPoolTerrain::beginRenderPass( S32 pass )
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
- LLFacePool::beginRenderPass(pass);
-
- sShader = LLPipeline::sUnderWaterRender ?
- &gTerrainWaterProgram :
- &gTerrainProgram;
-
- if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
- {
- sShader->bind();
- }
-}
-
-void LLDrawPoolTerrain::endRenderPass( S32 pass )
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
- //LLFacePool::endRenderPass(pass);
-
- if (mShaderLevel > 1 && sShader->mShaderLevel > 0) {
- sShader->unbind();
- }
-}
-
//static
S32 LLDrawPoolTerrain::getDetailMode()
{
@@ -148,66 +122,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures()
for (S32 i = 0; i < 4; i++)
{
compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
- compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
- }
-}
-
-void LLDrawPoolTerrain::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
-
- if (mDrawFace.empty())
- {
- return;
- }
-
- boostTerrainDetailTextures();
-
- LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f);
-
- if (!gGLManager.mHasMultitexture)
- {
- // No multitexture, render simple land.
- renderSimple(); // Render without multitexture
- return;
- }
- // Render simplified land if video card can't do sufficient multitexturing
- if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2))
- {
- renderSimple(); // Render without multitexture
- return;
- }
-
- LLGLSPipeline gls;
-
- if (mShaderLevel > 1 && sShader->mShaderLevel > 0)
- {
- gPipeline.enableLightsDynamic();
-
- renderFullShader();
- }
- else
- {
- gPipeline.enableLightsStatic();
-
- if (sDetailMode == 0)
- {
- renderSimple();
- }
- else if (gGLManager.mNumTextureUnits < 4)
- {
- renderFull2TU();
- }
- else
- {
- renderFull4TU();
- }
- }
-
- // Special-case for land ownership feedback
- if (gSavedSettings.getBOOL("ShowParcelOwners"))
- {
- hilightParcelOwners(false);
+ compp->mDetailTextures[i]->addTextureStats(1024.f * 1024.f);
}
}
@@ -216,7 +131,7 @@ void LLDrawPoolTerrain::beginDeferredPass(S32 pass)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_TERRAIN);
LLFacePool::beginRenderPass(pass);
- sShader = LLPipeline::sUnderWaterRender ? &gDeferredTerrainWaterProgram : &gDeferredTerrainProgram;
+ sShader = &gDeferredTerrainProgram;
sShader->bind();
}
@@ -243,7 +158,7 @@ void LLDrawPoolTerrain::renderDeferred(S32 pass)
// Special-case for land ownership feedback
if (gSavedSettings.getBOOL("ShowParcelOwners"))
{
- hilightParcelOwners(true);
+ hilightParcelOwners();
}
}
@@ -407,13 +322,12 @@ void LLDrawPoolTerrain::renderFullShader()
gGL.getTexUnit(detail0)->activate();
}
-void LLDrawPoolTerrain::hilightParcelOwners(bool deferred)
+void LLDrawPoolTerrain::hilightParcelOwners()
{
- if (mShaderLevel > 1)
{ //use fullbright shader for highlighting
LLGLSLShader* old_shader = sShader;
sShader->unbind();
- sShader = deferred ? &gDeferredHighlightProgram : &gHighlightProgram;
+ sShader = &gDeferredHighlightProgram;
sShader->bind();
gGL.diffuseColor4f(1, 1, 1, 1);
LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
@@ -422,11 +336,7 @@ void LLDrawPoolTerrain::hilightParcelOwners(bool deferred)
sShader = old_shader;
sShader->bind();
}
- else
- {
- gPipeline.disableLights();
- renderOwnership();
- }
+
}
void LLDrawPoolTerrain::renderFull4TU()
@@ -838,8 +748,7 @@ void LLDrawPoolTerrain::renderOwnership()
iter != mDrawFace.end(); iter++)
{
LLFace *facep = *iter;
- facep->renderIndexed(LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0);
+ facep->renderIndexed();
}
gGL.matrixMode(LLRender::MM_TEXTURE);
diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h
index 5b4558020d..03bef31541 100644
--- a/indra/newview/lldrawpoolterrain.h
+++ b/indra/newview/lldrawpoolterrain.h
@@ -33,14 +33,12 @@ class LLDrawPoolTerrain : public LLFacePool
{
LLPointer<LLViewerTexture> mTexturep;
public:
- enum
- {
- VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TEXCOORD1 |
- LLVertexBuffer::MAP_TEXCOORD2 |
- LLVertexBuffer::MAP_TEXCOORD3
+ enum
+ {
+ VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX |
+ LLVertexBuffer::MAP_NORMAL |
+ LLVertexBuffer::MAP_TEXCOORD0 |
+ LLVertexBuffer::MAP_TEXCOORD1
};
virtual U32 getVertexDataMask();
@@ -59,10 +57,7 @@ public:
/*virtual*/ void endShadowPass(S32 pass);
/*virtual*/ void renderShadow(S32 pass);
- /*virtual*/ void render(S32 pass = 0);
/*virtual*/ void prerender();
- /*virtual*/ void beginRenderPass( S32 pass );
- /*virtual*/ void endRenderPass( S32 pass );
/*virtual*/ void dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures);
/*virtual*/ LLViewerTexture *getTexture();
/*virtual*/ LLViewerTexture *getDebugTexture();
@@ -87,7 +82,7 @@ protected:
void drawLoop();
private:
- void hilightParcelOwners(bool deferred);
+ void hilightParcelOwners();
};
#endif // LL_LLDRAWPOOLSIMPLE_H
diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp
index facfb235c9..9dcbc48697 100644
--- a/indra/newview/lldrawpooltree.cpp
+++ b/indra/newview/lldrawpooltree.cpp
@@ -50,94 +50,6 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerTexture *texturep) :
mTexturep->setAddressMode(LLTexUnit::TAM_WRAP);
}
-void LLDrawPoolTree::prerender()
-{
- mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
-}
-
-void LLDrawPoolTree::beginRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
-
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gTreeWaterProgram;
- }
- else
- {
- shader = &gTreeProgram;
- }
-
- if (gPipeline.shadersLoaded())
- {
- shader->bind();
- shader->setMinimumAlpha(0.5f);
- gGL.diffuseColor4f(1,1,1,1);
- }
- else
- {
- gPipeline.enableLightsDynamic();
- gGL.flush();
- }
-}
-
-void LLDrawPoolTree::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED;
-
- if (mDrawFace.empty())
- {
- return;
- }
-
- LLGLState test(GL_ALPHA_TEST, 0);
-
- gGL.getTexUnit(sDiffTex)->bindFast(mTexturep);
- gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res
-
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- LLVertexBuffer* buff = face->getVertexBuffer();
-
- if(buff)
- {
- LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
-
- if (model_matrix != gGLLastMatrix)
- {
- gGLLastMatrix = model_matrix;
- gGL.loadMatrix(gGLModelView);
- if (model_matrix)
- {
- llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
- gGL.multMatrix((GLfloat*) model_matrix->mMatrix);
- }
- gPipeline.mMatrixOpCount++;
- }
-
- buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK);
- buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0);
- }
- }
-}
-
-void LLDrawPoolTree::endRenderPass(S32 pass)
-{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_TREES);
-
- if (gPipeline.canUseWindLightShadersOnObjects())
- {
- shader->unbind();
- }
-
- if (mShaderLevel <= 0)
- {
- gGL.flush();
- }
-}
-
//============================================
// deferred implementation
//============================================
@@ -153,7 +65,42 @@ void LLDrawPoolTree::beginDeferredPass(S32 pass)
void LLDrawPoolTree::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED;
- render(pass);
+
+ if (mDrawFace.empty())
+ {
+ return;
+ }
+
+
+ gGL.getTexUnit(sDiffTex)->bindFast(mTexturep);
+ mTexturep->addTextureStats(1024.f * 1024.f); // <=== keep Linden tree textures at full res
+
+ for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
+ {
+ LLFace* face = *iter;
+ LLVertexBuffer* buff = face->getVertexBuffer();
+
+ if (buff)
+ {
+ LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix);
+
+ if (model_matrix != gGLLastMatrix)
+ {
+ gGLLastMatrix = model_matrix;
+ gGL.loadMatrix(gGLModelView);
+ if (model_matrix)
+ {
+ llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW);
+ gGL.multMatrix((GLfloat*)model_matrix->mMatrix);
+ }
+ gPipeline.mMatrixOpCount++;
+ }
+
+ buff->setBuffer();
+ buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts() - 1, buff->getNumIndices(), 0);
+ }
+ }
}
void LLDrawPoolTree::endDeferredPass(S32 pass)
@@ -182,7 +129,7 @@ void LLDrawPoolTree::beginShadowPass(S32 pass)
void LLDrawPoolTree::renderShadow(S32 pass)
{
- render(pass);
+ renderDeferred(pass);
}
void LLDrawPoolTree::endShadowPass(S32 pass)
@@ -196,14 +143,6 @@ void LLDrawPoolTree::endShadowPass(S32 pass)
BOOL LLDrawPoolTree::verify() const
{
-/* BOOL ok = TRUE;
-
- if (!ok)
- {
- printDebugInfo();
- }
- return ok;*/
-
return TRUE;
}
diff --git a/indra/newview/lldrawpooltree.h b/indra/newview/lldrawpooltree.h
index 13f9ec8dce..496445692c 100644
--- a/indra/newview/lldrawpooltree.h
+++ b/indra/newview/lldrawpooltree.h
@@ -45,8 +45,6 @@ public:
LLDrawPoolTree(LLViewerTexture *texturep);
- /*virtual*/ void prerender();
-
/*virtual*/ S32 getNumDeferredPasses() { return 1; }
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
@@ -57,10 +55,6 @@ public:
/*virtual*/ void endShadowPass(S32 pass);
/*virtual*/ void renderShadow(S32 pass);
- /*virtual*/ void beginRenderPass( S32 pass );
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void endRenderPass( S32 pass );
- /*virtual*/ S32 getNumPasses() { return 1; }
/*virtual*/ BOOL verify() const;
/*virtual*/ LLViewerTexture *getTexture();
/*virtual*/ LLViewerTexture *getDebugTexture();
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index a84f62036e..14f3142e1b 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -41,7 +41,6 @@
#include "llsky.h"
#include "llviewertexturelist.h"
#include "llviewerregion.h"
-#include "llvosky.h"
#include "llvowater.h"
#include "llworld.h"
#include "pipeline.h"
@@ -50,13 +49,13 @@
#include "llsettingssky.h"
#include "llsettingswater.h"
-BOOL deferred_render = FALSE;
-
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
BOOL LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
BOOL LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
F32 LLDrawPoolWater::sWaterFogEnd = 0.f;
+extern BOOL gCubeSnapshot;
+
LLDrawPoolWater::LLDrawPoolWater() : LLFacePool(POOL_WATER)
{
}
@@ -90,407 +89,72 @@ void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nex
mWaterNormp[1]->addTextureStats(1024.f*1024.f);
}
-//static
-void LLDrawPoolWater::restoreGL()
-{
- /*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- if (pwater)
- {
- setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID());
- setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId());
- setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID());
- }*/
-}
-
void LLDrawPoolWater::prerender()
{
- mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
-}
-
-S32 LLDrawPoolWater::getNumPasses()
-{
- if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
- {
- return 1;
- }
-
- return 0;
-}
-
-void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
-{
- beginRenderPass(pass);
- deferred_render = TRUE;
-}
-
-void LLDrawPoolWater::endPostDeferredPass(S32 pass)
-{
- endRenderPass(pass);
- deferred_render = FALSE;
+ mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
}
-//===============================
-//DEFERRED IMPLEMENTATION
-//===============================
-void LLDrawPoolWater::renderDeferred(S32 pass)
+S32 LLDrawPoolWater::getNumPostDeferredPasses()
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
-
- if (!LLPipeline::sRenderTransparentWater)
+ if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
{
- // Will render opaque water without use of ALM
- render(pass);
- return;
+ return 1;
}
- deferred_render = TRUE;
- renderWater();
- deferred_render = FALSE;
+ return 0;
}
-//=========================================
-
-void LLDrawPoolWater::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
- if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
- {
- return;
- }
-
- //do a quick 'n dirty depth sort
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace* facep = *iter;
- facep->mDistance = -facep->mCenterLocal.mV[2];
- }
-
- std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
-
- // See if we are rendering water as opaque or not
- if (!LLPipeline::sRenderTransparentWater)
- {
- // render water for low end hardware
- renderOpaqueLegacyWater();
- return;
- }
-
- LLGLEnable blend(GL_BLEND);
-
- if ((mShaderLevel > 0) && !sSkipScreenCopy)
- {
- renderWater();
- return;
- }
-
- LLVOSky *voskyp = gSky.mVOSkyp;
-
- stop_glerror();
-
- if (!gGLManager.mHasMultitexture)
- {
- // Ack! No multitexture! Bail!
- return;
- }
-
- LLFace* refl_face = voskyp->getReflFace();
-
- gPipeline.disableLights();
-
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-
- LLGLDisable cullFace(GL_CULL_FACE);
-
- // Set up second pass first
- gGL.getTexUnit(1)->activate();
- gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->bind(mWaterImagep[0]) ;
-
- gGL.getTexUnit(2)->activate();
- gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->bind(mWaterImagep[1]) ;
-
- LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
- F32 up_dot = camera_up * LLVector3::z_axis;
-
- LLColor4 water_color;
- if (LLViewerCamera::getInstance()->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));
- }
-
- gGL.diffuseColor4fv(water_color.mV);
-
- // Automatically generate texture coords for detail map
- 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);
-
- gGL.getTexUnit(0)->activate();
-
- 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);
-
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (voskyp->isReflFace(face))
- {
- continue;
- }
- gGL.getTexUnit(0)->bind(face->getTexture());
- face->renderIndexed();
- }
-
- // Now, disable texture coord generation on texture state 1
- gGL.getTexUnit(1)->activate();
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->disable();
-
- glDisable(GL_TEXTURE_GEN_S); //texture unit 1
- glDisable(GL_TEXTURE_GEN_T); //texture unit 1
-
- gGL.getTexUnit(2)->activate();
- gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(2)->disable();
-
- glDisable(GL_TEXTURE_GEN_S); //texture unit 1
- glDisable(GL_TEXTURE_GEN_T); //texture unit 1
-
- // Disable texture coordinate and color arrays
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- stop_glerror();
-
- if (gSky.mVOSkyp->getCubeMap())
- {
- gSky.mVOSkyp->getCubeMap()->enable(0);
- gSky.mVOSkyp->getCubeMap()->bind();
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
- LLMatrix4 camera_rot(camera_mat.getMat3());
- camera_rot.invert();
-
- gGL.loadMatrix((F32 *)camera_rot.mMatrix);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot);
-
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (voskyp->isReflFace(face))
- {
- //refl_face = face;
- continue;
- }
-
- if (face->getGeomCount() > 0)
- {
- face->renderIndexed();
- }
- }
-
- gSky.mVOSkyp->getCubeMap()->disable();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- }
-
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
- if (refl_face)
- {
- glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
- renderReflection(refl_face);
- }
-}
-
-// for low end hardware
-void LLDrawPoolWater::renderOpaqueLegacyWater()
+void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
+ gGL.setColorMask(true, true);
- if (voskyp == NULL)
+ if (LLPipeline::sRenderTransparentWater)
{
- return;
- }
+ // copy framebuffer contents so far to a texture to be used for
+ // reflections and refractions
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- LLGLSLShader* shader = NULL;
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
- }
- else
- {
- shader = &gObjectSimpleNonIndexedTexGenProgram;
- }
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
- shader->bind();
+ dst.bindTarget();
+ gCopyDepthProgram.bind();
- stop_glerror();
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
- // Depth sorting and write to depth buffer
- // since this is opaque, we should see nothing
- // behind the water. No blending because
- // of no transparency. And no face culling so
- // that the underside of the water is also opaque.
- LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
- LLGLDisable no_cull(GL_CULL_FACE);
- LLGLDisable no_blend(GL_BLEND);
+ gGL.getTexUnit(diff_map)->bind(&src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
- gPipeline.disableLights();
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- // Activate the texture binding and bind one
- // texture since all images will have the same texture
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
-
- // Automatically generate texture coords for water texture
- if (!shader)
- {
- glEnable(GL_TEXTURE_GEN_S); //texture unit 0
- glEnable(GL_TEXTURE_GEN_T); //texture unit 0
- glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
- }
-
- // Use the fact that we know all water faces are the same size
- // to save some computation
-
- // Slowly move texture coordinates over time so the watter appears
- // to be moving.
- F32 movement_period_secs = 50.f;
-
- F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
-
- if (movement_period_secs != 0)
- {
- offset /= movement_period_secs;
- }
- else
- {
- offset = 0;
- }
-
- F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
- F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
-
- if (!shader)
- {
- glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
- glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
- }
- else
- {
- shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0);
- shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1);
- }
-
- gGL.diffuseColor3f(1.f, 1.f, 1.f);
-
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (voskyp->isReflFace(face))
- {
- continue;
- }
-
- face->renderIndexed();
- }
-
- stop_glerror();
-
- if (!shader)
- {
- // Reset the settings back to expected values
- glDisable(GL_TEXTURE_GEN_S); //texture unit 0
- glDisable(GL_TEXTURE_GEN_T); //texture unit 0
- }
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-}
-
-
-void LLDrawPoolWater::renderReflection(LLFace* face)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- LLVOSky *voskyp = gSky.mVOSkyp;
-
- if (!voskyp)
- {
- return;
- }
-
- if (!face->getGeomCount())
- {
- return;
- }
-
- S8 dr = voskyp->getDrawRefl();
- if (dr < 0)
- {
- return;
- }
-
- LLGLSNoFog noFog;
-
- gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex());
-
- LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
- face->renderIndexed();
+ dst.flush();
+ }
}
-void LLDrawPoolWater::renderWater()
+void LLDrawPoolWater::renderPostDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- if (!deferred_render)
- {
- gGL.setColorMask(true, true);
- }
-
LLGLDisable blend(GL_BLEND);
+
+ gGL.setColorMask(true, true);
LLColor3 light_diffuse(0, 0, 0);
F32 light_exp = 0.0f;
- LLEnvironment & environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
LLVector3 light_dir = environment.getLightDirection();
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
bool has_normal_mips = gSavedSettings.getBOOL("RenderWaterMipNormal");
bool underwater = LLViewerCamera::getInstance()->cameraUnderWater();
+ LLColor4 fog_color = LLColor4(pwater->getWaterFogColor(), 0.f);
+ LLColor3 fog_color_linear = linearColor3(fog_color);
if (sun_up)
{
@@ -508,56 +172,48 @@ void LLDrawPoolWater::renderWater()
F32 ground_proj_sq = light_dir.mV[0] * light_dir.mV[0] + light_dir.mV[1] * light_dir.mV[1];
light_exp = llmax(32.f, 256.f * powf(ground_proj_sq, 16.0f));
if (0.f < light_diffuse.normalize()) // Normalizing a color? Puzzling...
- {
+ {
light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
// set up normal maps filtering
for (auto norm_map : mWaterNormp)
- {
+ {
if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
- }
+ }
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
LLGLSLShader *shader = nullptr;
// two passes, first with standard water shader bound, second with edge water shader bound
- for( int edge = 0 ; edge < 2; edge++ )
+ for (int edge = 0; edge < 2; edge++)
{
// select shader
- if (underwater && LLPipeline::sWaterReflections)
+ if (underwater)
{
- shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
+ shader = &gUnderWaterProgram;
}
else
{
- if (edge && !deferred_render)
+ if (edge)
{
shader = &gWaterEdgeProgram;
}
else
{
- shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram;
+ shader = &gWaterProgram;
}
}
- shader->bind();
- // bind textures for water rendering
- S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
- if (reftex > -1)
- {
- gGL.getTexUnit(reftex)->activate();
- gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
- gGL.getTexUnit(0)->activate();
- }
+ gPipeline.bindDeferredShader(*shader);
- // bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ //bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- LLViewerTexture *tex_a = mWaterNormp[0];
- LLViewerTexture *tex_b = mWaterNormp[1];
+ LLViewerTexture* tex_a = mWaterNormp[0];
+ LLViewerTexture* tex_b = mWaterNormp[1];
F32 blend_factor = pwater->getBlendFactor();
@@ -567,12 +223,12 @@ void LLDrawPoolWater::renderWater()
if (tex_a && (!tex_b || (tex_a == tex_b)))
{
gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
+ blend_factor = 0; // only one tex provided, no blending
}
else if (tex_b && !tex_a)
{
gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
+ blend_factor = 0; // only one tex provided, no blending
}
else if (tex_b != tex_a)
{
@@ -581,25 +237,16 @@ void LLDrawPoolWater::renderWater()
}
// bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
- F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ S32 screenDepth = shader->enableTexture(LLShaderMgr::WATER_SCREENDEPTH);
- S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+ F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
- // set uniforms for shader
- if (deferred_render)
- {
- if (shader->getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
- {
- glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
- shader->uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
- }
- }
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
if (screentex > -1)
@@ -608,12 +255,17 @@ void LLDrawPoolWater::renderWater()
gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
}
+ if (screenDepth > -1)
+ {
+ gGL.getTexUnit(screenDepth)->bind(&gPipeline.mWaterDis, true);
+ }
+
if (mShaderLevel == 1)
{
fog_color.mV[VW] = log(fog_density) / log(2);
}
- F32 water_height = environment.getWaterHeight();
+ F32 water_height = environment.getWaterHeight();
F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, camera_height - water_height);
shader->uniform1f(LLShaderMgr::WATER_TIME, phase_time);
@@ -621,6 +273,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, 1, fog_color_linear.mV);
shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
@@ -635,7 +288,7 @@ void LLDrawPoolWater::renderWater()
shader->uniform1f(LLShaderMgr::WATER_FRESNEL_OFFSET, pwater->getFresnelOffset());
shader->uniform1f(LLShaderMgr::WATER_BLUR_MULTIPLIER, pwater->getBlurMultiplier());
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
F32 scaledAngle = 1.f - sunAngle;
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
@@ -644,8 +297,11 @@ void LLDrawPoolWater::renderWater()
shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
- LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ // SL-15861 This was changed from getRotatedLightNorm() as it was causing
+ // lightnorm in shaders\class1\windlight\atmosphericsFuncs.glsl in have inconsistent additive lighting for 180 degrees of the FOV.
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getClampedLightNorm();
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
if (LLViewerCamera::getInstance()->cameraUnderWater())
@@ -659,16 +315,16 @@ void LLDrawPoolWater::renderWater()
LLGLDisable cullface(GL_CULL_FACE);
- LLVOWater *water = nullptr;
- for (LLFace *const &face : mDrawFace)
+ LLVOWater* water = nullptr;
+ for (LLFace* const& face : mDrawFace)
{
if (!face) continue;
- water = static_cast<LLVOWater *>(face->getViewerObject());
+ water = static_cast<LLVOWater*>(face->getViewerObject());
if (!water) continue;
gGL.getTexUnit(diffTex)->bind(face->getTexture());
- if ((bool)edge == (bool) water->getIsEdgePatch())
+ if ((bool)edge == (bool)water->getIsEdgePatch())
{
face->renderIndexed();
@@ -689,22 +345,21 @@ void LLDrawPoolWater::renderWater()
shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
// clean up
- shader->unbind();
+ gPipeline.unbindDeferredShader(*shader);
+
gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
}
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!deferred_render)
- {
- gGL.setColorMask(true, false);
- }
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+
+ gGL.setColorMask(true, false);
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
{
- return LLViewerFetchedTexture::sSmokeImagep;
+ return LLViewerTextureManager::getFetchedTexture(IMG_SMOKE);
}
LLColor3 LLDrawPoolWater::getDebugColor() const
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 6f2fc3271d..3158b0a59b 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -35,7 +35,7 @@ class LLHeavenBody;
class LLWaterSurface;
class LLGLSLShader;
-class LLDrawPoolWater: public LLFacePool
+class LLDrawPoolWater final: public LLFacePool
{
protected:
LLPointer<LLViewerTexture> mWaterImagep[2];
@@ -56,29 +56,19 @@ public:
LLVertexBuffer::MAP_TEXCOORD0
};
- virtual U32 getVertexDataMask() { return VERTEX_DATA_MASK; }
+ virtual U32 getVertexDataMask() override { return VERTEX_DATA_MASK; }
LLDrawPoolWater();
/*virtual*/ ~LLDrawPoolWater();
- static void restoreGL();
-
- /*virtual*/ S32 getNumPostDeferredPasses() { return 0; } //getNumPasses(); }
- /*virtual*/ void beginPostDeferredPass(S32 pass);
- /*virtual*/ void endPostDeferredPass(S32 pass);
- /*virtual*/ void renderPostDeferred(S32 pass) { render(pass); }
- /*virtual*/ S32 getNumDeferredPasses() { return 1; }
- /*virtual*/ void renderDeferred(S32 pass = 0);
+ S32 getNumPostDeferredPasses() override;
+ void beginPostDeferredPass(S32 pass) override;
+ void renderPostDeferred(S32 pass) override;
- /*virtual*/ S32 getNumPasses();
- /*virtual*/ void render(S32 pass = 0);
- /*virtual*/ void prerender();
+ void prerender() override;
- /*virtual*/ LLViewerTexture *getDebugTexture();
- /*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
-
- void renderReflection(LLFace* face);
- void renderWater();
+ LLViewerTexture *getDebugTexture() override;
+ LLColor3 getDebugColor() const; // For AGP debug display
void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId);
void setOpaqueTexture(const LLUUID& opaqueTextureId);
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index 9873846669..05ee328e43 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -45,6 +45,8 @@
#include "llvowlsky.h"
#include "llsettingsvo.h"
+extern BOOL gCubeSnapshot;
+
static LLStaticHashedString sCamPosLocal("camPosLocal");
static LLStaticHashedString sCustomAlpha("custom_alpha");
@@ -69,51 +71,14 @@ LLViewerTexture *LLDrawPoolWLSky::getDebugTexture()
return NULL;
}
-void LLDrawPoolWLSky::beginRenderPass( S32 pass )
-{
- sky_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gWLSkyProgram;
-
- cloud_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gWLCloudProgram;
-
- sun_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gWLSunProgram;
-
- moon_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gWLMoonProgram;
-}
-
-void LLDrawPoolWLSky::endRenderPass( S32 pass )
-{
- sky_shader = nullptr;
- cloud_shader = nullptr;
- sun_shader = nullptr;
- moon_shader = nullptr;
-}
-
void LLDrawPoolWLSky::beginDeferredPass(S32 pass)
{
sky_shader = &gDeferredWLSkyProgram;
cloud_shader = &gDeferredWLCloudProgram;
- sun_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gDeferredWLSunProgram;
+ sun_shader = &gDeferredWLSunProgram;
- moon_shader =
- LLPipeline::sUnderWaterRender ?
- &gObjectFullbrightNoColorWaterProgram :
- &gDeferredWLMoonProgram;
+ moon_shader = &gDeferredWLMoonProgram;
}
void LLDrawPoolWLSky::endDeferredPass(S32 pass)
@@ -124,11 +89,6 @@ void LLDrawPoolWLSky::endDeferredPass(S32 pass)
moon_shader = nullptr;
}
-void LLDrawPoolWLSky::renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
-{
- gSky.mVOWLSkyp->drawFsSky();
-}
-
void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const
{
llassert_always(NULL != shader);
@@ -166,6 +126,11 @@ void LLDrawPoolWLSky::renderDome(const LLVector3& camPosLocal, F32 camHeightLoca
void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const
{
+ if (!gSky.mVOSkyp)
+ {
+ return;
+ }
+
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
@@ -174,6 +139,8 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
sky_shader->bind();
+ sky_shader->uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
+
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
LLViewerTexture* rainbow_tex = gSky.mVOSkyp->getRainbowTex();
@@ -208,76 +175,13 @@ void LLDrawPoolWLSky::renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 ca
}
}
-void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const
-{
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
-
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
- {
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- LLGLSPipelineDepthTestSkyBox sky(true, false);
- sky_shader->bind();
- sky_shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, 1);
- sky_shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
- renderDome(origin, camHeightLocal, sky_shader);
- sky_shader->unbind();
- }
-}
-
-void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
+void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
{
- LLGLSPipelineBlendSkyBox gls_skybox(true, false);
-
- // *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.
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
-
- // *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.
- LLColor4 star_alpha(LLColor4::black);
-
- star_alpha.mV[3] = LLEnvironment::instance().getCurrentSky()->getStarBrightness() / 512.f;
-
- // If star brightness is not set, exit
- if( star_alpha.mV[3] < 0.001 )
- {
- LL_DEBUGS("SKY") << "star_brightness below threshold." << LL_ENDL;
- return;
- }
-
- LLViewerTexture* tex_a = gSky.mVOSkyp->getBloomTex();
- LLViewerTexture* tex_b = gSky.mVOSkyp->getBloomTexNext();
-
- if (tex_a && (!tex_b || (tex_a == tex_b)))
+ if (!gSky.mVOSkyp)
{
- // Bind current and next sun textures
- gGL.getTexUnit(0)->bind(tex_a);
- }
- else if (tex_b && !tex_a)
- {
- gGL.getTexUnit(0)->bind(tex_b);
+ return;
}
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(0)->bind(tex_a);
- }
-
- gGL.pushMatrix();
- gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
- gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
- gCustomAlphaProgram.bind();
- gCustomAlphaProgram.uniform1f(sCustomAlpha, star_alpha.mV[3]);
-
- gSky.mVOWLSkyp->drawStars();
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.popMatrix();
- gCustomAlphaProgram.unbind();
-}
-
-void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
-{
LLGLSPipelineBlendSkyBox gls_sky(true, false);
gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
@@ -319,6 +223,7 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
gGL.pushMatrix();
gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
+ gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
if (LLPipeline::sReflectionRender)
@@ -343,7 +248,7 @@ void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
+ if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp && gSky.mVOSkyp->getCloudNoiseTex())
{
LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
@@ -360,60 +265,11 @@ void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32
F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
- // if we even have sun disc textures to work with...
- if (cloud_noise || cloud_noise_next)
+ if (psky->getCloudScrollRate().isExactlyZero())
{
- if (cloud_noise && (!cloud_noise_next || (cloud_noise == cloud_noise_next)))
- {
- // Bind current and next sun textures
- cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
- blend_factor = 0;
- }
- else if (cloud_noise_next && !cloud_noise)
- {
- cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise_next, LLTexUnit::TT_TEXTURE);
- blend_factor = 0;
- }
- else if (cloud_noise_next != cloud_noise)
- {
- cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP, cloud_noise, LLTexUnit::TT_TEXTURE);
- cloudshader->bindTexture(LLShaderMgr::CLOUD_NOISE_MAP_NEXT, cloud_noise_next, LLTexUnit::TT_TEXTURE);
- }
+ blend_factor = 0.f;
}
- cloudshader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- cloudshader->uniform1f(LLShaderMgr::CLOUD_VARIANCE, cloud_variance);
- cloudshader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, psky->getSunMoonGlowFactor());
-
- /// Render the skydome
- renderDome(camPosLocal, camHeightLocal, cloudshader);
-
- cloudshader->unbind();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
- }
-}
-
-void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
-{
- if (gPipeline.canUseWindLightShaders() && gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_CLOUDS) && gSky.mVOSkyp->getCloudNoiseTex())
- {
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
-
- LLGLSPipelineBlendSkyBox pipeline(true, true);
-
- cloudshader->bind();
-
- LLPointer<LLViewerTexture> cloud_noise = gSky.mVOSkyp->getCloudNoiseTex();
- LLPointer<LLViewerTexture> cloud_noise_next = gSky.mVOSkyp->getCloudNoiseTexNext();
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
-
- F32 cloud_variance = psky ? psky->getCloudVariance() : 0.0f;
- F32 blend_factor = psky ? psky->getBlendFactor() : 0.0f;
-
// if we even have sun disc textures to work with...
if (cloud_noise || cloud_noise_next)
{
@@ -451,11 +307,13 @@ void LLDrawPoolWLSky::renderSkyClouds(const LLVector3& camPosLocal, F32 camHeigh
void LLDrawPoolWLSky::renderHeavenlyBodies()
{
- LLGLSPipelineBlendSkyBox gls_skybox(true, false);
+ if (!gSky.mVOSkyp) return;
+
+ LLGLSPipelineBlendSkyBox gls_skybox(true, true); // SL-14113 we need moon to write to depth to clip stars behind
LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
gGL.pushMatrix();
- gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
+ gGL.translatef(origin.mV[0], origin.mV[1], origin.mV[2]);
LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
@@ -547,7 +405,7 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
F32 moon_brightness = (float)psky->getMoonBrightness();
moon_shader->uniform1f(LLShaderMgr::MOON_BRIGHTNESS, moon_brightness);
- moon_shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
+ moon_shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, gSky.mVOSkyp->getMoon().getColor().mV);
moon_shader->uniform4fv(LLShaderMgr::DIFFUSE_COLOR, 1, color.mV);
//moon_shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
moon_shader->uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, psky->getMoonDirection().mV); // shader: moon_dir
@@ -567,11 +425,14 @@ void LLDrawPoolWLSky::renderHeavenlyBodies()
void LLDrawPoolWLSky::renderDeferred(S32 pass)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
+ if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY) || gSky.mVOSkyp.isNull())
{
return;
}
+ // TODO: remove gSky.mVOSkyp and fold sun/moon into LLVOWLSky
+ gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable);
+
const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
gGL.setColorMask(true, false);
@@ -581,36 +442,21 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
if (gPipeline.canUseWindLightShaders())
{
renderSkyHazeDeferred(origin, camHeightLocal);
- renderStarsDeferred(origin);
renderHeavenlyBodies();
- renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
+ if (!gCubeSnapshot)
+ {
+ renderStarsDeferred(origin);
+ }
+
+ if (!gCubeSnapshot || gPipeline.mReflectionMapManager.isRadiancePass()) // don't draw clouds in irradiance maps to avoid popping
+ {
+ renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
+ }
}
gGL.setColorMask(true, true);
}
-void LLDrawPoolWLSky::render(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WL_SKY);
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SKY))
- {
- return;
- }
-
- const F32 camHeightLocal = LLEnvironment::instance().getCamHeight();
- LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
-
- renderSkyHaze(origin, camHeightLocal);
- renderStars(origin);
- renderHeavenlyBodies();
- renderSkyClouds(origin, camHeightLocal, cloud_shader);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-}
-void LLDrawPoolWLSky::prerender()
-{
- //LL_INFOS() << "wlsky prerendering pass." << LL_ENDL;
-}
LLViewerTexture* LLDrawPoolWLSky::getTexture()
{
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index 324886ed42..c26d0a1e23 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -51,11 +51,6 @@ public:
/*virtual*/ void renderDeferred(S32 pass);
/*virtual*/ LLViewerTexture *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 getShaderLevel() const { return mShaderLevel; }
@@ -69,17 +64,12 @@ public:
static void cleanupGL();
static void restoreGL();
private:
- void renderFsSky(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
void renderDome(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader * shader) const;
- void renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightLocal) const;
- void renderSkyClouds(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
-
void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
void renderStarsDeferred(const LLVector3& camPosLocal) const;
- void renderStars(const LLVector3& camPosLocal) const;
void renderHeavenlyBodies();
};
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 361a7666fa..425acd3392 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -118,35 +118,10 @@ BOOL LLViewerDynamicTexture::render()
//-----------------------------------------------------------------------------
void LLViewerDynamicTexture::preRender(BOOL clear_depth)
{
- gPipeline.allocatePhysicsBuffer();
- if (!gNonInteractive)
- {
- llassert(mFullWidth <= static_cast<S32>(gPipeline.mPhysicsDisplay.getWidth()));
- llassert(mFullHeight <= static_cast<S32>(gPipeline.mPhysicsDisplay.getHeight()));
- }
-
- if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD)
- { //using offscreen render target, just use the bottom left corner
- mOrigin.set(0, 0);
- }
- else
- { // force rendering to on-screen portion of frame buffer
- LLCoordScreen window_pos;
- gViewerWindow->getWindow()->getPosition( &window_pos );
- mOrigin.set(0, gViewerWindow->getWindowHeightRaw() - mFullHeight); // top left corner
-
- if (window_pos.mX < 0)
- {
- mOrigin.mX = -window_pos.mX;
- }
- if (window_pos.mY < 0)
- {
- mOrigin.mY += window_pos.mY;
- mOrigin.mY = llmax(mOrigin.mY, 0) ;
- }
- }
+ //use the bottom left corner
+ mOrigin.set(0, 0);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
// Set up camera
LLViewerCamera* camera = LLViewerCamera::getInstance();
mCamera.setOrigin(*camera);
@@ -195,7 +170,7 @@ void LLViewerDynamicTexture::postRender(BOOL success)
camera->setOrigin(mCamera);
camera->setAxes(mCamera);
camera->setAspect(mCamera.getAspect());
- camera->setView(mCamera.getView());
+ camera->setViewNoBroadcast(mCamera.getView());
camera->setNear(mCamera.getNear());
}
@@ -220,7 +195,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances()
gPipeline.mBake.clear();
}
- LLGLSLShader::bindNoShader();
+ LLGLSLShader::unbind();
LLVertexBuffer::unbind();
BOOL result = FALSE;
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 05c7decfbd..edc7bdef5f 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -168,6 +168,9 @@ namespace
// Find normalized track position of given time along full length of cycle
inline LLSettingsBase::TrackPosition convert_time_to_position(const LLSettingsBase::Seconds& time, const LLSettingsBase::Seconds& len)
{
+ // early out to avoid divide by zero. if len is zero then jump to end position
+ if (len == 0.f) return 1.f;
+
LLSettingsBase::TrackPosition position = LLSettingsBase::TrackPosition(fmod((F64)time, (F64)len) / (F64)len);
return llclamp(position, 0.0f, 1.0f);
}
@@ -812,7 +815,8 @@ const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
-const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
+const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("651510b8-5f4d-8991-1592-e7eeab2a5a06");
+const LLUUID LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY("cef49723-0292-af49-9b14-9598a616b8a3");
const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2");
const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090");
@@ -1178,13 +1182,14 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
return;
}
- DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
+ bool reset_probes = false;
+ DayInstance::ptr_t environment = getEnvironmentInstance(env, true);
if (fixed.first)
{
logEnvironment(env, fixed.first, env_version);
- environment->setSky(fixed.first);
+ reset_probes = environment->setSky(fixed.first);
environment->setFlags(DayInstance::NO_ANIMATE_SKY);
}
else if (!environment->getSky())
@@ -1195,7 +1200,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
// and then add water/sky on top
// This looks like it will result in sky using single keyframe instead of whole day if day is present
// when setting static water without static sky
- environment->setSky(mCurrentEnvironment->getSky());
+ reset_probes = environment->setSky(mCurrentEnvironment->getSky());
environment->setFlags(DayInstance::NO_ANIMATE_SKY);
}
else
@@ -1213,7 +1218,7 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
if (substitute && substitute->getSky())
{
- environment->setSky(substitute->getSky());
+ reset_probes = environment->setSky(substitute->getSky());
environment->setFlags(DayInstance::NO_ANIMATE_SKY);
}
else
@@ -1265,6 +1270,11 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, LLEnvironm
}
}
+ if (reset_probes)
+ { // the sky changed in a way that merits a reset of reflection probes
+ gPipeline.mReflectionMapManager.reset();
+ }
+
if (!mSignalEnvChanged.empty())
mSignalEnvChanged(env, env_version);
}
@@ -1629,28 +1639,31 @@ LLVector4 LLEnvironment::getRotatedLightNorm() const
return toLightNorm(light_direction);
}
+extern BOOL gCubeSnapshot;
+
//-------------------------------------------------------------------------
void LLEnvironment::update(const LLViewerCamera * cam)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT; //LL_RECORD_BLOCK_TIME(FTM_ENVIRONMENT_UPDATE);
//F32Seconds now(LLDate::now().secondsSinceEpoch());
- static LLFrameTimer timer;
-
- F32Seconds delta(timer.getElapsedTimeAndResetF32());
-
+ if (!gCubeSnapshot)
{
- DayInstance::ptr_t keeper = mCurrentEnvironment;
- // make sure the current environment does not go away until applyTimeDelta is done.
- mCurrentEnvironment->applyTimeDelta(delta);
+ static LLFrameTimer timer;
- }
- // update clouds, sun, and general
- updateCloudScroll();
+ F32Seconds delta(timer.getElapsedTimeAndResetF32());
- // cache this for use in rotating the rotated light vec for shader param updates later...
- mLastCamYaw = cam->getYaw() + SUN_DELTA_YAW;
+ {
+ DayInstance::ptr_t keeper = mCurrentEnvironment;
+ // make sure the current environment does not go away until applyTimeDelta is done.
+ mCurrentEnvironment->applyTimeDelta(delta);
+
+ }
+ // update clouds, sun, and general
+ updateCloudScroll();
- stop_glerror();
+ // cache this for use in rotating the rotated light vec for shader param updates later...
+ mLastCamYaw = cam->getYaw() + SUN_DELTA_YAW;
+ }
updateSettingsUniforms();
@@ -1681,8 +1694,16 @@ void LLEnvironment::updateCloudScroll()
if (mCurrentEnvironment->getSky() && !mCloudScrollPaused)
{
- LLVector2 cloud_delta = static_cast<F32>(delta_t)* (mCurrentEnvironment->getSky()->getCloudScrollRate()) / 100.0;
- mCloudScrollDelta += cloud_delta;
+ LLVector2 rate = mCurrentEnvironment->getSky()->getCloudScrollRate();
+ if (rate.isExactlyZero())
+ {
+ mCloudScrollDelta.setZero();
+ }
+ else
+ {
+ LLVector2 cloud_delta = static_cast<F32>(delta_t) * (mCurrentEnvironment->getSky()->getCloudScrollRate()) / 100.0;
+ mCloudScrollDelta += cloud_delta;
+ }
}
}
@@ -1739,8 +1760,30 @@ void LLEnvironment::updateGLVariablesForSettings(LLShaderUniforms* uniforms, con
case LLSD::TypeArray:
{
LLVector4 vect4(value);
+
+ if (gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass())
+ { // maximize and remove tinting if this is an irradiance map render pass and the parameter feeds into the sky background color
+ auto max_vec = [](LLVector4 col)
+ {
+ LLColor3 color(col);
+ F32 h, s, l;
+ color.calcHSL(&h, &s, &l);
+
+ col.mV[0] = col.mV[1] = col.mV[2] = l;
+ return col;
+ };
+
+ switch (it.second.getShaderKey())
+ {
+ case LLShaderMgr::BLUE_HORIZON:
+ case LLShaderMgr::BLUE_DENSITY:
+ vect4 = max_vec(vect4);
+ break;
+ }
+ }
+
//_WARNS("RIDER") << "pushing '" << (*it).first << "' as " << vect4 << LL_ENDL;
- shader->uniform4fv(it.second.getShaderKey(), vect4 );
+ shader->uniform3fv(it.second.getShaderKey(), LLVector3(vect4.mV) );
break;
}
@@ -2741,10 +2784,12 @@ void LLEnvironment::DayInstance::setDay(const LLSettingsDay::ptr_t &pday, LLSett
}
-void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
+bool LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
{
mInitialized = false;
+ bool changed = psky == nullptr || mSky == nullptr || mSky->getHash() != psky->getHash();
+
bool different_sky = mSky != psky;
mSky = psky;
@@ -2758,6 +2803,8 @@ void LLEnvironment::DayInstance::setSky(const LLSettingsSky::ptr_t &psky)
LLEnvironment::getAtmosphericModelSettings(settings, psky);
gAtmosphere->configureAtmosphericModel(settings);
}
+
+ return changed;
}
void LLEnvironment::DayInstance::setWater(const LLSettingsWater::ptr_t &pwater)
@@ -2907,12 +2954,20 @@ void LLEnvironment::DayTransition::animate()
setWater(mNextInstance->getWater());
});
+
+ // pause probe updates and reset reflection maps on sky change
+ gPipeline.mReflectionMapManager.pause();
+ gPipeline.mReflectionMapManager.reset();
+
mSky = mStartSky->buildClone();
mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(mSky, mStartSky, mNextInstance->getSky(), mTransitionTime);
mBlenderSky->setOnFinished(
[this](LLSettingsBlender::ptr_t blender) {
mBlenderSky.reset();
+ // resume reflection probe updates
+ gPipeline.mReflectionMapManager.resume();
+
if (!mBlenderSky && !mBlenderWater)
LLEnvironment::instance().mCurrentEnvironment = mNextInstance;
else
@@ -3503,12 +3558,19 @@ namespace
LLSettingsSky::ptr_t target_sky(start_sky->buildClone());
mInjectedSky->setSource(target_sky);
+ // clear reflection probes and pause updates during sky change
+ gPipeline.mReflectionMapManager.pause();
+ gPipeline.mReflectionMapManager.reset();
+
mBlenderSky = std::make_shared<LLSettingsBlenderTimeDelta>(target_sky, start_sky, psky, transition);
mBlenderSky->setOnFinished(
[this, psky](LLSettingsBlender::ptr_t blender)
{
mBlenderSky.reset();
mInjectedSky->setSource(psky);
+
+ // resume updating reflection probes when done animating sky
+ gPipeline.mReflectionMapManager.resume();
setSky(mInjectedSky);
if (!mBlenderWater && (countExperiencesActive() == 0))
{
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 1c8a68ae02..408952bb5b 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -63,6 +63,7 @@ public:
static const LLUUID KNOWN_SKY_SUNRISE;
static const LLUUID KNOWN_SKY_MIDDAY;
+ static const LLUUID KNOWN_SKY_LEGACY_MIDDAY;
static const LLUUID KNOWN_SKY_SUNSET;
static const LLUUID KNOWN_SKY_MIDNIGHT;
@@ -265,7 +266,7 @@ public:
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& delta);
virtual void setDay(const LLSettingsDay::ptr_t &pday, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset);
- virtual void setSky(const LLSettingsSky::ptr_t &psky);
+ bool setSky(const LLSettingsSky::ptr_t &psky);
virtual void setWater(const LLSettingsWater::ptr_t &pwater);
void initialize();
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index c3b3ccabb4..c1776705f9 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -47,7 +47,6 @@
#include "llviewercamera.h"
#include "llviewertexturelist.h"
#include "llvopartgroup.h"
-#include "llvosky.h"
#include "llvovolume.h"
#include "pipeline.h"
#include "llviewerregion.h"
@@ -192,7 +191,6 @@ void LLFace::destroy()
if (isState(LLFace::PARTICLE))
{
- LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
clearState(LLFace::PARTICLE);
}
@@ -213,7 +211,7 @@ void LLFace::destroy()
if (group)
{
group->dirtyGeom();
- gPipeline.markRebuild(group, TRUE);
+ gPipeline.markRebuild(group);
}
}
}
@@ -252,7 +250,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerTexture *texturep)
if (mDrawablep)
{
- gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_ALL);
}
}
mGeomIndex = 0;
@@ -334,7 +332,7 @@ void LLFace::dirtyTexture()
vobj->updateVisualComplexity();
}
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, FALSE);
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
}
}
}
@@ -342,34 +340,6 @@ void LLFace::dirtyTexture()
gPipeline.markTextured(drawablep);
}
-void LLFace::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{
- LLDrawable* drawablep = getDrawable();
- if(mVObjp.notNull() && mVObjp->getVolume())
- {
- LLVOVolume *vobj = drawablep->getVOVolume();
- if(vobj && vobj->notifyAboutCreatingTexture(texture))
- {
- gPipeline.markTextured(drawablep);
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
- }
- }
-}
-
-void LLFace::notifyAboutMissingAsset(LLViewerTexture *texture)
-{
- LLDrawable* drawablep = getDrawable();
- if(mVObjp.notNull() && mVObjp->getVolume())
- {
- LLVOVolume *vobj = drawablep->getVOVolume();
- if(vobj && vobj->notifyAboutMissingAsset(texture))
- {
- gPipeline.markTextured(drawablep);
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
- }
- }
-}
-
void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
{
llassert(ch < LLRender::NUM_TEXTURE_CHANNELS);
@@ -387,11 +357,9 @@ void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture)
llassert(mTexture[ch].notNull());
- new_texture->addTextureStats(mTexture[ch]->getMaxVirtualSize()) ;
-
if (ch == LLRender::DIFFUSE_MAP)
{
- getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
+ getViewerObject()->changeTEImage(mTEOffset, new_texture) ;
}
setTexture(ch, new_texture) ;
@@ -567,6 +535,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
if (mDrawablep->isState(LLDrawable::RIGGED))
{
+#if 0 // TODO -- there is no way this won't destroy our GL machine as implemented, rewrite it to not rely on software skinning
LLVOVolume* volume = mDrawablep->getVOVolume();
if (volume)
{
@@ -586,17 +555,17 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
glTexCoordPointer(2, GL_FLOAT, 8, vol_face.mTexCoords);
}
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x00FF00 );
glDrawElements(GL_TRIANGLES, vol_face.mNumIndices, GL_UNSIGNED_SHORT, vol_face.mIndices);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}
}
+#endif
}
else
{
// cheaters sometimes prosper...
//
- mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask());
+ mVertexBuffer->setBuffer();
mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex);
}
@@ -644,14 +613,6 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
}
else
{
- LLGLEnable fog(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
- LLColor4 fogCol = color * fogCfx;
- glFogf(GL_FOG_START, d);
- glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
- glFogfv(GL_FOG_COLOR, fogCol.mV);
-
gGL.flush();
{
gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
@@ -667,7 +628,7 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
{
LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
- LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+ //LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
if (!wireframe_selection)
{ //modify wireframe into outline selection mode
@@ -683,54 +644,8 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram
}
}
-/* removed in lieu of raycast uv detection
-void LLFace::renderSelectedUV()
-{
- LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI);
- LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI);
-
- LLGLSUVSelect object_select;
-
- // use red/blue gradient to get coarse UV coordinates
- renderSelected(red_blue_imagep, LLColor4::white);
-
- static F32 bias = 0.f;
- static F32 factor = -10.f;
- glPolygonOffset(factor, bias);
-
- // add green dither pattern on top of red/blue gradient
- gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.pushMatrix();
- // make green pattern repeat once per texel in red/blue texture
- gGL.scalef(256.f, 256.f, 1.f);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- renderSelected(green_imagep, LLColor4::white);
-
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
-}
-*/
-
void LLFace::setDrawInfo(LLDrawInfo* draw_info)
{
- if (draw_info)
- {
- if (draw_info->mFace)
- {
- draw_info->mFace->setDrawInfo(NULL);
- }
- draw_info->mFace = this;
- }
-
- if (mDrawInfo)
- {
- mDrawInfo->mFace = NULL;
- }
-
mDrawInfo = draw_info;
}
@@ -1166,21 +1081,27 @@ void LLFace::updateRebuildFlags()
bool LLFace::canRenderAsMask()
{
- if (LLPipeline::sNoAlpha)
+ const LLTextureEntry* te = getTextureEntry();
+ if( !te || !getViewerObject() || !getTexture() )
{
- return true;
+ return false;
}
+ if (te->getGLTFRenderMaterial())
+ {
+ return false;
+ }
+
+ if (LLPipeline::sNoAlpha)
+ {
+ return true;
+ }
+
if (isState(LLFace::RIGGED))
{ // never auto alpha-mask rigged faces
return false;
}
- const LLTextureEntry* te = getTextureEntry();
- if( !te || !getViewerObject() || !getTexture() )
- {
- return false;
- }
LLMaterial* mat = te->getMaterialParams();
if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
@@ -1192,75 +1113,19 @@ bool LLFace::canRenderAsMask()
(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
getTexture()->getIsAlphaMask()) // texture actually qualifies for masking (lazily recalculated but expensive)
{
- if (LLPipeline::sRenderDeferred)
- {
- if (getViewerObject()->isHUDAttachment() || te->getFullbright())
- { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe
- return LLPipeline::sAutoMaskAlphaNonDeferred;
- }
- else
- {
- return LLPipeline::sAutoMaskAlphaDeferred;
- }
+ if (getViewerObject()->isHUDAttachment() || te->getFullbright())
+ { //hud attachments and fullbright objects are NOT subject to the deferred rendering pipe
+ return LLPipeline::sAutoMaskAlphaNonDeferred;
}
else
{
- return LLPipeline::sAutoMaskAlphaNonDeferred;
+ return LLPipeline::sAutoMaskAlphaDeferred;
}
}
return false;
}
-
-//static
-void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL;
-
- if (vf.mWeights)
- {
- mask |= LLVertexBuffer::MAP_WEIGHT4;
- }
-
- LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW_ARB);
- vf.mVertexBuffer = buff;
-
- buff->allocateBuffer(vf.mNumVertices, 0, true);
-
- LLStrider<LLVector4a> f_vert;
- LLStrider<LLVector4a> f_tangent;
- LLStrider<LLVector3> f_norm;
- LLStrider<LLVector2> f_tc;
-
- buff->getTangentStrider(f_tangent);
- buff->getVertexStrider(f_vert);
- buff->getNormalStrider(f_norm);
- buff->getTexCoord0Strider(f_tc);
-
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- *f_vert++ = vf.mPositions[i];
- *f_tangent++ = vf.mTangents[i];
- *f_tc++ = vf.mTexCoords[i];
- (*f_norm++).set(vf.mNormals[i].getF32ptr());
- }
-
- if (vf.mWeights)
- {
- LLStrider<LLVector4> f_wght;
- buff->getWeight4Strider(f_wght);
- for (U32 i = 0; i < vf.mNumVertices; ++i)
- {
- (*f_wght++).set(vf.mWeights[i].getF32ptr());
- }
- }
-
- buff->flush();
-}
-
//helper function for pushing primitives for transform shaders and cleaning up
//uninitialized data on the tail, plus tracking number of expected primitives
void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
@@ -1279,22 +1144,32 @@ void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count)
}
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
- const S32 &f,
- const LLMatrix4& mat_vert_in, const LLMatrix3& mat_norm_in,
- const U16 &index_offset,
- bool force_rebuild)
+ S32 face_index,
+ const LLMatrix4& mat_vert_in,
+ const LLMatrix3& mat_norm_in,
+ U16 index_offset,
+ bool force_rebuild,
+ bool no_debug_assert)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE;
llassert(verify());
- if (volume.getNumVolumeFaces() <= f) {
- LL_WARNS() << "Attempt get volume face out of range! Total Faces: " << volume.getNumVolumeFaces() << " Attempt get access to: " << f << LL_ENDL;
- return FALSE;
- }
+ if (face_index < 0 || face_index >= volume.getNumVolumeFaces())
+ {
+ if (gDebugGL)
+ {
+ LL_WARNS() << "Face index is out of bounds!" << LL_ENDL;
+ LL_WARNS() << "Attempt get volume face out of range!"
+ " Total Faces: " << volume.getNumVolumeFaces() <<
+ " Attempt get access to: " << face_index << LL_ENDL;
+ llassert(no_debug_assert);
+ }
+ return FALSE;
+ }
bool rigged = isState(RIGGED);
- const LLVolumeFace &vf = volume.getVolumeFace(f);
+ const LLVolumeFace &vf = volume.getVolumeFace(face_index);
S32 num_vertices = (S32)vf.mNumVertices;
S32 num_indices = (S32) vf.mNumIndices;
@@ -1303,23 +1178,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
updateRebuildFlags();
}
-
- //don't use map range (generates many redundant unmap calls)
- bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange;
-
if (mVertexBuffer.notNull())
{
if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices())
{
if (gDebugGL)
{
- LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
+ LL_WARNS() << "Index buffer overflow!" << LL_ENDL;
LL_WARNS() << "Indices Count: " << mIndicesCount
<< " VF Num Indices: " << num_indices
<< " Indices Index: " << mIndicesIndex
<< " VB Num Indices: " << mVertexBuffer->getNumIndices() << LL_ENDL;
- LL_WARNS() << " Face Index: " << f
+ LL_WARNS() << " Face Index: " << face_index
<< " Pool Type: " << mPoolType << LL_ENDL;
+ llassert(no_debug_assert);
}
return FALSE;
}
@@ -1329,6 +1201,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (gDebugGL)
{
LL_WARNS() << "Vertex buffer overflow!" << LL_ENDL;
+ llassert(no_debug_assert);
}
return FALSE;
}
@@ -1365,7 +1238,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
bool rebuild_tangent = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TANGENT);
bool rebuild_weights = rebuild_pos && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_WEIGHT4);
- const LLTextureEntry *tep = mVObjp->getTE(f);
+ const LLTextureEntry *tep = mVObjp->getTE(face_index);
const U8 bump_code = tep ? tep->getBumpmap() : 0;
BOOL is_static = mDrawablep->isStatic();
@@ -1384,28 +1257,24 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLColor4U color = tep->getColor();
+ if (tep->getGLTFRenderMaterial())
+ {
+ color = tep->getGLTFRenderMaterial()->mBaseColor;
+ }
+
if (rebuild_color)
{ //decide if shiny goes in alpha channel of color
if (tep &&
- getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny
+ !isInAlphaPool()) // <--- alpha channel MUST contain transparency, not shiny
{
LLMaterial* mat = tep->getMaterialParams().get();
bool shiny_in_alpha = false;
- if (LLPipeline::sRenderDeferred)
- { //store shiny in alpha if we don't have a specular map
- if (!mat || mat->getSpecularID().isNull())
- {
- shiny_in_alpha = true;
- }
- }
- else
+ //store shiny in alpha if we don't have a specular map
+ if (!mat || mat->getSpecularID().isNull())
{
- if (!mat || mat->getDiffuseAlphaMode() != LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
- {
- shiny_in_alpha = true;
- }
+ shiny_in_alpha = true;
}
if (shiny_in_alpha)
@@ -1428,7 +1297,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (full_rebuild)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices");
- mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range);
+ mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount);
volatile __m128i* dst = (__m128i*) indicesp.get();
__m128i* src = (__m128i*) vf.mIndices;
@@ -1451,46 +1320,77 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
*idx++ = vf.mIndices[i]+index_offset;
}
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
+
+ LLMaterial* mat = tep->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial();
+
F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0;
- bool do_xform = false;
- if (rebuild_tcoord)
- {
- if (tep)
- {
- r = tep->getRotation();
- os = tep->mOffsetS;
- ot = tep->mOffsetT;
- ms = tep->mScaleS;
- mt = tep->mScaleT;
- cos_ang = cos(r);
- sin_ang = sin(r);
-
- if (cos_ang != 1.f ||
- sin_ang != 0.f ||
- os != 0.f ||
- ot != 0.f ||
- ms != 1.f ||
- mt != 1.f)
- {
- do_xform = true;
- }
- else
- {
- do_xform = false;
- }
- }
- else
- {
- do_xform = false;
- }
- }
+
+ constexpr S32 XFORM_NONE = 0;
+ constexpr S32 XFORM_BLINNPHONG_COLOR = 1;
+ constexpr S32 XFORM_BLINNPHONG_NORMAL = 1 << 1;
+ constexpr S32 XFORM_BLINNPHONG_SPECULAR = 1 << 2;
+
+ S32 xforms = XFORM_NONE;
+ // For GLTF, transforms will be applied later
+ if (rebuild_tcoord && tep && !gltf_mat)
+ {
+ r = tep->getRotation();
+ os = tep->mOffsetS;
+ ot = tep->mOffsetT;
+ ms = tep->mScaleS;
+ mt = tep->mScaleT;
+ cos_ang = cos(r);
+ sin_ang = sin(r);
+
+ if (cos_ang != 1.f ||
+ sin_ang != 0.f ||
+ os != 0.f ||
+ ot != 0.f ||
+ ms != 1.f ||
+ mt != 1.f)
+ {
+ xforms |= XFORM_BLINNPHONG_COLOR;
+ }
+ if (mat)
+ {
+ F32 r_norm = 0, os_norm = 0, ot_norm = 0, ms_norm = 0, mt_norm = 0, cos_ang_norm = 0, sin_ang_norm = 0;
+ mat->getNormalOffset(os_norm, ot_norm);
+ mat->getNormalRepeat(ms_norm, mt_norm);
+ r_norm = mat->getNormalRotation();
+ cos_ang_norm = cos(r_norm);
+ sin_ang_norm = sin(r_norm);
+ if (cos_ang_norm != 1.f ||
+ sin_ang_norm != 0.f ||
+ os_norm != 0.f ||
+ ot_norm != 0.f ||
+ ms_norm != 1.f ||
+ mt_norm != 1.f)
+ {
+ xforms |= XFORM_BLINNPHONG_NORMAL;
+ }
+ }
+ if (mat)
+ {
+ F32 r_spec = 0, os_spec = 0, ot_spec = 0, ms_spec = 0, mt_spec = 0, cos_ang_spec = 0, sin_ang_spec = 0;
+ mat->getSpecularOffset(os_spec, ot_spec);
+ mat->getSpecularRepeat(ms_spec, mt_spec);
+ r_spec = mat->getSpecularRotation();
+ cos_ang_spec = cos(r_spec);
+ sin_ang_spec = sin(r_spec);
+ if (cos_ang_spec != 1.f ||
+ sin_ang_spec != 0.f ||
+ os_spec != 0.f ||
+ ot_spec != 0.f ||
+ ms_spec != 1.f ||
+ mt_spec != 1.f)
+ {
+ xforms |= XFORM_BLINNPHONG_SPECULAR;
+ }
+ }
+ }
const LLMeshSkinInfo* skin = nullptr;
LLMatrix4a mat_vert;
@@ -1531,155 +1431,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
-#ifdef GL_TRANSFORM_FEEDBACK_BUFFER
- if (use_transform_feedback &&
- mVertexBuffer->getUsage() == GL_DYNAMIC_COPY_ARB &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- mVertexBuffer->useVBOs() && //target buffer is in VRAM
- !rebuild_weights && //TODO: add support for weights
- !volume.isUnique()) //source volume is NOT flexi
- { //use transform feedback to pack vertex buffer
-
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback");
- LLGLEnable discard(GL_RASTERIZER_DISCARD);
- LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
-
- if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices)
- {
- mVObjp->getVolume()->genTangents(f);
- LLFace::cacheFaceInVRAM(vf);
- buff = (LLVertexBuffer*) vf.mVertexBuffer.get();
- }
-
- LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
-
- gGL.pushMatrix();
- gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix);
-
- if (rebuild_pos)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position");
- gTransformPositionProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount);
-
- U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0;
-
- S32 val = 0;
- U8* vp = (U8*) &val;
- vp[0] = index;
- vp[1] = 0;
- vp[2] = 0;
- vp[3] = 0;
-
- gTransformPositionProgram.uniform1i(sTextureIndexIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
-
- glEndTransformFeedback();
- }
-
- if (rebuild_color)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount);
-
- S32 val = *((S32*) color.mV);
-
- gTransformColorProgram.uniform1i(sColorIn, val);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_emissive)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive");
- gTransformColorProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount);
-
- U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
-
- S32 glow32 = glow |
- (glow << 8) |
- (glow << 16) |
- (glow << 24);
-
- gTransformColorProgram.uniform1i(sColorIn, glow32);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_normal)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal");
- gTransformNormalProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_NORMAL);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tangent)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent");
- gTransformTangentProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TANGENT);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
-
- if (rebuild_tcoord)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord");
- gTransformTexCoordProgram.bind();
-
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount);
-
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
-
- bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
-
- if (do_bump)
- {
- mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount);
- glBeginTransformFeedback(GL_POINTS);
- buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0);
- push_for_transform(buff, vf.mNumVertices, mGeomCount);
- glEndTransformFeedback();
- }
- }
-
- glBindBufferARB(GL_TRANSFORM_FEEDBACK_BUFFER, 0);
- gGL.popMatrix();
-
- if (cur_shader)
- {
- cur_shader->bind();
- }
- }
- else
-#endif
{
//if it's not fullbright and has no normals, bake sunlight based on face normal
//bool bake_sunlight = !getTextureEntry()->getFullbright() &&
@@ -1702,7 +1453,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
if (bump_code)
{
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
F32 offset_multiple;
switch( bump_code )
{
@@ -1751,7 +1502,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
U8 texgen = getTextureEntry()->getTexGen();
if (rebuild_tcoord && texgen != LLTextureEntry::TEX_GEN_DEFAULT)
{ //planar texgen needs binormals
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
}
U8 tex_mode = 0;
@@ -1780,7 +1531,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
sin_ang = 0.f;
ms = mt = 1.f;
- do_xform = false;
+ xforms = XFORM_NONE;
}
if (getVirtualSize() >= MIN_TEX_ANIM_SIZE) // || isState(LLFace::RIGGED))
@@ -1792,17 +1543,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LLVector4a scalea;
scalea.load3(scale.mV);
- LLMaterial* mat = tep->getMaterialParams().get();
-
bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1);
- if (mat && !do_bump)
+ if ((mat || gltf_mat) && !do_bump)
{
do_bump = mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)
|| mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2);
}
- bool do_tex_mat = tex_mode && mTextureMatrix;
+ // For GLTF materials: Transforms will be applied later
+ bool do_tex_mat = tex_mode && mTextureMatrix && !gltf_mat;
if (!do_bump)
{ //not bump mapped, might be able to do a cheap update
@@ -1813,7 +1563,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - texgen");
if (!do_tex_mat)
{
- if (!do_xform)
+ if (xforms == XFORM_NONE)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("ggv - texgen 1");
S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF;
@@ -1892,7 +1642,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
*tex_coords0++ = tc;
}
}
- else
+ else if (xforms != XFORM_NONE)
{
for (S32 i = 0; i < num_vertices; i++)
{
@@ -1908,11 +1658,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
*tex_coords0++ = tc;
}
}
- }
+ else
+ {
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+ LLVector4a& norm = vf.mNormals[i];
+ LLVector4a& center = *(vf.mCenter);
+ LLVector4a vec = vf.mPositions[i];
+ vec.mul(scalea);
+ planarProjection(tc, norm, center, vec);
- if (map_range)
- {
- mVertexBuffer->flush();
+ *tex_coords0++ = tc;
+ }
+ }
}
}
else
@@ -1930,15 +1689,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
for (U32 ch = 0; ch < 3; ++ch)
{
+ S32 xform_channel = XFORM_NONE;
switch (ch)
{
case 0:
- mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range);
+ xform_channel = XFORM_BLINNPHONG_COLOR;
+ mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount);
break;
case 1:
+ xform_channel = XFORM_BLINNPHONG_NORMAL;
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1))
{
- mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount);
if (mat && !tex_anim)
{
r = mat->getNormalRotation();
@@ -1956,9 +1718,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
break;
case 2:
+ xform_channel = XFORM_BLINNPHONG_SPECULAR;
if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2))
{
- mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount);
if (mat && !tex_anim)
{
r = mat->getSpecularRotation();
@@ -1975,57 +1738,55 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
}
break;
}
+ const bool do_xform = (xforms & xform_channel) != XFORM_NONE;
- for (S32 i = 0; i < num_vertices; i++)
- {
- LLVector2 tc(vf.mTexCoords[i]);
-
- LLVector4a& norm = vf.mNormals[i];
-
- LLVector4a& center = *(vf.mCenter);
-
- if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
- {
- LLVector4a vec = vf.mPositions[i];
-
- vec.mul(scalea);
-
- if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
- {
- planarProjection(tc, norm, center, vec);
- }
- }
-
- if (tex_mode && mTextureMatrix)
- {
- LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
- tmp = tmp * *mTextureMatrix;
- tc.mV[0] = tmp.mV[0];
- tc.mV[1] = tmp.mV[1];
- }
- else
- {
- xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
- }
-
- *dst++ = tc;
- if (do_bump)
- {
- bump_tc.push_back(tc);
- }
- }
+ for (S32 i = 0; i < num_vertices; i++)
+ {
+ LLVector2 tc(vf.mTexCoords[i]);
+
+ LLVector4a& norm = vf.mNormals[i];
+
+ LLVector4a& center = *(vf.mCenter);
+
+ if (texgen != LLTextureEntry::TEX_GEN_DEFAULT)
+ {
+ LLVector4a vec = vf.mPositions[i];
+
+ vec.mul(scalea);
+
+ if (texgen == LLTextureEntry::TEX_GEN_PLANAR)
+ {
+ planarProjection(tc, norm, center, vec);
+ }
+ }
+
+ if (tex_mode && mTextureMatrix)
+ {
+ LLVector3 tmp(tc.mV[0], tc.mV[1], 0.f);
+ tmp = tmp * *mTextureMatrix;
+ tc.mV[0] = tmp.mV[0];
+ tc.mV[1] = tmp.mV[1];
+ }
+ else if (do_xform)
+ {
+ xform(tc, cos_ang, sin_ang, os, ot, ms, mt);
+ }
+
+ *dst++ = tc;
+ if (do_bump)
+ {
+ bump_tc.push_back(tc);
+ }
+ }
}
- if (map_range)
+ if ((!mat && !gltf_mat) && do_bump)
{
- mVertexBuffer->flush();
- }
-
- if (!mat && do_bump)
- {
- mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount);
+ mVObjp->getVolume()->genTangents(face_index);
+
for (S32 i = 0; i < num_vertices; i++)
{
LLVector4a tangent = vf.mTangents[i];
@@ -2057,11 +1818,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
*tex_coords1++ = tc;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
}
}
@@ -2077,7 +1833,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
llassert(num_vertices > 0);
- mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount);
F32* dst = (F32*) vert.get();
@@ -2123,18 +1879,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
res0.store4a((F32*) dst);
dst += 4;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
if (rebuild_normal)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - normal");
- mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount);
F32* normals = (F32*) norm.get();
LLVector4a* src = vf.mNormals;
LLVector4a* end = src+num_vertices;
@@ -2146,62 +1897,47 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
normal.store4a(normals);
normals += 4;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
if (rebuild_tangent)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tangent");
- mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount);
F32* tangents = (F32*) tangent.get();
- mVObjp->getVolume()->genTangents(f);
+ mVObjp->getVolume()->genTangents(face_index);
LLVector4Logical mask;
mask.clear();
mask.setElement<3>();
LLVector4a* src = vf.mTangents;
- LLVector4a* end = vf.mTangents+num_vertices;
+ LLVector4a* end = vf.mTangents +num_vertices;
while (src < end)
{
LLVector4a tangent_out;
mat_normal.rotate(*src, tangent_out);
- tangent_out.normalize3fast();
tangent_out.setSelectWithMask(mask, *src, tangent_out);
tangent_out.store4a(tangents);
src++;
tangents += 4;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
if (rebuild_weights && vf.mWeights)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - weight");
- mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount);
F32* weights = (F32*) wght.get();
LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32));
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) )
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - color");
- mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount);
LLVector4a src;
@@ -2222,18 +1958,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
src.store4a(dst);
dst += 4;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
if (rebuild_emissive)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - emissive");
LLStrider<LLColor4U> emissive;
- mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range);
+ mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount);
U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255);
@@ -2261,11 +1992,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
src.store4a(dst);
dst += 4;
}
-
- if (map_range)
- {
- mVertexBuffer->flush();
- }
}
}
@@ -2288,6 +2014,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
return TRUE;
}
+void LLFace::renderIndexed()
+{
+ if (mVertexBuffer.notNull())
+ {
+ mVertexBuffer->setBuffer();
+ mVertexBuffer->drawRange(LLRender::TRIANGLES, getGeomIndex(), getGeomIndex() + getGeomCount()-1, getIndicesCount(), getIndicesStart());
+ }
+}
+
//check if the face has a media
BOOL LLFace::hasMedia() const
{
@@ -2314,6 +2049,7 @@ void LLFace::resetVirtualSize()
F32 LLFace::getTextureVirtualSize()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
F32 radius;
F32 cos_angle_to_view_dir;
BOOL in_frustum = calcPixelArea(cos_angle_to_view_dir, radius);
@@ -2618,97 +2354,12 @@ void LLFace::setViewerObject(LLViewerObject* objp)
mVObjp = objp;
}
-const LLColor4& LLFace::getRenderColor() const
-{
- if (isState(USE_FACE_COLOR))
- {
- return mFaceColor; // Face Color
- }
- else
- {
- const LLTextureEntry* tep = getTextureEntry();
- return (tep ? tep->getColor() : LLColor4::white);
- }
-}
-
-void LLFace::renderSetColor() const
-{
- if (!LLFacePool::LLOverrideFaceColor::sOverrideFaceColor)
- {
- const LLColor4* color = &(getRenderColor());
-
- gGL.diffuseColor4fv(color->mV);
- }
-}
-
-S32 LLFace::pushVertices(const U16* index_array) const
-{
- if (mIndicesCount)
- {
- U32 render_type = LLRender::TRIANGLES;
- if (mDrawInfo)
- {
- render_type = mDrawInfo->mDrawMode;
- }
- mVertexBuffer->drawRange(render_type, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex);
- gPipeline.addTrianglesDrawn(mIndicesCount, render_type);
- }
-
- return mIndicesCount;
-}
const LLMatrix4& LLFace::getRenderMatrix() const
{
return mDrawablep->getRenderMatrix();
}
-S32 LLFace::renderElements(const U16 *index_array) const
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- S32 ret = 0;
-
- if (isState(GLOBAL))
- {
- ret = pushVertices(index_array);
- }
- else
- {
- gGL.pushMatrix();
- gGL.multMatrix((float*)getRenderMatrix().mMatrix);
- ret = pushVertices(index_array);
- gGL.popMatrix();
- }
-
- return ret;
-}
-
-S32 LLFace::renderIndexed()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- if(mDrawablep == NULL || mDrawPoolp == NULL)
- {
- return 0;
- }
-
- return renderIndexed(mDrawPoolp->getVertexDataMask());
-}
-
-S32 LLFace::renderIndexed(U32 mask)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE
-
- if (mVertexBuffer.isNull())
- {
- return 0;
- }
-
- mVertexBuffer->setBuffer(mask);
- U16* index_array = (U16*) mVertexBuffer->getIndicesPointer();
- return renderElements(index_array);
-}
-
//============================================================================
// From llface.inl
@@ -2792,3 +2443,10 @@ U64 LLFace::getSkinHash()
{
return mSkinInfo ? mSkinInfo->mHash : 0;
}
+
+bool LLFace::isInAlphaPool() const
+{
+ return getPoolType() == LLDrawPool::POOL_ALPHA ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_PRE_WATER ||
+ getPoolType() == LLDrawPool::POOL_ALPHA_POST_WATER;
+}
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index aa00c9d052..eb3b47d6d6 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -81,8 +81,6 @@ public:
PARTICLE = 0x0080,
};
- static void cacheFaceInVRAM(const LLVolumeFace& vf);
-
public:
LLFace(LLDrawable* drawablep, LLViewerObject* objp)
{
@@ -127,12 +125,6 @@ public:
S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];}
void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;}
-
- void renderSetColor() const;
- S32 renderElements(const U16 *index_array) const;
- S32 renderIndexed ();
- S32 renderIndexed (U32 mask);
- S32 pushVertices(const U16* index_array) const;
void setWorldMatrix(const LLMatrix4& mat);
const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); }
@@ -153,20 +145,23 @@ public:
void setDrawable(LLDrawable *drawable);
void setTEOffset(const S32 te_offset);
+ void renderIndexed();
void setFaceColor(const LLColor4& color); // override material color
void unsetFaceColor(); // switch back to material color
const LLColor4& getFaceColor() const { return mFaceColor; }
- const LLColor4& getRenderColor() const;
+
//for volumes
void updateRebuildFlags();
bool canRenderAsMask(); // logic helper
BOOL getGeometryVolume(const LLVolume& volume,
- const S32 &f,
- const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
- const U16 &index_offset,
- bool force_rebuild = false);
+ S32 face_index,
+ const LLMatrix4& mat_vert,
+ const LLMatrix3& mat_normal,
+ U16 index_offset,
+ bool force_rebuild = false,
+ bool no_debug_assert = false);
// For avatar
U16 getGeometryAvatar(
@@ -230,19 +225,19 @@ public:
LLVertexBuffer* getVertexBuffer() const { return mVertexBuffer; }
S32 getRiggedIndex(U32 type) const;
- void notifyAboutCreatingTexture(LLViewerTexture *texture);
- void notifyAboutMissingAsset(LLViewerTexture *texture);
-
// used to preserve draw order of faces that are batched together.
// Allows content creators to manipulate linked sets and face ordering
// for consistent alpha sorting results, particularly for rigged attachments
void setDrawOrderIndex(U32 index) { mDrawOrderIndex = index; }
U32 getDrawOrderIndex() const { return mDrawOrderIndex; }
+ // return true if this face is in an alpha draw pool
+ bool isInAlphaPool() const;
public: //aligned members
LLVector4a mExtents[2];
private:
+ friend class LLViewerTextureList;
F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius );
BOOL calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ;
public:
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 9bb3bac104..5b8ca6c49c 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -468,7 +468,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
{
//allocate render target for drawing charts
LLRenderTarget buffer;
- buffer.allocate(1024,512, GL_RGB, FALSE, FALSE);
+ buffer.allocate(1024,512, GL_RGB);
LLSD cur;
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index c7f3ef3490..f482d5a37d 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -408,7 +408,7 @@ bool LLFeatureManager::loadGPUClass()
{
if (!gSavedSettings.getBOOL("SkipBenchmark"))
{
- F32 class0_gbps = gSavedSettings.getF32("RenderClass0MemoryBandwidth");
+ F32 class1_gbps = gSavedSettings.getF32("RenderClass1MemoryBandwidth");
//get memory bandwidth from benchmark
F32 gbps;
try
@@ -434,64 +434,28 @@ bool LLFeatureManager::loadGPUClass()
gbps *= cpu_bias;
if (gbps < 0.f)
- { //couldn't bench, use GLVersion
+ { //couldn't bench, default to Low
#if LL_DARWIN
//GLVersion is misleading on OSX, just default to class 3 if we can't bench
LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL;
mGPUClass = GPU_CLASS_3;
#else
- if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
- else if (gGLManager.mGLVersion < 3.3f)
- {
- mGPUClass = GPU_CLASS_2;
- }
- else if (gGLManager.mGLVersion < 4.f)
- {
- mGPUClass = GPU_CLASS_3;
- }
- else
- {
- mGPUClass = GPU_CLASS_4;
- }
- if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1)
- {
- // Intels are generally weaker then other GPUs despite having advanced features
- mGPUClass = (EGPUClass)(mGPUClass - 1);
- }
- #endif
- }
- else if (gGLManager.mGLVersion <= 2.f)
- {
- mGPUClass = GPU_CLASS_0;
- }
- else if (gGLManager.mGLVersion <= 3.f)
- {
- mGPUClass = GPU_CLASS_1;
- }
- else if (gbps <= class0_gbps)
- {
mGPUClass = GPU_CLASS_0;
+ #endif
}
- else if (gbps <= class0_gbps*2.f)
+ else if (gbps <= class1_gbps)
{
mGPUClass = GPU_CLASS_1;
}
- else if (gbps <= class0_gbps*4.f)
+ else if (gbps <= class1_gbps *2.f)
{
mGPUClass = GPU_CLASS_2;
}
- else if (gbps <= class0_gbps*8.f)
+ else if (gbps <= class1_gbps*4.f)
{
mGPUClass = GPU_CLASS_3;
}
- else if (gbps <= class0_gbps*16.f)
+ else if (gbps <= class1_gbps*8.f)
{
mGPUClass = GPU_CLASS_4;
}
@@ -628,7 +592,7 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
{
LLViewerShaderMgr::sSkipReload = true;
-
+ flush_glerror(); // Whatever may have already happened (e.g., to cause us to change), don't let confuse it with new initializations.
applyBaseMasks();
// if we're passed an invalid level, default to "Low"
@@ -700,22 +664,18 @@ void LLFeatureManager::applyBaseMasks()
{
maskFeatures("TexUnit8orLess");
}
- if (gGLManager.mHasMapBufferRange)
- {
- maskFeatures("MapBufferRange");
- }
if (gGLManager.mVRAM > 512)
{
maskFeatures("VRAMGT512");
}
-
-#if LL_DARWIN
- const LLOSInfo& osInfo = LLOSInfo::instance();
- if (osInfo.mMajorVer == 10 && osInfo.mMinorVer < 7)
- {
- maskFeatures("OSX_10_6_8");
- }
-#endif
+ if (gGLManager.mVRAM < 2048)
+ {
+ maskFeatures("VRAMLT2GB");
+ }
+ if (gGLManager.mGLVersion < 3.99f)
+ {
+ maskFeatures("GL3");
+ }
// now mask by gpu string
// Replaces ' ' with '_' in mGPUString to deal with inability for parser to handle spaces
diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp
new file mode 100644
index 0000000000..1a47293523
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.cpp
@@ -0,0 +1,254 @@
+/**
+ * @file llfetchedgltfmaterial.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfetchedgltfmaterial.h"
+
+#include "llviewertexturelist.h"
+#include "llavatarappearancedefines.h"
+#include "llshadermgr.h"
+#include "pipeline.h"
+
+LLFetchedGLTFMaterial::LLFetchedGLTFMaterial()
+ : LLGLTFMaterial()
+ , mExpectedFlusTime(0.f)
+ , mActive(true)
+ , mFetching(false)
+{
+
+}
+
+LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial()
+{
+
+}
+
+LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs)
+{
+ LLGLTFMaterial::operator =(rhs);
+
+ mBaseColorTexture = rhs.mBaseColorTexture;
+ mNormalTexture = rhs.mNormalTexture;
+ mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture;
+ mEmissiveTexture = rhs.mEmissiveTexture;
+
+ return *this;
+}
+
+void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex)
+{
+ // glTF 2.0 Specification 3.9.4. Alpha Coverage
+ // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK
+ F32 min_alpha = -1.0;
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ // override emissive and base color textures with media tex if present
+ LLViewerTexture* baseColorTex = media_tex ? media_tex : mBaseColorTexture;
+ LLViewerTexture* emissiveTex = media_tex ? media_tex : mEmissiveTexture;
+
+ if (!LLPipeline::sShadowRender || (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK))
+ {
+ if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ // dividing the alpha cutoff by transparency here allows the shader to compare against
+ // the alpha value of the texture without needing the transparency value
+ min_alpha = mAlphaCutoff/mBaseColor.mV[3];
+ }
+ shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha);
+ }
+
+ if (baseColorTex != nullptr)
+ {
+ shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, baseColorTex);
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::DIFFUSE_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ F32 base_color_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed);
+
+ if (!LLPipeline::sShadowRender)
+ {
+ if (mNormalTexture.notNull() && mNormalTexture->getDiscardLevel() <= 4)
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture);
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep);
+ }
+
+ if (mMetallicRoughnessTexture.notNull())
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, mMetallicRoughnessTexture); // PBR linear packed Occlusion, Roughness, Metal.
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ if (emissiveTex != nullptr)
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, emissiveTex); // PBR sRGB Emissive
+ }
+ else
+ {
+ shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep);
+ }
+
+ // NOTE: base color factor is baked into vertex stream
+
+ shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor);
+ shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor);
+ shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV);
+
+ F32 normal_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, (F32*)normal_packed);
+
+ F32 metallic_roughness_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].getPacked(metallic_roughness_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, 2, (F32*)metallic_roughness_packed);
+
+ F32 emissive_packed[8];
+ mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].getPacked(emissive_packed);
+ shader->uniform4fv(LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM, 2, (F32*)emissive_packed);
+ }
+
+}
+
+LLViewerFetchedTexture* fetch_texture(const LLUUID& id)
+{
+ LLViewerFetchedTexture* img = nullptr;
+ if (id.notNull())
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ img->addTextureStats(64.f * 64.f, TRUE);
+ }
+ return img;
+};
+
+bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
+{
+ bool res = false;
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = new_id;
+ mBaseColorTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = new_id;
+ mNormalTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = new_id;
+ mMetallicRoughnessTexture = fetch_texture(new_id);
+ res = true;
+ }
+ if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] == old_id)
+ {
+ mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = new_id;
+ mEmissiveTexture = fetch_texture(new_id);
+ res = true;
+ }
+
+ for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i)
+ {
+ if (mTextureId[i] == new_id)
+ {
+ res = true;
+ }
+ }
+
+ if (res)
+ {
+ mTrackingIdToLocalTexture[tracking_id] = new_id;
+ }
+ else
+ {
+ mTrackingIdToLocalTexture.erase(tracking_id);
+ }
+
+ return res;
+}
+
+void LLFetchedGLTFMaterial::addTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.insert(te);
+}
+
+void LLFetchedGLTFMaterial::removeTextureEntry(LLTextureEntry* te)
+{
+ mTextureEntires.erase(te);
+}
+
+void LLFetchedGLTFMaterial::updateTextureTracking()
+{
+ for (local_tex_map_t::value_type &val : mTrackingIdToLocalTexture)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this);
+ }
+}
+
+void LLFetchedGLTFMaterial::materialBegin()
+{
+ llassert(!mFetching);
+ mFetching = true;
+}
+
+void LLFetchedGLTFMaterial::onMaterialComplete(std::function<void()> material_complete)
+{
+ if (!material_complete) { return; }
+
+ if (!mFetching)
+ {
+ material_complete();
+ return;
+ }
+
+ materialCompleteCallbacks.push_back(material_complete);
+}
+
+void LLFetchedGLTFMaterial::materialComplete()
+{
+ llassert(mFetching);
+ mFetching = false;
+
+ for (std::function<void()> material_complete : materialCompleteCallbacks)
+ {
+ material_complete();
+ }
+ materialCompleteCallbacks.clear();
+ materialCompleteCallbacks.shrink_to_fit();
+}
diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h
new file mode 100644
index 0000000000..2559aa46cc
--- /dev/null
+++ b/indra/newview/llfetchedgltfmaterial.h
@@ -0,0 +1,77 @@
+/**
+ * @file llfetchedgltfmaterial.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+#include "llviewertexture.h"
+
+class LLGLSLShader;
+
+class LLFetchedGLTFMaterial: public LLGLTFMaterial
+{
+ friend class LLGLTFMaterialList; // for lifetime management
+public:
+ LLFetchedGLTFMaterial();
+ virtual ~LLFetchedGLTFMaterial();
+
+ LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs);
+
+ // If this material is loaded, fire the given function
+ void onMaterialComplete(std::function<void()> material_complete);
+
+ // bind this material for rendering
+ // media_tex - optional media texture that may override the base color texture
+ void bind(LLViewerTexture* media_tex = nullptr);
+
+ bool isFetching() const { return mFetching; }
+
+ void addTextureEntry(LLTextureEntry* te) override;
+ void removeTextureEntry(LLTextureEntry* te) override;
+ virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override;
+ virtual void updateTextureTracking() override;
+
+ // Textures used for fetching/rendering
+ LLPointer<LLViewerFetchedTexture> mBaseColorTexture;
+ LLPointer<LLViewerFetchedTexture> mNormalTexture;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessTexture;
+ LLPointer<LLViewerFetchedTexture> mEmissiveTexture;
+
+ std::set<LLTextureEntry*> mTextureEntires;
+
+protected:
+ // Lifetime management
+
+ void materialBegin();
+ void materialComplete();
+
+ F64 mExpectedFlusTime; // since epoch in seconds
+ bool mActive;
+ bool mFetching;
+ std::vector<std::function<void()>> materialCompleteCallbacks;
+};
+
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index f1f156c2e0..4ad136e13a 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -55,10 +55,13 @@ LLFilePicker LLFilePicker::sInstance;
#define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0"
#define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0"
+#define GLTF_FILTER L"glTF (*.gltf; *.glb)\0*.gltf;*.glb\0"
#define XML_FILTER L"XML files (*.xml)\0*.xml\0"
#define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
#define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0"
+#define MATERIAL_FILTER L"GLTF Files (*.gltf; *.glb)\0*.gltf;*.glb\0"
+#define MATERIAL_TEXTURES_FILTER L"GLTF Import (*.gltf; *.glb; *.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.gltf;*.glb;*.tga;*.bmp;*.jpg;*.jpeg;*.png\0"
#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0"
#define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0"
#endif
@@ -176,6 +179,7 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
SOUND_FILTER \
IMAGE_FILTER \
ANIM_FILTER \
+ MATERIAL_FILTER \
L"\0";
break;
case FFLOAD_WAV:
@@ -190,6 +194,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = ANIM_FILTER \
L"\0";
break;
+ case FFLOAD_GLTF:
+ mOFN.lpstrFilter = GLTF_FILTER \
+ L"\0";
+ break;
case FFLOAD_COLLADA:
mOFN.lpstrFilter = COLLADA_FILTER \
L"\0";
@@ -210,6 +218,16 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
mOFN.lpstrFilter = MODEL_FILTER \
L"\0";
break;
+ case FFLOAD_MATERIAL:
+ mOFN.lpstrFilter = MATERIAL_FILTER \
+ L"\0";
+ break;
+ case FFLOAD_MATERIAL_TEXTURE:
+ mOFN.lpstrFilter = MATERIAL_TEXTURES_FILTER \
+ MATERIAL_FILTER \
+ IMAGE_FILTER \
+ L"\0";
+ break;
case FFLOAD_SCRIPT:
mOFN.lpstrFilter = SCRIPT_FILTER \
L"\0";
@@ -489,6 +507,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
L"XAF Anim File (*.xaf)\0*.xaf\0" \
L"\0";
break;
+ case FFSAVE_GLTF:
+ if (filename.empty())
+ {
+ wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/
+ }
+ mOFN.lpstrDefExt = L"glb";
+ mOFN.lpstrFilter =
+ L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \
+ L"\0";
+ break;
case FFSAVE_XML:
if (filename.empty())
{
@@ -608,6 +636,8 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
allowedv->push_back("dic");
allowedv->push_back("xcu");
allowedv->push_back("gif");
+ allowedv->push_back("gltf");
+ allowedv->push_back("glb");
case FFLOAD_IMAGE:
allowedv->push_back("jpg");
allowedv->push_back("jpeg");
@@ -628,6 +658,11 @@ std::unique_ptr<std::vector<std::string>> LLFilePicker::navOpenFilterProc(ELoadF
allowedv->push_back("bvh");
allowedv->push_back("anim");
break;
+ case FFLOAD_GLTF:
+ case FFLOAD_MATERIAL:
+ allowedv->push_back("gltf");
+ allowedv->push_back("glb");
+ break;
case FFLOAD_COLLADA:
allowedv->push_back("dae");
break;
@@ -745,6 +780,11 @@ void set_nav_save_data(LLFilePicker::ESaveFilter filter, std::string &extension,
creator = "\?\?\?\?";
extension = "xaf";
break;
+ case LLFilePicker::FFSAVE_GLTF:
+ type = "\?\?\?\?";
+ creator = "\?\?\?\?";
+ extension = "glb";
+ break;
case LLFilePicker::FFSAVE_XML:
type = "\?\?\?\?";
@@ -1468,10 +1508,13 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
case FFLOAD_XML:
filtername = add_xml_filter_to_gtkchooser(picker);
break;
- case FFLOAD_COLLADA:
- filtername = add_collada_filter_to_gtkchooser(picker);
- break;
- case FFLOAD_IMAGE:
+ case FFLOAD_GLTF:
+ filtername = dead_code_should_blow_up_here(picker);
+ break;
+ case FFLOAD_COLLADA:
+ filtername = add_collada_filter_to_gtkchooser(picker);
+ break;
+ case FFLOAD_IMAGE:
filtername = add_imageload_filter_to_gtkchooser(picker);
break;
case FFLOAD_SCRIPT:
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 692b908fff..38daff9937 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -77,6 +77,7 @@ public:
FFLOAD_WAV = 2,
FFLOAD_IMAGE = 3,
FFLOAD_ANIM = 4,
+ FFLOAD_GLTF = 5,
FFLOAD_XML = 6,
FFLOAD_SLOBJECT = 7,
FFLOAD_RAW = 8,
@@ -85,7 +86,9 @@ public:
FFLOAD_SCRIPT = 11,
FFLOAD_DICTIONARY = 12,
FFLOAD_DIRECTORY = 13, // To call from lldirpicker.
- FFLOAD_EXE = 14 // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_EXE = 14, // Note: EXE will be treated as ALL on Windows and Linux but not on Darwin
+ FFLOAD_MATERIAL = 15,
+ FFLOAD_MATERIAL_TEXTURE = 16,
};
enum ESaveFilter
@@ -96,6 +99,7 @@ public:
FFSAVE_BMP = 5,
FFSAVE_AVI = 6,
FFSAVE_ANIM = 7,
+ FFSAVE_GLTF = 8,
FFSAVE_XML = 9,
FFSAVE_COLLADA = 10,
FFSAVE_RAW = 11,
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index d5115df35f..e935bc5553 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -348,7 +348,7 @@ void LLVolumeImplFlexible::doIdleUpdate()
if (mRenderRes == -1)
{
updateRenderRes();
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION);
}
else
{
@@ -361,12 +361,12 @@ void LLVolumeImplFlexible::doIdleUpdate()
// MAINT-1890 Clamp the update period to ensure that the update_period is no greater than 32 frames
update_period = llclamp(update_period, 1U, 32U);
- // We control how fast flexies update, buy splitting updates among frames
+ // We control how fast flexies update, buy splitting updates among frames
U64 virtual_frame_num = LLTimer::getElapsedSeconds() / SEC_PER_FLEXI_FRAME;
if (visible)
{
- if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1) &&
+ if (!drawablep->isState(LLDrawable::IN_REBUILD_Q) &&
pixel_area > 256.f)
{
U32 id;
@@ -399,7 +399,8 @@ void LLVolumeImplFlexible::doIdleUpdate()
updateRenderRes();
- gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
+ mVO->shrinkWrap();
+ gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION);
}
}
}
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index ec05ba924c..0964daa4d5 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -350,7 +350,7 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry()
// called when the Import List button is pressed
void LLFloaterAutoReplaceSettings::onImportList()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames)
@@ -537,7 +537,7 @@ void LLFloaterAutoReplaceSettings::onExportList()
{
std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
std::string listFileName = listName + ".xml";
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName);
}
void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName)
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index a1a06706bc..abc9cdbcc2 100644
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -76,6 +76,8 @@ BOOL LLFloaterBulkPermission::postBuild()
mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
mBulkChangeIncludeSettings = gSavedSettings.getBOOL("BulkChangeIncludeSettings");
+ mBulkChangeIncludeMaterials = gSavedSettings.getBOOL("BulkChangeIncludeMaterials");
+
mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
@@ -188,6 +190,8 @@ void LLFloaterBulkPermission::onCloseBtn()
gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
gSavedSettings.setBOOL("BulkChangeIncludeSettings", mBulkChangeIncludeSettings);
+ gSavedSettings.setBOOL("BulkChangeIncludeMaterials", mBulkChangeIncludeMaterials);
+
gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
@@ -284,6 +288,7 @@ void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check)
gSavedSettings.setBOOL("BulkChangeIncludeSounds" , check);
gSavedSettings.setBOOL("BulkChangeIncludeTextures" , check);
gSavedSettings.setBOOL("BulkChangeIncludeSettings" , check);
+ gSavedSettings.setBOOL("BulkChangeIncludeMaterials" , check);
}
@@ -306,6 +311,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve
( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) ||
( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) ||
( asstype == LLAssetType::AT_SETTINGS && gSavedSettings.getBOOL("BulkChangeIncludeSettings" )) ||
+ ( asstype == LLAssetType::AT_MATERIAL && gSavedSettings.getBOOL("BulkChangeIncludeMaterials")) ||
( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" )))
{
LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 1afc876bba..ab5d568667 100644
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -103,6 +103,8 @@ private:
bool mBulkChangeIncludeSounds;
bool mBulkChangeIncludeTextures;
bool mBulkChangeIncludeSettings;
+ bool mBulkChangeIncludeMaterials;
+
bool mBulkChangeShareWithGroup;
bool mBulkChangeEveryoneCopy;
bool mBulkChangeNextOwnerModify;
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index ed3dc37043..6e29450ff3 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1113,18 +1113,17 @@ BOOL LLPreviewAnimation::render()
LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
LLQuaternion(mCameraYaw, LLVector3::z_axis);
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
- LLViewerCamera::getInstance()->setOriginAndLookAt(
+ camera->setOriginAndLookAt(
target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
LLVector3::z_axis, // up
target_pos + (mCameraOffset * av_rot) ); // point of interest
- LLViewerCamera::getInstance()->setView(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
- LLViewerCamera::getInstance()->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
-
- mCameraRelPos = LLViewerCamera::getInstance()->getOrigin() - avatarp->mHeadp->getWorldPosition();
-
- //avatarp->setAnimationData("LookAtPoint", (void *)&mCameraRelPos);
+ camera->setViewNoBroadcast(LLViewerCamera::getInstance()->getDefaultFOV() / mCameraZoom);
+ camera->setAspect((F32) mFullWidth / (F32) mFullHeight);
+ camera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, FALSE);
//SJB: Animation is updated in LLVOAvatar::updateCharacter
diff --git a/indra/newview/llfloaterbvhpreview.h b/indra/newview/llfloaterbvhpreview.h
index 20d15d9603..9dfefc5a5f 100644
--- a/indra/newview/llfloaterbvhpreview.h
+++ b/indra/newview/llfloaterbvhpreview.h
@@ -64,7 +64,6 @@ protected:
F32 mCameraPitch;
F32 mCameraZoom;
LLVector3 mCameraOffset;
- LLVector3 mCameraRelPos;
LLPointer<LLVOAvatar> mDummyAvatar;
};
diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp
index 780130039b..0301627c15 100644
--- a/indra/newview/llfloaterchangeitemthumbnail.cpp
+++ b/indra/newview/llfloaterchangeitemthumbnail.cpp
@@ -750,7 +750,6 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)
"SELECT PHOTO",
PERM_NONE,
PERM_NONE,
- PERM_NONE,
FALSE,
NULL);
@@ -761,7 +760,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id)
{
//texture_floaterp->setTextureSelectedCallback();
//texture_floaterp->setOnUpdateImageStatsCallback();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
index cd24d79b7f..e7e0ff717e 100644
--- a/indra/newview/llfloatereditenvironmentbase.cpp
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -47,6 +47,7 @@
#include "llsettingsvo.h"
#include "llinventorymodel.h"
+#include "pipeline.h"
namespace
{
@@ -106,6 +107,9 @@ void LLFloaterEditEnvironmentBase::onFocusReceived()
{
updateEditEnvironment();
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+
+ // HACK -- resume reflection map manager because setSelectedEnvironment may pause it (SL-20456)
+ gPipeline.mReflectionMapManager.resume();
}
}
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index 297ad24359..bb47feaa95 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -475,6 +475,8 @@ void LLFloaterEditExtDayCycle::refresh()
void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
{
setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+
+ showHDRNotification(std::dynamic_pointer_cast<LLSettingsDay>(settings));
}
void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
@@ -1524,7 +1526,7 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
void LLFloaterEditExtDayCycle::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string>& filenames)
@@ -1710,6 +1712,28 @@ void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
}
}
+void LLFloaterEditExtDayCycle::showHDRNotification(const LLSettingsDay::ptr_t &pday)
+{
+ for (U32 i = LLSettingsDay::TRACK_GROUND_LEVEL; i <= LLSettingsDay::TRACK_MAX; i++)
+ {
+ LLSettingsDay::CycleTrack_t &day_track = pday->getCycleTrack(i);
+
+ LLSettingsDay::CycleTrack_t::iterator iter = day_track.begin();
+ LLSettingsDay::CycleTrack_t::iterator end = day_track.end();
+
+ while (iter != end)
+ {
+ LLSettingsSky::ptr_t sky = std::static_pointer_cast<LLSettingsSky>(iter->second);
+ if (sky && sky->canAutoAdjust())
+ {
+ LLNotificationsUtil::add("AutoAdjustHDRSky");
+ return;
+ }
+ iter++;
+ }
+ }
+}
+
void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 source_track, S32 dest_track, LLSettingsBase::TrackPosition frame)
{
std::function<void()> cb = [this, settings, frame, source_track, dest_track]()
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index ab5d12fa36..025a2ee5d1 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -188,6 +188,8 @@ private:
bool isRemovingFrameAllowed();
bool isAddingFrameAllowed();
+ void showHDRNotification(const LLSettingsDay::ptr_t &pday);
+
LLSettingsDay::ptr_t mEditDay; // edited copy
LLSettingsDay::Seconds mDayLength;
U32 mCurrentTrack;
diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp
index 95d6a2d652..c64ee5a69c 100644
--- a/indra/newview/llfloaterenvironmentadjust.cpp
+++ b/indra/newview/llfloaterenvironmentadjust.cpp
@@ -36,6 +36,7 @@
#include "llvirtualtrackball.h"
#include "llenvironment.h"
#include "llviewercontrol.h"
+#include "pipeline.h"
//=========================================================================
namespace
@@ -62,6 +63,7 @@ namespace
const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
+ const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
const std::string BTN_RESET("btn_reset");
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
@@ -117,6 +119,8 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setBlankImageAssetID(LLUUID(gSavedSettings.getString("DefaultBlankNormalTexture")));
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onWaterMapChanged(); });
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
+
refresh();
return TRUE;
}
@@ -131,6 +135,9 @@ void LLFloaterEnvironmentAdjust::onOpen(const LLSD& key)
mEventConnection = LLEnvironment::instance().setEnvironmentChanged([this](LLEnvironment::EnvSelection_t env, S32 version){ onEnvironmentUpdated(env, version); });
+ // HACK -- resume reflection map manager because "setEnvironmentChanged" may pause it (SL-20456)
+ gPipeline.mReflectionMapManager.resume();
+
LLFloater::onOpen(key);
refresh();
}
@@ -171,6 +178,9 @@ void LLFloaterEnvironmentAdjust::refresh()
getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setValue(mLiveSky->getCloudNoiseTextureId());
getChild<LLTextureCtrl>(FIELD_WATER_NORMAL_MAP)->setValue(mLiveWater->getNormalMapID());
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(mLiveSky->getReflectionProbeAmbiance(should_auto_adjust));
+
LLColor3 glow(mLiveSky->getGlow());
// takes 40 - 0.2 range -> 0 - 1.99 UI range
@@ -196,6 +206,8 @@ void LLFloaterEnvironmentAdjust::refresh()
getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+
+ updateGammaLabel();
}
@@ -468,6 +480,33 @@ void LLFloaterEnvironmentAdjust::onSunColorChanged()
mLiveSky->update();
}
+void LLFloaterEnvironmentAdjust::onReflectionProbeAmbianceChanged()
+{
+ if (!mLiveSky) return;
+ F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
+ mLiveSky->setReflectionProbeAmbiance(ambiance);
+
+ updateGammaLabel();
+ mLiveSky->update();
+}
+
+void LLFloaterEnvironmentAdjust::updateGammaLabel()
+{
+ if (!mLiveSky) return;
+
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ F32 ambiance = mLiveSky->getReflectionProbeAmbiance(should_auto_adjust);
+ if (ambiance != 0.f)
+ {
+ childSetValue("scene_gamma_label", getString("hdr_string"));
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setToolTip(getString("hdr_tooltip"));
+ }
+ else
+ {
+ childSetValue("scene_gamma_label", getString("brightness_string"));
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setToolTip(std::string());
+ }
+}
void LLFloaterEnvironmentAdjust::onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version)
{
diff --git a/indra/newview/llfloaterenvironmentadjust.h b/indra/newview/llfloaterenvironmentadjust.h
index 05ff011be5..db893cca12 100644
--- a/indra/newview/llfloaterenvironmentadjust.h
+++ b/indra/newview/llfloaterenvironmentadjust.h
@@ -82,6 +82,8 @@ private:
void onCloudMapChanged();
void onWaterMapChanged();
+ void onReflectionProbeAmbianceChanged();
+ void updateGammaLabel();
void onButtonReset();
void onEnvironmentUpdated(LLEnvironment::EnvSelection_t env, S32 version);
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index aa9a2c164a..8e28fd6234 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -182,6 +182,14 @@ void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::p
syncronizeTabs();
refresh();
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+
+ // teach user about HDR settings
+ if (mSettings
+ && mSettings->getSettingsType() == "sky"
+ && ((LLSettingsSky*)mSettings.get())->canAutoAdjust())
+ {
+ LLNotificationsUtil::add("AutoAdjustHDRSky");
+ }
}
void LLFloaterFixedEnvironment::syncronizeTabs()
@@ -440,7 +448,7 @@ void LLFloaterFixedEnvironmentWater::onOpen(const LLSD& key)
void LLFloaterFixedEnvironmentWater::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<std::string>& filenames)
@@ -526,7 +534,7 @@ void LLFloaterFixedEnvironmentSky::onClose(bool app_quitting)
void LLFloaterFixedEnvironmentSky::doImportFromDisk()
{ // Load a a legacy Windlight XML from disk.
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterFixedEnvironmentSky::loadSkySettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 89ba687d25..ba0f97e2e1 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -251,7 +251,6 @@ void LLFloaterImagePreview::draw()
if (selected <= 0)
{
gl_rect_2d_checkerboard(mPreviewRect);
- LLGLDisable gls_alpha(GL_ALPHA_TEST);
if(mImagep.notNull())
{
@@ -797,8 +796,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
U32 num_indices = vf.mNumIndices;
U32 num_vertices = vf.mNumVertices;
- mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0);
- if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE))
+ mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
+ if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to"
<< num_vertices << " vertices and "
@@ -838,6 +837,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
{
*(index_strider++) = vf.mIndices[i];
}
+
+ mVertexBuffer->unmapBuffer();
}
@@ -906,7 +907,7 @@ BOOL LLImagePreviewSculpted::render()
const F32 BRIGHTNESS = 0.9f;
gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS);
- mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
+ mVertexBuffer->setBuffer();
mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0);
gGL.popMatrix();
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 172e672dc5..f997dc9910 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -303,6 +303,9 @@ void LLFloaterIMContainer::onOpen(const LLSD& key)
LLMultiFloater::onOpen(key);
reSelectConversation();
assignResizeLimits();
+
+ LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+ session_floater->onOpen(key);
}
// virtual
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index af4e7f5aff..0b0dce29fb 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -986,6 +986,8 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
}
mInputButtonPanel->setVisible(isTornOff());
+
+ setFocus(TRUE);
}
diff --git a/indra/newview/llfloaterlagmeter.cpp b/indra/newview/llfloaterlagmeter.cpp
index f72f2631a1..db00f69f03 100644
--- a/indra/newview/llfloaterlagmeter.cpp
+++ b/indra/newview/llfloaterlagmeter.cpp
@@ -179,7 +179,7 @@ void LLFloaterLagMeter::determineClient()
{
mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) );
}
- else if(LLViewerTexture::sBoundTextureMemory > LLViewerTexture::sMaxBoundTextureMemory)
+ else if(LLViewerTexture::isMemoryForTextureLow())
{
mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) );
}
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 1a98ab9d76..9c4c9b3e59 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2004,7 +2004,6 @@ BOOL LLPanelLandOptions::postBuild()
mSnapshotCtrl->setAllowNoTexture ( TRUE );
mSnapshotCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mSnapshotCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- mSnapshotCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
}
else
{
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 6f8f73bca0..c37d8fae53 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -97,7 +97,7 @@ private:
};
LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
-: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA)
+: LLFilePickerThread(LLFilePicker::FFLOAD_MODEL)
{
mMP = mp;
mLOD = lod;
@@ -330,8 +330,8 @@ void LLFloaterModelPreview::initModelPreview()
S32 tex_width = 512;
S32 tex_height = 512;
- S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenWidth);
- S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mScreenHeight);
+ S32 max_width = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->width);
+ S32 max_height = llmin(PREVIEW_RENDER_SIZE, (S32)gPipeline.mRT->height);
while ((tex_width << 1) < max_width)
{
diff --git a/indra/newview/llfloaternewfeaturenotification.cpp b/indra/newview/llfloaternewfeaturenotification.cpp
index 3a2035b9b9..1e50024967 100644
--- a/indra/newview/llfloaternewfeaturenotification.cpp
+++ b/indra/newview/llfloaternewfeaturenotification.cpp
@@ -50,6 +50,13 @@ BOOL LLFloaterNewFeatureNotification::postBuild()
getChild<LLUICtrl>(title_txt)->setValue(getString(title_txt + feature));
getChild<LLUICtrl>(dsc_txt)->setValue(getString(dsc_txt + feature));
+ if (getKey().asString() == "gltf")
+ {
+ LLRect rect = getRect();
+ // make automatic?
+ reshape(rect.getWidth() + 90, rect.getHeight() + 45);
+ }
+
return TRUE;
}
diff --git a/indra/newview/llfloaterperformance.cpp b/indra/newview/llfloaterperformance.cpp
index e35fa55564..19fc3e673e 100644
--- a/indra/newview/llfloaterperformance.cpp
+++ b/indra/newview/llfloaterperformance.cpp
@@ -56,10 +56,6 @@ const S32 BAR_LEFT_PAD = 2;
const S32 BAR_RIGHT_PAD = 5;
const S32 BAR_BOTTOM_PAD = 9;
-constexpr auto AvType {LLPerfStats::ObjType_t::OT_AVATAR};
-constexpr auto AttType {LLPerfStats::ObjType_t::OT_ATTACHMENT};
-constexpr auto HudType {LLPerfStats::ObjType_t::OT_HUD};
-
class LLExceptionsContextMenu : public LLListContextMenu
{
public:
@@ -83,8 +79,7 @@ protected:
LLFloaterPerformance::LLFloaterPerformance(const LLSD& key)
: LLFloater(key),
- mUpdateTimer(new LLTimer()),
- mNearbyMaxComplexity(0)
+ mUpdateTimer(new LLTimer())
{
mContextMenu = new LLExceptionsContextMenu(this);
}
@@ -142,8 +137,6 @@ BOOL LLFloaterPerformance::postBuild()
mMaxARTChangedSignal = gSavedSettings.getControl("RenderAvatarMaxART")->getCommitSignal()->connect(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
mNearbyPanel->getChild<LLSliderCtrl>("RenderAvatarMaxART")->setCommitCallback(boost::bind(&LLFloaterPerformance::updateMaxRenderTime, this));
- // store the current setting as the users desired reflection detail and DD
- gSavedSettings.setS32("UserTargetReflections", LLPipeline::RenderReflectionDetail);
if(!LLPerfStats::tunables.userAutoTuneEnabled)
{
gSavedSettings.setF32("AutoTuneRenderFarClipTarget", LLPipeline::RenderFarClip);
@@ -249,47 +242,82 @@ void LLFloaterPerformance::populateHUDList()
mHUDList->clearRows();
mHUDList->updateColumns(true);
- hud_complexity_list_t complexity_list = LLHUDRenderNotifier::getInstance()->getHUDComplexityList();
-
- hud_complexity_list_t::iterator iter = complexity_list.begin();
- hud_complexity_list_t::iterator end = complexity_list.end();
-
- auto huds_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(HudType, LLPerfStats::StatType_t::RENDER_GEOMETRY);
- for (iter = complexity_list.begin(); iter != end; ++iter)
- {
- LLHUDComplexity hud_object_complexity = *iter;
-
- auto hud_render_time_raw = LLPerfStats::StatsRecorder::get(HudType, hud_object_complexity.objectId, LLPerfStats::StatType_t::RENDER_GEOMETRY);
-
- LLSD item;
- item["special_id"] = hud_object_complexity.objectId;
- item["target"] = LLNameListCtrl::SPECIAL;
- LLSD& row = item["columns"];
- row[0]["column"] = "complex_visual";
- row[0]["type"] = "bar";
- LLSD& value = row[0]["value"];
- value["ratio"] = (F32)hud_render_time_raw / huds_max_render_time_raw;
- value["bottom"] = BAR_BOTTOM_PAD;
- value["left_pad"] = BAR_LEFT_PAD;
- value["right_pad"] = BAR_RIGHT_PAD;
-
- row[1]["column"] = "complex_value";
- row[1]["type"] = "text";
- row[1]["value"] = llformat( "%.f", llmax(LLPerfStats::raw_to_us(hud_render_time_raw), (double)1));
- row[1]["font"]["name"] = "SANSSERIF";
-
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = hud_object_complexity.objectName;
- row[2]["font"]["name"] = "SANSSERIF";
-
- LLScrollListItem* obj = mHUDList->addElement(item);
- if (obj)
+ LLVOAvatar* avatar = gAgentAvatarp;
+
+ gPipeline.profileAvatar(avatar, true);
+
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ // get max gpu render time of all attachments
+ F32 max_gpu_time = -1.f;
+
+ for (iter = begin; iter != end; ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isHUDAttachment())
+ {
+ max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime);
+ }
+ }
+ }
+
+
+ for (iter = begin; iter != end; ++iter)
+ {
+ if (!iter->second)
+ {
+ continue;
+ }
+
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
- if (value_text)
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && attached_object->isHUDAttachment())
{
- value_text->setAlignment(LLFontGL::HCENTER);
+ F32 gpu_time = attached_object->mGPURenderTime;
+
+ LLSD item;
+ item["special_id"] = attached_object->getID();
+ item["target"] = LLNameListCtrl::SPECIAL;
+ LLSD& row = item["columns"];
+ row[0]["column"] = "complex_visual";
+ row[0]["type"] = "bar";
+ LLSD& value = row[0]["value"];
+ value["ratio"] = gpu_time / max_gpu_time;
+ value["bottom"] = BAR_BOTTOM_PAD;
+ value["left_pad"] = BAR_LEFT_PAD;
+ value["right_pad"] = BAR_RIGHT_PAD;
+
+ row[1]["column"] = "complex_value";
+ row[1]["type"] = "text";
+ // show gpu time in us
+ row[1]["value"] = llformat("%.f", gpu_time * 1000.f);
+ row[1]["font"]["name"] = "SANSSERIF";
+
+ row[2]["column"] = "name";
+ row[2]["type"] = "text";
+ row[2]["value"] = attached_object->getAttachmentItemName();
+ row[2]["font"]["name"] = "SANSSERIF";
+
+ LLScrollListItem* obj = mHUDList->addElement(item);
+ if (obj)
+ {
+ LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+ if (value_text)
+ {
+ value_text->setAlignment(LLFontGL::HCENTER);
+ }
+ }
}
}
}
@@ -305,50 +333,82 @@ void LLFloaterPerformance::populateObjectList()
mObjectList->clearRows();
mObjectList->updateColumns(true);
- object_complexity_list_t complexity_list = LLAvatarRenderNotifier::getInstance()->getObjectComplexityList();
+ LLVOAvatar* avatar = gAgentAvatarp;
- object_complexity_list_t::iterator iter = complexity_list.begin();
- object_complexity_list_t::iterator end = complexity_list.end();
+ gPipeline.profileAvatar(avatar, true);
- // for consistency we lock the buffer while we build the list. In theory this is uncontended as the buffer should only toggle on end of frame
- {
- std::lock_guard<std::mutex> guard{ LLPerfStats::bufferToggleLock };
- auto att_max_render_time_raw = LLPerfStats::StatsRecorder::getMax(AttType, LLPerfStats::StatType_t::RENDER_COMBINED);
-
- for (iter = complexity_list.begin(); iter != end; ++iter)
- {
- LLObjectComplexity object_complexity = *iter;
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
- auto attach_render_time_raw = LLPerfStats::StatsRecorder::get(AttType, object_complexity.objectId, LLPerfStats::StatType_t::RENDER_COMBINED);
- LLSD item;
- item["special_id"] = object_complexity.objectId;
- item["target"] = LLNameListCtrl::SPECIAL;
- LLSD& row = item["columns"];
- row[0]["column"] = "complex_visual";
- row[0]["type"] = "bar";
- LLSD& value = row[0]["value"];
- value["ratio"] = ((F32)attach_render_time_raw) / att_max_render_time_raw;
- value["bottom"] = BAR_BOTTOM_PAD;
- value["left_pad"] = BAR_LEFT_PAD;
- value["right_pad"] = BAR_RIGHT_PAD;
+ // get max gpu render time of all attachments
+ F32 max_gpu_time = -1.f;
- row[1]["column"] = "complex_value";
- row[1]["type"] = "text";
- row[1]["value"] = llformat("%.f", llmax(LLPerfStats::raw_to_us(attach_render_time_raw), (double)1));
- row[1]["font"]["name"] = "SANSSERIF";
+ for (iter = begin; iter != end; ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isHUDAttachment())
+ {
+ max_gpu_time = llmax(max_gpu_time, attached_object->mGPURenderTime);
+ }
+ }
+ }
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = object_complexity.objectName;
- row[2]["font"]["name"] = "SANSSERIF";
+ {
+ for (iter = begin; iter != end; ++iter)
+ {
+ if (!iter->second)
+ {
+ continue;
+ }
- LLScrollListItem* obj = mObjectList->addElement(item);
- if (obj)
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
- if (value_text)
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object && !attached_object->isHUDAttachment())
{
- value_text->setAlignment(LLFontGL::HCENTER);
+ F32 gpu_time = attached_object->mGPURenderTime;
+
+ LLSD item;
+ item["special_id"] = attached_object->getID();
+ item["target"] = LLNameListCtrl::SPECIAL;
+ LLSD& row = item["columns"];
+ row[0]["column"] = "complex_visual";
+ row[0]["type"] = "bar";
+ LLSD& value = row[0]["value"];
+ value["ratio"] = gpu_time / max_gpu_time;
+ value["bottom"] = BAR_BOTTOM_PAD;
+ value["left_pad"] = BAR_LEFT_PAD;
+ value["right_pad"] = BAR_RIGHT_PAD;
+
+ row[1]["column"] = "complex_value";
+ row[1]["type"] = "text";
+ // show gpu time in us
+ row[1]["value"] = llformat("%.f", gpu_time * 1000.f);
+ row[1]["font"]["name"] = "SANSSERIF";
+
+ row[2]["column"] = "name";
+ row[2]["type"] = "text";
+ row[2]["value"] = attached_object->getAttachmentItemName();
+ row[2]["font"]["name"] = "SANSSERIF";
+
+ LLScrollListItem* obj = mObjectList->addElement(item);
+ if (obj)
+ {
+ LLScrollListText* value_text = dynamic_cast<LLScrollListText*>(obj->getColumn(1));
+ if (value_text)
+ {
+ value_text->setAlignment(LLFontGL::HCENTER);
+ }
+ }
}
}
}
@@ -360,6 +420,7 @@ void LLFloaterPerformance::populateObjectList()
void LLFloaterPerformance::populateNearbyList()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
static LLCachedControl<bool> showTunedART(gSavedSettings, "ShowTunedART");
S32 prev_pos = mNearbyList->getScrollPos();
LLUUID prev_selected_id = mNearbyList->getStringUUIDSelectedItem();
@@ -368,22 +429,16 @@ void LLFloaterPerformance::populateNearbyList()
static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0);
std::vector<LLCharacter*> valid_nearby_avs;
- mNearbyMaxComplexity = LLWorld::getInstance()->getNearbyAvatarsAndCompl(valid_nearby_avs);
+ mNearbyMaxGPUTime = LLWorld::getInstance()->getNearbyAvatarsAndMaxGPUTime(valid_nearby_avs);
std::vector<LLCharacter*>::iterator char_iter = valid_nearby_avs.begin();
- LLPerfStats::bufferToggleLock.lock();
- auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(AvType, LLPerfStats::StatType_t::RENDER_COMBINED);
- LLPerfStats::bufferToggleLock.unlock();
-
while (char_iter != valid_nearby_avs.end())
{
LLVOAvatar* avatar = dynamic_cast<LLVOAvatar*>(*char_iter);
if (avatar && (LLVOAvatar::AOA_INVISIBLE != avatar->getOverallAppearance()))
{
- LLPerfStats::bufferToggleLock.lock();
- auto render_av_raw = LLPerfStats::StatsRecorder::get(AvType, avatar->getID(),LLPerfStats::StatType_t::RENDER_COMBINED);
- LLPerfStats::bufferToggleLock.unlock();
+ F32 render_av_gpu_ms = avatar->getGPURenderTime();
auto is_slow = avatar->isTooSlow();
LLSD item;
@@ -394,27 +449,21 @@ void LLFloaterPerformance::populateNearbyList()
LLSD& value = row[0]["value"];
// The ratio used in the bar is the current cost, as soon as we take action this changes so we keep the
// pre-tune value for the numerical column and sorting.
- value["ratio"] = (double)render_av_raw / av_render_max_raw;
+ value["ratio"] = render_av_gpu_ms / mNearbyMaxGPUTime;
value["bottom"] = BAR_BOTTOM_PAD;
value["left_pad"] = BAR_LEFT_PAD;
value["right_pad"] = BAR_RIGHT_PAD;
row[1]["column"] = "complex_value";
row[1]["type"] = "text";
- if (is_slow && !showTunedART)
- {
- row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( avatar->getLastART() ) );
- }
- else
- {
- row[1]["value"] = llformat( "%.f", LLPerfStats::raw_to_us( render_av_raw ) );
- }
+ // use GPU time in us
+ row[1]["value"] = llformat( "%.f", render_av_gpu_ms * 1000.f);
row[1]["font"]["name"] = "SANSSERIF";
- row[2]["column"] = "name";
- row[2]["type"] = "text";
- row[2]["value"] = avatar->getFullname();
- row[2]["font"]["name"] = "SANSSERIF";
+ row[3]["column"] = "name";
+ row[3]["type"] = "text";
+ row[3]["value"] = avatar->getFullname();
+ row[3]["font"]["name"] = "SANSSERIF";
LLScrollListItem* av_item = mNearbyList->addElement(item);
if(av_item)
@@ -633,7 +682,7 @@ void LLFloaterPerformance::changeQualityLevel(const std::string& notif)
bool is_ALM_available()
{
- bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+ bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
bool shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
return LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
diff --git a/indra/newview/llfloaterperformance.h b/indra/newview/llfloaterperformance.h
index 00f904f6d6..620dbac5bb 100644
--- a/indra/newview/llfloaterperformance.h
+++ b/indra/newview/llfloaterperformance.h
@@ -94,7 +94,9 @@ private:
LLTimer* mUpdateTimer;
- S32 mNearbyMaxComplexity;
+ // maximum GPU time of nearby avatars in ms according to LLWorld::getNearbyAvatarsAndMaxGPUTime
+ // -1.f if no profile has happened yet
+ F32 mNearbyMaxGPUTime = -1.f;
boost::signals2::connection mMaxARTChangedSignal;
};
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 649a107d74..b53839977e 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -122,7 +122,8 @@ const std::string LLFloaterPermsDefault::sCategoryNames[CAT_LAST] =
"Notecards",
"Gestures",
"Wearables",
- "Settings"
+ "Settings",
+ "Materials"
};
BOOL LLFloaterPermsDefault::postBuild()
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
index 02359a256e..97ddec7cba 100644
--- a/indra/newview/llfloaterperms.h
+++ b/indra/newview/llfloaterperms.h
@@ -75,6 +75,7 @@ enum Categories
CAT_GESTURES,
CAT_WEARABLES,
CAT_SETTINGS,
+ CAT_MATERIALS,
CAT_LAST
};
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 47a78c049a..aa723eb3a8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -79,7 +79,6 @@
#include "llviewerthrottle.h"
#include "llvoavatarself.h"
#include "llvotree.h"
-#include "llvosky.h"
#include "llfloaterpathfindingconsole.h"
// linden library includes
#include "llavatarnamecache.h"
@@ -439,6 +438,7 @@ BOOL LLFloaterPreference::postBuild()
gSavedSettings.getControl("PreferredMaturity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeMaturity, this));
gSavedPerAccountSettings.getControl("ModelUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeModelFolder, this));
+ gSavedPerAccountSettings.getControl("PBRUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangePBRFolder, this));
gSavedPerAccountSettings.getControl("TextureUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeTextureFolder, this));
gSavedPerAccountSettings.getControl("SoundUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeSoundFolder, this));
gSavedPerAccountSettings.getControl("AnimationUploadFolder")->getSignal()->connect(boost::bind(&LLFloaterPreference::onChangeAnimationFolder, this));
@@ -732,6 +732,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
onChangeMaturity();
onChangeModelFolder();
+ onChangePBRFolder();
onChangeTextureFolder();
onChangeSoundFolder();
onChangeAnimationFolder();
@@ -1227,29 +1228,10 @@ void LLFloaterPreference::buildPopupLists()
void LLFloaterPreference::refreshEnabledState()
{
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
- LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
- // if vertex shaders off, disable all shader related products
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders"))
- {
- ctrl_wind_light->setEnabled(FALSE);
- ctrl_wind_light->setValue(FALSE);
- }
- else
- {
- ctrl_wind_light->setEnabled(TRUE);
- }
-
- //Deferred/SSAO/Shadows
- BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
- BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
- bumpshiny &&
- shaders &&
- (ctrl_wind_light->get()) ? TRUE : FALSE;
-
- ctrl_deferred->setEnabled(enabled);
+ //PBR
+ ctrl_pbr->setEnabled(TRUE);
// Cannot have floater active until caps have been received
getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
@@ -1257,7 +1239,6 @@ void LLFloaterPreference::refreshEnabledState()
getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
}
-// static
void LLAvatarComplexityControls::setIndirectControls()
{
/*
@@ -1680,6 +1661,14 @@ void LLFloaterPreference::onChangeModelFolder()
}
}
+void LLFloaterPreference::onChangePBRFolder()
+{
+ if (gInventory.isInventoryUsable())
+ {
+ getChild<LLTextBox>("upload_pbr")->setText(get_category_path(LLFolderType::FT_MATERIAL));
+ }
+}
+
void LLFloaterPreference::onChangeTextureFolder()
{
if (gInventory.isInventoryUsable())
@@ -1774,7 +1763,7 @@ void LLFloaterPreference::onAtmosShaderChange()
if(ctrl_alm)
{
//Deferred/SSAO/Shadows
- BOOL bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
+ BOOL bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump") && gSavedSettings.getBOOL("RenderObjectBump");
BOOL shaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
bumpshiny &&
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 6b23c4d4cd..04ac87364d 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -109,8 +109,8 @@ public:
void updateClickActionViews();
void updateSearchableItems();
- void onBtnOK(const LLSD& userdata);
- void onBtnCancel(const LLSD& userdata);
+ void onBtnOK(const LLSD& userdata);
+ void onBtnCancel(const LLSD& userdata);
protected:
@@ -179,6 +179,7 @@ public:
void applyResolution();
void onChangeMaturity();
void onChangeModelFolder();
+ void onChangePBRFolder();
void onChangeTextureFolder();
void onChangeSoundFolder();
void onChangeAnimationFolder();
diff --git a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
index a976b97831..a91f0ec060 100644
--- a/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
+++ b/indra/newview/llfloaterpreferencesgraphicsadvanced.cpp
@@ -354,13 +354,13 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
LLTextBox* reflections_text = getChild<LLTextBox>("ReflectionsText");
// Reflections
- BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps;
+ BOOL reflections = LLCubeMap::sUseCubeMaps;
ctrl_reflections->setEnabled(reflections);
reflections_text->setEnabled(reflections);
// Bump & Shiny
LLCheckBoxCtrl* bumpshiny_ctrl = getChild<LLCheckBoxCtrl>("BumpShiny");
- bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
+ bool bumpshiny = LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
bumpshiny_ctrl->setEnabled(bumpshiny ? TRUE : FALSE);
// Avatar Mode
@@ -396,21 +396,29 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
terrain_text->setEnabled(FALSE);
// WindLight
- LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+ //LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
+ //ctrl_wind_light->setEnabled(TRUE);
LLSliderCtrl* sky = getChild<LLSliderCtrl>("SkyMeshDetail");
LLTextBox* sky_text = getChild<LLTextBox>("SkyMeshDetailText");
- ctrl_wind_light->setEnabled(TRUE);
sky->setEnabled(TRUE);
sky_text->setEnabled(TRUE);
+ BOOL enabled = TRUE;
+#if 0 // deferred always on now
//Deferred/SSAO/Shadows
LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
- BOOL enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ enabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
((bumpshiny_ctrl && bumpshiny_ctrl->get()) ? TRUE : FALSE) &&
(ctrl_wind_light->get()) ? TRUE : FALSE;
ctrl_deferred->setEnabled(enabled);
+#endif
+
+ LLCheckBoxCtrl* ctrl_pbr = getChild<LLCheckBoxCtrl>("UsePBRShaders");
+
+ //PBR
+ ctrl_pbr->setEnabled(TRUE);
LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
LLCheckBoxCtrl* ctrl_dof = getChild<LLCheckBoxCtrl>("UseDoF");
@@ -418,9 +426,9 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
LLTextBox* shadow_text = getChild<LLTextBox>("RenderShadowDetailText");
// note, okay here to get from ctrl_deferred as it's twin, ctrl_deferred2 will alway match it
- enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+ enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO");// && (ctrl_deferred->get() ? TRUE : FALSE);
- ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
+ //ctrl_deferred->set(gSavedSettings.getBOOL("RenderDeferred"));
ctrl_ssao->setEnabled(enabled);
ctrl_dof->setEnabled(enabled);
@@ -431,20 +439,13 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
shadow_text->setEnabled(enabled);
// Hardware settings
- F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
- S32Megabytes min_tex_mem = LLViewerTextureList::getMinVideoRamSetting();
- S32Megabytes max_tex_mem = LLViewerTextureList::getMaxVideoRamSetting(false, mem_multiplier);
- getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMinValue(min_tex_mem.value());
- getChild<LLSliderCtrl>("GraphicsCardTextureMemory")->setMaxValue(max_tex_mem.value());
-
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
+
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable"))
{
getChildView("vbo")->setEnabled(FALSE);
}
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") ||
- !gGLManager.mHasVertexBufferObject)
+ if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures"))
{
getChildView("texture compression")->setEnabled(FALSE);
}
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index de5d59f484..32eb70cd39 100644
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -259,7 +259,7 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void)
void LLFloaterSpellCheckerImport::onBtnBrowse()
{
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false);
}
void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llfloatertexturefetchdebugger.cpp b/indra/newview/llfloatertexturefetchdebugger.cpp
deleted file mode 100644
index cda4dc8bcc..0000000000
--- a/indra/newview/llfloatertexturefetchdebugger.cpp
+++ /dev/null
@@ -1,480 +0,0 @@
-/**
- * @file llfloatertexturefetchdebugger.cpp
- * @brief LLFloaterTextureFetchDebugger class definition
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2012, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llfloatertexturefetchdebugger.h"
-
-#include "lluictrlfactory.h"
-#include "llbutton.h"
-#include "llspinctrl.h"
-#include "llresmgr.h"
-
-#include "llmath.h"
-#include "llviewerwindow.h"
-#include "llappviewer.h"
-#include "lltexturefetch.h"
-#include "llviewercontrol.h"
-#include "llviewerassetstats.h" //gTextureTimer
-
-LLFloaterTextureFetchDebugger::LLFloaterTextureFetchDebugger(const LLSD& key)
- : LLFloater(key),
- mDebugger(NULL)
-{
- setTitle("Texture Fetching Debugger Floater");
-
- mCommitCallbackRegistrar.add("TexFetchDebugger.ChangeTexelPixelRatio", boost::bind(&LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio, this));
-
- mCommitCallbackRegistrar.add("TexFetchDebugger.Start", boost::bind(&LLFloaterTextureFetchDebugger::onClickStart, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.Clear", boost::bind(&LLFloaterTextureFetchDebugger::onClickClear, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.Close", boost::bind(&LLFloaterTextureFetchDebugger::onClickClose, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.ResetFetchTime", boost::bind(&LLFloaterTextureFetchDebugger::onClickResetFetchTime, this));
-
- mCommitCallbackRegistrar.add("TexFetchDebugger.CacheRead", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheRead, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.CacheWrite", boost::bind(&LLFloaterTextureFetchDebugger::onClickCacheWrite, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.HTTPLoad", boost::bind(&LLFloaterTextureFetchDebugger::onClickHTTPLoad, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.Decode", boost::bind(&LLFloaterTextureFetchDebugger::onClickDecode, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.GLTexture", boost::bind(&LLFloaterTextureFetchDebugger::onClickGLTexture, this));
-
- mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisCache, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchVisHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllCache", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllCache, this));
- mCommitCallbackRegistrar.add("TexFetchDebugger.RefetchAllHTTP", boost::bind(&LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP, this));
-}
-//----------------------------------------------
-
-BOOL LLFloaterTextureFetchDebugger::postBuild(void)
-{
- mDebugger = LLAppViewer::getTextureFetch()->getFetchDebugger();
- mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
-
- //set states for buttons
- mButtonStateMap["start_btn"] = true;
- mButtonStateMap["close_btn"] = true;
- mButtonStateMap["clear_btn"] = true;
- mButtonStateMap["cacheread_btn"] = false;
- mButtonStateMap["cachewrite_btn"] = false;
- mButtonStateMap["http_btn"] = false;
- mButtonStateMap["decode_btn"] = false;
- mButtonStateMap["gl_btn"] = false;
-
- mButtonStateMap["refetchviscache_btn"] = false;
- mButtonStateMap["refetchvishttp_btn"] = false;
- mButtonStateMap["refetchallcache_btn"] = false;
- mButtonStateMap["refetchallhttp_btn"] = false;
-
- updateButtons();
-
- getChild<LLUICtrl>("texel_pixel_ratio")->setValue(gSavedSettings.getF32("TexelPixelRatio"));
-
- return TRUE ;
-}
-
-LLFloaterTextureFetchDebugger::~LLFloaterTextureFetchDebugger()
-{
- //stop everything
- mDebugger->setStopDebug();
-}
-
-void LLFloaterTextureFetchDebugger::updateButtons()
-{
- for(std::map<std::string, bool>::iterator iter = mButtonStateMap.begin(); iter != mButtonStateMap.end(); ++iter)
- {
- if(iter->second)
- {
- childEnable(iter->first.c_str());
- }
- else
- {
- childDisable(iter->first.c_str());
- }
- }
-}
-
-void LLFloaterTextureFetchDebugger::disableButtons()
-{
- childDisable("start_btn");
- childDisable("clear_btn");
- childDisable("cacheread_btn");
- childDisable("cachewrite_btn");
- childDisable("http_btn");
- childDisable("decode_btn");
- childDisable("gl_btn");
- childDisable("refetchviscache_btn");
- childDisable("refetchvishttp_btn");
- childDisable("refetchallcache_btn");
- childDisable("refetchallhttp_btn");
-}
-void LLFloaterTextureFetchDebugger::setStartStatus(S32 status)
-{
- llassert_always(LLTextureFetchDebugger::IDLE == (LLTextureFetchDebugger::e_debug_state)mStartStatus) ;
- mStartStatus = status;
-}
-
-bool LLFloaterTextureFetchDebugger::idleStart()
-{
- if(mStartStatus != (S32)LLTextureFetchDebugger::IDLE)
- {
- mDebugger->startWork((LLTextureFetchDebugger::e_debug_state)mStartStatus);
- mStartStatus = (S32)LLTextureFetchDebugger::IDLE;
- return true;
- }
-
- return false;
-}
-
-void LLFloaterTextureFetchDebugger::idle()
-{
- if(idleStart())
- {
- return;
- }
-
- const F32 max_time = 0.005f; //5ms
- LLTextureFetchDebugger::e_debug_state state = mDebugger->getState();
- if(mDebugger->update(max_time))
- {
- switch(state)
- {
- case LLTextureFetchDebugger::IDLE:
- break;
- case LLTextureFetchDebugger::START_DEBUG:
- mButtonStateMap["cacheread_btn"] = true;
- mButtonStateMap["http_btn"] = true;
- mButtonStateMap["refetchviscache_btn"] = true;
- mButtonStateMap["refetchvishttp_btn"] = true;
- mButtonStateMap["refetchallcache_btn"] = true;
- mButtonStateMap["refetchallhttp_btn"] = true;
- break;
- case LLTextureFetchDebugger::READ_CACHE:
- mButtonStateMap["decode_btn"] = true;
- break;
- case LLTextureFetchDebugger::WRITE_CACHE:
- break;
- case LLTextureFetchDebugger::DECODING:
- mButtonStateMap["gl_btn"] = true;
- break;
- case LLTextureFetchDebugger::HTTP_FETCHING:
- mButtonStateMap["cacheread_btn"] = true;
- mButtonStateMap["cachewrite_btn"] = true;
- mButtonStateMap["decode_btn"] = true;
- break;
- case LLTextureFetchDebugger::GL_TEX:
- break;
- case LLTextureFetchDebugger::REFETCH_VIS_CACHE:
- break;
- case LLTextureFetchDebugger::REFETCH_VIS_HTTP:
- break;
- case LLTextureFetchDebugger::REFETCH_ALL_CACHE:
- break;
- case LLTextureFetchDebugger::REFETCH_ALL_HTTP:
- break;
- default:
- break;
- }
-
- if(state != LLTextureFetchDebugger::IDLE)
- {
- updateButtons();
- }
- }
-}
-
-//----------------------
-void LLFloaterTextureFetchDebugger::onChangeTexelPixelRatio()
-{
- gSavedSettings.setF32("TexelPixelRatio", getChild<LLUICtrl>("texel_pixel_ratio")->getValue().asReal());
-}
-
-void LLFloaterTextureFetchDebugger::onClickStart()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::START_DEBUG);
-
- mButtonStateMap["start_btn"] = false;
-
- updateButtons();
-}
-
-void LLFloaterTextureFetchDebugger::onClickClose()
-{
- setVisible(FALSE);
-
- //stop everything
- mDebugger->setStopDebug();
-
- delete this;
-}
-
-void LLFloaterTextureFetchDebugger::onClickResetFetchTime()
-{
- gTextureTimer.start();
- gTextureTimer.pause();
-}
-
-void LLFloaterTextureFetchDebugger::onClickClear()
-{
- mButtonStateMap["start_btn"] = true;
- mButtonStateMap["close_btn"] = true;
- mButtonStateMap["clear_btn"] = true;
- mButtonStateMap["cacheread_btn"] = false;
- mButtonStateMap["cachewrite_btn"] = false;
- mButtonStateMap["http_btn"] = false;
- mButtonStateMap["decode_btn"] = false;
- mButtonStateMap["gl_btn"] = false;
- mButtonStateMap["refetchviscache_btn"] = true;
- mButtonStateMap["refetchvishttp_btn"] = true;
- updateButtons();
-
- //stop everything
- mDebugger->setStopDebug();
- mDebugger->clearHistory();
-}
-
-void LLFloaterTextureFetchDebugger::onClickCacheRead()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::READ_CACHE);
-}
-
-void LLFloaterTextureFetchDebugger::onClickCacheWrite()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::WRITE_CACHE);
-}
-
-void LLFloaterTextureFetchDebugger::onClickHTTPLoad()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::HTTP_FETCHING);
-}
-
-void LLFloaterTextureFetchDebugger::onClickDecode()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::DECODING);
-}
-
-void LLFloaterTextureFetchDebugger::onClickGLTexture()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::GL_TEX);
-}
-
-void LLFloaterTextureFetchDebugger::onClickRefetchVisCache()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_CACHE);
-}
-
-void LLFloaterTextureFetchDebugger::onClickRefetchVisHTTP()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::REFETCH_VIS_HTTP);
-}
-
-void LLFloaterTextureFetchDebugger::onClickRefetchAllCache()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_CACHE);
-}
-
-void LLFloaterTextureFetchDebugger::onClickRefetchAllHTTP()
-{
- disableButtons();
-
- setStartStatus((S32)LLTextureFetchDebugger::REFETCH_ALL_HTTP);
-}
-
-void LLFloaterTextureFetchDebugger::draw()
-{
- //total number of fetched textures
- {
- getChild<LLUICtrl>("total_num_fetched_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchedTextures()));
- }
-
- //total number of fetching requests
- {
- getChild<LLUICtrl>("total_num_fetching_requests_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumFetchingRequests()));
- }
-
- //total number of cache hits
- {
- getChild<LLUICtrl>("total_num_cache_hits_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumCacheHits()));
- }
-
- //total number of visible textures
- {
- getChild<LLUICtrl>("total_num_visible_tex_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchedTextures()));
- }
-
- //total number of visible texture fetching requests
- {
- getChild<LLUICtrl>("total_num_visible_tex_fetch_req_label")->setTextArg("[NUM]", llformat("%d", mDebugger->getNumVisibleFetchingRequests()));
- }
-
- //total number of fetched data
- {
- getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getFetchedData() >> 10));
- getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getDecodedData() >> 10));
- getChild<LLUICtrl>("total_fetched_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getFetchedPixels() / 1000000.f));
- }
-
- //total number of visible fetched data
- {
- getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getVisibleFetchedData() >> 10));
- getChild<LLUICtrl>("total_fetched_vis_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getVisibleDecodedData() >> 10));
- }
-
- //total number of rendered fetched data
- {
- getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE1]", llformat("%d", mDebugger->getRenderedData() >> 10));
- getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[SIZE2]", llformat("%d", mDebugger->getRenderedDecodedData() >> 10));
- getChild<LLUICtrl>("total_fetched_rendered_data_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRenderedPixels() / 1000000.f));
- }
-
- //total time on cache readings
- if(mDebugger->getCacheReadTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_cache_read_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheReadTime()));
- }
-
- //total time on cache writings
- if(mDebugger->getCacheWriteTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_cache_write_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getCacheWriteTime()));
- }
-
- //total time on decoding
- if(mDebugger->getDecodeTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_decode_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getDecodeTime()));
- }
-
- //total time on gl texture creation
- if(mDebugger->getGLCreationTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_gl_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getGLCreationTime()));
- }
-
- //total time on HTTP fetching
- if(mDebugger->getHTTPTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getHTTPTime()));
- }
-
- //total time on entire fetching
- {
- getChild<LLUICtrl>("total_time_fetch_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getTotalFetchingTime()));
- }
-
- //total time on refetching visible textures from cache
- if(mDebugger->getRefetchVisCacheTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisCacheTime()));
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_vis_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
- }
-
- //total time on refetching all textures from cache
- if(mDebugger->getRefetchAllCacheTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllCacheTime()));
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_all_cache_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
- }
-
- //total time on refetching visible textures from http
- if(mDebugger->getRefetchVisHTTPTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchVisHTTPTime()));
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedVisData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_vis_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedVisPixels() / 1000000.f));
- }
-
- //total time on refetching all textures from http
- if(mDebugger->getRefetchAllHTTPTime() < 0.f)
- {
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", std::string("----"));
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", std::string("----"));
- }
- else
- {
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[TIME]", llformat("%.3f", mDebugger->getRefetchAllHTTPTime()));
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[SIZE]", llformat("%d", mDebugger->getRefetchedAllData() >> 10));
- getChild<LLUICtrl>("total_time_refetch_all_http_label")->setTextArg("[PIXEL]", llformat("%.3f", mDebugger->getRefetchedAllPixels() / 1000000.f));
- }
-
- LLFloater::draw();
-}
diff --git a/indra/newview/llfloatertexturefetchdebugger.h b/indra/newview/llfloatertexturefetchdebugger.h
deleted file mode 100644
index 637f3b03e5..0000000000
--- a/indra/newview/llfloatertexturefetchdebugger.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/**
- * @file llfloatertexturefetchdebugger.h
- * @brief texture fetching debugger window, debug use only
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
-#define LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
-
-#include "llfloater.h"
-class LLTextureFetchDebugger;
-
-class LLFloaterTextureFetchDebugger : public LLFloater
-{
- friend class LLFloaterReg;
-public:
- /// initialize all the callbacks for the menu
-
- virtual BOOL postBuild() ;
- virtual void draw() ;
-
- void onChangeTexelPixelRatio();
-
- void onClickStart();
- void onClickClear();
- void onClickClose();
- void onClickResetFetchTime();
-
- void onClickCacheRead();
- void onClickCacheWrite();
- void onClickHTTPLoad();
- void onClickDecode();
- void onClickGLTexture();
-
- void onClickRefetchVisCache();
- void onClickRefetchVisHTTP();
- void onClickRefetchAllCache();
- void onClickRefetchAllHTTP();
-public:
- void idle() ;
-
-private:
- LLFloaterTextureFetchDebugger(const LLSD& key);
- virtual ~LLFloaterTextureFetchDebugger();
-
- void updateButtons();
- void disableButtons();
-
- void setStartStatus(S32 status);
- bool idleStart();
-private:
- LLTextureFetchDebugger* mDebugger;
- std::map<std::string, bool> mButtonStateMap;
- S32 mStartStatus;
-};
-
-#endif // LL_FLOATER_TEXTURE_FETCH_DEBUGGER__H
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index b6acba6558..5fb4fb9b07 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -925,6 +925,9 @@ void LLFloaterTools::onClose(bool app_quitting)
// hide the advanced object weights floater
LLFloaterReg::hideInstance("object_weights");
+ // hide gltf material editor
+ LLFloaterReg::hideInstance("live_material_editor");
+
// prepare content for next call
mPanelContents->clearContents();
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index e67c79a3a0..67a205417e 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -1023,7 +1023,7 @@ void LLFloaterUIPreview::onClickEditFloater()
void LLFloaterUIPreview::onClickBrowseForEditor()
{
// Let the user choose an executable through the file picker dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getExecutablePath, this, _1), LLFilePicker::FFLOAD_EXE, false);
}
void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filenames)
@@ -1077,7 +1077,7 @@ void LLFloaterUIPreview::getExecutablePath(const std::vector<std::string>& filen
void LLFloaterUIPreview::onClickBrowseForDiffs()
{
// create load dialog box
- (new LLFilePickerReplyThread(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLFloaterUIPreview::getDiffsFilePath, this, _1), LLFilePicker::FFLOAD_XML, false);
}
void LLFloaterUIPreview::getDiffsFilePath(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 03c1b6f631..1b22b903fc 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -821,7 +821,7 @@ void LLViewerObjectList::renderObjectBeacons()
const LLVector3 &thisline = debug_beacon.mPositionAgent;
gGL.begin(LLRender::LINES);
- gGL.color4fv(color.mV);
+ gGL.color4fv(linearColor4(color).mV);
draw_cross_lines(thisline, 2.0f, 2.0f, 50.f);
draw_line_cube(0.10f, thisline);
@@ -850,7 +850,7 @@ void LLViewerObjectList::renderObjectBeacons()
const LLVector3 &thisline = debug_beacon.mPositionAgent;
gGL.begin(LLRender::LINES);
- gGL.color4fv(debug_beacon.mColor.mV);
+ gGL.color4fv(linearColor4(debug_beacon.mColor).mV);
draw_cross_lines(thisline, 0.5f, 0.5f, 0.5f);
draw_line_cube(0.10f, thisline);
@@ -994,9 +994,8 @@ private:
//-----------------------------------------------------------------------------
F32 gpu_benchmark()
{
- if (!gGLManager.mHasTimerQuery)
+ if (gGLManager.mGLVersion < 3.3f)
{ // don't bother benchmarking venerable drivers which don't support accurate timing anyway
- // and are likely to be correctly identified by the GPU table already.
return -1.f;
}
@@ -1007,8 +1006,8 @@ F32 gpu_benchmark()
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mFeatures.attachNothing = true;
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(std::make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = 1;
if (!gBenchmarkProgram.createShader(NULL, NULL))
{
@@ -1036,8 +1035,6 @@ F32 gpu_benchmark()
//time limit, allocation operations shouldn't take longer then 30 seconds, same for actual benchmark.
const F32 time_limit = 30;
- ShaderProfileHelper initProfile;
-
std::vector<LLRenderTarget> dest(count);
TextureHolder texHolder(0, count);
std::vector<F32> results;
@@ -1058,7 +1055,7 @@ F32 gpu_benchmark()
for (U32 i = 0; i < count; ++i)
{
//allocate render targets and textures
- if (!dest[i].allocate(res, res, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true))
+ if (!dest[i].allocate(res, res, GL_RGBA))
{
LL_WARNS("Benchmark") << "Failed to allocate render target." << LL_ENDL;
// abandon the benchmark test
@@ -1091,9 +1088,9 @@ F32 gpu_benchmark()
delete [] pixels;
//make a dummy triangle to draw with
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW_ARB);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX);
- if (!buff->allocateBuffer(3, 0, true))
+ if (!buff->allocateBuffer(3, 0))
{
LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL;
// abandon the benchmark test
@@ -1117,67 +1114,51 @@ F32 gpu_benchmark()
v[1].set(-1, -3, 0);
v[2].set(3, 1, 0);
- buff->flush();
-
- // ensure matched pair of bind() and unbind() calls
- ShaderBinder binder(gBenchmarkProgram);
-
-#ifdef GL_ARB_vertex_array_object
- U32 glarray = 0;
-
- if (LLRender::sGLCoreProfile)
- {
- glGenVertexArrays(1, &glarray);
- glBindVertexArray(glarray);
+ buff->unmapBuffer();
+
+ LLGLSLShader::unbind();
+
+ F32 time_passed = 0; // seconds
+
+ { //run CPU timer benchmark
+ glFinish();
+ gBenchmarkProgram.bind();
+ for (S32 c = -1; c < samples && time_passed < time_limit; ++c)
+ {
+ LLTimer timer;
+ timer.start();
+
+ for (U32 i = 0; i < count; ++i)
+ {
+ dest[i].bindTarget();
+ texHolder.bind(i);
+ buff->setBuffer();
+ buff->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dest[i].flush();
+ }
+
+ //wait for current batch of copies to finish
+ glFinish();
+
+ F32 time = timer.getElapsedTimeF32();
+ time_passed += time;
+
+ if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
+ {
+ //store result in gigabytes per second
+ F32 gb = (F32)((F64)(res * res * 8 * count)) / (1000000000);
+ F32 gbps = gb / time;
+ results.push_back(gbps);
+ }
+ }
+ gBenchmarkProgram.unbind();
}
-#endif
-
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glFinish();
-
- F32 time_passed = 0; // seconds
- for (S32 c = -1; c < samples && time_passed < time_limit; ++c)
- {
- LLTimer timer;
- timer.start();
-
- for (U32 i = 0; i < count; ++i)
- {
- dest[i].bindTarget();
- texHolder.bind(i);
- buff->drawArrays(LLRender::TRIANGLES, 0, 3);
- dest[i].flush();
- }
-
- //wait for current batch of copies to finish
- glFinish();
-
- F32 time = timer.getElapsedTimeF32();
- time_passed += time;
-
- if (c >= 0) // <-- ignore the first sample as it tends to be artificially slow
- {
- //store result in gigabytes per second
- F32 gb = (F32) ((F64) (res*res*8*count))/(1000000000);
- F32 gbps = gb/time;
- results.push_back(gbps);
- }
- }
-
-#ifdef GL_ARB_vertex_array_object
- if (LLRender::sGLCoreProfile)
- {
- glBindVertexArray(0);
- glDeleteVertexArrays(1, &glarray);
- }
-#endif
-
std::sort(results.begin(), results.end());
F32 gbps = results[results.size()/2];
- LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
+ LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to CPU timers, " << (F32)results.size() << " tests took " << time_passed << " seconds" << LL_ENDL;
#if LL_DARWIN
if (gbps > 512.f)
@@ -1188,14 +1169,32 @@ F32 gpu_benchmark()
}
#endif
+ // run GPU timer benchmark
+ {
+ ShaderProfileHelper initProfile;
+ dest[0].bindTarget();
+ gBenchmarkProgram.bind();
+ for (S32 c = 0; c < samples; ++c)
+ {
+ for (U32 i = 0; i < count; ++i)
+ {
+ texHolder.bind(i);
+ buff->setBuffer();
+ buff->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+ gBenchmarkProgram.unbind();
+ dest[0].flush();
+ }
+
F32 ms = gBenchmarkProgram.mTimeElapsed/1000000.f;
F32 seconds = ms/1000.f;
- F64 samples_drawn = res*res*count*results.size();
+ F64 samples_drawn = gBenchmarkProgram.mSamplesDrawn;
F32 samples_sec = (samples_drawn/1000000000.0)/seconds;
- gbps = samples_sec*8;
+ gbps = samples_sec*4; // 4 bytes per sample
- LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << "GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
+ LL_INFOS("Benchmark") << "Memory bandwidth is " << llformat("%.3f", gbps) << " GB/sec according to ARB_timer_query, total time " << seconds << " seconds" << LL_ENDL;
return gbps;
}
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
new file mode 100644
index 0000000000..8919229c78
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -0,0 +1,870 @@
+/**
+ * @file llgltfmateriallist.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llgltfmateriallist.h"
+
+#include "llagent.h"
+#include "llassetstorage.h"
+#include "lldispatcher.h"
+#include "llfetchedgltfmaterial.h"
+#include "llfilesystem.h"
+#include "llsdserialize.h"
+#include "lltinygltfhelper.h"
+#include "llviewercontrol.h"
+#include "llviewergenericmessage.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "llviewerstats.h"
+#include "llcorehttputil.h"
+#include "llagent.h"
+#include "llvocache.h"
+#include "llworld.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include <strstream>
+
+#include "json/reader.h"
+#include "json/value.h"
+
+#include <unordered_set>
+
+LLGLTFMaterialList gGLTFMaterialList;
+
+LLGLTFMaterialList::modify_queue_t LLGLTFMaterialList::sModifyQueue;
+LLGLTFMaterialList::apply_queue_t LLGLTFMaterialList::sApplyQueue;
+LLSD LLGLTFMaterialList::sUpdates;
+
+const LLUUID LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID("968cbad0-4dad-d64e-71b5-72bf13ad051a");
+
+#ifdef SHOW_ASSERT
+// return true if given data is (probably) valid update message for ModifyMaterialParams capability
+static bool is_valid_update(const LLSD& data)
+{
+ llassert(data.isMap());
+
+ U32 count = 0;
+
+ if (data.has("object_id"))
+ {
+ if (!data["object_id"].isUUID())
+ {
+ LL_WARNS() << "object_id is not a UUID" << LL_ENDL;
+ return false;
+ }
+ ++count;
+ }
+ else
+ {
+ LL_WARNS() << "Missing required parameter: object_id" << LL_ENDL;
+ return false;
+ }
+
+ if (data.has("side"))
+ {
+ if (!data["side"].isInteger())
+ {
+ LL_WARNS() << "side is not an integer" << LL_ENDL;
+ return false;
+ }
+
+ if (data["side"].asInteger() < -1)
+ {
+ LL_WARNS() << "side is invalid" << LL_ENDL;
+ }
+ ++count;
+ }
+ else
+ {
+ LL_WARNS() << "Missing required parameter: side" << LL_ENDL;
+ return false;
+ }
+
+ if (data.has("gltf_json"))
+ {
+ if (!data["gltf_json"].isString())
+ {
+ LL_WARNS() << "gltf_json is not a string" << LL_ENDL;
+ return false;
+ }
+ ++count;
+ }
+
+ if (data.has("asset_id"))
+ {
+ if (!data["asset_id"].isUUID())
+ {
+ LL_WARNS() << "asset_id is not a UUID" << LL_ENDL;
+ return false;
+ }
+ ++count;
+ }
+
+ if (count < 3)
+ {
+ LL_WARNS() << "Only specified object_id and side, update won't actually change anything and is just noise" << LL_ENDL;
+ return false;
+ }
+
+ if (data.size() != count)
+ {
+ LL_WARNS() << "update data contains unrecognized parameters" << LL_ENDL;
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler
+{
+ LOG_CLASS(LLGLTFMaterialOverrideDispatchHandler);
+public:
+ LLGLTFMaterialOverrideDispatchHandler() = default;
+ ~LLGLTFMaterialOverrideDispatchHandler() override = default;
+
+ void addCallback(void(*callback)(const LLUUID& object_id, S32 side))
+ {
+ mSelectionCallbacks.push_back(callback);
+ }
+
+ bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override
+ {
+ LL_PROFILE_ZONE_SCOPED;
+ // receive override data from simulator via LargeGenericMessage
+ // message should have:
+ // object_id - UUID of LLViewerObject
+ // sides - array of S32 indices of texture entries
+ // gltf_json - array of corresponding Strings of GLTF json for override data
+
+ LLSD message;
+ bool success = true;
+#if 0 //deprecated
+ for(const std::string& llsdRaw : strings)
+ {
+ std::istringstream llsdData(llsdRaw);
+ if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
+ {
+ LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+ success = false;
+ continue;
+ }
+
+ LLGLTFOverrideCacheEntry object_override;
+ if (!object_override.fromLLSD(message))
+ {
+ // malformed message, nothing we can do to handle it
+ LL_DEBUGS("GLTF") << "Message without id:" << message << LL_ENDL;
+ success = false;
+ continue;
+ }
+
+ // Cache the data
+ {
+ LLViewerRegion * region = LLWorld::instance().getRegionFromHandle(object_override.mRegionHandle);
+
+ if (region)
+ {
+ region->cacheFullUpdateGLTFOverride(object_override);
+ }
+ else
+ {
+ LL_WARNS("GLTF") << "could not access region for material overrides message cache, region_handle: " << LL_ENDL;
+ }
+ }
+ applyData(object_override);
+ }
+
+#endif
+ return success;
+ }
+
+ void doSelectionCallbacks(const LLUUID& object_id, S32 side)
+ {
+ for (auto& callback : mSelectionCallbacks)
+ {
+ callback(object_id, side);
+ }
+ }
+
+ void applyData(const LLGLTFOverrideCacheEntry &object_override)
+ {
+ // Parse the data
+
+#if 0 // DEPRECATED
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+
+ struct ReturnData
+ {
+ public:
+ LLGLTFMaterial mMaterial;
+ S32 mSide;
+ bool mSuccess;
+ };
+
+ if (!object_override.mSides.empty())
+ {
+ // fromJson() is performance heavy offload to a thread.
+ main_queue->postTo(
+ general_queue,
+ [sides=object_override.mSides]() // Work done on general queue
+ {
+ std::vector<ReturnData> results;
+
+ results.reserve(sides.size());
+ // parse json
+ std::unordered_map<S32, LLSD>::const_iterator iter = sides.begin();
+ std::unordered_map<S32, LLSD>::const_iterator end = sides.end();
+ while (iter != end)
+ {
+ ReturnData result;
+
+ result.mMaterial.applyOverrideLLSD(iter->second);
+
+ result.mSuccess = true;
+ result.mSide = iter->first;
+
+ results.push_back(result);
+ iter++;
+ }
+ return results;
+ },
+ [object_id=object_override.mObjectId, this](std::vector<ReturnData> results) // Callback to main thread
+ {
+ LLViewerObject * obj = gObjectList.findObject(object_id);
+
+ if (results.size() > 0 )
+ {
+ std::unordered_set<S32> side_set;
+
+ for (auto const & result : results)
+ {
+ S32 side = result.mSide;
+ if (result.mSuccess)
+ {
+ // copy to heap here because LLTextureEntry is going to take ownership with an LLPointer
+ LLGLTFMaterial * material = new LLGLTFMaterial(result.mMaterial);
+
+ // flag this side to not be nulled out later
+ side_set.insert(side);
+
+ if (obj)
+ {
+ obj->setTEGLTFMaterialOverride(side, material);
+ }
+ }
+
+ // unblock material editor
+ if (obj && obj->getTE(side) && obj->getTE(side)->isSelected())
+ {
+ doSelectionCallbacks(object_id, side);
+ }
+ }
+
+ if (obj && side_set.size() != obj->getNumTEs())
+ { // object exists and at least one texture entry needs to have its override data nulled out
+ for (int i = 0; i < obj->getNumTEs(); ++i)
+ {
+ if (side_set.find(i) == side_set.end())
+ {
+ obj->setTEGLTFMaterialOverride(i, nullptr);
+ if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ {
+ doSelectionCallbacks(object_id, i);
+ }
+ }
+ }
+ }
+ }
+ else if (obj)
+ { // override list was empty or an error occurred, null out all overrides for this object
+ for (int i = 0; i < obj->getNumTEs(); ++i)
+ {
+ obj->setTEGLTFMaterialOverride(i, nullptr);
+ if (obj->getTE(i) && obj->getTE(i)->isSelected())
+ {
+ doSelectionCallbacks(obj->getID(), i);
+ }
+ }
+ }
+ });
+ }
+#endif
+ }
+
+private:
+
+ std::vector<void(*)(const LLUUID& object_id, S32 side)> mSelectionCallbacks;
+};
+
+namespace
+{
+ LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message;
+}
+
+void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::string& data_in)
+{
+ std::istringstream str(data_in);
+
+ LLSD data;
+
+ LLSDSerialize::fromNotation(data, str, data_in.length());
+
+ const LLHost& host = msg->getSender();
+
+ LLViewerRegion* region = LLWorld::instance().getRegion(host);
+ llassert(region);
+
+ if (region)
+ {
+ U32 local_id = data.get("id").asInteger();
+ LLUUID id;
+ gObjectList.getUUIDFromLocal(id, local_id, host.getAddress(), host.getPort());
+ LLViewerObject* obj = gObjectList.findObject(id);
+
+ // NOTE: obj may be null if the viewer hasn't heard about the object yet, cache update in any case
+
+ if (obj && gShowObjectUpdates)
+ { // display a cyan blip for override updates when "Show Updates to Objects" enabled
+ LLColor4 color(0.f, 1.f, 1.f, 1.f);
+ gPipeline.addDebugBlip(obj->getPositionAgent(), color);
+ }
+
+ const LLSD& tes = data["te"];
+ const LLSD& od = data["od"];
+
+ constexpr U32 MAX_TES = 45;
+ bool has_te[MAX_TES] = { false };
+
+ if (tes.isArray()) // NOTE: if no "te" array exists, this is a malformed message (null out all overrides will come in as an empty te array)
+ {
+ LLGLTFOverrideCacheEntry cache;
+ cache.mLocalId = local_id;
+ cache.mObjectId = id;
+ cache.mRegionHandle = region->getHandle();
+
+ U32 count = llmin(tes.size(), MAX_TES);
+ for (U32 i = 0; i < count; ++i)
+ {
+ LLGLTFMaterial* mat = new LLGLTFMaterial(); // setTEGLTFMaterialOverride and cache will take ownership
+ mat->applyOverrideLLSD(od[i]);
+
+ S32 te = tes[i].asInteger();
+
+ has_te[te] = true;
+ cache.mSides[te] = od[i];
+ cache.mGLTFMaterial[te] = mat;
+
+ if (obj)
+ {
+ obj->setTEGLTFMaterialOverride(te, mat);
+ if (obj->getTE(te) && obj->getTE(te)->isSelected())
+ {
+ handle_gltf_override_message.doSelectionCallbacks(id, te);
+ }
+ }
+ }
+
+ if (obj)
+ { // null out overrides on TEs that shouldn't have them
+ U32 count = llmin(obj->getNumTEs(), MAX_TES);
+ for (U32 i = 0; i < count; ++i)
+ {
+ LLTextureEntry* te = obj->getTE(i);
+ if (!has_te[i] && te && te->getGLTFMaterialOverride())
+ {
+ obj->setTEGLTFMaterialOverride(i, nullptr);
+ handle_gltf_override_message.doSelectionCallbacks(id, i);
+ }
+ }
+ }
+
+ region->cacheFullUpdateGLTFOverride(cache);
+ }
+
+ }
+}
+
+void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data)
+{
+#if 0
+ override_list_t& overrides = mQueuedOverrides[id];
+
+ if (overrides.size() < side + 1)
+ {
+ overrides.resize(side + 1);
+ }
+
+ overrides[side] = override_data;
+#endif
+}
+
+void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj)
+{
+ LL_PROFILE_ZONE_SCOPED;
+
+ llassert(obj);
+
+#if 0
+ const LLUUID& id = obj->getID();
+ auto iter = mQueuedOverrides.find(id);
+
+ if (iter != mQueuedOverrides.end())
+ {
+ override_list_t& overrides = iter->second;
+ for (int i = 0; i < overrides.size(); ++i)
+ {
+ if (overrides[i].notNull())
+ {
+ if (!obj->getTE(i))
+ { // object is incomplete
+ return;
+ }
+
+ if (!obj->getTE(i)->getGLTFMaterial())
+ {
+ // doesn't have its base GLTF material yet, don't apply override(yet)
+ return;
+ }
+
+ S32 status = obj->setTEGLTFMaterialOverride(i, overrides[i]);
+ if (status == TEM_CHANGE_NONE)
+ {
+ // can't apply this yet, since failure to change the material override
+ // probably means the base material is still being fetched. leave in
+ // the queue for later
+ //obj->setDebugText("early out 3");
+ return;
+ }
+
+ if (obj->getTE(i)->isSelected())
+ {
+ handle_gltf_override_message.doSelectionCallbacks(id, i);
+ }
+ // success!
+ overrides[i] = nullptr;
+ }
+ }
+
+ mQueuedOverrides.erase(iter);
+ }
+#else
+ // the override cache is the authoritarian source of the most recent override data
+ LLViewerRegion* regionp = obj->getRegion();
+ if (regionp)
+ {
+ regionp->applyCacheMiscExtras(obj);
+ }
+#endif
+}
+
+void LLGLTFMaterialList::queueModify(const LLViewerObject* obj, S32 side, const LLGLTFMaterial* mat)
+{
+ if (obj && obj->getRenderMaterialID(side).notNull())
+ {
+ if (mat == nullptr)
+ {
+ sModifyQueue.push_back({ obj->getID(), side, LLGLTFMaterial(), false });
+ }
+ else
+ {
+ sModifyQueue.push_back({ obj->getID(), side, *mat, true });
+ }
+ }
+}
+
+void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id)
+{
+ const LLGLTFMaterial* material_override = obj->getTE(side)->getGLTFMaterialOverride();
+ if (material_override)
+ {
+ LLGLTFMaterial* cleared_override = new LLGLTFMaterial(*material_override);
+ cleared_override->setBaseMaterial();
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, cleared_override });
+ }
+ else
+ {
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr });
+ }
+}
+
+void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* material_override)
+{
+ if (asset_id.isNull() || material_override == nullptr)
+ {
+ queueApply(obj, side, asset_id);
+ }
+ else
+ {
+ LLGLTFMaterial* material = new LLGLTFMaterial(*material_override);
+ sApplyQueue.push_back({ obj->getID(), side, asset_id, material });
+ }
+}
+
+void LLGLTFMaterialList::queueUpdate(const LLSD& data)
+{
+ llassert(is_valid_update(data));
+
+ if (!sUpdates.isArray())
+ {
+ sUpdates = LLSD::emptyArray();
+ }
+
+ sUpdates[sUpdates.size()] = data;
+}
+
+void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool))
+{
+ LLSD& data = sUpdates;
+
+ S32 i = data.size();
+
+ for (ModifyMaterialData& e : sModifyQueue)
+ {
+#ifdef SHOW_ASSERT
+ // validate object has a material id
+ LLViewerObject* obj = gObjectList.findObject(e.object_id);
+ llassert(obj && obj->getRenderMaterialID(e.side).notNull());
+#endif
+
+ data[i]["object_id"] = e.object_id;
+ data[i]["side"] = e.side;
+
+ if (e.has_override)
+ {
+ data[i]["gltf_json"] = e.override_data.asJSON();
+ }
+ else
+ {
+ // Clear all overrides
+ data[i]["gltf_json"] = "";
+ }
+
+ llassert(is_valid_update(data[i]));
+ ++i;
+ }
+ sModifyQueue.clear();
+
+ for (ApplyMaterialAssetData& e : sApplyQueue)
+ {
+ data[i]["object_id"] = e.object_id;
+ data[i]["side"] = e.side;
+ data[i]["asset_id"] = e.asset_id;
+ if (e.override_data)
+ {
+ data[i]["gltf_json"] = e.override_data->asJSON();
+ }
+ else
+ {
+ // Clear all overrides
+ data[i]["gltf_json"] = "";
+ }
+
+ llassert(is_valid_update(data[i]));
+ ++i;
+ }
+ sApplyQueue.clear();
+
+#if 0 // debug output of data being sent to capability
+ std::stringstream str;
+ LLSDSerialize::serialize(data, str, LLSDSerialize::LLSD_NOTATION, LLSDFormatter::OPTIONS_PRETTY);
+ LL_INFOS() << "\n" << str.str() << LL_ENDL;
+#endif
+
+ if (sUpdates.size() > 0)
+ {
+ LLCoros::instance().launch("modifyMaterialCoro",
+ std::bind(&LLGLTFMaterialList::modifyMaterialCoro,
+ gAgent.getRegionCapability("ModifyMaterialParams"),
+ sUpdates,
+ done_callback));
+
+ sUpdates = LLSD::emptyArray();
+ }
+}
+
+void LLGLTFMaterialList::addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side))
+{
+ handle_gltf_override_message.addCallback(update_callback);
+}
+
+class AssetLoadUserData
+{
+public:
+ AssetLoadUserData() {}
+ tinygltf::Model mModelIn;
+ LLPointer<LLFetchedGLTFMaterial> mMaterial;
+};
+
+void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status)
+{
+ LL_PROFILE_ZONE_NAMED("gltf asset callback");
+ AssetLoadUserData* asset_data = (AssetLoadUserData*)user_data;
+
+ if (status != LL_ERR_NOERR)
+ {
+ LL_WARNS("GLTF") << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL;
+ asset_data->mMaterial->materialComplete();
+ delete asset_data;
+ }
+ else
+ {
+
+ LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
+ LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
+
+ main_queue->postTo(
+ general_queue,
+ [id, asset_type, asset_data]() // Work done on general queue
+ {
+ std::vector<char> buffer;
+ {
+ LL_PROFILE_ZONE_NAMED("gltf read asset");
+ LLFileSystem file(id, asset_type, LLFileSystem::READ);
+ auto size = file.getSize();
+ if (!size)
+ {
+ return false;
+ }
+
+ buffer.resize(size);
+ file.read((U8*)&buffer[0], buffer.size());
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED("gltf deserialize asset");
+
+ LLSD asset;
+
+ // read file into buffer
+ std::istrstream str(&buffer[0], buffer.size());
+
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
+ {
+ if (asset.has("type") && asset["type"].asString() == LLGLTFMaterial::ASSET_TYPE)
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ std::string warn_msg, error_msg;
+
+ LL_PROFILE_ZONE_SCOPED;
+ tinygltf::TinyGLTF gltf;
+
+ if (!gltf.LoadASCIIFromString(&asset_data->mModelIn, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
+ {
+ LL_WARNS("GLTF") << "Failed to decode material asset: "
+ << LL_NEWLINE
+ << warn_msg
+ << LL_NEWLINE
+ << error_msg
+ << LL_ENDL;
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("GLTF") << "Failed to deserialize material LLSD" << LL_ENDL;
+ }
+ }
+
+ return false;
+ },
+ [id, asset_data](bool result) // Callback to main thread
+ {
+
+ if (result)
+ {
+ asset_data->mMaterial->setFromModel(asset_data->mModelIn, 0/*only one index*/);
+ }
+ else
+ {
+ LL_DEBUGS("GLTF") << "Failed to get material " << id << LL_ENDL;
+ }
+
+ asset_data->mMaterial->materialComplete();
+
+ delete asset_data;
+ });
+ }
+}
+
+LLFetchedGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ uuid_mat_map_t::iterator iter = mList.find(id);
+ if (iter == mList.end())
+ {
+ LL_PROFILE_ZONE_NAMED("gltf fetch")
+ LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial();
+ mList[id] = mat;
+
+ if (!mat->mFetching)
+ {
+ mat->materialBegin();
+
+ AssetLoadUserData *user_data = new AssetLoadUserData();
+ user_data->mMaterial = mat;
+
+ gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, onAssetLoadComplete, (void*)user_data);
+ }
+
+ return mat;
+ }
+
+ return iter->second;
+}
+
+void LLGLTFMaterialList::addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material)
+{
+ mList[id] = material;
+}
+
+void LLGLTFMaterialList::removeMaterial(const LLUUID& id)
+{
+ mList.erase(id);
+}
+
+void LLGLTFMaterialList::flushMaterials()
+{
+ // Similar variant to what textures use
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32
+ //update MIN_UPDATE_COUNT or 5% of materials, whichever is greater
+ U32 update_count = llmax((U32)MIN_UPDATE_COUNT, (U32)mList.size() / 20);
+ update_count = llmin(update_count, (U32)mList.size());
+
+ const F64 MAX_INACTIVE_TIME = 30.f;
+ F64 cur_time = LLTimer::getTotalSeconds();
+
+ // advance iter one past the last key we updated
+ uuid_mat_map_t::iterator iter = mList.find(mLastUpdateKey);
+ if (iter != mList.end()) {
+ ++iter;
+ }
+
+ while (update_count-- > 0)
+ {
+ if (iter == mList.end())
+ {
+ iter = mList.begin();
+ }
+
+ LLPointer<LLFetchedGLTFMaterial> material = iter->second;
+ if (material->getNumRefs() == 2) // this one plus one from the list
+ {
+
+ if (!material->mActive
+ && cur_time > material->mExpectedFlusTime)
+ {
+ iter = mList.erase(iter);
+ }
+ else
+ {
+ if (material->mActive)
+ {
+ material->mExpectedFlusTime = cur_time + MAX_INACTIVE_TIME;
+ material->mActive = false;
+ }
+ ++iter;
+ }
+ }
+ else
+ {
+ material->mActive = true;
+ ++iter;
+ }
+ }
+
+ if (iter != mList.end())
+ {
+ mLastUpdateKey = iter->first;
+ }
+ else
+ {
+ mLastUpdateKey.setNull();
+ }
+
+ {
+ using namespace LLStatViewer;
+ sample(NUM_MATERIALS, mList.size());
+ }
+}
+
+// static
+void LLGLTFMaterialList::registerCallbacks()
+{
+ gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message);
+}
+
+// static
+void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool) )
+{
+ LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+ LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+ httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy));
+ LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+ LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+ LLCore::HttpHeaders::ptr_t httpHeaders;
+
+ httpOpts->setFollowRedirects(true);
+
+ LL_DEBUGS("GLTF") << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL;
+
+ LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders);
+
+ LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+ LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+ bool success = true;
+ if (!status)
+ {
+ LL_WARNS("GLTF") << "Failed to modify material." << LL_ENDL;
+ success = false;
+ }
+ else if (!result["success"].asBoolean())
+ {
+ LL_WARNS("GLTF") << "Failed to modify material: " << result["message"] << LL_ENDL;
+ success = false;
+ }
+
+ if (done_callback)
+ {
+ done_callback(success);
+ }
+}
+
+void LLGLTFMaterialList::loadCacheOverrides(const LLGLTFOverrideCacheEntry& override)
+{
+ handle_gltf_override_message.applyData(override);
+}
diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h
new file mode 100644
index 0000000000..7317214019
--- /dev/null
+++ b/indra/newview/llgltfmateriallist.h
@@ -0,0 +1,161 @@
+/**
+ * @file llgltfmateriallist.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llassettype.h"
+#include "llextendedstatus.h"
+#include "llfetchedgltfmaterial.h"
+#include "llgltfmaterial.h"
+#include "llpointer.h"
+
+#include <unordered_map>
+
+class LLFetchedGLTFMaterial;
+class LLGLTFOverrideCacheEntry;
+
+class LLGLTFMaterialList
+{
+public:
+ static const LLUUID BLANK_MATERIAL_ASSET_ID;
+
+ LLGLTFMaterialList() {}
+
+
+ LLFetchedGLTFMaterial* getMaterial(const LLUUID& id);
+
+ void addMaterial(const LLUUID& id, LLFetchedGLTFMaterial* material);
+ void removeMaterial(const LLUUID& id);
+
+ void flushMaterials();
+
+ static void registerCallbacks();
+
+ // Queue an modification of a material that we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // id - ID of object to modify
+ // side - TexureEntry index to modify, or -1 for all sides
+ // mat - material to apply as override, or nullptr to remove existing overrides and revert to asset
+ //
+ // NOTE: do not use to revert to asset when applying a new asset id, use queueApply below
+ static void queueModify(const LLViewerObject* obj, S32 side, const LLGLTFMaterial* mat);
+
+ // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // object_id - ID of object to apply material asset to
+ // side - TextureEntry index to apply material to, or -1 for all sides
+ // asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
+ //
+ // NOTE: Implicitly clears most override data if present
+ static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id);
+
+ // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates.
+ // object_id - ID of object to apply material asset to
+ // side - TextureEntry index to apply material to, or -1 for all sides
+ // asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset
+ // mat - override material, if null, will clear most override data
+ static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id, const LLGLTFMaterial* mat);
+
+ // flush pending material updates to the simulator
+ // Automatically called once per frame, but may be called explicitly
+ // for cases that care about the done_callback forwarded to LLCoros::instance().launch
+ static void flushUpdates(void(*done_callback)(bool) = nullptr);
+
+ static void addSelectionUpdateCallback(void(*update_callback)(const LLUUID& object_id, S32 side));
+
+ // Queue an explicit LLSD ModifyMaterialParams update apply given override data
+ // overrides -- LLSD map (or array of maps) in the format:
+ // object_id UUID(required) id of object
+ // side integer(required) TE index of face to set, or -1 for all faces
+ // gltf_json string(optional) override data to set, empty string nulls out override data, omissions of this parameter keeps existing data
+ // asset_id UUID(optional) id of material asset to set, omission of this parameter keeps existing material asset id
+ //
+ // NOTE: Unless you already have a gltf_json string you want to send, strongly prefer using queueModify
+ // If the queue/flush API is insufficient, extend it.
+ static void queueUpdate(const LLSD& data);
+
+ // Called by batch builder to give LLGLTMaterialList an opportunity to apply
+ // any override data that arrived before the object was ready to receive it
+ void applyQueuedOverrides(LLViewerObject* obj);
+
+ static void loadCacheOverrides(const LLGLTFOverrideCacheEntry& override);
+
+ // Apply an override update with the given data
+ void applyOverrideMessage(LLMessageSystem* msg, const std::string& data);
+
+private:
+ friend class LLGLTFMaterialOverrideDispatchHandler;
+ // save an override update that we got from the simulator for later (for example, if an override arrived for an unknown object)
+ // NOTE: this is NOT for applying overrides from the UI, see queueModifyMaterial above
+ void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data);
+
+ static void modifyMaterialCoro(std::string cap_url, LLSD overrides, void(*done_callback)(bool));
+
+protected:
+ static void onAssetLoadComplete(
+ const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data,
+ S32 status,
+ LLExtStat ext_status);
+
+ typedef std::unordered_map<LLUUID, LLPointer<LLFetchedGLTFMaterial > > uuid_mat_map_t;
+ uuid_mat_map_t mList;
+
+ typedef std::vector<LLPointer<LLGLTFMaterial> > override_list_t;
+ typedef std::unordered_map<LLUUID, override_list_t > queued_override_map_t;
+ queued_override_map_t mQueuedOverrides;
+
+ LLUUID mLastUpdateKey;
+
+ struct ModifyMaterialData
+ {
+ LLUUID object_id;
+ S32 side = -1;
+ LLGLTFMaterial override_data;
+
+ bool has_override = false;
+ };
+
+ typedef std::list<ModifyMaterialData> modify_queue_t;
+ static modify_queue_t sModifyQueue;
+
+ struct ApplyMaterialAssetData
+ {
+ LLUUID object_id;
+ S32 side = -1;
+ LLUUID asset_id;
+ LLPointer<LLGLTFMaterial> override_data;
+ };
+
+ typedef std::list<ApplyMaterialAssetData> apply_queue_t;
+ static apply_queue_t sApplyQueue;
+
+ // data to be flushed to ModifyMaterialParams capability
+ static LLSD sUpdates;
+};
+
+extern LLGLTFMaterialList gGLTFMaterialList;
+
+
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index 6898dce7b1..0f230067bc 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -495,7 +495,7 @@ void LLHUDEffectLookAt::render()
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
LLVector3 target = mTargetPos + ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->mHeadp->getWorldPosition();
gGL.matrixMode(LLRender::MM_MODELVIEW);
diff --git a/indra/newview/llhudeffectpointat.cpp b/indra/newview/llhudeffectpointat.cpp
index ecf6d42d69..dfa299528a 100644
--- a/indra/newview/llhudeffectpointat.cpp
+++ b/indra/newview/llhudeffectpointat.cpp
@@ -322,7 +322,7 @@ void LLHUDEffectPointAt::render()
update();
if (sDebugPointAt && mTargetType != POINTAT_TARGET_NONE)
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLVector3 target = mTargetPos + mSourceObject->getRenderPosition();
diff --git a/indra/newview/llhudicon.cpp b/indra/newview/llhudicon.cpp
index 85a878c4a2..38be2b69fd 100644
--- a/indra/newview/llhudicon.cpp
+++ b/indra/newview/llhudicon.cpp
@@ -64,7 +64,6 @@ LLHUDIcon::icon_instance_t LLHUDIcon::sIconInstances;
LLHUDIcon::LLHUDIcon(const U8 type) :
LLHUDObject(type),
mImagep(NULL),
- mPickID(0),
mScale(0.1f),
mHidden(FALSE)
{
@@ -76,15 +75,11 @@ LLHUDIcon::~LLHUDIcon()
mImagep = NULL;
}
-void LLHUDIcon::renderIcon(BOOL for_select)
+void LLHUDIcon::render()
{
LLGLSUIDefault texture_state;
LLGLDepthTest gls_depth(GL_TRUE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
- if (for_select)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
if (mHidden)
return;
@@ -116,7 +111,7 @@ void LLHUDIcon::renderIcon(BOOL for_select)
mDistance = dist_vec(icon_position, camera->getOrigin());
- F32 alpha_factor = for_select ? 1.f : clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
+ F32 alpha_factor = clamp_rescale(mDistance, DIST_START_FADE, DIST_END_FADE, 1.f, 0.f);
LLVector3 x_pixel_vec;
LLVector3 y_pixel_vec;
@@ -150,13 +145,6 @@ void LLHUDIcon::renderIcon(BOOL for_select)
LLVector3 upper_left = icon_position - (x_scale * 0.5f) + y_scale;
LLVector3 upper_right = icon_position + (x_scale * 0.5f) + y_scale;
- if (for_select)
- {
- // set color to unique color id for picking
- LLColor4U coloru((U8)(mPickID >> 16), (U8)(mPickID >> 8), (U8)mPickID);
- gGL.color4ubv(coloru.mV);
- }
- else
{
LLColor4 icon_color = LLColor4::white;
icon_color.mV[VALPHA] = alpha_factor;
@@ -198,11 +186,6 @@ void LLHUDIcon::markDead()
LLHUDObject::markDead();
}
-void LLHUDIcon::render()
-{
- renderIcon(FALSE);
-}
-
BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
if (mHidden)
@@ -296,37 +279,6 @@ BOOL LLHUDIcon::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
}
//static
-S32 LLHUDIcon::generatePickIDs(S32 start_id, S32 step_size)
-{
- S32 cur_id = start_id;
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- (*icon_it)->mPickID = cur_id;
- cur_id += step_size;
- }
-
- return cur_id;
-}
-
-//static
-LLHUDIcon* LLHUDIcon::handlePick(S32 pick_id)
-{
- icon_instance_t::iterator icon_it;
-
- for(icon_it = sIconInstances.begin(); icon_it != sIconInstances.end(); ++icon_it)
- {
- if (pick_id == (*icon_it)->mPickID)
- {
- return *icon_it;
- }
- }
-
- return NULL;
-}
-
-//static
LLHUDIcon* LLHUDIcon::lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection)
{
icon_instance_t::iterator icon_it;
diff --git a/indra/newview/llhudicon.h b/indra/newview/llhudicon.h
index e00a985ddc..7f452b5c36 100644
--- a/indra/newview/llhudicon.h
+++ b/indra/newview/llhudicon.h
@@ -56,8 +56,6 @@ public:
void restartLifeTimer() { mLifeTimer.reset(); }
- static S32 generatePickIDs(S32 start_id, S32 step_size);
- static LLHUDIcon* handlePick(S32 pick_id);
static LLHUDIcon* lineSegmentIntersectAll(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection);
static void updateAll();
@@ -75,14 +73,11 @@ protected:
LLHUDIcon(const U8 type);
~LLHUDIcon();
- void renderIcon(BOOL for_select); // common render code
-
private:
LLPointer<LLViewerTexture> mImagep;
LLFrameTimer mAnimTimer;
LLFrameTimer mLifeTimer;
F32 mDistance;
- S32 mPickID;
F32 mScale;
BOOL mHidden;
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index ab6a64157c..26fc899eb5 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -229,7 +229,7 @@ void LLHUDNameTag::render()
if (sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText(FALSE);
}
}
@@ -258,7 +258,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
}
LLGLState gls_blend(GL_BLEND, for_select ? FALSE : TRUE);
- LLGLState gls_alpha(GL_ALPHA_TEST, for_select ? FALSE : TRUE);
LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f);
F32 alpha_factor = 1.f;
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 45fa09e1a1..292045f25d 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -267,6 +267,13 @@ void LLHUDObject::updateAll()
// static
void LLHUDObject::renderAll()
{
+ LLGLSUIDefault gls_ui;
+
+ gUIProgram.bind();
+ gGL.color4f(1, 1, 1, 1);
+
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
LLHUDObject *hud_objp;
hud_object_list_t::iterator object_it;
@@ -285,6 +292,7 @@ void LLHUDObject::renderAll()
}
LLVertexBuffer::unbind();
+ gUIProgram.unbind();
}
// static
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 5952edfc44..0b0de18534 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -102,7 +102,7 @@ void LLHUDText::render()
if (!mOnHUDAttachment && sDisplayText)
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderText();
}
}
@@ -117,7 +117,6 @@ void LLHUDText::renderText()
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
LLGLState gls_blend(GL_BLEND, TRUE);
- LLGLState gls_alpha(GL_ALPHA_TEST, TRUE);
LLColor4 shadow_color(0.f, 0.f, 0.f, 1.f);
F32 alpha_factor = 1.f;
@@ -224,6 +223,10 @@ void LLHUDText::renderText()
}
text_color = segment_iter->mColor;
+ if (mOnHUDAttachment)
+ {
+ text_color = linearColor4(text_color);
+ }
text_color.mV[VALPHA] *= alpha_factor;
hud_render_text(segment_iter->getText(), render_position, *fontp, style, shadow, x_offset, y_offset, text_color, mOnHUDAttachment);
@@ -569,10 +572,8 @@ void LLHUDText::markDead()
void LLHUDText::renderAllHUD()
{
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
{
- LLGLEnable color_mat(GL_COLOR_MATERIAL);
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
VisibleTextObjectIterator text_it;
@@ -586,7 +587,6 @@ void LLHUDText::renderAllHUD()
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
}
void LLHUDText::shiftAll(const LLVector3& offset)
diff --git a/indra/newview/llinspectobject.cpp b/indra/newview/llinspectobject.cpp
index c52d0be213..491c90c571 100644
--- a/indra/newview/llinspectobject.cpp
+++ b/indra/newview/llinspectobject.cpp
@@ -116,6 +116,7 @@ private:
viewer_media_t mMediaImpl;
LLMediaEntry* mMediaEntry;
LLSafeHandle<LLObjectSelection> mObjectSelection;
+ boost::signals2::connection mSelectionUpdateSlot;
};
LLInspectObject::LLInspectObject(const LLSD& sd)
@@ -141,6 +142,10 @@ LLInspectObject::LLInspectObject(const LLSD& sd)
LLInspectObject::~LLInspectObject()
{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
/*virtual*/
@@ -175,9 +180,12 @@ BOOL LLInspectObject::postBuild(void)
getChild<LLUICtrl>("more_info_btn")->setCommitCallback(
boost::bind(&LLInspectObject::onClickMoreInfo, this));
- // Watch for updates to selection properties off the network
- LLSelectMgr::getInstance()->mUpdateSignal.connect(
- boost::bind(&LLInspectObject::update, this) );
+ if (!mSelectionUpdateSlot.connected())
+ {
+ // Watch for updates to selection properties off the network
+ mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(
+ boost::bind(&LLInspectObject::update, this));
+ }
return TRUE;
}
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index d2e1cdb3af..932a0316dd 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -765,7 +765,7 @@ void hide_context_entries(LLMenuGL& menu,
// descend into split menus:
LLMenuItemBranchGL* branchp = dynamic_cast<LLMenuItemBranchGL*>(menu_item);
- if ((name == "More") && branchp)
+ if (((name == "More") || (name == "create_new")) && branchp)
{
hide_context_entries(*branchp->getBranch(), entries_to_show, disabled_entries);
}
@@ -820,7 +820,7 @@ void hide_context_entries(LLMenuGL& menu,
// so that some other UI element from multi-select doesn't later set this invisible.
menu_item->pushVisible(TRUE);
- bool enabled = (menu_item->getEnabled() == TRUE);
+ bool enabled = true;
for (itor2 = disabled_entries.begin(); enabled && (itor2 != disabled_entries.end()); ++itor2)
{
enabled &= (*itor2 != name);
@@ -842,7 +842,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
if (obj)
{
- items.push_back(std::string("Copy Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Copy Separator"));
+ }
items.push_back(std::string("Copy"));
if (!isItemCopyable())
{
@@ -964,7 +967,10 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
}
}
- items.push_back(std::string("Paste Separator"));
+ if (obj->getType() != LLAssetType::AT_CATEGORY)
+ {
+ items.push_back(std::string("Paste Separator"));
+ }
if(!single_folder_root)
{
@@ -1515,6 +1521,14 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
new_listener = new LLSettingsBridge(inventory, root, uuid, LLSettingsType::fromInventoryFlags(flags));
break;
+ case LLAssetType::AT_MATERIAL:
+ if (inv_type != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << LLAssetType::lookup(asset_type) << " asset has inventory type " << LLInventoryType::lookupHumanReadable(inv_type) << " on uuid " << uuid << LL_ENDL;
+ }
+ new_listener = new LLMaterialBridge(inventory, root, uuid);
+ break;
+
default:
LL_INFOS_ONCE() << "Unhandled asset type (llassetstorage.h): "
<< (S32)asset_type << " (" << LLAssetType::lookup(asset_type) << ")" << LL_ENDL;
@@ -4268,6 +4282,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
disabled_items.push_back(std::string("New Folder"));
disabled_items.push_back(std::string("upload_def"));
+ disabled_items.push_back(std::string("create_new"));
}
if (favorites == mUUID)
{
@@ -4290,6 +4305,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
{
disabled_items.push_back(std::string("New Folder"));
disabled_items.push_back(std::string("upload_def"));
+ disabled_items.push_back(std::string("create_new"));
}
if (marketplace_listings_id == mUUID)
{
@@ -4344,14 +4360,32 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t& items
if (!isInboxFolder() // don't allow creation in inbox
&& outfits_id != mUUID)
{
+ bool menu_items_added = false;
// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
{
items.push_back(std::string("New Folder"));
+ menu_items_added = true;
}
if (!isMarketplaceListingsFolder())
{
items.push_back(std::string("upload_def"));
+ items.push_back(std::string("create_new"));
+ items.push_back(std::string("New Script"));
+ items.push_back(std::string("New Note"));
+ items.push_back(std::string("New Gesture"));
+ items.push_back(std::string("New Material"));
+ items.push_back(std::string("New Clothes"));
+ items.push_back(std::string("New Body Parts"));
+ items.push_back(std::string("New Settings"));
+ if (!LLEnvironment::instance().isInventoryEnabled())
+ {
+ disabled_items.push_back("New Settings");
+ }
+ }
+ if (menu_items_added)
+ {
+ items.push_back(std::string("Create Separator"));
}
}
getClipboardEntries(false, items, disabled_items, flags);
@@ -4669,6 +4703,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = dragItemIntoFolder(inv_item, drop, tooltip_msg, TRUE, drop_cb);
break;
case DAD_LINK:
@@ -6233,6 +6268,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_GESTURE:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
const LLPermissions& perm = inv_item->getPermissions();
@@ -7425,6 +7461,39 @@ bool LLSettingsBridge::canUpdateRegion() const
// +=================================================+
+// | LLMaterialBridge |
+// +=================================================+
+
+void LLMaterialBridge::openItem()
+{
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLInvFVBridgeAction::doAction(item->getType(),mUUID,getInventoryModel());
+ }
+}
+
+void LLMaterialBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+ LL_DEBUGS() << "LLMaterialBridge::buildContextMenu()" << LL_ENDL;
+
+ if (isMarketplaceListingsFolder())
+ {
+ menuentry_vec_t items;
+ menuentry_vec_t disabled_items;
+ addMarketplaceContextMenuOptions(flags, items, disabled_items);
+ items.push_back(std::string("Properties"));
+ getClipboardEntries(false, items, disabled_items, flags);
+ hide_context_entries(menu, items, disabled_items);
+ }
+ else
+ {
+ LLItemBridge::buildContextMenu(menu, flags);
+ }
+}
+
+
+// +=================================================+
// | LLLinkBridge |
// +=================================================+
// For broken folder links.
@@ -7831,6 +7900,24 @@ protected:
LLSettingsBridgeAction(const LLUUID& id, LLInventoryModel* model) : LLInvFVBridgeAction(id, model) {}
};
+class LLMaterialBridgeAction : public LLInvFVBridgeAction
+{
+ friend class LLInvFVBridgeAction;
+public:
+ void doIt() override
+ {
+ LLViewerInventoryItem* item = getItem();
+ if (item)
+ {
+ LLFloaterReg::showInstance("material_editor", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+ }
+ LLInvFVBridgeAction::doIt();
+ }
+ ~LLMaterialBridgeAction() = default;
+private:
+ LLMaterialBridgeAction(const LLUUID& id,LLInventoryModel* model) : LLInvFVBridgeAction(id,model) {}
+};
+
LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_type,
const LLUUID& uuid,
@@ -7873,6 +7960,9 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
case LLAssetType::AT_SETTINGS:
action = new LLSettingsBridgeAction(uuid, model);
break;
+ case LLAssetType::AT_MATERIAL:
+ action = new LLMaterialBridgeAction(uuid, model);
+ break;
default:
break;
}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index decaee7db3..3cbbd68e51 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -644,6 +644,17 @@ protected:
};
+class LLMaterialBridge : public LLItemBridge
+{
+public:
+ LLMaterialBridge(LLInventoryPanel* inventory,
+ LLFolderView* root,
+ const LLUUID& uuid) :
+ LLItemBridge(inventory, root, uuid) {}
+ virtual void openItem();
+ virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+};
+
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInvFVBridgeAction
//
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 5cf6c3fb7d..7b4283e94d 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -1375,6 +1375,18 @@ const std::string& LLInventoryFilter::getFilterText()
filtered_by_all_types = FALSE;
}
+ if (isFilterObjectTypesWith(LLInventoryType::IT_MATERIAL))
+ {
+ filtered_types += LLTrans::getString("Materials");
+ filtered_by_type = TRUE;
+ num_filter_types++;
+ }
+ else
+ {
+ not_filtered_types += LLTrans::getString("Materials");
+ filtered_by_all_types = FALSE;
+ }
+
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
{
filtered_types += LLTrans::getString("Notecards");
diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 845ea01f56..68581d04eb 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -58,6 +58,7 @@
static LLPanelInjector<LLInventoryGallery> t_inventory_gallery("inventory_gallery");
const S32 GALLERY_ITEMS_PER_ROW_MIN = 2;
+const S32 FAST_LOAD_THUMBNAIL_TRSHOLD = 50; // load folders below this value immediately
// Helper dnd functions
BOOL dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, BOOL drop, std::string& tooltip_msg, BOOL is_link);
@@ -106,6 +107,7 @@ LLInventoryGallery::LLInventoryGallery(const LLInventoryGallery::Params& p)
mGalleryWidthFactor(p.gallery_width_factor),
mIsInitialized(false),
mRootDirty(false),
+ mLoadThumbnailsImmediately(true),
mNeedsArrange(false),
mSearchType(LLInventoryFilter::SEARCHTYPE_NAME),
mSortOrder(LLInventoryFilter::SO_DATE)
@@ -540,6 +542,12 @@ void LLInventoryGallery::addToGallery(LLInventoryGalleryItem* item)
int n_prev = n - 1;
int row_count_prev = (n_prev % mItemsInRow) == 0 ? n_prev / mItemsInRow : n_prev / mItemsInRow + 1;
+ // Avoid loading too many items.
+ // Intent is for small folders to display all content fast
+ // and for large folders to load content mostly as needed
+ // Todo: ideally needs to unload images outside visible area
+ mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD;
+
bool add_row = row_count != row_count_prev;
int pos = 0;
if (add_row)
@@ -573,6 +581,8 @@ void LLInventoryGallery::removeFromGalleryLast(LLInventoryGalleryItem* item, boo
mItemsAddedCount--;
mIndexToItemMap.erase(mItemsAddedCount);
+ mLoadThumbnailsImmediately = mItemsAddedCount < FAST_LOAD_THUMBNAIL_TRSHOLD;
+
bool remove_row = row_count != row_count_prev;
removeFromLastRow(mItems[mItemsAddedCount]);
mItems.pop_back();
@@ -636,6 +646,7 @@ LLInventoryGalleryItem* LLInventoryGallery::buildGalleryItem(std::string name, L
gitem->setUUID(item_id);
gitem->setGallery(this);
gitem->setType(type, inventory_type, flags, is_link);
+ gitem->setLoadImmediately(mLoadThumbnailsImmediately);
gitem->setThumbnail(thumbnail_id);
gitem->setWorn(is_worn);
gitem->setCreatorName(get_searchable_creator_name(&gInventory, item_id));
@@ -997,6 +1008,7 @@ void LLInventoryGallery::updateItemThumbnail(LLUUID item_id)
if (mItemMap[item_id])
{
+ mItemMap[item_id]->setLoadImmediately(mLoadThumbnailsImmediately);
mItemMap[item_id]->setThumbnail(thumbnail_id);
bool passes_filter = checkAgainstFilters(mItemMap[item_id], mFilterSubString);
@@ -2390,17 +2402,11 @@ void LLInventoryGallery::startDrag()
{
std::vector<EDragAndDropType> types;
uuid_vec_t ids;
- LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_AGENT;
for (LLUUID& selected_id : mSelectedItemIDs)
{
const LLInventoryItem* item = gInventory.getItem(selected_id);
if (item)
{
- if (item->getPermissions().getOwner() == ALEXANDRIA_LINDEN_ID)
- {
- src = LLToolDragAndDrop::SOURCE_LIBRARY;
- }
-
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(item->getType());
types.push_back(type);
ids.push_back(selected_id);
@@ -2410,18 +2416,11 @@ void LLInventoryGallery::startDrag()
if (cat && gInventory.isObjectDescendentOf(selected_id, gInventory.getRootFolderID())
&& !LLFolderType::lookupIsProtectedType((cat)->getPreferredType()))
{
- if (cat->getOwnerID() == ALEXANDRIA_LINDEN_ID)
- {
- src = LLToolDragAndDrop::SOURCE_LIBRARY;
- }
-
EDragAndDropType type = LLViewerAssetType::lookupDragAndDropType(cat->getType());
types.push_back(type);
ids.push_back(selected_id);
}
}
- // We must have set this for some reason, but it's causing compile errors
- (void)src;
LLToolDragAndDrop::getInstance()->beginMultiDrag(types, ids, LLToolDragAndDrop::SOURCE_AGENT);
}
@@ -2570,6 +2569,7 @@ BOOL LLInventoryGalleryItem::postBuild()
{
mNameText = getChild<LLTextBox>("item_name");
mTextBgPanel = getChild<LLPanel>("text_bg_panel");
+ mThumbnailCtrl = getChild<LLThumbnailCtrl>("preview_thumbnail");
return TRUE;
}
@@ -2645,14 +2645,19 @@ void LLInventoryGalleryItem::setThumbnail(LLUUID id)
mDefaultImage = id.isNull();
if(mDefaultImage)
{
- getChild<LLThumbnailCtrl>("preview_thumbnail")->clearTexture();
+ mThumbnailCtrl->clearTexture();
}
else
{
- getChild<LLThumbnailCtrl>("preview_thumbnail")->setValue(id);
+ mThumbnailCtrl->setValue(id);
}
}
+void LLInventoryGalleryItem::setLoadImmediately(bool val)
+{
+ mThumbnailCtrl->setInitImmediately(val);
+}
+
void LLInventoryGalleryItem::draw()
{
if (isFadeItem())
@@ -2667,7 +2672,7 @@ void LLInventoryGalleryItem::draw()
// Draw border
LLUIColor border_color = LLUIColorTable::instance().getColor(mSelected ? "MenuItemHighlightBgColor" : "TextFgTentativeColor", LLColor4::white);
- LLRect border = getChildView("preview_thumbnail")->getRect();
+ LLRect border = mThumbnailCtrl->getRect();
border.mRight = border.mRight + 1;
border.mTop = border.mTop + 1;
gl_rect_2d(border, border_color.get(), FALSE);
@@ -2889,7 +2894,7 @@ void LLInventoryGalleryItem::updateNameText()
mNameText->setFont(getTextFont());
mNameText->setText(mItemName + mPermSuffix + mWornSuffix);
mNameText->setToolTip(mItemName + mPermSuffix + mWornSuffix);
- getChild<LLThumbnailCtrl>("preview_thumbnail")->setToolTip(mItemName + mPermSuffix + mWornSuffix);
+ mThumbnailCtrl->setToolTip(mItemName + mPermSuffix + mWornSuffix);
}
bool LLInventoryGalleryItem::isFadeItem()
diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h
index 9b3f12701f..0c52e7b713 100644
--- a/indra/newview/llinventorygallery.h
+++ b/indra/newview/llinventorygallery.h
@@ -39,6 +39,7 @@ class LLInventoryGalleryItem;
class LLScrollContainer;
class LLTextBox;
class LLThumbnailsObserver;
+class LLThumbnailCtrl;
class LLGalleryGestureObserver;
class LLInventoryGalleryContextMenu;
@@ -246,6 +247,7 @@ private:
int mRowCount;
int mItemsAddedCount;
bool mGalleryCreated;
+ bool mLoadThumbnailsImmediately;
bool mNeedsArrange;
/* Params */
@@ -342,6 +344,7 @@ public:
LLAssetType::EType getAssetType() { return mType; }
void setThumbnail(LLUUID id);
void setGallery(LLInventoryGallery* gallery) { mGallery = gallery; }
+ void setLoadImmediately(bool val);
bool isFolder() { return mIsFolder; }
bool isLink() { return mIsLink; }
EInventorySortGroup getSortGroup() { return mSortGroup; }
@@ -354,6 +357,7 @@ private:
LLUUID mUUID;
LLTextBox* mNameText;
LLPanel* mTextBgPanel;
+ LLThumbnailCtrl* mThumbnailCtrl;
bool mSelected;
bool mWorn;
bool mDefaultImage;
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 44e493fdf4..e9b0e8404a 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -99,6 +99,8 @@ LLIconDictionary::LLIconDictionary()
addEntry(LLInventoryType::ICONNAME_SETTINGS_DAY, new IconEntry("Inv_SettingsDay"));
addEntry(LLInventoryType::ICONNAME_SETTINGS, new IconEntry("Inv_Settings"));
+ addEntry(LLInventoryType::ICONNAME_MATERIAL, new IconEntry("Inv_Material"));
+
addEntry(LLInventoryType::ICONNAME_INVALID, new IconEntry("Inv_Invalid"));
addEntry(LLInventoryType::ICONNAME_UNKNOWN, new IconEntry("Inv_Unknown"));
@@ -177,6 +179,9 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
case LLAssetType::AT_SETTINGS:
idx = assignSettingsIcon(misc_flag);
break;
+ case LLAssetType::AT_MATERIAL:
+ idx = LLInventoryType::ICONNAME_MATERIAL;
+ break;
case LLAssetType::AT_UNKNOWN:
idx = LLInventoryType::ICONNAME_UNKNOWN;
default:
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index ea771661ec..8583cca103 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -66,6 +66,7 @@
#include "bufferstream.h"
#include "llcorehttputil.h"
#include "hbxxh.h"
+#include "llstartup.h"
//#define DIFF_INVENTORY_FILES
#ifdef DIFF_INVENTORY_FILES
@@ -450,8 +451,6 @@ LLInventoryModel::LLInventoryModel()
mHttpOptions(),
mHttpHeaders(),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpPriorityFG(0),
- mHttpPriorityBG(0),
mCategoryLock(),
mItemLock(),
mValidationInfo(new LLInventoryValidationInfo)
@@ -961,6 +960,11 @@ const LLUUID LLInventoryModel::findUserDefinedCategoryUUIDForType(LLFolderType::
cat_id = LLUUID(gSavedPerAccountSettings.getString("AnimationUploadFolder"));
break;
}
+ case LLFolderType::FT_MATERIAL:
+ {
+ cat_id = LLUUID(gSavedPerAccountSettings.getString("PBRUploadFolder"));
+ break;
+ }
default:
break;
}
@@ -2639,6 +2643,7 @@ bool LLInventoryModel::loadSkeleton(
const LLSD& options,
const LLUUID& owner_id)
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS(LOG_INV) << "importing inventory skeleton for " << owner_id << LL_ENDL;
typedef std::set<LLPointer<LLViewerInventoryCategory>, InventoryIDPtrLess> cat_set_t;
@@ -3247,7 +3252,6 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
handle = LLCoreHttpUtil::requestPostWithLLSD(request,
mHttpPolicyClass,
- (foreground ? mHttpPriorityFG : mHttpPriorityBG),
url,
body,
mHttpOptions,
@@ -3267,7 +3271,7 @@ LLCore::HttpHandle LLInventoryModel::requestPost(bool foreground,
void LLInventoryModel::createCommonSystemCategories()
{
//amount of System Folder we should wait for
- sPendingSystemFolders = 8;
+ sPendingSystemFolders = 9;
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_TRASH);
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_FAVORITE);
@@ -3276,6 +3280,7 @@ void LLInventoryModel::createCommonSystemCategories()
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_CURRENT_OUTFIT);
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_LANDMARK); // folder should exist before user tries to 'landmark this'
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_SETTINGS);
+ gInventory.ensureCategoryForTypeExists(LLFolderType::FT_MATERIAL); // probably should be server created
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_INBOX);
}
@@ -3318,6 +3323,8 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
LLInventoryModel::changed_items_t& cats_to_update,
bool &is_cache_obsolete)
{
+ LL_PROFILE_ZONE_NAMED("inventory load from file");
+
if(filename.empty())
{
LL_ERRS(LOG_INV) << "filename is Null!" << LL_ENDL;
@@ -3335,6 +3342,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
is_cache_obsolete = true; // Obsolete until proven current
+ //U64 lines_count = 0U;
std::string line;
LLPointer<LLSDParser> parser = new LLSDNotationParser();
while (std::getline(file, line))
@@ -3383,7 +3391,7 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
{
if(inv_item->getUUID().isNull())
{
- LL_WARNS(LOG_INV) << "Ignoring inventory with null item id: "
+ LL_DEBUGS(LOG_INV) << "Ignoring inventory with null item id: "
<< inv_item->getName() << LL_ENDL;
}
else
@@ -3399,6 +3407,14 @@ bool LLInventoryModel::loadFromFile(const std::string& filename,
}
}
}
+
+// TODO(brad) - figure out how to reenable this without breaking everything else
+// static constexpr U64 BATCH_SIZE = 512U;
+// if ((++lines_count % BATCH_SIZE) == 0)
+// {
+// // SL-19968 - make sure message system code gets a chance to run every so often
+// pump_idle_startup_network();
+// }
}
file.close();
@@ -4732,7 +4748,11 @@ LLPointer<LLInventoryValidationInfo> LLInventoryModel::validate() const
else if (count_under_root > 1)
{
validation_info->mDuplicateRequiredSystemFolders.insert(folder_type);
- if (!is_automatic && folder_type != LLFolderType::FT_SETTINGS)
+ if (!is_automatic
+ && folder_type != LLFolderType::FT_SETTINGS
+ // FT_MATERIAL might need to be automatic like the rest of upload folders
+ && folder_type != LLFolderType::FT_MATERIAL
+ )
{
// It is a fatal problem or can lead to fatal problems for COF,
// outfits, trash and other non-automatic folders.
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 4309c03f8e..69d987cabd 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -634,8 +634,6 @@ private:
LLCore::HttpOptions::ptr_t mHttpOptions;
LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
- LLCore::HttpRequest::priority_t mHttpPriorityFG;
- LLCore::HttpRequest::priority_t mHttpPriorityBG;
/** HTTP Transport
** **
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 7c3be92772..154d8e2e18 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1743,6 +1743,10 @@ void LLInventoryPanel::fileUploadLocation(const LLSD& userdata)
{
gSavedPerAccountSettings.setString("AnimationUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
}
+ else if (param == "pbr_material")
+ {
+ gSavedPerAccountSettings.setString("PBRUploadFolder", LLFolderBridge::sSelf.get()->getUUID().asString());
+ }
}
void LLInventoryPanel::openSingleViewInventory(LLUUID folder_id)
@@ -2429,14 +2433,49 @@ void LLInventorySingleFolderPanel::doShare()
LLAssetFilteredInventoryPanel::LLAssetFilteredInventoryPanel(const Params& p)
: LLInventoryPanel(p)
- , mAssetType(LLAssetType::AT_NONE)
{
}
void LLAssetFilteredInventoryPanel::initFromParams(const Params& p)
{
- mAssetType = LLAssetType::lookup(p.filter_asset_type.getValue());
+ // Init asset types
+ std::string types = p.filter_asset_types.getValue();
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep("|");
+ tokenizer tokens(types, sep);
+ tokenizer::iterator token_iter = tokens.begin();
+
+ memset(mAssetTypes, 0, LLAssetType::AT_COUNT * sizeof(bool));
+ while (token_iter != tokens.end())
+ {
+ const std::string& token_str = *token_iter;
+ LLAssetType::EType asset_type = LLAssetType::lookup(token_str);
+ if (asset_type > LLAssetType::AT_NONE && asset_type < LLAssetType::AT_COUNT)
+ {
+ mAssetTypes[asset_type] = true;
+ }
+ ++token_iter;
+ }
+
+ // Init drag types
+ memset(mDragTypes, 0, EDragAndDropType::DAD_COUNT * sizeof(bool));
+ for (S32 i = 0; i < LLAssetType::AT_COUNT; i++)
+ {
+ if (mAssetTypes[i])
+ {
+ EDragAndDropType drag_type = LLViewerAssetType::lookupDragAndDropType((LLAssetType::EType)i);
+ if (drag_type != DAD_NONE)
+ {
+ mDragTypes[drag_type] = true;
+ }
+ }
+ }
+ // Always show AT_CATEGORY, but it shouldn't get into mDragTypes
+ mAssetTypes[LLAssetType::AT_CATEGORY] = true;
+
+ // Init the panel
LLInventoryPanel::initFromParams(p);
U64 filter_cats = getFilter().getFilterCategoryTypes();
filter_cats &= ~(1ULL << LLFolderType::FT_MARKETPLACE_LISTINGS);
@@ -2454,10 +2493,9 @@ BOOL LLAssetFilteredInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, B
if (mAcceptsDragAndDrop)
{
- EDragAndDropType allow_type = LLViewerAssetType::lookupDragAndDropType(mAssetType);
// Don't allow DAD_CATEGORY here since it can contain other items besides required assets
// We should see everything we drop!
- if (allow_type == cargo_type)
+ if (mDragTypes[cargo_type])
{
result = LLInventoryPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
}
@@ -2473,8 +2511,14 @@ bool LLAssetFilteredInventoryPanel::typedViewsFilter(const LLUUID& id, LLInvento
{
return false;
}
+ LLAssetType::EType asset_type = objectp->getType();
+
+ if (asset_type < 0 || asset_type >= LLAssetType::AT_COUNT)
+ {
+ return false;
+ }
- if (objectp->getType() != mAssetType && objectp->getType() != LLAssetType::AT_CATEGORY)
+ if (!mAssetTypes[asset_type])
{
return false;
}
@@ -2490,11 +2534,16 @@ void LLAssetFilteredInventoryPanel::itemChanged(const LLUUID& id, U32 mask, cons
return;
}
- if (model_item
- && model_item->getType() != mAssetType
- && model_item->getType() != LLAssetType::AT_CATEGORY)
+ if (model_item)
{
- return;
+ LLAssetType::EType asset_type = model_item->getType();
+
+ if (asset_type < 0
+ || asset_type >= LLAssetType::AT_COUNT
+ || !mAssetTypes[asset_type])
+ {
+ return;
+ }
}
LLInventoryPanel::itemChanged(id, mask, model_item);
@@ -2530,6 +2579,7 @@ namespace LLInitParam
declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX) , LLFolderType::FT_OUTBOX);
declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT) , LLFolderType::FT_BASIC_ROOT);
declare(LLFolderType::lookup(LLFolderType::FT_SETTINGS) , LLFolderType::FT_SETTINGS);
+ declare(LLFolderType::lookup(LLFolderType::FT_MATERIAL) , LLFolderType::FT_MATERIAL);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_LISTINGS) , LLFolderType::FT_MARKETPLACE_LISTINGS);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_STOCK), LLFolderType::FT_MARKETPLACE_STOCK);
declare(LLFolderType::lookup(LLFolderType::FT_MARKETPLACE_VERSION), LLFolderType::FT_MARKETPLACE_VERSION);
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 45b675de13..b68433bab0 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -459,9 +459,9 @@ public:
struct Params
: public LLInitParam::Block<Params, LLInventoryPanel::Params>
{
- Mandatory<std::string> filter_asset_type;
+ Mandatory<std::string> filter_asset_types;
- Params() : filter_asset_type("filter_asset_type") {}
+ Params() : filter_asset_types("filter_asset_types") {}
};
void initFromParams(const Params& p);
@@ -482,7 +482,8 @@ protected:
/*virtual*/ void itemChanged(const LLUUID& item_id, U32 mask, const LLInventoryObject* model_item) override;
private:
- LLAssetType::EType mAssetType;
+ bool mAssetTypes[LLAssetType::AT_COUNT];
+ bool mDragTypes[EDragAndDropType::DAD_COUNT];
};
#endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index de8db69e19..5a5fb7474c 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -46,8 +46,8 @@
#include <ctime>
/* misc headers */
+#include "llgltfmaterial.h"
#include "llscrolllistctrl.h"
-#include "llfilepicker.h"
#include "lllocaltextureobject.h"
#include "llviewertexturelist.h"
#include "llviewerobjectlist.h"
@@ -62,6 +62,7 @@
#include "pipeline.h"
#include "llmaterialmgr.h"
#include "llimagedimensionsinfo.h"
+#include "llinventoryicon.h"
#include "llviewercontrol.h"
#include "lltrans.h"
#include "llviewerdisplay.h"
@@ -131,6 +132,14 @@ LLLocalBitmap::~LLLocalBitmap()
LLLocalBitmapMgr::getInstance()->doRebake();
}
+ for (LLPointer<LLGLTFMaterial> &mat : mGLTFMaterialWithLocalTextures)
+ {
+ mat->removeLocalTextureTracking(getTrackingID());
+ }
+
+ mChangedSignal(getTrackingID(), getWorldID(), LLUUID());
+ mChangedSignal.disconnect_all_slots();
+
// delete self from gimagelist
LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD);
gTextureList.deleteImage(image);
@@ -142,27 +151,27 @@ LLLocalBitmap::~LLLocalBitmap()
}
/* accessors */
-std::string LLLocalBitmap::getFilename()
+std::string LLLocalBitmap::getFilename() const
{
return mFilename;
}
-std::string LLLocalBitmap::getShortName()
+std::string LLLocalBitmap::getShortName() const
{
return mShortName;
}
-LLUUID LLLocalBitmap::getTrackingID()
+LLUUID LLLocalBitmap::getTrackingID() const
{
return mTrackingID;
}
-LLUUID LLLocalBitmap::getWorldID()
+LLUUID LLLocalBitmap::getWorldID() const
{
return mWorldID;
}
-bool LLLocalBitmap::getValid()
+bool LLLocalBitmap::getValid() const
{
return mValid;
}
@@ -273,6 +282,41 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
return updated;
}
+boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextureCallback& cb)
+{
+ return mChangedSignal.connect(cb);
+}
+
+void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat)
+{
+ if (!mat)
+ {
+ return;
+ }
+
+ mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ if (it->get() == mat)
+ {
+ return;
+ }
+
+ if ((*it)->getNumRefs() == 1)
+ {
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ else
+ {
+ it++;
+ }
+ }
+
+ mat->addLocalTextureTracking(getTrackingID(), getWorldID());
+ mGLTFMaterialWithLocalTextures.push_back(mat);
+}
+
bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg)
{
bool decode_successful = false;
@@ -340,7 +384,7 @@ bool LLLocalBitmap::decodeBitmap(LLPointer<LLImageRaw> rawimg)
return decode_successful;
}
-void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
+void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id)
{
// checking for misuse.
if (old_id == new_id)
@@ -350,6 +394,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
return;
}
+ mChangedSignal(getTrackingID(), old_id, new_id);
+
// processing updates per channel; makes the process scalable.
// the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc.
updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP);
@@ -381,6 +427,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id)
updateUserLayers(old_id, new_id, LLWearableType::WT_UNIVERSAL);
updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS);
updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT);
+
+ updateGLTFMaterials(old_id, new_id);
}
// this function sorts the faces from a getFaceList[getNumFaces] into a list of objects
@@ -578,6 +626,67 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
}
}
+void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id)
+{
+ // Might be a better idea to hold this in LLGLTFMaterialList
+ mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ if ((*it)->getNumRefs() == 1)
+ {
+ // render and override materials are often recreated,
+ // clean up any remains
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id))
+ {
+ it++;
+ }
+ else
+ {
+ // Matching id not found, no longer in use
+ // material would clean itself, remove from the list
+ it = mGLTFMaterialWithLocalTextures.erase(it);
+ end = mGLTFMaterialWithLocalTextures.end();
+ }
+ }
+
+ // Render material consists of base and override materials, make sure replaceLocalTexture
+ // gets called for base and override before applyOverride
+ end = mGLTFMaterialWithLocalTextures.end();
+ for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;)
+ {
+ LLFetchedGLTFMaterial* fetched_mat = dynamic_cast<LLFetchedGLTFMaterial*>((*it).get());
+ if (fetched_mat)
+ {
+ for (LLTextureEntry* entry : fetched_mat->mTextureEntires)
+ {
+ // Normally a change in applied material id is supposed to
+ // drop overrides thus reset material, but local materials
+ // currently reuse their existing asset id, and purpose is
+ // to preview how material will work in-world, overrides
+ // included, so do an override to render update instead.
+ LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+ if (override_mat)
+ {
+ // do not create a new material, reuse existing pointer
+ LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+ if (render_mat)
+ {
+ llassert(dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()) != nullptr);
+ {
+ *render_mat = *fetched_mat;
+ }
+ render_mat->applyOverride(*override_mat);
+ }
+ }
+ }
+ }
+ ++it;
+ }
+}
+
LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(
LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)
{
@@ -919,7 +1028,22 @@ LLLocalBitmapMgr::~LLLocalBitmapMgr()
mBitmapList.clear();
}
-LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename)
+bool LLLocalBitmapMgr::addUnit(const std::vector<std::string>& filenames)
+{
+ bool add_successful = false;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty() && addUnit(*iter).notNull())
+ {
+ add_successful = true;
+ }
+ iter++;
+ }
+ return add_successful;
+}
+
+LLUUID LLLocalBitmapMgr::addUnit(const std::string& filename)
{
if (!checkTextureDimensions(filename))
{
@@ -949,31 +1073,6 @@ LLUUID LLLocalBitmapMgr::addUnit(const std::string &filename)
return LLUUID::null;
}
-bool LLLocalBitmapMgr::addUnit()
-{
- bool add_successful = false;
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles(LLFilePicker::FFLOAD_IMAGE))
- {
- mTimer.stopTimer();
-
- std::string filename = picker.getFirstFile();
- while(!filename.empty())
- {
- if (addUnit(filename).notNull())
- {
- add_successful = true;
- }
- filename = picker.getNextFile();
- }
-
- mTimer.startTimer();
- }
-
- return add_successful;
-}
-
bool LLLocalBitmapMgr::checkTextureDimensions(std::string filename)
{
std::string exten = gDirUtilp->getExtension(filename);
@@ -1030,11 +1129,11 @@ void LLLocalBitmapMgr::delUnit(LLUUID tracking_id)
}
}
-LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)
+LLUUID LLLocalBitmapMgr::getWorldID(const LLUUID &tracking_id) const
{
LLUUID world_id = LLUUID::null;
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getTrackingID() == tracking_id)
@@ -1046,9 +1145,9 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id)
return world_id;
}
-bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)
+bool LLLocalBitmapMgr::isLocal(const LLUUID &world_id) const
{
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getWorldID() == world_id)
@@ -1059,11 +1158,11 @@ bool LLLocalBitmapMgr::isLocal(const LLUUID world_id)
return false;
}
-std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)
+std::string LLLocalBitmapMgr::getFilename(const LLUUID &tracking_id) const
{
std::string filename = "";
- for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
{
LLLocalBitmap* unit = *iter;
if (unit->getTrackingID() == tracking_id)
@@ -1075,11 +1174,39 @@ std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id)
return filename;
}
+boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback &cb)
+{
+ for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ {
+ LLLocalBitmap* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ return unit->setChangedCallback(cb);
+ }
+ }
+
+ return boost::signals2::connection();
+}
+
+void LLLocalBitmapMgr::associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat)
+{
+ for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++)
+ {
+ LLLocalBitmap* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ unit->addGLTFMaterial(mat);
+ }
+ }
+}
+
void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
{
if (ctrl)
{
- ctrl->clearRows();
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_TEXTURE,
+ LLInventoryType::IT_NONE);
if (!mBitmapList.empty())
{
@@ -1087,13 +1214,19 @@ void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl)
iter != mBitmapList.end(); iter++)
{
LLSD element;
- element["columns"][0]["column"] = "unit_name";
- element["columns"][0]["type"] = "text";
- element["columns"][0]["value"] = (*iter)->getShortName();
- element["columns"][1]["column"] = "unit_id_HIDDEN";
- element["columns"][1]["type"] = "text";
- element["columns"][1]["value"] = (*iter)->getTrackingID();
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_TEXTURE;
+ element["value"] = data;
ctrl->addElement(element);
}
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 02b8834c16..1fdf9dccbf 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -36,6 +36,7 @@
class LLScrollListCtrl;
class LLImageRaw;
class LLViewerObject;
+class LLGLTFMaterial;
class LLLocalBitmap
{
@@ -44,11 +45,11 @@ class LLLocalBitmap
~LLLocalBitmap();
public: /* accessors */
- std::string getFilename();
- std::string getShortName();
- LLUUID getTrackingID();
- LLUUID getWorldID();
- bool getValid();
+ std::string getFilename() const;
+ std::string getShortName() const;
+ LLUUID getTrackingID() const;
+ LLUUID getWorldID() const;
+ bool getValid() const;
public: /* self update public section */
enum EUpdateType
@@ -59,13 +60,21 @@ class LLLocalBitmap
bool updateSelf(EUpdateType = UT_REGUPDATE);
+ typedef boost::signals2::signal<void(const LLUUID& tracking_id,
+ const LLUUID& old_id,
+ const LLUUID& new_id)> LLLocalTextureChangedSignal;
+ typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback;
+ boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb);
+ void addGLTFMaterial(LLGLTFMaterial* mat);
+
private: /* self update private section */
bool decodeBitmap(LLPointer<LLImageRaw> raw);
- void replaceIDs(LLUUID old_id, LLUUID new_id);
+ void replaceIDs(const LLUUID &old_id, LLUUID new_id);
std::vector<LLViewerObject*> prepUpdateObjects(LLUUID old_id, U32 channel);
void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel);
void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
+ void updateGLTFMaterials(LLUUID old_id, LLUUID new_id);
LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
private: /* private enums */
@@ -93,6 +102,12 @@ class LLLocalBitmap
EExtension mExtension;
ELinkStatus mLinkStatus;
S32 mUpdateRetries;
+ LLLocalTextureChangedSignal mChangedSignal;
+
+ // Store a list of accosiated materials
+ // Might be a better idea to hold this in LLGLTFMaterialList
+ typedef std::vector<LLPointer<LLGLTFMaterial> > mat_list_t;
+ mat_list_t mGLTFMaterialWithLocalTextures;
};
@@ -115,15 +130,17 @@ class LLLocalBitmapMgr : public LLSingleton<LLLocalBitmapMgr>
LLSINGLETON(LLLocalBitmapMgr);
~LLLocalBitmapMgr();
public:
- bool addUnit();
- LLUUID addUnit(const std::string &filename);
+ bool addUnit(const std::vector<std::string>& filenames);
+ LLUUID addUnit(const std::string& filename);
void delUnit(LLUUID tracking_id);
bool checkTextureDimensions(std::string filename);
- LLUUID getWorldID(LLUUID tracking_id);
- bool isLocal(LLUUID world_id);
- std::string getFilename(LLUUID tracking_id);
-
+ LLUUID getWorldID(const LLUUID &tracking_id) const;
+ bool isLocal(const LLUUID& world_id) const;
+ std::string getFilename(const LLUUID &tracking_id) const;
+ boost::signals2::connection setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback& cb);
+ void associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat);
+
void feedScrollList(LLScrollListCtrl* ctrl);
void doUpdates();
void setNeedsRebake();
@@ -134,6 +151,7 @@ private:
LLLocalBitmapTimer mTimer;
bool mNeedsRebake;
typedef std::list<LLLocalBitmap*>::iterator local_list_iter;
+ typedef std::list<LLLocalBitmap*>::const_iterator local_list_citer;
};
#endif
diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp
new file mode 100644
index 0000000000..61e0163798
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.cpp
@@ -0,0 +1,497 @@
+/**
+ * @file lllocalrendermaterials.cpp
+ * @brief Local GLTF materials source
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+/* precompiled headers */
+#include "llviewerprecompiledheaders.h"
+
+/* own header */
+#include "lllocalgltfmaterials.h"
+
+/* boost: will not compile unless equivalent is undef'd, beware. */
+#include "fix_macros.h"
+#include <boost/filesystem.hpp>
+
+/* time headers */
+#include <time.h>
+#include <ctime>
+
+/* misc headers */
+#include "llgltfmateriallist.h"
+#include "llimage.h"
+#include "llinventoryicon.h"
+#include "llmaterialmgr.h"
+#include "llnotificationsutil.h"
+#include "llscrolllistctrl.h"
+#include "lltextureentry.h"
+#include "lltinygltfhelper.h"
+#include "llviewertexture.h"
+
+/*=======================================*/
+/* Formal declarations, constants, etc. */
+/*=======================================*/
+
+static const F32 LL_LOCAL_TIMER_HEARTBEAT = 3.0;
+static const S32 LL_LOCAL_UPDATE_RETRIES = 5;
+
+/*=======================================*/
+/* LLLocalGLTFMaterial: unit class */
+/*=======================================*/
+LLLocalGLTFMaterial::LLLocalGLTFMaterial(std::string filename, S32 index)
+ : mFilename(filename)
+ , mShortName(gDirUtilp->getBaseFileName(filename, true))
+ , mLastModified()
+ , mLinkStatus(LS_ON)
+ , mUpdateRetries(LL_LOCAL_UPDATE_RETRIES)
+ , mMaterialIndex(index)
+{
+ mTrackingID.generate();
+
+ /* extension */
+ std::string temp_exten = gDirUtilp->getExtension(mFilename);
+
+ if (temp_exten == "gltf")
+ {
+ mExtension = ET_MATERIAL_GLTF;
+ }
+ else if (temp_exten == "glb")
+ {
+ mExtension = ET_MATERIAL_GLB;
+ }
+ else
+ {
+ LL_WARNS("GLTF") << "File of no valid extension given, local material creation aborted." << "\n"
+ << "Filename: " << mFilename << LL_ENDL;
+ return; // no valid extension.
+ }
+}
+
+LLLocalGLTFMaterial::~LLLocalGLTFMaterial()
+{
+ // gGLTFMaterialList will clean itself
+}
+
+/* accessors */
+std::string LLLocalGLTFMaterial::getFilename() const
+{
+ return mFilename;
+}
+
+std::string LLLocalGLTFMaterial::getShortName() const
+{
+ return mShortName;
+}
+
+LLUUID LLLocalGLTFMaterial::getTrackingID() const
+{
+ return mTrackingID;
+}
+
+LLUUID LLLocalGLTFMaterial::getWorldID() const
+{
+ return mWorldID;
+}
+
+S32 LLLocalGLTFMaterial::getIndexInFile() const
+{
+ return mMaterialIndex;
+}
+
+/* update functions */
+bool LLLocalGLTFMaterial::updateSelf()
+{
+ bool updated = false;
+
+ if (mLinkStatus == LS_ON)
+ {
+ // verifying that the file exists
+ if (gDirUtilp->fileExists(mFilename))
+ {
+ // verifying that the file has indeed been modified
+
+#ifndef LL_WINDOWS
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+#else
+ const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename)));
+#endif
+ LLSD new_last_modified = asctime(localtime(&temp_time));
+
+ if (mLastModified.asString() != new_last_modified.asString())
+ {
+ if (loadMaterial())
+ {
+ // decode is successful, we can safely proceed.
+ if (mWorldID.isNull())
+ {
+ mWorldID.generate();
+ }
+ mLastModified = new_last_modified;
+
+ // addMaterial will replace material witha a new
+ // pointer if value already exists but we are
+ // reusing existing pointer, so it should add only.
+ gGLTFMaterialList.addMaterial(mWorldID, this);
+
+ mUpdateRetries = LL_LOCAL_UPDATE_RETRIES;
+
+ for (LLTextureEntry* entry : mTextureEntires)
+ {
+ // Normally a change in applied material id is supposed to
+ // drop overrides thus reset material, but local materials
+ // currently reuse their existing asset id, and purpose is
+ // to preview how material will work in-world, overrides
+ // included, so do an override to render update instead.
+ LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride();
+ if (override_mat)
+ {
+ // do not create a new material, reuse existing pointer
+ LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial();
+ if (render_mat)
+ {
+ llassert(dynamic_cast<LLFetchedGLTFMaterial*>(entry->getGLTFRenderMaterial()) != nullptr);
+ *render_mat = *this;
+ render_mat->applyOverride(*override_mat);
+ }
+ }
+ }
+
+ updated = true;
+ }
+
+ // if decoding failed, we get here and it will attempt to decode it in the next cycles
+ // until mUpdateRetries runs out. this is done because some software lock the material while writing to it
+ else
+ {
+ if (mUpdateRetries)
+ {
+ mUpdateRetries--;
+ }
+ else
+ {
+ LL_WARNS("GLTF") << "During the update process the following file was found" << "\n"
+ << "but could not be opened or decoded for " << LL_LOCAL_UPDATE_RETRIES << " attempts." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ notif_args["NRETRIES"] = LL_LOCAL_UPDATE_RETRIES;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFailedFinal", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+ }
+
+ } // end if file exists
+
+ else
+ {
+ LL_WARNS("GLTF") << "During the update process, the following file was not found." << "\n"
+ << "Filename: " << mFilename << "\n"
+ << "Disabling further update attempts for this file." << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = mFilename;
+ LLNotificationsUtil::add("LocalBitmapsUpdateFileNotFound", notif_args);
+
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return updated;
+}
+
+bool LLLocalGLTFMaterial::loadMaterial()
+{
+ bool decode_successful = false;
+
+ switch (mExtension)
+ {
+ case ET_MATERIAL_GLTF:
+ case ET_MATERIAL_GLB:
+ {
+ std::string filename_lc = mFilename;
+ LLStringUtil::toLower(filename_lc);
+ std::string material_name;
+
+ tinygltf::Model model;
+ decode_successful = LLTinyGLTFHelper::loadModel(mFilename, model);
+ if (decode_successful)
+ {
+ // Might be a good idea to make these textures into local textures
+ decode_successful = LLTinyGLTFHelper::getMaterialFromModel(
+ mFilename,
+ model,
+ mMaterialIndex,
+ this,
+ material_name);
+ }
+
+ if (!material_name.empty())
+ {
+ mShortName = gDirUtilp->getBaseFileName(filename_lc, true) + " (" + material_name + ")";
+ }
+
+ break;
+ }
+
+ default:
+ {
+ // separating this into -several- LL_WARNS() calls because in the extremely unlikely case that this happens
+ // accessing mFilename and any other object properties might very well crash the viewer.
+ // getting here should be impossible, or there's been a pretty serious bug.
+
+ LL_WARNS("GLTF") << "During a decode attempt, the following local material had no properly assigned extension." << LL_ENDL;
+ LL_WARNS("GLTF") << "Filename: " << mFilename << LL_ENDL;
+ LL_WARNS("GLTF") << "Disabling further update attempts for this file." << LL_ENDL;
+ mLinkStatus = LS_BROKEN;
+ }
+ }
+
+ return decode_successful;
+}
+
+
+/*=======================================*/
+/* LLLocalGLTFMaterialTimer: timer class */
+/*=======================================*/
+LLLocalGLTFMaterialTimer::LLLocalGLTFMaterialTimer() : LLEventTimer(LL_LOCAL_TIMER_HEARTBEAT)
+{
+}
+
+LLLocalGLTFMaterialTimer::~LLLocalGLTFMaterialTimer()
+{
+}
+
+void LLLocalGLTFMaterialTimer::startTimer()
+{
+ mEventTimer.start();
+}
+
+void LLLocalGLTFMaterialTimer::stopTimer()
+{
+ mEventTimer.stop();
+}
+
+bool LLLocalGLTFMaterialTimer::isRunning()
+{
+ return mEventTimer.getStarted();
+}
+
+BOOL LLLocalGLTFMaterialTimer::tick()
+{
+ // todo: do on idle? No point in timer
+ LLLocalGLTFMaterialMgr::getInstance()->doUpdates();
+ return FALSE;
+}
+
+/*=======================================*/
+/* LLLocalGLTFMaterialMgr: manager class */
+/*=======================================*/
+LLLocalGLTFMaterialMgr::LLLocalGLTFMaterialMgr()
+{
+}
+
+LLLocalGLTFMaterialMgr::~LLLocalGLTFMaterialMgr()
+{
+ mMaterialList.clear();
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::vector<std::string>& filenames)
+{
+ S32 add_count = 0;
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ add_count += addUnit(*iter);
+ }
+ iter++;
+ }
+ return add_count;
+}
+
+S32 LLLocalGLTFMaterialMgr::addUnit(const std::string& filename)
+{
+ tinygltf::Model model;
+ LLTinyGLTFHelper::loadModel(filename, model);
+
+ S32 materials_in_file = model.materials.size();
+ if (materials_in_file <= 0)
+ {
+ return 0;
+ }
+
+ S32 loaded_materials = 0;
+ for (S32 i = 0; i < materials_in_file; i++)
+ {
+ // Todo: this is rather inefficient, files will be spammed with
+ // separate loads and date checks, find a way to improve this.
+ // May be doUpdates() should be checking individual files.
+ LLPointer<LLLocalGLTFMaterial> unit = new LLLocalGLTFMaterial(filename, i);
+
+ // load material from file
+ if (unit->updateSelf())
+ {
+ mMaterialList.emplace_back(unit);
+ loaded_materials++;
+ }
+ else
+ {
+ LL_WARNS("GLTF") << "Attempted to add invalid or unreadable image file, attempt cancelled.\n"
+ << "Filename: " << filename << LL_ENDL;
+
+ LLSD notif_args;
+ notif_args["FNAME"] = filename;
+ LLNotificationsUtil::add("LocalGLTFVerifyFail", notif_args);
+
+ unit = NULL;
+ }
+ }
+
+ return loaded_materials;
+}
+
+void LLLocalGLTFMaterialMgr::delUnit(LLUUID tracking_id)
+{
+ if (!mMaterialList.empty())
+ {
+ std::vector<LLLocalGLTFMaterial*> to_delete;
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ { /* finding which ones we want deleted and making a separate list */
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ to_delete.push_back(unit);
+ }
+ }
+
+ for (std::vector<LLLocalGLTFMaterial*>::iterator del_iter = to_delete.begin();
+ del_iter != to_delete.end(); del_iter++)
+ { /* iterating over a temporary list, hence preserving the iterator validity while deleting. */
+ LLLocalGLTFMaterial* unit = *del_iter;
+ mMaterialList.remove(unit);
+
+ unit = NULL;
+ }
+ }
+}
+
+LLUUID LLLocalGLTFMaterialMgr::getWorldID(LLUUID tracking_id)
+{
+ LLUUID world_id = LLUUID::null;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ world_id = unit->getWorldID();
+ }
+ }
+
+ return world_id;
+}
+
+bool LLLocalGLTFMaterialMgr::isLocal(const LLUUID world_id)
+{
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getWorldID() == world_id)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+void LLLocalGLTFMaterialMgr::getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index)
+{
+ filename = "";
+ index = 0;
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ LLLocalGLTFMaterial* unit = *iter;
+ if (unit->getTrackingID() == tracking_id)
+ {
+ filename = unit->getFilename();
+ index = unit->getIndexInFile();
+ }
+ }
+}
+
+// probably shouldn't be here, but at the moment this mirrors lllocalbitmaps
+void LLLocalGLTFMaterialMgr::feedScrollList(LLScrollListCtrl* ctrl)
+{
+ if (ctrl)
+ {
+ if (!mMaterialList.empty())
+ {
+ std::string icon_name = LLInventoryIcon::getIconName(
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_NONE);
+
+ for (local_list_iter iter = mMaterialList.begin();
+ iter != mMaterialList.end(); iter++)
+ {
+ LLSD element;
+
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = icon_name;
+
+ element["columns"][1]["column"] = "unit_name";
+ element["columns"][1]["type"] = "text";
+ element["columns"][1]["value"] = (*iter)->getShortName();
+
+ LLSD data;
+ data["id"] = (*iter)->getTrackingID();
+ data["type"] = (S32)LLAssetType::AT_MATERIAL;
+ element["value"] = data;
+
+ ctrl->addElement(element);
+ }
+ }
+ }
+
+}
+
+void LLLocalGLTFMaterialMgr::doUpdates()
+{
+ // preventing theoretical overlap in cases with huge number of loaded images.
+ mTimer.stopTimer();
+
+ for (local_list_iter iter = mMaterialList.begin(); iter != mMaterialList.end(); iter++)
+ {
+ (*iter)->updateSelf();
+ }
+
+ mTimer.startTimer();
+}
+
diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h
new file mode 100644
index 0000000000..13b7577e96
--- /dev/null
+++ b/indra/newview/lllocalgltfmaterials.h
@@ -0,0 +1,119 @@
+/**
+ * @file lllocalrendermaterials.h
+ * @brief Local GLTF materials header
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LOCALGLTFMATERIALS_H
+#define LL_LOCALGLTFMATERIALS_H
+
+#include "lleventtimer.h"
+#include "llpointer.h"
+#include "llgltfmateriallist.h"
+
+class LLScrollListCtrl;
+class LLGLTFMaterial;
+class LLViewerObject;
+class LLTextureEntry;
+
+class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial
+{
+public: /* main */
+ LLLocalGLTFMaterial(std::string filename, S32 index);
+ virtual ~LLLocalGLTFMaterial();
+
+public: /* accessors */
+ std::string getFilename() const;
+ std::string getShortName() const;
+ LLUUID getTrackingID() const;
+ LLUUID getWorldID() const;
+ S32 getIndexInFile() const;
+
+public:
+ bool updateSelf();
+
+private:
+ bool loadMaterial();
+
+private: /* private enums */
+ enum ELinkStatus
+ {
+ LS_ON,
+ LS_BROKEN,
+ };
+
+ enum EExtension
+ {
+ ET_MATERIAL_GLTF,
+ ET_MATERIAL_GLB,
+ };
+
+private: /* members */
+ std::string mFilename;
+ std::string mShortName;
+ LLUUID mTrackingID;
+ LLUUID mWorldID;
+ LLSD mLastModified;
+ EExtension mExtension;
+ ELinkStatus mLinkStatus;
+ S32 mUpdateRetries;
+ S32 mMaterialIndex; // Single file can have more than one
+};
+
+class LLLocalGLTFMaterialTimer : public LLEventTimer
+{
+public:
+ LLLocalGLTFMaterialTimer();
+ ~LLLocalGLTFMaterialTimer();
+
+public:
+ void startTimer();
+ void stopTimer();
+ bool isRunning();
+ BOOL tick();
+};
+
+class LLLocalGLTFMaterialMgr : public LLSingleton<LLLocalGLTFMaterialMgr>
+{
+ LLSINGLETON(LLLocalGLTFMaterialMgr);
+ ~LLLocalGLTFMaterialMgr();
+public:
+ S32 addUnit(const std::vector<std::string>& filenames);
+ S32 addUnit(const std::string& filename); // file can hold multiple materials
+ void delUnit(LLUUID tracking_id);
+
+ LLUUID getWorldID(LLUUID tracking_id);
+ bool isLocal(LLUUID world_id);
+ void getFilenameAndIndex(LLUUID tracking_id, std::string &filename, S32 &index);
+
+ void feedScrollList(LLScrollListCtrl* ctrl);
+ void doUpdates();
+
+private:
+ std::list<LLPointer<LLLocalGLTFMaterial> > mMaterialList;
+ LLLocalGLTFMaterialTimer mTimer;
+ typedef std::list<LLPointer<LLLocalGLTFMaterial> >::iterator local_list_iter;
+};
+
+#endif // LL_LOCALGLTFMATERIALS_H
+
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 8c03292361..052ac50185 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -59,7 +59,7 @@
#include <boost/date_time/posix_time/posix_time.hpp>
#include <boost/date_time/local_time_adjustor.hpp>
-const S32 LOG_RECALL_SIZE = 2048;
+const S32 LOG_RECALL_SIZE = 20480;
const std::string LL_IM_TIME("time");
const std::string LL_IM_DATE_TIME("datetime");
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 6589aa477f..feb691520f 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -72,14 +72,14 @@ void LLManip::rebuild(LLViewerObject* vobj)
LLDrawable* drawablep = vobj->mDrawable;
if (drawablep && drawablep->getVOVolume())
{
- gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(drawablep,LLDrawable::REBUILD_VOLUME);
drawablep->setState(LLDrawable::MOVE_UNDAMPED); // force to UNDAMPED
drawablep->updateMove();
LLSpatialGroup* group = drawablep->getSpatialGroup();
if (group)
{
group->dirtyGeom();
- gPipeline.markRebuild(group, TRUE);
+ gPipeline.markRebuild(group);
}
LLViewerObject::const_child_list_t& child_list = vobj->getChildren();
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d85a846f4d..7f37f98568 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -118,7 +118,6 @@ void LLManipRotate::render()
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
LLGLDepthTest gls_depth(GL_TRUE);
LLGLEnable gl_blend(GL_BLEND);
- LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
// You can rotate if you can move
LLViewerObject* first_object = mObjectSelection->getFirstMoveableObject(TRUE);
@@ -277,7 +276,7 @@ void LLManipRotate::render()
LLGLEnable cull_face(GL_CULL_FACE);
LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
// First pass: centers. Second pass: sides.
for( S32 i=0; i<2; i++ )
@@ -1715,6 +1714,7 @@ LLVector3 LLManipRotate::intersectRayWithSphere( const LLVector3& ray_pt, const
}
// Utility function. Should probably be moved to another class.
+// x,y - mouse position in scaled window coordinates (NOT GL viewport coordinates)
//static
void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_dir )
{
@@ -1728,10 +1728,8 @@ void LLManipRotate::mouseToRay( S32 x, S32 y, LLVector3* ray_pt, LLVector3* ray_
}
else
{
- *ray_pt = gAgentCamera.getCameraPositionAgent();
- LLViewerCamera::getInstance()->projectScreenToPosAgent(x, y, ray_dir);
- *ray_dir -= *ray_pt;
- ray_dir->normVec();
+ *ray_pt = gAgentCamera.getCameraPositionAgent();
+ *ray_dir = gViewerWindow->mouseDirectionGlobal(x, y);
}
}
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index e74fd1241b..6f685d4e62 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -212,7 +212,6 @@ void LLManipScale::render()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_TRUE);
LLGLEnable gl_blend(GL_BLEND);
- LLGLEnable gls_alpha_test(GL_ALPHA_TEST);
LLBBox bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
if( canAffectSelection() )
@@ -757,7 +756,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.pushMatrix();
{
@@ -1317,11 +1316,11 @@ void LLManipScale::renderGuidelinesPart( const LLBBox& bbox )
{
LLGLDepthTest gls_depth(GL_TRUE);
- gl_stippled_line_3d( guideline_start, guideline_end, LLColor4(1.f, 1.f, 1.f, 0.5f) );
+ gl_line_3d( guideline_start, guideline_end, LLColor4(1.f, 1.f, 1.f, 0.5f) );
}
{
LLGLDepthTest gls_depth(GL_FALSE);
- gl_stippled_line_3d( guideline_start, guideline_end, LLColor4(1.f, 1.f, 1.f, 0.25f) );
+ gl_line_3d( guideline_start, guideline_end, LLColor4(1.f, 1.f, 1.f, 0.25f) );
}
}
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 0b2a1ef389..cafb3fef67 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -267,11 +267,7 @@ void LLManipTranslate::restoreGL()
}
}
}
-#ifdef LL_WINDOWS
LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_BYTE, d);
-#else
- LLImageGL::setManualImage(GL_TEXTURE_2D, mip, GL_RGBA, rez, rez, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8_REV, d);
-#endif
rez = rez >> 1;
mip++;
}
@@ -1063,7 +1059,7 @@ void LLManipTranslate::render()
renderGuidelines();
}
{
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderTranslationHandles();
renderSnapGuides();
}
@@ -1529,7 +1525,7 @@ void LLManipTranslate::renderSnapGuides()
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
{
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getGridTexName());
@@ -1541,7 +1537,6 @@ void LLManipTranslate::renderSnapGuides()
}
{
- LLGLDisable alpha_test(GL_ALPHA_TEST);
//draw black overlay
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
renderGrid(u,v,tiles,0.0f, 0.0f, 0.0f,a*0.16f);
@@ -1562,7 +1557,6 @@ void LLManipTranslate::renderSnapGuides()
{
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GREATER);
- LLGLEnable stipple(GL_LINE_STIPPLE);
gGL.flush();
switch (mManipPart)
@@ -1628,6 +1622,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLQuaternion grid_rotation,
LLColor4 inner_color)
{
+#if 0 // DEPRECATED
if (!gSavedSettings.getBOOL("GridCrossSections"))
{
return;
@@ -1651,13 +1646,13 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
{
- glStencilMask(stencil_mask);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
+ //glStencilMask(stencil_mask); //deprecated
+ //glClearStencil(1);
+ //glClear(GL_STENCIL_BUFFER_BIT);
LLGLEnable cull_face(GL_CULL_FACE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
LLGLDepthTest depth (GL_TRUE, GL_FALSE, GL_ALWAYS);
- glStencilFunc(GL_ALWAYS, 0, stencil_mask);
+ //glStencilFunc(GL_ALWAYS, 0, stencil_mask);
gGL.setColorMask(false, false);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -1690,14 +1685,14 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
}
//stencil in volumes
- glStencilOp(GL_INCR, GL_INCR, GL_INCR);
+ //glStencilOp(GL_INCR, GL_INCR, GL_INCR);
glCullFace(GL_FRONT);
for (U32 i = 0; i < num_types; i++)
{
gPipeline.renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE);
}
- glStencilOp(GL_DECR, GL_DECR, GL_DECR);
+ //glStencilOp(GL_DECR, GL_DECR, GL_DECR);
glCullFace(GL_BACK);
for (U32 i = 0; i < num_types; i++)
{
@@ -1741,7 +1736,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_FALSE);
- LLGLEnable stencil(GL_STENCIL_TEST);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glStencilFunc(GL_EQUAL, 0, stencil_mask);
renderGrid(0,0,tiles,inner_color.mV[0], inner_color.mV[1], inner_color.mV[2], 0.25f);
@@ -1752,6 +1747,7 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gGL.popMatrix();
+#endif
}
void LLManipTranslate::renderText()
@@ -2184,7 +2180,6 @@ void LLManipTranslate::renderArrow(S32 which_arrow, S32 selected_arrow, F32 box_
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLEnable gls_blend(GL_BLEND);
- LLGLEnable gls_color_material(GL_COLOR_MATERIAL);
for (S32 pass = 1; pass <= 2; pass++)
{
diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp
new file mode 100644
index 0000000000..a5437f7a88
--- /dev/null
+++ b/indra/newview/llmaterialeditor.cpp
@@ -0,0 +1,3708 @@
+/**
+ * @file llmaterialeditor.cpp
+ * @brief Implementation of the gltf material editor
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llmaterialeditor.h"
+
+#include "llagent.h"
+#include "llagentbenefits.h"
+#include "llappviewer.h"
+#include "llcolorswatch.h"
+#include "llcombobox.h"
+#include "llfloaterreg.h"
+#include "llfilesystem.h"
+#include "llgltfmateriallist.h"
+#include "llinventorymodel.h"
+#include "llinventoryobserver.h"
+#include "lllocalgltfmaterials.h"
+#include "llnotificationsutil.h"
+#include "lltexturectrl.h"
+#include "lltrans.h"
+#include "llviewermenufile.h"
+#include "llviewertexture.h"
+#include "llsdutil.h"
+#include "llselectmgr.h"
+#include "llstatusbar.h" // can_afford_transaction()
+#include "lltoolpie.h"
+#include "llviewerinventory.h"
+#include "llinventory.h"
+#include "llviewerregion.h"
+#include "llvovolume.h"
+#include "roles_constants.h"
+#include "llviewerobjectlist.h"
+#include "llsdserialize.h"
+#include "llimagej2c.h"
+#include "llviewertexturelist.h"
+#include "llfloaterperms.h"
+
+#include "tinygltf/tiny_gltf.h"
+#include "lltinygltfhelper.h"
+#include <strstream>
+
+
+const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color";
+const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal";
+const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness";
+const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive";
+
+// Dirty flags
+static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0;
+static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1;
+
+static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 2;
+
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 3;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 4;
+static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 5;
+
+static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 6;
+static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 7;
+
+static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 8;
+static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 9;
+static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 10;
+
+LLUUID LLMaterialEditor::mOverrideObjectId;
+S32 LLMaterialEditor::mOverrideObjectTE = -1;
+bool LLMaterialEditor::mOverrideInProgress = false;
+bool LLMaterialEditor::mSelectionNeedsUpdate = true;
+
+LLFloaterComboOptions::LLFloaterComboOptions()
+ : LLFloater(LLSD())
+{
+ buildFromFile("floater_combobox_ok_cancel.xml");
+}
+
+LLFloaterComboOptions::~LLFloaterComboOptions()
+{
+
+}
+
+BOOL LLFloaterComboOptions::postBuild()
+{
+ mConfirmButton = getChild<LLButton>("combo_ok", TRUE);
+ mCancelButton = getChild<LLButton>("combo_cancel", TRUE);
+ mComboOptions = getChild<LLComboBox>("combo_options", TRUE);
+ mComboText = getChild<LLTextBox>("combo_text", TRUE);
+
+ mConfirmButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onConfirm(); });
+ mCancelButton->setCommitCallback([this](LLUICtrl* ctrl, const LLSD& param) {onCancel(); });
+
+ return TRUE;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = new LLFloaterComboOptions();
+ if (combo_picker)
+ {
+ combo_picker->mCallback = callback;
+ combo_picker->setTitle(title);
+
+ combo_picker->mComboText->setText(description);
+
+ std::list<std::string>::const_iterator iter = options.begin();
+ std::list<std::string>::const_iterator end = options.end();
+ for (; iter != end; iter++)
+ {
+ combo_picker->mComboOptions->addSimpleElement(*iter);
+ }
+ combo_picker->mComboOptions->selectFirstItem();
+
+ combo_picker->openFloater(LLSD(title));
+ combo_picker->setFocus(TRUE);
+ combo_picker->center();
+ }
+ return combo_picker;
+}
+
+LLFloaterComboOptions* LLFloaterComboOptions::showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options)
+{
+ LLFloaterComboOptions* combo_picker = showUI(callback, title, description, options);
+ if (combo_picker)
+ {
+ combo_picker->mConfirmButton->setLabel(ok_text);
+ combo_picker->mCancelButton->setLabel(cancel_text);
+ }
+ return combo_picker;
+}
+
+void LLFloaterComboOptions::onConfirm()
+{
+ mCallback(mComboOptions->getSimple(), mComboOptions->getCurrentIndex());
+ closeFloater();
+}
+
+void LLFloaterComboOptions::onCancel()
+{
+ mCallback(std::string(), -1);
+ closeFloater();
+}
+
+class LLMaterialEditorCopiedCallback : public LLInventoryCallback
+{
+public:
+ LLMaterialEditorCopiedCallback(
+ const std::string &buffer,
+ const LLSD &old_key,
+ bool has_unsaved_changes)
+ : mBuffer(buffer),
+ mOldKey(old_key),
+ mHasUnsavedChanges(has_unsaved_changes)
+ {}
+
+ LLMaterialEditorCopiedCallback(
+ const LLSD &old_key,
+ const std::string &new_name)
+ : mOldKey(old_key),
+ mNewName(new_name),
+ mHasUnsavedChanges(false)
+ {}
+
+ virtual void fire(const LLUUID& inv_item_id)
+ {
+ if (!mNewName.empty())
+ {
+ // making a copy from a notecard doesn't change name, do it now
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (item->getName() != mNewName)
+ {
+ LLSD updates;
+ updates["name"] = mNewName;
+ update_inventory_item(inv_item_id, updates, NULL);
+ }
+ }
+ LLMaterialEditor::finishSaveAs(mOldKey, inv_item_id, mBuffer, mHasUnsavedChanges);
+ }
+
+private:
+ std::string mBuffer;
+ LLSD mOldKey;
+ std::string mNewName;
+ bool mHasUnsavedChanges;
+};
+
+///----------------------------------------------------------------------------
+/// Class LLSelectedTEGetMatData
+/// For finding selected applicable inworld material
+///----------------------------------------------------------------------------
+
+struct LLSelectedTEGetMatData : public LLSelectedTEFunctor
+{
+ LLSelectedTEGetMatData(bool for_override);
+
+ bool apply(LLViewerObject* objectp, S32 te_index);
+
+ bool mIsOverride;
+ bool mIdenticalTexColor;
+ bool mIdenticalTexMetal;
+ bool mIdenticalTexEmissive;
+ bool mIdenticalTexNormal;
+ bool mFirst;
+ LLUUID mTexColorId;
+ LLUUID mTexMetalId;
+ LLUUID mTexEmissiveId;
+ LLUUID mTexNormalId;
+ LLUUID mObjectId;
+ LLViewerObject* mObject = nullptr;
+ S32 mObjectTE;
+ LLUUID mMaterialId;
+ LLPointer<LLGLTFMaterial> mMaterial;
+ LLPointer<LLLocalGLTFMaterial> mLocalMaterial;
+};
+
+LLSelectedTEGetMatData::LLSelectedTEGetMatData(bool for_override)
+ : mIsOverride(for_override)
+ , mIdenticalTexColor(true)
+ , mIdenticalTexMetal(true)
+ , mIdenticalTexEmissive(true)
+ , mIdenticalTexNormal(true)
+ , mObjectTE(-1)
+ , mFirst(true)
+{}
+
+bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index)
+{
+ if (!objectp)
+ {
+ return false;
+ }
+ LLUUID mat_id = objectp->getRenderMaterialID(te_index);
+ mMaterialId = mat_id;
+ bool can_use = mIsOverride ? objectp->permModify() : objectp->permCopy();
+ LLTextureEntry *tep = objectp->getTE(te_index);
+ // We might want to disable this entirely if at least
+ // something in selection is no-copy or no modify
+ // or has no base material
+ if (can_use && tep && mat_id.notNull())
+ {
+ if (mIsOverride)
+ {
+ LLPointer<LLGLTFMaterial> mat = tep->getGLTFRenderMaterial();
+
+ LLUUID tex_color_id;
+ LLUUID tex_metal_id;
+ LLUUID tex_emissive_id;
+ LLUUID tex_normal_id;
+ llassert(mat.notNull()); // by this point shouldn't be null
+ if (mat.notNull())
+ {
+ tex_color_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR];
+ tex_metal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS];
+ tex_emissive_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE];
+ tex_normal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL];
+ }
+ if (mFirst)
+ {
+ mMaterial = mat;
+ mTexColorId = tex_color_id;
+ mTexMetalId = tex_metal_id;
+ mTexEmissiveId = tex_emissive_id;
+ mTexNormalId = tex_normal_id;
+ mObjectTE = te_index;
+ mObject = objectp;
+ mObjectId = objectp->getID();
+ mFirst = false;
+ }
+ else
+ {
+ if (mTexColorId != tex_color_id)
+ {
+ mIdenticalTexColor = false;
+ }
+ if (mTexMetalId != tex_metal_id)
+ {
+ mIdenticalTexMetal = false;
+ }
+ if (mTexEmissiveId != tex_emissive_id)
+ {
+ mIdenticalTexEmissive = false;
+ }
+ if (mTexNormalId != tex_normal_id)
+ {
+ mIdenticalTexNormal = false;
+ }
+ }
+ }
+ else
+ {
+ LLGLTFMaterial *mat = tep->getGLTFMaterial();
+ LLLocalGLTFMaterial *local_mat = dynamic_cast<LLLocalGLTFMaterial*>(mat);
+
+ mObject = objectp;
+ mObjectId = objectp->getID();
+ if (local_mat)
+ {
+ mLocalMaterial = local_mat;
+ }
+ mMaterial = tep->getGLTFRenderMaterial();
+
+ if (mMaterial.isNull())
+ {
+ // Shouldn't be possible?
+ LL_WARNS("MaterialEditor") << "Object has material id, but no material" << LL_ENDL;
+ mMaterial = gGLTFMaterialList.getMaterial(mat_id);
+ }
+ }
+ return true;
+ }
+ return false;
+}
+
+class LLSelectedTEUpdateOverrides: public LLSelectedNodeFunctor
+{
+public:
+ LLSelectedTEUpdateOverrides(LLMaterialEditor* me) : mEditor(me) {}
+
+ virtual bool apply(LLSelectNode* nodep);
+
+ LLMaterialEditor* mEditor;
+};
+
+bool LLSelectedTEUpdateOverrides::apply(LLSelectNode* nodep)
+{
+ LLViewerObject* objectp = nodep->getObject();
+ if (!objectp)
+ {
+ return false;
+ }
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+ for (S32 te_index = 0; te_index < num_tes; ++te_index)
+ {
+
+ LLTextureEntry* tep = objectp->getTE(te_index);
+ LLGLTFMaterial* override_mat = tep->getGLTFMaterialOverride();
+ if (mEditor->updateMaterialLocalSubscription(override_mat))
+ {
+ LLGLTFMaterial* render_mat = tep->getGLTFRenderMaterial();
+ mEditor->updateMaterialLocalSubscription(render_mat);
+ }
+ }
+
+ return true;
+}
+
+///----------------------------------------------------------------------------
+/// Class LLMaterialEditor
+///----------------------------------------------------------------------------
+
+// Default constructor
+LLMaterialEditor::LLMaterialEditor(const LLSD& key)
+ : LLPreview(key)
+ , mUnsavedChanges(0)
+ , mRevertedChanges(0)
+ , mExpectedUploadCost(0)
+ , mUploadingTexturesCount(0)
+ , mUploadingTexturesFailure(false)
+{
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+LLMaterialEditor::~LLMaterialEditor()
+{
+}
+
+void LLMaterialEditor::setObjectID(const LLUUID& object_id)
+{
+ LLPreview::setObjectID(object_id);
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+void LLMaterialEditor::setAuxItem(const LLInventoryItem* item)
+{
+ LLPreview::setAuxItem(item);
+ if (item)
+ {
+ mAssetID = item->getAssetUUID();
+ }
+}
+
+BOOL LLMaterialEditor::postBuild()
+{
+ // if this is a 'live editor' instance, it is also
+ // single instance and uses live overrides
+ mIsOverride = getIsSingleInstance();
+
+ mBaseColorTextureCtrl = getChild<LLTextureCtrl>("base_color_texture");
+ mMetallicTextureCtrl = getChild<LLTextureCtrl>("metallic_roughness_texture");
+ mEmissiveTextureCtrl = getChild<LLTextureCtrl>("emissive_texture");
+ mNormalTextureCtrl = getChild<LLTextureCtrl>("normal_texture");
+ mBaseColorCtrl = getChild<LLColorSwatchCtrl>("base color");
+ mEmissiveColorCtrl = getChild<LLColorSwatchCtrl>("emissive color");
+
+ if (!gAgent.isGodlike())
+ {
+ // Only allow fully permissive textures
+ mBaseColorTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mMetallicTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mEmissiveTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ mNormalTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+
+ // Texture callback
+ mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY));
+ mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY));
+ mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY));
+ mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitTexture, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY));
+
+ if (mIsOverride)
+ {
+ // Live editing needs a recovery mechanism on cancel
+ mBaseColorTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY));
+ mMetallicTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY));
+ mEmissiveTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY));
+ mNormalTextureCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY));
+
+ // Save applied changes on 'OK' to our recovery mechanism.
+ mBaseColorTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_TEX_DIRTY));
+ mMetallicTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY));
+ mEmissiveTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_TEX_DIRTY));
+ mNormalTextureCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_NORMAL_TEX_DIRTY));
+ }
+ else
+ {
+ mBaseColorTextureCtrl->setCanApplyImmediately(false);
+ mMetallicTextureCtrl->setCanApplyImmediately(false);
+ mEmissiveTextureCtrl->setCanApplyImmediately(false);
+ mNormalTextureCtrl->setCanApplyImmediately(false);
+ }
+
+ if (!mIsOverride)
+ {
+ childSetAction("save", boost::bind(&LLMaterialEditor::onClickSave, this));
+ childSetAction("save_as", boost::bind(&LLMaterialEditor::onClickSaveAs, this));
+ childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this));
+ }
+
+ if (mIsOverride)
+ {
+ childSetVisible("base_color_upload_fee", FALSE);
+ childSetVisible("metallic_upload_fee", FALSE);
+ childSetVisible("emissive_upload_fee", FALSE);
+ childSetVisible("normal_upload_fee", FALSE);
+ }
+ else
+ {
+ S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ getChild<LLUICtrl>("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost));
+ }
+
+ boost::function<void(LLUICtrl*, void*)> changes_callback = [this](LLUICtrl * ctrl, void* userData)
+ {
+ const U32 *flag = (const U32*)userData;
+ markChangesUnsaved(*flag);
+ // Apply changes to object live
+ applyToSelection();
+ };
+
+ childSetCommitCallback("double sided", changes_callback, (void*)&MATERIAL_DOUBLE_SIDED_DIRTY);
+
+ // BaseColor
+ mBaseColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
+ if (mIsOverride)
+ {
+ mBaseColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY));
+ mBaseColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_BASE_COLOR_DIRTY));
+ }
+ else
+ {
+ mBaseColorCtrl->setCanApplyImmediately(false);
+ }
+ // transparency is a part of base color
+ childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY);
+ childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY);
+ childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY);
+
+ // Metallic-Roughness
+ childSetCommitCallback("metalness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY);
+ childSetCommitCallback("roughness factor", changes_callback, (void*)&MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY);
+
+ // Emissive
+ mEmissiveColorCtrl->setCommitCallback(changes_callback, (void*)&MATERIAL_EMISIVE_COLOR_DIRTY);
+ if (mIsOverride)
+ {
+ mEmissiveColorCtrl->setOnCancelCallback(boost::bind(&LLMaterialEditor::onCancelCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY));
+ mEmissiveColorCtrl->setOnSelectCallback(boost::bind(&LLMaterialEditor::onSelectCtrl, this, _1, _2, MATERIAL_EMISIVE_COLOR_DIRTY));
+ }
+ else
+ {
+ mEmissiveColorCtrl->setCanApplyImmediately(false);
+ }
+
+ if (!mIsOverride)
+ {
+ // "unsaved_changes" doesn't exist in live editor
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ // Doesn't exist in live editor
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", 0));
+ }
+
+ // Todo:
+ // Disable/enable setCanApplyImmediately() based on
+ // working from inventory, upload or editing inworld
+
+ return LLPreview::postBuild();
+}
+
+void LLMaterialEditor::onClickCloseBtn(bool app_quitting)
+{
+ if (app_quitting || mIsOverride)
+ {
+ closeFloater(app_quitting);
+ }
+ else
+ {
+ onClickCancel();
+ }
+}
+
+void LLMaterialEditor::onClose(bool app_quitting)
+{
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
+ for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates)
+ {
+ cn.second.mConnection.disconnect();
+ }
+ mTextureChangesUpdates.clear();
+
+ LLPreview::onClose(app_quitting);
+}
+
+void LLMaterialEditor::draw()
+{
+ if (mIsOverride)
+ {
+ if (mSelectionNeedsUpdate)
+ {
+ mSelectionNeedsUpdate = false;
+ clearTextures();
+ setFromSelection();
+ }
+ }
+ LLPreview::draw();
+}
+
+void LLMaterialEditor::handleReshape(const LLRect& new_rect, bool by_user)
+{
+ if (by_user)
+ {
+ const LLRect old_rect = getRect();
+ LLRect clamp_rect(new_rect);
+ clamp_rect.mRight = clamp_rect.mLeft + old_rect.getWidth();
+ LLPreview::handleReshape(clamp_rect, by_user);
+ }
+ else
+ {
+ LLPreview::handleReshape(new_rect, by_user);
+ }
+}
+
+LLUUID LLMaterialEditor::getBaseColorId()
+{
+ return mBaseColorTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setBaseColorId(const LLUUID& id)
+{
+ mBaseColorTextureCtrl->setValue(id);
+ mBaseColorTextureCtrl->setDefaultImageAssetID(id);
+ mBaseColorTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id)
+{
+ // Might be better to use local textures and
+ // assign a fee in case of a local texture
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("base_color_upload_fee", getString("upload_fee_string"));
+ // Only set if we will need to upload this texture
+ mBaseColorTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_BASE_COLOR_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getBaseColor()
+{
+ LLColor4 ret = linearColor4(LLColor4(mBaseColorCtrl->getValue()));
+ ret.mV[3] = getTransparency();
+ return ret;
+}
+
+void LLMaterialEditor::setBaseColor(const LLColor4& color)
+{
+ mBaseColorCtrl->setValue(srgbColor4(color).getValue());
+ setTransparency(color.mV[3]);
+}
+
+F32 LLMaterialEditor::getTransparency()
+{
+ return childGetValue("transparency").asReal();
+}
+
+void LLMaterialEditor::setTransparency(F32 transparency)
+{
+ childSetValue("transparency", transparency);
+}
+
+std::string LLMaterialEditor::getAlphaMode()
+{
+ return childGetValue("alpha mode").asString();
+}
+
+void LLMaterialEditor::setAlphaMode(const std::string& alpha_mode)
+{
+ childSetValue("alpha mode", alpha_mode);
+}
+
+F32 LLMaterialEditor::getAlphaCutoff()
+{
+ return childGetValue("alpha cutoff").asReal();
+}
+
+void LLMaterialEditor::setAlphaCutoff(F32 alpha_cutoff)
+{
+ childSetValue("alpha cutoff", alpha_cutoff);
+}
+
+void LLMaterialEditor::setMaterialName(const std::string &name)
+{
+ setTitle(name);
+ mMaterialName = name;
+}
+
+LLUUID LLMaterialEditor::getMetallicRoughnessId()
+{
+ return mMetallicTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setMetallicRoughnessId(const LLUUID& id)
+{
+ mMetallicTextureCtrl->setValue(id);
+ mMetallicTextureCtrl->setDefaultImageAssetID(id);
+ mMetallicTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setMetallicRoughnessUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("metallic_upload_fee", getString("upload_fee_string"));
+ mMetallicTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+}
+
+F32 LLMaterialEditor::getMetalnessFactor()
+{
+ return childGetValue("metalness factor").asReal();
+}
+
+void LLMaterialEditor::setMetalnessFactor(F32 factor)
+{
+ childSetValue("metalness factor", factor);
+}
+
+F32 LLMaterialEditor::getRoughnessFactor()
+{
+ return childGetValue("roughness factor").asReal();
+}
+
+void LLMaterialEditor::setRoughnessFactor(F32 factor)
+{
+ childSetValue("roughness factor", factor);
+}
+
+LLUUID LLMaterialEditor::getEmissiveId()
+{
+ return mEmissiveTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setEmissiveId(const LLUUID& id)
+{
+ mEmissiveTextureCtrl->setValue(id);
+ mEmissiveTextureCtrl->setDefaultImageAssetID(id);
+ mEmissiveTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setEmissiveUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("emissive_upload_fee", getString("upload_fee_string"));
+ mEmissiveTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_EMISIVE_TEX_DIRTY);
+}
+
+LLColor4 LLMaterialEditor::getEmissiveColor()
+{
+ return linearColor4(LLColor4(mEmissiveColorCtrl->getValue()));
+}
+
+void LLMaterialEditor::setEmissiveColor(const LLColor4& color)
+{
+ mEmissiveColorCtrl->setValue(srgbColor4(color).getValue());
+}
+
+LLUUID LLMaterialEditor::getNormalId()
+{
+ return mNormalTextureCtrl->getValue().asUUID();
+}
+
+void LLMaterialEditor::setNormalId(const LLUUID& id)
+{
+ mNormalTextureCtrl->setValue(id);
+ mNormalTextureCtrl->setDefaultImageAssetID(id);
+ mNormalTextureCtrl->setTentative(FALSE);
+}
+
+void LLMaterialEditor::setNormalUploadId(const LLUUID& id)
+{
+ if (id.notNull())
+ {
+ // todo: this does not account for posibility of texture
+ // being from inventory, need to check that
+ childSetValue("normal_upload_fee", getString("upload_fee_string"));
+ mNormalTextureUploadId = id;
+ }
+ markChangesUnsaved(MATERIAL_NORMAL_TEX_DIRTY);
+}
+
+bool LLMaterialEditor::getDoubleSided()
+{
+ return childGetValue("double sided").asBoolean();
+}
+
+void LLMaterialEditor::setDoubleSided(bool double_sided)
+{
+ childSetValue("double sided", double_sided);
+}
+
+void LLMaterialEditor::resetUnsavedChanges()
+{
+ mUnsavedChanges = 0;
+ mRevertedChanges = 0;
+ if (!mIsOverride)
+ {
+ childSetVisible("unsaved_changes", false);
+ setCanSave(false);
+
+ mExpectedUploadCost = 0;
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+ }
+}
+
+void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag)
+{
+ mUnsavedChanges |= dirty_flag;
+ if (mIsOverride)
+ {
+ // at the moment live editing (mIsOverride) applies everything 'live'
+ // and "unsaved_changes", save/cancel buttons don't exist there
+ return;
+ }
+
+ childSetVisible("unsaved_changes", mUnsavedChanges);
+
+ if (mUnsavedChanges)
+ {
+ const LLInventoryItem* item = getItem();
+ if (item)
+ {
+ //LLPermissions perm(item->getPermissions());
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+ bool source_notecard = mNotecardInventoryID.notNull();
+
+ setCanSave(allow_modify && !source_library && !source_notecard);
+ }
+ }
+ else
+ {
+ setCanSave(false);
+ }
+
+ S32 upload_texture_count = 0;
+ if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId())
+ {
+ upload_texture_count++;
+ }
+ if (mMetallicTextureUploadId.notNull() && mMetallicTextureUploadId == getMetallicRoughnessId())
+ {
+ upload_texture_count++;
+ }
+ if (mEmissiveTextureUploadId.notNull() && mEmissiveTextureUploadId == getEmissiveId())
+ {
+ upload_texture_count++;
+ }
+ if (mNormalTextureUploadId.notNull() && mNormalTextureUploadId == getNormalId())
+ {
+ upload_texture_count++;
+ }
+
+ mExpectedUploadCost = upload_texture_count * LLAgentBenefitsMgr::current().getTextureUploadCost();
+ getChild<LLUICtrl>("total_upload_fee")->setTextArg("[FEE]", llformat("%d", mExpectedUploadCost));
+}
+
+void LLMaterialEditor::setCanSaveAs(bool value)
+{
+ if (!mIsOverride)
+ {
+ childSetEnabled("save_as", value);
+ }
+}
+
+void LLMaterialEditor::setCanSave(bool value)
+{
+ if (!mIsOverride)
+ {
+ childSetEnabled("save", value);
+ }
+}
+
+void LLMaterialEditor::setEnableEditing(bool can_modify)
+{
+ childSetEnabled("double sided", can_modify);
+
+ // BaseColor
+ childSetEnabled("base color", can_modify);
+ childSetEnabled("transparency", can_modify);
+ childSetEnabled("alpha mode", can_modify);
+ childSetEnabled("alpha cutoff", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Metallic-Roughness
+ childSetEnabled("metalness factor", can_modify);
+ childSetEnabled("roughness factor", can_modify);
+
+ // Emissive
+ childSetEnabled("emissive color", can_modify);
+
+ mBaseColorTextureCtrl->setEnabled(can_modify);
+ mMetallicTextureCtrl->setEnabled(can_modify);
+ mEmissiveTextureCtrl->setEnabled(can_modify);
+ mNormalTextureCtrl->setEnabled(can_modify);
+}
+
+void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id)
+{
+ if (mTextureChangesUpdates[dirty_flag].mTrackingId != tracking_id)
+ {
+ mTextureChangesUpdates[dirty_flag].mConnection.disconnect();
+ mTextureChangesUpdates[dirty_flag].mTrackingId = tracking_id;
+ mTextureChangesUpdates[dirty_flag].mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id,
+ [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id)
+ {
+ if (new_id.isNull())
+ {
+ mTextureChangesUpdates[dirty_flag].mConnection.disconnect();
+ //mTextureChangesUpdates.erase(dirty_flag);
+ }
+ else
+ {
+ replaceLocalTexture(old_id, new_id);
+ }
+ });
+ }
+}
+
+LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag)
+{
+ mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag);
+ if (found != mTextureChangesUpdates.end())
+ {
+ return found->second.mTrackingId;
+ }
+ return LLUUID();
+}
+
+bool LLMaterialEditor::updateMaterialLocalSubscription(LLGLTFMaterial* mat)
+{
+ if (!mat)
+ {
+ return false;
+ }
+
+ bool res = false;
+ for (mat_connection_map_t::value_type& cn : mTextureChangesUpdates)
+ {
+ LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId);
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat);
+ res = true;
+ continue;
+ }
+ }
+ return res;
+}
+
+void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id)
+{
+ // todo: might be a good idea to set mBaseColorTextureUploadId here
+ // and when texturectrl picks a local texture
+ if (getBaseColorId() == old_id)
+ {
+ mBaseColorTextureCtrl->setValue(new_id);
+ }
+ if (mBaseColorTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mBaseColorTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getMetallicRoughnessId() == old_id)
+ {
+ mMetallicTextureCtrl->setValue(new_id);
+ }
+ if (mMetallicTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mMetallicTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getEmissiveId() == old_id)
+ {
+ mEmissiveTextureCtrl->setValue(new_id);
+ }
+ if (mEmissiveTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mEmissiveTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+
+ if (getNormalId() == old_id)
+ {
+ mNormalTextureCtrl->setValue(new_id);
+ }
+ if (mNormalTextureCtrl->getDefaultImageAssetID() == old_id)
+ {
+ mNormalTextureCtrl->setDefaultImageAssetID(new_id);
+ }
+}
+
+void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)
+{
+ if (!mIsOverride)
+ {
+ std::string upload_fee_ctrl_name;
+ LLUUID old_uuid;
+
+ switch (dirty_flag)
+ {
+ case MATERIAL_BASE_COLOR_TEX_DIRTY:
+ {
+ upload_fee_ctrl_name = "base_color_upload_fee";
+ old_uuid = mBaseColorTextureUploadId;
+ break;
+ }
+ case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
+ {
+ upload_fee_ctrl_name = "metallic_upload_fee";
+ old_uuid = mMetallicTextureUploadId;
+ break;
+ }
+ case MATERIAL_EMISIVE_TEX_DIRTY:
+ {
+ upload_fee_ctrl_name = "emissive_upload_fee";
+ old_uuid = mEmissiveTextureUploadId;
+ break;
+ }
+ case MATERIAL_NORMAL_TEX_DIRTY:
+ {
+ upload_fee_ctrl_name = "normal_upload_fee";
+ old_uuid = mNormalTextureUploadId;
+ break;
+ }
+ default:
+ break;
+ }
+ LLUUID new_val = ctrl->getValue().asUUID();
+ if (new_val == old_uuid && old_uuid.notNull())
+ {
+ childSetValue(upload_fee_ctrl_name, getString("upload_fee_string"));
+ }
+ else
+ {
+ // Texture picker has 'apply now' with 'cancel' support.
+ // Don't clean mBaseColorJ2C and mBaseColorFetched, it's our
+ // storage in case user decides to cancel changes.
+ // Without mBaseColorFetched, viewer will eventually cleanup
+ // the texture that is not in use
+ childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string"));
+ }
+ }
+
+ LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl;
+ if (tex_ctrl->isImageLocal())
+ {
+ subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID());
+ }
+ else
+ {
+ // unsubcribe potential old callabck
+ mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag);
+ if (found != mTextureChangesUpdates.end())
+ {
+ found->second.mConnection.disconnect();
+ }
+ }
+
+ markChangesUnsaved(dirty_flag);
+ applyToSelection();
+}
+
+void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)
+{
+ mRevertedChanges |= dirty_flag;
+ applyToSelection();
+}
+
+void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat)
+{
+ LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl;
+ if (tex_ctrl->isImageLocal())
+ {
+ // subscrive material to updates of local textures
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat);
+ }
+}
+
+void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag)
+{
+ mUnsavedChanges |= dirty_flag;
+ applyToSelection();
+
+ struct f : public LLSelectedNodeFunctor
+ {
+ f(LLUICtrl* ctrl, S32 dirty_flag) : mCtrl(ctrl), mDirtyFlag(dirty_flag)
+ {
+ }
+
+ virtual bool apply(LLSelectNode* nodep)
+ {
+ LLViewerObject* objectp = nodep->getObject();
+ if (!objectp)
+ {
+ return false;
+ }
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (nodep->isTESelected(te) && nodep->mSavedGLTFOverrideMaterials.size() > te)
+ {
+ if (nodep->mSavedGLTFOverrideMaterials[te].isNull())
+ {
+ // populate with default values, default values basically mean 'not in use'
+ nodep->mSavedGLTFOverrideMaterials[te] = new LLGLTFMaterial();
+ }
+
+ switch (mDirtyFlag)
+ {
+ //Textures
+ case MATERIAL_BASE_COLOR_TEX_DIRTY:
+ {
+ nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
+ break;
+ }
+ case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY:
+ {
+ nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
+ break;
+ }
+ case MATERIAL_EMISIVE_TEX_DIRTY:
+ {
+ nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
+ break;
+ }
+ case MATERIAL_NORMAL_TEX_DIRTY:
+ {
+ nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true);
+ update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get());
+ break;
+ }
+ // Colors
+ case MATERIAL_BASE_COLOR_DIRTY:
+ {
+ LLColor4 ret = linearColor4(LLColor4(mCtrl->getValue()));
+ // except transparency
+ ret.mV[3] = nodep->mSavedGLTFOverrideMaterials[te]->mBaseColor.mV[3];
+ nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorFactor(ret, true);
+ break;
+ }
+ case MATERIAL_EMISIVE_COLOR_DIRTY:
+ {
+ nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveColorFactor(LLColor3(mCtrl->getValue()), true);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+ }
+ return true;
+ }
+
+ LLUICtrl* mCtrl;
+ S32 mDirtyFlag;
+ } func(ctrl, dirty_flag);
+
+ LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func);
+}
+
+void LLMaterialEditor::onClickSave()
+{
+ if (!capabilitiesAvailable())
+ {
+ LLNotificationsUtil::add("MissingMaterialCaps");
+ return;
+ }
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ applyToSelection();
+ saveIfNeeded();
+}
+
+std::string LLMaterialEditor::getEncodedAsset()
+{
+ LLSD asset;
+ asset["version"] = LLGLTFMaterial::ASSET_VERSION;
+ asset["type"] = LLGLTFMaterial::ASSET_TYPE;
+ LLGLTFMaterial mat;
+ getGLTFMaterial(&mat);
+ asset["data"] = mat.asJSON();
+
+ std::ostringstream str;
+ LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
+
+ return str.str();
+}
+
+bool LLMaterialEditor::decodeAsset(const std::vector<char>& buffer)
+{
+ LLSD asset;
+
+ std::istrstream str(&buffer[0], buffer.size());
+ if (LLSDSerialize::deserialize(asset, str, buffer.size()))
+ {
+ if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString()))
+ {
+ if (asset.has("type") && asset["type"] == LLGLTFMaterial::ASSET_TYPE)
+ {
+ if (asset.has("data") && asset["data"].isString())
+ {
+ std::string data = asset["data"];
+
+ tinygltf::TinyGLTF gltf;
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ tinygltf::Model model_in;
+
+ if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), ""))
+ {
+ // assets are only supposed to have one item
+ // *NOTE: This duplicates some functionality from
+ // LLGLTFMaterial::fromJSON, but currently does the job
+ // better for the material editor use case.
+ // However, LLGLTFMaterial::asJSON should always be
+ // used when uploading materials, to ensure the
+ // asset is valid.
+ return setFromGltfModel(model_in, 0, true);
+ }
+ else
+ {
+ LL_WARNS("MaterialEditor") << "Floater " << getKey() << " Failed to decode material asset: " << LL_NEWLINE
+ << warn_msg << LL_NEWLINE
+ << error_msg << LL_ENDL;
+ }
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("MaterialEditor") << "Invalid LLSD content "<< asset << " for flaoter " << getKey() << LL_ENDL;
+ }
+ }
+ else
+ {
+ LL_WARNS("MaterialEditor") << "Failed to deserialize material LLSD for flaoter " << getKey() << LL_ENDL;
+ }
+
+ return false;
+}
+
+/**
+ * Build a description of the material we just imported.
+ * Currently this means a list of the textures present but we
+ * may eventually want to make it more complete - will be guided
+ * by what the content creators say they need.
+ */
+const std::string LLMaterialEditor::buildMaterialDescription()
+{
+ std::ostringstream desc;
+ desc << LLTrans::getString("Material Texture Name Header");
+
+ // add the texture names for each just so long as the material
+ // we loaded has an entry for it (i think testing the texture
+ // control UUI for NULL is a valid metric for if it was loaded
+ // or not but I suspect this code will change a lot so may need
+ // to revisit
+ if (!mBaseColorTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mBaseColorName;
+ desc << ", ";
+ }
+ if (!mMetallicTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mMetallicRoughnessName;
+ desc << ", ";
+ }
+ if (!mEmissiveTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mEmissiveName;
+ desc << ", ";
+ }
+ if (!mNormalTextureCtrl->getValue().asUUID().isNull())
+ {
+ desc << mNormalName;
+ }
+
+ // trim last char if it's a ',' in case there is no normal texture
+ // present and the code above inserts one
+ // (no need to check for string length - always has initial string)
+ std::string::iterator iter = desc.str().end() - 1;
+ if (*iter == ',')
+ {
+ desc.str().erase(iter);
+ }
+
+ // sanitize the material description so that it's compatible with the inventory
+ // note: split this up because clang doesn't like operating directly on the
+ // str() - error: lvalue reference to type 'basic_string<...>' cannot bind to a
+ // temporary of type 'basic_string<...>'
+ std::string inv_desc = desc.str();
+ LLInventoryObject::correctInventoryName(inv_desc);
+
+ return inv_desc;
+}
+
+bool LLMaterialEditor::saveIfNeeded()
+{
+ if (mUploadingTexturesCount > 0)
+ {
+ // Upload already in progress, wait until
+ // textures upload will retry saving on callback.
+ // Also should prevent some failure-callbacks
+ return true;
+ }
+
+ if (saveTextures() > 0)
+ {
+ // started texture upload
+ setEnabled(false);
+ return true;
+ }
+
+ std::string buffer = getEncodedAsset();
+
+ const LLInventoryItem* item = getItem();
+ // save it out to database
+ if (item)
+ {
+ if (!updateInventoryItem(buffer, mItemUUID, mObjectUUID))
+ {
+ return false;
+ }
+
+ if (mCloseAfterSave)
+ {
+ closeFloater();
+ }
+ else
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ }
+ else
+ {
+ // Make a new inventory item and set upload permissions
+ LLPermissions local_permissions;
+ local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+
+ U32 everyone_perm = LLFloaterPerms::getEveryonePerms("Materials");
+ U32 group_perm = LLFloaterPerms::getGroupPerms("Materials");
+ U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ local_permissions.initMasks(PERM_ALL, PERM_ALL, everyone_perm, group_perm, next_owner_perm);
+
+ std::string res_desc = buildMaterialDescription();
+ createInventoryItem(buffer, mMaterialName, res_desc, local_permissions);
+
+ // We do not update floater with uploaded asset yet, so just close it.
+ closeFloater();
+ }
+
+ return true;
+}
+
+// static
+bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id)
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS("MaterialEditor") << "Not connected to a region, cannot save material." << LL_ENDL;
+ return false;
+ }
+ std::string agent_url = region->getCapability("UpdateMaterialAgentInventory");
+ std::string task_url = region->getCapability("UpdateMaterialTaskInventory");
+
+ if (!agent_url.empty() && !task_url.empty())
+ {
+ std::string url;
+ LLResourceUploadInfo::ptr_t uploadInfo;
+
+ if (task_id.isNull() && !agent_url.empty())
+ {
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(item_id, LLAssetType::AT_MATERIAL, buffer,
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD)
+ {
+ // done callback
+ LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId);
+ },
+ [](LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)
+ {
+ // failure callback
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(itemId));
+ if (me)
+ {
+ me->setEnabled(true);
+ }
+ return true;
+ }
+ );
+ url = agent_url;
+ }
+ else if (!task_id.isNull() && !task_url.empty())
+ {
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(task_id, item_id, LLAssetType::AT_MATERIAL, buffer,
+ [](LLUUID itemId, LLUUID task_id, LLUUID newAssetId, LLSD)
+ {
+ // done callback
+ LLMaterialEditor::finishTaskUpload(itemId, newAssetId, task_id);
+ },
+ [](LLUUID itemId, LLUUID task_id, LLSD response, std::string reason)
+ {
+ // failure callback
+ LLSD floater_key;
+ floater_key["taskid"] = task_id;
+ floater_key["itemid"] = itemId;
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (me)
+ {
+ me->setEnabled(true);
+ }
+ return true;
+ }
+ );
+ url = task_url;
+ }
+
+ if (!url.empty() && uploadInfo)
+ {
+ LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
+ }
+ else
+ {
+ return false;
+ }
+
+ }
+ else // !gAssetStorage
+ {
+ LL_WARNS("MaterialEditor") << "Not connected to an materials capable region." << LL_ENDL;
+ return false;
+ }
+
+ // todo: apply permissions from textures here if server doesn't
+ // if any texture is 'no transfer', material should be 'no transfer' as well
+
+ return true;
+}
+
+// Callback intended for when a material is saved from an object and needs to
+// be modified to reflect the new asset/name.
+class LLObjectsMaterialItemCallback : public LLInventoryCallback
+{
+public:
+ LLObjectsMaterialItemCallback(const LLPermissions& permissions, const std::string& asset_data, const std::string& new_name)
+ : mPermissions(permissions),
+ mAssetData(asset_data),
+ mNewName(new_name)
+ {
+ }
+
+ void fire(const LLUUID& inv_item_id) override
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+ if (!item)
+ {
+ return;
+ }
+
+ // create_inventory_item/copy_inventory_item don't allow presetting some permissions, fix it now
+ item->setPermissions(mPermissions);
+ item->updateServer(FALSE);
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+
+ if (item->getName() != mNewName)
+ {
+ LLSD updates;
+ updates["name"] = mNewName;
+ update_inventory_item(inv_item_id, updates, NULL);
+ }
+
+ // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem()
+ LLResourceUploadInfo::ptr_t uploadInfo =
+ std::make_shared<LLBufferedAssetUploadInfo>(
+ inv_item_id,
+ LLAssetType::AT_MATERIAL,
+ mAssetData,
+ [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response)
+ {
+ // done callback
+ LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL;
+ },
+ nullptr // failure callback, floater already closed
+ );
+
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ std::string agent_url(region->getCapability("UpdateMaterialAgentInventory"));
+ if (agent_url.empty())
+ {
+ LL_ERRS("MaterialEditor") << "missing required agent inventory cap url" << LL_ENDL;
+ }
+ LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
+ }
+ }
+private:
+ LLPermissions mPermissions;
+ std::string mAssetData;
+ std::string mNewName;
+};
+
+void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions)
+{
+ // gen a new uuid for this asset
+ LLTransactionID tid;
+ tid.generate(); // timestamp-based randomization + uniquification
+ LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ?
+
+ LLPointer<LLObjectsMaterialItemCallback> cb = new LLObjectsMaterialItemCallback(permissions, buffer, name);
+ create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, name, desc,
+ LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, permissions.getMaskNextOwner(),
+ cb);
+}
+
+void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId)
+{
+ // Update the UI with the new asset.
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(itemId));
+ if (me)
+ {
+ if (newItemId.isNull())
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ }
+ else if (newItemId.notNull())
+ {
+ // Not supposed to happen?
+ me->refreshFromInventory(newItemId);
+ }
+ else
+ {
+ me->refreshFromInventory(itemId);
+ }
+
+ if (me && !me->mTextureChangesUpdates.empty())
+ {
+ const LLInventoryItem* item = me->getItem();
+ if (item)
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID());
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
+ }
+ }
+}
+
+void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId)
+{
+ LLSD floater_key;
+ floater_key["taskid"] = taskId;
+ floater_key["itemid"] = itemId;
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (me)
+ {
+ me->setAssetId(newAssetId);
+ me->refreshFromInventory();
+ me->setEnabled(true);
+
+ if (me && !me->mTextureChangesUpdates.empty())
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId);
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
+ }
+}
+
+void LLMaterialEditor::finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes)
+{
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", oldKey);
+ LLViewerInventoryItem* item = gInventory.getItem(newItemId);
+ if (item)
+ {
+ if (me)
+ {
+ me->mItemUUID = newItemId;
+ me->mObjectUUID = LLUUID::null;
+ me->mNotecardInventoryID = LLUUID::null;
+ me->mNotecardObjectID = LLUUID::null;
+ me->mAuxItem = nullptr;
+ me->setKey(LLSD(newItemId)); // for findTypedInstance
+ me->setMaterialName(item->getName());
+ if (has_unsaved_changes)
+ {
+ if (!updateInventoryItem(buffer, newItemId, LLUUID::null))
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ me->loadAsset();
+ me->setEnabled(true);
+
+ // Local texure support
+ if (!me->mTextureChangesUpdates.empty())
+ {
+ // local materials were assigned, force load material and init tracking
+ LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID());
+ for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat);
+ }
+ }
+ }
+ }
+ else if(has_unsaved_changes)
+ {
+ updateInventoryItem(buffer, newItemId, LLUUID::null);
+ }
+ }
+ else if (me)
+ {
+ me->setEnabled(true);
+ LL_WARNS("MaterialEditor") << "Item does not exist, floater " << me->getKey() << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id)
+{
+ if (mIsOverride)
+ {
+ // refreshFromInventory shouldn't be called for overrides,
+ // but just in case.
+ LL_WARNS("MaterialEditor") << "Tried to refresh from inventory for live editor" << LL_ENDL;
+ return;
+ }
+ LLSD old_key = getKey();
+ if (new_item_id.notNull())
+ {
+ mItemUUID = new_item_id;
+ if (mNotecardInventoryID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["objectid"] = mNotecardObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ setKey(floater_key);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = new_item_id;
+ floater_key["itemid"] = mObjectUUID;
+ setKey(floater_key);
+ }
+ else
+ {
+ setKey(LLSD(new_item_id));
+ }
+ }
+ LL_DEBUGS("MaterialEditor") << "New floater key: " << getKey() << " Old key: " << old_key << LL_ENDL;
+ loadAsset();
+}
+
+
+void LLMaterialEditor::onClickSaveAs()
+{
+ if (!LLMaterialEditor::capabilitiesAvailable())
+ {
+ LLNotificationsUtil::add("MissingMaterialCaps");
+ return;
+ }
+
+ if (!can_afford_transaction(mExpectedUploadCost))
+ {
+ LLSD args;
+ args["COST"] = llformat("%d", mExpectedUploadCost);
+ LLNotificationsUtil::add("ErrorCannotAffordUpload", args);
+ return;
+ }
+
+ LLSD args;
+ args["DESC"] = mMaterialName;
+
+ LLNotificationsUtil::add("SaveMaterialAs", args, LLSD(), boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
+}
+
+void LLMaterialEditor::onSaveAsMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ std::string new_name = response["message"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (!new_name.empty())
+ {
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+ if (item)
+ {
+ const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
+ LLUUID parent_id = item->getParentUUID();
+ if (mObjectUUID.notNull() || marketplacelistings_id == parent_id || gInventory.isObjectDescendentOf(item->getUUID(), gInventory.getLibraryRootFolderID()))
+ {
+ parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ }
+
+ // A two step process, first copy an existing item, then create new asset
+ if (mNotecardInventoryID.notNull())
+ {
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(getKey(), new_name);
+ copy_inventory_from_notecard(parent_id,
+ mNotecardObjectID,
+ mNotecardInventoryID,
+ mAuxItem.get(),
+ gInventoryCallbacks.registerCB(cb));
+ }
+ else
+ {
+ std::string buffer = getEncodedAsset();
+ LLPointer<LLInventoryCallback> cb = new LLMaterialEditorCopiedCallback(buffer, getKey(), mUnsavedChanges);
+ copy_inventory_item(
+ gAgent.getID(),
+ item->getPermissions().getOwner(),
+ item->getUUID(),
+ parent_id,
+ new_name,
+ cb);
+ }
+
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+ setEnabled(false);
+ }
+ else
+ {
+ setMaterialName(new_name);
+ onClickSave();
+ }
+ }
+ else
+ {
+ LLNotificationsUtil::add("InvalidMaterialName", LLSD(), LLSD(), [this](const LLSD& notification, const LLSD& response)
+ {
+ LLNotificationsUtil::add("SaveMaterialAs", LLSD().with("DESC", mMaterialName), LLSD(),
+ boost::bind(&LLMaterialEditor::onSaveAsMsgCallback, this, _1, _2));
+ });
+ }
+ }
+}
+
+void LLMaterialEditor::onClickCancel()
+{
+ if (mUnsavedChanges)
+ {
+ LLNotificationsUtil::add("UsavedMaterialChanges", LLSD(), LLSD(), boost::bind(&LLMaterialEditor::onCancelMsgCallback, this, _1, _2));
+ }
+ else
+ {
+ closeFloater();
+ }
+}
+
+void LLMaterialEditor::onCancelMsgCallback(const LLSD& notification, const LLSD& response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 == option)
+ {
+ closeFloater();
+ }
+}
+
+static void pack_textures(
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLImageJ2C>& base_color_j2c,
+ LLPointer<LLImageJ2C>& normal_j2c,
+ LLPointer<LLImageJ2C>& mr_j2c,
+ LLPointer<LLImageJ2C>& emissive_j2c)
+{
+ // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful
+
+ if (base_color_img)
+ {
+ base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img);
+ LL_DEBUGS("MaterialEditor") << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (normal_img)
+ {
+ // create a losslessly compressed version of the normal map
+ normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true);
+ LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (mr_img)
+ {
+ mr_j2c = LLViewerTextureList::convertToUploadFile(mr_img);
+ LL_DEBUGS("MaterialEditor") << "Metallic/Roughness: " << mr_j2c->getDataSize() << LL_ENDL;
+ }
+
+ if (emissive_img)
+ {
+ emissive_j2c = LLViewerTextureList::convertToUploadFile(emissive_img);
+ LL_DEBUGS("MaterialEditor") << "Emissive: " << emissive_j2c->getDataSize() << LL_ENDL;
+ }
+}
+
+void LLMaterialEditor::uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model_in, S32 index)
+{
+ if (index < 0 || !LLMaterialEditor::capabilitiesAvailable())
+ {
+ return;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ return;
+ }
+
+ if (index >= 0 && model_in.materials.size() <= index)
+ {
+ // material is missing
+ return;
+ }
+
+ // Todo: no point in loading whole editor
+ // This uses 'filename' to make sure multiple bulk uploads work
+ // instead of fighting for a single instance.
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD().with("filename", filename).with("index", LLSD::Integer(index)));
+ me->loadMaterial(model_in, filename, index, false);
+ me->saveIfNeeded();
+}
+
+
+void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 index)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
+
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ bool loaded = false;
+ tinygltf::Model model_in;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ loaded = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+ else
+ { // file is ascii
+ loaded = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename);
+ }
+
+ if (!loaded)
+ {
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ if (index >= 0 && model_in.materials.size() <= index)
+ {
+ // material is missing
+ LLNotificationsUtil::add("CannotUploadMaterial");
+ return;
+ }
+
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+
+ if (index >= 0)
+ {
+ // Prespecified material
+ me->loadMaterial(model_in, filename, index);
+ }
+ else if (model_in.materials.size() == 1)
+ {
+ // Only one, just load it
+ me->loadMaterial(model_in, filename, 0);
+ }
+ else
+ {
+ // Promt user to select material
+ std::list<std::string> material_list;
+ std::vector<tinygltf::Material>::const_iterator mat_iter = model_in.materials.begin();
+ std::vector<tinygltf::Material>::const_iterator mat_end = model_in.materials.end();
+
+ for (; mat_iter != mat_end; mat_iter++)
+ {
+ std::string mat_name = mat_iter->name;
+ if (mat_name.empty())
+ {
+ material_list.push_back("Material " + std::to_string(material_list.size()));
+ }
+ else
+ {
+ material_list.push_back(mat_name);
+ }
+ }
+
+ material_list.push_back(me->getString("material_batch_import_text"));
+
+ LLFloaterComboOptions::showUI(
+ [me, model_in, filename](const std::string& option, S32 index)
+ {
+ me->loadMaterial(model_in, filename, index);
+ },
+ me->getString("material_selection_title"),
+ me->getString("material_selection_text"),
+ material_list
+ );
+ }
+}
+
+void LLMaterialEditor::onSelectionChanged()
+{
+ // Drop selection updates if we are waiting for
+ // overrides to finish applying to not reset values
+ // (might need a timeout)
+ if (!mOverrideInProgress)
+ {
+ // mUpdateSignal triggers a lot per frame, breakwater
+ mSelectionNeedsUpdate = true;
+ }
+}
+
+void LLMaterialEditor::updateLive()
+{
+ mSelectionNeedsUpdate = true;
+ mOverrideInProgress = false;
+}
+
+void LLMaterialEditor::loadLive()
+{
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("live_material_editor");
+ if (me)
+ {
+ me->mOverrideInProgress = false;
+ me->setFromSelection();
+
+ // Set up for selection changes updates
+ if (!me->mSelectionUpdateSlot.connected())
+ {
+ me->mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLMaterialEditor::onSelectionChanged, me));
+ }
+
+ me->openFloater();
+ me->setFocus(TRUE);
+ }
+}
+
+// *NOTE: permissions_out includes user preferences for new item creation (LLFloaterPerms)
+bool can_use_objects_material(LLSelectedTEGetMatData& func, const std::vector<PermissionBit>& ops, LLPermissions& permissions_out, LLViewerInventoryItem*& item_out)
+{
+ if (!LLMaterialEditor::capabilitiesAvailable())
+ {
+ return false;
+ }
+
+ // func.mIsOverride=true is used for the singleton material editor floater
+ // associated with the build floater. This flag also excludes objects from
+ // the selection that do not satisfy PERM_MODIFY.
+ llassert(func.mIsOverride);
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, true /*first applicable*/);
+
+ LLViewerObject* selected_object = func.mObject;
+ if (!selected_object)
+ {
+ // LLSelectedTEGetMatData can fail if there are no selected faces
+ // with materials, but we expect at least some object is selected.
+ llassert(LLSelectMgr::getInstance()->getSelection()->getFirstObject());
+ return false;
+ }
+ if (selected_object->isInventoryPending())
+ {
+ return false;
+ }
+ for (PermissionBit op : ops)
+ {
+ if (op == PERM_MODIFY && selected_object->isPermanentEnforced())
+ {
+ return false;
+ }
+ }
+
+ item_out = selected_object->getInventoryItemByAsset(func.mMaterialId);
+
+ LLPermissions item_permissions;
+ if (item_out)
+ {
+ item_permissions.set(item_out->getPermissions());
+ for (PermissionBit op : ops)
+ {
+ if (!gAgent.allowOperation(op, item_permissions, GP_OBJECT_MANIPULATE))
+ {
+ return false;
+ }
+ }
+ // Update flags for new owner
+ if (!item_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true))
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ else
+ {
+ item_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+ }
+
+ // Use root object for permissions checking
+ LLViewerObject* root_object = selected_object->getRootEdit();
+ LLPermissions* object_permissions_p = LLSelectMgr::getInstance()->findObjectPermissions(root_object);
+ LLPermissions object_permissions;
+ if (object_permissions_p)
+ {
+ object_permissions.set(*object_permissions_p);
+ for (PermissionBit op : ops)
+ {
+ if (!gAgent.allowOperation(op, object_permissions, GP_OBJECT_MANIPULATE))
+ {
+ return false;
+ }
+ }
+ // Update flags for new owner
+ if (!object_permissions.setOwnerAndGroup(LLUUID::null, gAgent.getID(), LLUUID::null, true))
+ {
+ llassert(false);
+ return false;
+ }
+ }
+ else
+ {
+ object_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+ }
+
+ LLPermissions floater_perm;
+ floater_perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+ floater_perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Materials"));
+ floater_perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Materials"));
+ floater_perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Materials"));
+
+ // *NOTE: A close inspection of LLPermissions::accumulate shows that
+ // conflicting UUIDs will be unset. This is acceptable behavior for now.
+ // The server will populate creator info based on the item creation method
+ // used.
+ // *NOTE: As far as I'm aware, there is currently no good way to preserve
+ // creation history when there's no material item present. In that case,
+ // the agent who saved the material will be considered the creator.
+ // -Cosmic,2023-08-07
+ if (item_out)
+ {
+ permissions_out.set(item_permissions);
+ }
+ else
+ {
+ permissions_out.set(object_permissions);
+ }
+ permissions_out.accumulate(floater_perm);
+
+ return true;
+}
+
+bool LLMaterialEditor::canModifyObjectsMaterial()
+{
+ LLSelectedTEGetMatData func(true);
+ LLPermissions permissions;
+ LLViewerInventoryItem* item_out;
+ return can_use_objects_material(func, std::vector({PERM_MODIFY}), permissions, item_out);
+}
+
+bool LLMaterialEditor::canSaveObjectsMaterial()
+{
+ LLSelectedTEGetMatData func(true);
+ LLPermissions permissions;
+ LLViewerInventoryItem* item_out;
+ return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item_out);
+}
+
+bool LLMaterialEditor::canClipboardObjectsMaterial()
+{
+ if (LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 1)
+ {
+ return false;
+ }
+
+ struct LLSelectedTEGetNullMat : public LLSelectedTEFunctor
+ {
+ bool apply(LLViewerObject* objectp, S32 te_index)
+ {
+ return objectp->getRenderMaterialID(te_index).isNull();
+ }
+ } null_func;
+
+ if (LLSelectMgr::getInstance()->getSelection()->applyToTEs(&null_func))
+ {
+ return true;
+ }
+
+ LLSelectedTEGetMatData func(true);
+ LLPermissions permissions;
+ LLViewerInventoryItem* item_out;
+ return can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY, PERM_TRANSFER}), permissions, item_out);
+}
+
+void LLMaterialEditor::saveObjectsMaterialAs()
+{
+ LLSelectedTEGetMatData func(true);
+ LLPermissions permissions;
+ LLViewerInventoryItem* item = nullptr;
+ bool allowed = can_use_objects_material(func, std::vector({PERM_COPY, PERM_MODIFY}), permissions, item);
+ if (!allowed)
+ {
+ LL_WARNS("MaterialEditor") << "Failed to save GLTF material from object" << LL_ENDL;
+ return;
+ }
+ const LLUUID item_id = item ? item->getUUID() : LLUUID::null;
+ saveObjectsMaterialAs(func.mMaterial, func.mLocalMaterial, permissions, func.mObjectId, item_id);
+}
+
+
+void LLMaterialEditor::saveObjectsMaterialAs(const LLGLTFMaterial* render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id)
+{
+ if (local_material)
+ {
+ // This is a local material, reload it from file
+ // so that user won't end up with grey textures
+ // on next login.
+ LLMaterialEditor::loadMaterialFromFile(local_material->getFilename(), local_material->getIndexInFile());
+
+ LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor");
+ if (me)
+ {
+ // don't use override material here, it has 'hacked ids'
+ // and values, use end result, apply it on top of local.
+ const LLColor4& base_color = render_material->mBaseColor;
+ me->setBaseColor(LLColor3(base_color));
+ me->setTransparency(base_color[VW]);
+ me->setMetalnessFactor(render_material->mMetallicFactor);
+ me->setRoughnessFactor(render_material->mRoughnessFactor);
+ me->setEmissiveColor(render_material->mEmissiveColor);
+ me->setDoubleSided(render_material->mDoubleSided);
+ me->setAlphaMode(render_material->getAlphaMode());
+ me->setAlphaCutoff(render_material->mAlphaCutoff);
+
+ // most things like colors we can apply without verifying
+ // but texture ids are going to be different from both, base and override
+ // so only apply override id if there is actually a difference
+ if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
+ {
+ me->setBaseColorId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string"));
+ }
+ if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
+ {
+ me->setNormalId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+ me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string"));
+ }
+ if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
+ {
+ me->setMetallicRoughnessId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+ me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string"));
+ }
+ if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
+ {
+ me->setEmissiveId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+ me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string"));
+ }
+
+ // recalculate upload prices
+ me->markChangesUnsaved(0);
+ }
+
+ return;
+ }
+
+ LLSD payload;
+ if (render_material)
+ {
+ // Make a copy of the render material with unsupported transforms removed
+ LLGLTFMaterial asset_material = *render_material;
+ asset_material.sanitizeAssetMaterial();
+ // Serialize the sanitized render material
+ payload["data"] = asset_material.asJSON();
+ }
+ else
+ {
+ // Menu shouldn't allow this, but as a fallback
+ // pick defaults from a blank material
+ LLGLTFMaterial blank_mat;
+ payload["data"] = blank_mat.asJSON();
+ LL_WARNS() << "Got no material when trying to save material" << LL_ENDL;
+ }
+
+ LLSD args;
+ args["DESC"] = LLTrans::getString("New Material");
+
+ if (local_material)
+ {
+ LLPermissions local_permissions;
+ local_permissions.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+ LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, local_permissions));
+ }
+ else
+ {
+ if (item_id.notNull())
+ {
+ // Copy existing item from object inventory, and create new composite asset on top of it
+ LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback, _1, _2, permissions, object_id, item_id));
+ }
+ else
+ {
+ LLNotificationsUtil::add("SaveMaterialAs", args, payload, boost::bind(&LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback, _1, _2, permissions));
+ }
+ }
+}
+
+// static
+void LLMaterialEditor::onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 != option)
+ {
+ return;
+ }
+
+ LLSD asset;
+ asset["version"] = LLGLTFMaterial::ASSET_VERSION;
+ asset["type"] = LLGLTFMaterial::ASSET_TYPE;
+ // This is the string serialized from LLGLTFMaterial::asJSON
+ asset["data"] = notification["payload"]["data"];
+
+ std::ostringstream str;
+ LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
+
+ LLViewerObject* object = gObjectList.findObject(object_id);
+ if (!object)
+ {
+ return;
+ }
+ const LLInventoryItem* item = object->getInventoryItem(item_id);
+ if (!item)
+ {
+ return;
+ }
+
+ std::string new_name = response["message"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (new_name.empty())
+ {
+ return;
+ }
+
+ const LLUUID destination_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+
+ LLPointer<LLInventoryCallback> cb = new LLObjectsMaterialItemCallback(permissions, str.str(), new_name);
+ // NOTE: This should be an item copy. Saving a material to an inventory should be disabled when the associated material is no-copy.
+ move_or_copy_inventory_from_object(destination_id,
+ object_id,
+ item_id,
+ cb);
+}
+
+// static
+void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (0 != option)
+ {
+ return;
+ }
+
+ LLSD asset;
+ asset["version"] = LLGLTFMaterial::ASSET_VERSION;
+ asset["type"] = LLGLTFMaterial::ASSET_TYPE;
+ // This is the string serialized from LLGLTFMaterial::asJSON
+ asset["data"] = notification["payload"]["data"];
+
+ std::ostringstream str;
+ LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY);
+
+ std::string new_name = response["message"].asString();
+ LLInventoryObject::correctInventoryName(new_name);
+ if (new_name.empty())
+ {
+ return;
+ }
+
+ createInventoryItem(str.str(), new_name, std::string(), permissions);
+}
+
+const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type);
+
+void LLMaterialEditor::loadMaterial(const tinygltf::Model &model_in, const std::string &filename, S32 index, bool open_floater)
+{
+ if (index == model_in.materials.size())
+ {
+ // bulk upload all the things
+ upload_bulk({ filename }, LLFilePicker::FFLOAD_MATERIAL);
+ return;
+ }
+
+ if (model_in.materials.size() <= index)
+ {
+ return;
+ }
+ std::string folder = gDirUtilp->getDirName(filename);
+
+ tinygltf::Material material_in = model_in.materials[index];
+
+ tinygltf::Model model_out;
+ model_out.asset.version = "2.0";
+ model_out.materials.resize(1);
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_color_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mBaseColorName);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index, mMetallicRoughnessName);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index, mEmissiveName);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ std::string tmp;
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp);
+ }
+
+ LLTinyGLTFHelper::initFetchedTextures(material_in, base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched);
+ pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img,
+ mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C);
+
+ LLUUID base_color_id;
+ if (mBaseColorFetched.notNull())
+ {
+ mBaseColorFetched->forceToSaveRawImage(0, F32_MAX);
+ base_color_id = mBaseColorFetched->getID();
+
+ if (mBaseColorName.empty())
+ {
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID normal_id;
+ if (mNormalFetched.notNull())
+ {
+ mNormalFetched->forceToSaveRawImage(0, F32_MAX);
+ normal_id = mNormalFetched->getID();
+
+ if (mNormalName.empty())
+ {
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID mr_id;
+ if (mMetallicRoughnessFetched.notNull())
+ {
+ mMetallicRoughnessFetched->forceToSaveRawImage(0, F32_MAX);
+ mr_id = mMetallicRoughnessFetched->getID();
+
+ if (mMetallicRoughnessName.empty())
+ {
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ }
+ }
+
+ LLUUID emissive_id;
+ if (mEmissiveFetched.notNull())
+ {
+ mEmissiveFetched->forceToSaveRawImage(0, F32_MAX);
+ emissive_id = mEmissiveFetched->getID();
+
+ if (mEmissiveName.empty())
+ {
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ }
+ }
+
+ setBaseColorId(base_color_id);
+ setBaseColorUploadId(base_color_id);
+ setMetallicRoughnessId(mr_id);
+ setMetallicRoughnessUploadId(mr_id);
+ setEmissiveId(emissive_id);
+ setEmissiveUploadId(emissive_id);
+ setNormalId(normal_id);
+ setNormalUploadId(normal_id);
+
+ setFromGltfModel(model_in, index);
+
+ setFromGltfMetaData(filename, model_in, index);
+
+ if (getDoubleSided())
+ {
+ // SL-19392 Double sided materials double the number of pixels that must be rasterized,
+ // and a great many tools that export GLTF simply leave double sided enabled whether
+ // or not it is necessary.
+ LL_DEBUGS("MaterialEditor") << "Defaulting Double Sided to disabled on import" << LL_ENDL;
+ setDoubleSided(false);
+ }
+
+ markChangesUnsaved(U32_MAX);
+
+ if (open_floater)
+ {
+ openFloater(getKey());
+ setFocus(TRUE);
+ setCanSave(true);
+ setCanSaveAs(true);
+
+ applyToSelection();
+ }
+}
+
+bool LLMaterialEditor::setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures)
+{
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& material_in = model.materials[index];
+
+ if (set_textures)
+ {
+ S32 index;
+ LLUUID id;
+
+ // get base color texture
+ index = material_in.pbrMetallicRoughness.baseColorTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setBaseColorId(id);
+ }
+ else
+ {
+ setBaseColorId(LLUUID::null);
+ }
+
+ // get normal map
+ index = material_in.normalTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setNormalId(id);
+ }
+ else
+ {
+ setNormalId(LLUUID::null);
+ }
+
+ // get metallic-roughness texture
+ index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setMetallicRoughnessId(id);
+ }
+ else
+ {
+ setMetallicRoughnessId(LLUUID::null);
+ }
+
+ // get emissive texture
+ index = material_in.emissiveTexture.index;
+ if (index >= 0)
+ {
+ id.set(model.images[index].uri);
+ setEmissiveId(id);
+ }
+ else
+ {
+ setEmissiveId(LLUUID::null);
+ }
+ }
+
+ setAlphaMode(material_in.alphaMode);
+ setAlphaCutoff(material_in.alphaCutoff);
+
+ setBaseColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor));
+ setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor));
+
+ setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor);
+ setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor);
+
+ setDoubleSided(material_in.doubleSided);
+ }
+
+ return true;
+}
+
+/**
+ * Build a texture name from the contents of the (in tinyGLFT parlance)
+ * Image URI. This often is filepath to the original image on the users'
+ * local file system.
+ */
+const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, const std::string texture_type)
+{
+ // getBaseFileName() works differently on each platform and file patchs
+ // can contain both types of delimiter so unify them then extract the
+ // base name (no path or extension)
+ std::replace(image_uri.begin(), image_uri.end(), '\\', gDirUtilp->getDirDelimiter()[0]);
+ std::replace(image_uri.begin(), image_uri.end(), '/', gDirUtilp->getDirDelimiter()[0]);
+ const bool strip_extension = true;
+ std::string stripped_uri = gDirUtilp->getBaseFileName(image_uri, strip_extension);
+
+ // sometimes they can be really long and unwieldy - 64 chars is enough for anyone :)
+ const int max_texture_name_length = 64;
+ if (stripped_uri.length() > max_texture_name_length)
+ {
+ stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1);
+ }
+
+ // We intend to append the type of texture (base color, emissive etc.) to the
+ // name of the texture but sometimes the creator already did that. To try
+ // to avoid repeats (not perfect), we look for the texture type in the name
+ // and if we find it, do not append the type, later on. One way this fails
+ // (and it's fine for now) is I see some texture/image uris have a name like
+ // "metallic roughness" and of course, that doesn't match our predefined
+ // name "metallicroughness" - consider fix later..
+ bool name_includes_type = false;
+ std::string stripped_uri_lower = stripped_uri;
+ LLStringUtil::toLower(stripped_uri_lower);
+ stripped_uri_lower.erase(std::remove_if(stripped_uri_lower.begin(), stripped_uri_lower.end(), isspace), stripped_uri_lower.end());
+ std::string texture_type_lower = texture_type;
+ LLStringUtil::toLower(texture_type_lower);
+ texture_type_lower.erase(std::remove_if(texture_type_lower.begin(), texture_type_lower.end(), isspace), texture_type_lower.end());
+ if (stripped_uri_lower.find(texture_type_lower) != std::string::npos)
+ {
+ name_includes_type = true;
+ }
+
+ // uri doesn't include the type at all
+ if (name_includes_type == false)
+ {
+ // uri doesn't include the type and the uri is not empty
+ // so we can include everything
+ if (stripped_uri.length() > 0)
+ {
+ // example "DamagedHelmet: base layer"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ else
+ // uri doesn't include the type (because the uri is empty)
+ // so we must reorganize the string a bit to include the name
+ // and an explicit name type
+ {
+ // example "DamagedHelmet: (Emissive)"
+ return STRINGIZE(
+ mMaterialNameShort <<
+ " (" <<
+ texture_type <<
+ ")"
+ );
+ }
+ }
+ else
+ // uri includes the type so just use it directly with the
+ // name of the material
+ {
+ return STRINGIZE(
+ // example: AlienBust: normal_layer
+ mMaterialNameShort <<
+ ": " <<
+ stripped_uri
+ );
+ }
+}
+
+/**
+ * Update the metadata for the material based on what we find in the loaded
+ * file (along with some assumptions and interpretations...). Fields include
+ * the name of the material, a material description and the names of the
+ * composite textures.
+ */
+void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index)
+{
+ // Use the name (without any path/extension) of the file that was
+ // uploaded as the base of the material name. Then if the name of the
+ // scene is present and not blank, append that and use the result as
+ // the name of the material. This is a first pass at creating a
+ // naming scheme that is useful to real content creators and hopefully
+ // avoid 500 materials in your inventory called "scene" or "Default"
+ const bool strip_extension = true;
+ std::string base_filename = gDirUtilp->getBaseFileName(filename, strip_extension);
+
+ // Extract the name of the scene. Note it is often blank or some very
+ // generic name like "Scene" or "Default" so using this in the name
+ // is less useful than you might imagine.
+ std::string material_name;
+ if (model.materials.size() > index && !model.materials[index].name.empty())
+ {
+ material_name = model.materials[index].name;
+ }
+ else if (model.scenes.size() > 0)
+ {
+ const tinygltf::Scene& scene_in = model.scenes[0];
+ if (scene_in.name.length())
+ {
+ material_name = scene_in.name;
+ }
+ else
+ {
+ // scene name is empty so no point using it
+ }
+ }
+ else
+ {
+ // scene name isn't present so no point using it
+ }
+
+ // If we have a valid material or scene name, use it to build the short and
+ // long versions of the material name. The long version is used
+ // as you might expect, for the material name. The short version is
+ // used as part of the image/texture name - the theory is that will
+ // allow content creators to track the material and the corresponding
+ // textures
+ if (material_name.length())
+ {
+ mMaterialNameShort = base_filename;
+
+ mMaterialName = STRINGIZE(
+ base_filename <<
+ " " <<
+ "(" <<
+ material_name <<
+ ")"
+ );
+ }
+ else
+ // otherwise, just use the trimmed filename as is
+ {
+ mMaterialNameShort = base_filename;
+ mMaterialName = base_filename;
+ }
+
+ // sanitize the material name so that it's compatible with the inventory
+ LLInventoryObject::correctInventoryName(mMaterialName);
+ LLInventoryObject::correctInventoryName(mMaterialNameShort);
+
+ // We also set the title of the floater to match the
+ // name of the material
+ setTitle(mMaterialName);
+
+ /**
+ * Extract / derive the names of each composite texture. For each, the
+ * index is used to to determine which of the "Images" is used. If the index
+ * is -1 then that texture type is not present in the material (Seems to be
+ * quite common that a material is missing 1 or more types of texture)
+ */
+ if (model.materials.size() > index)
+ {
+ const tinygltf::Material& first_material = model.materials[index];
+
+ mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME;
+ // note: unlike the other textures, base color doesn't have its own entry
+ // in the tinyGLTF Material struct. Rather, it is taken from a
+ // sub-texture in the pbrMetallicRoughness member
+ int index = first_material.pbrMetallicRoughness.baseColorTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ // sanitize the name we decide to use for each texture
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_BASE_COLOR_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mBaseColorName = texture_name;
+ }
+
+ mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME;
+ index = first_material.emissiveTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_EMISSIVE_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mEmissiveName = texture_name;
+ }
+
+ mMetallicRoughnessName = MATERIAL_METALLIC_DEFAULT_NAME;
+ index = first_material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_METALLIC_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mMetallicRoughnessName = texture_name;
+ }
+
+ mNormalName = MATERIAL_NORMAL_DEFAULT_NAME;
+ index = first_material.normalTexture.index;
+ if (index > -1 && index < model.images.size())
+ {
+ std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_NORMAL_DEFAULT_NAME);
+ LLInventoryObject::correctInventoryName(texture_name);
+ mNormalName = texture_name;
+ }
+ }
+}
+
+void LLMaterialEditor::importMaterial()
+{
+ LLFilePickerReplyThread::startPicker(
+ [](const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)
+ {
+ if (LLAppViewer::instance()->quitRequested())
+ {
+ return;
+ }
+ if (filenames.size() > 0)
+ {
+ LLMaterialEditor::loadMaterialFromFile(filenames[0], -1);
+ }
+ },
+ LLFilePicker::FFLOAD_MATERIAL,
+ true);
+}
+
+class LLRenderMaterialFunctor : public LLSelectedTEFunctor
+{
+public:
+ LLRenderMaterialFunctor(const LLUUID &id)
+ : mMatId(id)
+ {
+ }
+
+ bool apply(LLViewerObject* objectp, S32 te) override
+ {
+ if (objectp && objectp->permModify() && objectp->getVolume())
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)objectp;
+ vobjp->setRenderMaterialID(te, mMatId, false /*preview only*/);
+ vobjp->updateTEMaterialTextures(te);
+ }
+ return true;
+ }
+private:
+ LLUUID mMatId;
+};
+
+class LLRenderMaterialOverrideFunctor : public LLSelectedNodeFunctor
+{
+public:
+ LLRenderMaterialOverrideFunctor(
+ LLMaterialEditor * me,
+ const LLUUID &report_on_object_id,
+ S32 report_on_te)
+ : mEditor(me)
+ , mSuccess(false)
+ , mObjectId(report_on_object_id)
+ , mObjectTE(report_on_te)
+ {
+ }
+
+ virtual bool apply(LLSelectNode* nodep) override
+ {
+ LLViewerObject* objectp = nodep->getObject();
+ if (!objectp || !objectp->permModify() || !objectp->getVolume())
+ {
+ return false;
+ }
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces
+
+ // post override from given object and te to the simulator
+ // requestData should have:
+ // object_id - UUID of LLViewerObject
+ // side - S32 index of texture entry
+ // gltf_json - String of GLTF json for override data
+
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (!nodep->isTESelected(te))
+ {
+ continue;
+ }
+
+ // Get material from object
+ // Selection can cover multiple objects, and live editor is
+ // supposed to overwrite changed values only
+ LLTextureEntry* tep = objectp->getTE(te);
+
+ if (tep->getGLTFMaterial() == nullptr)
+ {
+ // overrides are not supposed to work or apply if
+ // there is no base material to work from
+ continue;
+ }
+
+ LLPointer<LLGLTFMaterial> material = tep->getGLTFMaterialOverride();
+ // make a copy to not invalidate existing
+ // material for multiple objects
+ if (material.isNull())
+ {
+ // Start with a material override which does not make any changes
+ material = new LLGLTFMaterial();
+ }
+ else
+ {
+ material = new LLGLTFMaterial(*material);
+ }
+
+ U32 changed_flags = mEditor->getUnsavedChangesFlags();
+ U32 reverted_flags = mEditor->getRevertedChangesFlags();
+
+ LLPointer<LLGLTFMaterial> revert_mat;
+ if (nodep->mSavedGLTFOverrideMaterials.size() > te)
+ {
+ if (nodep->mSavedGLTFOverrideMaterials[te].notNull())
+ {
+ revert_mat = nodep->mSavedGLTFOverrideMaterials[te];
+ }
+ else
+ {
+ // mSavedGLTFOverrideMaterials[te] being present but null
+ // means we need to use a default value
+ revert_mat = new LLGLTFMaterial();
+ }
+ }
+ // else can not revert at all
+
+ // Override object's values with values from editor where appropriate
+ if (changed_flags & MATERIAL_BASE_COLOR_DIRTY)
+ {
+ material->setBaseColorFactor(mEditor->getBaseColor(), true);
+ }
+ else if ((reverted_flags & MATERIAL_BASE_COLOR_DIRTY) && revert_mat.notNull())
+ {
+ material->setBaseColorFactor(revert_mat->mBaseColor, false);
+ }
+
+ if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY)
+ {
+ material->setBaseColorId(mEditor->getBaseColorId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+ else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull())
+ {
+ material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+
+ if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY)
+ {
+ material->setNormalId(mEditor->getNormalId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+ else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull())
+ {
+ material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+
+ if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY)
+ {
+ material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+ else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull())
+ {
+ material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+
+ if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY)
+ {
+ material->setMetallicFactor(mEditor->getMetalnessFactor(), true);
+ }
+ else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) && revert_mat.notNull())
+ {
+ material->setMetallicFactor(revert_mat->mMetallicFactor, false);
+ }
+
+ if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY)
+ {
+ material->setRoughnessFactor(mEditor->getRoughnessFactor(), true);
+ }
+ else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) && revert_mat.notNull())
+ {
+ material->setRoughnessFactor(revert_mat->mRoughnessFactor, false);
+ }
+
+ if (changed_flags & MATERIAL_EMISIVE_COLOR_DIRTY)
+ {
+ material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true);
+ }
+ else if ((reverted_flags & MATERIAL_EMISIVE_COLOR_DIRTY) && revert_mat.notNull())
+ {
+ material->setEmissiveColorFactor(revert_mat->mEmissiveColor, false);
+ }
+
+ if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY)
+ {
+ material->setEmissiveId(mEditor->getEmissiveId(), true);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+ else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull())
+ {
+ material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false);
+ LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY);
+ if (tracking_id.notNull())
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material);
+ }
+ }
+
+ if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY)
+ {
+ material->setDoubleSided(mEditor->getDoubleSided(), true);
+ }
+ else if ((reverted_flags & MATERIAL_DOUBLE_SIDED_DIRTY) && revert_mat.notNull())
+ {
+ material->setDoubleSided(revert_mat->mDoubleSided, false);
+ }
+
+ if (changed_flags & MATERIAL_ALPHA_MODE_DIRTY)
+ {
+ material->setAlphaMode(mEditor->getAlphaMode(), true);
+ }
+ else if ((reverted_flags & MATERIAL_ALPHA_MODE_DIRTY) && revert_mat.notNull())
+ {
+ material->setAlphaMode(revert_mat->mAlphaMode, false);
+ }
+
+ if (changed_flags & MATERIAL_ALPHA_CUTOFF_DIRTY)
+ {
+ material->setAlphaCutoff(mEditor->getAlphaCutoff(), true);
+ }
+ else if ((reverted_flags & MATERIAL_ALPHA_CUTOFF_DIRTY) && revert_mat.notNull())
+ {
+ material->setAlphaCutoff(revert_mat->mAlphaCutoff, false);
+ }
+
+ if (mObjectTE == te
+ && mObjectId == objectp->getID())
+ {
+ mSuccess = true;
+ }
+ LLGLTFMaterialList::queueModify(objectp, te, material);
+ }
+ return true;
+ }
+
+ static void modifyCallback(bool success)
+ {
+ if (!success)
+ {
+ // something went wrong update selection
+ LLMaterialEditor::updateLive();
+ }
+ // else we will get updateLive() from panel face
+ }
+
+ bool getResult() { return mSuccess; }
+
+private:
+ LLMaterialEditor * mEditor;
+ LLUUID mObjectId;
+ S32 mObjectTE;
+ bool mSuccess;
+};
+
+void LLMaterialEditor::applyToSelection()
+{
+ if (!mIsOverride)
+ {
+ // Only apply if working with 'live' materials
+ // Might need a better way to distinguish 'live' mode.
+ // But only one live edit is supposed to work at a time
+ // as a pair to tools floater.
+ return;
+ }
+
+ std::string url = gAgent.getRegionCapability("ModifyMaterialParams");
+ if (!url.empty())
+ {
+ // Don't send data if there is nothing to send.
+ // Some UI elements will cause multiple commits,
+ // like spin ctrls on click and on down
+ if (mUnsavedChanges != 0 || mRevertedChanges != 0)
+ {
+ mOverrideInProgress = true;
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLRenderMaterialOverrideFunctor override_func(this, mOverrideObjectId, mOverrideObjectTE);
+ selected_objects->applyToNodes(&override_func);
+
+ void(*done_callback)(bool) = LLRenderMaterialOverrideFunctor::modifyCallback;
+
+ LLGLTFMaterialList::flushUpdates(done_callback);
+
+ if (!override_func.getResult())
+ {
+ // OverrideFunctor didn't find expected object or face
+ mOverrideInProgress = false;
+ }
+
+ // we posted all changes
+ mUnsavedChanges = 0;
+ mRevertedChanges = 0;
+ }
+ }
+ else
+ {
+ LL_WARNS("MaterialEditor") << "Not connected to materials capable region, missing ModifyMaterialParams cap" << LL_ENDL;
+
+ // Fallback local preview. Will be removed once override systems is finished and new cap is deployed everywhere.
+ LLPointer<LLFetchedGLTFMaterial> mat = new LLFetchedGLTFMaterial();
+ getGLTFMaterial(mat);
+ static const LLUUID placeholder("984e183e-7811-4b05-a502-d79c6f978a98");
+ gGLTFMaterialList.addMaterial(placeholder, mat);
+ LLRenderMaterialFunctor mat_func(placeholder);
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ selected_objects->applyToTEs(&mat_func);
+ }
+}
+
+// Get a dump of the json representation of the current state of the editor UI
+// in GLTF format, excluding transforms as they are not supported in material
+// assets. (See also LLGLTFMaterial::sanitizeAssetMaterial())
+void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat)
+{
+ mat->mBaseColor = getBaseColor();
+ mat->mBaseColor.mV[3] = getTransparency();
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = getBaseColorId();
+
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = getNormalId();
+
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = getMetallicRoughnessId();
+ mat->mMetallicFactor = getMetalnessFactor();
+ mat->mRoughnessFactor = getRoughnessFactor();
+
+ mat->mEmissiveColor = getEmissiveColor();
+ mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = getEmissiveId();
+
+ mat->mDoubleSided = getDoubleSided();
+ mat->setAlphaMode(getAlphaMode());
+ mat->mAlphaCutoff = getAlphaCutoff();
+}
+
+void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat)
+{
+ setBaseColor(mat->mBaseColor);
+ setBaseColorId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ setNormalId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+
+ setMetallicRoughnessId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+ setMetalnessFactor(mat->mMetallicFactor);
+ setRoughnessFactor(mat->mRoughnessFactor);
+
+ setEmissiveColor(mat->mEmissiveColor);
+ setEmissiveId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+
+ setDoubleSided(mat->mDoubleSided);
+ setAlphaMode(mat->getAlphaMode());
+ setAlphaCutoff(mat->mAlphaCutoff);
+
+ if (mat->hasLocalTextures())
+ {
+ for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture)
+ {
+ LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first);
+ if (val.second != world_id)
+ {
+ LL_WARNS() << "world id mismatch" << LL_ENDL;
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR])
+ {
+ subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS])
+ {
+ subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE])
+ {
+ subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, val.first);
+ }
+ if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL])
+ {
+ subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, val.first);
+ }
+ }
+ }
+}
+
+bool LLMaterialEditor::setFromSelection()
+{
+ LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection();
+ LLSelectedTEGetMatData func(mIsOverride);
+
+ selected_objects->applyToTEs(&func);
+ mHasSelection = !selected_objects->isEmpty();
+ mSelectionNeedsUpdate = false;
+
+ if (func.mMaterial.notNull())
+ {
+ setFromGLTFMaterial(func.mMaterial);
+ LLViewerObject* selected_object = func.mObject;
+ const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId);
+ const bool allow_modify = !item || canModify(selected_object, item);
+ setEnableEditing(allow_modify);
+
+ // todo: apply local texture data to all materials in selection
+ }
+ else
+ {
+ // pick defaults from a blank material;
+ LLGLTFMaterial blank_mat;
+ setFromGLTFMaterial(&blank_mat);
+ if (mIsOverride)
+ {
+ setEnableEditing(false);
+ }
+ }
+
+ if (mIsOverride)
+ {
+ mBaseColorTextureCtrl->setTentative(!func.mIdenticalTexColor);
+ mMetallicTextureCtrl->setTentative(!func.mIdenticalTexMetal);
+ mEmissiveTextureCtrl->setTentative(!func.mIdenticalTexEmissive);
+ mNormalTextureCtrl->setTentative(!func.mIdenticalTexNormal);
+
+ // Memorize selection data for filtering further updates
+ mOverrideObjectId = func.mObjectId;
+ mOverrideObjectTE = func.mObjectTE;
+
+ // Ovverdired might have been updated,
+ // refresh state of local textures in overrides
+ //
+ // Todo: this probably shouldn't be here, but in localbitmap,
+ // subscried to all material overrides if we want copied
+ // objects to get properly updated as well
+ LLSelectedTEUpdateOverrides local_tex_func(this);
+ selected_objects->applyToNodes(&local_tex_func);
+ }
+
+ return func.mMaterial.notNull();
+}
+
+
+void LLMaterialEditor::loadAsset()
+{
+ const LLInventoryItem* item;
+ if (mNotecardInventoryID.notNull())
+ {
+ item = mAuxItem.get();
+ }
+ else
+ {
+ item = getItem();
+ }
+
+ bool fail = false;
+
+ if (item)
+ {
+ LLPermissions perm(item->getPermissions());
+ bool allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE);
+ bool allow_modify = canModify(mObjectUUID, item);
+ bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID());
+
+ setCanSaveAs(allow_copy);
+ setMaterialName(item->getName());
+
+ {
+ mAssetID = item->getAssetUUID();
+
+ if (mAssetID.isNull())
+ {
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ loadDefaults();
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ }
+ else
+ {
+ LLHost source_sim = LLHost();
+ LLSD* user_data = new LLSD();
+
+ if (mNotecardInventoryID.notNull())
+ {
+ user_data->with("objectid", mNotecardObjectID).with("notecardid", mNotecardInventoryID);
+ }
+ else if (mObjectUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && objectp->getRegion())
+ {
+ source_sim = objectp->getRegion()->getHost();
+ }
+ else
+ {
+ // The object that we're trying to look at disappeared, bail.
+ LL_WARNS("MaterialEditor") << "Can't find object " << mObjectUUID << " associated with material." << LL_ENDL;
+ mAssetID.setNull();
+ mAssetStatus = PREVIEW_ASSET_LOADED;
+ resetUnsavedChanges();
+ setEnableEditing(allow_modify && !source_library);
+ return;
+ }
+ user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID);
+ }
+ else
+ {
+ user_data = new LLSD(mItemUUID);
+ }
+
+ setEnableEditing(false); // wait for it to load
+
+ mAssetStatus = PREVIEW_ASSET_LOADING;
+
+ // May callback immediately
+ gAssetStorage->getAssetData(item->getAssetUUID(),
+ LLAssetType::AT_MATERIAL,
+ &onLoadComplete,
+ (void*)user_data,
+ TRUE);
+ }
+ }
+ }
+ else if (mObjectUUID.notNull() && mItemUUID.notNull())
+ {
+ LLViewerObject* objectp = gObjectList.findObject(mObjectUUID);
+ if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty()))
+ {
+ // It's a material in object's inventory and we failed to get it because inventory is not up to date.
+ // Subscribe for callback and retry at inventoryChanged()
+ registerVOInventoryListener(objectp, NULL); //removes previous listener
+
+ if (objectp->isInventoryDirty())
+ {
+ objectp->requestInventory();
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+ }
+ else
+ {
+ fail = true;
+ }
+
+ if (fail)
+ {
+ /*editor->setText(LLStringUtil::null);
+ editor->makePristine();
+ editor->setEnabled(TRUE);*/
+ // Don't set asset status here; we may not have set the item id yet
+ // (e.g. when this gets called initially)
+ //mAssetStatus = PREVIEW_ASSET_LOADED;
+ }
+}
+
+// static
+void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid,
+ LLAssetType::EType type,
+ void* user_data, S32 status, LLExtStat ext_status)
+{
+ LLSD* floater_key = (LLSD*)user_data;
+ LL_DEBUGS("MaterialEditor") << "loading " << asset_uuid << " for " << *floater_key << LL_ENDL;
+ LLMaterialEditor* editor = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", *floater_key);
+ if (editor)
+ {
+ if (asset_uuid != editor->mAssetID)
+ {
+ LL_WARNS("MaterialEditor") << "Asset id mismatch, expected: " << editor->mAssetID << " got: " << asset_uuid << LL_ENDL;
+ }
+ if (0 == status)
+ {
+ LLFileSystem file(asset_uuid, type, LLFileSystem::READ);
+
+ S32 file_length = file.getSize();
+
+ std::vector<char> buffer(file_length + 1);
+ file.read((U8*)&buffer[0], file_length);
+
+ editor->decodeAsset(buffer);
+
+ BOOL allow_modify = editor->canModify(editor->mObjectUUID, editor->getItem());
+ BOOL source_library = editor->mObjectUUID.isNull() && gInventory.isObjectDescendentOf(editor->mItemUUID, gInventory.getLibraryRootFolderID());
+ editor->setEnableEditing(allow_modify && !source_library);
+ editor->resetUnsavedChanges();
+ editor->mAssetStatus = PREVIEW_ASSET_LOADED;
+ editor->setEnabled(true); // ready for use
+ }
+ else
+ {
+ if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
+ LL_ERR_FILE_EMPTY == status)
+ {
+ LLNotificationsUtil::add("MaterialMissing");
+ }
+ else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
+ {
+ // Not supposed to happen?
+ LL_WARNS("MaterialEditor") << "No permission to view material " << asset_uuid << LL_ENDL;
+ LLNotificationsUtil::add("MaterialNoPermissions");
+ }
+ else
+ {
+ LLNotificationsUtil::add("UnableToLoadMaterial");
+ }
+ editor->setEnableEditing(false);
+
+ LL_WARNS("MaterialEditor") << "Problem loading material: " << status << LL_ENDL;
+ editor->mAssetStatus = PREVIEW_ASSET_ERROR;
+ }
+ }
+ else
+ {
+ LL_DEBUGS("MaterialEditor") << "Floater " << *floater_key << " does not exist." << LL_ENDL;
+ }
+ delete floater_key;
+}
+
+void LLMaterialEditor::inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data)
+{
+ removeVOInventoryListener();
+ loadAsset();
+}
+
+
+void LLMaterialEditor::saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb)
+{
+ if (asset_id.isNull()
+ || img == nullptr
+ || img->getDataSize() == 0)
+ {
+ return;
+ }
+
+ // copy image bytes into string
+ std::string buffer;
+ buffer.assign((const char*) img->getData(), img->getDataSize());
+
+ U32 expected_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+
+ LLSD key = getKey();
+ std::function<bool(LLUUID itemId, LLSD response, std::string reason)> failed_upload([key](LLUUID assetId, LLSD response, std::string reason)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ me->setFailedToUploadTexture();
+ }
+ return true; // handled
+ });
+
+ LLResourceUploadInfo::ptr_t uploadInfo(std::make_shared<LLNewBufferedResourceUploadInfo>(
+ buffer,
+ asset_id,
+ name,
+ name,
+ 0,
+ LLFolderType::FT_TEXTURE,
+ LLInventoryType::IT_TEXTURE,
+ LLAssetType::AT_TEXTURE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost,
+ false,
+ cb,
+ failed_upload));
+
+ upload_new_resource(uploadInfo);
+}
+
+void LLMaterialEditor::setFailedToUploadTexture()
+{
+ mUploadingTexturesFailure = true;
+ mUploadingTexturesCount--;
+ if (mUploadingTexturesCount == 0)
+ {
+ setEnabled(true);
+ }
+}
+
+S32 LLMaterialEditor::saveTextures()
+{
+ mUploadingTexturesFailure = false; // not supposed to get here if already uploading
+
+ S32 work_count = 0;
+ LLSD key = getKey(); // must be locally declared for lambda's capture to work
+ if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+
+ // For ease of inventory management, we prepend the material name.
+ std::string name = mMaterialName + ": " + mBaseColorName;
+
+ saveTexture(mBaseColorJ2C, name, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setBaseColorId(newAssetId);
+
+ // discard upload buffers once texture have been saved
+ me->mBaseColorJ2C = nullptr;
+ me->mBaseColorFetched = nullptr;
+ me->mBaseColorTextureUploadId.setNull();
+
+ me->mUploadingTexturesCount--;
+
+ if (!me->mUploadingTexturesFailure)
+ {
+ // try saving
+ me->saveIfNeeded();
+ }
+ else if (me->mUploadingTexturesCount == 0)
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ // stop upload if possible, unblock and let user decide
+ me->setFailedToUploadTexture();
+ }
+ }
+ });
+ }
+ if (mNormalTextureUploadId == getNormalId() && mNormalTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+
+ // For ease of inventory management, we prepend the material name.
+ std::string name = mMaterialName + ": " + mNormalName;
+
+ saveTexture(mNormalJ2C, name, mNormalTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setNormalId(newAssetId);
+
+ // discard upload buffers once texture have been saved
+ me->mNormalJ2C = nullptr;
+ me->mNormalFetched = nullptr;
+ me->mNormalTextureUploadId.setNull();
+
+ me->mUploadingTexturesCount--;
+
+ if (!me->mUploadingTexturesFailure)
+ {
+ // try saving
+ me->saveIfNeeded();
+ }
+ else if (me->mUploadingTexturesCount == 0)
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ // stop upload if possible, unblock and let user decide
+ me->setFailedToUploadTexture();
+ }
+ }
+ });
+ }
+ if (mMetallicTextureUploadId == getMetallicRoughnessId() && mMetallicTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+
+ // For ease of inventory management, we prepend the material name.
+ std::string name = mMaterialName + ": " + mMetallicRoughnessName;
+
+ saveTexture(mMetallicRoughnessJ2C, name, mMetallicTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", key);
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setMetallicRoughnessId(newAssetId);
+
+ // discard upload buffers once texture have been saved
+ me->mMetallicRoughnessJ2C = nullptr;
+ me->mMetallicRoughnessFetched = nullptr;
+ me->mMetallicTextureUploadId.setNull();
+
+ me->mUploadingTexturesCount--;
+
+ if (!me->mUploadingTexturesFailure)
+ {
+ // try saving
+ me->saveIfNeeded();
+ }
+ else if (me->mUploadingTexturesCount == 0)
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ // stop upload if possible, unblock and let user decide
+ me->setFailedToUploadTexture();
+ }
+ }
+ });
+ }
+
+ if (mEmissiveTextureUploadId == getEmissiveId() && mEmissiveTextureUploadId.notNull())
+ {
+ mUploadingTexturesCount++;
+ work_count++;
+
+ // For ease of inventory management, we prepend the material name.
+ std::string name = mMaterialName + ": " + mEmissiveName;
+
+ saveTexture(mEmissiveJ2C, name, mEmissiveTextureUploadId, [key](LLUUID newAssetId, LLSD response)
+ {
+ LLMaterialEditor* me = LLFloaterReg::findTypedInstance<LLMaterialEditor>("material_editor", LLSD(key));
+ if (me)
+ {
+ if (response["success"].asBoolean())
+ {
+ me->setEmissiveId(newAssetId);
+
+ // discard upload buffers once texture have been saved
+ me->mEmissiveJ2C = nullptr;
+ me->mEmissiveFetched = nullptr;
+ me->mEmissiveTextureUploadId.setNull();
+
+ me->mUploadingTexturesCount--;
+
+ if (!me->mUploadingTexturesFailure)
+ {
+ // try saving
+ me->saveIfNeeded();
+ }
+ else if (me->mUploadingTexturesCount == 0)
+ {
+ me->setEnabled(true);
+ }
+ }
+ else
+ {
+ // stop upload if possible, unblock and let user decide
+ me->setFailedToUploadTexture();
+ }
+ }
+ });
+ }
+
+ if (!work_count)
+ {
+ // Discard upload buffers once textures have been confirmed as saved.
+ // Otherwise we keep buffers for potential upload failure recovery.
+ clearTextures();
+ }
+
+ // asset storage can callback immediately, causing a decrease
+ // of mUploadingTexturesCount, report amount of work scheduled
+ // not amount of work remaining
+ return work_count;
+}
+
+void LLMaterialEditor::clearTextures()
+{
+ mBaseColorJ2C = nullptr;
+ mNormalJ2C = nullptr;
+ mEmissiveJ2C = nullptr;
+ mMetallicRoughnessJ2C = nullptr;
+
+ mBaseColorFetched = nullptr;
+ mNormalFetched = nullptr;
+ mMetallicRoughnessFetched = nullptr;
+ mEmissiveFetched = nullptr;
+
+ mBaseColorTextureUploadId.setNull();
+ mNormalTextureUploadId.setNull();
+ mMetallicTextureUploadId.setNull();
+ mEmissiveTextureUploadId.setNull();
+}
+
+void LLMaterialEditor::loadDefaults()
+{
+ tinygltf::Model model_in;
+ model_in.materials.resize(1);
+ setFromGltfModel(model_in, 0, true);
+}
+
+bool LLMaterialEditor::capabilitiesAvailable()
+{
+ const LLViewerRegion* region = gAgent.getRegion();
+ if (!region)
+ {
+ LL_WARNS("MaterialEditor") << "Not connected to a region, cannot save material." << LL_ENDL;
+ return false;
+ }
+ std::string agent_url = region->getCapability("UpdateMaterialAgentInventory");
+ std::string task_url = region->getCapability("UpdateMaterialTaskInventory");
+
+ return (!agent_url.empty() && !task_url.empty());
+}
+
diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h
new file mode 100644
index 0000000000..95a4c4572d
--- /dev/null
+++ b/indra/newview/llmaterialeditor.h
@@ -0,0 +1,323 @@
+/**
+ * @file llmaterialeditor.h
+ * @brief LLMaterialEditor class header file
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llpreview.h"
+#include "llvoinventorylistener.h"
+#include "llimagej2c.h"
+#include "llviewertexture.h"
+
+class LLButton;
+class LLColorSwatchCtrl;
+class LLComboBox;
+class LLGLTFMaterial;
+class LLLocalGLTFMaterial;
+class LLTextureCtrl;
+class LLTextBox;
+class LLViewerInventoryItem;
+
+namespace tinygltf
+{
+ class Model;
+}
+
+// todo: Consider making into a notification or just merging with
+// presets. Layout is identical to camera/graphics presets so there
+// is no point in having multiple separate xmls and classes.
+class LLFloaterComboOptions : public LLFloater
+{
+public:
+ typedef std::function<void(const std::string&, S32)> combo_callback;
+ LLFloaterComboOptions();
+
+ virtual ~LLFloaterComboOptions();
+ /*virtual*/ BOOL postBuild();
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::list<std::string> &options);
+
+ static LLFloaterComboOptions* showUI(
+ combo_callback callback,
+ const std::string &title,
+ const std::string &description,
+ const std::string &ok_text,
+ const std::string &cancel_text,
+ const std::list<std::string> &options);
+
+private:
+ void onConfirm();
+ void onCancel();
+
+protected:
+ combo_callback mCallback;
+
+ LLButton *mConfirmButton;
+ LLButton *mCancelButton;
+ LLComboBox *mComboOptions;
+ LLTextBox *mComboText;
+};
+
+class LLMaterialEditor : public LLPreview, public LLVOInventoryListener
+{ public:
+ LLMaterialEditor(const LLSD& key);
+ ~LLMaterialEditor();
+
+ bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false);
+
+ void setFromGltfMetaData(const std::string& filename, const tinygltf::Model& model, S32 index);
+
+ // open a file dialog and select a gltf/glb file for import
+ static void importMaterial();
+
+ // for live preview, apply current material to currently selected object
+ void applyToSelection();
+
+ // get a dump of the json representation of the current state of the editor UI as a material object
+ void getGLTFMaterial(LLGLTFMaterial* mat);
+
+ void loadAsset() override;
+ // @index if -1 and file contains more than one material,
+ // will promt to select specific one
+ static void uploadMaterialFromModel(const std::string& filename, tinygltf::Model& model, S32 index);
+ static void loadMaterialFromFile(const std::string& filename, S32 index = -1);
+
+ void onSelectionChanged(); // live overrides selection changes
+
+ static void updateLive();
+ static void loadLive();
+
+ static bool canModifyObjectsMaterial();
+ static bool canSaveObjectsMaterial();
+ static bool canClipboardObjectsMaterial();
+ static void saveObjectsMaterialAs();
+ static void onCopyObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions, const LLUUID& object_id, const LLUUID& item_id);
+ static void onSaveObjectsMaterialAsMsgCallback(const LLSD& notification, const LLSD& response, const LLPermissions& permissions);
+
+ static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status);
+
+ void inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data) override;
+
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> upload_callback_f;
+ void saveTexture(LLImageJ2C* img, const std::string& name, const LLUUID& asset_id, upload_callback_f cb);
+ void setFailedToUploadTexture();
+
+ // save textures to inventory if needed
+ // returns amount of scheduled uploads
+ S32 saveTextures();
+ void clearTextures();
+
+ void onClickSave();
+
+ void getGLTFModel(tinygltf::Model& model);
+
+ std::string getEncodedAsset();
+
+ bool decodeAsset(const std::vector<char>& buffer);
+
+ bool saveIfNeeded();
+
+ static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
+
+ static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
+
+ static void finishSaveAs(
+ const LLSD &oldKey,
+ const LLUUID &newItemId,
+ const std::string &buffer,
+ bool has_unsaved_changes);
+
+ void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null);
+
+ void onClickSaveAs();
+ void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response);
+ void onClickCancel();
+ void onCancelMsgCallback(const LLSD& notification, const LLSD& response);
+
+ // llpreview
+ void setObjectID(const LLUUID& object_id) override;
+ void setAuxItem(const LLInventoryItem* item) override;
+
+ // llpanel
+ BOOL postBuild() override;
+ void onClickCloseBtn(bool app_quitting = false) override;
+
+ void onClose(bool app_quitting) override;
+ void draw() override;
+ void handleReshape(const LLRect& new_rect, bool by_user = false) override;
+
+ LLUUID getBaseColorId();
+ void setBaseColorId(const LLUUID& id);
+ void setBaseColorUploadId(const LLUUID& id);
+
+ LLColor4 getBaseColor();
+
+ // sets both base color and transparency
+ void setBaseColor(const LLColor4& color);
+
+ F32 getTransparency();
+ void setTransparency(F32 transparency);
+
+ std::string getAlphaMode();
+ void setAlphaMode(const std::string& alpha_mode);
+
+ F32 getAlphaCutoff();
+ void setAlphaCutoff(F32 alpha_cutoff);
+
+ void setMaterialName(const std::string &name);
+
+ LLUUID getMetallicRoughnessId();
+ void setMetallicRoughnessId(const LLUUID& id);
+ void setMetallicRoughnessUploadId(const LLUUID& id);
+
+ F32 getMetalnessFactor();
+ void setMetalnessFactor(F32 factor);
+
+ F32 getRoughnessFactor();
+ void setRoughnessFactor(F32 factor);
+
+ LLUUID getEmissiveId();
+ void setEmissiveId(const LLUUID& id);
+ void setEmissiveUploadId(const LLUUID& id);
+
+ LLColor4 getEmissiveColor();
+ void setEmissiveColor(const LLColor4& color);
+
+ LLUUID getNormalId();
+ void setNormalId(const LLUUID& id);
+ void setNormalUploadId(const LLUUID& id);
+
+ bool getDoubleSided();
+ void setDoubleSided(bool double_sided);
+
+ void setCanSaveAs(bool value);
+ void setCanSave(bool value);
+ void setEnableEditing(bool can_modify);
+
+ void subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id);
+ void replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support
+ void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
+ void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
+ void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag);
+
+ // initialize the UI from a default GLTF material
+ void loadDefaults();
+
+ U32 getUnsavedChangesFlags() { return mUnsavedChanges; }
+ U32 getRevertedChangesFlags() { return mRevertedChanges; }
+ LLUUID getLocalTextureTrackingIdFromFlag(U32 flag);
+ bool updateMaterialLocalSubscription(LLGLTFMaterial* mat);
+
+ static bool capabilitiesAvailable();
+
+private:
+ static void saveObjectsMaterialAs(const LLGLTFMaterial *render_material, const LLLocalGLTFMaterial *local_material, const LLPermissions& permissions, const LLUUID& object_id /* = LLUUID::null */, const LLUUID& item /* = LLUUID::null */);
+
+ static bool updateInventoryItem(const std::string &buffer, const LLUUID &item_id, const LLUUID &task_id);
+ static void createInventoryItem(const std::string &buffer, const std::string &name, const std::string &desc, const LLPermissions& permissions);
+
+ void setFromGLTFMaterial(LLGLTFMaterial* mat);
+ bool setFromSelection();
+
+ void loadMaterial(const tinygltf::Model &model, const std::string & filename, S32 index, bool open_floater = true);
+
+ friend class LLMaterialFilePicker;
+
+ LLUUID mAssetID;
+
+ LLTextureCtrl* mBaseColorTextureCtrl;
+ LLTextureCtrl* mMetallicTextureCtrl;
+ LLTextureCtrl* mEmissiveTextureCtrl;
+ LLTextureCtrl* mNormalTextureCtrl;
+ LLColorSwatchCtrl* mBaseColorCtrl;
+ LLColorSwatchCtrl* mEmissiveColorCtrl;
+
+ // 'Default' texture, unless it's null or from inventory is the one with the fee
+ LLUUID mBaseColorTextureUploadId;
+ LLUUID mMetallicTextureUploadId;
+ LLUUID mEmissiveTextureUploadId;
+ LLUUID mNormalTextureUploadId;
+
+ // last known name of each texture
+ std::string mBaseColorName;
+ std::string mNormalName;
+ std::string mMetallicRoughnessName;
+ std::string mEmissiveName;
+
+ // keep pointers to fetched textures or viewer will remove them
+ // if user temporary selects something else with 'apply now'
+ LLPointer<LLViewerFetchedTexture> mBaseColorFetched;
+ LLPointer<LLViewerFetchedTexture> mNormalFetched;
+ LLPointer<LLViewerFetchedTexture> mMetallicRoughnessFetched;
+ LLPointer<LLViewerFetchedTexture> mEmissiveFetched;
+
+ // J2C versions of packed buffers for uploading
+ LLPointer<LLImageJ2C> mBaseColorJ2C;
+ LLPointer<LLImageJ2C> mNormalJ2C;
+ LLPointer<LLImageJ2C> mMetallicRoughnessJ2C;
+ LLPointer<LLImageJ2C> mEmissiveJ2C;
+
+ // utility function for converting image uri into a texture name
+ const std::string getImageNameFromUri(std::string image_uri, const std::string texture_type);
+
+ // utility function for building a description of the imported material
+ // based on what we know about it.
+ const std::string buildMaterialDescription();
+
+ void resetUnsavedChanges();
+ void markChangesUnsaved(U32 dirty_flag);
+
+ U32 mUnsavedChanges; // flags to indicate individual changed parameters
+ U32 mRevertedChanges; // flags to indicate individual reverted parameters
+ S32 mUploadingTexturesCount;
+ S32 mExpectedUploadCost;
+ bool mUploadingTexturesFailure;
+ std::string mMaterialNameShort;
+ std::string mMaterialName;
+
+ // if true, this instance is live instance editing overrides
+ bool mIsOverride = false;
+ bool mHasSelection = false;
+ // local id, texture ids per face for object overrides
+ // for "cancel" support
+ static LLUUID mOverrideObjectId; // static to avoid searching for the floater
+ static S32 mOverrideObjectTE;
+ static bool mOverrideInProgress;
+ static bool mSelectionNeedsUpdate;
+ boost::signals2::connection mSelectionUpdateSlot;
+
+ struct LocalTextureConnection
+ {
+ LLUUID mTrackingId;
+ boost::signals2::connection mConnection;
+ };
+ typedef std::map<S32, LocalTextureConnection> mat_connection_map_t;
+ mat_connection_map_t mTextureChangesUpdates;
+};
+
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index a52f7244f3..3b59b2f05e 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -133,8 +133,7 @@ LLMaterialMgr::LLMaterialMgr():
mHttpRequest(),
mHttpHeaders(),
mHttpOptions(),
- mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpPriority(0)
+ mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID)
{
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
@@ -693,7 +692,7 @@ void LLMaterialMgr::processGetQueue()
<< "\ndata: " << ll_pretty_print_sd(materialsData) << LL_ENDL;
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
- mHttpPolicy, mHttpPriority, capURL,
+ mHttpPolicy, capURL,
postData, mHttpOptions, mHttpHeaders, handler);
if (handle == LLCORE_HTTP_HANDLE_INVALID)
@@ -979,7 +978,7 @@ void LLMaterialMgr::processPutQueue()
));
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPutWithLLSD(
- mHttpRequest, mHttpPolicy, mHttpPriority, capURL,
+ mHttpRequest, mHttpPolicy, capURL,
putData, mHttpOptions, mHttpHeaders, handler);
if (handle == LLCORE_HTTP_HANDLE_INVALID)
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 8f1ec8584b..6e574219ae 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -138,7 +138,6 @@ private:
LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpOptions::ptr_t mHttpOptions;
LLCore::HttpRequest::policy_t mHttpPolicy;
- LLCore::HttpRequest::priority_t mHttpPriority;
U32 getMaxEntries(const LLViewerRegion* regionp);
};
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 9d0f62a30d..d3b981e205 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -354,7 +354,7 @@ void LLMediaDataClient::serviceQueue()
// and make the post
LLCore::HttpHandler::ptr_t handler = request->createHandler();
- LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy, 0,
+ LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest, mHttpPolicy,
url, sd_payload, mHttpOpts, mHttpHeaders, handler);
if (handle == LLCORE_HTTP_HANDLE_INVALID)
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index d6eba6b4bf..01d6469010 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -828,8 +828,7 @@ LLMeshRepoThread::LLMeshRepoThread()
mHttpLargeOptions(),
mHttpHeaders(),
mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
- mHttpPriority(0)
+ mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID)
{
LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
@@ -1287,7 +1286,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
if (len < LARGE_MESH_FETCH_THRESHOLD)
{
handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass,
- mHttpPriority,
url,
(disable_range_req ? size_t(0) : offset),
(disable_range_req ? size_t(0) : len),
@@ -1302,7 +1300,6 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
else
{
handle = mHttpRequest->requestGetByteRange(mHttpLargePolicyClass,
- mHttpPriority,
url,
(disable_range_req ? size_t(0) : offset),
(disable_range_req ? size_t(0) : len),
@@ -1346,10 +1343,11 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id, bool can_retry)
if (header_size > 0)
{
- const LLSD& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["skin"]["offset"].asInteger();
- S32 size = header["skin"]["size"].asInteger();
+ const LLMeshHeader& header = header_it->second.second;
+
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mSkinOffset;
+ S32 size = header.mSkinSize;
mHeaderMutex->unlock();
@@ -1460,9 +1458,9 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["physics_convex"]["offset"].asInteger();
- S32 size = header["physics_convex"]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mPhysicsConvexOffset;
+ S32 size = header.mPhysicsConvexSize;
mHeaderMutex->unlock();
@@ -1559,9 +1557,9 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header["physics_mesh"]["offset"].asInteger();
- S32 size = header["physics_mesh"]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mPhysicsMeshOffset;
+ S32 size = header.mPhysicsMeshSize;
mHeaderMutex->unlock();
@@ -1757,9 +1755,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
if (header_size > 0)
{
const auto& header = header_it->second.second;
- S32 version = header["version"].asInteger();
- S32 offset = header_size + header[header_lod[lod]]["offset"].asInteger();
- S32 size = header[header_lod[lod]]["size"].asInteger();
+ S32 version = header.mVersion;
+ S32 offset = header_size + header.mLodOffset[lod];
+ S32 size = header.mLodSize[lod];
mHeaderMutex->unlock();
if (version <= MAX_MESH_VERSION && offset >= 0 && size > 0)
@@ -1861,7 +1859,9 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod,
EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* data, S32 data_size)
{
const LLUUID mesh_id = mesh_params.getSculptID();
- LLSD header;
+ LLSD header_data;
+
+ LLMeshHeader header;
llssize header_size = 0;
if (data_size > 0)
@@ -1873,23 +1873,25 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
boost::iostreams::stream<boost::iostreams::array_source> stream(result_ptr, data_size);
- if (!LLSDSerialize::fromBinary(header, stream, data_size))
+ if (!LLSDSerialize::fromBinary(header_data, stream, data_size))
{
LL_WARNS(LOG_MESH) << "Mesh header parse error. Not a valid mesh asset! ID: " << mesh_id
<< LL_ENDL;
return MESH_PARSE_FAILURE;
}
- if (!header.isMap())
+ if (!header_data.isMap())
{
LL_WARNS(LOG_MESH) << "Mesh header is invalid for ID: " << mesh_id << LL_ENDL;
return MESH_INVALID;
}
- if (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION)
+ header.fromLLSD(header_data);
+
+ if (header.mVersion > MAX_MESH_VERSION)
{
LL_INFOS(LOG_MESH) << "Wrong version in header for " << mesh_id << LL_ENDL;
- header["404"] = 1;
+ header.m404 = true;
}
// make sure there is at least one lod, function returns -1 and marks as 404 otherwise
else if (LLMeshRepository::getActualMeshLOD(header, 0) >= 0)
@@ -1901,7 +1903,7 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
{
LL_INFOS(LOG_MESH) << "Non-positive data size. Marking header as non-existent, will not retry. ID: " << mesh_id
<< LL_ENDL;
- header["404"] = 1;
+ header.m404 = 1;
}
{
@@ -1911,7 +1913,6 @@ EMeshProcessingResult LLMeshRepoThread::headerReceived(const LLVolumeParams& mes
mMeshHeader[mesh_id] = { header_size, header };
LLMeshRepository::sCacheBytesHeaders += header_size;
}
-
LLMutexLock lock(mMutex); // make sure only one thread access mPendingLOD at the same time.
@@ -2129,7 +2130,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
mHttpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_LLSD_XML);
mHttpPolicyClass = LLAppViewer::instance()->getAppCoreHttp().getPolicy(LLAppCoreHttp::AP_UPLOADS);
- mHttpPriority = 0;
}
LLMeshUploadThread::~LLMeshUploadThread()
@@ -2648,7 +2648,6 @@ void LLMeshUploadThread::doWholeModelUpload()
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
mHttpPolicyClass,
- mHttpPriority,
mWholeModelUploadURL,
body,
mHttpOptions,
@@ -2699,7 +2698,6 @@ void LLMeshUploadThread::requestWholeModelFee()
dump_llsd_to_file(mModelData, make_dump_name("whole_model_fee_request_", dump_num));
LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
mHttpPolicyClass,
- mHttpPriority,
mWholeModelFeeCapability,
mModelData,
mHttpOptions,
@@ -2984,7 +2982,7 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
if (iter != mMeshHeader.end())
{
- LLSD& header = iter->second.second;
+ auto& header = iter->second.second;
return LLMeshRepository::getActualMeshLOD(header, lod);
}
@@ -2993,23 +2991,23 @@ S32 LLMeshRepoThread::getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lo
}
//static
-S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
+S32 LLMeshRepository::getActualMeshLOD(LLMeshHeader& header, S32 lod)
{
lod = llclamp(lod, 0, 3);
- if (header.has("404"))
+ if (header.m404)
{
return -1;
}
- S32 version = header["version"];
+ S32 version = header.mVersion;
if (version > MAX_MESH_VERSION)
{
return -1;
}
- if (header[header_lod[lod]]["size"].asInteger() > 0)
+ if (header.mLodSize[lod] > 0)
{
return lod;
}
@@ -3017,24 +3015,25 @@ S32 LLMeshRepository::getActualMeshLOD(LLSD& header, S32 lod)
//search down to find the next available lower lod
for (S32 i = lod-1; i >= 0; --i)
{
- if (header[header_lod[i]]["size"].asInteger() > 0)
+ if (header.mLodSize[i] > 0)
{
return i;
}
}
//search up to find then ext available higher lod
- for (S32 i = lod+1; i < 4; ++i)
+ for (S32 i = lod+1; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
- if (header[header_lod[i]]["size"].asInteger() > 0)
+ if (header.mLodSize[i] > 0)
{
return i;
}
}
//header exists and no good lod found, treat as 404
- header["404"] = 1;
- return -1;
+ header.m404 = true;
+
+ return -1;
}
// Handle failed or successful requests for mesh assets.
@@ -3185,7 +3184,7 @@ void LLMeshHeaderHandler::processFailure(LLCore::HttpStatus status)
// Can't get the header so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3214,7 +3213,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
// Can't get the header so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3223,7 +3222,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
{
// header was successfully retrieved from sim and parsed and is in cache
S32 header_bytes = 0;
- LLSD header;
+ LLMeshHeader header;
gMeshRepo.mThread->mHeaderMutex->lock();
LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
@@ -3234,8 +3233,8 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
}
if (header_bytes > 0
- && !header.has("404")
- && (!header.has("version") || header["version"].asInteger() <= MAX_MESH_VERSION))
+ && !header.m404
+ && (header.mVersion <= MAX_MESH_VERSION))
{
std::stringstream str;
@@ -3244,13 +3243,12 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
for (U32 i = 0; i < LLModel::LOD_PHYSICS; ++i)
{
// figure out how many bytes we'll need to reserve in the file
- const std::string & lod_name = header_lod[i];
- lod_bytes = llmax(lod_bytes, header[lod_name]["offset"].asInteger()+header[lod_name]["size"].asInteger());
+ lod_bytes = llmax(lod_bytes, header.mLodOffset[i]+header.mLodSize[i]);
}
// just in case skin info or decomposition is at the end of the file (which it shouldn't be)
- lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
- lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
+ lod_bytes = llmax(lod_bytes, header.mSkinOffset+header.mSkinSize);
+ lod_bytes = llmax(lod_bytes, header.mPhysicsConvexOffset + header.mPhysicsConvexSize);
// Do not unlock mutex untill we are done with LLSD.
// LLSD is smart and can work like smart pointer, is not thread safe.
@@ -3296,7 +3294,7 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
LLMutexLock lock(gMeshRepo.mThread->mMutex);
- for (int i(0); i < 4; ++i)
+ for (int i(0); i < LLVolumeLODGroup::NUM_LODS; ++i)
{
gMeshRepo.mThread->mUnavailableQ.push_back(LLMeshRepoThread::LODRequest(mMeshParams, i));
}
@@ -3657,7 +3655,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
// Manage time-to-load metrics for mesh download operations.
metricsProgress(1);
- if (detail < 0 || detail >= 4)
+ if (detail < 0 || detail >= LLVolumeLODGroup::NUM_LODS)
{
return detail;
}
@@ -3720,7 +3718,7 @@ S32 LLMeshRepository::loadMesh(LLVOVolume* vobj, const LLVolumeParams& mesh_para
}
//no lower LOD is a available, is a higher lod available?
- for (S32 i = detail+1; i < 4; ++i)
+ for (S32 i = detail+1; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
LLVolume* lod = group->refLOD(i);
if (lod && lod->isMeshAssetLoaded() && lod->getNumVolumeFaces() > 0)
@@ -3921,7 +3919,7 @@ void LLMeshRepository::notifyLoadedMeshes()
//create score map
std::map<LLUUID, F32> score_map;
- for (U32 i = 0; i < 4; ++i)
+ for (U32 i = 0; i < LLVolumeLODGroup::NUM_LODS; ++i)
{
for (mesh_load_map::iterator iter = mLoadingMeshes[i].begin(); iter != mLoadingMeshes[i].end(); ++iter)
{
@@ -4070,7 +4068,7 @@ void LLMeshRepository::notifyMeshLoaded(const LLVolumeParams& mesh_params, LLVol
if (sys_volume)
{
sys_volume->copyVolumeFaces(volume);
- sys_volume->setMeshAssetLoaded(TRUE);
+ sys_volume->setMeshAssetLoaded(true);
LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
}
else
@@ -4104,6 +4102,13 @@ void LLMeshRepository::notifyMeshUnavailable(const LLVolumeParams& mesh_params,
{
F32 detail = LLVolumeLODGroup::getVolumeScaleFromDetail(lod);
+ LLVolume* sys_volume = LLPrimitive::getVolumeManager()->refVolume(mesh_params, lod);
+ if (sys_volume)
+ {
+ sys_volume->setMeshAssetUnavaliable(true);
+ LLPrimitive::getVolumeManager()->unrefVolume(sys_volume);
+ }
+
for (LLVOVolume* vobj : obj_iter->second)
{
if (vobj)
@@ -4260,14 +4265,45 @@ bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
return false;
}
+bool LLMeshRepository::hasSkinInfo(const LLUUID& mesh_id)
+{
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
+
+ if (mThread->hasSkinInfoInHeader(mesh_id))
+ {
+ return true;
+ }
+
+ const LLMeshSkinInfo* skininfo = getSkinInfo(mesh_id);
+ if (skininfo)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+bool LLMeshRepository::hasHeader(const LLUUID& mesh_id)
+{
+ if (mesh_id.isNull())
+ {
+ return false;
+ }
+
+ return mThread->hasHeader(mesh_id);
+}
+
bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
{
LLMutexLock lock(mHeaderMutex);
mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
if (iter != mMeshHeader.end() && iter->second.first > 0)
{
- LLSD &mesh = iter->second.second;
- if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0))
+ LLMeshHeader &mesh = iter->second.second;
+ if (mesh.mPhysicsMeshSize > 0)
{
return true;
}
@@ -4276,6 +4312,29 @@ bool LLMeshRepoThread::hasPhysicsShapeInHeader(const LLUUID& mesh_id)
return false;
}
+bool LLMeshRepoThread::hasSkinInfoInHeader(const LLUUID& mesh_id)
+{
+ LLMutexLock lock(mHeaderMutex);
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ if (iter != mMeshHeader.end() && iter->second.first > 0)
+ {
+ LLMeshHeader& mesh = iter->second.second;
+ if (mesh.mSkinOffset >= 0
+ && mesh.mSkinSize > 0)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLMeshRepoThread::hasHeader(const LLUUID& mesh_id)
+{
+ LLMutexLock lock(mHeaderMutex);
+ mesh_header_map::iterator iter = mMeshHeader.find(mesh_id);
+ return iter != mMeshHeader.end();
+}
void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures,
bool upload_skin, bool upload_joints, bool lock_scale_if_joint_position,
@@ -4290,20 +4349,21 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- const LLSD& header = iter->second.second;
+ const LLMeshHeader& header = iter->second.second;
- if (header.has("404"))
+ if (header.m404)
{
return -1;
}
- S32 size = header[header_lod[lod]]["size"].asInteger();
+ S32 size = header.mLodSize[lod];
return size;
}
@@ -4424,7 +4484,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
{
LL_WARNS() << mesh_id << "bytes mismatch " << *bytes << " " << data.getSizeTotal() << LL_ENDL;
}
- if (bytes_visible && (lod >=0) && (lod < 4) && (*bytes_visible != data.getSizeByLOD(lod)))
+ if (bytes_visible && (lod >=0) && (lod < LLVolumeLODGroup::NUM_LODS) && (*bytes_visible != data.getSizeByLOD(lod)))
{
LL_WARNS() << mesh_id << "bytes_visible mismatch " << *bytes_visible << " " << data.getSizeByLOD(lod) << LL_ENDL;
}
@@ -4439,11 +4499,11 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* by
// FIXME replace with calc based on LLMeshCostData
//static
-F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
+F32 LLMeshRepository::getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes, S32* bytes_visible, S32 lod, F32 *unscaled_value)
{
- if (header.has("404")
- || !header.has("lowest_lod")
- || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION))
+ if (header.m404
+ || header.mLodSize[0] <= 0
+ || (header.mVersion > MAX_MESH_VERSION))
{
return 0.f;
}
@@ -4462,10 +4522,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
F32 minimum_size = (F32)minimum_size_ch;
F32 bytes_per_triangle = (F32)bytes_per_triangle_ch;
- S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
- S32 bytes_low = header["low_lod"]["size"].asInteger();
- S32 bytes_mid = header["medium_lod"]["size"].asInteger();
- S32 bytes_high = header["high_lod"]["size"].asInteger();
+ S32 bytes_lowest = header.mLodSize[0];
+ S32 bytes_low = header.mLodSize[1];
+ S32 bytes_mid = header.mLodSize[2];
+ S32 bytes_high = header.mLodSize[3];
if (bytes_high == 0)
{
@@ -4495,10 +4555,10 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
if (bytes)
{
*bytes = 0;
- *bytes += header["lowest_lod"]["size"].asInteger();
- *bytes += header["low_lod"]["size"].asInteger();
- *bytes += header["medium_lod"]["size"].asInteger();
- *bytes += header["high_lod"]["size"].asInteger();
+ *bytes += header.mLodSize[0];
+ *bytes += header.mLodSize[1];
+ *bytes += header.mLodSize[2];
+ *bytes += header.mLodSize[3];
}
if (bytes_visible)
@@ -4506,7 +4566,7 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
lod = LLMeshRepository::getActualMeshLOD(header, lod);
if (lod >= 0 && lod <= 3)
{
- *bytes_visible = header[header_lod[lod]]["size"].asInteger();
+ *bytes_visible = header.mLodSize[lod];
}
}
@@ -4548,33 +4608,29 @@ F32 LLMeshRepository::getStreamingCostLegacy(LLSD& header, F32 radius, S32* byte
LLMeshCostData::LLMeshCostData()
{
- mSizeByLOD.resize(4);
- mEstTrisByLOD.resize(4);
-
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
}
-bool LLMeshCostData::init(const LLSD& header)
+bool LLMeshCostData::init(const LLMeshHeader& header)
{
- mSizeByLOD.resize(4);
- mEstTrisByLOD.resize(4);
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
std::fill(mSizeByLOD.begin(), mSizeByLOD.end(), 0);
std::fill(mEstTrisByLOD.begin(), mEstTrisByLOD.end(), 0.f);
- S32 bytes_high = header["high_lod"]["size"].asInteger();
- S32 bytes_med = header["medium_lod"]["size"].asInteger();
+ S32 bytes_high = header.mLodSize[3];
+ S32 bytes_med = header.mLodSize[2];
if (bytes_med == 0)
{
bytes_med = bytes_high;
}
- S32 bytes_low = header["low_lod"]["size"].asInteger();
+ S32 bytes_low = header.mLodSize[1];
if (bytes_low == 0)
{
bytes_low = bytes_med;
}
- S32 bytes_lowest = header["lowest_lod"]["size"].asInteger();
+ S32 bytes_lowest = header.mLodSize[0];
if (bytes_lowest == 0)
{
bytes_lowest = bytes_low;
@@ -4588,7 +4644,7 @@ bool LLMeshCostData::init(const LLSD& header)
static LLCachedControl<U32> minimum_size(gSavedSettings, "MeshMinimumByteSize", 16); //make sure nothing is "free"
static LLCachedControl<U32> bytes_per_triangle(gSavedSettings, "MeshBytesPerTriangle", 16);
- for (S32 i=0; i<4; i++)
+ for (S32 i=0; i<LLVolumeLODGroup::NUM_LODS; i++)
{
mEstTrisByLOD[i] = llmax((F32)mSizeByLOD[i] - (F32)metadata_discount, (F32)minimum_size) / (F32)bytes_per_triangle;
}
@@ -4709,6 +4765,7 @@ F32 LLMeshCostData::getTriangleBasedStreamingCost()
bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
data = LLMeshCostData();
if (mThread && mesh_id.notNull())
@@ -4717,11 +4774,11 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
if (iter != mThread->mMeshHeader.end() && iter->second.first > 0)
{
- LLSD& header = iter->second.second;
+ LLMeshHeader& header = iter->second.second;
- bool header_invalid = (header.has("404")
- || !header.has("lowest_lod")
- || (header.has("version") && header["version"].asInteger() > MAX_MESH_VERSION));
+ bool header_invalid = (header.m404
+ || header.mLodSize[0] <= 0
+ || header.mVersion > MAX_MESH_VERSION);
if (!header_invalid)
{
return getCostData(header, data);
@@ -4733,7 +4790,7 @@ bool LLMeshRepository::getCostData(LLUUID mesh_id, LLMeshCostData& data)
return false;
}
-bool LLMeshRepository::getCostData(LLSD& header, LLMeshCostData& data)
+bool LLMeshRepository::getCostData(LLMeshHeader& header, LLMeshCostData& data)
{
data = LLMeshCostData();
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index e3688ff243..89cd2d867f 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -194,6 +194,63 @@ private:
LLFrameTimer mTimer;
};
+class LLMeshHeader
+{
+public:
+
+ LLMeshHeader() {}
+
+ explicit LLMeshHeader(const LLSD& header)
+ {
+ fromLLSD(header);
+ }
+
+ void fromLLSD(const LLSD& header)
+ {
+ const char* lod[] =
+ {
+ "lowest_lod",
+ "low_lod",
+ "medium_lod",
+ "high_lod"
+ };
+
+ mVersion = header["version"].asInteger();
+
+ for (U32 i = 0; i < 4; ++i)
+ {
+ mLodOffset[i] = header[lod[i]]["offset"].asInteger();
+ mLodSize[i] = header[lod[i]]["size"].asInteger();
+ }
+
+ mSkinOffset = header["skin"]["offset"].asInteger();
+ mSkinSize = header["skin"]["size"].asInteger();
+
+ mPhysicsConvexOffset = header["physics_convex"]["offset"].asInteger();
+ mPhysicsConvexSize = header["physics_convex"]["size"].asInteger();
+
+ mPhysicsMeshOffset = header["physics_mesh"]["offset"].asInteger();
+ mPhysicsMeshSize = header["physics_mesh"]["size"].asInteger();
+
+ m404 = header.has("404");
+ }
+
+ S32 mVersion = -1;
+ S32 mSkinOffset = -1;
+ S32 mSkinSize = -1;
+
+ S32 mPhysicsConvexOffset = -1;
+ S32 mPhysicsConvexSize = -1;
+
+ S32 mPhysicsMeshOffset = -1;
+ S32 mPhysicsMeshSize = -1;
+
+ S32 mLodOffset[4] = { -1 };
+ S32 mLodSize[4] = { -1 };
+
+ bool m404 = false;
+};
+
class LLMeshRepoThread : public LLThread
{
public:
@@ -210,7 +267,7 @@ public:
LLCondition* mSignal;
//map of known mesh headers
- typedef boost::unordered_map<LLUUID, std::pair<U32, LLSD>> mesh_header_map; // pair is header_size and data
+ typedef boost::unordered_map<LLUUID, std::pair<U32, LLMeshHeader>> mesh_header_map; // pair is header_size and data
mesh_header_map mMeshHeader;
class HeaderRequest : public RequestStats
@@ -322,7 +379,6 @@ public:
LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
LLCore::HttpRequest::policy_t mHttpLargePolicyClass;
- LLCore::HttpRequest::priority_t mHttpPriority;
typedef std::set<LLCore::HttpHandler::ptr_t> http_request_set;
http_request_set mHttpRequestSet; // Outstanding HTTP requests
@@ -345,6 +401,8 @@ public:
bool decompositionReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
EMeshProcessingResult physicsShapeReceived(const LLUUID& mesh_id, U8* data, S32 data_size);
bool hasPhysicsShapeInHeader(const LLUUID& mesh_id);
+ bool hasSkinInfoInHeader(const LLUUID& mesh_id);
+ bool hasHeader(const LLUUID& mesh_id);
void notifyLoadedMeshes();
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
@@ -490,7 +548,6 @@ private:
LLCore::HttpOptions::ptr_t mHttpOptions;
LLCore::HttpHeaders::ptr_t mHttpHeaders;
LLCore::HttpRequest::policy_t mHttpPolicyClass;
- LLCore::HttpRequest::priority_t mHttpPriority;
};
// Params related to streaming cost, render cost, and scene complexity tracking.
@@ -499,7 +556,7 @@ class LLMeshCostData
public:
LLMeshCostData();
- bool init(const LLSD& header);
+ bool init(const LLMeshHeader& header);
// Size for given LOD
S32 getSizeByLOD(S32 lod);
@@ -534,10 +591,10 @@ public:
private:
// From the "size" field of the mesh header. LOD 0=lowest, 3=highest.
- std::vector<S32> mSizeByLOD;
+ std::array<S32,4> mSizeByLOD;
// Estimated triangle counts derived from the LOD sizes. LOD 0=lowest, 3=highest.
- std::vector<F32> mEstTrisByLOD;
+ std::array<F32,4> mEstTrisByLOD;
};
class LLMeshRepository
@@ -568,9 +625,9 @@ public:
F32 getEstTrianglesMax(LLUUID mesh_id);
F32 getEstTrianglesStreamingCost(LLUUID mesh_id);
F32 getStreamingCostLegacy(LLUUID mesh_id, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
- static F32 getStreamingCostLegacy(LLSD& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
+ static F32 getStreamingCostLegacy(LLMeshHeader& header, F32 radius, S32* bytes = NULL, S32* visible_bytes = NULL, S32 detail = -1, F32 *unscaled_value = NULL);
bool getCostData(LLUUID mesh_id, LLMeshCostData& data);
- bool getCostData(LLSD& header, LLMeshCostData& data);
+ bool getCostData(LLMeshHeader& header, LLMeshCostData& data);
LLMeshRepository();
@@ -590,11 +647,13 @@ public:
void notifyDecompositionReceived(LLModel::Decomposition* info);
S32 getActualMeshLOD(const LLVolumeParams& mesh_params, S32 lod);
- static S32 getActualMeshLOD(LLSD& header, S32 lod);
+ static S32 getActualMeshLOD(LLMeshHeader& header, S32 lod);
const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id, LLVOVolume* requesting_obj = nullptr);
LLModel::Decomposition* getDecomposition(const LLUUID& mesh_id);
void fetchPhysicsShape(const LLUUID& mesh_id);
bool hasPhysicsShape(const LLUUID& mesh_id);
+ bool hasSkinInfo(const LLUUID& mesh_id);
+ bool hasHeader(const LLUUID& mesh_id);
void buildHull(const LLVolumeParams& params, S32 detail);
void buildPhysicsMesh(LLModel::Decomposition& decomp);
diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp
index 495153981b..ccae1030f1 100644
--- a/indra/newview/llmodelpreview.cpp
+++ b/indra/newview/llmodelpreview.cpp
@@ -30,6 +30,7 @@
#include "llmodelloader.h"
#include "lldaeloader.h"
+#include "llgltfloader.h"
#include "llfloatermodelpreview.h"
#include "llagent.h"
@@ -747,20 +748,43 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable
std::map<std::string, std::string> joint_alias_map;
getJointAliases(joint_alias_map);
- mModelLoader = new LLDAELoader(
- filename,
- lod,
- &LLModelPreview::loadedCallback,
- &LLModelPreview::lookupJointByName,
- &LLModelPreview::loadTextures,
- &LLModelPreview::stateChangedCallback,
- this,
- mJointTransformMap,
- mJointsFromNode,
- joint_alias_map,
- LLSkinningUtil::getMaxJointCount(),
- gSavedSettings.getU32("ImporterModelLimit"),
- gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ // three possible file extensions, .dae .gltf .glb
+ // check for .dae and if not then assume one of the .gl??
+ std::string filename_lc(filename);
+ LLStringUtil::toLower(filename_lc);
+ if (std::string::npos != filename_lc.rfind(".dae"))
+ {
+ mModelLoader = new LLDAELoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"),
+ gSavedSettings.getBOOL("ImporterPreprocessDAE"));
+ }
+ else
+ {
+ mModelLoader = new LLGLTFLoader(
+ filename,
+ lod,
+ &LLModelPreview::loadedCallback,
+ &LLModelPreview::lookupJointByName,
+ &LLModelPreview::loadTextures,
+ &LLModelPreview::stateChangedCallback,
+ this,
+ mJointTransformMap,
+ mJointsFromNode,
+ joint_alias_map,
+ LLSkinningUtil::getMaxJointCount(),
+ gSavedSettings.getU32("ImporterModelLimit"));
+ }
if (force_disable_slm)
{
@@ -1307,7 +1331,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// extra space for normals and text coords
S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF;
- LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* combined_normals = combined_positions + size_vertices;
LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices);
@@ -1427,7 +1451,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
// IV. Repack back into individual faces
- LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size);
+ LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size);
LLVector4a* buffer_normals = buffer_positions + size_vertices;
LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices);
S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF;
@@ -1548,7 +1572,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe
{
new_face.resizeIndices(buf_indices_copied);
new_face.resizeVertices(buf_positions_copied);
-
+ new_face.allocateTangents(buf_positions_copied);
S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size);
@@ -1715,7 +1739,7 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
out << "Invalid level of detail: " << which_lod;
LL_WARNS() << out.str() << LL_ENDL;
LLFloaterModelPreview::addStringToLog(out, false);
- assert(lod >= -1 && lod < LLModel::NUM_LODS);
+ llassert(which_lod >= -1 && which_lod < LLModel::NUM_LODS);
return;
}
@@ -1832,6 +1856,14 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d
LLModel* target_model = mModel[lod][mdl_idx];
+ // carry over normalized transform into simplified model
+ for (int i = 0; i < base->getNumVolumeFaces(); ++i)
+ {
+ LLVolumeFace& src = base->getVolumeFace(i);
+ LLVolumeFace& dst = target_model->getVolumeFace(i);
+ dst.mNormalizedScale = src.mNormalizedScale;
+ }
+
S32 model_meshopt_mode = meshopt_mode;
// Ideally this should run not per model,
@@ -2716,6 +2748,16 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
base_iter++;
+ bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
+
+ LLMatrix4a mat_normal;
+ if (skinned)
+ {
+ glh::matrix4f m((F32*)mdl->mSkinInfo.mBindShapeMatrix.getF32ptr());
+ m = m.inverse().transpose();
+ mat_normal.loadu(m.m);
+ }
+
S32 num_faces = mdl->getNumVolumeFaces();
for (S32 i = 0; i < num_faces; ++i)
{
@@ -2730,7 +2772,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLVertexBuffer* vb = NULL;
- bool skinned = include_skin_weights && !mdl->mSkinWeights.empty();
+
U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
@@ -2739,9 +2781,9 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
mask |= LLVertexBuffer::MAP_WEIGHT4;
}
- vb = new LLVertexBuffer(mask, 0);
+ vb = new LLVertexBuffer(mask);
- if (!vb->allocateBuffer(num_vertices, num_indices, TRUE))
+ if (!vb->allocateBuffer(num_vertices, num_indices))
{
// We are likely to crash due this failure, if this happens, find a way to gracefully stop preview
std::ostringstream out;
@@ -2768,6 +2810,15 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
LLVector4a::memcpyNonAliased16((F32*)vertex_strider.get(), (F32*)vf.mPositions, num_vertices * 4 * sizeof(F32));
+ if (skinned)
+ {
+ for (U32 i = 0; i < num_vertices; ++i)
+ {
+ LLVector4a* v = (LLVector4a*)vertex_strider.get();
+ mdl->mSkinInfo.mBindShapeMatrix.affineTransform(*v, *v);
+ vertex_strider++;
+ }
+ }
if (vf.mTexCoords)
{
vb->getTexCoord0Strider(tc_strider);
@@ -2778,7 +2829,25 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
if (vf.mNormals)
{
vb->getNormalStrider(normal_strider);
- LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32));
+
+ if (skinned)
+ {
+ F32* normals = (F32*)normal_strider.get();
+ LLVector4a* src = vf.mNormals;
+ LLVector4a* end = src + num_vertices;
+
+ while (src < end)
+ {
+ LLVector4a normal;
+ mat_normal.rotate(*src++, normal);
+ normal.store4a(normals);
+ normals += 4;
+ }
+ }
+ else
+ {
+ LLVector4a::memcpyNonAliased16((F32*)normal_strider.get(), (F32*)vf.mNormals, num_vertices * 4 * sizeof(F32));
+ }
}
if (skinned)
@@ -2812,7 +2881,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
*(index_strider++) = vf.mIndices[i];
}
- vb->flush();
+ vb->unmapBuffer();
mVertexBuffer[lod][mdl].push_back(vb);
}
@@ -3004,11 +3073,11 @@ void LLModelPreview::addEmptyFace(LLModel* pTarget)
{
U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask, 0);
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(type_mask);
- buff->allocateBuffer(1, 3, true);
+ buff->allocateBuffer(1, 3);
memset((U8*)buff->getMappedData(), 0, buff->getSize());
- memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize());
+ memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize());
buff->validateRange(0, buff->getNumVerts() - 1, buff->getNumIndices(), 0);
@@ -3059,12 +3128,11 @@ BOOL LLModelPreview::render()
S32 width = getWidth();
S32 height = getHeight();
- LLGLSUIDefault def; // GL_BLEND, GL_ALPHA_TEST, GL_CULL_FACE, depth test
+ LLGLSUIDefault def;
LLGLDisable no_blend(GL_BLEND);
LLGLEnable cull(GL_CULL_FACE);
LLGLDepthTest depth(GL_FALSE); // SL-12781 disable z-buffer to render background color
- LLGLDisable fog(GL_FOG);
-
+
{
gUIProgram.bind();
@@ -3240,7 +3308,7 @@ BOOL LLModelPreview::render()
refresh();
}
- gObjectPreviewProgram.bind();
+ gObjectPreviewProgram.bind(skin_weight);
gGL.loadIdentity();
gPipeline.enableLightsPreview();
@@ -3265,10 +3333,6 @@ BOOL LLModelPreview::render()
gGL.pushMatrix();
gGL.color4fv(PREVIEW_EDGE_COL.mV);
- const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0;
-
- LLGLEnable normalize(GL_NORMALIZE);
-
if (!mBaseModel.empty() && mVertexBuffer[5].empty())
{
genBuffers(-1, skin_weight);
@@ -3319,17 +3383,17 @@ BOOL LLModelPreview::render()
}
gGL.pushMatrix();
+
LLMatrix4 mat = instance.mTransform;
gGL.multMatrix((GLfloat*)mat.mMatrix);
-
-
+
U32 num_models = mVertexBuffer[mPreviewLOD][model].size();
for (U32 i = 0; i < num_models; ++i)
{
LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->setBuffer();
if (textures)
{
@@ -3366,7 +3430,7 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
}
- buffer->flush();
+ buffer->unmapBuffer();
}
gGL.popMatrix();
}
@@ -3480,7 +3544,7 @@ BOOL LLModelPreview::render()
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_PSYH_FILL_COL.mV);
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->setBuffer();
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0);
gGL.diffuseColor4fv(PREVIEW_PSYH_EDGE_COL.mV);
@@ -3491,7 +3555,7 @@ BOOL LLModelPreview::render()
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
- buffer->flush();
+ buffer->unmapBuffer();
}
}
}
@@ -3541,7 +3605,7 @@ BOOL LLModelPreview::render()
{
LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v];
- buffer->setBuffer(type_mask & buffer->getTypeMask());
+ buffer->setBuffer();
LLStrider<LLVector3> pos_strider;
buffer->getVertexStrider(pos_strider, 0);
@@ -3563,7 +3627,7 @@ BOOL LLModelPreview::render()
}
}
- buffer->flush();
+ buffer->unmapBuffer();
}
}
}
@@ -3653,63 +3717,41 @@ BOOL LLModelPreview::render()
{
LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i];
- const LLVolumeFace& face = model->getVolumeFace(i);
-
- LLStrider<LLVector3> position;
- buffer->getVertexStrider(position);
-
- LLStrider<LLVector4> weight;
- buffer->getWeight4Strider(weight);
+ model->mSkinInfo.updateHash();
+ LLRenderPass::uploadMatrixPalette(mPreviewAvatar, &model->mSkinInfo);
- //quick 'n dirty software vertex skinning
-
- //build matrix palette
-
- LLMatrix4a mat[LL_MAX_JOINTS_PER_MESH_OBJECT];
- LLSkinningUtil::initSkinningMatrixPalette(mat, joint_count,
- skin, getPreviewAvatar());
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- const LLMatrix4a& bind_shape_matrix = skin->mBindShapeMatrix;
- U32 max_joints = LLSkinningUtil::getMaxJointCount();
- for (U32 j = 0; j < buffer->getNumVerts(); ++j)
+ if (textures)
{
- LLMatrix4a final_mat;
- F32 *wptr = weight[j].mV;
- LLSkinningUtil::getPerVertexSkinMatrix(wptr, mat, true, final_mat, max_joints);
-
- //VECTORIZE THIS
- LLVector4a& v = face.mPositions[j];
+ int materialCnt = instance.mModel->mMaterialList.size();
+ if (i < materialCnt)
+ {
+ const std::string& binding = instance.mModel->mMaterialList[i];
+ const LLImportMaterial& material = instance.mMaterial[binding];
- LLVector4a t;
- LLVector4a dst;
- bind_shape_matrix.affineTransform(v, t);
- final_mat.affineTransform(t, dst);
+ gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- position[j][0] = dst[0];
- position[j][1] = dst[1];
- position[j][2] = dst[2];
+ // Find the tex for this material, bind it, and add it to our set
+ //
+ LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
+ if (tex)
+ {
+ mTextureSet.insert(tex);
+ }
+ }
}
-
- llassert(model->mMaterialList.size() > i);
- const std::string& binding = instance.mModel->mMaterialList[i];
- const LLImportMaterial& material = instance.mMaterial[binding];
-
- buffer->setBuffer(type_mask & buffer->getTypeMask());
- gGL.diffuseColor4fv(material.mDiffuseColor.mV);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- // Find the tex for this material, bind it, and add it to our set
- //
- LLViewerFetchedTexture* tex = bindMaterialDiffuseTexture(material);
- if (tex)
+ else
{
- mTextureSet.insert(tex);
+ gGL.diffuseColor4fv(PREVIEW_BASE_COL.mV);
}
+ buffer->setBuffer();
buffer->draw(LLRender::TRIANGLES, buffer->getNumIndices(), 0);
if (edges)
{
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.diffuseColor4fv(PREVIEW_EDGE_COL.mV);
glLineWidth(PREVIEW_EDGE_WIDTH);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
index a169712bd8..839f25761a 100644
--- a/indra/newview/llpaneleditsky.cpp
+++ b/indra/newview/llpaneleditsky.cpp
@@ -36,6 +36,7 @@
#include "llsettingssky.h"
#include "llenvironment.h"
#include "llatmosphere.h"
+#include "llviewercontrol.h"
namespace
{
@@ -108,6 +109,8 @@ namespace
const std::string FIELD_SKY_DENSITY_DROPLET_RADIUS("droplet_radius");
const std::string FIELD_SKY_DENSITY_ICE_LEVEL("ice_level");
+ const std::string FIELD_REFLECTION_PROBE_AMBIANCE("probe_ambiance");
+
const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
const F32 SLIDER_SCALE_BLUE_HORIZON_DENSITY(2.0f);
const F32 SLIDER_SCALE_GLOW_R(20.0f);
@@ -150,6 +153,7 @@ BOOL LLPanelSettingsSkyAtmosTab::postBuild()
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoistureLevelChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onDropletRadiusChanged(); });
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onIceLevelChanged(); });
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setCommitCallback([this](LLUICtrl*, const LLSD&) { onReflectionProbeAmbianceChanged(); });
refresh();
return TRUE;
@@ -172,6 +176,7 @@ void LLPanelSettingsSkyAtmosTab::setEnabled(BOOL enabled)
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setEnabled(enabled);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setEnabled(enabled);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setEnabled(enabled);
}
}
@@ -204,9 +209,15 @@ void LLPanelSettingsSkyAtmosTab::refresh()
F32 droplet_radius = mSkySettings->getSkyDropletRadius();
F32 ice_level = mSkySettings->getSkyIceLevel();
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ F32 rp_ambiance = mSkySettings->getReflectionProbeAmbiance(should_auto_adjust);
+
getChild<LLUICtrl>(FIELD_SKY_DENSITY_MOISTURE_LEVEL)->setValue(moisture_level);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_DROPLET_RADIUS)->setValue(droplet_radius);
getChild<LLUICtrl>(FIELD_SKY_DENSITY_ICE_LEVEL)->setValue(ice_level);
+ getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->setValue(rp_ambiance);
+
+ updateGammaLabel(should_auto_adjust);
}
//-------------------------------------------------------------------------
@@ -311,6 +322,35 @@ void LLPanelSettingsSkyAtmosTab::onIceLevelChanged()
setIsDirty();
}
+void LLPanelSettingsSkyAtmosTab::onReflectionProbeAmbianceChanged()
+{
+ if (!mSkySettings) return;
+ F32 ambiance = getChild<LLUICtrl>(FIELD_REFLECTION_PROBE_AMBIANCE)->getValue().asReal();
+
+ mSkySettings->setReflectionProbeAmbiance(ambiance);
+ mSkySettings->update();
+ setIsDirty();
+
+ updateGammaLabel();
+}
+
+
+void LLPanelSettingsSkyAtmosTab::updateGammaLabel(bool auto_adjust)
+{
+ if (!mSkySettings) return;
+ F32 ambiance = mSkySettings->getReflectionProbeAmbiance(auto_adjust);
+ if (ambiance != 0.f)
+ {
+ childSetValue("scene_gamma_label", getString("hdr_string"));
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setToolTip(getString("hdr_tooltip"));
+ }
+ else
+ {
+ childSetValue("scene_gamma_label", getString("brightness_string"));
+ getChild<LLUICtrl>(FIELD_SKY_SCENE_GAMMA)->setToolTip(std::string());
+ }
+
+}
//==========================================================================
LLPanelSettingsSkyCloudTab::LLPanelSettingsSkyCloudTab() :
LLPanelSettingsSky()
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index cb63d40b0c..523cc134a8 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -79,6 +79,8 @@ private:
void onMoistureLevelChanged();
void onDropletRadiusChanged();
void onIceLevelChanged();
+ void onReflectionProbeAmbianceChanged();
+ void updateGammaLabel(bool auto_adjust = false);
};
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 1b4684d073..cb69f72288 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -574,7 +574,6 @@ static void init_texture_ctrl(LLPanelEditWearable* self, LLPanel* panel, const L
// Don't allow (no copy) or (notransfer) textures to be selected.
texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
texture_ctrl->setDnDFilterPermMask(PERM_NONE);
- texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);
}
}
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index cbb87f63bb..9150b89de3 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -32,7 +32,6 @@
// library includes
#include "llcalc.h"
#include "llerror.h"
-#include "llfocusmgr.h"
#include "llrect.h"
#include "llstring.h"
#include "llfontgl.h"
@@ -46,13 +45,16 @@
#include "llcombobox.h"
#include "lldrawpoolbump.h"
#include "llface.h"
+#include "llgltfmateriallist.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h" // gInventory
#include "llinventorymodelbackgroundfetch.h"
#include "llfloatermediasettings.h"
#include "llfloaterreg.h"
+#include "llfloatertools.h"
#include "lllineeditor.h"
#include "llmaterialmgr.h"
+#include "llmaterialeditor.h"
#include "llmediactrl.h"
#include "llmediaentry.h"
#include "llmenubutton.h"
@@ -76,22 +78,112 @@
#include "llviewerregion.h"
#include "llviewerstats.h"
#include "llvovolume.h"
+#include "llvoinventorylistener.h"
#include "lluictrlfactory.h"
#include "llpluginclassmedia.h"
#include "llviewertexturelist.h"// Update sel manager as to which channel we're editing so it can reflect the correct overlay UI
+
+
+#include "llagent.h"
+#include "llfilesystem.h"
+#include "llviewerassetupload.h"
+#include "llviewermenufile.h"
+#include "llsd.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llinventorymodel.h"
+
+using namespace std::literals;
+
+LLPanelFace::Selection LLPanelFace::sMaterialOverrideSelection;
+
//
// Constant definitions for comboboxes
// Must match the commbobox definitions in panel_tools_texture.xml
//
const S32 MATMEDIA_MATERIAL = 0; // Material
-const S32 MATMEDIA_MEDIA = 1; // Media
+const S32 MATMEDIA_PBR = 1; // PBR
+const S32 MATMEDIA_MEDIA = 2; // Media
const S32 MATTYPE_DIFFUSE = 0; // Diffuse material texture
const S32 MATTYPE_NORMAL = 1; // Normal map
const S32 MATTYPE_SPECULAR = 2; // Specular map
const S32 ALPHAMODE_MASK = 2; // Alpha masking mode
const S32 BUMPY_TEXTURE = 18; // use supplied normal map
const S32 SHINY_TEXTURE = 4; // use supplied specular map
+const S32 PBRTYPE_RENDER_MATERIAL_ID = 0; // Render Material ID
+const S32 PBRTYPE_BASE_COLOR = 1; // PBR Base Color
+const S32 PBRTYPE_METALLIC_ROUGHNESS = 2; // PBR Metallic
+const S32 PBRTYPE_EMISSIVE = 3; // PBR Emissive
+const S32 PBRTYPE_NORMAL = 4; // PBR Normal
+
+LLGLTFMaterial::TextureInfo texture_info_from_pbrtype(S32 pbr_type)
+{
+ switch (pbr_type)
+ {
+ case PBRTYPE_BASE_COLOR:
+ return LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR;
+ break;
+ case PBRTYPE_NORMAL:
+ return LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL;
+ break;
+ case PBRTYPE_METALLIC_ROUGHNESS:
+ return LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS;
+ break;
+ case PBRTYPE_EMISSIVE:
+ return LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE;
+ break;
+ default:
+ return LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
+ break;
+ }
+}
+
+void LLPanelFace::updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func)
+{
+ struct LLSelectedTEGLTFMaterialFunctor : public LLSelectedTEFunctor
+ {
+ LLSelectedTEGLTFMaterialFunctor(std::function<void(LLGLTFMaterial*)> func) : mFunc(func) {}
+ virtual ~LLSelectedTEGLTFMaterialFunctor() {};
+ bool apply(LLViewerObject* object, S32 face) override
+ {
+ LLGLTFMaterial new_override;
+ const LLTextureEntry* tep = object->getTE(face);
+ if (tep->getGLTFMaterialOverride())
+ {
+ new_override = *tep->getGLTFMaterialOverride();
+ }
+ mFunc(&new_override);
+ LLGLTFMaterialList::queueModify(object, face, &new_override);
+
+ return true;
+ }
+
+ std::function<void(LLGLTFMaterial*)> mFunc;
+ } select_func(func);
+
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&select_func);
+}
+
+template<typename T>
+void readSelectedGLTFMaterial(std::function<T(const LLGLTFMaterial*)> func, T& value, bool& identical, bool has_tolerance, T tolerance)
+{
+ struct LLSelectedTEGetGLTFMaterialFunctor : public LLSelectedTEGetFunctor<T>
+ {
+ LLSelectedTEGetGLTFMaterialFunctor(std::function<T(const LLGLTFMaterial*)> func) : mFunc(func) {}
+ virtual ~LLSelectedTEGetGLTFMaterialFunctor() {};
+ T get(LLViewerObject* object, S32 face) override
+ {
+ const LLTextureEntry* tep = object->getTE(face);
+ const LLGLTFMaterial* render_material = tep->getGLTFRenderMaterial();
+
+ return mFunc(render_material);
+ }
+
+ std::function<T(const LLGLTFMaterial*)> mFunc;
+ } select_func(func);
+ identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue(&select_func, value, has_tolerance, tolerance);
+}
BOOST_STATIC_ASSERT(MATTYPE_DIFFUSE == LLRender::DIFFUSE_MAP && MATTYPE_NORMAL == LLRender::NORMAL_MAP && MATTYPE_SPECULAR == LLRender::SPECULAR_MAP);
@@ -103,16 +195,38 @@ std::string USE_TEXTURE;
LLRender::eTexIndex LLPanelFace::getTextureChannelToEdit()
{
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
-
- LLRender::eTexIndex channel_to_edit = (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ?
- (radio_mat_type ? (LLRender::eTexIndex)radio_mat_type->getSelectedIndex() : LLRender::DIFFUSE_MAP) : LLRender::DIFFUSE_MAP;
+ LLRender::eTexIndex channel_to_edit = LLRender::DIFFUSE_MAP;
+ if (mComboMatMedia)
+ {
+ U32 matmedia_selection = mComboMatMedia->getCurrentIndex();
+ if (matmedia_selection == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ if (matmedia_selection == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_pbr_type");
+ channel_to_edit = (LLRender::eTexIndex)radio_mat_type->getSelectedIndex();
+ }
+ }
channel_to_edit = (channel_to_edit == LLRender::NORMAL_MAP) ? (getCurrentNormalMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
channel_to_edit = (channel_to_edit == LLRender::SPECULAR_MAP) ? (getCurrentSpecularMap().isNull() ? LLRender::DIFFUSE_MAP : channel_to_edit) : channel_to_edit;
return channel_to_edit;
}
+LLRender::eTexIndex LLPanelFace::getTextureDropChannel()
+{
+ if (mComboMatMedia && mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ return LLRender::eTexIndex(radio_mat_type->getSelectedIndex());
+ }
+
+ return LLRender::eTexIndex(MATTYPE_DIFFUSE);
+}
+
// Things the UI provides...
//
LLUUID LLPanelFace::getCurrentNormalMap() { return getChild<LLTextureCtrl>("bumpytexture control")->getImageAssetID(); }
@@ -167,8 +281,20 @@ BOOL LLPanelFace::postBuild()
childSetCommitCallback("add_media", &LLPanelFace::onClickBtnAddMedia, this);
childSetCommitCallback("delete_media", &LLPanelFace::onClickBtnDeleteMedia, this);
+ getChild<LLUICtrl>("gltfTextureScaleU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleU, this, _1), nullptr);
+ getChild<LLUICtrl>("gltfTextureScaleV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureScaleV, this, _1), nullptr);
+ getChild<LLUICtrl>("gltfTextureRotation")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFRotation, this, _1), nullptr);
+ getChild<LLUICtrl>("gltfTextureOffsetU")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetU, this, _1), nullptr);
+ getChild<LLUICtrl>("gltfTextureOffsetV")->setCommitCallback(boost::bind(&LLPanelFace::onCommitGLTFTextureOffsetV, this, _1), nullptr);
+
+ LLGLTFMaterialList::addSelectionUpdateCallback(&LLPanelFace::onMaterialOverrideReceived);
+ sMaterialOverrideSelection.connect();
+
childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
childSetAction("button align textures", &LLPanelFace::onAlignTexture, this);
+ childSetAction("pbr_from_inventory", &LLPanelFace::onClickBtnLoadInvPBR, this);
+ childSetAction("edit_selected_pbr", &LLPanelFace::onClickBtnEditPBR, this);
+ childSetAction("save_selected_pbr", &LLPanelFace::onClickBtnSavePBR, this);
LLTextureCtrl* mTextureCtrl;
LLTextureCtrl* mShinyTextureCtrl;
@@ -187,6 +313,26 @@ BOOL LLPanelFace::postBuild()
setMouseOpaque(FALSE);
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setDefaultImageAssetID(LLUUID::null);
+ pbr_ctrl->setBlankImageAssetID(LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID);
+ pbr_ctrl->setCommitCallback(boost::bind(&LLPanelFace::onCommitPbr, this, _2));
+ pbr_ctrl->setOnCancelCallback(boost::bind(&LLPanelFace::onCancelPbr, this, _2));
+ pbr_ctrl->setOnSelectCallback(boost::bind(&LLPanelFace::onSelectPbr, this, _2));
+ pbr_ctrl->setDragCallback(boost::bind(&LLPanelFace::onDragPbr, this, _2));
+ pbr_ctrl->setOnTextureSelectedCallback(boost::bind(&LLPanelFace::onPbrSelectionChanged, this, _1));
+ pbr_ctrl->setOnCloseCallback(boost::bind(&LLPanelFace::onCloseTexturePicker, this, _2));
+
+ pbr_ctrl->setFollowsTop();
+ pbr_ctrl->setFollowsLeft();
+ pbr_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ pbr_ctrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ pbr_ctrl->setBakeTextureEnabled(false);
+ pbr_ctrl->setInventoryPickType(LLTextureCtrl::PICK_MATERIAL);
+ }
+
mTextureCtrl = getChild<LLTextureCtrl>("texture control");
if(mTextureCtrl)
{
@@ -290,20 +436,27 @@ BOOL LLPanelFace::postBuild()
mComboTexGen->setFollows(FOLLOWS_LEFT | FOLLOWS_TOP);
}
- mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
+ mComboMatMedia = getChild<LLComboBox>("combobox matmedia");
if(mComboMatMedia)
{
- mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
- mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ mComboMatMedia->setCommitCallback(LLPanelFace::onCommitMaterialsMedia,this);
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
}
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
if(radio_mat_type)
{
radio_mat_type->setCommitCallback(LLPanelFace::onCommitMaterialType, this);
radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
}
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type)
+ {
+ radio_pbr_type->setCommitCallback(LLPanelFace::onCommitPbrType, this);
+ radio_pbr_type->selectNthItem(PBRTYPE_RENDER_MATERIAL_ID);
+ }
+
mCtrlGlow = getChild<LLSpinCtrl>("glow");
if(mCtrlGlow)
{
@@ -339,6 +492,15 @@ LLPanelFace::~LLPanelFace()
unloadMedia();
}
+void LLPanelFace::onVisibilityChange(BOOL new_visibility)
+{
+ if (new_visibility)
+ {
+ gAgent.showLatestFeatureNotification("gltf");
+ }
+ LLPanel::onVisibilityChange(new_visibility);
+}
+
void LLPanelFace::draw()
{
updateCopyTexButton();
@@ -349,6 +511,12 @@ void LLPanelFace::draw()
updateMediaTitle();
LLPanel::draw();
+
+ if (sMaterialOverrideSelection.update())
+ {
+ setMaterialOverridesFromSelection();
+ LLMaterialEditor::updateLive();
+ }
}
void LLPanelFace::sendTexture()
@@ -364,7 +532,11 @@ void LLPanelFace::sendTexture()
{
id = mTextureCtrl->getImageAssetID();
}
- LLSelectMgr::getInstance()->selectionSetImage(id);
+ if (!LLSelectMgr::getInstance()->selectionSetImage(id))
+ {
+ // need to refresh value in texture ctrl
+ refresh();
+ }
}
}
@@ -474,9 +646,11 @@ struct LLPanelFaceSetTEFunctor : public LLSelectedTEFunctor
{
BOOL valid;
F32 value;
+ std::string prefix;
+ // Effectively the same as MATMEDIA_PBR sans using different radio,
+ // separate for the sake of clarity
LLRadioGroup * radio_mat_type = mPanel->getChild<LLRadioGroup>("radio_material_type");
- std::string prefix;
switch (radio_mat_type->getSelectedIndex())
{
case MATTYPE_DIFFUSE:
@@ -829,61 +1003,121 @@ void LLPanelFace::getState()
void LLPanelFace::updateUI(bool force_set_values /*false*/)
{ //set state of UI to match state of texture entry(ies) (calls setEnabled, setValue, etc, but NOT setVisible)
- LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ LLViewerObject* objectp = node ? node->getObject() : NULL;
if (objectp
&& objectp->getPCode() == LL_PCODE_VOLUME
&& objectp->permModify())
{
BOOL editable = objectp->permModify() && !objectp->isPermanentEnforced();
+ BOOL attachment = objectp->isAttachment();
+
+ bool has_pbr_material;
+ bool has_faces_without_pbr;
+ updateUIGLTF(objectp, has_pbr_material, has_faces_without_pbr, force_set_values);
+
+ const bool has_material = !has_pbr_material;
// only turn on auto-adjust button if there is a media renderer and the media is loaded
childSetEnabled("button align", editable);
- if (mComboMatMedia)
- {
- if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
- {
+ if (mComboMatMedia->getCurrentIndex() < MATMEDIA_MATERIAL)
+ {
+ // When selecting an object with a pbr and UI combo is not set,
+ // set to pbr option, otherwise to a texture (material)
+ if (has_pbr_material)
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_PBR);
+ }
+ else
+ {
mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
- }
- mComboMatMedia->setEnabled(editable);
- }
- else
- {
- LL_WARNS() << "failed getChild for 'combobox matmedia'" << LL_ENDL;
- }
+ }
+ }
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- if (radio_mat_type)
- {
- if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
- {
- radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
- }
- }
- else
- {
- LL_WARNS("Materials") << "failed getChild for 'radio_material_type'" << LL_ENDL;
- }
+ // *NOTE: The "identical" variable is currently only used to decide if
+ // the texgen control should be tentative - this is not used by GLTF
+ // materials. -Cosmic;2022-11-09
+ bool identical = true; // true because it is anded below
+ bool identical_diffuse = false;
+ bool identical_norm = false;
+ bool identical_spec = false;
+
+ LLTextureCtrl *texture_ctrl = getChild<LLTextureCtrl>("texture control");
+ LLTextureCtrl *shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
+ LLTextureCtrl *bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
+
+ LLUUID id;
+ LLUUID normmap_id;
+ LLUUID specmap_id;
+
+ LLSelectedTE::getTexId(id, identical_diffuse);
+ LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm);
+ LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
+
+ static S32 selected_te = -1;
+ static LLUUID prev_obj_id;
+ if ((LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()) &&
+ !LLSelectMgr::getInstance()->getSelection()->isMultipleTESelected())
+ {
+ S32 new_selection = -1; // Don't use getLastSelectedTE, it could have been deselected
+ S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces());
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ new_selection = te;
+ break;
+ }
+ }
+
+ if ((new_selection != selected_te)
+ || (prev_obj_id != objectp->getID()))
+ {
+ bool te_has_media = objectp->getTE(new_selection) && objectp->getTE(new_selection)->hasMedia();
+ bool te_has_pbr = objectp->getRenderMaterialID(new_selection).notNull();
+
+ if (te_has_pbr && !((mComboMatMedia->getCurrentIndex() == MATMEDIA_MEDIA) && te_has_media))
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_PBR);
+ }
+ else if (te_has_media)
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_MEDIA);
+ }
+ else if (id.notNull() || normmap_id.notNull() || specmap_id.notNull())
+ {
+ mComboMatMedia->selectNthItem(MATMEDIA_MATERIAL);
+ }
+ selected_te = new_selection;
+ prev_obj_id = objectp->getID();
+ }
+ }
+
+ mComboMatMedia->setEnabled(editable);
+
+ LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
+ if (radio_mat_type->getSelectedIndex() < MATTYPE_DIFFUSE)
+ {
+ radio_mat_type->selectNthItem(MATTYPE_DIFFUSE);
+ }
+ radio_mat_type->setEnabled(editable);
+
+ LLRadioGroup* radio_pbr_type = getChild<LLRadioGroup>("radio_pbr_type");
+ if (radio_pbr_type->getSelectedIndex() < PBRTYPE_RENDER_MATERIAL_ID)
+ {
+ radio_pbr_type->selectNthItem(PBRTYPE_RENDER_MATERIAL_ID);
+ }
+ radio_pbr_type->setEnabled(editable);
+ const bool pbr_selected = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR;
+ const bool texture_info_selected = pbr_selected && radio_pbr_type->getSelectedIndex() != PBRTYPE_RENDER_MATERIAL_ID;
- getChildView("radio_material_type")->setEnabled(editable);
getChildView("checkbox_sync_settings")->setEnabled(editable);
childSetValue("checkbox_sync_settings", gSavedSettings.getBOOL("SyncMaterialSettings"));
- updateVisibility();
- bool identical = true; // true because it is anded below
- bool identical_diffuse = false;
- bool identical_norm = false;
- bool identical_spec = false;
+ updateVisibility(objectp);
- LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
- LLTextureCtrl* shinytexture_ctrl = getChild<LLTextureCtrl>("shinytexture control");
- LLTextureCtrl* bumpytexture_ctrl = getChild<LLTextureCtrl>("bumpytexture control");
-
- LLUUID id;
- LLUUID normmap_id;
- LLUUID specmap_id;
-
// Color swatch
{
getChildView("color label")->setEnabled(editable);
@@ -901,9 +1135,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
color_swatch->setOriginal(color);
color_swatch->set(color, force_set_values || (prev_color != color) || !editable);
- color_swatch->setValid(editable);
- color_swatch->setEnabled( editable );
- color_swatch->setCanApplyImmediately( editable );
+ color_swatch->setValid(editable && !has_pbr_material);
+ color_swatch->setEnabled( editable && !has_pbr_material);
+ color_swatch->setCanApplyImmediately( editable && !has_pbr_material);
}
// Color transparency
@@ -911,11 +1145,8 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
F32 transparency = (1.f - color.mV[VALPHA]) * 100.f;
getChild<LLUICtrl>("ColorTrans")->setValue(editable ? transparency : 0);
- getChildView("ColorTrans")->setEnabled(editable);
+ getChildView("ColorTrans")->setEnabled(editable && has_material);
- // Specular map
- LLSelectedTEMaterial::getSpecularID(specmap_id, identical_spec);
-
U8 shiny = 0;
bool identical_shiny = false;
@@ -981,11 +1212,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
// Texture
{
- LLSelectedTE::getTexId(id,identical_diffuse);
-
- // Normal map
- LLSelectedTEMaterial::getNormalID(normmap_id, identical_norm);
-
mIsAlpha = FALSE;
LLGLenum image_format = GL_RGB;
bool identical_image_format = false;
@@ -1050,12 +1276,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
if (identical_diffuse)
{
texture_ctrl->setTentative(FALSE);
- texture_ctrl->setEnabled(editable);
+ texture_ctrl->setEnabled(editable && !has_pbr_material);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
@@ -1076,29 +1302,59 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
{
// Tentative: multiple selected with different textures
texture_ctrl->setTentative(TRUE);
- texture_ctrl->setEnabled(editable);
+ texture_ctrl->setEnabled(editable && !has_pbr_material);
texture_ctrl->setImageAssetID(id);
- getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f);
- getChildView("label alphamode")->setEnabled(editable && mIsAlpha);
- getChildView("maskcutoff")->setEnabled(editable && mIsAlpha);
- getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha);
+ getChildView("combobox alphamode")->setEnabled(editable && mIsAlpha && transparency <= 0.f && !has_pbr_material);
+ getChildView("label alphamode")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
+ getChildView("label maskcutoff")->setEnabled(editable && mIsAlpha && !has_pbr_material);
texture_ctrl->setBakeTextureEnabled(TRUE);
}
+
+ if (attachment)
+ {
+ // attachments are in world and in inventory,
+ // server doesn't support changing permissions
+ // in such case
+ texture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ texture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
if (shinytexture_ctrl)
{
shinytexture_ctrl->setTentative( !identical_spec );
- shinytexture_ctrl->setEnabled( editable );
+ shinytexture_ctrl->setEnabled( editable && !has_pbr_material);
shinytexture_ctrl->setImageAssetID( specmap_id );
+
+ if (attachment)
+ {
+ shinytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ shinytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
if (bumpytexture_ctrl)
{
bumpytexture_ctrl->setTentative( !identical_norm );
- bumpytexture_ctrl->setEnabled( editable );
+ bumpytexture_ctrl->setEnabled( editable && !has_pbr_material);
bumpytexture_ctrl->setImageAssetID( normmap_id );
+
+ if (attachment)
+ {
+ bumpytexture_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ bumpytexture_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
}
@@ -1109,9 +1365,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLCheckBoxCtrl* cb_planar_align = getChild<LLCheckBoxCtrl>("checkbox planar align");
align_planar = (cb_planar_align && cb_planar_align->get());
- bool enabled = (editable && isIdenticalPlanarTexgen());
+ bool enabled = (editable && isIdenticalPlanarTexgen() && !texture_info_selected);
childSetValue("checkbox planar align", align_planar && enabled);
- childSetVisible("checkbox planar align", enabled);
+ childSetVisible("checkbox planar align", enabled);
childSetEnabled("checkbox planar align", enabled);
childSetEnabled("button align textures", enabled && LLSelectMgr::getInstance()->getSelection()->getObjectCount() > 1);
@@ -1169,9 +1425,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyScaleU")->setValue(spec_scale_s);
getChild<LLUICtrl>("bumpyScaleU")->setValue(norm_scale_s);
- getChildView("TexScaleU")->setEnabled(editable);
- getChildView("shinyScaleU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleU")->setEnabled(editable && normmap_id.notNull());
+ getChildView("TexScaleU")->setEnabled(editable && has_material);
+ getChildView("shinyScaleU")->setEnabled(editable && has_material && specmap_id.notNull());
+ getChildView("bumpyScaleU")->setEnabled(editable && has_material && normmap_id.notNull());
BOOL diff_scale_tentative = !(identical && identical_diff_scale_s);
BOOL norm_scale_tentative = !(identical && identical_norm_scale_s);
@@ -1208,9 +1464,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
BOOL norm_scale_tentative = !identical_norm_scale_t;
BOOL spec_scale_tentative = !identical_spec_scale_t;
- getChildView("TexScaleV")->setEnabled(editable);
- getChildView("shinyScaleV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyScaleV")->setEnabled(editable && normmap_id.notNull());
+ getChildView("TexScaleV")->setEnabled(editable && has_material);
+ getChildView("shinyScaleV")->setEnabled(editable && has_material && specmap_id.notNull());
+ getChildView("bumpyScaleV")->setEnabled(editable && has_material && normmap_id.notNull());
if (force_set_values)
{
@@ -1254,9 +1510,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetU")->setTentative(LLSD(norm_offset_u_tentative));
getChild<LLUICtrl>("bumpyOffsetU")->setTentative(LLSD(spec_offset_u_tentative));
- getChildView("TexOffsetU")->setEnabled(editable);
- getChildView("shinyOffsetU")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetU")->setEnabled(editable && normmap_id.notNull());
+ getChildView("TexOffsetU")->setEnabled(editable && has_material);
+ getChildView("shinyOffsetU")->setEnabled(editable && has_material && specmap_id.notNull());
+ getChildView("bumpyOffsetU")->setEnabled(editable && has_material && normmap_id.notNull());
}
{
@@ -1284,9 +1540,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChild<LLUICtrl>("shinyOffsetV")->setTentative(LLSD(norm_offset_v_tentative));
getChild<LLUICtrl>("bumpyOffsetV")->setTentative(LLSD(spec_offset_v_tentative));
- getChildView("TexOffsetV")->setEnabled(editable);
- getChildView("shinyOffsetV")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyOffsetV")->setEnabled(editable && normmap_id.notNull());
+ getChildView("TexOffsetV")->setEnabled(editable && has_material);
+ getChildView("shinyOffsetV")->setEnabled(editable && has_material && specmap_id.notNull());
+ getChildView("bumpyOffsetV")->setEnabled(editable && has_material && normmap_id.notNull());
}
// Texture rotation
@@ -1310,10 +1566,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
F32 diff_rot_deg = diff_rotation * RAD_TO_DEG;
F32 norm_rot_deg = norm_rotation * RAD_TO_DEG;
F32 spec_rot_deg = spec_rotation * RAD_TO_DEG;
-
- getChildView("TexRot")->setEnabled(editable);
- getChildView("shinyRot")->setEnabled(editable && specmap_id.notNull());
- getChildView("bumpyRot")->setEnabled(editable && normmap_id.notNull());
+
+ getChildView("TexRot")->setEnabled(editable && has_material);
+ getChildView("shinyRot")->setEnabled(editable && has_material && specmap_id.notNull());
+ getChildView("bumpyRot")->setEnabled(editable && has_material && normmap_id.notNull());
getChild<LLUICtrl>("TexRot")->setTentative(diff_rot_tentative);
getChild<LLUICtrl>("shinyRot")->setTentative(LLSD(norm_rot_tentative));
@@ -1358,8 +1614,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLSelectedTE::getFullbright(fullbright_flag,identical_fullbright);
getChild<LLUICtrl>("checkbox fullbright")->setValue((S32)(fullbright_flag != 0));
- getChildView("checkbox fullbright")->setEnabled(editable);
+ getChildView("checkbox fullbright")->setEnabled(editable && !has_pbr_material);
getChild<LLUICtrl>("checkbox fullbright")->setTentative(!identical_fullbright);
+ mComboMatMedia->setEnabledByValue("Materials", !has_pbr_material);
}
// Repeats per meter
@@ -1380,44 +1637,61 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
if (mComboTexGen)
{
S32 index = mComboTexGen ? mComboTexGen->getCurrentIndex() : 0;
- BOOL enabled = editable && (index != 1);
- BOOL identical_repeats = true;
+ bool enabled = editable && (index != 1);
+ bool identical_repeats = true;
+ S32 material_selection = mComboMatMedia->getCurrentIndex();
F32 repeats = 1.0f;
- U32 material_type = (mComboMatMedia->getCurrentIndex() == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : MATTYPE_DIFFUSE;
- LLSelectMgr::getInstance()->setTextureChannel(LLRender::eTexIndex(material_type));
+ U32 material_type = MATTYPE_DIFFUSE;
+ if (material_selection == MATMEDIA_MATERIAL)
+ {
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ else if (material_selection == MATMEDIA_PBR)
+ {
+ enabled = editable && has_pbr_material;
+ material_type = radio_pbr_type->getSelectedIndex();
+ }
- switch (material_type)
- {
- default:
- case MATTYPE_DIFFUSE:
- {
- enabled = editable && !id.isNull();
- identical_repeats = identical_diff_repeats;
- repeats = repeats_diff;
- }
- break;
+ switch (material_type)
+ {
+ default:
+ case MATTYPE_DIFFUSE:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = editable && !id.isNull();
+ }
+ identical_repeats = identical_diff_repeats;
+ repeats = repeats_diff;
+ }
+ break;
- case MATTYPE_SPECULAR:
- {
- enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
- identical_repeats = identical_spec_repeats;
- repeats = repeats_spec;
- }
- break;
+ case MATTYPE_SPECULAR:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((shiny == SHINY_TEXTURE) && !specmap_id.isNull()));
+ }
+ identical_repeats = identical_spec_repeats;
+ repeats = repeats_spec;
+ }
+ break;
- case MATTYPE_NORMAL:
- {
- enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
- identical_repeats = identical_norm_repeats;
- repeats = repeats_norm;
- }
- break;
- }
+ case MATTYPE_NORMAL:
+ {
+ if (material_selection != MATMEDIA_PBR)
+ {
+ enabled = (editable && ((bumpy == BUMPY_TEXTURE) && !normmap_id.isNull()));
+ }
+ identical_repeats = identical_norm_repeats;
+ repeats = repeats_norm;
+ }
+ break;
+ }
BOOL repeats_tentative = !identical_repeats;
- getChildView("rptctrl")->setEnabled(identical_planar_texgen ? FALSE : enabled);
LLSpinCtrl* rpt_ctrl = getChild<LLSpinCtrl>("rptctrl");
if (force_set_values)
{
@@ -1429,6 +1703,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
rpt_ctrl->setValue(editable ? repeats : 1.0f);
}
rpt_ctrl->setTentative(LLSD(repeats_tentative));
+ rpt_ctrl->setEnabled(has_material && !identical_planar_texgen && enabled);
}
}
@@ -1437,7 +1712,7 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
LLMaterialPtr material;
LLSelectedTEMaterial::getCurrent(material, identical);
- if (material && editable)
+ if (material && editable)
{
LL_DEBUGS("Materials") << material->asLLSD() << LL_ENDL;
@@ -1556,6 +1831,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
clearCtrls();
// Disable non-UICtrls
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ pbr_ctrl->setImageAssetID(LLUUID::null);
+ pbr_ctrl->setEnabled(FALSE);
+ }
LLTextureCtrl* texture_ctrl = getChild<LLTextureCtrl>("texture control");
if (texture_ctrl)
{
@@ -1581,8 +1862,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
getChildView("label shininess")->setEnabled(FALSE);
getChildView("label bumpiness")->setEnabled(FALSE);
getChildView("button align")->setEnabled(FALSE);
- //getChildView("has media")->setEnabled(FALSE);
- //getChildView("media info set")->setEnabled(FALSE);
+ getChildView("pbr_from_inventory")->setEnabled(FALSE);
+ getChildView("edit_selected_pbr")->setEnabled(FALSE);
+ getChildView("save_selected_pbr")->setEnabled(FALSE);
updateVisibility();
@@ -1598,13 +1880,147 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/)
}
}
+// One-off listener that updates the build floater UI when the prim inventory updates
+class PBRPickerItemListener : public LLVOInventoryListener
+{
+protected:
+ LLViewerObject* mObjectp;
+ bool mChangePending = true;
+public:
+
+ PBRPickerItemListener(LLViewerObject* object)
+ : mObjectp(object)
+ {
+ registerVOInventoryListener(mObjectp, nullptr);
+ }
+
+ const bool isListeningFor(const LLViewerObject* objectp) const
+ {
+ return mChangePending && (objectp == mObjectp);
+ }
+
+ void inventoryChanged(LLViewerObject* object,
+ LLInventoryObject::object_list_t* inventory,
+ S32 serial_num,
+ void* user_data) override
+ {
+ if (gFloaterTools)
+ {
+ gFloaterTools->dirty();
+ }
+ removeVOInventoryListener();
+ mChangePending = false;
+ }
+
+ ~PBRPickerItemListener()
+ {
+ removeVOInventoryListener();
+ mChangePending = false;
+ }
+};
+
+void LLPanelFace::updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool& has_faces_without_pbr, bool force_set_values)
+{
+ has_pbr_material = false;
+
+ bool has_pbr_capabilities = LLMaterialEditor::capabilitiesAvailable();
+ bool identical_pbr = true;
+ const bool settable = has_pbr_capabilities && objectp->permModify() && !objectp->isPermanentEnforced();
+ const bool editable = LLMaterialEditor::canModifyObjectsMaterial();
+ const bool saveable = LLMaterialEditor::canSaveObjectsMaterial();
+
+ // pbr material
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID pbr_id;
+ LLSelectedTE::getPbrMaterialId(pbr_id, identical_pbr, has_pbr_material, has_faces_without_pbr);
+
+ pbr_ctrl->setTentative(identical_pbr ? FALSE : TRUE);
+ pbr_ctrl->setEnabled(settable);
+ pbr_ctrl->setImageAssetID(pbr_id);
+
+ if (objectp->isAttachment())
+ {
+ pbr_ctrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER | PERM_MODIFY);
+ }
+ else
+ {
+ pbr_ctrl->setImmediateFilterPermMask(PERM_NONE);
+ }
+ }
+
+ getChildView("pbr_from_inventory")->setEnabled(settable);
+ getChildView("edit_selected_pbr")->setEnabled(editable && !has_faces_without_pbr);
+ getChildView("save_selected_pbr")->setEnabled(saveable && identical_pbr);
+ if (objectp->isInventoryPending())
+ {
+ // Reuse the same listener when possible
+ if (!mInventoryListener || !mInventoryListener->isListeningFor(objectp))
+ {
+ mInventoryListener = std::make_unique<PBRPickerItemListener>(objectp);
+ }
+ }
+ else
+ {
+ mInventoryListener = nullptr;
+ }
+
+ const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
+ if (show_pbr)
+ {
+ const bool new_state = has_pbr_capabilities && has_pbr_material && !has_faces_without_pbr;
+
+ LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
+ LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
+ LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation");
+ LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");
+ LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV");
+
+ gltfCtrlTextureScaleU->setEnabled(new_state);
+ gltfCtrlTextureScaleV->setEnabled(new_state);
+ gltfCtrlTextureRotation->setEnabled(new_state);
+ gltfCtrlTextureOffsetU->setEnabled(new_state);
+ gltfCtrlTextureOffsetV->setEnabled(new_state);
+
+ // Control values will be set once per frame in
+ // setMaterialOverridesFromSelection
+ sMaterialOverrideSelection.setDirty();
+ }
+}
+
+void LLPanelFace::updateVisibilityGLTF(LLViewerObject* objectp /*= nullptr */)
+{
+ const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
+ const bool inventory_pending = objectp && objectp->isInventoryPending();
+
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ radio_pbr_type->setVisible(show_pbr);
+
+ const U32 pbr_type = radio_pbr_type->getSelectedIndex();
+ const bool show_pbr_render_material_id = show_pbr && (pbr_type == PBRTYPE_RENDER_MATERIAL_ID);
+
+ getChildView("pbr_control")->setVisible(show_pbr_render_material_id);
+
+ getChildView("pbr_from_inventory")->setVisible(show_pbr_render_material_id);
+ getChildView("edit_selected_pbr")->setVisible(show_pbr_render_material_id && !inventory_pending);
+ getChildView("save_selected_pbr")->setVisible(show_pbr_render_material_id && !inventory_pending);
+ getChildView("material_permissions_loading_label")->setVisible(show_pbr_render_material_id && inventory_pending);
+
+ getChildView("gltfTextureScaleU")->setVisible(show_pbr);
+ getChildView("gltfTextureScaleV")->setVisible(show_pbr);
+ getChildView("gltfTextureRotation")->setVisible(show_pbr);
+ getChildView("gltfTextureOffsetU")->setVisible(show_pbr);
+ getChildView("gltfTextureOffsetV")->setVisible(show_pbr);
+}
void LLPanelFace::updateCopyTexButton()
{
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify()
&& !objectp->isPermanentEnforced() && !objectp->isInventoryPending()
- && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1));
+ && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)
+ && LLMaterialEditor::canClipboardObjectsMaterial());
std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options");
mMenuClipboardTexture->setToolTip(tooltip);
}
@@ -1795,6 +2211,12 @@ void LLPanelFace::unloadMedia()
mTitleMedia->unloadMediaSource();
}
+// static
+void LLPanelFace::onMaterialOverrideReceived(const LLUUID& object_id, S32 side)
+{
+ sMaterialOverrideSelection.onSelectedObjectUpdated(object_id, side);
+}
+
//////////////////////////////////////////////////////////////////////////////
//
void LLPanelFace::navigateToTitleMedia( const std::string url )
@@ -2425,12 +2847,13 @@ void LLPanelFace::onCommitMaterialsMedia(LLUICtrl* ctrl, void* userdata)
self->refreshMedia();
}
-void LLPanelFace::updateVisibility()
-{
- LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
- LLComboBox* combo_shininess = getChild<LLComboBox>("combobox shininess");
- LLComboBox* combo_bumpiness = getChild<LLComboBox>("combobox bumpiness");
- if (!radio_mat_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
+void LLPanelFace::updateVisibility(LLViewerObject* objectp /* = nullptr */)
+{
+ LLRadioGroup* radio_mat_type = findChild<LLRadioGroup>("radio_material_type");
+ LLRadioGroup* radio_pbr_type = findChild<LLRadioGroup>("radio_pbr_type");
+ LLComboBox* combo_shininess = findChild<LLComboBox>("combobox shininess");
+ LLComboBox* combo_bumpiness = findChild<LLComboBox>("combobox bumpiness");
+ if (!radio_mat_type || !radio_pbr_type || !mComboMatMedia || !combo_shininess || !combo_bumpiness)
{
LL_WARNS("Materials") << "Combo box not found...exiting." << LL_ENDL;
return;
@@ -2438,10 +2861,22 @@ void LLPanelFace::updateVisibility()
U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
- bool show_texture = (show_media || ((material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
- bool show_bumpiness = (!show_media) && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
- getChildView("radio_material_type")->setVisible(!show_media);
+ bool show_material = materials_media == MATMEDIA_MATERIAL;
+ bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled()));
+ bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled();
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ const bool show_pbr = mComboMatMedia->getCurrentIndex() == MATMEDIA_PBR && mComboMatMedia->getEnabled();
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
+ const bool show_pbr_asset = show_pbr && texture_info == LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
+
+ radio_mat_type->setVisible(show_material);
+
+ // Shared material controls
+ getChildView("checkbox_sync_settings")->setVisible(show_material || show_media);
+ getChildView("tex gen")->setVisible(show_material || show_media || show_pbr_asset);
+ getChildView("combobox texgen")->setVisible(show_material || show_media || show_pbr_asset);
+ getChildView("button align textures")->setVisible(show_material || show_media);
// Media controls
mTitleMediaText->setVisible(show_media);
@@ -2450,15 +2885,16 @@ void LLPanelFace::updateVisibility()
getChildView("button align")->setVisible(show_media);
// Diffuse texture controls
- getChildView("texture control")->setVisible(show_texture && !show_media);
- getChildView("label alphamode")->setVisible(show_texture && !show_media);
- getChildView("combobox alphamode")->setVisible(show_texture && !show_media);
+ getChildView("texture control")->setVisible(show_texture && show_material);
+ getChildView("label alphamode")->setVisible(show_texture && show_material);
+ getChildView("combobox alphamode")->setVisible(show_texture && show_material);
getChildView("label maskcutoff")->setVisible(false);
getChildView("maskcutoff")->setVisible(false);
- if (show_texture && !show_media)
+ if (show_texture && show_material)
{
updateAlphaControls();
}
+ // texture scale and position controls
getChildView("TexScaleU")->setVisible(show_texture);
getChildView("TexScaleV")->setVisible(show_texture);
getChildView("TexRot")->setVisible(show_texture);
@@ -2499,7 +2935,10 @@ void LLPanelFace::updateVisibility()
getChildView("bumpyOffsetU")->setVisible(show_bumpiness);
getChildView("bumpyOffsetV")->setVisible(show_bumpiness);
+ getChild<LLSpinCtrl>("rptctrl")->setVisible(show_material || show_media);
+ // PBR controls
+ updateVisibilityGLTF(objectp);
}
// static
@@ -2515,6 +2954,16 @@ void LLPanelFace::onCommitMaterialType(LLUICtrl* ctrl, void* userdata)
}
// static
+void LLPanelFace::onCommitPbrType(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ // Force to default states to side-step problems with menu contents
+ // and generally reflecting old state when switching tabs or objects
+ //
+ self->updateUI();
+}
+
+// static
void LLPanelFace::onCommitBump(LLUICtrl* ctrl, void* userdata)
{
LLPanelFace* self = (LLPanelFace*) userdata;
@@ -2579,8 +3028,8 @@ void LLPanelFace::updateShinyControls(bool is_setting_texture, bool mess_with_sh
LLRadioGroup* radio_mat_type = getChild<LLRadioGroup>("radio_material_type");
U32 materials_media = mComboMatMedia->getCurrentIndex();
U32 material_type = radio_mat_type->getSelectedIndex();
- bool show_media = (materials_media == MATMEDIA_MEDIA) && mComboMatMedia->getEnabled();
- bool show_shininess = (!show_media) && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
+ bool show_material = (materials_media == MATMEDIA_MATERIAL);
+ bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled();
U32 shiny_value = comboShiny->getCurrentIndex();
bool show_shinyctrls = (shiny_value == SHINY_TEXTURE) && show_shininess; // Use texture
getChildView("label glossiness")->setVisible(show_shinyctrls);
@@ -2697,21 +3146,87 @@ void LLPanelFace::onCommitGlow(LLUICtrl* ctrl, void* userdata)
}
// static
+BOOL LLPanelFace::onDragPbr(LLUICtrl*, LLInventoryItem* item)
+{
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
+}
+
+void LLPanelFace::onCommitPbr(const LLSD& data)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id))
+ {
+ // If failed to set material, refresh pbr_ctrl's value
+ refresh();
+ }
+ }
+}
+
+void LLPanelFace::onCancelPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->selectionRevertGLTFMaterials();
+}
+
+void LLPanelFace::onSelectPbr(const LLSD& data)
+{
+ LLSelectMgr::getInstance()->saveSelectedObjectTextures();
+
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (!pbr_ctrl) return;
+ if (!pbr_ctrl->getTentative())
+ {
+ // we grab the item id first, because we want to do a
+ // permissions check in the selection manager. ARGH!
+ LLUUID id = pbr_ctrl->getImageItemID();
+ if (id.isNull())
+ {
+ id = pbr_ctrl->getImageAssetID();
+ }
+ if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id))
+ {
+ refresh();
+ }
+ }
+}
+
+// static
BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
{
- BOOL accept = TRUE;
- for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
- iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
- {
- LLSelectNode* node = *iter;
- LLViewerObject* obj = node->getObject();
- if(!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
- {
- accept = FALSE;
- break;
- }
- }
- return accept;
+ BOOL accept = TRUE;
+ for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
+ iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* obj = node->getObject();
+ if (!LLToolDragAndDrop::isInventoryDropAcceptable(obj, item))
+ {
+ accept = FALSE;
+ break;
+ }
+ }
+ return accept;
}
void LLPanelFace::onCommitTexture( const LLSD& data )
@@ -3262,11 +3777,20 @@ void LLPanelFace::onCommitRepeatsPerMeter(LLUICtrl* ctrl, void* userdata)
LLPanelFace* self = (LLPanelFace*) userdata;
LLUICtrl* repeats_ctrl = self->getChild<LLUICtrl>("rptctrl");
- LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
U32 materials_media = self->mComboMatMedia->getCurrentIndex();
+ U32 material_type = 0;
+ if (materials_media == MATMEDIA_PBR)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_pbr_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
+ if (materials_media == MATMEDIA_MATERIAL)
+ {
+ LLRadioGroup* radio_mat_type = self->getChild<LLRadioGroup>("radio_material_type");
+ material_type = radio_mat_type->getSelectedIndex();
+ }
- U32 material_type = (materials_media == MATMEDIA_MATERIAL) ? radio_mat_type->getSelectedIndex() : 0;
F32 repeats_per_meter = repeats_ctrl->getValue().asReal();
F32 obj_scale_s = 1.0f;
@@ -3395,6 +3919,24 @@ void LLPanelFace::onAlignTexture(void* userdata)
self->alignTestureLayer();
}
+void LLPanelFace::onClickBtnLoadInvPBR(void* userdata)
+{
+ // Shouldn't this be "save to inventory?"
+ LLPanelFace* self = (LLPanelFace*)userdata;
+ LLTextureCtrl* pbr_ctrl = self->findChild<LLTextureCtrl>("pbr_control");
+ pbr_ctrl->showPicker(true);
+}
+
+void LLPanelFace::onClickBtnEditPBR(void* userdata)
+{
+ LLMaterialEditor::loadLive();
+}
+
+void LLPanelFace::onClickBtnSavePBR(void* userdata)
+{
+ LLMaterialEditor::saveObjectsMaterialAs();
+}
+
enum EPasteMode
{
PASTE_COLOR,
@@ -3426,10 +3968,14 @@ private:
struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor
{
- LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {}
+ LLPanelFaceUpdateFunctor(bool update_media)
+ : mUpdateMedia(update_media)
+ {}
+
virtual bool apply(LLViewerObject* object)
{
object->sendTEUpdate();
+
if (mUpdateMedia)
{
LLVOVolume *vo = dynamic_cast<LLVOVolume*>(object);
@@ -3646,7 +4192,8 @@ void LLPanelFace::onCopyTexture()
|| objectp->getPCode() != LL_PCODE_VOLUME
|| !objectp->permModify()
|| objectp->isPermanentEnforced()
- || selected_count > 1)
+ || selected_count > 1
+ || !LLMaterialEditor::canClipboardObjectsMaterial())
{
return;
}
@@ -3680,6 +4227,11 @@ void LLPanelFace::onCopyTexture()
te_data["te"]["bumpmap"] = tep->getBumpmap();
te_data["te"]["bumpshiny"] = tep->getBumpShiny();
te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright();
+ te_data["te"]["pbr"] = objectp->getRenderMaterialID(te);
+ if (tep->getGLTFMaterialOverride() != nullptr)
+ {
+ te_data["te"]["pbr_override"] = tep->getGLTFMaterialOverride()->asJSON();
+ }
if (te_data["te"].has("imageid"))
{
@@ -3836,7 +4388,8 @@ void LLPanelFace::onPasteTexture()
|| objectp->getPCode() != LL_PCODE_VOLUME
|| !objectp->permModify()
|| objectp->isPermanentEnforced()
- || selected_count > 1)
+ || selected_count > 1
+ || !LLMaterialEditor::canClipboardObjectsMaterial())
{
// not supposed to happen
LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL;
@@ -3936,6 +4489,8 @@ void LLPanelFace::onPasteTexture()
LLPanelFaceUpdateFunctor sendfunc(true);
selected_objects->applyToObjects(&sendfunc);
+ LLGLTFMaterialList::flushUpdates();
+
LLPanelFaceNavigateHomeFunctor navigate_home_func;
selected_objects->applyToTEs(&navigate_home_func);
}
@@ -4067,6 +4622,38 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te)
{
objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger());
}
+ // PBR/GLTF
+ if (te_data["te"].has("pbr"))
+ {
+ objectp->setRenderMaterialID(te, te_data["te"]["pbr"].asUUID(), false /*managing our own update*/);
+ tep->setGLTFRenderMaterial(nullptr);
+ tep->setGLTFMaterialOverride(nullptr);
+
+ LLSD override_data;
+ override_data["object_id"] = objectp->getID();
+ override_data["side"] = te;
+ if (te_data["te"].has("pbr_override"))
+ {
+ override_data["gltf_json"] = te_data["te"]["pbr_override"];
+ }
+ else
+ {
+ override_data["gltf_json"] = "";
+ }
+
+ override_data["asset_id"] = te_data["te"]["pbr"].asUUID();
+
+ LLGLTFMaterialList::queueUpdate(override_data);
+ }
+ else
+ {
+ objectp->setRenderMaterialID(te, LLUUID::null, false /*send in bulk later*/ );
+ tep->setGLTFRenderMaterial(nullptr);
+ tep->setGLTFMaterialOverride(nullptr);
+
+ // blank out most override data on the server
+ LLGLTFMaterialList::queueApply(objectp, te, LLUUID::null);
+ }
// Texture map
if (te_data["te"].has("scales") && te_data["te"].has("scalet"))
@@ -4208,6 +4795,250 @@ void LLPanelFace::onCommitPlanarAlign(LLUICtrl* ctrl, void* userdata)
self->sendTextureInfo();
}
+void LLPanelFace::updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit)
+{
+ U32 texture_info_start;
+ U32 texture_info_end;
+ const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
+ if (texture_info == LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT)
+ {
+ texture_info_start = 0;
+ texture_info_end = LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT;
+ }
+ else
+ {
+ texture_info_start = texture_info_from_pbrtype(pbr_type);
+ texture_info_end = texture_info_start + 1;
+ }
+ updateSelectedGLTFMaterials([&](LLGLTFMaterial* new_override)
+ {
+ for (U32 ti = texture_info_start; ti < texture_info_end; ++ti)
+ {
+ LLGLTFMaterial::TextureTransform& new_transform = new_override->mTextureTransform[(LLGLTFMaterial::TextureInfo)ti];
+ edit(&new_transform);
+ }
+ });
+}
+
+void LLPanelFace::setMaterialOverridesFromSelection()
+{
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ const LLGLTFMaterial::TextureInfo texture_info = texture_info_from_pbrtype(pbr_type);
+ U32 texture_info_start;
+ U32 texture_info_end;
+ if (texture_info == LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT)
+ {
+ texture_info_start = 0;
+ texture_info_end = LLGLTFMaterial::TextureInfo::GLTF_TEXTURE_INFO_COUNT;
+ }
+ else
+ {
+ texture_info_start = texture_info;
+ texture_info_end = texture_info + 1;
+ }
+
+ bool read_transform = true;
+ LLGLTFMaterial::TextureTransform transform;
+ bool scale_u_same = true;
+ bool scale_v_same = true;
+ bool rotation_same = true;
+ bool offset_u_same = true;
+ bool offset_v_same = true;
+
+ for (U32 i = texture_info_start; i < texture_info_end; ++i)
+ {
+ LLGLTFMaterial::TextureTransform this_transform;
+ bool this_scale_u_same = true;
+ bool this_scale_v_same = true;
+ bool this_rotation_same = true;
+ bool this_offset_u_same = true;
+ bool this_offset_v_same = true;
+
+ readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
+ {
+ return mat ? mat->mTextureTransform[i].mScale[VX] : 0.f;
+ }, this_transform.mScale[VX], this_scale_u_same, true, 1e-3f);
+ readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
+ {
+ return mat ? mat->mTextureTransform[i].mScale[VY] : 0.f;
+ }, this_transform.mScale[VY], this_scale_v_same, true, 1e-3f);
+ readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
+ {
+ return mat ? mat->mTextureTransform[i].mRotation : 0.f;
+ }, this_transform.mRotation, this_rotation_same, true, 1e-3f);
+ readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
+ {
+ return mat ? mat->mTextureTransform[i].mOffset[VX] : 0.f;
+ }, this_transform.mOffset[VX], this_offset_u_same, true, 1e-3f);
+ readSelectedGLTFMaterial<float>([&](const LLGLTFMaterial* mat)
+ {
+ return mat ? mat->mTextureTransform[i].mOffset[VY] : 0.f;
+ }, this_transform.mOffset[VY], this_offset_v_same, true, 1e-3f);
+
+ scale_u_same = scale_u_same && this_scale_u_same;
+ scale_v_same = scale_v_same && this_scale_v_same;
+ rotation_same = rotation_same && this_rotation_same;
+ offset_u_same = offset_u_same && this_offset_u_same;
+ offset_v_same = offset_v_same && this_offset_v_same;
+
+ if (read_transform)
+ {
+ read_transform = false;
+ transform = this_transform;
+ }
+ else
+ {
+ scale_u_same = scale_u_same && (this_transform.mScale[VX] == transform.mScale[VX]);
+ scale_v_same = scale_v_same && (this_transform.mScale[VY] == transform.mScale[VY]);
+ rotation_same = rotation_same && (this_transform.mRotation == transform.mRotation);
+ offset_u_same = offset_u_same && (this_transform.mOffset[VX] == transform.mOffset[VX]);
+ offset_v_same = offset_v_same && (this_transform.mOffset[VY] == transform.mOffset[VY]);
+ }
+ }
+
+ LLUICtrl* gltfCtrlTextureScaleU = getChild<LLUICtrl>("gltfTextureScaleU");
+ LLUICtrl* gltfCtrlTextureScaleV = getChild<LLUICtrl>("gltfTextureScaleV");
+ LLUICtrl* gltfCtrlTextureRotation = getChild<LLUICtrl>("gltfTextureRotation");
+ LLUICtrl* gltfCtrlTextureOffsetU = getChild<LLUICtrl>("gltfTextureOffsetU");
+ LLUICtrl* gltfCtrlTextureOffsetV = getChild<LLUICtrl>("gltfTextureOffsetV");
+
+ gltfCtrlTextureScaleU->setValue(transform.mScale[VX]);
+ gltfCtrlTextureScaleV->setValue(transform.mScale[VY]);
+ gltfCtrlTextureRotation->setValue(transform.mRotation * RAD_TO_DEG);
+ gltfCtrlTextureOffsetU->setValue(transform.mOffset[VX]);
+ gltfCtrlTextureOffsetV->setValue(transform.mOffset[VY]);
+
+ gltfCtrlTextureScaleU->setTentative(!scale_u_same);
+ gltfCtrlTextureScaleV->setTentative(!scale_v_same);
+ gltfCtrlTextureRotation->setTentative(!rotation_same);
+ gltfCtrlTextureOffsetU->setTentative(!offset_u_same);
+ gltfCtrlTextureOffsetV->setTentative(!offset_v_same);
+}
+
+void LLPanelFace::Selection::connect()
+{
+ if (!mSelectConnection.connected())
+ {
+ mSelectConnection = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLPanelFace::Selection::onSelectionChanged, this));
+ }
+}
+
+bool LLPanelFace::Selection::update()
+{
+ const bool changed = mChanged || compareSelection();
+ mChanged = false;
+ return changed;
+}
+
+void LLPanelFace::Selection::onSelectedObjectUpdated(const LLUUID& object_id, S32 side)
+{
+ if (object_id == mSelectedObjectID)
+ {
+ if (side == mLastSelectedSide)
+ {
+ mChanged = true;
+ }
+ else if (mLastSelectedSide == -1) // if last selected face was deselected
+ {
+ LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
+ if (node && node->isTESelected(side))
+ {
+ mChanged = true;
+ }
+ }
+ }
+}
+
+bool LLPanelFace::Selection::compareSelection()
+{
+ if (!mNeedsSelectionCheck)
+ {
+ return false;
+ }
+ mNeedsSelectionCheck = false;
+
+ const S32 old_object_count = mSelectedObjectCount;
+ const S32 old_te_count = mSelectedTECount;
+ const LLUUID old_object_id = mSelectedObjectID;
+ const S32 old_side = mLastSelectedSide;
+
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ LLSelectNode* node = selection->getFirstNode();
+ if (node)
+ {
+ LLViewerObject* object = node->getObject();
+ mSelectedObjectCount = selection->getObjectCount();
+ mSelectedTECount = selection->getTECount();
+ mSelectedObjectID = object->getID();
+ mLastSelectedSide = node->getLastSelectedTE();
+ }
+ else
+ {
+ mSelectedObjectCount = 0;
+ mSelectedTECount = 0;
+ mSelectedObjectID = LLUUID::null;
+ mLastSelectedSide = -1;
+ }
+
+ const bool selection_changed =
+ old_object_count != mSelectedObjectCount
+ || old_te_count != mSelectedTECount
+ || old_object_id != mSelectedObjectID
+ || old_side != mLastSelectedSide;
+ mChanged = mChanged || selection_changed;
+ return selection_changed;
+}
+
+void LLPanelFace::onCommitGLTFTextureScaleU(LLUICtrl* ctrl)
+{
+ const float value = ctrl->getValue().asReal();
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ updateGLTFTextureTransform(value, pbr_type, [&](LLGLTFMaterial::TextureTransform* new_transform)
+ {
+ new_transform->mScale.mV[VX] = value;
+ });
+}
+
+void LLPanelFace::onCommitGLTFTextureScaleV(LLUICtrl* ctrl)
+{
+ const float value = ctrl->getValue().asReal();
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ updateGLTFTextureTransform(value, pbr_type, [&](LLGLTFMaterial::TextureTransform* new_transform)
+ {
+ new_transform->mScale.mV[VY] = value;
+ });
+}
+
+void LLPanelFace::onCommitGLTFRotation(LLUICtrl* ctrl)
+{
+ const float value = ctrl->getValue().asReal() * DEG_TO_RAD;
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ updateGLTFTextureTransform(value, pbr_type, [&](LLGLTFMaterial::TextureTransform* new_transform)
+ {
+ new_transform->mRotation = value;
+ });
+}
+
+void LLPanelFace::onCommitGLTFTextureOffsetU(LLUICtrl* ctrl)
+{
+ const float value = ctrl->getValue().asReal();
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ updateGLTFTextureTransform(value, pbr_type, [&](LLGLTFMaterial::TextureTransform* new_transform)
+ {
+ new_transform->mOffset.mV[VX] = value;
+ });
+}
+
+void LLPanelFace::onCommitGLTFTextureOffsetV(LLUICtrl* ctrl)
+{
+ const float value = ctrl->getValue().asReal();
+ const U32 pbr_type = findChild<LLRadioGroup>("radio_pbr_type")->getSelectedIndex();
+ updateGLTFTextureTransform(value, pbr_type, [&](LLGLTFMaterial::TextureTransform* new_transform)
+ {
+ new_transform->mOffset.mV[VY] = value;
+ });
+}
+
void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
{
LL_DEBUGS("Materials") << "item asset " << itemp->getAssetUUID() << LL_ENDL;
@@ -4260,6 +5091,40 @@ void LLPanelFace::onTextureSelectionChanged(LLInventoryItem* itemp)
}
}
+void LLPanelFace::onPbrSelectionChanged(LLInventoryItem* itemp)
+{
+ LLTextureCtrl* pbr_ctrl = findChild<LLTextureCtrl>("pbr_control");
+ if (pbr_ctrl)
+ {
+ LLUUID obj_owner_id;
+ std::string obj_owner_name;
+ LLSelectMgr::instance().selectGetOwner(obj_owner_id, obj_owner_name);
+
+ LLSaleInfo sale_info;
+ LLSelectMgr::instance().selectGetSaleInfo(sale_info);
+
+ bool can_copy = itemp->getPermissions().allowCopyBy(gAgentID); // do we have perm to copy this material?
+ bool can_transfer = itemp->getPermissions().allowOperationBy(PERM_TRANSFER, gAgentID); // do we have perm to transfer this material?
+ bool can_modify = itemp->getPermissions().allowOperationBy(PERM_MODIFY, gAgentID); // do we have perm to transfer this material?
+ bool is_object_owner = gAgentID == obj_owner_id; // does object for which we are going to apply material belong to the agent?
+ bool not_for_sale = !sale_info.isForSale(); // is object for which we are going to apply material not for sale?
+
+ if (can_copy && can_transfer && can_modify)
+ {
+ pbr_ctrl->setCanApply(true, true);
+ return;
+ }
+
+ // if material has (no-transfer) attribute it can be applied only for object which we own and is not for sale
+ pbr_ctrl->setCanApply(false, can_transfer ? true : is_object_owner && not_for_sale);
+
+ if (gSavedSettings.getBOOL("TextureLivePreview"))
+ {
+ LLNotificationsUtil::add("LivePreviewUnavailablePBR");
+ }
+ }
+}
+
bool LLPanelFace::isIdenticalPlanarTexgen()
{
LLTextureEntry::e_texgen selected_texgen = LLTextureEntry::TEX_GEN_DEFAULT;
@@ -4339,6 +5204,77 @@ void LLPanelFace::LLSelectedTE::getTexId(LLUUID& id, bool& identical)
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
}
+void LLPanelFace::LLSelectedTE::getPbrMaterialId(LLUUID& id, bool& identical, bool& has_faces_with_pbr, bool& has_faces_without_pbr)
+{
+ struct LLSelectedTEGetmatId : public LLSelectedTEFunctor
+ {
+ LLSelectedTEGetmatId()
+ : mHasFacesWithoutPBR(false)
+ , mHasFacesWithPBR(false)
+ , mIdenticalId(true)
+ , mIdenticalOverride(true)
+ , mInitialized(false)
+ , mMaterialOverride(LLGLTFMaterial::sDefault)
+ {
+ }
+ bool apply(LLViewerObject* object, S32 te_index) override
+ {
+ LLUUID pbr_id = object->getRenderMaterialID(te_index);
+ if (pbr_id.isNull())
+ {
+ mHasFacesWithoutPBR = true;
+ }
+ else
+ {
+ mHasFacesWithPBR = true;
+ }
+ if (mInitialized)
+ {
+ if (mPBRId != pbr_id)
+ {
+ mIdenticalId = false;
+ }
+
+ LLGLTFMaterial* te_override = object->getTE(te_index)->getGLTFMaterialOverride();
+ if (te_override)
+ {
+ LLGLTFMaterial override = *te_override;
+ override.sanitizeAssetMaterial();
+ mIdenticalOverride &= (override == mMaterialOverride);
+ }
+ else
+ {
+ mIdenticalOverride &= (mMaterialOverride == LLGLTFMaterial::sDefault);
+ }
+ }
+ else
+ {
+ mInitialized = true;
+ mPBRId = pbr_id;
+ LLGLTFMaterial* override = object->getTE(te_index)->getGLTFMaterialOverride();
+ if (override)
+ {
+ mMaterialOverride = *override;
+ mMaterialOverride.sanitizeAssetMaterial();
+ }
+ }
+ return true;
+ }
+ bool mHasFacesWithoutPBR;
+ bool mHasFacesWithPBR;
+ bool mIdenticalId;
+ bool mIdenticalOverride;
+ bool mInitialized;
+ LLGLTFMaterial mMaterialOverride;
+ LLUUID mPBRId;
+ } func;
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
+ id = func.mPBRId;
+ identical = func.mIdenticalId && func.mIdenticalOverride;
+ has_faces_with_pbr = func.mHasFacesWithPBR;
+ has_faces_without_pbr = func.mHasFacesWithoutPBR;
+}
+
void LLPanelFace::LLSelectedTEMaterial::getCurrent(LLMaterialPtr& material_ptr, bool& identical_material)
{
struct MaterialFunctor : public LLSelectedTEGetFunctor<LLMaterialPtr>
@@ -4477,3 +5413,4 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic
} max_diff_repeats_func;
identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats );
}
+
diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h
index aaf8eddaf7..d36662c11b 100644
--- a/indra/newview/llpanelface.h
+++ b/indra/newview/llpanelface.h
@@ -29,11 +29,14 @@
#include "v4color.h"
#include "llpanel.h"
+#include "llgltfmaterial.h"
#include "llmaterial.h"
#include "llmaterialmgr.h"
#include "lltextureentry.h"
#include "llselectmgr.h"
+#include <memory>
+
class LLButton;
class LLCheckBoxCtrl;
class LLColorSwatchCtrl;
@@ -50,6 +53,8 @@ class LLMaterialID;
class LLMediaCtrl;
class LLMenuButton;
+class PBRPickerItemListener;
+
// Represents an edit for use in replicating the op across one or more materials in the selection set.
//
// The apply function optionally performs the edit which it implements
@@ -102,6 +107,9 @@ public:
void refreshMedia();
void unloadMedia();
+ static void onMaterialOverrideReceived(const LLUUID& object_id, S32 side);
+
+ /*virtual*/ void onVisibilityChange(BOOL new_visibility);
/*virtual*/ void draw();
LLMaterialPtr createDefaultMaterial(LLMaterialPtr current_material)
@@ -116,6 +124,7 @@ public:
}
LLRender::eTexIndex getTextureChannelToEdit();
+ LLRender::eTexIndex getTextureDropChannel();
protected:
void navigateToTitleMedia(const std::string url);
@@ -139,6 +148,11 @@ protected:
void updateCopyTexButton();
+ void onCommitPbr(const LLSD& data);
+ void onCancelPbr(const LLSD& data);
+ void onSelectPbr(const LLSD& data);
+ static BOOL onDragPbr(LLUICtrl* ctrl, LLInventoryItem* item);
+
// this function is to return TRUE if the drag should succeed.
static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item);
@@ -205,9 +219,11 @@ protected:
static void onCommitMaterialGloss( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialEnv( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialMaskCutoff( LLUICtrl* ctrl, void* userdata);
+ static void onCommitMaterialID( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialsMedia( LLUICtrl* ctrl, void* userdata);
static void onCommitMaterialType( LLUICtrl* ctrl, void* userdata);
+ static void onCommitPbrType(LLUICtrl* ctrl, void* userdata);
static void onClickBtnEditMedia(LLUICtrl* ctrl, void* userdata);
static void onClickBtnDeleteMedia(LLUICtrl* ctrl, void* userdata);
static void onClickBtnAddMedia(LLUICtrl* ctrl, void* userdata);
@@ -219,8 +235,18 @@ protected:
static void onCommitGlow( LLUICtrl* ctrl, void *userdata);
static void onCommitPlanarAlign( LLUICtrl* ctrl, void* userdata);
static void onCommitRepeatsPerMeter( LLUICtrl* ctrl, void* userinfo);
+
+ void onCommitGLTFTextureScaleU(LLUICtrl* ctrl);
+ void onCommitGLTFTextureScaleV(LLUICtrl* ctrl);
+ void onCommitGLTFRotation(LLUICtrl* ctrl);
+ void onCommitGLTFTextureOffsetU(LLUICtrl* ctrl);
+ void onCommitGLTFTextureOffsetV(LLUICtrl* ctrl);
+
static void onClickAutoFix(void*);
static void onAlignTexture(void*);
+ static void onClickBtnLoadInvPBR(void* userdata);
+ static void onClickBtnEditPBR(void* userdata);
+ static void onClickBtnSavePBR(void* userdata);
public: // needs to be accessible to selection manager
void onCopyColor(); // records all selected faces
@@ -271,7 +297,7 @@ private:
//
// Do NOT call updateUI from within this function.
//
- void updateVisibility();
+ void updateVisibility(LLViewerObject* objectp = nullptr);
// Hey look everyone, a type-safe alternative to copy and paste! :)
//
@@ -429,30 +455,61 @@ private:
* all controls of the floater texture picker which allow to apply the texture will be disabled.
*/
void onTextureSelectionChanged(LLInventoryItem* itemp);
+ void onPbrSelectionChanged(LLInventoryItem* itemp);
+
+ void updateUIGLTF(LLViewerObject* objectp, bool& has_pbr_material, bool& has_faces_without_pbr, bool force_set_values);
+ void updateVisibilityGLTF(LLViewerObject* objectp = nullptr);
+
+ void updateSelectedGLTFMaterials(std::function<void(LLGLTFMaterial*)> func);
+ void updateGLTFTextureTransform(float value, U32 pbr_type, std::function<void(LLGLTFMaterial::TextureTransform*)> edit);
+
+ void setMaterialOverridesFromSelection();
LLMenuButton* mMenuClipboardColor;
LLMenuButton* mMenuClipboardTexture;
bool mIsAlpha;
- /* These variables interlock processing of materials updates sent to
- * the sim. mUpdateInFlight is set to flag that an update has been
- * sent to the sim and not acknowledged yet, and cleared when an
- * update is received from the sim. mUpdatePending is set when
- * there's an update in flight and another UI change has been made
- * that needs to be sent as a materials update, and cleared when the
- * update is sent. This prevents the sim from getting spammed with
- * update messages when, for example, the user holds down the
- * up-arrow on a spinner, and avoids running afoul of its throttle.
- */
- bool mUpdateInFlight;
- bool mUpdatePending;
-
LLSD mClipboardParams;
LLSD mMediaSettings;
bool mNeedMediaTitle;
+ class Selection
+ {
+ public:
+ void connect();
+
+ // Returns true if the selected objects or sides have changed since
+ // this was last called, and no object update is pending
+ bool update();
+
+ // Prevents update() returning true until the provided object is
+ // updated. Necessary to prevent controls updating when the mouse is
+ // held down.
+ void setDirty() { mChanged = true; };
+
+ // Callbacks
+ void onSelectionChanged() { mNeedsSelectionCheck = true; }
+ void onSelectedObjectUpdated(const LLUUID &object_id, S32 side);
+
+ protected:
+ bool compareSelection();
+
+ bool mChanged = false;
+
+ boost::signals2::scoped_connection mSelectConnection;
+ bool mNeedsSelectionCheck = true;
+ S32 mSelectedObjectCount = 0;
+ S32 mSelectedTECount = 0;
+ LLUUID mSelectedObjectID;
+ S32 mLastSelectedSide = -1;
+ };
+
+ static Selection sMaterialOverrideSelection;
+
+ std::unique_ptr<PBRPickerItemListener> mInventoryListener;
+
public:
#if defined(DEF_GET_MAT_STATE)
#undef DEF_GET_MAT_STATE
@@ -541,6 +598,7 @@ public:
static void getFace(class LLFace*& face_to_return, bool& identical_face);
static void getImageFormat(LLGLenum& image_format_to_return, bool& identical_face);
static void getTexId(LLUUID& id, bool& identical);
+ static void getPbrMaterialId(LLUUID& id, bool& identical, bool& has_pbr, bool& has_faces_without_pbr);
static void getObjectScaleS(F32& scale_s, bool& identical);
static void getObjectScaleT(F32& scale_t, bool& identical);
static void getMaxDiffuseRepeats(F32& repeats, bool& identical);
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index ab32ea3956..82f880c9ee 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data;
if(gInventory.getItem(inv_item->getUUID())
diff --git a/indra/newview/llpanellandmedia.cpp b/indra/newview/llpanellandmedia.cpp
index e379d67e37..ca252d1455 100644
--- a/indra/newview/llpanellandmedia.cpp
+++ b/indra/newview/llpanellandmedia.cpp
@@ -86,7 +86,6 @@ BOOL LLPanelLandMedia::postBuild()
mMediaTextureCtrl->setAllowNoTexture ( TRUE );
mMediaTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaTextureCtrl->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- mMediaTextureCtrl->setNonImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mMediaAutoScaleCheck = getChild<LLCheckBoxCtrl>("media_auto_scale");
childSetCommitCallback("media_auto_scale", onCommitAny, this);
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 30f301027c..20241aac24 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -134,6 +134,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
mEnableCallbackRegistrar.add("Inventory.EnvironmentEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasSettingsInventory(); });
+ mEnableCallbackRegistrar.add("Inventory.MaterialsEnabled", [](LLUICtrl *, const LLSD &) { return LLPanelMainInventory::hasMaterialsInventory(); });
mSavedFolderState = new LLSaveFolderState();
@@ -1195,6 +1196,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
getChild<LLUICtrl>("check_clothing")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_WEARABLE));
getChild<LLUICtrl>("check_gesture")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_GESTURE));
getChild<LLUICtrl>("check_landmark")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LANDMARK));
+ getChild<LLUICtrl>("check_material")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_MATERIAL));
getChild<LLUICtrl>("check_notecard")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_NOTECARD));
getChild<LLUICtrl>("check_object")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_OBJECT));
getChild<LLUICtrl>("check_script")->setValue((S32) (filter_types & 0x1 << LLInventoryType::IT_LSL));
@@ -1251,6 +1253,12 @@ void LLFloaterInventoryFinder::draw()
filtered_by_all_types = FALSE;
}
+ if (!getChild<LLUICtrl>("check_material")->getValue())
+ {
+ filter &= ~(0x1 << LLInventoryType::IT_MATERIAL);
+ filtered_by_all_types = FALSE;
+ }
+
if (!getChild<LLUICtrl>("check_notecard")->getValue())
{
filter &= ~(0x1 << LLInventoryType::IT_NOTECARD);
@@ -1438,6 +1446,7 @@ void LLFloaterInventoryFinder::selectAllTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(TRUE);
self->getChild<LLUICtrl>("check_gesture")->setValue(TRUE);
self->getChild<LLUICtrl>("check_landmark")->setValue(TRUE);
+ self->getChild<LLUICtrl>("check_material")->setValue(TRUE);
self->getChild<LLUICtrl>("check_notecard")->setValue(TRUE);
self->getChild<LLUICtrl>("check_object")->setValue(TRUE);
self->getChild<LLUICtrl>("check_script")->setValue(TRUE);
@@ -1458,6 +1467,7 @@ void LLFloaterInventoryFinder::selectNoTypes(void* user_data)
self->getChild<LLUICtrl>("check_clothing")->setValue(FALSE);
self->getChild<LLUICtrl>("check_gesture")->setValue(FALSE);
self->getChild<LLUICtrl>("check_landmark")->setValue(FALSE);
+ self->getChild<LLUICtrl>("check_material")->setValue(FALSE);
self->getChild<LLUICtrl>("check_notecard")->setValue(FALSE);
self->getChild<LLUICtrl>("check_object")->setValue(FALSE);
self->getChild<LLUICtrl>("check_script")->setValue(FALSE);
@@ -2283,6 +2293,14 @@ bool LLPanelMainInventory::hasSettingsInventory()
return LLEnvironment::instance().isInventoryEnabled();
}
+bool LLPanelMainInventory::hasMaterialsInventory()
+{
+ std::string agent_url = gAgent.getRegionCapability("UpdateMaterialAgentInventory");
+ std::string task_url = gAgent.getRegionCapability("UpdateMaterialTaskInventory");
+
+ return (!agent_url.empty() && !task_url.empty());
+}
+
void LLPanelMainInventory::updateTitle()
{
LLFloater* inventory_floater = gFloaterView->getParentFloater(this);
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 79501e63bc..fbfca43f64 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -229,6 +229,7 @@ protected:
void onCustomAction(const LLSD& command_name);
bool isActionVisible(const LLSD& userdata);
static bool hasSettingsInventory();
+ static bool hasMaterialsInventory();
void updateTitle();
void updateNavButtons();
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 2da431955f..0704fc881d 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -252,8 +252,6 @@ BOOL LLPanelObject::postBuild()
// Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
mCtrlSculptTexture->setDnDFilterPermMask(PERM_COPY | PERM_TRANSFER);
- // Allow any texture to be used during non-immediate mode.
- mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
LLAggregatePermissions texture_perms;
if (LLSelectMgr::getInstance()->selectGetAggregateTexturePermissions(texture_perms))
{
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index a3bbd00601..f3a41f2e25 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -50,6 +50,7 @@
#include "llinventoryicon.h"
#include "llinventoryfilter.h"
#include "llinventoryfunctions.h"
+#include "llmaterialeditor.h"
#include "llpreviewanim.h"
#include "llpreviewgesture.h"
#include "llpreviewnotecard.h"
@@ -717,6 +718,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop,
case DAD_CALLINGCARD:
case DAD_MESH:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data);
if(accept && drop)
{
@@ -1164,6 +1166,58 @@ LLSettingsType::type_e LLTaskSettingsBridge::getSettingsType() const
}
///----------------------------------------------------------------------------
+/// Class LLTaskMaterialBridge
+///----------------------------------------------------------------------------
+
+class LLTaskMaterialBridge : public LLTaskInvFVBridge
+{
+public:
+ LLTaskMaterialBridge(LLPanelObjectInventory* panel,
+ const LLUUID& uuid,
+ const std::string& name) :
+ LLTaskInvFVBridge(panel, uuid, name) {}
+
+ BOOL canOpenItem() const override { return TRUE; }
+ void openItem() override;
+ BOOL removeItem() override;
+};
+
+void LLTaskMaterialBridge::openItem()
+{
+ LLViewerObject* object = gObjectList.findObject(mPanel->getTaskUUID());
+ if(!object || object->isInventoryPending())
+ {
+ return;
+ }
+
+ // Note: even if we are not allowed to modify copyable notecard, we should be able to view it
+ LLInventoryItem *item = dynamic_cast<LLInventoryItem*>(object->getInventoryObject(mUUID));
+ BOOL item_copy = item && gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
+ if( item_copy
+ || object->permModify()
+ || gAgent.isGodlike())
+ {
+ LLSD floater_key;
+ floater_key["taskid"] = mPanel->getTaskUUID();
+ floater_key["itemid"] = mUUID;
+ LLMaterialEditor* mat = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (mat)
+ {
+ mat->setObjectID(mPanel->getTaskUUID());
+ mat->openFloater(floater_key);
+ mat->setFocus(TRUE);
+ }
+ }
+}
+
+BOOL LLTaskMaterialBridge::removeItem()
+{
+ LLFloaterReg::hideInstance("material_editor", LLSD(mUUID));
+ return LLTaskInvFVBridge::removeItem();
+}
+
+
+///----------------------------------------------------------------------------
/// LLTaskInvFVBridge impl
//----------------------------------------------------------------------------
@@ -1250,6 +1304,11 @@ LLTaskInvFVBridge* LLTaskInvFVBridge::createObjectBridge(LLPanelObjectInventory*
object_name,
itemflags);
break;
+ case LLAssetType::AT_MATERIAL:
+ new_bridge = new LLTaskMaterialBridge(panel,
+ object_id,
+ object_name);
+ break;
default:
LL_INFOS() << "Unhandled inventory type (llassetstorage.h): "
<< (S32)type << LL_ENDL;
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index c2b66e59b5..ffbed778c1 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -1968,13 +1968,12 @@ void LLPanelProfileSecondLife::onShowTexturePicker()
"SELECT PHOTO",
PERM_NONE,
PERM_NONE,
- PERM_NONE,
FALSE,
NULL);
mFloaterTexturePickerHandle = texture_floaterp->getHandle();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
@@ -2304,13 +2303,12 @@ void LLPanelProfileFirstLife::onChangePhoto()
"SELECT PHOTO",
PERM_NONE,
PERM_NONE,
- PERM_NONE,
FALSE,
NULL);
mFloaterTexturePickerHandle = texture_floaterp->getHandle();
- texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&)
+ texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&)
{
if (op == LLTextureCtrl::TEXTURE_SELECT)
{
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 39f4c7485b..d6c36bbfb7 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -48,6 +48,7 @@
#include "lltexturectrl.h"
#include "llcombobox.h"
//#include "llfirstuse.h"
+#include "llfloaterreg.h"
#include "llfocusmgr.h"
#include "llmanipscale.h"
#include "llinventorymodel.h"
@@ -146,6 +147,15 @@ BOOL LLPanelVolume::postBuild()
getChild<LLUICtrl>("Light Ambiance")->setValidateBeforeCommit( precommitValidate);
}
+ // REFLECTION PROBE Parameters
+ {
+ childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this);
+ childSetCommitCallback("Probe Dynamic", onCommitProbe, this);
+ childSetCommitCallback("Probe Volume Type", onCommitProbe, this);
+ childSetCommitCallback("Probe Ambiance", onCommitProbe, this);
+ childSetCommitCallback("Probe Near Clip", onCommitProbe, this);
+ }
+
// PHYSICS Parameters
{
// PhysicsShapeType combobox
@@ -355,6 +365,15 @@ void LLPanelVolume::getState( )
{
LightTextureCtrl->setEnabled(FALSE);
LightTextureCtrl->setValid(FALSE);
+
+ if (objectp->isAttachment())
+ {
+ LightTextureCtrl->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ }
+ else
+ {
+ LightTextureCtrl->setImmediateFilterPermMask(PERM_NONE);
+ }
}
getChildView("Light Intensity")->setEnabled(false);
@@ -366,6 +385,43 @@ void LLPanelVolume::getState( )
getChildView("Light Ambiance")->setEnabled(false);
}
+ // Reflection Probe
+ BOOL is_probe = volobjp && volobjp->isReflectionProbe();
+ getChild<LLUICtrl>("Reflection Probe")->setValue(is_probe);
+ getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp && !volobjp->isMesh());
+
+ bool probe_enabled = is_probe && editable && single_volume;
+
+ getChildView("Probe Dynamic")->setEnabled(probe_enabled);
+ getChildView("Probe Volume Type")->setEnabled(probe_enabled);
+ getChildView("Probe Ambiance")->setEnabled(probe_enabled);
+ getChildView("Probe Near Clip")->setEnabled(probe_enabled);
+
+ if (!probe_enabled)
+ {
+ getChild<LLComboBox>("Probe Volume Type", true)->clear();
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->clear();
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->clear();
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->clear();
+ }
+ else
+ {
+ std::string volume_type;
+ if (volobjp->getReflectionProbeIsBox())
+ {
+ volume_type = "Box";
+ }
+ else
+ {
+ volume_type = "Sphere";
+ }
+
+ getChild<LLComboBox>("Probe Volume Type", true)->setValue(volume_type);
+ getChild<LLSpinCtrl>("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance());
+ getChild<LLSpinCtrl>("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip());
+ getChild<LLCheckBoxCtrl>("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic());
+ }
+
// Animated Mesh
BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject();
getChild<LLUICtrl>("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh);
@@ -648,6 +704,11 @@ void LLPanelVolume::clearCtrls()
getChildView("Light Radius")->setEnabled(false);
getChildView("Light Falloff")->setEnabled(false);
+ getChildView("Reflection Probe")->setEnabled(false);;
+ getChildView("Probe Volume Type")->setEnabled(false);
+ getChildView("Probe Dynamic")->setEnabled(false);
+ getChildView("Probe Ambiance")->setEnabled(false);
+ getChildView("Probe Near Clip")->setEnabled(false);
getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false);
getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false);
getChildView("FlexNumSections")->setEnabled(false);
@@ -685,6 +746,64 @@ void LLPanelVolume::sendIsLight()
LL_INFOS() << "update light sent" << LL_ENDL;
}
+void LLPanelVolume::sendIsReflectionProbe()
+{
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ BOOL value = getChild<LLUICtrl>("Reflection Probe")->getValue();
+ BOOL old_value = volobjp->isReflectionProbe();
+
+ if (value && value != old_value)
+ { // defer to notification util as to whether or not we *really* make this object a reflection probe
+ LLNotificationsUtil::add("ReflectionProbeApplied", LLSD(), LLSD(), boost::bind(&LLPanelVolume::doSendIsReflectionProbe, this, _1, _2));
+ }
+ else
+ {
+ volobjp->setIsReflectionProbe(value);
+ }
+}
+
+void LLPanelVolume::doSendIsReflectionProbe(const LLSD & notification, const LLSD & response)
+{
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ if (option == 0) // YES
+ {
+ LLViewerObject* objectp = mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ volobjp->setIsReflectionProbe(true);
+
+ { // has become a reflection probe, slam to a 10m sphere and pop up a message
+ // warning people about the pitfalls of reflection probes
+
+ auto* select_mgr = LLSelectMgr::getInstance();
+
+ select_mgr->selectionUpdatePhantom(true);
+ select_mgr->selectionSetGLTFMaterial(LLUUID::null);
+ select_mgr->selectionSetAlphaOnly(0.f);
+
+ LLVolumeParams params;
+ params.getPathParams().setCurveType(LL_PCODE_PATH_CIRCLE);
+ params.getProfileParams().setCurveType(LL_PCODE_PROFILE_CIRCLE_HALF);
+ mObject->updateVolume(params);
+ }
+ }
+ else
+ {
+ // cancelled, touch up UI state
+ getChild<LLUICtrl>("Reflection Probe")->setValue(false);
+ }
+}
+
void LLPanelVolume::sendIsFlexible()
{
LLViewerObject* objectp = mObject;
@@ -1026,6 +1145,14 @@ void LLPanelVolume::onCopyLight()
}
}
+ if (volobjp && volobjp->isReflectionProbe())
+ {
+ clipboard["reflection_probe"]["is_box"] = volobjp->getReflectionProbeIsBox();
+ clipboard["reflection_probe"]["ambiance"] = volobjp->getReflectionProbeAmbiance();
+ clipboard["reflection_probe"]["near_clip"] = volobjp->getReflectionProbeNearClip();
+ clipboard["reflection_probe"]["dynamic"] = volobjp->getReflectionProbeIsDynamic();
+ }
+
mClipboardParams["light"] = clipboard;
}
@@ -1073,6 +1200,19 @@ void LLPanelVolume::onPasteLight()
spot_params.mV[2] = (F32)clipboard["spot"]["ambiance"].asReal();
volobjp->setSpotLightParams(spot_params);
}
+
+ if (clipboard.has("reflection_probe"))
+ {
+ volobjp->setIsReflectionProbe(TRUE);
+ volobjp->setReflectionProbeIsBox(clipboard["reflection_probe"]["is_box"].asBoolean());
+ volobjp->setReflectionProbeAmbiance((F32)clipboard["reflection_probe"]["ambiance"].asReal());
+ volobjp->setReflectionProbeNearClip((F32)clipboard["reflection_probe"]["near_clip"].asReal());
+ volobjp->setReflectionProbeIsDynamic(clipboard["reflection_probe"]["dynamic"].asBoolean());
+ }
+ else
+ {
+ volobjp->setIsReflectionProbe(false);
+ }
}
}
@@ -1212,6 +1352,59 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
}
+//static
+void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ LLViewerObject* objectp = self->mObject;
+ if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME))
+ {
+ return;
+ }
+ LLVOVolume* volobjp = (LLVOVolume*)objectp;
+
+ volobjp->setReflectionProbeAmbiance((F32)self->getChild<LLUICtrl>("Probe Ambiance")->getValue().asReal());
+ volobjp->setReflectionProbeNearClip((F32)self->getChild<LLUICtrl>("Probe Near Clip")->getValue().asReal());
+ volobjp->setReflectionProbeIsDynamic(self->getChild<LLUICtrl>("Probe Dynamic")->getValue().asBoolean());
+
+ std::string shape_type = self->getChild<LLUICtrl>("Probe Volume Type")->getValue().asString();
+
+ bool is_box = shape_type == "Box";
+
+ if (volobjp->setReflectionProbeIsBox(is_box))
+ {
+ // make the volume match the probe
+ auto* select_mgr = LLSelectMgr::getInstance();
+
+ select_mgr->selectionUpdatePhantom(true);
+ select_mgr->selectionSetGLTFMaterial(LLUUID::null);
+ select_mgr->selectionSetAlphaOnly(0.f);
+
+ U8 profile, path;
+
+ if (!is_box)
+ {
+ profile = LL_PCODE_PROFILE_CIRCLE_HALF;
+ path = LL_PCODE_PATH_CIRCLE;
+
+ F32 scale = volobjp->getScale().mV[0];
+ volobjp->setScale(LLVector3(scale, scale, scale), FALSE);
+ LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_ROTATION | UPD_POSITION | UPD_SCALE);
+ }
+ else
+ {
+ profile = LL_PCODE_PROFILE_SQUARE;
+ path = LL_PCODE_PATH_LINE;
+ }
+
+ LLVolumeParams params;
+ params.getProfileParams().setCurveType(profile);
+ params.getPathParams().setCurveType(path);
+ objectp->updateVolume(params);
+ }
+
+}
+
// static
void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata )
{
@@ -1225,9 +1418,22 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
if (volobjp)
{
LLViewerInventoryItem* item = gInventory.getItem(item_id);
+
+ if (item && volobjp->isAttachment())
+ {
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
+ }
+
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- LLToolDragAndDrop::handleDropTextureProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(volobjp, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
volobjp->setLightTextureID(asset_id);
}
@@ -1235,6 +1441,15 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item
//----------------------------------------------------------------------------
// static
+void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelVolume* self = (LLPanelVolume*)userdata;
+ self->sendIsReflectionProbe();
+}
+
+//----------------------------------------------------------------------------
+
+// static
void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata )
{
LLPanelVolume* self = (LLPanelVolume*) userdata;
diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h
index d9198f3693..01b7ebb75c 100644
--- a/indra/newview/llpanelvolume.h
+++ b/indra/newview/llpanelvolume.h
@@ -57,12 +57,22 @@ public:
void refresh();
void sendIsLight();
+
+ // when an object is becoming a refleciton probe, present a dialog asking for confirmation
+ // otherwise, send the reflection probe update immediately
+ void sendIsReflectionProbe();
+
+ // callback for handling response of the ok/cancel/ignore dialog for making an object a reflection probe
+ void doSendIsReflectionProbe(const LLSD& notification, const LLSD& response);
+
void sendIsFlexible();
static bool precommitValidate(const LLSD& data);
static void onCommitIsLight( LLUICtrl* ctrl, void* userdata);
static void onCommitLight( LLUICtrl* ctrl, void* userdata);
+ static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata);
+ static void onCommitProbe(LLUICtrl* ctrl, void* userdata);
void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata);
static void onCommitFlexible( LLUICtrl* ctrl, void* userdata);
void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata);
diff --git a/indra/newview/llperfstats.cpp b/indra/newview/llperfstats.cpp
index 7ff363c3c1..64e66d520b 100644
--- a/indra/newview/llperfstats.cpp
+++ b/indra/newview/llperfstats.cpp
@@ -39,6 +39,11 @@ extern LLControlGroup gSavedSettings;
namespace LLPerfStats
{
+ // avatar timing metrics in ms (updated once per mainloop iteration)
+ std::atomic<F32> sTotalAvatarTime = 0.f;
+ std::atomic<F32> sAverageAvatarTime = 0.f;
+ std::atomic<F32> sMaxAvatarTime = 0.f;
+
std::atomic<int64_t> tunedAvatars{0};
std::atomic<U64> renderAvatarMaxART_ns{(U64)(ART_UNLIMITED_NANOS)}; // highest render time we'll allow without culling features
bool belowTargetFPS{false};
@@ -75,7 +80,6 @@ namespace LLPerfStats
if( tuningFlag & UserAutoTuneEnabled ){ gSavedSettings.setBOOL("AutoTuneFPS", userAutoTuneEnabled); };
if( tuningFlag & UserAutoTuneLock ){ gSavedSettings.setBOOL("AutoTuneLock", userAutoTuneLock); };
if( tuningFlag & UserTargetFPS ){ gSavedSettings.setU32("TargetFPS", userTargetFPS); };
- if( tuningFlag & UserTargetReflections ){ gSavedSettings.setS32("UserTargetReflections", userTargetReflections); };
// Note: The Max ART slider is logarithmic and thus we have an intermediate proxy value
if( tuningFlag & UserARTCutoff ){ gSavedSettings.setF32("RenderAvatarMaxART", userARTCutoffSliderValue); };
resetChanges();
@@ -122,7 +126,6 @@ namespace LLPerfStats
LLPerfStats::tunables.userFPSTuningStrategy = gSavedSettings.getU32("TuningFPSStrategy");
LLPerfStats::tunables.userTargetFPS = gSavedSettings.getU32("TargetFPS");
LLPerfStats::tunables.vsyncEnabled = gSavedSettings.getBOOL("RenderVSyncEnable");
- LLPerfStats::tunables.userTargetReflections = gSavedSettings.getS32("UserTargetReflections");
LLPerfStats::tunables.userAutoTuneLock = gSavedSettings.getBOOL("AutoTuneLock") && gSavedSettings.getU32("KeepAutoTuneLock");
@@ -143,14 +146,12 @@ namespace LLPerfStats
resetChanges();
}
- StatsRecorder::StatsRecorder():q(1024*16),t(&StatsRecorder::run)
+ StatsRecorder::StatsRecorder()
{
// create a queue
- // create a thread to consume from the queue
tunables.initialiseFromSettings();
LLPerfStats::cpu_hertz = (F64)LLTrace::BlockTimer::countsPerSecond();
LLPerfStats::vsync_max_fps = gViewerWindow->getWindow()->getRefreshRate();
- t.detach();
}
// static
@@ -174,11 +175,13 @@ namespace LLPerfStats
// RENDER_MESHREPO,
StatType_t::RENDER_IDLE };
+#if 0
static constexpr std::initializer_list<StatType_t> avatarStatsToAvg = {
StatType_t::RENDER_GEOMETRY,
StatType_t::RENDER_SHADOWS,
StatType_t::RENDER_COMBINED,
StatType_t::RENDER_IDLE };
+#endif
if( /*sceneStats[static_cast<size_t>(StatType_t::RENDER_FPSLIMIT)] != 0 ||*/ sceneStats[static_cast<size_t>(StatType_t::RENDER_SLEEP)] != 0 )
@@ -201,32 +204,7 @@ namespace LLPerfStats
// LL_INFOS("scenestats") << "Scenestat: " << static_cast<size_t>(statEntry) << " before=" << avg << " new=" << val << " newavg=" << statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_GENERAL)][LLUUID::null][static_cast<size_t>(statEntry)] << LL_ENDL;
}
}
-// Allow attachment times etc to update even when FPS limited or sleeping.
- auto& statsMap = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)];
- for(auto& stat_entry : statsMap)
- {
- auto val = stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)];
- if(val > SMOOTHING_PERIODS){
- auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_ATTACHMENT)][stat_entry.first][static_cast<size_t>(ST::RENDER_COMBINED)];
- stat_entry.second[static_cast<size_t>(ST::RENDER_COMBINED)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
- }
- }
-
-
- auto& statsMapAv = statsDoubleBuffer[writeBuffer][static_cast<size_t>(ObjType_t::OT_AVATAR)];
- for(auto& stat_entry : statsMapAv)
- {
- for(auto& stat : avatarStatsToAvg)
- {
- auto val = stat_entry.second[static_cast<size_t>(stat)];
- if(val > SMOOTHING_PERIODS)
- {
- auto avg = statsDoubleBuffer[writeBuffer ^ 1][static_cast<size_t>(ObjType_t::OT_AVATAR)][stat_entry.first][static_cast<size_t>(stat)];
- stat_entry.second[static_cast<size_t>(stat)] = avg + (val / SMOOTHING_PERIODS) - (avg / SMOOTHING_PERIODS);
- }
- }
- }
-
+
// swap the buffers
if(enabled())
{
@@ -306,6 +284,16 @@ namespace LLPerfStats
}
}
+ // called once per main loop iteration on main thread
+ void updateClass()
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+
+ sTotalAvatarTime = LLVOAvatar::getTotalGPURenderTime();
+ sAverageAvatarTime = LLVOAvatar::getAverageGPURenderTime();
+ sMaxAvatarTime = LLVOAvatar::getMaxGPURenderTime();
+ }
+
//static
int StatsRecorder::countNearbyAvatars(S32 distance)
{
@@ -340,6 +328,8 @@ namespace LLPerfStats
// static
void StatsRecorder::updateAvatarParams()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+
if(tunables.autoTuneTimeout)
{
LLPerfStats::lastSleepedFrame = gFrameCount;
@@ -393,10 +383,10 @@ namespace LLPerfStats
}
}
- auto av_render_max_raw = LLPerfStats::StatsRecorder::getMax(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+ auto av_render_max_raw = ms_to_raw(sMaxAvatarTime);
// Is our target frame time lower than current? If so we need to take action to reduce draw overheads.
// cumulative avatar time (includes idle processing, attachments and base av)
- auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+ auto tot_avatar_time_raw = ms_to_raw(sTotalAvatarTime);
// The frametime budget we have based on the target FPS selected
auto target_frame_time_raw = (U64)llround(LLPerfStats::cpu_hertz / (target_fps == 0 ? 1 : target_fps));
@@ -430,7 +420,7 @@ namespace LLPerfStats
// if so we've got work to do
// how much of the frame was spent on non avatar related work?
- U64 non_avatar_time_raw = tot_frame_time_raw - tot_avatar_time_raw;
+ U64 non_avatar_time_raw = tot_frame_time_raw > tot_avatar_time_raw ? tot_frame_time_raw - tot_avatar_time_raw : 0;
// If the target frame time < scene time (estimated as non_avatar time)
U64 target_avatar_time_raw;
@@ -443,6 +433,7 @@ namespace LLPerfStats
{
// 1 - hack the water to opaque. all non opaque have a significant hit, this is a big boost for (arguably) a minor visual hit.
// the other reflection options make comparatively little change and if this overshoots we'll be stepping back up later
+# if 0 // TODO RenderReflectionDetail went away
if(LLPipeline::RenderReflectionDetail != -2)
{
LLPerfStats::tunables.updateReflectionDetail(-2);
@@ -450,6 +441,7 @@ namespace LLPerfStats
return;
}
else // deliberately "else" here so we only do one of these in any given frame
+#endif
{
// step down the DD by 10m per update
auto new_dd = (LLPipeline::RenderFarClip - DD_STEP > tunables.userMinDrawDistance)?(LLPipeline::RenderFarClip - DD_STEP) : tunables.userMinDrawDistance;
@@ -486,7 +478,11 @@ namespace LLPerfStats
{
new_render_limit_ns = renderAvatarMaxART_ns;
}
- new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
+
+ if (new_render_limit_ns > LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS)
+ {
+ new_render_limit_ns -= LLPerfStats::ART_MIN_ADJUST_DOWN_NANOS;
+ }
// bounce at the bottom to prevent "no limit"
new_render_limit_ns = std::max((U64)new_render_limit_ns, (U64)LLPerfStats::ART_MINIMUM_NANOS);
@@ -539,7 +535,9 @@ namespace LLPerfStats
if( (tot_frame_time_raw * 1.5) < target_frame_time_raw )
{
// if everything else is "max" and we have >50% headroom let's knock the water quality up a notch at a time.
+# if 0 // RenderReflectionDetail went away
LLPerfStats::tunables.updateReflectionDetail( std::min(LLPipeline::RenderReflectionDetail + 1, tunables.userTargetReflections) );
+#endif
}
}
}
diff --git a/indra/newview/llperfstats.h b/indra/newview/llperfstats.h
index 48ac483ce7..33777abdbf 100644
--- a/indra/newview/llperfstats.h
+++ b/indra/newview/llperfstats.h
@@ -42,6 +42,10 @@ extern U32 gFrameCount;
extern LLUUID gAgentID;
namespace LLPerfStats
{
+
+ // called once per main loop iteration
+ void updateClass();
+
// Note if changing these, they should correspond with the log range of the correpsonding sliders
static constexpr U64 ART_UNLIMITED_NANOS{50000000};
static constexpr U64 ART_MINIMUM_NANOS{100000};
@@ -68,9 +72,6 @@ namespace LLPerfStats
enum class ObjType_t{
OT_GENERAL=0, // Also Unknown. Used for n/a type stats such as scenery
- OT_AVATAR,
- OT_ATTACHMENT,
- OT_HUD,
OT_COUNT
};
enum class StatType_t{
@@ -117,7 +118,6 @@ namespace LLPerfStats
static constexpr U32 UserAutoTuneEnabled{256};
static constexpr U32 UserTargetFPS{512};
static constexpr U32 UserARTCutoff{1024};
- static constexpr U32 UserTargetReflections{2048};
static constexpr U32 UserAutoTuneLock{4096};
U32 tuningFlag{0}; // bit mask for changed settings
@@ -151,7 +151,6 @@ namespace LLPerfStats
void updateUserARTCutoffSlider(F32 nv){userARTCutoffSliderValue=nv; tuningFlag |= UserARTCutoff;};
void updateUserAutoTuneEnabled(bool nv){userAutoTuneEnabled=nv; tuningFlag |= UserAutoTuneEnabled;};
void updateUserAutoTuneLock(bool nv){userAutoTuneLock=nv; tuningFlag |= UserAutoTuneLock;};
- void updateUserTargetReflections(S32 nv){userTargetReflections=nv; tuningFlag |= UserTargetReflections;};
void resetChanges(){tuningFlag=Nothing;};
void initialiseFromSettings();
@@ -163,9 +162,7 @@ namespace LLPerfStats
extern Tunables tunables;
class StatsRecorder{
- using Queue = LLThreadSafeQueue<StatsRecord>;
public:
-
static inline StatsRecorder& getInstance()
{
static StatsRecorder instance;
@@ -174,9 +171,24 @@ namespace LLPerfStats
static inline void setFocusAv(const LLUUID& avID){focusAv = avID;};
static inline const LLUUID& getFocusAv(){return focusAv;};
static inline void setAutotuneInit(){autotuneInit = true;};
- static inline void send(StatsRecord && upd){StatsRecorder::getInstance().q.pushFront(std::move(upd));};
- static void endFrame(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});};
- static void clearStats(){StatsRecorder::getInstance().q.pushFront(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});};
+
+ static inline void send(StatsRecord && upd)
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+ StatsRecorder::getInstance().processUpdate(upd);
+ }
+
+ static void endFrame()
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+ StatsRecorder::getInstance().processUpdate(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 0});
+ }
+
+ static void clearStats()
+ {
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
+ StatsRecorder::getInstance().processUpdate(StatsRecord{StatType_t::RENDER_DONE, ObjType_t::OT_GENERAL, LLUUID::null, LLUUID::null, 1});
+ }
static inline void setEnabled(bool on_or_off){collectionEnabled=on_or_off;};
static inline void enable() { collectionEnabled=true; };
@@ -229,10 +241,6 @@ namespace LLPerfStats
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
// LL_INFOS("perfstats") << "processing update:" << LL_ENDL;
// Note: nullptr is used as the key for global stats
- #ifdef TRACY_ENABLE
- static char avstr[36];
- static char obstr[36];
- #endif
if (upd.statType == StatType_t::RENDER_DONE && upd.objType == ObjType_t::OT_GENERAL && upd.time == 0)
{
@@ -249,7 +257,6 @@ namespace LLPerfStats
auto ot{upd.objType};
auto& key{upd.objID};
- auto& avKey{upd.avID};
auto type {upd.statType};
auto val {upd.time};
@@ -259,38 +266,6 @@ namespace LLPerfStats
doUpd(key, ot, type,val);
return;
}
-
- if (ot == ObjType_t::OT_AVATAR)
- {
- // LL_INFOS("perfstats") << "Avatar update:" << LL_ENDL;
- doUpd(avKey, ot, type, val);
- return;
- }
-
- if (ot == ObjType_t::OT_ATTACHMENT)
- {
- if( !upd.isHUD ) // don't include HUD cost in self.
- {
- LL_PROFILE_ZONE_NAMED("Att as Av")
- // For all attachments that are not rigged we add them to the avatar (for all avatars) cost.
- doUpd(avKey, ObjType_t::OT_AVATAR, type, val);
- }
- if( avKey == focusAv )
- {
- LL_PROFILE_ZONE_NAMED("Att as Att")
- // For attachments that are for the focusAv (self for now) we record them for the attachment/complexity view
- if(upd.isHUD)
- {
- ot = ObjType_t::OT_HUD;
- }
- // LL_INFOS("perfstats") << "frame: " << gFrameCount << " Attachment update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << LL_ENDL;
- doUpd(key, ot, type, val);
- }
- // else
- // {
- // // LL_INFOS("perfstats") << "frame: " << gFrameCount << " non-self Att update("<< (type==StatType_t::RENDER_GEOMETRY?"GEOMETRY":"SHADOW") << ": " << key.asString() << " = " << val << " for av " << avKey.asString() << LL_ENDL;
- // }
- }
}
static inline void doUpd(const LLUUID& key, ObjType_t ot, StatType_t type, uint64_t val)
@@ -319,43 +294,6 @@ namespace LLPerfStats
static void toggleBuffer();
static void clearStatsBuffers();
- // thread entry
- static void run()
- {
- StatsRecord upd[10];
- auto & instance {StatsRecorder::getInstance()};
- LL_PROFILER_SET_THREAD_NAME("PerfStats");
-
- while( enabled() && !LLApp::isExiting() )
- {
- auto count = 0;
- while (count < 10)
- {
- if (instance.q.tryPopFor(std::chrono::milliseconds(10), upd[count]))
- {
- count++;
- }
- else
- {
- break;
- }
- }
- //LL_PROFILER_THREAD_BEGIN("PerfStats");
- if(count)
- {
- // LL_INFOS("perfstats") << "processing " << count << " updates." << LL_ENDL;
- for(auto i =0; i < count; i++)
- {
- instance.processUpdate(upd[i]);
- }
- }
- //LL_PROFILER_THREAD_END("PerfStats");
- }
- }
-
- Queue q;
- std::thread t;
-
~StatsRecorder() = default;
StatsRecorder(const StatsRecorder&) = delete;
StatsRecorder& operator=(const StatsRecorder&) = delete;
@@ -377,7 +315,7 @@ namespace LLPerfStats
start{LLTrace::BlockTimer::getCPUClockCount64()},
stat{type, ObjTypeDiscriminator, std::move(av), std::move(id), 0, isRiggedAtt, isHUDAtt}
{
- //LL_PROFILE_ZONE_COLOR(tracy::Color::Orange);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
};
template < ObjType_t OD = ObjTypeDiscriminator,
@@ -387,13 +325,6 @@ namespace LLPerfStats
LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
};
- template < ObjType_t OD = ObjTypeDiscriminator,
- std::enable_if_t<OD == ObjType_t::OT_AVATAR> * = nullptr>
- RecordTime( const LLUUID & av, StatType_t type ):RecordTime<ObjTypeDiscriminator>(std::move(av), LLUUID::null, type)
- {
- //LL_PROFILE_ZONE_COLOR(tracy::Color::Purple);
- };
-
~RecordTime()
{
if(!LLPerfStats::StatsRecorder::enabled())
@@ -401,65 +332,25 @@ namespace LLPerfStats
return;
}
- //LL_PROFILE_ZONE_COLOR(tracy::Color::Red);
-
stat.time = LLTrace::BlockTimer::getCPUClockCount64() - start;
StatsRecorder::send(std::move(stat));
};
};
-
+
inline double raw_to_ns(U64 raw) { return (static_cast<double>(raw) * 1000000000.0) / LLPerfStats::cpu_hertz; };
inline double raw_to_us(U64 raw) { return (static_cast<double>(raw) * 1000000.0) / LLPerfStats::cpu_hertz; };
inline double raw_to_ms(U64 raw) { return (static_cast<double>(raw) * 1000.0) / LLPerfStats::cpu_hertz; };
- using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
- using RecordAvatarTime = RecordTime<ObjType_t::OT_AVATAR>;
- using RecordAttachmentTime = RecordTime<ObjType_t::OT_ATTACHMENT>;
- using RecordHudAttachmentTime = RecordTime<ObjType_t::OT_HUD>;
-
-};// namespace LLPerfStats
-
-// helper functions
-using RATptr = std::unique_ptr<LLPerfStats::RecordAttachmentTime>;
-using RSTptr = std::unique_ptr<LLPerfStats::RecordSceneTime>;
+ inline U64 ns_to_raw(double ns) { return (U64)(LLPerfStats::cpu_hertz * (ns / 1000000000.0)); }
+ inline U64 us_to_raw(double us) { return (U64)(LLPerfStats::cpu_hertz * (us / 1000000.0)); }
+ inline U64 ms_to_raw(double ms) { return (U64)(LLPerfStats::cpu_hertz * (ms / 1000.0));
-template <typename T>
-static inline void trackAttachments(const T * vobj, bool isRigged, RATptr* ratPtrp)
-{
- if( !vobj ){ ratPtrp->reset(); return;};
+ }
- const T* rootAtt{vobj};
- if (rootAtt->isAttachment())
- {
- LL_PROFILE_ZONE_SCOPED_CATEGORY_STATS;
-
- while( !rootAtt->isRootEdit() )
- {
- rootAtt = (T*)(rootAtt->getParent());
- }
- auto avPtr = (T*)(rootAtt->getParent());
- if(!avPtr){ratPtrp->reset(); return;}
+ using RecordSceneTime = RecordTime<ObjType_t::OT_GENERAL>;
- auto& av = avPtr->getID();
- auto& obj = rootAtt->getAttachmentItemID();
- if (!*ratPtrp || (*ratPtrp)->stat.objID != obj || (*ratPtrp)->stat.avID != av)
- {
- if (*ratPtrp)
- {
- // deliberately reset to ensure destruction before construction of replacement.
- ratPtrp->reset();
- };
- *ratPtrp = std::make_unique<LLPerfStats::RecordAttachmentTime>(
- av,
- obj,
- ( LLPipeline::sShadowRender?LLPerfStats::StatType_t::RENDER_SHADOWS : LLPerfStats::StatType_t::RENDER_GEOMETRY ),
- isRigged,
- rootAtt->isHUDAttachment());
- }
- }
- return;
-};
+};// namespace LLPerfStats
#endif
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index 5629438415..3c27964ec5 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -40,7 +40,7 @@ public:
{
Params()
{
- filter_asset_type = "landmark";
+ filter_asset_types = "landmark";
}
};
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index fc2de4844e..0117db86e8 100644
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -115,8 +115,11 @@ const LLInventoryItem *LLPreview::getItem() const
}
else if (mObjectUUID.isNull())
{
- // it's an inventory item, so get the item.
- item = gInventory.getItem(mItemUUID);
+ if (mItemUUID.notNull())
+ {
+ // it's an inventory item, so get the item.
+ item = gInventory.getItem(mItemUUID);
+ }
}
else
{
@@ -238,14 +241,22 @@ void LLPreview::refreshFromItem()
// static
BOOL LLPreview::canModify(const LLUUID taskUUID, const LLInventoryItem* item)
{
+ const LLViewerObject* object = nullptr;
if (taskUUID.notNull())
{
- LLViewerObject* object = gObjectList.findObject(taskUUID);
- if(object && !object->permModify())
- {
- // No permission to edit in-world inventory
- return FALSE;
- }
+ object = gObjectList.findObject(taskUUID);
+ }
+
+ return canModify(object, item);
+}
+
+// static
+BOOL LLPreview::canModify(const LLViewerObject* object, const LLInventoryItem* item)
+{
+ if (object && !object->permModify())
+ {
+ // No permission to edit in-world inventory
+ return FALSE;
}
return item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE);
diff --git a/indra/newview/llpreview.h b/indra/newview/llpreview.h
index 9ac15d1639..3688ee0192 100644
--- a/indra/newview/llpreview.h
+++ b/indra/newview/llpreview.h
@@ -36,6 +36,7 @@
#include <map>
class LLInventoryItem;
+class LLViewerObject;
class LLLineEditor;
class LLRadioGroup;
class LLPreview;
@@ -83,7 +84,7 @@ public:
virtual BOOL handleHover(S32 x, S32 y, MASK mask);
virtual void onOpen(const LLSD& key);
- void setAuxItem( const LLInventoryItem* item );
+ virtual void setAuxItem( const LLInventoryItem* item );
static void onBtnCopyToInv(void* userdata);
@@ -109,6 +110,7 @@ public:
// We can't modify Item or description in preview if either in-world Object
// or Item itself is unmodifiable
static BOOL canModify(const LLUUID taskUUID, const LLInventoryItem* item);
+ static BOOL canModify(const LLViewerObject* object, const LLInventoryItem* item);
protected:
virtual void onCommit();
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 759e7859f2..544ff8b5dc 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -1108,14 +1108,16 @@ void LLPreviewGesture::saveIfNeeded()
item->setComplete(true);
uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mItemUUID, LLAssetType::AT_GESTURE, buffer,
- [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD) {
+ [](LLUUID itemId, LLUUID newAssetId, LLUUID, LLSD)
+ {
LLPreviewGesture::finishInventoryUpload(itemId, newAssetId);
- });
+ },
+ nullptr);
url = agent_url;
}
else if (!mObjectUUID.isNull() && !task_url.empty())
{
- uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr);
+ uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mObjectUUID, mItemUUID, LLAssetType::AT_GESTURE, buffer, nullptr, nullptr);
url = task_url;
}
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 095d5a0a1e..6681703625 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -555,7 +555,8 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mItemUUID, LLAssetType::AT_NOTECARD, buffer,
[](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) {
LLPreviewNotecard::finishInventoryUpload(itemId, newAssetId, newItemId);
- });
+ },
+ nullptr);
url = agent_url;
}
else if (!mObjectUUID.isNull() && !task_url.empty())
@@ -564,7 +565,8 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem, bool sync)
uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer,
[object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) {
LLPreviewNotecard::finishTaskUpload(itemId, newAssetId, object_uuid);
- });
+ },
+ nullptr);
url = task_url;
}
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 23c6cc01f5..aceb8539d2 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -1203,7 +1203,7 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
void LLScriptEdCore::onBtnLoadFromFile( void* data )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false);
}
void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data)
@@ -1244,7 +1244,7 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata )
if( self->mSaveCallback )
{
- (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName);
}
}
@@ -1687,6 +1687,32 @@ void LLPreviewLSL::finishedLSLUpload(LLUUID itemId, LLSD response)
}
}
+bool LLPreviewLSL::failedLSLUpload(LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)
+{
+ LLSD floater_key;
+ if (taskId.notNull())
+ {
+ floater_key["taskid"] = taskId;
+ floater_key["itemid"] = itemId;
+ }
+ else
+ {
+ floater_key = LLSD(itemId);
+ }
+
+ LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script", floater_key);
+ if (preview)
+ {
+ // unfreeze floater
+ LLSD errors;
+ errors.append(LLTrans::getString("UploadFailed") + reason);
+ preview->callbackLSLCompileFailed(errors);
+ return true;
+ }
+
+ return false;
+}
+
// Save needs to compile the text in the buffer. If the compile
// succeeds, then save both assets out to the database. If the compile
// fails, go ahead and save the text anyway.
@@ -1724,7 +1750,8 @@ void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/)
[old_asset_id](LLUUID itemId, LLUUID, LLUUID, LLSD response) {
LLFileSystem::removeFile(old_asset_id, LLAssetType::AT_LSL_TEXT);
LLPreviewLSL::finishedLSLUpload(itemId, response);
- }));
+ },
+ LLPreviewLSL::failedLSLUpload));
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
@@ -2283,7 +2310,8 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)
[isRunning, old_asset_id](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) {
LLFileSystem::removeFile(old_asset_id, LLAssetType::AT_LSL_TEXT);
LLLiveLSLEditor::finishLSLUpload(itemId, taskId, newAssetId, response, isRunning);
- }));
+ },
+ nullptr)); // needs failure handling?
LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo);
}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index f851ff6f3f..b01c7fd4ad 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -245,6 +245,7 @@ protected:
static void* createScriptEdPanel(void* userdata);
static void finishedLSLUpload(LLUUID itemId, LLSD response);
+ static bool failedLSLUpload(LLUUID itemId, LLUUID taskId, LLSD response, std::string reason);
protected:
// Can safely close only after both text and bytecode are uploaded
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 10177c8023..975e2bb910 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -296,7 +296,7 @@ void LLPreviewTexture::saveAs()
return;
std::string filename = getItem() ? LLDir::getScrubbedFileName(getItem()->getName()) : LLStringUtil::null;
- (new LLFilePickerReplyThread(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLPreviewTexture::saveTextureToFile, this, _1), LLFilePicker::FFSAVE_TGAPNG, filename);
}
void LLPreviewTexture::saveTextureToFile(const std::vector<std::string>& filenames)
diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp
new file mode 100644
index 0000000000..ec54fa1165
--- /dev/null
+++ b/indra/newview/llreflectionmap.cpp
@@ -0,0 +1,368 @@
+/**
+ * @file llreflectionmap.cpp
+ * @brief LLReflectionMap class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmap.h"
+#include "pipeline.h"
+#include "llviewerwindow.h"
+#include "llviewerregion.h"
+#include "llworld.h"
+#include "llshadermgr.h"
+
+extern F32SecondsImplicit gFrameTimeSeconds;
+
+extern U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
+
+LLReflectionMap::LLReflectionMap()
+{
+}
+
+LLReflectionMap::~LLReflectionMap()
+{
+ if (mOcclusionQuery)
+ {
+ glDeleteQueries(1, &mOcclusionQuery);
+ }
+}
+
+void LLReflectionMap::update(U32 resolution, U32 face)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ mLastUpdateTime = gFrameTimeSeconds;
+ llassert(mCubeArray.notNull());
+ llassert(mCubeIndex != -1);
+ //llassert(LLPipeline::sRenderDeferred);
+
+ // make sure we don't walk off the edge of the render target
+ while (resolution > gPipeline.mRT->deferredScreen.getWidth() ||
+ resolution > gPipeline.mRT->deferredScreen.getHeight())
+ {
+ resolution /= 2;
+ }
+ gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic());
+}
+
+void LLReflectionMap::autoAdjustOrigin()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ if (mGroup && !mComplete)
+ {
+ const LLVector4a* bounds = mGroup->getBounds();
+ auto* node = mGroup->getOctreeNode();
+
+ if (mGroup->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ mPriority = 0;
+ // cast a ray towards 8 corners of bounding box
+ // nudge origin towards center of empty space
+
+ if (!node)
+ {
+ return;
+ }
+
+ mOrigin = bounds[0];
+
+ LLVector4a size = bounds[1];
+
+ LLVector4a corners[] =
+ {
+ { 1, 1, 1 },
+ { -1, 1, 1 },
+ { 1, -1, 1 },
+ { -1, -1, 1 },
+ { 1, 1, -1 },
+ { -1, 1, -1 },
+ { 1, -1, -1 },
+ { -1, -1, -1 }
+ };
+
+ for (int i = 0; i < 8; ++i)
+ {
+ corners[i].mul(size);
+ corners[i].add(bounds[0]);
+ }
+
+ LLVector4a extents[2];
+ extents[0].setAdd(bounds[0], bounds[1]);
+ extents[1].setSub(bounds[0], bounds[1]);
+
+ bool hit = false;
+ for (int i = 0; i < 8; ++i)
+ {
+ int face = -1;
+ LLVector4a intersection;
+ LLDrawable* drawable = mGroup->lineSegmentIntersect(bounds[0], corners[i], false, false, true, true, &face, &intersection);
+ if (drawable != nullptr)
+ {
+ hit = true;
+ update_min_max(extents[0], extents[1], intersection);
+ }
+ else
+ {
+ update_min_max(extents[0], extents[1], corners[i]);
+ }
+ }
+
+ if (hit)
+ {
+ mOrigin.setAdd(extents[0], extents[1]);
+ mOrigin.mul(0.5f);
+ }
+
+ // make sure origin isn't under ground
+ F32* fp = mOrigin.getF32ptr();
+ LLVector3 origin(fp);
+ F32 height = LLWorld::instance().resolveLandHeightAgent(origin) + 2.f;
+ fp[2] = llmax(fp[2], height);
+
+ // make sure radius encompasses all objects
+ LLSimdScalar r2 = 0.0;
+ for (int i = 0; i < 8; ++i)
+ {
+ LLVector4a v;
+ v.setSub(corners[i], mOrigin);
+
+ LLSimdScalar d = v.dot3(v);
+
+ if (d > r2)
+ {
+ r2 = d;
+ }
+ }
+
+ mRadius = llmax(sqrtf(r2.getF32()), 8.f);
+
+ // make sure near clip doesn't poke through ground
+ fp[2] = llmax(fp[2], height+mRadius*0.5f);
+
+ }
+ }
+ else if (mViewerObject)
+ {
+ mPriority = 1;
+ mOrigin.load3(mViewerObject->getPositionAgent().mV);
+ mRadius = mViewerObject->getScale().mV[0]*0.5f;
+ }
+}
+
+bool LLReflectionMap::intersects(LLReflectionMap* other)
+{
+ LLVector4a delta;
+ delta.setSub(other->mOrigin, mOrigin);
+
+ F32 dist = delta.dot3(delta).getF32();
+
+ F32 r2 = mRadius + other->mRadius;
+
+ r2 *= r2;
+
+ return dist < r2;
+}
+
+extern LLControlGroup gSavedSettings;
+
+F32 LLReflectionMap::getAmbiance()
+{
+ F32 ret = 0.f;
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance();
+ }
+
+ return ret;
+}
+
+F32 LLReflectionMap::getNearClip()
+{
+ const F32 MINIMUM_NEAR_CLIP = 0.1f;
+
+ F32 ret = 0.f;
+
+ if (mViewerObject && mViewerObject->getVolume())
+ {
+ ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip();
+ }
+ else if (mGroup)
+ {
+ ret = mRadius * 0.5f; // default to half radius for automatic object probes
+ }
+ else
+ {
+ ret = 1.f; // default to 1m for automatic terrain probes
+ }
+
+ return llmax(ret, MINIMUM_NEAR_CLIP);
+}
+
+bool LLReflectionMap::getIsDynamic()
+{
+ if (gSavedSettings.getS32("RenderReflectionProbeDetail") > (S32) LLReflectionMapManager::DetailLevel::STATIC_ONLY &&
+ mViewerObject &&
+ mViewerObject->getVolume())
+ {
+ return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic();
+ }
+
+ return false;
+}
+
+bool LLReflectionMap::getBox(LLMatrix4& box)
+{
+ if (mViewerObject)
+ {
+ LLVolume* volume = mViewerObject->getVolume();
+ if (volume)
+ {
+ LLVOVolume* vobjp = (LLVOVolume*)mViewerObject;
+
+ if (vobjp->getReflectionProbeIsBox())
+ {
+ glh::matrix4f mv(gGLModelView);
+ glh::matrix4f scale;
+ LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f));
+ mRadius = s.magVec();
+ scale.set_scale(glh::vec3f(s.mV));
+ if (vobjp->mDrawable != nullptr)
+ {
+ // object to agent space (no scale)
+ glh::matrix4f rm((F32*)vobjp->mDrawable->getWorldMatrix().mMatrix);
+
+ // construct object to camera space (with scale)
+ mv = mv * rm * scale;
+
+ // inverse is camera space to object unit cube
+ mv = mv.inverse();
+
+ box = LLMatrix4(mv.m);
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool LLReflectionMap::isActive()
+{
+ return mCubeIndex != -1;
+}
+
+bool LLReflectionMap::isRelevant()
+{
+ static LLCachedControl<S32> RenderReflectionProbeLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
+
+ if (mViewerObject && RenderReflectionProbeLevel > 0)
+ { // not an automatic probe
+ return true;
+ }
+
+ if (RenderReflectionProbeLevel == 3)
+ { // all automatics are relevant
+ return true;
+ }
+
+ if (RenderReflectionProbeLevel == 2)
+ { // terrain and water only, ignore probes that have a group
+ return !mGroup;
+ }
+
+ // no automatic probes, yes manual probes
+ return mViewerObject != nullptr;
+}
+
+
+void LLReflectionMap::doOcclusion(const LLVector4a& eye)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ if (LLGLSLShader::sProfileEnabled)
+ {
+ return;
+ }
+
+#if 1
+ // super sloppy, but we're doing an occlusion cull against a bounding cube of
+ // a bounding sphere, pad radius so we assume if the eye is within
+ // the bounding sphere of the bounding cube, the node is not culled
+ F32 dist = mRadius * F_SQRT3 + 1.f;
+
+ LLVector4a o;
+ o.setSub(mOrigin, eye);
+
+ bool do_query = false;
+
+ if (o.getLength3().getF32() < dist)
+ { // eye is inside radius, don't attempt to occlude
+ mOccluded = false;
+ return;
+ }
+
+ if (mOcclusionQuery == 0)
+ { // no query was previously issued, allocate one and issue
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGenQueries");
+ glGenQueries(1, &mOcclusionQuery);
+ do_query = true;
+ }
+ else
+ { // query was previously issued, check it and only issue a new query
+ // if previous query is available
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - glGetQueryObject");
+ GLuint result = 0;
+ glGetQueryObjectuiv(mOcclusionQuery, GL_QUERY_RESULT_AVAILABLE, &result);
+
+ if (result > 0)
+ {
+ do_query = true;
+ glGetQueryObjectuiv(mOcclusionQuery, GL_QUERY_RESULT, &result);
+ mOccluded = result == 0;
+ mOcclusionPendingFrames = 0;
+ }
+ else
+ {
+ mOcclusionPendingFrames++;
+ }
+ }
+
+ if (do_query)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("rmdo - push query");
+ glBeginQuery(GL_ANY_SAMPLES_PASSED, mOcclusionQuery);
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ shader->uniform3fv(LLShaderMgr::BOX_CENTER, 1, mOrigin.getF32ptr());
+ shader->uniform3f(LLShaderMgr::BOX_SIZE, mRadius, mRadius, mRadius);
+
+ gPipeline.mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(LLViewerCamera::getInstance(), mOrigin));
+
+ glEndQuery(GL_ANY_SAMPLES_PASSED);
+ }
+#endif
+}
diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h
new file mode 100644
index 0000000000..7ea0fe6187
--- /dev/null
+++ b/indra/newview/llreflectionmap.h
@@ -0,0 +1,131 @@
+/**
+ * @file llreflectionmap.h
+ * @brief LLReflectionMap class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llcubemaparray.h"
+#include "llmemory.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+class alignas(16) LLReflectionMap : public LLRefCount
+{
+ LL_ALIGN_NEW
+public:
+ // allocate an environment map of the given resolution
+ LLReflectionMap();
+
+ ~LLReflectionMap();
+
+ // update this environment map
+ // resolution - size of cube map to generate
+ void update(U32 resolution, U32 face);
+
+ // for volume partition probes, try to place this probe in the best spot
+ void autoAdjustOrigin();
+
+ // return true if given Reflection Map's influence volume intersect's with this one's
+ bool intersects(LLReflectionMap* other);
+
+ // Get the ambiance value to use for this probe
+ F32 getAmbiance();
+
+ // Get the near clip plane distance to use for this probe
+ F32 getNearClip();
+
+ // Return true if this probe should include avatars in its reflection map
+ bool getIsDynamic();
+
+ // get the encoded bounding box of this probe's influence volume
+ // will only return a box if this probe is associated with a VOVolume
+ // with its reflection probe influence volume to to VOLUME_TYPE_BOX
+ // return false if no bounding box (treat as sphere influence volume)
+ bool getBox(LLMatrix4& box);
+
+ // return true if this probe is active for rendering
+ bool isActive();
+
+ // perform occlusion query/readback
+ void doOcclusion(const LLVector4a& eye);
+
+ // return false if this probe isn't currently relevant (for example, disabled due to graphics preferences)
+ bool isRelevant();
+
+ // point at which environment map was last generated from (in agent space)
+ LLVector4a mOrigin;
+
+ // distance from main viewer camera
+ F32 mDistance = -1.f;
+
+ // Minimum and maximum depth in current render camera
+ F32 mMinDepth = -1.f;
+ F32 mMaxDepth = -1.f;
+
+ // radius of this probe's affected area
+ F32 mRadius = 16.f;
+
+ // last time this probe was updated (or when its update timer got reset)
+ F32 mLastUpdateTime = 0.f;
+
+ // last time this probe was bound for rendering
+ F32 mLastBindTime = 0.f;
+
+ // cube map used to sample this environment map
+ LLPointer<LLCubeMapArray> mCubeArray;
+ S32 mCubeIndex = -1; // index into cube map array or -1 if not currently stored in cube map array
+
+ // probe has had at least one full update and is ready to render
+ bool mComplete = false;
+
+ // fade in parameter for this probe
+ F32 mFadeIn = 0.f;
+
+ // index into array packed by LLReflectionMapManager::getReflectionMaps
+ // WARNING -- only valid immediately after call to getReflectionMaps
+ S32 mProbeIndex = -1;
+
+ // set of any LLReflectionMaps that intersect this map (maintained by LLReflectionMapManager
+ std::vector<LLReflectionMap*> mNeighbors;
+
+ // spatial group this probe is tracking (if any)
+ LLSpatialGroup* mGroup = nullptr;
+
+ // viewer object this probe is tracking (if any)
+ LLViewerObject* mViewerObject = nullptr;
+
+ // what priority should this probe have (higher is higher priority)
+ // currently only 0 or 1
+ // 0 - automatic probe
+ // 1 - manual probe
+ U32 mPriority = 0;
+
+ // occlusion culling state
+ GLuint mOcclusionQuery = 0;
+ bool mOccluded = false;
+ U32 mOcclusionPendingFrames = 0;
+};
+
diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp
new file mode 100644
index 0000000000..72f7e23b0c
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.cpp
@@ -0,0 +1,1376 @@
+/**
+ * @file llreflectionmapmanager.cpp
+ * @brief LLReflectionMapManager class implementation
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llreflectionmapmanager.h"
+#include "llviewercamera.h"
+#include "llspatialpartition.h"
+#include "llviewerregion.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llviewercontrol.h"
+#include "llenvironment.h"
+#include "llstartup.h"
+
+extern BOOL gCubeSnapshot;
+extern BOOL gTeleportDisplay;
+
+static U32 sUpdateCount = 0;
+
+// get the next highest power of two of v (or v if v is already a power of two)
+//defined in llvertexbuffer.cpp
+extern U32 nhpo2(U32 v);
+
+static void touch_default_probe(LLReflectionMap* probe)
+{
+ if (LLViewerCamera::getInstance())
+ {
+ LLVector3 origin = LLViewerCamera::getInstance()->getOrigin();
+ origin.mV[2] += 64.f;
+
+ probe->mOrigin.load3(origin.mV);
+ }
+}
+
+LLReflectionMapManager::LLReflectionMapManager()
+{
+ initCubeFree();
+}
+
+void LLReflectionMapManager::initCubeFree()
+{
+ // start at 1 because index 0 is reserved for mDefaultProbe
+ for (int i = 1; i < LL_MAX_REFLECTION_PROBE_COUNT; ++i)
+ {
+ mCubeFree.push_back(i);
+ }
+}
+
+struct CompareProbeDistance
+{
+ LLReflectionMap* mDefaultProbe;
+
+ bool operator()(const LLPointer<LLReflectionMap>& lhs, const LLPointer<LLReflectionMap>& rhs)
+ {
+ return lhs->mDistance < rhs->mDistance;
+ }
+};
+
+static F32 update_score(LLReflectionMap* p)
+{
+ return gFrameTimeSeconds - p->mLastUpdateTime - p->mDistance*0.1f;
+}
+
+// return true if a is higher priority for an update than b
+static bool check_priority(LLReflectionMap* a, LLReflectionMap* b)
+{
+ if (a->mCubeIndex == -1)
+ { // not a candidate for updating
+ return false;
+ }
+ else if (b->mCubeIndex == -1)
+ { // b is not a candidate for updating, a is higher priority by default
+ return true;
+ }
+ else if (!a->mComplete && !b->mComplete)
+ { //neither probe is complete, use distance
+ return a->mDistance < b->mDistance;
+ }
+ else if (a->mComplete && b->mComplete)
+ { //both probes are complete, use update_score metric
+ return update_score(a) > update_score(b);
+ }
+
+ // a or b is not complete,
+ if (sUpdateCount % 3 == 0)
+ { // every third update, allow complete probes to cut in line in front of non-complete probes to avoid spammy probe generators from deadlocking scheduler (SL-20258))
+ return !b->mComplete;
+ }
+
+ // prioritize incomplete probe
+ return b->mComplete;
+}
+
+// helper class to seed octree with probes
+void LLReflectionMapManager::update()
+{
+ if (!LLPipeline::sReflectionProbesEnabled || gTeleportDisplay || LLStartUp::getStartupState() < STATE_PRECACHE)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(!gCubeSnapshot); // assert a snapshot is not in progress
+ if (LLAppViewer::instance()->logoutRequestSent())
+ {
+ return;
+ }
+
+ initReflectionMaps();
+
+ if (!mRenderTarget.isComplete())
+ {
+ U32 color_fmt = GL_RGB16F;
+ U32 targetRes = mProbeResolution * 4; // super sample
+ mRenderTarget.allocate(targetRes, targetRes, color_fmt, true);
+ }
+
+ if (mMipChain.empty())
+ {
+ U32 res = mProbeResolution;
+ U32 count = log2((F32)res) + 0.5f;
+
+ mMipChain.resize(count);
+ for (int i = 0; i < count; ++i)
+ {
+ mMipChain[i].allocate(res, res, GL_RGB16F);
+ res /= 2;
+ }
+ }
+
+ llassert(mProbes[0] == mDefaultProbe);
+
+ LLVector4a camera_pos;
+ camera_pos.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ // process kill list
+ for (auto& probe : mKillList)
+ {
+ auto const & iter = std::find(mProbes.begin(), mProbes.end(), probe);
+ if (iter != mProbes.end())
+ {
+ deleteProbe(iter - mProbes.begin());
+ }
+ }
+
+ mKillList.clear();
+
+ // process create list
+ for (auto& probe : mCreateList)
+ {
+ mProbes.push_back(probe);
+ }
+
+ mCreateList.clear();
+
+ if (mProbes.empty())
+ {
+ return;
+ }
+
+
+ bool did_update = false;
+
+ static LLCachedControl<S32> sDetail(gSavedSettings, "RenderReflectionProbeDetail", -1);
+ static LLCachedControl<S32> sLevel(gSavedSettings, "RenderReflectionProbeLevel", 3);
+
+ bool realtime = sDetail >= (S32)LLReflectionMapManager::DetailLevel::REALTIME;
+
+ LLReflectionMap* closestDynamic = nullptr;
+
+ LLReflectionMap* oldestProbe = nullptr;
+ LLReflectionMap* oldestOccluded = nullptr;
+
+ if (mUpdatingProbe != nullptr)
+ {
+ did_update = true;
+ doProbeUpdate();
+ }
+
+ // update distance to camera for all probes
+ std::sort(mProbes.begin()+1, mProbes.end(), CompareProbeDistance());
+ llassert(mProbes[0] == mDefaultProbe);
+ llassert(mProbes[0]->mCubeArray == mTexture);
+ llassert(mProbes[0]->mCubeIndex == 0);
+
+ // make sure we're assigning cube slots to the closest probes
+
+ // first free any cube indices for distant probes
+ for (U32 i = mReflectionProbeCount; i < mProbes.size(); ++i)
+ {
+ LLReflectionMap* probe = mProbes[i];
+ llassert(probe != nullptr);
+
+ if (probe->mCubeIndex != -1 && mUpdatingProbe != probe)
+ { // free this index
+ mCubeFree.push_back(probe->mCubeIndex);
+
+ probe->mCubeArray = nullptr;
+ probe->mCubeIndex = -1;
+ probe->mComplete = false;
+ }
+ }
+
+ // next distribute the free indices
+ U32 count = llmin(mReflectionProbeCount, (U32)mProbes.size());
+
+ for (S32 i = 1; i < count && !mCubeFree.empty(); ++i)
+ {
+ // find the closest probe that needs a cube index
+ LLReflectionMap* probe = mProbes[i];
+
+ if (probe->mCubeIndex == -1)
+ {
+ S32 idx = allocateCubeIndex();
+ llassert(idx > 0); //if we're still in this loop, mCubeFree should not be empty and allocateCubeIndex should be returning good indices
+ probe->mCubeArray = mTexture;
+ probe->mCubeIndex = idx;
+ }
+ }
+
+ for (int i = 0; i < mProbes.size(); ++i)
+ {
+ LLReflectionMap* probe = mProbes[i];
+ if (probe->getNumRefs() == 1)
+ { // no references held outside manager, delete this probe
+ deleteProbe(i);
+ --i;
+ continue;
+ }
+
+ if (probe != mDefaultProbe &&
+ (!probe->isRelevant() || mPaused))
+ { // skip irrelevant probes (or all non-default probes if paused)
+ continue;
+ }
+
+
+
+ LLVector4a d;
+
+ if (probe != mDefaultProbe)
+ {
+ if (probe->mViewerObject) //make sure probes track the viewer objects they are attached to
+ {
+ probe->mOrigin.load3(probe->mViewerObject->getPositionAgent().mV);
+ }
+ d.setSub(camera_pos, probe->mOrigin);
+ probe->mDistance = d.getLength3().getF32() - probe->mRadius;
+ }
+ else if (probe->mComplete)
+ {
+ // make default probe have a distance of 64m for the purposes of prioritization (if it's already been generated once)
+ probe->mDistance = 64.f;
+ }
+ else
+ {
+ probe->mDistance = -4096.f; //boost priority of default probe when it's not complete
+ }
+
+ if (probe->mComplete)
+ {
+ probe->autoAdjustOrigin();
+ probe->mFadeIn = llmin((F32) (probe->mFadeIn + gFrameIntervalSeconds), 1.f);
+ }
+ if (probe->mOccluded && probe->mComplete)
+ {
+ if (oldestOccluded == nullptr)
+ {
+ oldestOccluded = probe;
+ }
+ else if (probe->mLastUpdateTime < oldestOccluded->mLastUpdateTime)
+ {
+ oldestOccluded = probe;
+ }
+ }
+ else
+ {
+ if (!did_update &&
+ i < mReflectionProbeCount &&
+ (oldestProbe == nullptr ||
+ check_priority(probe, oldestProbe)))
+ {
+ oldestProbe = probe;
+ }
+ }
+
+ if (realtime &&
+ closestDynamic == nullptr &&
+ probe->mCubeIndex != -1 &&
+ probe->getIsDynamic())
+ {
+ closestDynamic = probe;
+ }
+ }
+
+ if (realtime && closestDynamic != nullptr)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmu - realtime");
+ // update the closest dynamic probe realtime
+ // should do a full irradiance pass on "odd" frames and a radiance pass on "even" frames
+ closestDynamic->autoAdjustOrigin();
+
+ // store and override the value of "isRadiancePass" -- parts of the render pipe rely on "isRadiancePass" to set
+ // lighting values etc
+ bool radiance_pass = isRadiancePass();
+ mRadiancePass = mRealtimeRadiancePass;
+ for (U32 i = 0; i < 6; ++i)
+ {
+ updateProbeFace(closestDynamic, i);
+ }
+ mRealtimeRadiancePass = !mRealtimeRadiancePass;
+
+ // restore "isRadiancePass"
+ mRadiancePass = radiance_pass;
+ }
+
+ static LLCachedControl<F32> sUpdatePeriod(gSavedSettings, "RenderDefaultProbeUpdatePeriod", 2.f);
+ if ((gFrameTimeSeconds - mDefaultProbe->mLastUpdateTime) < sUpdatePeriod)
+ {
+ if (sLevel == 0)
+ { // when probes are disabled don't update the default probe more often than the prescribed update period
+ oldestProbe = nullptr;
+ }
+ }
+ else if (sLevel > 0)
+ { // when probes are enabled don't update the default probe less often than the prescribed update period
+ oldestProbe = mDefaultProbe;
+ }
+
+ // switch to updating the next oldest probe
+ if (!did_update && oldestProbe != nullptr)
+ {
+ LLReflectionMap* probe = oldestProbe;
+ llassert(probe->mCubeIndex != -1);
+
+ probe->autoAdjustOrigin();
+
+ sUpdateCount++;
+ mUpdatingProbe = probe;
+ doProbeUpdate();
+ }
+
+ if (oldestOccluded)
+ {
+ // as far as this occluded probe is concerned, an origin/radius update is as good as a full update
+ oldestOccluded->autoAdjustOrigin();
+ oldestOccluded->mLastUpdateTime = gFrameTimeSeconds;
+ }
+}
+
+LLReflectionMap* LLReflectionMapManager::addProbe(LLSpatialGroup* group)
+{
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mGroup = group;
+
+ if (mDefaultProbe.isNull())
+ { //safety check to make sure default probe is always first probe added
+ mDefaultProbe = new LLReflectionMap();
+ mProbes.push_back(mDefaultProbe);
+ }
+
+ llassert(mProbes[0] == mDefaultProbe);
+
+ if (group)
+ {
+ probe->mOrigin = group->getOctreeNode()->getCenter();
+ }
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+struct CompareProbeDepth
+{
+ bool operator()(const LLReflectionMap* lhs, const LLReflectionMap* rhs)
+ {
+ return lhs->mMinDepth < rhs->mMinDepth;
+ }
+};
+
+void LLReflectionMapManager::getReflectionMaps(std::vector<LLReflectionMap*>& maps)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+
+ U32 count = 0;
+ U32 lastIdx = 0;
+ for (U32 i = 0; count < maps.size() && i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mLastBindTime = gFrameTimeSeconds; // something wants to use this probe, indicate it's been requested
+ if (mProbes[i]->mCubeIndex != -1)
+ {
+ if (!mProbes[i]->mOccluded && mProbes[i]->mComplete)
+ {
+ maps[count++] = mProbes[i];
+ modelview.affineTransform(mProbes[i]->mOrigin, oa);
+ mProbes[i]->mMinDepth = -oa.getF32ptr()[2] - mProbes[i]->mRadius;
+ mProbes[i]->mMaxDepth = -oa.getF32ptr()[2] + mProbes[i]->mRadius;
+ }
+ }
+ else
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+ lastIdx = i;
+ }
+
+ // set remaining probe indices to -1
+ for (U32 i = lastIdx+1; i < mProbes.size(); ++i)
+ {
+ mProbes[i]->mProbeIndex = -1;
+ }
+
+ if (count > 1)
+ {
+ std::sort(maps.begin(), maps.begin() + count, CompareProbeDepth());
+ }
+
+ for (U32 i = 0; i < count; ++i)
+ {
+ maps[i]->mProbeIndex = i;
+ }
+
+ // null terminate list
+ if (count < maps.size())
+ {
+ maps[count] = nullptr;
+ }
+}
+
+LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* group)
+{
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_VOLUME)
+ {
+ OctreeNode* node = group->getOctreeNode();
+ F32 size = node->getSize().getF32ptr()[0];
+ if (size >= 15.f && size <= 17.f)
+ {
+ return addProbe(group);
+ }
+ }
+
+ return nullptr;
+}
+
+LLReflectionMap* LLReflectionMapManager::registerViewerObject(LLViewerObject* vobj)
+{
+ llassert(vobj != nullptr);
+
+ LLReflectionMap* probe = new LLReflectionMap();
+ probe->mViewerObject = vobj;
+ probe->mOrigin.load3(vobj->getPositionAgent().mV);
+
+ if (gCubeSnapshot)
+ { //snapshot is in progress, mProbes is being iterated over, defer insertion until next update
+ mCreateList.push_back(probe);
+ }
+ else
+ {
+ mProbes.push_back(probe);
+ }
+
+ return probe;
+}
+
+S32 LLReflectionMapManager::allocateCubeIndex()
+{
+ if (!mCubeFree.empty())
+ {
+ S32 ret = mCubeFree.front();
+ mCubeFree.pop_front();
+ return ret;
+ }
+
+ return -1;
+}
+
+void LLReflectionMapManager::deleteProbe(U32 i)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ LLReflectionMap* probe = mProbes[i];
+
+ llassert(probe != mDefaultProbe);
+
+ if (probe->mCubeIndex != -1)
+ { // mark the cube index used by this probe as being free
+ mCubeFree.push_back(probe->mCubeIndex);
+ }
+ if (mUpdatingProbe == probe)
+ {
+ mUpdatingProbe = nullptr;
+ mUpdatingFace = 0;
+ }
+
+ // remove from any Neighbors lists
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end());
+ other->mNeighbors.erase(iter);
+ }
+
+ mProbes.erase(mProbes.begin() + i);
+}
+
+
+void LLReflectionMapManager::doProbeUpdate()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(mUpdatingProbe != nullptr);
+
+ updateProbeFace(mUpdatingProbe, mUpdatingFace);
+
+ bool debug_updates = gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PROBE_UPDATES) && mUpdatingProbe->mViewerObject;
+
+ if (++mUpdatingFace == 6)
+ {
+ if (debug_updates)
+ {
+ mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 1, 1));
+ }
+ updateNeighbors(mUpdatingProbe);
+ mUpdatingFace = 0;
+ if (isRadiancePass())
+ {
+ mUpdatingProbe->mComplete = true;
+ mUpdatingProbe = nullptr;
+ mRadiancePass = false;
+ }
+ else
+ {
+ mRadiancePass = true;
+ }
+ }
+ else if (debug_updates)
+ {
+ mUpdatingProbe->mViewerObject->setDebugText(llformat("%.1f", (F32)gFrameTimeSeconds), LLColor4(1, 1, 0, 1));
+ }
+}
+
+// Do the reflection map update render passes.
+// For every 12 calls of this function, one complete reflection probe radiance map and irradiance map is generated
+// First six passes render the scene with direct lighting only into a scratch space cube map at the end of the cube map array and generate
+// a simple mip chain (not convolution filter).
+// At the end of these passes, an irradiance map is generated for this probe and placed into the irradiance cube map array at the index for this probe
+// The next six passes render the scene with both radiance and irradiance into the same scratch space cube map and generate a simple mip chain.
+// At the end of these passes, a radiance map is generated for this probe and placed into the radiance cube map array at the index for this probe.
+// In effect this simulates single-bounce lighting.
+void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face)
+{
+ // hacky hot-swap of camera specific render targets
+ gPipeline.mRT = &gPipeline.mAuxillaryRT;
+
+ mLightScale = 1.f;
+ static LLCachedControl<F32> max_local_light_ambiance(gSavedSettings, "RenderReflectionProbeMaxLocalLightAmbiance", 8.f);
+ if (!isRadiancePass() && probe->getAmbiance() > max_local_light_ambiance)
+ {
+ mLightScale = max_local_light_ambiance / probe->getAmbiance();
+ }
+
+ if (probe == mDefaultProbe)
+ {
+ touch_default_probe(probe);
+
+ gPipeline.pushRenderTypeMask();
+
+ //only render sky, water, terrain, and clouds
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::END_RENDER_TYPES);
+
+ probe->update(mRenderTarget.getWidth(), face);
+
+ gPipeline.popRenderTypeMask();
+ }
+ else
+ {
+ probe->update(mRenderTarget.getWidth(), face);
+ }
+
+ gPipeline.mRT = &gPipeline.mMainRT;
+
+ S32 sourceIdx = mReflectionProbeCount;
+
+ if (probe != mUpdatingProbe)
+ { // this is the "realtime" probe that's updating every frame, use the secondary scratch space channel
+ sourceIdx += 1;
+ }
+
+ gGL.setColorMask(true, true);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
+ LLGLDisable blend(GL_BLEND);
+
+ // downsample to placeholder map
+ {
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.matrixMode(gGL.MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ gGL.flush();
+ U32 res = mProbeResolution * 2;
+
+ static LLStaticHashedString resScale("resScale");
+ static LLStaticHashedString direction("direction");
+ static LLStaticHashedString znear("znear");
+ static LLStaticHashedString zfar("zfar");
+
+ LLRenderTarget* screen_rt = &gPipeline.mAuxillaryRT.screen;
+
+ // perform a gaussian blur on the super sampled render before downsampling
+ {
+ gGaussianProgram.bind();
+ gGaussianProgram.uniform1f(resScale, 1.f / (mProbeResolution * 2));
+ S32 diffuseChannel = gGaussianProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
+
+ // horizontal
+ gGaussianProgram.uniform2f(direction, 1.f, 0.f);
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ mRenderTarget.bindTarget();
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mRenderTarget.flush();
+
+ // vertical
+ gGaussianProgram.uniform2f(direction, 0.f, 1.f);
+ gGL.getTexUnit(diffuseChannel)->bind(&mRenderTarget);
+ screen_rt->bindTarget();
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ screen_rt->flush();
+ }
+
+
+ S32 mips = log2((F32)mProbeResolution) + 0.5f;
+
+ gReflectionMipProgram.bind();
+ S32 diffuseChannel = gReflectionMipProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_TEXTURE);
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip");
+ mMipChain[i].bindTarget();
+ if (i == 0)
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(screen_rt);
+ }
+ else
+ {
+ gGL.getTexUnit(diffuseChannel)->bind(&(mMipChain[i - 1]));
+ }
+
+
+ gReflectionMipProgram.uniform1f(resScale, 1.f/(mProbeResolution*2));
+
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ res /= 2;
+
+ S32 mip = i - (mMipChain.size() - mips);
+
+ if (mip >= 0)
+ {
+ LL_PROFILE_GPU_ZONE("probe mip copy");
+ mTexture->bind(0);
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, sourceIdx * 6 + face, 0, 0, res, res);
+ //if (i == 0)
+ //{
+ //glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, mip, 0, 0, probe->mCubeIndex * 6 + face, 0, 0, res, res);
+ //}
+ mTexture->unbind();
+ }
+ mMipChain[i].flush();
+ }
+
+ gGL.popMatrix();
+ gGL.matrixMode(gGL.MM_MODELVIEW);
+ gGL.popMatrix();
+
+ gGL.getTexUnit(diffuseChannel)->unbind(LLTexUnit::TT_TEXTURE);
+ gReflectionMipProgram.unbind();
+ }
+
+ if (face == 5)
+ {
+ mMipChain[0].bindTarget();
+ static LLStaticHashedString sSourceIdx("sourceIdx");
+
+ if (isRadiancePass())
+ {
+ //generate radiance map (even if this is not the irradiance map, we need the mip chain for the irradiance map)
+ gRadianceGenProgram.bind();
+ mVertexBuffer->setBuffer();
+
+ S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+ gRadianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
+ gRadianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
+
+ U32 res = mMipChain[0].getWidth();
+
+ for (int i = 0; i < mMipChain.size(); ++i)
+ {
+ LL_PROFILE_GPU_ZONE("probe radiance gen");
+ static LLStaticHashedString sMipLevel("mipLevel");
+ static LLStaticHashedString sRoughness("roughness");
+ static LLStaticHashedString sWidth("u_width");
+
+ gRadianceGenProgram.uniform1f(sRoughness, (F32)i / (F32)(mMipChain.size() - 1));
+ gRadianceGenProgram.uniform1f(sMipLevel, i);
+ gRadianceGenProgram.uniform1i(sWidth, mProbeResolution);
+
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ }
+
+ if (i != mMipChain.size() - 1)
+ {
+ res /= 2;
+ glViewport(0, 0, res, res);
+ }
+ }
+
+ gRadianceGenProgram.unbind();
+ }
+ else
+ {
+ //generate irradiance map
+ gIrradianceGenProgram.bind();
+ S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ mTexture->bind(channel);
+
+ gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx);
+ gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD);
+
+ mVertexBuffer->setBuffer();
+ int start_mip = 0;
+ // find the mip target to start with based on irradiance map resolution
+ for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip)
+ {
+ if (mMipChain[start_mip].getWidth() == LL_IRRADIANCE_MAP_RESOLUTION)
+ {
+ break;
+ }
+ }
+
+ //for (int i = start_mip; i < mMipChain.size(); ++i)
+ {
+ int i = start_mip;
+ LL_PROFILE_GPU_ZONE("probe irradiance gen");
+ glViewport(0, 0, mMipChain[i].getWidth(), mMipChain[i].getHeight());
+ for (int cf = 0; cf < 6; ++cf)
+ { // for each cube face
+ LLCoordFrame frame;
+ frame.lookAt(LLVector3(0, 0, 0), LLCubeMapArray::sClipToCubeLookVecs[cf], LLCubeMapArray::sClipToCubeUpVecs[cf]);
+
+ F32 mat[16];
+ frame.getOpenGLRotation(mat);
+ gGL.loadMatrix(mat);
+
+ mVertexBuffer->drawArrays(gGL.TRIANGLE_STRIP, 0, 4);
+
+ S32 res = mMipChain[i].getWidth();
+ mIrradianceMaps->bind(channel);
+ glCopyTexSubImage3D(GL_TEXTURE_CUBE_MAP_ARRAY, i - start_mip, 0, 0, probe->mCubeIndex * 6 + cf, 0, 0, res, res);
+ mTexture->bind(channel);
+ }
+ }
+ }
+
+ mMipChain[0].flush();
+
+ gIrradianceGenProgram.unbind();
+ }
+}
+
+void LLReflectionMapManager::reset()
+{
+ mReset = true;
+}
+
+void LLReflectionMapManager::pause()
+{
+ mPaused = true;
+}
+
+void LLReflectionMapManager::resume()
+{
+ mPaused = false;
+}
+
+void LLReflectionMapManager::shift(const LLVector4a& offset)
+{
+ for (auto& probe : mProbes)
+ {
+ probe->mOrigin.add(offset);
+ }
+}
+
+void LLReflectionMapManager::updateNeighbors(LLReflectionMap* probe)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mDefaultProbe == probe)
+ {
+ return;
+ }
+
+ //remove from existing neighbors
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - clear");
+
+ for (auto& other : probe->mNeighbors)
+ {
+ auto const & iter = std::find(other->mNeighbors.begin(), other->mNeighbors.end(), probe);
+ llassert(iter != other->mNeighbors.end()); // <--- bug davep if this ever happens, something broke badly
+ other->mNeighbors.erase(iter);
+ }
+
+ probe->mNeighbors.clear();
+ }
+
+ // search for new neighbors
+ if (probe->isRelevant())
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmun - search");
+ for (auto& other : mProbes)
+ {
+ if (other != mDefaultProbe && other != probe)
+ {
+ if (other->isRelevant() && probe->intersects(other))
+ {
+ probe->mNeighbors.push_back(other);
+ other->mNeighbors.push_back(probe);
+ }
+ }
+ }
+ }
+}
+
+void LLReflectionMapManager::updateUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+
+ // structure for packing uniform buffer object
+ // see class3/deferred/reflectionProbeF.glsl
+ struct ReflectionProbeData
+ {
+ // for box probes, matrix that transforms from camera space to a [-1, 1] cube representing the bounding box of
+ // the box probe
+ LLMatrix4 refBox[LL_MAX_REFLECTION_PROBE_COUNT];
+
+ // for sphere probes, origin (xyz) and radius (w) of refmaps in clip space
+ LLVector4 refSphere[LL_MAX_REFLECTION_PROBE_COUNT];
+
+ // extra parameters
+ // x - irradiance scale
+ // y - radiance scale
+ // z - fade in
+ // w - znear
+ LLVector4 refParams[LL_MAX_REFLECTION_PROBE_COUNT];
+
+ // indices used by probe:
+ // [i][0] - cubemap array index for this probe
+ // [i][1] - index into "refNeighbor" for probes that intersect this probe
+ // [i][2] - number of probes that intersect this probe, or -1 for no neighbors
+ // [i][3] - priority (probe type stored in sign bit - positive for spheres, negative for boxes)
+ GLint refIndex[LL_MAX_REFLECTION_PROBE_COUNT][4];
+
+ // list of neighbor indices
+ GLint refNeighbor[4096];
+
+ GLint refBucket[256][4]; //lookup table for which index to start with for the given Z depth
+ // numbrer of active refmaps
+ GLint refmapCount;
+ };
+
+ mReflectionMaps.resize(mReflectionProbeCount);
+ getReflectionMaps(mReflectionMaps);
+
+ ReflectionProbeData rpd;
+
+ F32 minDepth[256];
+
+ for (int i = 0; i < 256; ++i)
+ {
+ rpd.refBucket[i][0] = mReflectionProbeCount;
+ rpd.refBucket[i][1] = mReflectionProbeCount;
+ rpd.refBucket[i][2] = mReflectionProbeCount;
+ rpd.refBucket[i][3] = mReflectionProbeCount;
+ minDepth[i] = FLT_MAX;
+ }
+
+ // load modelview matrix into matrix 4a
+ LLMatrix4a modelview;
+ modelview.loadu(gGLModelView);
+ LLVector4a oa; // scratch space for transformed origin
+
+ S32 count = 0;
+ U32 nc = 0; // neighbor "cursor" - index into refNeighbor to start writing the next probe's list of neighbors
+
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale, should_auto_adjust);
+
+ bool is_ambiance_pass = gCubeSnapshot && !isRadiancePass();
+ F32 ambscale = is_ambiance_pass ? 0.f : 1.f;
+ F32 radscale = is_ambiance_pass ? 0.5f : 1.f;
+
+ for (auto* refmap : mReflectionMaps)
+ {
+ if (refmap == nullptr)
+ {
+ break;
+ }
+
+ if (refmap != mDefaultProbe)
+ {
+ // bucket search data
+ // theory of operation:
+ // 1. Determine minimum and maximum depth of each influence volume and store in mDepth (done in getReflectionMaps)
+ // 2. Sort by minimum depth
+ // 3. Prepare a bucket for each 1m of depth out to 256m
+ // 4. For each bucket, store the index of the nearest probe that might influence pixels in that bucket
+ // 5. In the shader, lookup the bucket for the pixel depth to get the index of the first probe that could possibly influence
+ // the current pixel.
+ int depth_min = llclamp(llfloor(refmap->mMinDepth), 0, 255);
+ int depth_max = llclamp(llfloor(refmap->mMaxDepth), 0, 255);
+ for (U32 i = depth_min; i <= depth_max; ++i)
+ {
+ if (refmap->mMinDepth < minDepth[i])
+ {
+ minDepth[i] = refmap->mMinDepth;
+ rpd.refBucket[i][0] = refmap->mProbeIndex;
+ }
+ }
+ }
+
+ llassert(refmap->mProbeIndex == count);
+ llassert(mReflectionMaps[refmap->mProbeIndex] == refmap);
+
+ llassert(refmap->mCubeIndex >= 0); // should always be true, if not, getReflectionMaps is bugged
+
+ {
+ if (refmap->mViewerObject)
+ { // have active manual probes live-track the object they're associated with
+ refmap->mOrigin.load3(refmap->mViewerObject->getPositionAgent().mV);
+ refmap->mRadius = refmap->mViewerObject->getScale().mV[0] * 0.5f;
+
+ }
+ modelview.affineTransform(refmap->mOrigin, oa);
+ rpd.refSphere[count].set(oa.getF32ptr());
+ rpd.refSphere[count].mV[3] = refmap->mRadius;
+ }
+
+ rpd.refIndex[count][0] = refmap->mCubeIndex;
+ llassert(nc % 4 == 0);
+ rpd.refIndex[count][1] = nc / 4;
+ rpd.refIndex[count][3] = refmap->mPriority;
+
+ // for objects that are reflection probes, use the volume as the influence volume of the probe
+ // only possibile influence volumes are boxes and spheres, so detect boxes and treat everything else as spheres
+ if (refmap->getBox(rpd.refBox[count]))
+ { // negate priority to indicate this probe has a box influence volume
+ rpd.refIndex[count][3] = -rpd.refIndex[count][3];
+ }
+
+ rpd.refParams[count].set(
+ llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, // ambiance scale
+ radscale, // radiance scale
+ refmap->mFadeIn, // fade in weight
+ oa.getF32ptr()[2] - refmap->mRadius); // z near
+
+ S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors
+ {
+ //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors");
+ //pack neghbor list
+ const U32 max_neighbors = 64;
+ U32 neighbor_count = 0;
+
+ for (auto& neighbor : refmap->mNeighbors)
+ {
+ if (ni >= 4096)
+ { // out of space
+ break;
+ }
+
+ GLint idx = neighbor->mProbeIndex;
+ if (idx == -1 || neighbor->mOccluded || neighbor->mCubeIndex == -1)
+ {
+ continue;
+ }
+
+ // this neighbor may be sampled
+ rpd.refNeighbor[ni++] = idx;
+
+ neighbor_count++;
+ if (neighbor_count >= max_neighbors)
+ {
+ break;
+ }
+ }
+ }
+
+ if (nc == ni)
+ {
+ //no neighbors, tag as empty
+ rpd.refIndex[count][1] = -1;
+ }
+ else
+ {
+ rpd.refIndex[count][2] = ni - nc;
+
+ // move the cursor forward
+ nc = ni;
+ if (nc % 4 != 0)
+ { // jump to next power of 4 for compatibility with ivec4
+ nc += 4 - (nc % 4);
+ }
+ }
+
+
+ count++;
+ }
+
+#if 0
+ {
+ // fill in gaps in refBucket
+ S32 probe_idx = mReflectionProbeCount;
+
+ for (int i = 0; i < 256; ++i)
+ {
+ if (i < count)
+ { // for debugging, store depth of mReflectionsMaps[i]
+ rpd.refBucket[i][1] = (S32) (mReflectionMaps[i]->mDepth * 10);
+ }
+
+ if (rpd.refBucket[i][0] == mReflectionProbeCount)
+ {
+ rpd.refBucket[i][0] = probe_idx;
+ }
+ else
+ {
+ probe_idx = rpd.refBucket[i][0];
+ }
+ }
+ }
+#endif
+
+ rpd.refmapCount = count;
+
+ //copy rpd into uniform buffer object
+ if (mUBO == 0)
+ {
+ glGenBuffers(1, &mUBO);
+ }
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - update buffer");
+ glBindBuffer(GL_UNIFORM_BUFFER, mUBO);
+ glBufferData(GL_UNIFORM_BUFFER, sizeof(ReflectionProbeData), &rpd, GL_STREAM_DRAW);
+ glBindBuffer(GL_UNIFORM_BUFFER, 0);
+ }
+
+#if 0
+ if (!gCubeSnapshot)
+ {
+ for (auto& probe : mProbes)
+ {
+ LLViewerObject* vobj = probe->mViewerObject;
+ if (vobj)
+ {
+ F32 time = (F32)gFrameTimeSeconds - probe->mLastUpdateTime;
+ vobj->setDebugText(llformat("%d/%d/%d/%.1f - %.1f/%.1f", probe->mCubeIndex, probe->mProbeIndex, (U32) probe->mNeighbors.size(), probe->mMinDepth, probe->mMaxDepth, time), time > 1.f ? LLColor4::white : LLColor4::green);
+ }
+ }
+ }
+#endif
+}
+
+void LLReflectionMapManager::setUniforms()
+{
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ return;
+ }
+
+ if (mUBO == 0)
+ {
+ updateUniforms();
+ }
+ glBindBufferBase(GL_UNIFORM_BUFFER, 1, mUBO);
+}
+
+
+void renderReflectionProbe(LLReflectionMap* probe)
+{
+ if (probe->isRelevant())
+ {
+ F32* po = probe->mOrigin.getF32ptr();
+
+ //draw orange line from probe to neighbors
+ gGL.flush();
+ gGL.diffuseColor4f(1, 0.5f, 0, 1);
+ gGL.begin(gGL.LINES);
+ for (auto& neighbor : probe->mNeighbors)
+ {
+ if (probe->mViewerObject && neighbor->mViewerObject)
+ {
+ continue;
+ }
+
+ gGL.vertex3fv(po);
+ gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
+ }
+ gGL.end();
+ gGL.flush();
+
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(gGL.LINES);
+ for (auto& neighbor : probe->mNeighbors)
+ {
+ if (probe->mViewerObject && neighbor->mViewerObject)
+ {
+ gGL.vertex3fv(po);
+ gGL.vertex3fv(neighbor->mOrigin.getF32ptr());
+ }
+ }
+ gGL.end();
+ gGL.flush();
+ }
+
+#if 0
+ LLSpatialGroup* group = probe->mGroup;
+ if (group)
+ { // draw lines from corners of object aabb to reflection probe
+
+ const LLVector4a* bounds = group->getBounds();
+ LLVector4a o = bounds[0];
+
+ gGL.flush();
+ gGL.diffuseColor4f(0, 0, 1, 1);
+ F32* c = o.getF32ptr();
+
+ const F32* bc = bounds[0].getF32ptr();
+ const F32* bs = bounds[1].getF32ptr();
+
+ // daaw blue lines from corners to center of node
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] + bs[2]);
+
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] + bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] + bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.vertex3fv(c);
+ gGL.vertex3f(bc[0] - bs[0], bc[1] - bs[1], bc[2] - bs[2]);
+ gGL.end();
+
+ //draw yellow line from center of node to reflection probe origin
+ gGL.flush();
+ gGL.diffuseColor4f(1, 1, 0, 1);
+ gGL.begin(gGL.LINES);
+ gGL.vertex3fv(c);
+ gGL.vertex3fv(po);
+ gGL.end();
+ gGL.flush();
+ }
+#endif
+}
+
+void LLReflectionMapManager::renderDebug()
+{
+ gDebugProgram.bind();
+
+ for (auto& probe : mProbes)
+ {
+ renderReflectionProbe(probe);
+ }
+
+ gDebugProgram.unbind();
+}
+
+void LLReflectionMapManager::initReflectionMaps()
+{
+ U32 count = LL_MAX_REFLECTION_PROBE_COUNT;
+
+ if (mTexture.isNull() || mReflectionProbeCount != count || mReset)
+ {
+ mReset = false;
+ mReflectionProbeCount = count;
+ mProbeResolution = nhpo2(llclamp(gSavedSettings.getU32("RenderReflectionProbeResolution"), (U32)64, (U32)512));
+ mMaxProbeLOD = log2f(mProbeResolution) - 1.f; // number of mips - 1
+
+ if (mTexture.isNull() ||
+ mTexture->getWidth() != mProbeResolution ||
+ mReflectionProbeCount + 2 != mTexture->getCount())
+ {
+ mTexture = new LLCubeMapArray();
+
+ // store mReflectionProbeCount+2 cube maps, final two cube maps are used for render target and radiance map generation source)
+ mTexture->allocate(mProbeResolution, 3, mReflectionProbeCount + 2);
+
+ mIrradianceMaps = new LLCubeMapArray();
+ mIrradianceMaps->allocate(LL_IRRADIANCE_MAP_RESOLUTION, 3, mReflectionProbeCount, FALSE);
+ }
+
+ // reset probe state
+ mUpdatingFace = 0;
+ mUpdatingProbe = nullptr;
+ mRadiancePass = false;
+ mRealtimeRadiancePass = false;
+
+ // if default probe already exists, remember whether or not it's complete (SL-20498)
+ bool default_complete = mDefaultProbe.isNull() ? false : mDefaultProbe->mComplete;
+
+ for (auto& probe : mProbes)
+ {
+ probe->mLastUpdateTime = 0.f;
+ probe->mComplete = false;
+ probe->mProbeIndex = -1;
+ probe->mCubeArray = nullptr;
+ probe->mCubeIndex = -1;
+ probe->mNeighbors.clear();
+ }
+
+ mCubeFree.clear();
+ initCubeFree();
+
+ if (mDefaultProbe.isNull())
+ {
+ llassert(mProbes.empty()); // default probe MUST be the first probe created
+ mDefaultProbe = new LLReflectionMap();
+ mProbes.push_back(mDefaultProbe);
+ }
+
+ llassert(mProbes[0] == mDefaultProbe);
+
+ mDefaultProbe->mCubeIndex = 0;
+ mDefaultProbe->mCubeArray = mTexture;
+ mDefaultProbe->mDistance = 64.f;
+ mDefaultProbe->mRadius = 4096.f;
+ mDefaultProbe->mProbeIndex = 0;
+ mDefaultProbe->mComplete = default_complete;
+
+ touch_default_probe(mDefaultProbe);
+
+ }
+
+ if (mVertexBuffer.isNull())
+ {
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask);
+ buff->allocateBuffer(4, 0);
+
+ LLStrider<LLVector3> v;
+
+ buff->getVertexStrider(v);
+
+ v[0] = LLVector3(-1, -1, -1);
+ v[1] = LLVector3(1, -1, -1);
+ v[2] = LLVector3(-1, 1, -1);
+ v[3] = LLVector3(1, 1, -1);
+
+ buff->unmapBuffer();
+
+ mVertexBuffer = buff;
+ }
+}
+
+void LLReflectionMapManager::cleanup()
+{
+ mVertexBuffer = nullptr;
+ mRenderTarget.release();
+
+ mMipChain.clear();
+
+ mTexture = nullptr;
+ mIrradianceMaps = nullptr;
+
+ mProbes.clear();
+ mKillList.clear();
+ mCreateList.clear();
+
+ mReflectionMaps.clear();
+ mUpdatingFace = 0;
+
+ mDefaultProbe = nullptr;
+ mUpdatingProbe = nullptr;
+
+ glDeleteBuffers(1, &mUBO);
+ mUBO = 0;
+
+ // note: also called on teleport (not just shutdown), so make sure we're in a good "starting" state
+ initCubeFree();
+}
+
+void LLReflectionMapManager::doOcclusion()
+{
+ LLVector4a eye;
+ eye.load3(LLViewerCamera::instance().getOrigin().mV);
+
+ for (auto& probe : mProbes)
+ {
+ if (probe != nullptr && probe != mDefaultProbe)
+ {
+ probe->doOcclusion(eye);
+ }
+ }
+}
diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h
new file mode 100644
index 0000000000..b77a33da89
--- /dev/null
+++ b/indra/newview/llreflectionmapmanager.h
@@ -0,0 +1,204 @@
+/**
+ * @file llreflectionmapmanager.h
+ * @brief LLReflectionMapManager class declaration
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#pragma once
+
+#include "llreflectionmap.h"
+#include "llrendertarget.h"
+#include "llcubemaparray.h"
+#include "llcubemap.h"
+
+class LLSpatialGroup;
+class LLViewerObject;
+
+// number of reflection probes to keep in vram
+#define LL_MAX_REFLECTION_PROBE_COUNT 256
+
+// reflection probe resolution
+#define LL_IRRADIANCE_MAP_RESOLUTION 64
+
+// reflection probe mininum scale
+#define LL_REFLECTION_PROBE_MINIMUM_SCALE 1.f;
+
+class alignas(16) LLReflectionMapManager
+{
+ LL_ALIGN_NEW
+public:
+ enum class DetailLevel
+ {
+ STATIC_ONLY = 0,
+ STATIC_AND_DYNAMIC,
+ REALTIME = 2
+ };
+
+ // allocate an environment map of the given resolution
+ LLReflectionMapManager();
+
+ // release any GL state
+ void cleanup();
+
+ // maintain reflection probes
+ void update();
+
+ // add a probe for the given spatial group
+ LLReflectionMap* addProbe(LLSpatialGroup* group = nullptr);
+
+ // Populate "maps" with the N most relevant Reflection Maps where N is no more than maps.size()
+ // If less than maps.size() ReflectionMaps are available, will assign trailing elements to nullptr.
+ // maps -- presized array of Reflection Map pointers
+ void getReflectionMaps(std::vector<LLReflectionMap*>& maps);
+
+ // called by LLSpatialGroup constructor
+ // If spatial group should receive a Reflection Probe, will create one for the specified spatial group
+ LLReflectionMap* registerSpatialGroup(LLSpatialGroup* group);
+
+ // presently hacked into LLViewerObject::setTE
+ // Used by LLViewerObjects that are Reflection Probes
+ // vobj must not be null
+ // Guaranteed to not return null
+ LLReflectionMap* registerViewerObject(LLViewerObject* vobj);
+
+ // reset all state on the next update
+ void reset();
+
+ // pause all updates other than the default probe
+ void pause();
+
+ // unpause (see pause)
+ void resume();
+
+ // called on region crossing to "shift" probes into new coordinate frame
+ void shift(const LLVector4a& offset);
+
+ // debug display, called from llspatialpartition if reflection
+ // probe debug display is active
+ void renderDebug();
+
+ // call once at startup to allocate cubemap arrays
+ void initReflectionMaps();
+
+ // True if currently updating a radiance map, false if currently updating an irradiance map
+ bool isRadiancePass() { return mRadiancePass; }
+
+ // perform occlusion culling on all active reflection probes
+ void doOcclusion();
+
+private:
+ friend class LLPipeline;
+
+ // initialize mCubeFree array to default values
+ void initCubeFree();
+
+ // delete the probe with the given index in mProbes
+ void deleteProbe(U32 i);
+
+ // get a free cube index
+ // returns -1 if allocation failed
+ S32 allocateCubeIndex();
+
+ // update the neighbors of the given probe
+ void updateNeighbors(LLReflectionMap* probe);
+
+ // update UBO used for rendering (call only once per render pipe flush)
+ void updateUniforms();
+
+ // bind UBO used for rendering
+ void setUniforms();
+
+ // render target for cube snapshots
+ // used to generate mipmaps without doing a copy-to-texture
+ LLRenderTarget mRenderTarget;
+
+ std::vector<LLRenderTarget> mMipChain;
+
+ // storage for reflection probe radiance maps (plus two scratch space cubemaps)
+ LLPointer<LLCubeMapArray> mTexture;
+
+ // vertex buffer for pushing verts to filter shaders
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+
+ // storage for reflection probe irradiance maps
+ LLPointer<LLCubeMapArray> mIrradianceMaps;
+
+ // list of free cubemap indices
+ std::list<S32> mCubeFree;
+
+ // perform an update on the currently updating Probe
+ void doProbeUpdate();
+
+ // update the specified face of the specified probe
+ void updateProbeFace(LLReflectionMap* probe, U32 face);
+
+ // list of active reflection maps
+ std::vector<LLPointer<LLReflectionMap> > mProbes;
+
+ // list of reflection maps to kill
+ std::vector<LLPointer<LLReflectionMap> > mKillList;
+
+ // list of reflection maps to create
+ std::vector<LLPointer<LLReflectionMap> > mCreateList;
+
+ // handle to UBO
+ U32 mUBO = 0;
+
+ // list of maps being used for rendering
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
+ LLReflectionMap* mUpdatingProbe = nullptr;
+ U32 mUpdatingFace = 0;
+
+ // if true, we're generating the radiance map for the current probe, otherwise we're generating the irradiance map.
+ // Update sequence should be to generate the irradiance map from render of the world that has no irradiance,
+ // then generate the radiance map from a render of the world that includes irradiance.
+ // This should avoid feedback loops and ensure that the colors in the radiance maps match the colors in the environment.
+ bool mRadiancePass = false;
+
+ // same as above, but for the realtime probe.
+ // Realtime probes should update all six sides of the irradiance map on "odd" frames and all six sides of the
+ // radiance map on "even" frames.
+ bool mRealtimeRadiancePass = false;
+
+ LLPointer<LLReflectionMap> mDefaultProbe; // default reflection probe to fall back to for pixels with no probe influences (should always be at cube index 0)
+
+ // number of reflection probes to use for rendering
+ U32 mReflectionProbeCount;
+
+ // resolution of reflection probes
+ U32 mProbeResolution = 128;
+
+ // maximum LoD of reflection probes (mip levels - 1)
+ F32 mMaxProbeLOD = 6.f;
+
+ // amount to scale local lights during an irradiance map update (set during updateProbeFace and used by LLPipeline)
+ F32 mLightScale = 1.f;
+
+ // if true, reset all probe render state on the next update (for teleports and sky changes)
+ bool mReset = false;
+
+ // if true, only update the default probe
+ bool mPaused = false;
+};
+
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 7089df677e..8d86e2de4c 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -177,7 +177,7 @@ LLRenderTarget& LLSceneMonitor::getCaptureTarget()
if(!mFrames[0])
{
mFrames[0] = new LLRenderTarget();
- mFrames[0]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ mFrames[0]->allocate(width, height, GL_RGB);
gGL.getTexUnit(0)->bind(mFrames[0]);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -187,7 +187,7 @@ LLRenderTarget& LLSceneMonitor::getCaptureTarget()
else if(!mFrames[1])
{
mFrames[1] = new LLRenderTarget();
- mFrames[1]->allocate(width, height, GL_RGB, false, false, LLTexUnit::TT_TEXTURE, true);
+ mFrames[1]->allocate(width, height, GL_RGB);
gGL.getTexUnit(0)->bind(mFrames[1]);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -360,7 +360,7 @@ void LLSceneMonitor::compare()
if(!mDiff)
{
mDiff = new LLRenderTarget();
- mDiff->allocate(width, height, GL_RGBA, false, false, LLTexUnit::TT_TEXTURE, true);
+ mDiff->allocate(width, height, GL_RGBA);
generateDitheringTexture(width, height);
}
@@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate()
if(mDiffState == EXECUTE_DIFF)
{
- glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mQueryObject);
+ glBeginQuery(GL_SAMPLES_PASSED, mQueryObject);
}
gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff);
if(mDiffState == EXECUTE_DIFF)
{
- glEndQueryARB(GL_SAMPLES_PASSED_ARB);
+ glEndQuery(GL_SAMPLES_PASSED);
mDiffState = WAIT_ON_RESULT;
}
@@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult()
mDiffState = WAITING_FOR_NEXT_DIFF;
GLuint available = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available);
if(available)
{
GLuint count = 0;
- glGetQueryObjectuivARB(mQueryObject, GL_QUERY_RESULT_ARB, &count);
+ glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count);
mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face)
diff --git a/indra/newview/llsculptidsize.cpp b/indra/newview/llsculptidsize.cpp
index 9edd78bff0..5d051d0ebf 100644
--- a/indra/newview/llsculptidsize.cpp
+++ b/indra/newview/llsculptidsize.cpp
@@ -65,7 +65,7 @@ void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz)
pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
if (itLU.first == itLU.second)
{ //register
- llassert(mSizeInfo.get<tag_BY_DRAWABLE>().end() == mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable));
+ //llassert(mSizeInfo.get<tag_BY_DRAWABLE>().end() == mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable));
mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, boost::make_shared<SizeSum>(sz), sculptId));
total_size = sz;
}
@@ -85,29 +85,6 @@ void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz)
//trying insert the LLDrawable
mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, nfo.mSharedSizeSum, sculptId));
}
-
- static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
-
- if (0 != render_auto_mute_byte_limit && total_size > render_auto_mute_byte_limit)
- {
- pair_iter_iter_BY_SCULPT_ID_t it_eqr = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
- for (; it_eqr.first != it_eqr.second; ++it_eqr.first)
- {
- const Info &i = *it_eqr.first;
- LLVOVolume *pVVol = i.mDrawable->getVOVolume();
- if (pVVol
- && !pVVol->isDead()
- && pVVol->isAttachment()
- && !pVVol->getAvatar()->isSelf()
- && LLVOVolume::NO_LOD != pVVol->getLOD()
- )
- {
- addToUnloaded(sculptId);
- //immediately
- const_cast<LLDrawable*>(i.mDrawable)->unload();
- }
- }
- }
}
void LLSculptIDSize::dec(const LLDrawable *pdrawable)
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index cf9a80221b..d172a87b1d 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -62,6 +62,7 @@
#include "llfloatertools.h"
#include "llframetimer.h"
#include "llfocusmgr.h"
+#include "llgltfmateriallist.h"
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventorymodel.h"
@@ -1037,10 +1038,6 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab
// check to see if object is already in list
LLSelectNode *nodep = mSelectedObjects->findNode(objectp);
- // Reset (in anticipation of being set to an appropriate value by panel refresh, if they're up)
- //
- setTextureChannel(LLRender::DIFFUSE_MAP);
-
// if not in list, add it
if (!nodep)
{
@@ -1167,8 +1164,8 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp)
return;
}
- if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
- || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
+ if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner())
+ || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())))
{
// only select my own objects
return;
@@ -1745,6 +1742,7 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
bool texture_copied = false;
+ bool updated = false;
for (S32 te = 0; te < num_tes; ++te)
{
if (node->isTESelected(te))
@@ -1753,27 +1751,89 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
// without making any copies
if (!texture_copied)
{
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
texture_copied = true;
}
// apply texture for the selected faces
add(LLStatViewer::EDIT_TEXTURE, 1);
object->setTEImage(te, image);
- dialog_refresh_all();
-
- // send the update to the simulator
- object->sendTEUpdate();
+ updated = true;
}
}
+
+ if (updated) // not nessesary? sendTEUpdate update supposed to be done by sendfunc
+ {
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ object->sendTEUpdate();
+ }
}
}
+bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item)
+{
+ if (!item)
+ {
+ return false;
+ }
+
+ LLUUID asset_id = item->getAssetUUID();
+ if (asset_id.isNull())
+ {
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
+ bool material_copied_all_faces = true;
+
+ for (iterator iter = begin(); iter != end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ LLViewerObject* object = (*iter)->getObject();
+ if (!object)
+ {
+ continue;
+ }
+
+ S32 num_tes = llmin((S32)object->getNumTEs(), (S32)object->getNumFaces());
+ bool material_copied = false;
+ for (S32 te = 0; te < num_tes; ++te)
+ {
+ if (node->isTESelected(te))
+ {
+ //(no-copy), (no-modify), and (no-transfer) materials must be moved to the object's inventory only once
+ // without making any copies
+ if (!material_copied && asset_id.notNull())
+ {
+ material_copied = (bool)LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ }
+ if (!material_copied)
+ {
+ // Applying the material is not possible for this object given the current inventory
+ material_copied_all_faces = false;
+ break;
+ }
+
+ // apply texture for the selected faces
+ // blank out most override data on the server
+ //add(LLStatViewer::EDIT_TEXTURE, 1);
+ object->setRenderMaterialID(te, asset_id);
+ }
+ }
+ }
+
+ LLGLTFMaterialList::flushUpdates();
+
+ return material_copied_all_faces;
+}
+
+
//-----------------------------------------------------------------------------
// selectionSetImage()
//-----------------------------------------------------------------------------
// *TODO: re-arch texture applying out of lltooldraganddrop
-void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
+bool LLSelectMgr::selectionSetImage(const LLUUID& imageid)
{
// First for (no copy) textures and multiple object selection
LLViewerInventoryItem* item = gInventory.getItem(imageid);
@@ -1781,9 +1841,11 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
&& !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
&& (mSelectedObjects->getNumNodes() > 1) )
{
- LL_WARNS() << "Attempted to apply no-copy texture to multiple objects"
- << LL_ENDL;
- return;
+ LL_DEBUGS() << "Attempted to apply no-copy texture " << imageid
+ << " to multiple objects" << LL_ENDL;
+
+ LLNotificationsUtil::add("FailedToApplyTextureNoCopyToMultiple");
+ return false;
}
struct f : public LLSelectedTEFunctor
@@ -1793,27 +1855,31 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mImageID(id) {}
bool apply(LLViewerObject* objectp, S32 te)
{
- if(objectp && !objectp->permModify())
+ if(!objectp || !objectp->permModify())
{
return false;
}
+
+ // Might be better to run willObjectAcceptInventory
+ if (mItem && objectp->isAttachment())
+ {
+ const LLPermissions& perm = mItem->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return false;
+ }
+ }
+
if (mItem)
{
- if (te == -1) // all faces
- {
- LLToolDragAndDrop::dropTextureAllFaces(objectp,
- mItem,
- LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
- }
- else // one face
- {
- LLToolDragAndDrop::dropTextureOneFace(objectp,
- te,
- mItem,
- LLToolDragAndDrop::SOURCE_AGENT,
- LLUUID::null);
- }
+ LLToolDragAndDrop::dropTextureOneFace(objectp,
+ te,
+ mItem,
+ LLToolDragAndDrop::SOURCE_AGENT,
+ LLUUID::null);
}
else // not an inventory item
{
@@ -1858,6 +1924,121 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
}
} sendfunc(item);
getSelection()->applyToObjects(&sendfunc);
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// selectionSetGLTFMaterial()
+//-----------------------------------------------------------------------------
+bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id)
+{
+ // First for (no copy) textures and multiple object selection
+ LLViewerInventoryItem* item = gInventory.getItem(mat_id);
+ if (item
+ && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())
+ && (mSelectedObjects->getNumNodes() > 1))
+ {
+ LL_DEBUGS() << "Attempted to apply no-copy material " << mat_id
+ << "to multiple objects" << LL_ENDL;
+
+ LLNotificationsUtil::add("FailedToApplyGLTFNoCopyToMultiple");
+ return false;
+ }
+
+ struct f : public LLSelectedTEFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ LLUUID mMatId;
+ bool material_copied_any_face = false;
+ bool material_copied_all_faces = true;
+ f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mMatId(id) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (!objectp || !objectp->permModify())
+ {
+ return false;
+ }
+ if (mItem && objectp->isAttachment())
+ {
+ const LLPermissions& perm = mItem->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ if (!unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return false;
+ }
+ }
+ LLUUID asset_id = mMatId;
+ if (mItem)
+ {
+ // If success, the material may be copied into the object's inventory
+ BOOL success = LLToolDragAndDrop::handleDropMaterialProtections(objectp, mItem, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ if (!success)
+ {
+ return false;
+ }
+ asset_id = mItem->getAssetUUID();
+ if (asset_id.isNull())
+ {
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+ }
+
+ // Blank out most override data on the object and send to server
+ objectp->setRenderMaterialID(te, asset_id);
+
+ return true;
+ }
+ };
+
+ bool success = true;
+ if (item &&
+ (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) ||
+ !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) ||
+ !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())
+ ))
+ {
+ success = success && getSelection()->applyRestrictedPbrMaterialToTEs(item);
+ }
+ else
+ {
+ f setfunc(item, mat_id);
+ success = success && getSelection()->applyToTEs(&setfunc);
+ }
+
+ struct g : public LLSelectedObjectFunctor
+ {
+ LLViewerInventoryItem* mItem;
+ g(LLViewerInventoryItem* item) : mItem(item) {}
+ virtual bool apply(LLViewerObject* object)
+ {
+ if (object && !object->permModify())
+ {
+ return false;
+ }
+
+ if (!mItem)
+ {
+ // 1 particle effect per object
+ LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM, TRUE);
+ effectp->setSourceObject(gAgentAvatarp);
+ effectp->setTargetObject(object);
+ effectp->setDuration(LL_HUD_DUR_SHORT);
+ effectp->setColor(LLColor4U(gAgent.getEffectColor()));
+ }
+
+ dialog_refresh_all();
+ object->sendTEUpdate();
+ return true;
+ }
+ } sendfunc(item);
+ success = success && getSelection()->applyToObjects(&sendfunc);
+
+ LLGLTFMaterialList::flushUpdates();
+
+ return success;
}
//-----------------------------------------------------------------------------
@@ -2037,6 +2218,48 @@ BOOL LLSelectMgr::selectionRevertTextures()
return revert_successful;
}
+void LLSelectMgr::selectionRevertGLTFMaterials()
+{
+ struct f : public LLSelectedTEFunctor
+ {
+ LLObjectSelectionHandle mSelectedObjects;
+ f(LLObjectSelectionHandle sel) : mSelectedObjects(sel) {}
+ bool apply(LLViewerObject* objectp, S32 te)
+ {
+ if (objectp && !objectp->permModify())
+ {
+ return false;
+ }
+
+ LLSelectNode* nodep = mSelectedObjects->findNode(objectp);
+ if (nodep && te < (S32)nodep->mSavedGLTFMaterialIds.size())
+ {
+ // Restore base material
+ LLUUID asset_id = nodep->mSavedGLTFMaterialIds[te];
+
+ // Update material locally
+ objectp->setRenderMaterialID(te, asset_id, false /*wait for LLGLTFMaterialList update*/);
+ objectp->setTEGLTFMaterialOverride(te, nodep->mSavedGLTFOverrideMaterials[te]);
+
+ // Enqueue update to server
+ if (asset_id.notNull())
+ {
+ // Restore overrides and base material
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id, nodep->mSavedGLTFOverrideMaterials[te]);
+ }
+ else
+ {
+ //blank override out
+ LLGLTFMaterialList::queueApply(objectp, te, asset_id);
+ }
+
+ }
+ return true;
+ }
+ } setfunc(mSelectedObjects);
+ getSelection()->applyToTEs(&setfunc);
+}
+
void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
{
struct f : public LLSelectedTEFunctor
@@ -2065,8 +2288,20 @@ void LLSelectMgr::selectionSetBumpmap(U8 bumpmap, const LLUUID &image_id)
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ if (!object)
+ {
+ return;
+ }
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ BOOL attached = object->isAttachment();
+ if (attached && !unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -2125,8 +2360,20 @@ void LLSelectMgr::selectionSetShiny(U8 shiny, const LLUUID &image_id)
if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
LLViewerObject *object = mSelectedObjects->getFirstRootObject();
- if (!object) return;
- LLToolDragAndDrop::handleDropTextureProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
+ if (!object)
+ {
+ return;
+ }
+ const LLPermissions& perm = item->getPermissions();
+ BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
+ BOOL attached = object->isAttachment();
+ if (attached && !unrestricted)
+ {
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
+ return;
+ }
+ LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null);
}
getSelection()->applyToTEs(&setfunc);
@@ -5583,13 +5830,19 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
}
else
{
+ // save texture data as soon as we get texture perms first time
+ bool save_textures = !node->mValid;
if (node->mInventorySerial != inv_serial && node->getObject())
{
node->getObject()->dirtyInventory();
+
+ // Even if this isn't object's first udpate, inventory changed
+ // and some of the applied textures might have been in inventory
+ // so update texture list.
+ save_textures = true;
}
- // save texture data as soon as we get texture perms first time
- if (!node->mValid)
+ if (save_textures)
{
BOOL can_copy = FALSE;
BOOL can_transfer = FALSE;
@@ -5624,9 +5877,38 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
if (can_copy && can_transfer)
{
- // this should be the only place that saved textures is called
node->saveTextures(texture_ids);
}
+
+ if (can_copy && can_transfer && node->getObject()->getVolume())
+ {
+ uuid_vec_t material_ids;
+ gltf_materials_vec_t override_materials;
+ LLVOVolume* vobjp = (LLVOVolume*)node->getObject();
+ for (int i = 0; i < vobjp->getNumTEs(); ++i)
+ {
+ material_ids.push_back(vobjp->getRenderMaterialID(i));
+
+ // Make a copy to ensure we won't affect live material
+ // with any potential changes nor live changes will be
+ // reflected in a saved copy.
+ // Like changes from local material (reuses pointer) or
+ // from live editor (revert mechanics might modify this)
+ LLGLTFMaterial* old_override = node->getObject()->getTE(i)->getGLTFMaterialOverride();
+ if (old_override)
+ {
+ LLPointer<LLGLTFMaterial> mat = new LLGLTFMaterial(*old_override);
+ override_materials.push_back(mat);
+ }
+ else
+ {
+ override_materials.push_back(nullptr);
+ }
+ }
+ // processObjectProperties does not include overrides so this
+ // might need to be moved to LLGLTFMaterialOverrideDispatchHandler
+ node->saveGLTFMaterials(material_ids, override_materials);
+ }
}
node->mValid = TRUE;
@@ -6092,9 +6374,6 @@ void LLSelectMgr::renderSilhouettes(BOOL for_hud)
auto renderMeshSelection_f = [fogCfx, wireframe_selection](LLSelectNode* node, LLViewerObject* objectp, LLColor4 hlColor)
{
- //Need to because crash on ATI 3800 (and similar cards) MAINT-5018
- LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
if (shader)
@@ -6378,6 +6657,7 @@ LLSelectNode::LLSelectNode(const LLSelectNode& nodep)
}
saveTextures(nodep.mSavedTextures);
+ saveGLTFMaterials(nodep.mSavedGLTFMaterialIds, nodep.mSavedGLTFOverrideMaterials);
}
LLSelectNode::~LLSelectNode()
@@ -6511,6 +6791,27 @@ void LLSelectNode::saveTextures(const uuid_vec_t& textures)
}
}
+void LLSelectNode::saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials)
+{
+ if (mObject.notNull())
+ {
+ mSavedGLTFMaterialIds.clear();
+ mSavedGLTFOverrideMaterials.clear();
+
+ for (uuid_vec_t::const_iterator materials_it = materials.begin();
+ materials_it != materials.end(); ++materials_it)
+ {
+ mSavedGLTFMaterialIds.push_back(*materials_it);
+ }
+
+ for (gltf_materials_vec_t::const_iterator mat_it = override_materials.begin();
+ mat_it != override_materials.end(); ++mat_it)
+ {
+ mSavedGLTFOverrideMaterials.push_back(*mat_it);
+ }
+ }
+}
+
void LLSelectNode::saveTextureScaleRatios(LLRender::eTexIndex index_to_query)
{
mTextureScaleRatios.clear();
@@ -6730,15 +7031,8 @@ void LLSelectNode::renderOneSilhouette(const LLColor4 &color)
{
gGL.flush();
gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
- LLGLEnable fog(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
- LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
- glFogf(GL_FOG_START, d);
- glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
- glFogfv(GL_FOG_COLOR, fogCol.mV);
-
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
gGL.flush();
gGL.begin(LLRender::LINES);
{
@@ -7610,7 +7904,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
- cost += iter->second;
+ cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();
@@ -7632,7 +7926,7 @@ S32 LLObjectSelection::getSelectedObjectRenderCost()
for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
{
// add the cost of each individual texture in the linkset
- cost += iter->second;
+ cost += LLVOVolume::getTextureCost(*iter);
}
textures.clear();
@@ -8304,6 +8598,7 @@ DEF_DUMMY_CHECK_FUNCTOR(int)
DEF_DUMMY_CHECK_FUNCTOR(LLColor4)
DEF_DUMMY_CHECK_FUNCTOR(LLMediaEntry)
DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLMaterial>)
+DEF_DUMMY_CHECK_FUNCTOR(LLPointer<LLGLTFMaterial>)
DEF_DUMMY_CHECK_FUNCTOR(std::string)
DEF_DUMMY_CHECK_FUNCTOR(std::vector<std::string>)
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index 199141fc32..f89209b437 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -161,6 +161,8 @@ typedef enum e_selection_type
SELECT_TYPE_HUD
}ESelectType;
+typedef std::vector<LLPointer<LLGLTFMaterial> > gltf_materials_vec_t;
+
const S32 TE_SELECT_MASK_ALL = 0xFFFFFFFF;
// Contains information about a selected object, particularly which TEs are selected.
@@ -184,11 +186,19 @@ public:
LLViewerObject* getObject();
void setObject(LLViewerObject* object);
// *NOTE: invalidate stored textures and colors when # faces change
+ // Used by tools floater's color/texture pickers to restore changes
void saveColors();
void saveShinyColors();
void saveTextures(const uuid_vec_t& textures);
void saveTextureScaleRatios(LLRender::eTexIndex index_to_query);
+ // GLTF materials are applied to objects by ids,
+ // overrides get applied on top of materials resulting in
+ // final gltf material that users see.
+ // Ids get applied and restored by tools floater,
+ // overrides get applied in live material editor
+ void saveGLTFMaterials(const uuid_vec_t& materials, const gltf_materials_vec_t& override_materials);
+
BOOL allowOperationOnNode(PermissionBit op, U64 group_proxy_power) const;
public:
@@ -224,6 +234,8 @@ public:
std::vector<LLColor4> mSavedColors;
std::vector<LLColor4> mSavedShinyColors;
uuid_vec_t mSavedTextures;
+ uuid_vec_t mSavedGLTFMaterialIds;
+ gltf_materials_vec_t mSavedGLTFOverrideMaterials;
std::vector<LLVector3> mTextureScaleRatios;
std::vector<LLVector3> mSilhouetteVertices; // array of vertices to render silhouette of object
std::vector<LLVector3> mSilhouetteNormals; // array of normals to render silhouette of object
@@ -366,6 +378,17 @@ public:
* Then this only texture is used for all selected faces.
*/
void applyNoCopyTextureToTEs(LLViewerInventoryItem* item);
+ /*
+ * Multi-purpose function for applying PBR materials to the
+ * selected object or faces, any combination of copy/mod/transfer
+ * permission restrictions. This method moves the restricted
+ * material to the object's inventory and doesn't make a copy of the
+ * material for each face. Then this only material is used for
+ * all selected faces.
+ * Returns false if applying the material failed on one or more selected
+ * faces.
+ */
+ bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item);
ESelectType getSelectType() const { return mSelectType; }
@@ -605,11 +628,6 @@ public:
void saveSelectedShinyColors();
void saveSelectedObjectTextures();
- // Sets which texture channel to query for scale and rot of display
- // and depends on UI state of LLPanelFace when editing
- void setTextureChannel(LLRender::eTexIndex texIndex) { mTextureChannel = texIndex; }
- LLRender::eTexIndex getTextureChannel() { return mTextureChannel; }
-
void selectionUpdatePhysics(BOOL use_physics);
void selectionUpdateTemporary(BOOL is_temporary);
void selectionUpdatePhantom(BOOL is_ghost);
@@ -626,13 +644,15 @@ public:
void selectionSetDensity(F32 density);
void selectionSetRestitution(F32 restitution);
void selectionSetMaterial(U8 material);
- void selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ bool selectionSetImage(const LLUUID& imageid); // could be item or asset id
+ bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only
void selectionSetColor(const LLColor4 &color);
void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels
void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel
void selectionRevertColors();
void selectionRevertShinyColors();
BOOL selectionRevertTextures();
+ void selectionRevertGLTFMaterials();
void selectionSetBumpmap( U8 bumpmap, const LLUUID &image_id );
void selectionSetTexGen( U8 texgen );
void selectionSetShiny( U8 shiny, const LLUUID &image_id );
diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp
index eaa23d6a6c..42587658a6 100644
--- a/indra/newview/llsettingsvo.cpp
+++ b/indra/newview/llsettingsvo.cpp
@@ -68,6 +68,8 @@
#undef VERIFY_LEGACY_CONVERSION
+extern BOOL gCubeSnapshot;
+
//=========================================================================
namespace
{
@@ -137,7 +139,7 @@ void LLSettingsVOBase::createNewInventoryItem(LLSettingsType::type_e stype, cons
void LLSettingsVOBase::createInventoryItem(const LLSettingsBase::ptr_t &settings, const LLUUID &parent_id, std::string settings_name, inventory_result_fn callback)
{
- U32 nextOwnerPerm = LLPermissions::DEFAULT.getMaskNextOwner();
+ U32 nextOwnerPerm = LLFloaterPerms::getNextOwnerPerms("Settings");
createInventoryItem(settings, nextOwnerPerm, parent_id, settings_name, callback);
}
@@ -248,9 +250,11 @@ void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings
LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),
- [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response) {
+ [settings, callback](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)
+ {
LLSettingsVOBase::onAgentAssetUploadComplete(itemId, newAssetId, newItemId, response, settings, callback);
- });
+ },
+ nullptr);
LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
}
@@ -279,9 +283,11 @@ void LLSettingsVOBase::updateInventoryItem(const LLSettingsBase::ptr_t &settings
LLSDSerialize::serialize(settingdata, buffer, LLSDSerialize::LLSD_NOTATION);
LLResourceUploadInfo::ptr_t uploadInfo = std::make_shared<LLBufferedAssetUploadInfo>(object_id, inv_item_id, LLAssetType::AT_SETTINGS, buffer.str(),
- [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response) {
- LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback);
- });
+ [settings, callback](LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)
+ {
+ LLSettingsVOBase::onTaskAssetUploadComplete(itemId, taskId, newAssetId, response, settings, callback);
+ },
+ nullptr);
LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo);
}
@@ -681,59 +687,108 @@ void LLSettingsVOSky::updateSettings()
void LLSettingsVOSky::applySpecial(void *ptarget, bool force)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER;
- LLVector4 light_direction = LLEnvironment::instance().getClampedLightNorm();
+ LLVector3 light_direction = LLVector3(LLEnvironment::instance().getClampedLightNorm().mV);
+
+ bool irradiance_pass = gCubeSnapshot && !gPipeline.mReflectionMapManager.isRadiancePass();
LLShaderUniforms* shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_DEFAULT];
{
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, LLViewerCamera::getInstance()->getOrigin());
}
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_SKY];
- {
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
- // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
- LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
- LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
+ shader->uniform3fv(LLViewerShaderMgr::LIGHTNORM, light_direction);
- // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
- // Keep in Sync!
- // * indra\newview\llsettingsvo.cpp
- // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
- // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
- cloud_scroll[0] = -cloud_scroll[0];
- vect_c_p_d1 += cloud_scroll;
- shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, vect_c_p_d1);
+ // Legacy? SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate")
+ LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
+ LLVector4 cloud_scroll( LLEnvironment::instance().getCloudScrollDelta() );
- LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
+ // Keep in Sync!
+ // * indra\newview\llsettingsvo.cpp
+ // * indra\newview\app_settings\shaders\class2\windlight\cloudsV.glsl
+ // * indra\newview\app_settings\shaders\class1\deferred\cloudsV.glsl
+ cloud_scroll[0] = -cloud_scroll[0];
+ vect_c_p_d1 += cloud_scroll;
+ shader->uniform3fv(LLShaderMgr::CLOUD_POS_DENSITY1, LLVector3(vect_c_p_d1.mV));
- LLVector4 sunDiffuse = LLVector4(LLVector3(psky->getSunlightColor().mV));
- LLVector4 moonDiffuse = LLVector4(LLVector3(psky->getMoonlightColor().mV));
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- shader->uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
- shader->uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
+ // TODO -- make these getters return vec3s
+ LLVector3 sunDiffuse = LLVector3(psky->getSunlightColor().mV);
+ LLVector3 moonDiffuse = LLVector3(psky->getMoonlightColor().mV);
+
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sunDiffuse);
+ shader->uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, moonDiffuse);
+
+ shader->uniform3fv(LLShaderMgr::CLOUD_COLOR, LLVector3(psky->getCloudColor().mV));
- LLVector4 cloud_color(LLVector3(psky->getCloudColor().mV), 1.0);
- shader->uniform4fv(LLShaderMgr::CLOUD_COLOR, cloud_color);
- }
-
shader = &((LLShaderUniforms*)ptarget)[LLGLSLShader::SG_ANY];
shader->uniform1f(LLShaderMgr::SCENE_LIGHT_STRENGTH, mSceneLightStrength);
- LLColor4 ambient(getTotalAmbient());
- shader->uniform4fv(LLShaderMgr::AMBIENT, LLVector4(ambient.mV));
+ LLColor3 ambient(getTotalAmbient());
+
+ F32 g = getGamma();
+
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ static LLCachedControl<F32> auto_adjust_ambient_scale(gSavedSettings, "RenderSkyAutoAdjustAmbientScale", 0.75f);
+ static LLCachedControl<F32> auto_adjust_hdr_scale(gSavedSettings, "RenderSkyAutoAdjustHDRScale", 2.f);
+ static LLCachedControl<F32> auto_adjust_blue_horizon_scale(gSavedSettings, "RenderSkyAutoAdjustBlueHorizonScale", 1.f);
+ static LLCachedControl<F32> auto_adjust_blue_density_scale(gSavedSettings, "RenderSkyAutoAdjustBlueDensityScale", 1.f);
+ static LLCachedControl<F32> auto_adjust_sun_color_scale(gSavedSettings, "RenderSkyAutoAdjustSunColorScale", 1.f);
+ static LLCachedControl<F32> auto_adjust_probe_ambiance(gSavedSettings, "RenderSkyAutoAdjustProbeAmbiance", 1.f);
+ static LLCachedControl<F32> sunlight_scale(gSavedSettings, "RenderSkySunlightScale", 1.5f);
+ static LLCachedControl<F32> ambient_scale(gSavedSettings, "RenderSkyAmbientScale", 1.5f);
+
+ shader->uniform1f(LLShaderMgr::SKY_SUNLIGHT_SCALE, sunlight_scale);
+ shader->uniform1f(LLShaderMgr::SKY_AMBIENT_SCALE, ambient_scale);
+
+ static LLCachedControl<F32> cloud_shadow_scale(gSavedSettings, "RenderCloudShadowAmbianceFactor", 0.125f);
+ F32 probe_ambiance = getTotalReflectionProbeAmbiance(cloud_shadow_scale);
+
+ if (irradiance_pass)
+ { // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue)
+ shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3::zero.mV);
+ }
+ else
+ {
+ if (psky->getReflectionProbeAmbiance() != 0.f)
+ {
+ shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
+ shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, sqrtf(g)*2.0); // use a modifier here so 1.0 maps to the "most desirable" default and the maximum value doesn't go off the rails
+ }
+ else if (psky->canAutoAdjust() && should_auto_adjust)
+ { // auto-adjust legacy sky to take advantage of probe ambiance
+ shader->uniform3fv(LLShaderMgr::AMBIENT, (ambient * auto_adjust_ambient_scale).mV);
+ shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, auto_adjust_hdr_scale);
+ LLColor3 blue_horizon = getBlueHorizon() * auto_adjust_blue_horizon_scale;
+ LLColor3 blue_density = getBlueDensity() * auto_adjust_blue_density_scale;
+ LLColor3 sun_diffuse = getSunDiffuse() * auto_adjust_sun_color_scale;
+
+ shader->uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, sun_diffuse.mV);
+ shader->uniform3fv(LLShaderMgr::BLUE_DENSITY, blue_density.mV);
+ shader->uniform3fv(LLShaderMgr::BLUE_HORIZON, blue_horizon.mV);
+
+ LLSettingsSky::sAutoAdjustProbeAmbiance = auto_adjust_probe_ambiance;
+ probe_ambiance = auto_adjust_probe_ambiance; // NOTE -- must match LLSettingsSky::getReflectionProbeAmbiance value for "auto_adjust" true
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::SKY_HDR_SCALE, 1.f);
+ shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV));
+ }
+ }
+
+ shader->uniform1f(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, probe_ambiance);
shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, getIsSunUp() ? 1 : 0);
shader->uniform1f(LLShaderMgr::SUN_MOON_GLOW_FACTOR, getSunMoonGlowFactor());
shader->uniform1f(LLShaderMgr::DENSITY_MULTIPLIER, getDensityMultiplier());
shader->uniform1f(LLShaderMgr::DISTANCE_MULTIPLIER, getDistanceMultiplier());
- F32 g = getGamma();
- F32 display_gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
-
shader->uniform1f(LLShaderMgr::GAMMA, g);
- shader->uniform1f(LLShaderMgr::DISPLAY_GAMMA, display_gamma);
}
LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
@@ -772,6 +827,7 @@ LLSettingsSky::parammapping_t LLSettingsVOSky::getParameterMap() const
param_map[SETTING_SKY_DROPLET_RADIUS] = DefaultParam(LLShaderMgr::DROPLET_RADIUS, sky_defaults[SETTING_SKY_DROPLET_RADIUS]);
param_map[SETTING_SKY_ICE_LEVEL] = DefaultParam(LLShaderMgr::ICE_LEVEL, sky_defaults[SETTING_SKY_ICE_LEVEL]);
+ param_map[SETTING_REFLECTION_PROBE_AMBIANCE] = DefaultParam(LLShaderMgr::REFLECTION_PROBE_AMBIANCE, sky_defaults[SETTING_REFLECTION_PROBE_AMBIANCE]);
// AdvancedAtmospherics TODO
// Provide mappings for new shader params here
}
@@ -935,7 +991,7 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
//transform water plane to eye space
glh::vec3f norm(0.f, 0.f, 1.f);
- glh::vec3f p(0.f, 0.f, water_height + 0.1f);
+ glh::vec3f p(0.f, 0.f, water_height);
F32 modelView[16];
for (U32 i = 0; i < 16; i++)
@@ -953,6 +1009,8 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
LLVector4 waterPlane(enorm.v[0], enorm.v[1], enorm.v[2], -ep.dot(enorm));
+ LLDrawPoolAlpha::sWaterPlane = waterPlane;
+
shader->uniform4fv(LLShaderMgr::WATER_WATERPLANE, waterPlane.mV);
LLVector4 light_direction = env.getClampedLightNorm();
@@ -967,14 +1025,16 @@ void LLSettingsVOWater::applySpecial(void *ptarget, bool force)
F32 waterFogDensity = env.getCurrentWater()->getModifiedWaterFogDensity(underwater);
shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, waterFogDensity);
- LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor(), 0.0f);
+ LLColor4 fog_color(env.getCurrentWater()->getWaterFogColor());
shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, fog_color.mV);
+ shader->uniform3fv(LLShaderMgr::WATER_FOGCOLOR_LINEAR, linearColor3(fog_color).mV);
+
F32 blend_factor = env.getCurrentWater()->getBlendFactor();
shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
// update to normal lightnorm, water shader itself will use rotated lightnorm as necessary
- shader->uniform4fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::LIGHTNORM, light_direction.mV);
}
}
@@ -997,13 +1057,6 @@ LLSettingsWater::parammapping_t LLSettingsVOWater::getParameterMap() const
{
static parammapping_t param_map;
- if (param_map.empty())
- {
- //LLSD water_defaults = LLSettingsWater::defaults();
- //param_map[SETTING_FOG_COLOR] = DefaultParam(LLShaderMgr::WATER_FOGCOLOR, water_defaults[SETTING_FOG_COLOR]);
- // let this get set by LLSettingsVOWater::applySpecial so that it can properly reflect the underwater modifier
- //param_map[SETTING_FOG_DENSITY] = DefaultParam(LLShaderMgr::WATER_FOGDENSITY, water_defaults[SETTING_FOG_DENSITY]);
- }
return param_map;
}
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 1d6b3cd80c..fe61b7a02a 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -79,7 +79,7 @@ LLSidepanelTaskInfo::LLSidepanelTaskInfo()
: mVisibleDebugPermissions(true) // space was allocated by default
{
setMouseOpaque(FALSE);
- LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
+ mSelectionUpdateSlot = LLSelectMgr::instance().mUpdateSignal.connect(boost::bind(&LLSidepanelTaskInfo::refreshAll, this));
gIdleCallbacks.addFunction(&LLSidepanelTaskInfo::onIdle, (void*)this);
}
@@ -89,6 +89,11 @@ LLSidepanelTaskInfo::~LLSidepanelTaskInfo()
if (sActivePanel == this)
sActivePanel = NULL;
gIdleCallbacks.deleteFunction(&LLSidepanelTaskInfo::onIdle, (void*)this);
+
+ if (mSelectionUpdateSlot.connected())
+ {
+ mSelectionUpdateSlot.disconnect();
+ }
}
// virtual
diff --git a/indra/newview/llsidepaneltaskinfo.h b/indra/newview/llsidepaneltaskinfo.h
index 852d36293b..2baafc67e7 100644
--- a/indra/newview/llsidepaneltaskinfo.h
+++ b/indra/newview/llsidepaneltaskinfo.h
@@ -162,6 +162,8 @@ private:
LLUICtrl* mDAE;
LLUICtrl* mDAN;
LLUICtrl* mDAF;
+
+ boost::signals2::connection mSelectionUpdateSlot;
};
diff --git a/indra/newview/llsky.cpp b/indra/newview/llsky.cpp
index ac7dbcacaa..4926b86b14 100644
--- a/indra/newview/llsky.cpp
+++ b/indra/newview/llsky.cpp
@@ -85,7 +85,6 @@ void LLSky::cleanup()
{
mVOSkyp = NULL;
mVOWLSkyp = NULL;
- mVOGroundp = NULL;
}
void LLSky::destroyGL()
@@ -114,18 +113,16 @@ void LLSky::restoreGL()
void LLSky::resetVertexBuffers()
{
- if (gSky.mVOSkyp.notNull() && gSky.mVOGroundp.notNull())
+ 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);
+ gPipeline.markRebuild(gSky.mVOSkyp->mDrawable, LLDrawable::REBUILD_ALL);
}
if (gSky.mVOWLSkyp.notNull())
{
gSky.mVOWLSkyp->resetVertexBuffers();
gPipeline.resetVertexBuffers(gSky.mVOWLSkyp->mDrawable);
- gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(gSky.mVOWLSkyp->mDrawable, LLDrawable::REBUILD_ALL);
}
}
@@ -208,9 +205,6 @@ void LLSky::init()
mVOSkyp->init();
gPipeline.createObject(mVOSkyp.get());
- mVOGroundp = (LLVOGround*)gObjectList.createObjectViewer(LLViewerObject::LL_VO_GROUND, NULL);
- gPipeline.createObject(mVOGroundp.get());
-
gSky.setFogRatio(gSavedSettings.getF32("RenderFogRatio"));
mUpdatedThisFrame = TRUE;
diff --git a/indra/newview/llsky.h b/indra/newview/llsky.h
index ec0de1fbfd..cce645e2be 100644
--- a/indra/newview/llsky.h
+++ b/indra/newview/llsky.h
@@ -34,7 +34,6 @@
#include "v4color.h"
#include "v4coloru.h"
#include "llvosky.h"
-#include "llvoground.h"
class LLViewerCamera;
@@ -88,7 +87,6 @@ public:
public:
LLPointer<LLVOSky> mVOSkyp; // Pointer to the LLVOSky object (only one, ever!)
- LLPointer<LLVOGround> mVOGroundp;
LLPointer<LLVOWLSky> mVOWLSkyp;
protected:
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index ae97ce604a..c650513ab8 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -59,13 +59,11 @@ extern bool gShiftFrame;
static U32 sZombieGroups = 0;
U32 LLSpatialGroup::sNodeCount = 0;
-BOOL LLSpatialGroup::sNoDelete = FALSE;
+bool LLSpatialGroup::sNoDelete = false;
static F32 sLastMaxTexPriority = 1.f;
static F32 sCurMaxTexPriority = 1.f;
-BOOL LLSpatialPartition::sTeleportRequested = FALSE;
-
//static counter for frame to switch LOD on
void sg_assert(BOOL expr)
@@ -263,11 +261,11 @@ void LLSpatialGroup::expandExtents(const LLVector4a* addingExtents, const LLXfor
LLVector3(mExtents[1].getF32ptr())
};
- LLQuaternion backwardRotation = ~currentTransform.getRotation();
+ LLQuaternion backwardRotation = ~currentTransform.getWorldRotation();
for (LLVector3& corner : corners)
{
// Make coordinates relative to the current position
- corner -= currentTransform.getPosition();
+ corner -= currentTransform.getWorldPosition();
// Rotate coordinates backward to the current rotation
corner.rotVec(backwardRotation);
// Expand root extents on the current corner
@@ -301,7 +299,7 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep)
drawablep->setGroup(this);
setState(OBJECT_DIRTY | GEOM_DIRTY);
setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
- gPipeline.markRebuild(this, TRUE);
+ gPipeline.markRebuild(this);
if (drawablep->isSpatialBridge())
{
mBridgeList.push_back((LLSpatialBridge*) drawablep);
@@ -362,14 +360,13 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
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->mVertexBuffer->isWriteable() ||
- (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs))
+ if (group->mVertexBuffer.isNull() ||
+ group->mVertexBuffer->getNumVerts() != vertex_count ||
+ group->mVertexBuffer->getNumVerts() != index_count)
{
- group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage);
- if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true))
+ group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask);
+ if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to "
<< vertex_count << " vertices and "
@@ -378,18 +375,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group)
group->mBufferMap.clear();
}
}
- else
- {
- if (!group->mVertexBuffer->resizeBuffer(vertex_count, index_count))
- {
- // Is likely to cause a crash. If this gets triggered find a way to avoid it (don't forget to reset face)
- LL_WARNS() << "Failed to resize Vertex Buffer on rebuild to "
- << vertex_count << " vertices and "
- << index_count << " indices" << LL_ENDL;
- group->mVertexBuffer = NULL;
- group->mBufferMap.clear();
- }
- }
}
if (group->mVertexBuffer)
@@ -436,7 +421,7 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree)
{
drawablep->setGroup(NULL);
setState(GEOM_DIRTY);
- gPipeline.markRebuild(this, TRUE);
+ gPipeline.markRebuild(this);
if (drawablep->isSpatialBridge())
{
@@ -479,7 +464,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
getSpatialPartition()->mPartitionType != LLViewerRegion::PARTITION_CONTROL_AV)
{
setState(GEOM_DIRTY);
- gPipeline.markRebuild(this, TRUE);
+ gPipeline.markRebuild(this);
}
}
@@ -591,7 +576,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
mSurfaceArea(0.f),
mBuilt(0.f),
mVertexBuffer(NULL),
- mBufferUsage(part->mBufferUsage),
mDistance(0.f),
mDepth(0.f),
mLastUpdateDistance(-1.f),
@@ -606,10 +590,13 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO
sg_assert(mOctreeNode->getListenerCount() == 0);
setState(SG_INITIAL_STATE_MASK);
- gPipeline.markRebuild(this, TRUE);
+ gPipeline.markRebuild(this);
+
+ // let the reflection map manager know about this spatial group
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerSpatialGroup(this);
- mRadius = 1;
- mPixelArea = 1024.f;
+ mRadius = 1;
+ mPixelArea = 1024.f;
}
void LLSpatialGroup::updateDistance(LLCamera &camera)
@@ -617,6 +604,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera)
if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD)
{
LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL;
+ llassert(false);
return;
}
@@ -676,7 +664,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera)
//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);
- gPipeline.markRebuild(group, FALSE);
+ gPipeline.markRebuild(group);
}
}
}
@@ -773,11 +761,6 @@ BOOL LLSpatialGroup::changeLOD()
return TRUE;
}
-
- if (mDistance > mRadius*2.f)
- {
- return FALSE;
- }
}
if (needsUpdate())
@@ -884,13 +867,13 @@ void LLSpatialGroup::rebound()
}
}
-void LLSpatialGroup::destroyGL(bool keep_occlusion)
+void LLSpatialGroup::destroyGLState(bool keep_occlusion)
{
setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY);
if (!keep_occlusion)
{ //going to need a rebuild
- gPipeline.markRebuild(this, TRUE);
+ gPipeline.markRebuild(this);
}
mLastUpdateTime = gFrameTimeSeconds;
@@ -925,13 +908,12 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion)
//==============================================
-LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp)
+LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp)
: mRenderByGroup(render_by_group), mBridge(NULL)
{
mRegionp = regionp;
mPartitionType = LLViewerRegion::PARTITION_NONE;
mVertexDataMask = data_mask;
- mBufferUsage = buffer_usage;
mDepthMask = FALSE;
mSlopRatio = 0.25f;
mInfiniteFarClip = FALSE;
@@ -1100,11 +1082,11 @@ public:
virtual void processGroup(LLViewerOctreeGroup* base_group)
{
LLSpatialGroup* group = (LLSpatialGroup*)base_group;
- if (group->needsUpdate() ||
+ /*if (group->needsUpdate() ||
group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
{
group->doOcclusion(mCamera);
- }
+ }*/
gPipeline.markNotCulled(group, *mCamera);
}
};
@@ -1398,50 +1380,11 @@ void drawBoxOutline(const LLVector4a& pos, const LLVector4a& size)
drawBoxOutline(reinterpret_cast<const LLVector3&>(pos), reinterpret_cast<const LLVector3&>(size));
}
-class LLOctreeDirty : public OctreeTraveler
-{
-public:
- LLOctreeDirty(bool no_rebuild) : mNoRebuild(no_rebuild){}
-
- virtual void visit(const OctreeNode* state)
- {
- LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0);
- group->destroyGL();
-
- for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
- {
- LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
- if(!drawable)
- {
- continue;
- }
- if (!mNoRebuild && drawable->getVObj().notNull() && !group->getSpatialPartition()->mRenderByGroup)
- {
- gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE);
- }
- }
-
- for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- traverse(bridge->mOctree);
- }
- }
-
-private:
- BOOL mNoRebuild;
-};
void LLSpatialPartition::restoreGL()
{
}
-void LLSpatialPartition::resetVertexBuffers()
-{
- LLOctreeDirty dirty(sTeleportRequested);
- dirty.traverse(mOctree);
-}
-
BOOL LLSpatialPartition::getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
@@ -1488,8 +1431,10 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result
selecter.traverse(mOctree);
return 0;
- }
-
+}
+
+extern BOOL gCubeSnapshot;
+
S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_SPATIAL;
@@ -1508,7 +1453,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
LLOctreeCullShadow culler(&camera);
culler.traverse(mOctree);
}
- else if (mInfiniteFarClip || !LLPipeline::sUseFarClip)
+ else if (mInfiniteFarClip || (!LLPipeline::sUseFarClip && !gCubeSnapshot))
{
LLOctreeCullNoFarClip culler(&camera);
culler.traverse(mOctree);
@@ -1522,15 +1467,15 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion)
return 0;
}
-void pushVerts(LLDrawInfo* params, U32 mask)
+void pushVerts(LLDrawInfo* params)
{
LLRenderPass::applyModelMatrix(*params);
- params->mVertexBuffer->setBuffer(mask);
- params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES,
+ params->mVertexBuffer->setBuffer();
+ params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
params->mStart, params->mEnd, params->mCount, params->mOffset);
}
-void pushVerts(LLSpatialGroup* group, U32 mask)
+void pushVerts(LLSpatialGroup* group)
{
LLDrawInfo* params = NULL;
@@ -1539,36 +1484,25 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j)
{
params = *j;
- pushVerts(params, mask);
+ pushVerts(params);
}
}
}
-void pushVerts(LLFace* face, U32 mask)
+void pushVerts(LLFace* face)
{
if (face)
{
llassert(face->verify());
-
- LLVertexBuffer* buffer = face->getVertexBuffer();
-
- if (buffer && (face->getGeomCount() >= 3))
- {
- buffer->setBuffer(mask);
- U16 start = face->getGeomStart();
- U16 end = start + face->getGeomCount()-1;
- U32 count = face->getIndicesCount();
- U16 offset = face->getIndicesStart();
- buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset);
- }
+ face->renderIndexed();
}
}
-void pushVerts(LLDrawable* drawable, U32 mask)
+void pushVerts(LLDrawable* drawable)
{
for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
- pushVerts(drawable->getFace(i), mask);
+ pushVerts(drawable->getFace(i));
}
}
@@ -1582,16 +1516,16 @@ void pushVerts(LLVolume* volume)
}
}
-void pushBufferVerts(LLVertexBuffer* buffer, U32 mask)
+void pushBufferVerts(LLVertexBuffer* buffer)
{
if (buffer)
{
- buffer->setBuffer(mask);
+ buffer->setBuffer();
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
}
}
-void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
+void pushBufferVerts(LLSpatialGroup* group, bool push_alpha = true)
{
if (group->getSpatialPartition()->mRenderByGroup)
{
@@ -1602,7 +1536,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
if (push_alpha)
{
- pushBufferVerts(group->mVertexBuffer, mask);
+ pushBufferVerts(group->mVertexBuffer);
}
for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
@@ -1611,7 +1545,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
{
for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k)
{
- pushBufferVerts(*k, mask);
+ pushBufferVerts(*k);
}
}
}
@@ -1624,7 +1558,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true)
}*/
}
-void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
+void pushVertsColorCoded(LLSpatialGroup* group)
{
LLDrawInfo* params = NULL;
@@ -1649,8 +1583,8 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
params = *j;
LLRenderPass::applyModelMatrix(*params);
gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f);
- params->mVertexBuffer->setBuffer(mask);
- params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES,
+ params->mVertexBuffer->setBuffer();
+ params->mVertexBuffer->drawRange(LLRender::TRIANGLES,
params->mStart, params->mEnd, params->mCount, params->mOffset);
col = (col+1)%col_count;
}
@@ -1662,6 +1596,7 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask)
// - a linked rigged drawable face has the wrong draw order index
bool check_rigged_group(LLDrawable* drawable)
{
+#if 0
if (drawable->isState(LLDrawable::RIGGED))
{
LLSpatialGroup* group = drawable->getSpatialGroup();
@@ -1709,7 +1644,7 @@ bool check_rigged_group(LLDrawable* drawable)
}
}
}
-
+#endif
return true;
}
@@ -1722,17 +1657,8 @@ void renderOctree(LLSpatialGroup* group)
if (group->mBuilt > 0.f)
{
group->mBuilt -= 2.f * gFrameIntervalSeconds.value();
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB)
- {
- col.setVec(1.0f, 0, 0, group->mBuilt*0.5f);
- }
- else
- {
- col.setVec(0.1f,0.1f,1,0.1f);
- //col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f);
- }
-
- if (group->mBufferUsage != GL_STATIC_DRAW_ARB)
+ col.setVec(0.1f,0.1f,1,0.1f);
+
{
LLGLDepthTest gl_depth(FALSE, FALSE);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
@@ -1793,22 +1719,36 @@ void renderOctree(LLSpatialGroup* group)
LLFace* face = drawable->getFace(j);
if (face && face->getVertexBuffer())
{
- if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
- {
- gGL.diffuseColor4f(0, 1, 0, group->mBuilt);
- }
- else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f)
- {
- gGL.diffuseColor4f(1, 0, 0, group->mBuilt);
- }
- else
- {
- continue;
- }
+ LLVOVolume* vol = drawable->getVOVolume();
- face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX | (rigged ? LLVertexBuffer::MAP_WEIGHT4 : 0));
- //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f,
- // (face->mExtents[1]-face->mExtents[0])*0.5f);
+ if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f)
+ {
+ if (vol && vol->isShrinkWrapped())
+ {
+ gGL.diffuseColor4f(0, 1, 1, group->mBuilt);
+ }
+ else
+ {
+ gGL.diffuseColor4f(0, 1, 0, group->mBuilt);
+ }
+ }
+ else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f)
+ {
+ if (vol && vol->isShrinkWrapped())
+ {
+ gGL.diffuseColor4f(1, 1, 0, group->mBuilt);
+ }
+ else
+ {
+ gGL.diffuseColor4f(1, 0, 0, group->mBuilt);
+ }
+ }
+ else
+ {
+ continue;
+ }
+
+ face->getVertexBuffer()->setBuffer();
face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart());
}
}
@@ -1828,162 +1768,25 @@ void renderOctree(LLSpatialGroup* group)
gGL.diffuseColor4f(1,1,1,1);
}
}
- else
- {
- if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->isEmpty()
- && group->getSpatialPartition()->mRenderByGroup)
- {
- col.setVec(0.8f, 0.4f, 0.1f, 0.1f);
- }
- else
- {
- col.setVec(0.1f, 0.1f, 1.f, 0.1f);
- }
- }
gGL.diffuseColor4fv(col.mV);
LLVector4a fudge;
fudge.splat(0.001f);
- //LLVector4a size = group->mObjectBounds[1];
- //size.mul(1.01f);
- //size.add(fudge);
-
- //{
- // LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- // drawBox(group->mObjectBounds[0], fudge);
- //}
-
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- //if (group->mBuilt <= 0.f)
{
//draw opaque outline
- //gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f);
- //drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]);
-
gGL.diffuseColor4f(0,1,1,1);
const LLVector4a* bounds = group->getBounds();
drawBoxOutline(bounds[0], bounds[1]);
-
- //draw bounding box for draw info
- /*if (group->getSpatialPartition()->mRenderByGroup)
- {
- gGL.diffuseColor4f(1.0f, 0.75f, 0.25f, 0.6f);
- 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)
- {
- LLDrawInfo* draw_info = *j;
- LLVector4a center;
- center.setAdd(draw_info->mExtents[1], draw_info->mExtents[0]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(draw_info->mExtents[1], draw_info->mExtents[0]);
- size.mul(0.5f);
- drawBoxOutline(center, size);
- }
- }
- }*/
}
-
-// LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
-// gGL.diffuseColor4f(0,1,0,1);
-// drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize()));
}
std::set<LLSpatialGroup*> visible_selected_groups;
-void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
-{
- /*LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- LLGLEnable cull(GL_CULL_FACE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/
-
- /*BOOL render_objects = (!LLPipeline::sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) && group->isVisible() &&
- !group->isEmpty();
-
-
- if (render_objects)
- {
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- LLGLDisable blend(GL_BLEND);
- gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glLineWidth(4.f);
- gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
- glLineWidth(1.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
- bool selected = false;
-
- for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
- {
- LLDrawable* drawable = *iter;
- if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
- {
- selected = true;
- break;
- }
- }
-
- if (selected)
- { //store for rendering occlusion volume as overlay
- visible_selected_groups.insert(group);
- }
- }*/
-
- /*if (render_objects)
- {
- LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER);
- gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
- gGL.diffuseColor4f(0, 0.5f, 0, 0.5f);
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
- }
-
- {
- LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL);
-
- if (render_objects)
- {
- gGL.diffuseColor4f(0.f, 0.5f, 0.f,1.f);
- gGL.diffuseColor4f(0.f, 0.5f, 0.f, 1.f);
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
- }
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-
- if (render_objects)
- {
- gGL.diffuseColor4f(0.f, 0.75f, 0.f,0.5f);
- gGL.diffuseColor4f(0.f, 0.75f, 0.f, 0.5f);
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
-
- bool selected = false;
-
- for (LLSpatialGroup::element_iter iter = group->getDataBegin(); iter != group->getDataEnd(); ++iter)
- {
- LLDrawable* drawable = *iter;
- if (drawable->getVObj().notNull() && drawable->getVObj()->isSelected())
- {
- selected = true;
- break;
- }
- }
-
- if (selected)
- { //store for rendering occlusion volume as overlay
- visible_selected_groups.insert(group);
- }
- }
- }*/
-}
void renderXRay(LLSpatialGroup* group, LLCamera* camera)
{
@@ -1992,7 +1795,7 @@ void renderXRay(LLSpatialGroup* group, LLCamera* camera)
if (render_objects)
{
- pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false);
+ pushBufferVerts(group, false);
bool selected = false;
@@ -2074,121 +1877,11 @@ void renderUpdateType(LLDrawable* drawablep)
{
for (S32 i = 0; i < num_faces; ++i)
{
- pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
+ pushVerts(drawablep->getFace(i));
}
}
}
-void renderComplexityDisplay(LLDrawable* drawablep)
-{
- LLViewerObject* vobj = drawablep->getVObj();
- if (!vobj)
- {
- return;
- }
-
- LLVOVolume *voVol = dynamic_cast<LLVOVolume*>(vobj);
-
- if (!voVol)
- {
- return;
- }
-
- if (!voVol->isRoot())
- {
- return;
- }
-
- LLVOVolume::texture_cost_t textures;
- F32 cost = (F32) voVol->getRenderCost(textures);
-
- // add any child volumes
- LLViewerObject::const_child_list_t children = voVol->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
- {
- const LLViewerObject *child = *iter;
- const LLVOVolume *child_volume = dynamic_cast<const LLVOVolume*>(child);
- if (child_volume)
- {
- cost += child_volume->getRenderCost(textures);
- }
- }
-
- // add texture cost
- for (LLVOVolume::texture_cost_t::iterator iter = textures.begin(); iter != textures.end(); ++iter)
- {
- // add the cost of each individual texture in the linkset
- cost += iter->second;
- }
-
- F32 cost_max = (F32) LLVOVolume::getRenderComplexityMax();
-
-
-
- // allow user to set a static color scale
- if (gSavedSettings.getS32("RenderComplexityStaticMax") > 0)
- {
- cost_max = gSavedSettings.getS32("RenderComplexityStaticMax");
- }
-
- F32 cost_ratio = cost / cost_max;
-
- // cap cost ratio at 1.0f in case cost_max is at a low threshold
- cost_ratio = cost_ratio > 1.0f ? 1.0f : cost_ratio;
-
- LLGLEnable blend(GL_BLEND);
-
- LLColor4 color;
- const LLColor4 color_min = gSavedSettings.getColor4("RenderComplexityColorMin");
- const LLColor4 color_mid = gSavedSettings.getColor4("RenderComplexityColorMid");
- const LLColor4 color_max = gSavedSettings.getColor4("RenderComplexityColorMax");
-
- if (cost_ratio < 0.5f)
- {
- color = color_min * (1 - cost_ratio * 2) + color_mid * (cost_ratio * 2);
- }
- else
- {
- color = color_mid * (1 - (cost_ratio - 0.5) * 2) + color_max * ((cost_ratio - 0.5) * 2);
- }
-
- LLSD color_val = color.getValue();
-
- // don't highlight objects below the threshold
- if (cost > gSavedSettings.getS32("RenderComplexityThreshold"))
- {
- glColor4f(color[0],color[1],color[2],0.5f);
-
-
- S32 num_faces = drawablep->getNumFaces();
- if (num_faces)
- {
- for (S32 i = 0; i < num_faces; ++i)
- {
- pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX);
- }
- }
- LLViewerObject::const_child_list_t children = voVol->getChildren();
- for (LLViewerObject::const_child_list_t::const_iterator iter = children.begin(); iter != children.end(); ++iter)
- {
- const LLViewerObject *child = *iter;
- if (child)
- {
- num_faces = child->getNumFaces();
- if (num_faces)
- {
- for (S32 i = 0; i < num_faces; ++i)
- {
- pushVerts(child->mDrawable->getFace(i), LLVertexBuffer::MAP_VERTEX);
- }
- }
- }
- }
- }
-
- voVol->setDebugText(llformat("%4.0f", cost));
-}
-
void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
{
if (set_color)
@@ -2413,7 +2106,7 @@ S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& sca
return detail;
}
-void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLColor4& line_color)
+void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color)
{
LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
LLModel::Decomposition* decomp = gMeshRepo.getDecomposition(mesh_id);
@@ -2425,13 +2118,8 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo
{
if (!decomp->mBaseHullMesh.empty())
{
- gGL.diffuseColor4fv(color.mV);
+ gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- gGL.diffuseColor4fv(line_color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mBaseHullMesh.mPositions);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{
@@ -2448,19 +2136,13 @@ void renderMeshBaseHull(LLVOVolume* volume, U32 data_mask, LLColor4& color, LLCo
}
}
-void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color, const LLColor4& line_color)
+void render_hull(LLModel::PhysicsMesh& mesh, const LLColor4& color)
{
- gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- glLineWidth(3.f);
- gGL.diffuseColor4fv(line_color.mV);
+ gGL.diffuseColor4fv(color.mV);
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, mesh.mPositions);
- glLineWidth(1.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
-void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
+void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume, bool wireframe)
{
U8 physics_type = volume->getPhysicsShapeType();
@@ -2490,7 +2172,10 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
color = lerp( mid, high, 2.f * ( normalizedCost - 0.5f ) );
}
- LLColor4 line_color = color*0.5f;
+ if (wireframe)
+ {
+ color = color * 0.5f;
+ }
U32 data_mask = LLVertexBuffer::MAP_VERTEX;
@@ -2510,9 +2195,6 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.pushMatrix();
gGL.multMatrix((F32*) volume->getRelativeXform().mMatrix);
- LLGLEnable(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(3.f, 3.f);
-
if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH)
{
LLUUID mesh_id = volume->getVolume()->getParams().getSculptID();
@@ -2533,23 +2215,19 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
for (U32 i = 0; i < decomp->mMesh.size(); ++i)
{
- render_hull(decomp->mMesh[i], color, line_color);
+ render_hull(decomp->mMesh[i], color);
}
}
else if (!decomp->mPhysicsShapeMesh.empty())
{
//decomp has physics mesh, render that mesh
- gGL.diffuseColor4fv(color.mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions);
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- gGL.diffuseColor4fv(line_color.mV);
+ gGL.diffuseColor4fv(color.mV);
+
LLVertexBuffer::drawArrays(LLRender::TRIANGLES, decomp->mPhysicsShapeMesh.mPositions);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
else
{ //no mesh or decomposition, render base hull
- renderMeshBaseHull(volume, data_mask, color, line_color);
+ renderMeshBaseHull(volume, data_mask, color);
if (decomp->mPhysicsShapeMesh.empty())
{
@@ -2569,7 +2247,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
{
if (volume->isMesh())
{
- renderMeshBaseHull(volume, data_mask, color, line_color);
+ renderMeshBaseHull(volume, data_mask, color);
}
else
{
@@ -2665,20 +2343,10 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
if (phys_volume->mHullPoints)
{
//render hull
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- gGL.diffuseColor4fv(line_color.mV);
- LLVertexBuffer::unbind();
+ gGL.diffuseColor4fv(color.mV);
- llassert(LLGLSLShader::sCurBoundShader != 0);
-
- LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
-
- gGL.diffuseColor4fv(color.mV);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ LLVertexBuffer::unbind();
LLVertexBuffer::drawElements(LLRender::TRIANGLES, phys_volume->mHullPoints, NULL, phys_volume->mNumHullIndices, phys_volume->mHullIndices);
-
}
else
{
@@ -2691,41 +2359,50 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX)
{
- LLVector3 center = physics_spec.getCenter();
- LLVector3 scale = physics_spec.getScale();
- LLVector3 vscale = volume->getScale()*2.f;
- scale.set(scale[0]/vscale[0], scale[1]/vscale[1], scale[2]/vscale[2]);
-
- gGL.diffuseColor4fv(color.mV);
- drawBox(center, scale);
+ if (!wireframe)
+ {
+ LLVector3 center = physics_spec.getCenter();
+ LLVector3 scale = physics_spec.getScale();
+ LLVector3 vscale = volume->getScale() * 2.f;
+ scale.set(scale[0] / vscale[0], scale[1] / vscale[1], scale[2] / vscale[2]);
+
+ gGL.diffuseColor4fv(color.mV);
+ drawBox(center, scale);
+ }
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
{
- LLVolumeParams volume_params;
- volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
- volume_params.setBeginAndEndS( 0.f, 1.f );
- volume_params.setBeginAndEndT( 0.f, 1.f );
- volume_params.setRatio ( 1, 1 );
- volume_params.setShear ( 0, 0 );
- LLVolume* sphere = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
-
- gGL.diffuseColor4fv(color.mV);
- pushVerts(sphere);
- LLPrimitive::sVolumeManager->unrefVolume(sphere);
+ if (!wireframe)
+ {
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE);
+ volume_params.setBeginAndEndS(0.f, 1.f);
+ volume_params.setBeginAndEndT(0.f, 1.f);
+ volume_params.setRatio(1, 1);
+ volume_params.setShear(0, 0);
+ LLVolume* sphere = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
+
+ gGL.diffuseColor4fv(color.mV);
+ pushVerts(sphere);
+ LLPrimitive::sVolumeManager->unrefVolume(sphere);
+ }
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
{
- LLVolumeParams volume_params;
- volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE );
- volume_params.setBeginAndEndS( 0.f, 1.f );
- volume_params.setBeginAndEndT( 0.f, 1.f );
- volume_params.setRatio ( 1, 1 );
- volume_params.setShear ( 0, 0 );
- LLVolume* cylinder = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
-
- gGL.diffuseColor4fv(color.mV);
- pushVerts(cylinder);
- LLPrimitive::sVolumeManager->unrefVolume(cylinder);
+ if (!wireframe)
+ {
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE);
+ volume_params.setBeginAndEndS(0.f, 1.f);
+ volume_params.setBeginAndEndT(0.f, 1.f);
+ volume_params.setRatio(1, 1);
+ volume_params.setShear(0, 0);
+ LLVolume* cylinder = LLPrimitive::sVolumeManager->refVolume(volume_params, 3);
+
+ gGL.diffuseColor4fv(color.mV);
+ pushVerts(cylinder);
+ LLPrimitive::sVolumeManager->unrefVolume(cylinder);
+ }
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH)
{
@@ -2733,14 +2410,10 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
S32 detail = get_physics_detail(volume_params, volume->getScale());
LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- gGL.diffuseColor4fv(line_color.mV);
- pushVerts(phys_volume);
-
- gGL.diffuseColor4fv(color.mV);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+
+ gGL.diffuseColor4fv(color.mV);
pushVerts(phys_volume);
+
LLPrimitive::sVolumeManager->unrefVolume(phys_volume);
}
else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX)
@@ -2752,23 +2425,15 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
if (phys_volume->mHullPoints && phys_volume->mHullIndices)
{
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+
llassert(LLGLSLShader::sCurBoundShader != 0);
LLVertexBuffer::unbind();
glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints);
- gGL.diffuseColor4fv(line_color.mV);
- gGL.syncMatrices();
- {
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x20FF20 )
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
- }
-
- gGL.diffuseColor4fv(color.mV);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- {
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x40FF40 )
- glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
- }
+
+ gGL.diffuseColor4fv(color.mV);
+
+ gGL.syncMatrices();
+ glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices);
}
else
{
@@ -2790,7 +2455,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
gGL.popMatrix();
}
-void renderPhysicsShapes(LLSpatialGroup* group)
+void renderPhysicsShapes(LLSpatialGroup* group, bool wireframe)
{
for (OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
@@ -2808,7 +2473,7 @@ void renderPhysicsShapes(LLSpatialGroup* group)
{
gGL.pushMatrix();
gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- bridge->renderPhysicsShapes();
+ bridge->renderPhysicsShapes(wireframe);
gGL.popMatrix();
}
}
@@ -2822,16 +2487,17 @@ void renderPhysicsShapes(LLSpatialGroup* group)
gGL.pushMatrix();
LLVector3 trans = drawable->getRegion()->getOriginAgent();
gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- renderPhysicsShape(drawable, volume);
+ renderPhysicsShape(drawable, volume, wireframe);
gGL.popMatrix();
}
else
{
- renderPhysicsShape(drawable, volume);
+ renderPhysicsShape(drawable, volume, wireframe);
}
}
else
{
+#if 0
LLViewerObject* object = drawable->getVObj();
if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
{
@@ -2848,11 +2514,11 @@ void renderPhysicsShapes(LLSpatialGroup* group)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
- gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+ buff->setBuffer();
+ gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f);
buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
- gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
+ gGL.diffuseColor4f(0.2f, 1.f, 0.3f, 0.75f);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
}
@@ -2860,6 +2526,7 @@ void renderPhysicsShapes(LLSpatialGroup* group)
}
gGL.popMatrix();
}
+#endif
}
}
}
@@ -2953,7 +2620,7 @@ void renderTextureAnim(LLDrawInfo* params)
LLGLEnable blend(GL_BLEND);
gGL.diffuseColor4f(1,1,0,0.5f);
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
+ pushVerts(params);
}
void renderBatchSize(LLDrawInfo* params)
@@ -2961,7 +2628,6 @@ void renderBatchSize(LLDrawInfo* params)
LLGLEnable offset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.f, 1.f);
LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr;
- U32 mask = LLVertexBuffer::MAP_VERTEX;
bool bind = false;
if (params->mAvatar)
{
@@ -2970,11 +2636,11 @@ void renderBatchSize(LLDrawInfo* params)
bind = true;
old_shader->mRiggedVariant->bind();
LLRenderPass::uploadMatrixPalette(*params);
- mask |= LLVertexBuffer::MAP_WEIGHT4;
}
- gGL.diffuseColor4ubv((GLubyte*)&(params->mDebugColor));
- pushVerts(params, mask);
+
+ gGL.diffuseColor4ubv(params->getDebugColor().mV);
+ pushVerts(params);
if (bind)
{
@@ -2983,42 +2649,6 @@ void renderBatchSize(LLDrawInfo* params)
}
}
-void renderShadowFrusta(LLDrawInfo* params)
-{
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ADD);
-
- LLVector4a center;
- center.setAdd(params->mExtents[1], params->mExtents[0]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(params->mExtents[1],params->mExtents[0]);
- size.mul(0.5f);
-
- if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size))
- {
- gGL.diffuseColor3f(1,0,0);
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
- }
- if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size))
- {
- gGL.diffuseColor3f(0,1,0);
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
- }
- if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size))
- {
- gGL.diffuseColor3f(0,0,1);
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
- }
- if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size))
- {
- gGL.diffuseColor3f(1,0,1);
- pushVerts(params, LLVertexBuffer::MAP_VERTEX);
- }
-
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-}
-
void renderTexelDensity(LLDrawable* drawable)
{
if (LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_OFF
@@ -3028,8 +2658,7 @@ void renderTexelDensity(LLDrawable* drawable)
}
LLGLEnable _(GL_BLEND);
- //gObjectFullbrightProgram.bind();
-
+
LLMatrix4 checkerboard_matrix;
S32 discard_level = -1;
@@ -3066,7 +2695,7 @@ void renderTexelDensity(LLDrawable* drawable)
if (buffer && (facep->getGeomCount() >= 3))
{
- buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ buffer->setBuffer();
U16 start = facep->getGeomStart();
U16 end = start + facep->getGeomCount()-1;
U32 count = facep->getIndicesCount();
@@ -3141,7 +2770,7 @@ void renderLights(LLDrawable* drawablep)
LLFace * face = drawablep->getFace(i);
if (face)
{
- pushVerts(face, LLVertexBuffer::MAP_VERTEX);
+ pushVerts(face);
}
}
@@ -3305,7 +2934,6 @@ void renderRaycast(LLDrawable* drawablep)
gGL.diffuseColor4f(0,1,1,0.5f);
glVertexPointer(3, GL_FLOAT, sizeof(LLVector4a), face.mPositions);
gGL.syncMatrices();
- LL_PROFILER_GPU_ZONEC( "gl.DrawElements", 0x60FF60 );
glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices);
}
@@ -3407,6 +3035,60 @@ void renderAgentTarget(LLVOAvatar* avatar)
}
}
+static void setTextureAreaDebugText(LLDrawable* drawablep)
+{
+ LLVOVolume* vobjp = drawablep->getVOVolume();
+
+ if (vobjp)
+ {
+ if (drawablep->mDistanceWRTCamera < 32.f)
+ {
+ std::ostringstream str;
+
+ //for (S32 i = 0; i < vobjp->getNumTEs(); ++i)
+ S32 i = 0;
+ {
+ if (i < drawablep->getNumFaces())
+ {
+ LLFace* facep = drawablep->getFace(i);
+
+ if (facep)
+ {
+ LLViewerTexture* imagep = facep->getTexture();
+
+ if (imagep)
+ {
+ str << llformat("D - %.2f", sqrtf(imagep->getMaxVirtualSize()));
+ }
+
+ imagep = vobjp->getTENormalMap(i);
+
+ if (imagep && imagep != LLViewerFetchedTexture::sDefaultImagep)
+ {
+ str << llformat("\nN - %.2f", sqrtf(imagep->getMaxVirtualSize()));
+ }
+
+ imagep = vobjp->getTESpecularMap(i);
+
+ if (imagep && imagep != LLViewerFetchedTexture::sDefaultImagep)
+ {
+ str << llformat("\nS - %.2f", sqrtf(imagep->getMaxVirtualSize()));
+ }
+
+ str << "\n\n";
+ }
+
+ vobjp->setDebugText(str.str());
+ }
+ }
+ }
+ else
+ {
+ vobjp->setDebugText(".");
+ }
+ }
+}
+
class LLOctreeRenderNonOccluded : public OctreeTraveler
{
public:
@@ -3438,23 +3120,6 @@ public:
renderOctree(group);
stop_glerror();
}
-
- //render visibility wireframe
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
- {
- group->rebuildGeom();
- group->rebuildMesh();
-
- gGL.flush();
- gGL.pushMatrix();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- renderVisibility(group, mCamera);
- stop_glerror();
- gGLLastMatrix = NULL;
- gGL.popMatrix();
- gGL.diffuseColor4f(1,1,1,1);
- }
}
}
@@ -3498,26 +3163,15 @@ public:
renderNormals(drawable);
}
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE))
- {
- if (drawable->isState(LLDrawable::IN_REBUILD_Q2))
- {
- gGL.diffuseColor4f(0.6f, 0.6f, 0.1f, 1.f);
- const LLVector4a* ext = drawable->getSpatialExtents();
- LLVector4a center;
- center.setAdd(ext[0], ext[1]);
- center.mul(0.5f);
- LLVector4a size;
- size.setSub(ext[1], ext[0]);
- size.mul(0.5f);
- drawBoxOutline(center, size);
- }
- }
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
+ {
+ setTextureAreaDebugText(drawable);
+ }
- if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ /*if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
renderTexturePriority(drawable);
- }
+ }*/
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS))
{
@@ -3537,10 +3191,6 @@ public:
{
renderUpdateType(drawable);
}
- if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY))
- {
- renderComplexityDisplay(drawable);
- }
if(gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
renderTexelDensity(drawable);
@@ -3563,6 +3213,7 @@ public:
renderAgentTarget(avatar);
}
+#if 0
if (gDebugGL)
{
for (U32 i = 0; i < drawable->getNumFaces(); ++i)
@@ -3588,6 +3239,7 @@ public:
}
}
}
+#endif
}
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
@@ -3604,10 +3256,6 @@ public:
{
renderBatchSize(draw_info);
}
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
- {
- renderShadowFrusta(draw_info);
- }
}
}
}
@@ -3661,7 +3309,9 @@ class LLOctreeRenderPhysicsShapes : public OctreeTraveler
{
public:
LLCamera* mCamera;
- LLOctreeRenderPhysicsShapes(LLCamera* camera): mCamera(camera) {}
+ bool mWireframe;
+
+ LLOctreeRenderPhysicsShapes(LLCamera* camera, bool wireframe): mCamera(camera), mWireframe(wireframe) {}
virtual void traverse(const OctreeNode* node)
{
@@ -3682,7 +3332,7 @@ public:
group->rebuildGeom();
group->rebuildMesh();
- renderPhysicsShapes(group);
+ renderPhysicsShapes(group, mWireframe);
}
}
@@ -3815,7 +3465,7 @@ public:
};
-void LLSpatialPartition::renderPhysicsShapes()
+void LLSpatialPartition::renderPhysicsShapes(bool wireframe)
{
LLSpatialBridge* bridge = asBridge();
LLCamera* camera = LLViewerCamera::getInstance();
@@ -3827,11 +3477,9 @@ void LLSpatialPartition::renderPhysicsShapes()
gGL.flush();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glLineWidth(3.f);
- LLOctreeRenderPhysicsShapes render_physics(camera);
+ LLOctreeRenderPhysicsShapes render_physics(camera, wireframe);
render_physics.traverse(mOctree);
gGL.flush();
- glLineWidth(1.f);
}
void LLSpatialPartition::renderDebug()
@@ -3844,16 +3492,14 @@ void LLSpatialPartition::renderDebug()
LLPipeline::RENDER_DEBUG_BBOXES |
LLPipeline::RENDER_DEBUG_NORMALS |
LLPipeline::RENDER_DEBUG_POINTS |
- LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY |
+ LLPipeline::RENDER_DEBUG_TEXTURE_AREA |
LLPipeline::RENDER_DEBUG_TEXTURE_ANIM |
LLPipeline::RENDER_DEBUG_RAYCAST |
LLPipeline::RENDER_DEBUG_AVATAR_VOLUME |
LLPipeline::RENDER_DEBUG_AVATAR_JOINTS |
LLPipeline::RENDER_DEBUG_AGENT_TARGET |
- //LLPipeline::RENDER_DEBUG_BUILD_QUEUE |
LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA |
- LLPipeline::RENDER_DEBUG_RENDER_COMPLEXITY |
- LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
+ LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
{
return;
}
@@ -3887,7 +3533,6 @@ void LLSpatialPartition::renderDebug()
LLOctreeRenderNonOccluded render_debug(camera);
render_debug.traverse(mOctree);
-
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
{
{
@@ -3950,8 +3595,10 @@ public:
LLDrawable* mHit;
BOOL mPickTransparent;
BOOL mPickRigged;
+ BOOL mPickUnselectable;
+ BOOL mPickReflectionProbe;
- LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged,
+ LLOctreeIntersect(const LLVector4a& start, const LLVector4a& end, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, BOOL pick_reflection_probe,
S32* face_hit, LLVector4a* intersection, LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
: mStart(start),
mEnd(end),
@@ -3962,7 +3609,9 @@ public:
mTangent(tangent),
mHit(NULL),
mPickTransparent(pick_transparent),
- mPickRigged(pick_rigged)
+ mPickRigged(pick_rigged),
+ mPickUnselectable(pick_unselectable),
+ mPickReflectionProbe(pick_reflection_probe)
{
}
@@ -4038,7 +3687,8 @@ public:
{
LLViewerObject* vobj = drawable->getVObj();
- if (vobj)
+ if (vobj &&
+ (!vobj->isReflectionProbe() || mPickReflectionProbe))
{
if (vobj->getClickAction() == CLICK_ACTION_IGNORE && !LLFloater::isVisible(gFloaterTools))
{
@@ -4052,7 +3702,7 @@ public:
LLVOAvatar* avatar = (LLVOAvatar*) vobj;
if ((mPickRigged) || ((avatar->isSelf()) && (LLFloater::isVisible(gFloaterTools))))
{
- LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
+ LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent);
if (hit)
{
mEnd = intersection;
@@ -4068,7 +3718,9 @@ public:
}
}
- if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mPickRigged, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
+ if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1,
+ (mPickReflectionProbe && vobj->isReflectionProbe()) ? TRUE : mPickTransparent, // always pick transparent when picking selection probe
+ mPickRigged, mPickUnselectable, mFaceHit, &intersection, mTexCoord, mNormal, mTangent))
{
mEnd = intersection; // shorten ray so we only find CLOSER hits
if (mIntersection)
@@ -4088,6 +3740,8 @@ public:
LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
S32* face_hit, // return the face hit
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -4096,68 +3750,73 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
)
{
- LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, face_hit, intersection, tex_coord, normal, tangent);
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent);
LLDrawable* drawable = intersect.check(mOctree);
return drawable;
}
+LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection, // return the intersection point
+ LLVector2* tex_coord, // return the texture coordinates of the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
+)
+
+{
+ LLOctreeIntersect intersect(start, end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* drawable = intersect.check(getOctreeNode());
+
+ return drawable;
+}
+
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
- bool selected,
- BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
+ bool fullbright, U8 bump)
: mVertexBuffer(buffer),
mTexture(texture),
- mTextureMatrix(NULL),
- mModelMatrix(NULL),
mStart(start),
mEnd(end),
mCount(count),
mOffset(offset),
mFullbright(fullbright),
mBump(bump),
- mParticle(particle),
- mPartSize(part_size),
- mVSize(0.f),
- mGroup(NULL),
- mFace(NULL),
- mDistance(0.f),
- mDrawMode(LLRender::TRIANGLES),
- mMaterial(NULL),
- mShaderMask(0),
- mSpecColor(1.0f, 1.0f, 1.0f, 0.5f),
mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA),
mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA),
- mHasGlow(FALSE),
+ mHasGlow(false),
mEnvIntensity(0.0f),
- mAlphaMaskCutoff(0.5f),
- mDiffuseAlphaMode(0),
- mSelected(selected)
+ mAlphaMaskCutoff(0.5f)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
-
- mDebugColor = (rand() << 16) + rand();
- ((U8*)&mDebugColor)[3] = 200;
}
LLDrawInfo::~LLDrawInfo()
{
- /*if (LLSpatialGroup::sNoDelete)
- {
- LL_ERRS() << "LLDrawInfo deleted illegally!" << LL_ENDL;
- }*/
-
- if (mFace)
- {
- mFace->setDrawInfo(NULL);
- }
-
if (gDebugGL)
{
gPipeline.checkReferences(this);
}
}
+LLColor4U LLDrawInfo::getDebugColor() const
+{
+ LLColor4U color;
+
+ LLCRC hash;
+ hash.update((U8*)this + sizeof(S32), sizeof(LLDrawInfo) - sizeof(S32));
+
+ *((U32*) color.mV) = hash.getCRC();
+
+ color.mV[3] = 200;
+
+ return color;
+}
+
void LLDrawInfo::validate()
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
@@ -4168,11 +3827,6 @@ U64 LLDrawInfo::getSkinHash()
return mSkinInfo ? mSkinInfo->mHash : 0;
}
-LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
-{
- return new LLVertexBuffer(type_mask, usage);
-}
-
LLCullResult::LLCullResult()
{
mVisibleGroupsAllocated = 0;
@@ -4458,7 +4112,8 @@ void LLCullResult::assertDrawMapsEmpty()
{
if (mRenderMapSize[i] != 0)
{
- LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!" << LL_ENDL;
+ LL_ERRS() << "Stale LLDrawInfo's in LLCullResult!"
+ << " (mRenderMapSize[" << i << "] = " << mRenderMapSize[i] << ")" << LL_ENDL;
}
}
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 259ea24038..758e716c00 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -41,6 +41,7 @@
#include "llviewercamera.h"
#include "llvector4a.h"
#include "llvoavatar.h"
+#include "llfetchedgltfmaterial.h"
#include <queue>
#include <unordered_map>
@@ -53,10 +54,17 @@ class LLSpatialPartition;
class LLSpatialBridge;
class LLSpatialGroup;
class LLViewerRegion;
+class LLReflectionMap;
-void pushVerts(LLFace* face, U32 mask);
+void pushVerts(LLFace* face);
-class LLDrawInfo : public LLRefCount
+/*
+ Class that represents a single Draw Call
+
+ Make every effort to keep size minimal.
+ Member ordering is important for cache coherency
+*/
+class LLDrawInfo final : public LLRefCount
{
LL_ALIGN_NEW;
protected:
@@ -73,11 +81,13 @@ public:
LL_ERRS() << "Illegal operation!" << LL_ENDL;
return *this;
}
+
+ // return a hash of this LLDrawInfo as a debug color
+ LLColor4U getDebugColor() const;
LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
- LLViewerTexture* image, LLVertexBuffer* buffer,
- bool selected,
- BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
+ LLViewerTexture* image, LLVertexBuffer* buffer,
+ bool fullbright = false, U8 bump = 0);
void validate();
@@ -85,51 +95,47 @@ public:
// return mSkinHash->mHash, or 0 if mSkinHash is null
U64 getSkinHash();
- LLVector4a mExtents[2];
-
LLPointer<LLVertexBuffer> mVertexBuffer;
+ U16 mStart = 0;
+ U16 mEnd = 0;
+ U32 mCount = 0;
+ U32 mOffset = 0;
+
LLPointer<LLViewerTexture> mTexture;
- std::vector<LLPointer<LLViewerTexture> > mTextureList;
+ LLPointer<LLViewerTexture> mSpecularMap;
+ LLPointer<LLViewerTexture> mNormalMap;
+
+ const LLMatrix4* mSpecularMapMatrix = nullptr;
+ const LLMatrix4* mNormalMapMatrix = nullptr;
+ const LLMatrix4* mTextureMatrix = nullptr;
+ const LLMatrix4* mModelMatrix = nullptr;
- // virtual size of mTexture and mTextureList textures
- // used to update the decode priority of textures in this DrawInfo
- std::vector<F32> mTextureListVSize;
-
- S32 mDebugColor;
- const LLMatrix4* mTextureMatrix;
- const LLMatrix4* mModelMatrix;
- U16 mStart;
- U16 mEnd;
- U32 mCount;
- U32 mOffset;
- BOOL mFullbright;
- U8 mBump;
- U8 mShiny;
- BOOL mParticle;
- F32 mPartSize;
- F32 mVSize;
- LLSpatialGroup* mGroup;
- LL_ALIGN_16(LLFace* mFace); //associated face
- F32 mDistance;
- U32 mDrawMode;
- LLMaterialPtr mMaterial; // If this is null, the following parameters are unused.
- LLMaterialID mMaterialID;
- U32 mShaderMask;
- U32 mBlendFuncSrc;
- U32 mBlendFuncDst;
- BOOL mHasGlow;
- LLPointer<LLViewerTexture> mSpecularMap;
- const LLMatrix4* mSpecularMapMatrix;
- LLPointer<LLViewerTexture> mNormalMap;
- const LLMatrix4* mNormalMapMatrix;
- LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent
- F32 mEnvIntensity;
- F32 mAlphaMaskCutoff;
- U8 mDiffuseAlphaMode;
- bool mSelected;
LLPointer<LLVOAvatar> mAvatar = nullptr;
LLMeshSkinInfo* mSkinInfo = nullptr;
+ // Material pointer here is likely for debugging only and are immaterial (zing!)
+ LLPointer<LLMaterial> mMaterial;
+
+ // PBR material parameters
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
+
+ LLVector4 mSpecColor = LLVector4(1.f, 1.f, 1.f, 0.5f); // XYZ = Specular RGB, W = Specular Exponent
+
+ std::vector<LLPointer<LLViewerTexture> > mTextureList;
+
+ LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info
+
+ U32 mShaderMask = 0;
+ F32 mEnvIntensity = 0.f;
+ F32 mAlphaMaskCutoff = 0.5f;
+
+ LLRender::eBlendFactor mBlendFuncSrc = LLRender::BF_SOURCE_ALPHA;
+ LLRender::eBlendFactor mBlendFuncDst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ U8 mDiffuseAlphaMode = 0;
+ U8 mBump = 0;
+ U8 mShiny = 0;
+ bool mFullbright = false;
+ bool mHasGlow = false;
struct CompareTexture
{
@@ -190,19 +196,9 @@ public:
&& (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump));
}
};
-
- struct CompareDistanceGreater
- {
- bool operator()(const LLPointer<LLDrawInfo>& lhs, const LLPointer<LLDrawInfo>& rhs)
- {
- // sort by mBump value, sort NULL down to the end
- return lhs.get() != rhs.get()
- && (lhs.isNull() || (rhs.notNull() && lhs->mDistance > rhs->mDistance));
- }
- };
};
-LL_ALIGN_PREFIX(64)
+LL_ALIGN_PREFIX(16)
class LLSpatialGroup : public LLOcclusionCullingGroup
{
using super = LLOcclusionCullingGroup;
@@ -222,7 +218,7 @@ public:
}
static U32 sNodeCount;
- static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
+ static bool sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE
typedef std::vector<LLPointer<LLSpatialGroup> > sg_vector_t;
typedef std::vector<LLPointer<LLSpatialBridge> > bridge_list_t;
@@ -301,7 +297,9 @@ public:
BOOL updateInGroup(LLDrawable *drawablep, BOOL immediate = FALSE); // Update position if it's in the group
void expandExtents(const LLVector4a* addingExtents, const LLXformMatrix& currentTransform);
void shift(const LLVector4a &offset);
- void destroyGL(bool keep_occlusion = false);
+
+ // TODO: this no longer appears to be called, figure out if it's important and if not remove it
+ void destroyGLState(bool keep_occlusion = false);
void updateDistance(LLCamera& camera);
F32 getUpdateUrgency() const;
@@ -315,6 +313,19 @@ public:
void drawObjectBox(LLColor4 col);
+ LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
+ S32* face_hit, // return the face hit
+ LLVector4a* intersection = NULL, // return the intersection point
+ LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
+ LLVector4a* normal = NULL, // return the surface normal at the intersection point
+ LLVector4a* tangent = NULL // return the surface tangent at the intersection point
+ );
+
+
LLSpatialPartition* getSpatialPartition() {return (LLSpatialPartition*)mSpatialPartition;}
//LISTENER FUNCTIONS
@@ -330,25 +341,21 @@ public:
LL_ALIGN_16(LLVector4a mViewAngle);
LL_ALIGN_16(LLVector4a mLastUpdateViewAngle);
- F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
-
protected:
virtual ~LLSpatialGroup();
public:
+ LLPointer<LLVertexBuffer> mVertexBuffer;
+ draw_map_t mDrawMap;
+
bridge_list_t mBridgeList;
buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers
+ F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3()
U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node
F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node
-
F32 mBuilt;
- LLPointer<LLVertexBuffer> mVertexBuffer;
-
- U32 mBufferUsage;
- draw_map_t mDrawMap;
-
F32 mDistance;
F32 mDepth;
F32 mLastUpdateDistance;
@@ -360,7 +367,9 @@ public:
//used by LLVOAVatar to set render order in alpha draw pool to preserve legacy render order behavior
LLVOAvatar* mAvatarp = nullptr;
U32 mRenderOrder = 0;
-} LL_ALIGN_POSTFIX(64);
+ // Reflection Probe associated with this node (if any)
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr;
+} LL_ALIGN_POSTFIX(16);
class LLGeometryManager
{
@@ -371,14 +380,12 @@ public:
virtual void rebuildMesh(LLSpatialGroup* group) = 0;
virtual void getGeometry(LLSpatialGroup* group) = 0;
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count);
-
- virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager
{
public:
- LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp);
+ LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp);
virtual ~LLSpatialPartition();
LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE);
@@ -387,6 +394,8 @@ public:
LLDrawable* lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -415,11 +424,10 @@ public:
LLSpatialBridge* asBridge() { return mBridge; }
BOOL isBridge() { return asBridge() != NULL; }
- void renderPhysicsShapes();
+ void renderPhysicsShapes(bool depth_only);
void renderDebug();
void renderIntersectingBBoxes(LLCamera* camera);
void restoreGL();
- void resetVertexBuffers();
BOOL getVisibleExtents(LLCamera& camera, LLVector3& visMin, LLVector3& visMax);
@@ -428,14 +436,11 @@ public:
// use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe
// to call asBridge() from the destructor
- BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
- U32 mBufferUsage;
- const BOOL mRenderByGroup;
+ bool mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane
+ const bool mRenderByGroup;
U32 mVertexDataMask;
F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25);
- BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
-
- static BOOL sTeleportRequested; //started to issue a teleport request
+ bool mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering
};
// class for creating bridges between spatial partitions
@@ -486,6 +491,23 @@ public:
typedef LLDrawInfo** drawinfo_iterator;
typedef LLDrawable** drawable_iterator;
+ // Helper function for taking advantage of _mm_prefetch when iterating over cull results
+ static inline void increment_iterator(LLCullResult::drawinfo_iterator& i, const LLCullResult::drawinfo_iterator& end)
+ {
+ ++i;
+
+ if (i != end)
+ {
+ _mm_prefetch((char*)(*i)->mVertexBuffer.get(), _MM_HINT_NTA);
+
+ auto* ni = i + 1;
+ if (ni != end)
+ {
+ _mm_prefetch((char*)*ni, _MM_HINT_NTA);
+ }
+ }
+ }
+
void clear();
sg_iterator beginVisibleGroups();
@@ -597,7 +619,6 @@ class LLTerrainPartition : public LLSpatialPartition
public:
LLTerrainPartition(LLViewerRegion* regionp);
virtual void getGeometry(LLSpatialGroup* group);
- virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage);
};
//spatial partition for trees
@@ -671,6 +692,7 @@ private:
static LLFace** sNormFaces[2];
static LLFace** sSpecFaces[2];
static LLFace** sNormSpecFaces[2];
+ static LLFace** sPbrFaces[2];
static LLFace** sAlphaFaces[2];
};
diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp
index fd41cdf0d7..af0b5a40b4 100644
--- a/indra/newview/llsprite.cpp
+++ b/indra/newview/llsprite.cpp
@@ -188,9 +188,8 @@ void LLSprite::updateFace(LLFace &face)
if (!face.getVertexBuffer())
{
LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0,
- GL_STREAM_DRAW_ARB);
- buff->allocateBuffer(4, 12, TRUE);
+ LLVertexBuffer::MAP_TEXCOORD0 );
+ buff->allocateBuffer(4, 12);
face.setGeomIndex(0);
face.setIndicesIndex(0);
face.setVertexBuffer(buff);
@@ -238,7 +237,7 @@ void LLSprite::updateFace(LLFace &face)
*indicesp++ = 3 + index_offset;
}
- face.getVertexBuffer()->flush();
+ face.getVertexBuffer()->unmapBuffer();
face.mCenterAgent = mPosition;
}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index faa3382b76..d0b76848f7 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -60,6 +60,7 @@
#include "llfloatergridstatus.h"
#include "llfloaterimsession.h"
#include "lllocationhistory.h"
+#include "llgltfmateriallist.h"
#include "llimageworker.h"
#include "llloginflags.h"
@@ -301,10 +302,22 @@ void callback_cache_name(const LLUUID& id, const std::string& full_name, bool is
// exported functionality
//
+void pump_idle_startup_network(void)
+{
+ {
+ LockMessageChecker lmc(gMessageSystem);
+ while (lmc.checkAllMessages(gFrameCount, gServicePump))
+ {
+ display_startup();
+ }
+ lmc.processAcks();
+ }
+ display_startup();
+}
+
//
// local classes
//
-
void update_texture_fetch()
{
LLAppViewer::getTextureCache()->update(1); // unpauses the texture cache thread
@@ -312,7 +325,7 @@ void update_texture_fetch()
LLAppViewer::getTextureFetch()->update(1); // unpauses the texture fetch thread
gTextureList.updateImages(0.10f);
- if (LLImageGLThread::sEnabled)
+ if (LLImageGLThread::sEnabledTextures)
{
std::shared_ptr<LL::WorkQueue> main_queue = LL::WorkQueue::getInstance("mainloop");
main_queue->runFor(std::chrono::milliseconds(1));
@@ -1498,6 +1511,9 @@ bool idle_startup()
gXferManager->registerCallbacks(gMessageSystem);
display_startup();
+ LLGLTFMaterialList::registerCallbacks();
+ display_startup();
+
LLStartUp::initNameCache();
display_startup();
@@ -1567,19 +1583,14 @@ bool idle_startup()
gAgentCamera.resetCamera();
display_startup();
- // start up the ThreadPool we'll use for textures et al.
- LLAppViewer::instance()->initGeneralThread();
-
// Initialize global class data needed for surfaces (i.e. textures)
LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL;
// Initialize all of the viewer object classes for the first time (doing things like texture fetches.
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
gSky.init();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
display_startup();
@@ -1645,15 +1656,7 @@ bool idle_startup()
{
LLStartUp::setStartupState( STATE_AGENT_SEND );
}
- {
- LockMessageChecker lmc(gMessageSystem);
- while (lmc.checkAllMessages(gFrameCount, gServicePump))
- {
- display_startup();
- }
- lmc.processAcks();
- }
- display_startup();
+ pump_idle_startup_network();
return FALSE;
}
@@ -1753,6 +1756,7 @@ bool idle_startup()
//---------------------------------------------------------------------
if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
{
+ LL_PROFILE_ZONE_NAMED("State inventory send")
display_startup();
// request mute list
@@ -1784,7 +1788,7 @@ bool idle_startup()
}
}
display_startup();
-
+
LLSD inv_lib_owner = response["inventory-lib-owner"];
if(inv_lib_owner.isDefined())
{
@@ -1792,30 +1796,52 @@ bool idle_startup()
LLSD id = inv_lib_owner[0]["agent_id"];
if(id.isDefined())
{
- gInventory.setLibraryOwnerID( LLUUID(id.asUUID()));
+ gInventory.setLibraryOwnerID(LLUUID(id.asUUID()));
}
}
display_startup();
-
- LLSD inv_skel_lib = response["inventory-skel-lib"];
- if(inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
- {
- if(!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
- {
- LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
- }
- }
+ LLStartUp::setStartupState(STATE_INVENTORY_SKEL);
display_startup();
+ return FALSE;
+ }
- LLSD inv_skeleton = response["inventory-skeleton"];
- if(inv_skeleton.isDefined())
- {
- if(!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
- {
- LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
- }
- }
- display_startup();
+ if (STATE_INVENTORY_SKEL == LLStartUp::getStartupState())
+ {
+ LL_PROFILE_ZONE_NAMED("State inventory load skeleton")
+
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
+
+ LLSD inv_skel_lib = response["inventory-skel-lib"];
+ if (inv_skel_lib.isDefined() && gInventory.getLibraryOwnerID().notNull())
+ {
+ LL_PROFILE_ZONE_NAMED("load library inv")
+ if (!gInventory.loadSkeleton(inv_skel_lib, gInventory.getLibraryOwnerID()))
+ {
+ LL_WARNS("AppInit") << "Problem loading inventory-skel-lib" << LL_ENDL;
+ }
+ }
+ display_startup();
+
+ LLSD inv_skeleton = response["inventory-skeleton"];
+ if (inv_skeleton.isDefined())
+ {
+ LL_PROFILE_ZONE_NAMED("load personal inv")
+ if (!gInventory.loadSkeleton(inv_skeleton, gAgent.getID()))
+ {
+ LL_WARNS("AppInit") << "Problem loading inventory-skel-targets" << LL_ENDL;
+ }
+ }
+ display_startup();
+ LLStartUp::setStartupState(STATE_INVENTORY_SEND2);
+ display_startup();
+ return FALSE;
+ }
+
+ if (STATE_INVENTORY_SEND2 == LLStartUp::getStartupState())
+ {
+ LL_PROFILE_ZONE_NAMED("State inventory send2")
+
+ LLSD response = LLLoginInstance::getInstance()->getResponse();
LLSD inv_basic = response["inventory-basic"];
if(inv_basic.isDefined())
@@ -2307,7 +2333,7 @@ bool idle_startup()
if (STATE_CLEANUP == LLStartUp::getStartupState())
{
- set_startup_status(1.0, "", "");
+ set_startup_status(1.0, "", "");
display_startup();
if (!mBenefitsSuccessfullyInit)
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 921f088423..b55b86dd91 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -40,6 +40,7 @@ class LLSLURL;
bool idle_startup();
void release_start_screen();
bool login_alert_done(const LLSD& notification, const LLSD& response);
+void pump_idle_startup_network();
// start location constants
enum EStartLocation
@@ -72,6 +73,8 @@ typedef enum {
STATE_AGENT_WAIT, // Wait for region
STATE_INVENTORY_SEND, // Do inventory transfer
STATE_INVENTORY_CALLBACKS, // Wait for missing system folders and register callbacks
+ STATE_INVENTORY_SKEL, // Do more inventory skeleton loading
+ STATE_INVENTORY_SEND2, // Do more inventory init after skeleton is loaded
STATE_MISC, // Do more things (set bandwidth, start audio, save location, etc)
STATE_PRECACHE, // Wait a bit for textures to download
STATE_WEARABLES_WAIT, // Wait for clothing to download
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ea36e1d7be..1418499f8b 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -681,6 +681,13 @@ BOOL LLSurface::idleUpdate(F32 max_update_time)
}
}
}
+
+ if (did_update)
+ {
+ // some patches changed, update region reflection probes
+ mRegionp->updateReflectionProbes();
+ }
+
return did_update;
}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 5c6f7254f2..a14d4f7a30 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -95,14 +95,13 @@ private:
};
public:
- LLTextureCacheWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
+ LLTextureCacheWorker(LLTextureCache* cache, const LLUUID& id,
U8* data, S32 datasize, S32 offset,
S32 imagesize, // for writes
LLTextureCache::Responder* responder)
: LLWorkerClass(cache, "LLTextureCacheWorker"),
mID(id),
mCache(cache),
- mPriority(priority),
mReadData(NULL),
mWriteData(data),
mDataSize(datasize),
@@ -115,7 +114,6 @@ public:
mBytesToRead(0),
mBytesRead(0)
{
- mPriority &= LLWorkerThread::PRIORITY_LOWBITS;
}
~LLTextureCacheWorker()
{
@@ -129,13 +127,12 @@ public:
virtual bool doWork(S32 param); // Called from LLWorkerThread::processRequest()
- handle_t read() { addWork(0, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
- handle_t write() { addWork(1, LLWorkerThread::PRIORITY_HIGH | mPriority); return mRequestHandle; }
+ handle_t read() { addWork(0); return mRequestHandle; }
+ handle_t write() { addWork(1); return mRequestHandle; }
bool complete() { return checkWork(); }
void ioComplete(S32 bytes)
{
mBytesRead = bytes;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mPriority);
}
private:
@@ -145,7 +142,6 @@ private:
protected:
LLTextureCache* mCache;
- U32 mPriority;
LLUUID mID;
U8* mReadData;
@@ -164,11 +160,11 @@ protected:
class LLTextureCacheLocalFileWorker : public LLTextureCacheWorker
{
public:
- LLTextureCacheLocalFileWorker(LLTextureCache* cache, U32 priority, const std::string& filename, const LLUUID& id,
+ LLTextureCacheLocalFileWorker(LLTextureCache* cache, const std::string& filename, const LLUUID& id,
U8* data, S32 datasize, S32 offset,
S32 imagesize, // for writes
LLTextureCache::Responder* responder)
- : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
+ : LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
mFileName(filename)
{
@@ -183,6 +179,7 @@ private:
bool LLTextureCacheLocalFileWorker::doRead()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
S32 local_size = LLAPRFile::size(mFileName, mCache->getLocalAPRFilePool());
if (local_size > 0 && mFileName.size() > 4)
@@ -207,50 +204,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
return true;
}
-#if USE_LFS_READ
- if (mFileHandle == LLLFSThread::nullHandle())
- {
- mImageLocal = TRUE;
- mImageSize = local_size;
- if (!mDataSize || mDataSize + mOffset > local_size)
- {
- mDataSize = local_size - mOffset;
- }
- if (mDataSize <= 0)
- {
- // no more data to read
- mDataSize = 0;
- return true;
- }
- mReadData = (U8*)ALLOCATE_MEM(LLImageBase::getPrivatePool(), mDataSize);
- mBytesRead = -1;
- mBytesToRead = mDataSize;
- setPriority(LLWorkerThread::PRIORITY_LOW | mPriority);
- mFileHandle = LLLFSThread::sLocal->read(local_filename, mReadData, mOffset, mDataSize,
- new ReadResponder(mCache, mRequestHandle));
- return false;
- }
- else
- {
- if (mBytesRead >= 0)
- {
- if (mBytesRead != mBytesToRead)
- {
-// LL_WARNS() << "Error reading file from local cache: " << local_filename
-// << " Bytes: " << mDataSize << " Offset: " << mOffset
-// << " / " << mDataSize << LL_ENDL;
- mDataSize = 0; // failed
- ll_aligned_free_16(mReadData);
- mReadData = NULL;
- }
- return true;
- }
- else
- {
- return false;
- }
- }
-#else
if (!mDataSize || mDataSize > local_size)
{
mDataSize = local_size;
@@ -274,7 +227,6 @@ bool LLTextureCacheLocalFileWorker::doRead()
mImageLocal = TRUE;
}
return true;
-#endif
}
bool LLTextureCacheLocalFileWorker::doWrite()
@@ -286,12 +238,12 @@ bool LLTextureCacheLocalFileWorker::doWrite()
class LLTextureCacheRemoteWorker : public LLTextureCacheWorker
{
public:
- LLTextureCacheRemoteWorker(LLTextureCache* cache, U32 priority, const LLUUID& id,
+ LLTextureCacheRemoteWorker(LLTextureCache* cache, const LLUUID& id,
U8* data, S32 datasize, S32 offset,
S32 imagesize, // for writes
LLPointer<LLImageRaw> raw, S32 discardlevel,
LLTextureCache::Responder* responder)
- : LLTextureCacheWorker(cache, priority, id, data, datasize, offset, imagesize, responder),
+ : LLTextureCacheWorker(cache, id, data, datasize, offset, imagesize, responder),
mState(INIT),
mRawImage(raw),
mRawDiscardLevel(discardlevel)
@@ -329,6 +281,7 @@ void LLTextureCacheWorker::startWork(S32 param)
// - the code supports offset reading but this is actually never exercised in the viewer
bool LLTextureCacheRemoteWorker::doRead()
{
+ LL_PROFILE_ZONE_SCOPED;
bool done = false;
S32 idx = -1;
@@ -580,6 +533,7 @@ bool LLTextureCacheRemoteWorker::doRead()
// - the code *does not* support offset writing so there are no difference between buffer addresses and start of data
bool LLTextureCacheRemoteWorker::doWrite()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
bool done = false;
S32 idx = -1;
@@ -756,6 +710,7 @@ bool LLTextureCacheRemoteWorker::doWrite()
//virtual
bool LLTextureCacheWorker::doWork(S32 param)
{
+ LL_PROFILE_ZONE_SCOPED;
bool res = false;
if (param == 0) // read
{
@@ -775,11 +730,13 @@ bool LLTextureCacheWorker::doWork(S32 param)
//virtual (WORKER THREAD)
void LLTextureCacheWorker::finishWork(S32 param, bool completed)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mResponder.notNull())
{
bool success = (completed && mDataSize > 0);
if (param == 0)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read");
// read
if (success)
{
@@ -789,12 +746,14 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
}
else
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - read fail");
ll_aligned_free_16(mReadData);
mReadData = NULL;
}
}
else
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("tcwfw - write");
// write
mWriteData = NULL; // we never owned data
mDataSize = 0;
@@ -806,6 +765,7 @@ void LLTextureCacheWorker::finishWork(S32 param, bool completed)
//virtual (MAIN THREAD)
void LLTextureCacheWorker::endWork(S32 param, bool aborted)
{
+ LL_PROFILE_ZONE_SCOPED;
if (aborted)
{
// Let the destructor handle any cleanup
@@ -861,6 +821,7 @@ LLTextureCache::~LLTextureCache()
//virtual
size_t LLTextureCache::update(F32 max_time_ms)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static LLFrameTimer timer ;
static const F32 MAX_TIME_INTERVAL = 300.f ; //seconds.
@@ -874,22 +835,6 @@ size_t LLTextureCache::update(F32 max_time_ms)
mCompletedList.clear();
mListMutex.unlock();
- lockWorkers();
-
- for (handle_list_t::iterator iter1 = priorty_list.begin();
- iter1 != priorty_list.end(); ++iter1)
- {
- handle_t handle = *iter1;
- handle_map_t::iterator iter2 = mWriters.find(handle);
- if(iter2 != mWriters.end())
- {
- LLTextureCacheWorker* worker = iter2->second;
- worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mPriority);
- }
- }
-
- unlockWorkers();
-
// call 'completed' with workers list unlocked (may call readComplete() or writeComplete()
for (responder_list_t::iterator iter1 = completed_list.begin();
iter1 != completed_list.end(); ++iter1)
@@ -1324,6 +1269,7 @@ void LLTextureCache::updateEntryTimeStamp(S32 idx, Entry& entry)
//update an existing entry, write to header file immediately.
bool LLTextureCache::updateEntry(S32& idx, Entry& entry, S32 new_image_size, S32 new_data_size)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
S32 new_body_size = llmax(0, new_data_size - TEXTURE_CACHE_ENTRY_SIZE) ;
if(new_image_size == entry.mImageSize && new_body_size == entry.mBodySize)
@@ -1879,6 +1825,7 @@ void LLTextureCache::purgeTextures(bool validate)
// call lockWorkers() first!
LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLTextureCacheWorker* res = NULL;
handle_map_t::iterator iter = mReaders.find(handle);
if (iter != mReaders.end())
@@ -1890,6 +1837,7 @@ LLTextureCacheWorker* LLTextureCache::getReader(handle_t handle)
LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLTextureCacheWorker* res = NULL;
handle_map_t::iterator iter = mWriters.find(handle);
if (iter != mWriters.end())
@@ -1905,6 +1853,7 @@ LLTextureCacheWorker* LLTextureCache::getWriter(handle_t handle)
// Reads imagesize from the header, updates timestamp
S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLMutexLock lock(&mHeaderMutex);
S32 idx = openAndReadEntry(id, entry, false);
if (idx >= 0)
@@ -1917,6 +1866,7 @@ S32 LLTextureCache::getHeaderCacheEntry(const LLUUID& id, Entry& entry)
// Writes imagesize to the header, updates timestamp
S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imagesize, S32 datasize)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
mHeaderMutex.lock();
S32 idx = openAndReadEntry(id, entry, true); // read or create
mHeaderMutex.unlock();
@@ -1949,13 +1899,14 @@ S32 LLTextureCache::setHeaderCacheEntry(const LLUUID& id, Entry& entry, S32 imag
// Calls from texture pipeline thread (i.e. LLTextureFetch)
-LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filename, const LLUUID& id,
S32 offset, S32 size, ReadResponder* responder)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Note: checking to see if an entry exists can cause a stall,
// so let the thread handle it
LLMutexLock lock(&mWorkersMutex);
- LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, priority, filename, id,
+ LLTextureCacheWorker* worker = new LLTextureCacheLocalFileWorker(this, filename, id,
NULL, size, offset, 0,
responder);
handle_t handle = worker->read();
@@ -1963,13 +1914,14 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const std::string& filena
return handle;
}
-LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id,
S32 offset, S32 size, ReadResponder* responder)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
// Note: checking to see if an entry exists can cause a stall,
// so let the thread handle it
LLMutexLock lock(&mWorkersMutex);
- LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
+ LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
NULL, size, offset,
0, NULL, 0, responder);
handle_t handle = worker->read();
@@ -1980,6 +1932,7 @@ LLTextureCache::handle_t LLTextureCache::readFromCache(const LLUUID& id, U32 pri
bool LLTextureCache::readComplete(handle_t handle, bool abort)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
lockWorkers();
handle_map_t::iterator iter = mReaders.find(handle);
LLTextureCacheWorker* worker = NULL;
@@ -2007,7 +1960,7 @@ bool LLTextureCache::readComplete(handle_t handle, bool abort)
return (complete || abort);
}
-LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 priority,
+LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id,
U8* data, S32 datasize, S32 imagesize,
LLPointer<LLImageRaw> rawimage, S32 discardlevel,
WriteResponder* responder)
@@ -2025,7 +1978,7 @@ LLTextureCache::handle_t LLTextureCache::writeToCache(const LLUUID& id, U32 prio
mDoPurge = !mPurgeEntryList.empty();
}
LLMutexLock lock(&mWorkersMutex);
- LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, priority, id,
+ LLTextureCacheWorker* worker = new LLTextureCacheRemoteWorker(this, id,
data, datasize, 0,
imagesize, rawimage, discardlevel, responder);
handle_t handle = worker->write();
@@ -2093,6 +2046,7 @@ LLPointer<LLImageRaw> LLTextureCache::readFromFastCache(const LLUUID& id, S32& d
//return the fast cache location
bool LLTextureCache::writeToFastCache(LLUUID image_id, S32 id, LLPointer<LLImageRaw> raw, S32 discardlevel)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
//rescale image if needed
if (raw.isNull() || raw->isBufferInvalid() || !raw->getData())
{
diff --git a/indra/newview/lltexturecache.h b/indra/newview/lltexturecache.h
index b6ace467c7..43e91b3e4c 100644
--- a/indra/newview/lltexturecache.h
+++ b/indra/newview/lltexturecache.h
@@ -119,13 +119,13 @@ public:
void setReadOnly(BOOL read_only) ;
S64 initCache(ELLPath location, S64 maxsize, BOOL texture_cache_mismatch);
- handle_t readFromCache(const std::string& local_filename, const LLUUID& id, U32 priority, S32 offset, S32 size,
+ handle_t readFromCache(const std::string& local_filename, const LLUUID& id, S32 offset, S32 size,
ReadResponder* responder);
- handle_t readFromCache(const LLUUID& id, U32 priority, S32 offset, S32 size,
+ handle_t readFromCache(const LLUUID& id, S32 offset, S32 size,
ReadResponder* responder);
bool readComplete(handle_t handle, bool abort);
- handle_t writeToCache(const LLUUID& id, U32 priority, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
+ handle_t writeToCache(const LLUUID& id, U8* data, S32 datasize, S32 imagesize, LLPointer<LLImageRaw> rawimage, S32 discardlevel,
WriteResponder* responder);
LLPointer<LLImageRaw> readFromFastCache(const LLUUID& id, S32& discardlevel);
bool writeComplete(handle_t handle, bool abort = false);
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 2e137a8e12..3988bceb4e 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -41,12 +41,15 @@
#include "llfolderviewmodel.h"
#include "llinventory.h"
#include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
#include "llinventorymodelbackgroundfetch.h"
#include "llinventoryobserver.h"
#include "llinventorypanel.h"
#include "lllineeditor.h"
+#include "llmaterialeditor.h"
#include "llui.h"
#include "llviewerinventory.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llpermissions.h"
#include "llpreviewtexture.h"
#include "llsaleinfo.h"
@@ -70,19 +73,12 @@
#include "llradiogroup.h"
#include "llfloaterreg.h"
#include "lllocalbitmaps.h"
+#include "lllocalgltfmaterials.h"
#include "llerror.h"
#include "llavatarappearancedefines.h"
-static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
-
-//static const char CURRENT_IMAGE_NAME[] = "Current Texture";
-//static const char WHITE_IMAGE_NAME[] = "Blank Texture";
-//static const char NO_IMAGE_NAME[] = "None";
-
-
-
//static
bool get_is_predefined_texture(LLUUID asset_id)
{
@@ -142,6 +138,8 @@ bool get_can_copy_texture(LLUUID asset_id)
return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull();
}
+S32 LLFloaterTexturePicker::sLastPickerMode = 0;
+
LLFloaterTexturePicker::LLFloaterTexturePicker(
LLView* owner,
LLUUID image_asset_id,
@@ -152,7 +150,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask dnd_filter_perm_mask,
- PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image)
: LLFloater(LLSD()),
@@ -171,7 +168,6 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mFilterEdit(NULL),
mImmediateFilterPermMask(immediate_filter_perm_mask),
mDnDFilterPermMask(dnd_filter_perm_mask),
- mNonImmediateFilterPermMask(non_immediate_filter_perm_mask),
mContextConeOpacity(0.f),
mSelectedItemPinned( FALSE ),
mCanApply(true),
@@ -184,10 +180,11 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
mOnFloaterCloseCallback(NULL),
mSetImageAssetIDCallback(NULL),
mOnUpdateImageStatsCallback(NULL),
- mBakeTextureEnabled(FALSE)
+ mBakeTextureEnabled(FALSE),
+ mInventoryPickType(LLTextureCtrl::PICK_TEXTURE)
{
- buildFromFile("floater_texture_ctrl.xml");
mCanApplyImmediately = can_apply_immediately;
+ buildFromFile("floater_texture_ctrl.xml");
setCanMinimize(FALSE);
}
@@ -218,15 +215,38 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
mModeSelector->selectByValue(0);
onModeSelect(0,this);
}
-
- LLUUID item_id = findItemID(mImageAssetID, FALSE);
+
+ LLUUID item_id;
+ LLFolderView* root_folder = mInventoryPanel->getRootFolder();
+ if (root_folder && root_folder->getCurSelectedItem())
+ {
+ LLFolderViewItem* last_selected = root_folder->getCurSelectedItem();
+ LLFolderViewModelItemInventory* inv_view = static_cast<LLFolderViewModelItemInventory*>(last_selected->getViewModelItem());
+
+ LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL
+ && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && itemp && itemp->getAssetUUID().isNull())
+ {
+ item_id = inv_view->getUUID();
+ }
+ else if (itemp && itemp->getAssetUUID() == mImageAssetID)
+ {
+ item_id = inv_view->getUUID();
+ }
+ }
+ if (item_id.isNull())
+ {
+ item_id = findItemID(mImageAssetID, FALSE);
+ }
if (item_id.isNull())
{
mInventoryPanel->getRootFolder()->clearSelection();
}
else
{
- LLInventoryItem* itemp = gInventory.getItem(image_id);
+ LLInventoryItem* itemp = gInventory.getItem(item_id);
if (itemp && !itemp->getPermissions().allowCopyBy(gAgent.getID()))
{
// no copy texture
@@ -240,12 +260,20 @@ void LLFloaterTexturePicker::setImageID(const LLUUID& image_id, bool set_selecti
mInventoryPanel->setSelection(item_id, TAKE_FOCUS_NO);
}
}
-
-
-
}
}
+void LLFloaterTexturePicker::setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection)
+{
+ LLUUID asset_id = itemp->getAssetUUID();
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull())
+ {
+ // If an inventory item has a null asset, consider it a valid blank material(gltf)
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+ setImageID(asset_id, set_selection);
+}
+
void LLFloaterTexturePicker::setActive( BOOL active )
{
if (!active && getChild<LLUICtrl>("Pipette")->getValue().asBoolean())
@@ -258,11 +286,10 @@ void LLFloaterTexturePicker::setActive( BOOL active )
void LLFloaterTexturePicker::setCanApplyImmediately(BOOL b)
{
mCanApplyImmediately = b;
- if (!mCanApplyImmediately)
- {
- getChild<LLUICtrl>("apply_immediate_check")->setValue(FALSE);
- }
- updateFilterPermMask();
+
+ LLUICtrl *apply_checkbox = getChild<LLUICtrl>("apply_immediate_check");
+ apply_checkbox->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
+ apply_checkbox->setEnabled(mCanApplyImmediately);
}
void LLFloaterTexturePicker::stopUsingPipette()
@@ -276,7 +303,59 @@ void LLFloaterTexturePicker::stopUsingPipette()
bool LLFloaterTexturePicker::updateImageStats()
{
bool result = true;
- if (mTexturep.notNull())
+ if (mGLTFMaterial.notNull())
+ {
+ S32 width = 0;
+ S32 height = 0;
+
+ bool has_texture = false;
+
+ if (mGLTFMaterial->mBaseColorTexture)
+ {
+ width = llmax(width, mGLTFMaterial->mBaseColorTexture->getFullWidth());
+ height = llmax(height, mGLTFMaterial->mBaseColorTexture->getFullHeight());
+ has_texture = true;
+ }
+ if (mGLTFMaterial->mNormalTexture)
+ {
+ width = llmax(width, mGLTFMaterial->mNormalTexture->getFullWidth());
+ height = llmax(height, mGLTFMaterial->mNormalTexture->getFullHeight());
+ has_texture = true;
+ }
+ if (mGLTFMaterial->mMetallicRoughnessTexture)
+ {
+ width = llmax(width, mGLTFMaterial->mMetallicRoughnessTexture->getFullWidth());
+ height = llmax(height, mGLTFMaterial->mMetallicRoughnessTexture->getFullHeight());
+ has_texture = true;
+ }
+ if (mGLTFMaterial->mEmissiveTexture)
+ {
+ width = llmax(width, mGLTFMaterial->mEmissiveTexture->getFullWidth());
+ height = llmax(height, mGLTFMaterial->mEmissiveTexture->getFullHeight());
+ has_texture = true;
+ }
+
+ if (width > 0 && height > 0)
+ {
+ std::string formatted_dims = llformat("%d x %d", width, height);
+ mResolutionLabel->setTextArg("[DIMENSIONS]", formatted_dims);
+ if (mOnUpdateImageStatsCallback)
+ {
+ mOnUpdateImageStatsCallback(mTexturep);
+ }
+ }
+ else if (has_texture)
+ {
+ // unknown resolution
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string("[? x ?]"));
+ }
+ else
+ {
+ // No textures - no applicable resolution (may be show some max value instead?)
+ mResolutionLabel->setTextArg("[DIMENSIONS]", std::string(""));
+ }
+ }
+ else if (mTexturep.notNull())
{
//RN: have we received header data for this image?
S32 width = mTexturep->getFullWidth();
@@ -342,8 +421,24 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
BOOL handled = FALSE;
bool is_mesh = cargo_type == DAD_MESH;
+ bool is_texture = cargo_type == DAD_TEXTURE;
+ bool is_material = cargo_type == DAD_MATERIAL;
+
+ bool allow_dnd = false;
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ allow_dnd = is_material;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ allow_dnd = is_texture || is_mesh;
+ }
+ else
+ {
+ allow_dnd = is_texture || is_mesh || is_material;
+ }
- if ((cargo_type == DAD_TEXTURE) || is_mesh)
+ if (allow_dnd)
{
LLInventoryItem *item = (LLInventoryItem *)cargo_data;
@@ -357,13 +452,12 @@ BOOL LLFloaterTexturePicker::handleDragAndDrop(
if (mod) item_perm_mask |= PERM_MODIFY;
if (xfer) item_perm_mask |= PERM_TRANSFER;
- //PermissionMask filter_perm_mask = getFilterPermMask(); Commented out due to no-copy texture loss.
PermissionMask filter_perm_mask = mDnDFilterPermMask;
if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
{
if (drop)
{
- setImageID( item->getAssetUUID() );
+ setImageIDFromItem(item);
commitIfImmediateSet();
}
@@ -423,6 +517,15 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
return LLFloater::handleKeyHere(key, mask);
}
+void LLFloaterTexturePicker::onOpen(const LLSD& key)
+{
+ if (sLastPickerMode != 0
+ && mModeSelector->selectByValue(sLastPickerMode))
+ {
+ changeMode();
+ }
+}
+
void LLFloaterTexturePicker::onClose(bool app_quitting)
{
if (mOwner && mOnFloaterCloseCallback)
@@ -430,6 +533,7 @@ void LLFloaterTexturePicker::onClose(bool app_quitting)
mOnFloaterCloseCallback();
}
stopUsingPipette();
+ sLastPickerMode = mModeSelector->getValue().asInteger();
}
// virtual
@@ -463,12 +567,8 @@ BOOL LLFloaterTexturePicker::postBuild()
mSelectBtn->setClickedCallback(boost::bind(LLFloaterTexturePicker::onBtnSelect, this));
mCancelBtn->setClickedCallback(boost::bind(LLFloaterTexturePicker::onBtnCancel, this));
-
- childSetCommitCallback("show_folders_check", onShowFolders, this);
- getChildView("show_folders_check")->setVisible( FALSE);
-
- mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
- mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
+ mFilterEdit = getChild<LLFilterEditor>("inventory search editor");
+ mFilterEdit->setCommitCallback(boost::bind(&LLFloaterTexturePicker::onFilterEdit, this, _2));
mInventoryPanel = getChild<LLInventoryPanel>("inventory panel");
@@ -478,12 +578,12 @@ BOOL LLFloaterTexturePicker::postBuild()
if(mInventoryPanel)
{
- U32 filter_types = 0x0;
- filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
- filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ // to avoid having to make an assumption about which option is
+ // selected at startup, we call the same function that is triggered
+ // when a texture/materials/both choice is made and let it take care
+ // of setting the filters
+ refreshInventoryFilter();
- mInventoryPanel->setFilterTypes(filter_types);
- //mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
mInventoryPanel->setFilterPermMask(mImmediateFilterPermMask);
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterTexturePicker::onSelectionChange, this, _1, _2));
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
@@ -516,26 +616,23 @@ BOOL LLFloaterTexturePicker::postBuild()
mLocalScrollCtrl = getChild<LLScrollListCtrl>("l_name_list");
mLocalScrollCtrl->setCommitCallback(onLocalScrollCommit, this);
- LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ refreshLocalList();
mNoCopyTextureSelected = FALSE;
- getChild<LLUICtrl>("apply_immediate_check")->setValue(gSavedSettings.getBOOL("TextureLivePreview"));
+ getChild<LLUICtrl>("apply_immediate_check")->setValue(mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview"));
childSetCommitCallback("apply_immediate_check", onApplyImmediateCheck, this);
+ getChildView("apply_immediate_check")->setEnabled(mCanApplyImmediately);
- if (!mCanApplyImmediately)
- {
- getChildView("show_folders_check")->setEnabled(FALSE);
- }
+ getChild<LLUICtrl>("Pipette")->setCommitCallback( boost::bind(&LLFloaterTexturePicker::onBtnPipette, this));
+ childSetAction("Cancel", LLFloaterTexturePicker::onBtnCancel,this);
+ childSetAction("Select", LLFloaterTexturePicker::onBtnSelect,this);
- // update permission filter once UI is fully initialized
- updateFilterPermMask();
mSavedFolderState.setApply(FALSE);
LLToolPipette::getInstance()->setToolSelectCallback(boost::bind(&LLFloaterTexturePicker::onTextureSelect, this, _1));
getChild<LLComboBox>("l_bake_use_texture_combo_box")->setCommitCallback(onBakeTextureSelect, this);
- getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setCommitCallback(onHideBaseMeshRegionCheck, this);
setBakeTextureEnabled(TRUE);
return TRUE;
@@ -547,6 +644,8 @@ void LLFloaterTexturePicker::draw()
static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
drawConeToOwner(mContextConeOpacity, max_opacity, mOwner);
+ // This is going to spam mOnUpdateImageStatsCallback,
+ // either move elsewhere or fix to cause update once per image
bool valid_dims = updateImageStats();
// if we're inactive, gray out "apply immediate" checkbox
@@ -559,28 +658,39 @@ void LLFloaterTexturePicker::draw()
if( mOwner )
{
mTexturep = NULL;
- if(mImageAssetID.notNull())
- {
- LLPointer<LLViewerFetchedTexture> texture = NULL;
+ mGLTFMaterial = NULL;
+ if (mImageAssetID.notNull())
+ {
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ mGLTFMaterial = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mImageAssetID);
+ llassert(mGLTFMaterial == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mImageAssetID)) != nullptr);
+ }
+ else
+ {
+ LLPointer<LLViewerFetchedTexture> texture = NULL;
- if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
- {
- LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
- if (obj)
- {
- LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
- texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
- }
- }
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(mImageAssetID))
+ {
+ // TODO: Fix this! Picker is not warrantied to be connected to a selection
+ // LLSelectMgr shouldn't be used in texture picker
+ LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
+ if (obj)
+ {
+ LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(mImageAssetID);
+ texture = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : NULL;
+ }
+ }
- if (texture.isNull())
- {
- texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
- }
+ if (texture.isNull())
+ {
+ texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
+ }
- mTexturep = texture;
- mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
- }
+ mTexturep = texture;
+ mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
+ }
+ }
if (mTentativeLabel)
{
@@ -588,7 +698,7 @@ void LLFloaterTexturePicker::draw()
}
mDefaultBtn->setEnabled(mImageAssetID != mDefaultImageAssetID || mTentative);
- mBlankBtn->setEnabled(mImageAssetID != mBlankImageAssetID || mTentative);
+ mBlankBtn->setEnabled((mImageAssetID != mBlankImageAssetID && mBlankImageAssetID.notNull()) || mTentative);
mNoneBtn->setEnabled(mAllowNoTexture && (!mImageAssetID.isNull() || mTentative));
LLFloater::draw();
@@ -666,9 +776,22 @@ void LLFloaterTexturePicker::draw()
const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only, BOOL ignore_library)
{
+ LLUUID loockup_id = asset_id;
+ if (loockup_id.isNull())
+ {
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ loockup_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+ else
+ {
+ return LLUUID::null;
+ }
+ }
+
LLViewerInventoryCategory::cat_array_t cats;
LLViewerInventoryItem::item_array_t items;
- LLAssetIDMatches asset_id_matches(asset_id);
+ LLAssetIDMatches asset_id_matches(loockup_id);
gInventory.collectDescendentsIf(LLUUID::null,
cats,
items,
@@ -707,12 +830,6 @@ const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL co
return LLUUID::null;
}
-PermissionMask LLFloaterTexturePicker::getFilterPermMask()
-{
- bool apply_immediate = getChild<LLUICtrl>("apply_immediate_check")->getValue().asBoolean();
- return apply_immediate ? mImmediateFilterPermMask : mNonImmediateFilterPermMask;
-}
-
void LLFloaterTexturePicker::commitIfImmediateSet()
{
if (!mNoCopyTextureSelected && mCanApply)
@@ -729,6 +846,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
}
LLUUID asset_id = mImageAssetID;
LLUUID inventory_id;
+ LLUUID tracking_id;
LLPickerSource mode = (LLPickerSource)mModeSelector->getValue().asInteger();
switch (mode)
@@ -742,7 +860,14 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
LLFolderViewModelItemInventory* inv_view = static_cast<LLFolderViewModelItemInventory*>(last_selected->getViewModelItem());
LLInventoryItem* itemp = gInventory.getItem(inv_view->getUUID());
- if (itemp && itemp->getAssetUUID() == mImageAssetID)
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL
+ && mImageAssetID == LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID
+ && itemp && itemp->getAssetUUID().isNull())
+ {
+ inventory_id = inv_view->getUUID();
+ }
+ else if (itemp && itemp->getAssetUUID() == mImageAssetID)
{
inventory_id = inv_view->getUUID();
}
@@ -761,8 +886,18 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
{
if (!mLocalScrollCtrl->getAllSelected().empty())
{
- LLUUID temp_id = mLocalScrollCtrl->getFirstSelected()->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id);
+ LLSD data = mLocalScrollCtrl->getFirstSelected()->getValue();
+ tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
+ }
+ else
+ {
+ asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ }
}
else
{
@@ -778,13 +913,13 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op)
break;
}
- mOnFloaterCommitCallback(op, mode, asset_id, inventory_id);
+ mOnFloaterCommitCallback(op, mode, asset_id, inventory_id, tracking_id);
}
void LLFloaterTexturePicker::commitCancel()
{
if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply)
{
- mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null);
+ mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null);
}
}
@@ -814,8 +949,9 @@ void LLFloaterTexturePicker::onBtnBlank(void* userdata)
void LLFloaterTexturePicker::onBtnNone(void* userdata)
{
LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->setCanApply(true, true);
self->setImageID( LLUUID::null );
- self->commitCancel();
+ self->commitIfImmediateSet();
}
/*
@@ -837,7 +973,7 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
self->setImageID( self->mOriginalImageAssetID );
if (self->mOnFloaterCommitCallback)
{
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null);
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null);
}
self->mViewModel->resetDirty();
self->closeFloater();
@@ -846,8 +982,11 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata)
// static
void LLFloaterTexturePicker::onBtnSelect(void* userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- self->commitCallback(LLTextureCtrl::TEXTURE_SELECT);
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ if (self->mOnFloaterCommitCallback)
+ {
+ self->commitCallback(LLTextureCtrl::TEXTURE_SELECT);
+ }
self->closeFloater();
}
@@ -882,12 +1021,12 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
{
mNoCopyTextureSelected = TRUE;
}
- setImageID(itemp->getAssetUUID(),false);
+ setImageIDFromItem(itemp, false);
mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
if(!mPreviewSettingChanged)
{
- mCanPreview = gSavedSettings.getBOOL("TextureLivePreview");
+ mCanPreview = mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
}
else
{
@@ -906,92 +1045,27 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
// static
void LLFloaterTexturePicker::onModeSelect(LLUICtrl* ctrl, void *userdata)
{
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- int index = self->mModeSelector->getValue().asInteger();
-
- self->mDefaultBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->mBlankBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->mNoneBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->mPipetteBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->getChild<LLFilterEditor>("inventory search editor")->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
- self->getChild<LLInventoryPanel>("inventory panel")->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
-
- /*self->getChild<LLCheckBox>("show_folders_check")->setVisible(mode);
- no idea under which conditions the above is even shown, needs testing. */
-
- self->getChild<LLButton>("l_add_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLButton>("l_rem_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLButton>("l_upl_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
- self->getChild<LLScrollListCtrl>("l_name_list")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
-
- self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(index == PICKER_BAKE ? TRUE : FALSE);
- self->getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE);
-
- if (index == PICKER_BAKE)
- {
- self->stopUsingPipette();
-
- S8 val = -1;
-
- LLUUID imageID = self->mImageAssetID;
- if (imageID == IMG_USE_BAKED_HEAD)
- {
- val = 0;
- }
- else if (imageID == IMG_USE_BAKED_UPPER)
- {
- val = 1;
- }
- else if (imageID == IMG_USE_BAKED_LOWER)
- {
- val = 2;
- }
- else if (imageID == IMG_USE_BAKED_EYES)
- {
- val = 3;
- }
- else if (imageID == IMG_USE_BAKED_SKIRT)
- {
- val = 4;
- }
- else if (imageID == IMG_USE_BAKED_HAIR)
- {
- val = 5;
- }
- else if (imageID == IMG_USE_BAKED_LEFTARM)
- {
- val = 6;
- }
- else if (imageID == IMG_USE_BAKED_LEFTLEG)
- {
- val = 7;
- }
- else if (imageID == IMG_USE_BAKED_AUX1)
- {
- val = 8;
- }
- else if (imageID == IMG_USE_BAKED_AUX2)
- {
- val = 9;
- }
- else if (imageID == IMG_USE_BAKED_AUX3)
- {
- val = 10;
- }
-
-
- self->getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE);
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
+ self->changeMode();
}
// static
void LLFloaterTexturePicker::onBtnAdd(void* userdata)
{
- if (LLLocalBitmapMgr::getInstance()->addUnit() == true)
- {
- LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
- }
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)userdata;
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL_TEXTURE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_IMAGE, true);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLFilePickerReplyThread::startPicker(boost::bind(&onPickerCallback, _1, self->getHandle()), LLFilePicker::FFLOAD_MATERIAL, true);
+ }
}
// static
@@ -1002,22 +1076,32 @@ void LLFloaterTexturePicker::onBtnRemove(void* userdata)
if (!selected_items.empty())
{
+
for(std::vector<LLScrollListItem*>::iterator iter = selected_items.begin();
iter != selected_items.end(); iter++)
{
LLScrollListItem* list_item = *iter;
if (list_item)
{
- LLUUID tracking_id = list_item->getColumn(LOCAL_TRACKING_ID_COLUMN)->getValue().asUUID();
- LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->delUnit(tracking_id);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->delUnit(tracking_id);
+ }
}
}
self->getChild<LLButton>("l_rem_btn")->setEnabled(false);
self->getChild<LLButton>("l_upl_btn")->setEnabled(false);
- LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ self->refreshLocalList();
}
-
}
// static
@@ -1033,15 +1117,29 @@ void LLFloaterTexturePicker::onBtnUpload(void* userdata)
/* currently only allows uploading one by one, picks the first item from the selection list. (not the vector!)
in the future, it might be a good idea to check the vector size and if more than one units is selected - opt for multi-image upload. */
-
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
- if (!filename.empty())
- {
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
- }
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ std::string filename;
+ S32 index;
+ LLLocalGLTFMaterialMgr::getInstance()->getFilenameAndIndex(tracking_id, filename, index);
+ if (!filename.empty())
+ {
+ LLMaterialEditor::loadMaterialFromFile(filename, index);
+ }
+ }
+ else
+ {
+ std::string filename = LLLocalBitmapMgr::getInstance()->getFilename(tracking_id);
+ if (!filename.empty())
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+ }
}
//static
@@ -1057,8 +1155,20 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
if (has_selection)
{
- LLUUID tracking_id = (LLUUID)self->mLocalScrollCtrl->getSelectedItemLabel(LOCAL_TRACKING_ID_COLUMN);
- LLUUID inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ LLSD data = self->mLocalScrollCtrl->getFirstSelected()->getValue();
+ LLUUID tracking_id = data["id"];
+ S32 asset_type = data["type"].asInteger();
+ LLUUID inworld_id;
+
+ if (LLAssetType::AT_MATERIAL == asset_type)
+ {
+ inworld_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id);
+ }
+ else
+ {
+ inworld_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id);
+ }
+
if (self->mSetImageAssetIDCallback)
{
self->mSetImageAssetIDCallback(inworld_id);
@@ -1068,29 +1178,13 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata)
{
if (self->mOnFloaterCommitCallback)
{
- self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null);
+ self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id);
}
}
}
}
// static
-void LLFloaterTexturePicker::onShowFolders(LLUICtrl* ctrl, void *user_data)
-{
- LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
- LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
-
- if (check_box->get())
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
- }
- else
- {
- picker->mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NO_FOLDERS);
- }
-}
-
-// static
void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_data)
{
LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
@@ -1098,7 +1192,6 @@ void LLFloaterTexturePicker::onApplyImmediateCheck(LLUICtrl* ctrl, void *user_da
LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
gSavedSettings.setBOOL("TextureLivePreview", check_box->get());
- picker->updateFilterPermMask();
picker->commitIfImmediateSet();
}
@@ -1161,7 +1254,7 @@ void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data
if (!self->mPreviewSettingChanged)
{
- self->mCanPreview = gSavedSettings.getBOOL("TextureLivePreview");
+ self->mCanPreview = self->mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview");
}
else
{
@@ -1175,18 +1268,6 @@ void LLFloaterTexturePicker::onBakeTextureSelect(LLUICtrl* ctrl, void *user_data
}
}
-//static
-void LLFloaterTexturePicker::onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *user_data)
-{
- //LLFloaterTexturePicker* picker = (LLFloaterTexturePicker*)user_data;
- //LLCheckBoxCtrl* check_box = (LLCheckBoxCtrl*)ctrl;
-}
-
-void LLFloaterTexturePicker::updateFilterPermMask()
-{
- //mInventoryPanel->setFilterPermMask( getFilterPermMask() ); Commented out due to no-copy texture loss.
-}
-
void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool inworld_image)
{
mSelectBtn->setEnabled(can_apply);
@@ -1194,7 +1275,7 @@ void LLFloaterTexturePicker::setCanApply(bool can_preview, bool can_apply, bool
getChildRef<LLUICtrl>("apply_immediate_check").setVisible(can_preview);
mCanApply = can_apply;
- mCanPreview = can_preview ? gSavedSettings.getBOOL("TextureLivePreview") : false;
+ mCanPreview = can_preview ? (mCanApplyImmediately && gSavedSettings.getBOOL("TextureLivePreview")) : false;
mPreviewSettingChanged = true;
}
@@ -1241,6 +1322,126 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
mInventoryPanel->setFilterSubString(search_string);
}
+void LLFloaterTexturePicker::changeMode()
+{
+ int index = mModeSelector->getValue().asInteger();
+
+ mDefaultBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mBlankBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mNoneBtn->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mFilterEdit->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+ mInventoryPanel->setVisible(index == PICKER_INVENTORY ? TRUE : FALSE);
+
+ getChild<LLButton>("l_add_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLButton>("l_rem_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLButton>("l_upl_btn")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+ getChild<LLScrollListCtrl>("l_name_list")->setVisible(index == PICKER_LOCAL ? TRUE : FALSE);
+
+ getChild<LLComboBox>("l_bake_use_texture_combo_box")->setVisible(index == PICKER_BAKE ? TRUE : FALSE);
+ getChild<LLCheckBoxCtrl>("hide_base_mesh_region")->setVisible(FALSE);// index == 2 ? TRUE : FALSE);
+
+ bool pipette_visible = (index == PICKER_INVENTORY)
+ && (mInventoryPickType != LLTextureCtrl::PICK_MATERIAL);
+ mPipetteBtn->setVisible(pipette_visible);
+
+ if (index == PICKER_BAKE)
+ {
+ stopUsingPipette();
+
+ S8 val = -1;
+
+ LLUUID imageID = mImageAssetID;
+ if (imageID == IMG_USE_BAKED_HEAD)
+ {
+ val = 0;
+ }
+ else if (imageID == IMG_USE_BAKED_UPPER)
+ {
+ val = 1;
+ }
+ else if (imageID == IMG_USE_BAKED_LOWER)
+ {
+ val = 2;
+ }
+ else if (imageID == IMG_USE_BAKED_EYES)
+ {
+ val = 3;
+ }
+ else if (imageID == IMG_USE_BAKED_SKIRT)
+ {
+ val = 4;
+ }
+ else if (imageID == IMG_USE_BAKED_HAIR)
+ {
+ val = 5;
+ }
+ else if (imageID == IMG_USE_BAKED_LEFTARM)
+ {
+ val = 6;
+ }
+ else if (imageID == IMG_USE_BAKED_LEFTLEG)
+ {
+ val = 7;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX1)
+ {
+ val = 8;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX2)
+ {
+ val = 9;
+ }
+ else if (imageID == IMG_USE_BAKED_AUX3)
+ {
+ val = 10;
+ }
+
+ getChild<LLComboBox>("l_bake_use_texture_combo_box")->setSelectedByValue(val, TRUE);
+ }
+}
+
+void LLFloaterTexturePicker::refreshLocalList()
+{
+ mLocalScrollCtrl->clearRows();
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(mLocalScrollCtrl);
+ }
+}
+
+void LLFloaterTexturePicker::refreshInventoryFilter()
+{
+ U32 filter_types = 0x0;
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_TEXTURE;
+ filter_types |= 0x1 << LLInventoryType::IT_SNAPSHOT;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ filter_types |= 0x1 << LLInventoryType::IT_MATERIAL;
+ }
+
+ mInventoryPanel->setFilterTypes(filter_types);
+}
+
void LLFloaterTexturePicker::setLocalTextureEnabled(BOOL enabled)
{
mModeSelector->setEnabledByValue(1, enabled);
@@ -1268,13 +1469,103 @@ void LLFloaterTexturePicker::setBakeTextureEnabled(BOOL enabled)
onModeSelect(0, this);
}
+void LLFloaterTexturePicker::setInventoryPickType(LLTextureCtrl::EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ refreshLocalList();
+ refreshInventoryFilter();
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ getChild<LLButton>("Pipette")->setVisible(false);
+ }
+ else
+ {
+ S32 index = mModeSelector->getValue().asInteger();
+ getChild<LLButton>("Pipette")->setVisible(index == 0);
+ }
+
+ if (!mLabel.empty())
+ {
+ std::string pick = getString("pick title");
+
+ setTitle(pick + mLabel);
+ }
+ else if(mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ setTitle(getString("pick_material"));
+ }
+ else
+ {
+ setTitle(getString("pick_texture"));
+ }
+}
+
+void LLFloaterTexturePicker::setImmediateFilterPermMask(PermissionMask mask)
+{
+ mImmediateFilterPermMask = mask;
+ mInventoryPanel->setFilterPermMask(mask);
+}
+
+void LLFloaterTexturePicker::onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle)
+{
+ std::vector<std::string>::const_iterator iter = filenames.begin();
+ while (iter != filenames.end())
+ {
+ if (!iter->empty())
+ {
+ std::string temp_exten = gDirUtilp->getExtension(*iter);
+ if (temp_exten == "gltf" || temp_exten == "glb")
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->addUnit(*iter);
+ }
+ else
+ {
+ LLLocalBitmapMgr::getInstance()->addUnit(*iter);
+ }
+ }
+ iter++;
+ }
+
+ // Todo: this should referesh all pickers, not just a current one
+ if (!handle.isDead())
+ {
+ LLFloaterTexturePicker* self = (LLFloaterTexturePicker*)handle.get();
+ self->mLocalScrollCtrl->clearRows();
+
+ if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE_MATERIAL)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ LLLocalBitmapMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ else if (self->mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ LLLocalGLTFMaterialMgr::getInstance()->feedScrollList(self->mLocalScrollCtrl);
+ }
+ }
+}
+
void LLFloaterTexturePicker::onTextureSelect( const LLTextureEntry& te )
{
LLUUID inventory_item_id = findItemID(te.getID(), TRUE);
if (inventory_item_id.notNull())
{
LLToolPipette::getInstance()->setResult(TRUE, "");
- setImageID(te.getID());
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ // tes have no data about material ids
+ // Plus gltf materials are layered with overrides,
+ // which mean that end result might have no id.
+ LL_WARNS() << "tes have no data about material ids" << LL_ENDL;
+ }
+ else
+ {
+ setImageID(te.getID());
+ }
mNoCopyTextureSelected = FALSE;
LLInventoryItem* itemp = gInventory.getItem(inventory_item_id);
@@ -1306,15 +1597,16 @@ LLTextureCtrl::LLTextureCtrl(const LLTextureCtrl::Params& p)
mOnCloseCallback(NULL),
mOnSelectCallback(NULL),
mBorderColor( p.border_color() ),
- mAllowNoTexture( FALSE ),
+ mAllowNoTexture( p.allow_no_texture ),
mAllowLocalTexture( TRUE ),
mImmediateFilterPermMask( PERM_NONE ),
- mNonImmediateFilterPermMask( PERM_NONE ),
mCanApplyImmediately( FALSE ),
mNeedsRawImageData( FALSE ),
mValid( TRUE ),
mShowLoadingPlaceholder( TRUE ),
mOpenTexPreview(false),
+ mBakeTextureEnabled(true),
+ mInventoryPickType(PICK_TEXTURE),
mImageAssetID(p.image_id),
mDefaultImageAssetID(p.default_image_id),
mDefaultImageName(p.default_image_name),
@@ -1402,6 +1694,17 @@ void LLTextureCtrl::setCanApply(bool can_preview, bool can_apply)
}
}
+void LLTextureCtrl::setImmediateFilterPermMask(PermissionMask mask)
+{
+ mImmediateFilterPermMask = mask;
+
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setImmediateFilterPermMask(mask);
+ }
+}
+
void LLTextureCtrl::setVisible( BOOL visible )
{
if( !visible )
@@ -1487,7 +1790,6 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
mLabel,
mImmediateFilterPermMask,
mDnDFilterPermMask,
- mNonImmediateFilterPermMask,
mCanApplyImmediately,
mFallbackImage);
mFloaterHandle = floaterp->getHandle();
@@ -1503,15 +1805,14 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
}
if (texture_floaterp)
{
- texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4));
+ texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5));
}
if (texture_floaterp)
{
texture_floaterp->setSetImageAssetIDCallback(boost::bind(&LLTextureCtrl::setImageAssetID, this, _1));
- }
- if (texture_floaterp)
- {
- texture_floaterp->setBakeTextureEnabled(TRUE);
+
+ texture_floaterp->setBakeTextureEnabled(mBakeTextureEnabled);
+ texture_floaterp->setInventoryPickType(mInventoryPickType);
}
LLFloater* root_floater = gFloaterView->getParentFloater(this);
@@ -1574,9 +1875,17 @@ BOOL LLTextureCtrl::handleMouseDown(S32 x, S32 y, MASK mask)
if (!mOpenTexPreview)
{
showPicker(FALSE);
- //grab textures first...
- LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
- //...then start full inventory fetch (should have been done on startup, but just in case.
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ //grab materials first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL));
+ }
+ else
+ {
+ //grab textures first...
+ LLInventoryModelBackgroundFetch::instance().start(gInventory.findCategoryUUIDForType(LLFolderType::FT_TEXTURE));
+ }
+ //...then start full inventory fetch.
if (!LLInventoryModelBackgroundFetch::instance().inventoryFetchStarted())
{
LLInventoryModelBackgroundFetch::instance().start();
@@ -1620,11 +1929,11 @@ void LLTextureCtrl::onFloaterClose()
mFloaterHandle.markDead();
}
-void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id)
+void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id)
{
- LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
- if( floaterp && getEnabled())
+ if( floaterp && getEnabled())
{
if (op == TEXTURE_CANCEL)
mViewModel->resetDirty();
@@ -1643,16 +1952,23 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
case PICKER_INVENTORY:
mImageItemID = inv_id;
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
break;
case PICKER_BAKE:
+ mImageItemID = LLUUID::null;
+ mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
+ break;
case PICKER_LOCAL:
mImageItemID = LLUUID::null;
mImageAssetID = asset_id;
+ mLocalTrackingID = tracking_id;
break;
case PICKER_UNKNOWN:
default:
mImageItemID = floaterp->findItemID(asset_id, FALSE);
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
break;
}
@@ -1660,7 +1976,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
if (op == TEXTURE_SELECT && mOnSelectCallback)
{
- mOnSelectCallback( this, LLSD() );
+ mOnSelectCallback(this, LLSD());
}
else if (op == TEXTURE_CANCEL && mOnCancelCallback)
{
@@ -1671,8 +1987,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co
// If the "no_commit_on_selection" parameter is set
// we commit only when user presses OK in the picker
// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
- if (mCommitOnSelection || op == TEXTURE_SELECT)
- onCommit();
+ if (mCommitOnSelection || op == TEXTURE_SELECT)
+ {
+ onCommit();
+ }
}
}
}
@@ -1708,6 +2026,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
{
mImageItemID.setNull();
mImageAssetID = asset_id;
+ mLocalTrackingID.setNull();
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if( floaterp && getEnabled() )
{
@@ -1717,8 +2036,9 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id )
}
}
-void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
+void LLTextureCtrl::setBakeTextureEnabled(bool enabled)
{
+ mBakeTextureEnabled = enabled;
LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
if (floaterp)
{
@@ -1726,6 +2046,16 @@ void LLTextureCtrl::setBakeTextureEnabled(BOOL enabled)
}
}
+void LLTextureCtrl::setInventoryPickType(EPickInventoryType type)
+{
+ mInventoryPickType = type;
+ LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get();
+ if (floaterp)
+ {
+ floaterp->setInventoryPickType(type);
+ }
+}
+
BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
BOOL drop, EDragAndDropType cargo_type, void *cargo_data,
EAcceptance *accept,
@@ -1737,11 +2067,26 @@ BOOL LLTextureCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask,
// returns true, then the cast was valid, and we can perform
// the third test without problems.
LLInventoryItem* item = (LLInventoryItem*)cargo_data;
- bool is_mesh = cargo_type == DAD_MESH;
- if (getEnabled() &&
- ((cargo_type == DAD_TEXTURE) || is_mesh) &&
- allowDrop(item))
+ bool is_mesh = cargo_type == DAD_MESH;
+ bool is_texture = cargo_type == DAD_TEXTURE;
+ bool is_material = cargo_type == DAD_MATERIAL;
+
+ bool allow_dnd = false;
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL)
+ {
+ allow_dnd = is_material;
+ }
+ else if (mInventoryPickType == LLTextureCtrl::PICK_TEXTURE)
+ {
+ allow_dnd = is_texture || is_mesh;
+ }
+ else
+ {
+ allow_dnd = is_texture || is_mesh || is_material;
+ }
+
+ if (getEnabled() && allow_dnd && allowDrop(item, cargo_type, tooltip_msg))
{
if (drop)
{
@@ -1805,7 +2150,7 @@ void LLTextureCtrl::draw()
}
else//mImageAssetID == LLUUID::null
{
- mTexturep = NULL;
+ mTexturep = NULL;
}
// Border
@@ -1893,7 +2238,7 @@ void LLTextureCtrl::draw()
LLUICtrl::draw();
}
-BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
+BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg)
{
BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
BOOL mod = item->getPermissions().allowModifyBy(gAgent.getID());
@@ -1905,8 +2250,6 @@ BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
if (mod) item_perm_mask |= PERM_MODIFY;
if (xfer) item_perm_mask |= PERM_TRANSFER;
-// PermissionMask filter_perm_mask = mCanApplyImmediately ? commented out due to no-copy texture loss.
-// mImmediateFilterPermMask : mNonImmediateFilterPermMask;
PermissionMask filter_perm_mask = mImmediateFilterPermMask;
if ( (item_perm_mask & filter_perm_mask) == filter_perm_mask )
{
@@ -1921,6 +2264,12 @@ BOOL LLTextureCtrl::allowDrop(LLInventoryItem* item)
}
else
{
+ PermissionMask mask = PERM_COPY | PERM_TRANSFER;
+ if ((filter_perm_mask & mask) == mask
+ && cargo_type == DAD_TEXTURE)
+ {
+ tooltip_msg.assign(LLTrans::getString("TooltipTextureRestrictedDrop"));
+ }
return FALSE;
}
}
@@ -1935,8 +2284,16 @@ BOOL LLTextureCtrl::doDrop(LLInventoryItem* item)
return mDropCallback(this, item);
}
- // no callback installed, so just set the image ids and carry on.
- setImageAssetID( item->getAssetUUID() );
+ // no callback installed, so just set the image ids and carry on.
+ LLUUID asset_id = item->getAssetUUID();
+
+ if (mInventoryPickType == LLTextureCtrl::PICK_MATERIAL && asset_id.isNull())
+ {
+ // If an inventory material has a null asset, consider it a valid blank material(gltf)
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
+ setImageAssetID(asset_id);
mImageItemID = item->getUUID();
return TRUE;
}
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index e2bfe286d3..c47df5accb 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -47,6 +47,7 @@ class LLComboBox;
class LLFloaterTexturePicker;
class LLInventoryItem;
class LLViewerFetchedTexture;
+class LLFetchedGLTFMaterial;
// used for setting drag & drop callbacks.
typedef boost::function<BOOL (LLUICtrl*, LLInventoryItem*)> drag_n_drop_callback;
@@ -86,6 +87,13 @@ public:
TEXTURE_CANCEL
} ETexturePickOp;
+ typedef enum e_pick_inventory_type
+ {
+ PICK_TEXTURE_MATERIAL = 0,
+ PICK_TEXTURE = 1,
+ PICK_MATERIAL = 2,
+ } EPickInventoryType;
+
public:
struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
{
@@ -109,7 +117,7 @@ public:
: image_id("image"),
default_image_id("default_image_id"),
default_image_name("default_image_name"),
- allow_no_texture("allow_no_texture"),
+ allow_no_texture("allow_no_texture", false),
can_apply_immediately("can_apply_immediately"),
no_commit_on_selection("no_commit_on_selection", false),
label_width("label_width", -1),
@@ -184,19 +192,19 @@ public:
void setCanApply(bool can_preview, bool can_apply);
- void setImmediateFilterPermMask(PermissionMask mask)
- { mImmediateFilterPermMask = mask; }
+ void setImmediateFilterPermMask(PermissionMask mask);
void setDnDFilterPermMask(PermissionMask mask)
{ mDnDFilterPermMask = mask; }
- void setNonImmediateFilterPermMask(PermissionMask mask)
- { mNonImmediateFilterPermMask = mask; }
PermissionMask getImmediateFilterPermMask() { return mImmediateFilterPermMask; }
- PermissionMask getNonImmediateFilterPermMask() { return mNonImmediateFilterPermMask; }
void closeDependentFloater();
void onFloaterClose();
- void onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& local_id, const LLUUID& inv_id);
+ void onFloaterCommit(ETexturePickOp op,
+ LLPickerSource source,
+ const LLUUID& local_id,
+ const LLUUID& inv_id,
+ const LLUUID& tracking_id);
// This call is returned when a drag is detected. Your callback
// should return TRUE if the drag is acceptable.
@@ -220,10 +228,17 @@ public:
LLViewerFetchedTexture* getTexture() { return mTexturep; }
- void setBakeTextureEnabled(BOOL enabled);
+ void setBakeTextureEnabled(bool enabled);
+ bool getBakeTextureEnabled() const { return mBakeTextureEnabled; }
+
+ void setInventoryPickType(EPickInventoryType type);
+ EPickInventoryType getInventoryPickType() { return mInventoryPickType; };
+
+ bool isImageLocal() { return mLocalTrackingID.notNull(); }
+ LLUUID getLocalTrackingID() { return mLocalTrackingID; }
private:
- BOOL allowDrop(LLInventoryItem* item);
+ BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg);
BOOL doDrop(LLInventoryItem* item);
private:
@@ -239,6 +254,7 @@ private:
LLUUID mImageAssetID;
LLUUID mDefaultImageAssetID;
LLUUID mBlankImageAssetID;
+ LLUUID mLocalTrackingID;
LLUIImagePtr mFallbackImage;
std::string mDefaultImageName;
LLHandle<LLFloater> mFloaterHandle;
@@ -249,7 +265,6 @@ private:
BOOL mAllowLocalTexture;
PermissionMask mImmediateFilterPermMask;
PermissionMask mDnDFilterPermMask;
- PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mCommitOnSelection;
BOOL mNeedsRawImageData;
@@ -259,12 +274,13 @@ private:
std::string mLoadingPlaceholderString;
S32 mLabelWidth;
bool mOpenTexPreview;
- BOOL mBakeTextureEnabled;
+ bool mBakeTextureEnabled;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
};
//////////////////////////////////////////////////////////////////////////////////////////
// LLFloaterTexturePicker
-typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inventory_id)> floater_commit_callback;
+typedef boost::function<void(LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inventory_id, const LLUUID& tracking_id)> floater_commit_callback;
typedef boost::function<void()> floater_close_callback;
typedef boost::function<void(const LLUUID& asset_id)> set_image_asset_id_callback;
typedef boost::function<void(LLPointer<LLViewerTexture> texture)> set_on_update_image_stats_callback;
@@ -282,7 +298,6 @@ public:
const std::string& label,
PermissionMask immediate_filter_perm_mask,
PermissionMask dnd_filter_perm_mask,
- PermissionMask non_immediate_filter_perm_mask,
BOOL can_apply_immediately,
LLUIImagePtr fallback_image_name
);
@@ -299,6 +314,7 @@ public:
// LLFloater overrides
/*virtual*/ BOOL postBuild();
+ /*virtual*/ void onOpen(const LLSD& key);
/*virtual*/ void onClose(bool app_settings);
// New functions
@@ -313,9 +329,7 @@ public:
LLView* getOwner() const { return mOwner; }
void setOwner(LLView* owner) { mOwner = owner; }
void stopUsingPipette();
- PermissionMask getFilterPermMask();
- void updateFilterPermMask();
void commitIfImmediateSet();
void commitCallback(LLTextureCtrl::ETexturePickOp op);
void commitCancel();
@@ -339,9 +353,7 @@ public:
//static void onBtnRevert( void* userdata );
static void onBtnBlank(void* userdata);
static void onBtnNone(void* userdata);
- static void onBtnClear(void* userdata);
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
- static void onShowFolders(LLUICtrl* ctrl, void* userdata);
static void onApplyImmediateCheck(LLUICtrl* ctrl, void* userdata);
void onTextureSelect(const LLTextureEntry& te);
@@ -352,13 +364,23 @@ public:
static void onLocalScrollCommit(LLUICtrl* ctrl, void* userdata);
static void onBakeTextureSelect(LLUICtrl* ctrl, void *userdata);
- static void onHideBaseMeshRegionCheck(LLUICtrl* ctrl, void *userdata);
void setLocalTextureEnabled(BOOL enabled);
void setBakeTextureEnabled(BOOL enabled);
+ void setInventoryPickType(LLTextureCtrl::EPickInventoryType type);
+ void setImmediateFilterPermMask(PermissionMask mask);
+
+ static void onPickerCallback(const std::vector<std::string>& filenames, LLHandle<LLFloater> handle);
+
protected:
+ void changeMode();
+ void refreshLocalList();
+ void refreshInventoryFilter();
+ void setImageIDFromItem(const LLInventoryItem* itemp, bool set_selection = true);
+
LLPointer<LLViewerTexture> mTexturep;
+ LLPointer<LLFetchedGLTFMaterial> mGLTFMaterial;
LLView* mOwner;
LLUUID mImageAssetID; // Currently selected texture
@@ -383,7 +405,6 @@ protected:
LLInventoryPanel* mInventoryPanel;
PermissionMask mImmediateFilterPermMask;
PermissionMask mDnDFilterPermMask;
- PermissionMask mNonImmediateFilterPermMask;
BOOL mCanApplyImmediately;
BOOL mNoCopyTextureSelected;
F32 mContextConeOpacity;
@@ -406,6 +427,7 @@ private:
bool mLimitsSet;
S32 mMaxDim;
S32 mMinDim;
+ LLTextureCtrl::EPickInventoryType mInventoryPickType;
texture_selected_callback mTextureSelectedCallback;
@@ -415,6 +437,8 @@ private:
set_on_update_image_stats_callback mOnUpdateImageStatsCallback;
BOOL mBakeTextureEnabled;
+
+ static S32 sLastPickerMode;
};
#endif // LL_LLTEXTURECTRL_H
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index a1beec7c1f..38c9b3717d 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -62,8 +62,6 @@
#include "llcorehttputil.h"
#include "llhttpretrypolicy.h"
-bool LLTextureFetchDebugger::sDebuggerEnabled = false ;
-
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheHit("texture_cache_hit");
LLTrace::CountStatHandle<F64> LLTextureFetch::sCacheAttempt("texture_cache_attempt");
LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > LLTextureFetch::sCacheHitRate("texture_cache_hits");
@@ -213,35 +211,17 @@ const std::string sTesterName("TextureFetchTester");
//
// Worker State Machine
//
-// (ASCII art needed)
-//
-//
-// Priority Scheme
-//
-// [PRIORITY_LOW, PRIORITY_NORMAL) - for WAIT_HTTP_RESOURCE state
-// and other wait states
-// [PRIORITY_HIGH, PRIORITY_URGENT) - External event delivered,
-// rapidly transitioning through states,
-// no waiting allowed
-//
-// By itself, the above work queue model would fail the concurrency
-// and liveness requirements of the interface. A high priority
-// request could find itself on the head and stalled for external
-// reasons (see VWR-28996). So a few additional constraints are
-// required to keep things running:
-// * Anything that can make forward progress must be kept at a
-// higher priority than anything that can't.
-// * On completion of external events, the associated request
-// needs to be elevated beyond the normal range to handle
-// any data delivery and release any external resource.
-//
-// This effort is made to keep higher-priority entities moving
-// forward in their state machines at every possible step of
-// processing. It's not entirely proven that this produces the
-// experiencial benefits promised.
+// "doWork" will be executed for a given worker on its respective
+// LLQueuedThread. If doWork returns true, the worker is treated
+// as completed. If doWork returns false, the worker will be
+// put on the back of the work queue at the start of the next iteration
+// of the mainloop. If a worker is waiting on a resource, it should
+// return false as soon as possible and not block to avoid starving
+// other workers of cpu cycles.
//
+
//////////////////////////////////////////////////////////////////////////////
// Tuning/Parameterization Constants
@@ -259,11 +239,15 @@ static const S32 HTTP_NONPIPE_REQUESTS_LOW_WATER = 20;
// request (e.g. 'Range: <start>-') which seems to fix the problem.
static const S32 HTTP_REQUESTS_RANGE_END_MAX = 20000000;
+// stop after 720 seconds, might be overkill, but cap request can keep going forever.
+static const S32 MAX_CAP_MISSING_RETRIES = 720;
+static const S32 CAP_MISSING_EXPIRATION_DELAY = 1; // seconds
+
//////////////////////////////////////////////////////////////////////////////
namespace
{
- // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker and
- // the LLTextureFetchDebugger) in a smart pointer below for passage into
+ // The NoOpDeletor is used when passing certain objects (the LLTextureFetchWorker)
+ // in a smart pointer below for passage into
// the LLCore::Http libararies. When the smart pointer is destroyed, no
// action will be taken since we do not in these cases want the object to
// be destroyed at the end of the call.
@@ -300,7 +284,6 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
{
friend class LLTextureFetch;
- friend class LLTextureFetchDebugger;
private:
class CacheReadResponder : public LLTextureCache::ReadResponder
@@ -385,14 +368,7 @@ private:
bool operator()(const LLTextureFetchWorker* lhs, const LLTextureFetchWorker* rhs) const
{
// greater priority is "less"
- const F32 lpriority = lhs->mImagePriority;
- const F32 rpriority = rhs->mImagePriority;
- if (lpriority > rpriority) // higher priority
- return true;
- else if (lpriority < rpriority)
- return false;
- else
- return lhs < rhs;
+ return lhs->mImagePriority > rhs->mImagePriority;
}
};
@@ -482,6 +458,9 @@ private:
// Locks: Mw
void resetFormattedData();
+ // get the relative priority of this worker (should map to max virtual size)
+ F32 getImagePriority() const;
+
// Locks: Mw
void setImagePriority(F32 priority);
@@ -496,9 +475,6 @@ private:
void clearPackets();
- // Locks: Mw (ctor invokes without lock)
- U32 calcWorkPriority();
-
// Locks: Mw
void removeFromCache();
@@ -554,6 +530,7 @@ private:
e_state mState;
void setState(e_state new_state);
+ LLViewerRegion* getRegion();
e_write_to_cache_state mWriteToCacheState;
LLTextureFetch* mFetcher;
@@ -565,16 +542,13 @@ private:
LLHost mHost;
std::string mUrl;
U8 mType;
- F32 mImagePriority;
- U32 mWorkPriority;
+ F32 mImagePriority; // should map to max virtual size
F32 mRequestedPriority;
S32 mDesiredDiscard;
S32 mSimRequestedDiscard;
S32 mRequestedDiscard;
S32 mLoadedDiscard;
S32 mDecodedDiscard;
- S32 mFullWidth;
- S32 mFullHeight;
LLFrameTimer mRequestedDeltaTimer;
LLFrameTimer mFetchDeltaTimer;
LLTimer mCacheReadTimer;
@@ -610,6 +584,10 @@ private:
LLCore::HttpStatus mGetStatus;
std::string mGetReason;
LLAdaptiveRetryPolicy mFetchRetryPolicy;
+ bool mCanUseCapability;
+ LLTimer mRegionRetryTimer;
+ S32 mRegionRetryAttempt;
+ LLUUID mLastRegionId;
// Work Data
@@ -913,7 +891,6 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mHost(host),
mUrl(url),
mImagePriority(priority),
- mWorkPriority(0),
mRequestedPriority(0.f),
mDesiredDiscard(-1),
mSimRequestedDiscard(-1),
@@ -960,15 +937,15 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
mCacheReadCount(0U),
mCacheWriteCount(0U),
mResourceWaitCount(0U),
- mFetchRetryPolicy(10.0,3600.0,2.0,10)
+ mFetchRetryPolicy(10.f,3600.f,2.f,10),
+ mCanUseCapability(true),
+ mRegionRetryAttempt(0)
{
- calcWorkPriority();
mType = host.isOk() ? LLImageBase::TYPE_AVATAR_BAKE : LLImageBase::TYPE_NORMAL;
// LL_INFOS(LOG_TXT) << "Create: " << mID << " mHost:" << host << " Discard=" << discard << LL_ENDL;
if (!mFetcher->mDebugPause)
{
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- addWork(0, work_priority );
+ addWork(0);
}
setDesiredDiscard(discard, size);
}
@@ -1026,16 +1003,6 @@ void LLTextureFetchWorker::clearPackets()
}
// Locks: Mw (ctor invokes without lock)
-U32 LLTextureFetchWorker::calcWorkPriority()
-{
- //llassert_always(mImagePriority >= 0 && mImagePriority <= LLViewerFetchedTexture::maxDecodePriority());
- static const F32 PRIORITY_SCALE = (F32)LLWorkerThread::PRIORITY_LOWBITS / LLViewerFetchedTexture::maxDecodePriority();
-
- mWorkPriority = llmin((U32)LLWorkerThread::PRIORITY_LOWBITS, (U32)(mImagePriority * PRIORITY_SCALE));
- return mWorkPriority;
-}
-
-// Locks: Mw (ctor invokes without lock)
void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
bool prioritize = false;
@@ -1043,11 +1010,9 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
{
if (!haveWork())
{
- calcWorkPriority();
if (!mFetcher->mDebugPause)
{
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- addWork(0, work_priority);
+ addWork(0);
}
}
else if (mDesiredDiscard < discard)
@@ -1066,23 +1031,13 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
if ((prioritize && mState == INIT) || mState == DONE)
{
setState(INIT);
- U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
- setPriority(work_priority);
}
}
// Locks: Mw
void LLTextureFetchWorker::setImagePriority(F32 priority)
{
-// llassert_always(priority >= 0 && priority <= LLViewerTexture::maxDecodePriority());
- F32 delta = fabs(priority - mImagePriority);
- if (delta > (mImagePriority * .05f) || mState == DONE)
- {
- mImagePriority = priority;
- calcWorkPriority();
- U32 work_priority = mWorkPriority | (getPriority() & LLWorkerThread::PRIORITY_HIGHBITS);
- setPriority(work_priority);
- }
+ mImagePriority = priority; //should map to max virtual size, abort if zero
}
// Locks: Mw
@@ -1102,6 +1057,11 @@ void LLTextureFetchWorker::resetFormattedData()
mHaveAllData = FALSE;
}
+F32 LLTextureFetchWorker::getImagePriority() const
+{
+ return mImagePriority;
+}
+
// Threads: Tmain
void LLTextureFetchWorker::startWork(S32 param)
{
@@ -1111,7 +1071,7 @@ void LLTextureFetchWorker::startWork(S32 param)
// Threads: Ttf
bool LLTextureFetchWorker::doWork(S32 param)
{
- LL_PROFILE_ZONE_SCOPED;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_THREAD;
if (gNonInteractive)
{
return true;
@@ -1126,20 +1086,35 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mState < DECODE_IMAGE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state < decode");
return true; // abort
}
}
- if(mImagePriority < F_ALMOST_ZERO)
+ if (mImagePriority < F_ALMOST_ZERO)
{
if (mState == INIT || mState == LOAD_FROM_NETWORK)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - priority < 0");
LL_DEBUGS(LOG_TXT) << mID << " abort: mImagePriority < F_ALMOST_ZERO" << LL_ENDL;
return true; // abort
}
}
+ if (mState > CACHE_POST && !mCanUseCapability && mCanUseHTTP)
+ {
+ if (mRegionRetryAttempt > MAX_CAP_MISSING_RETRIES)
+ {
+ mCanUseHTTP = false;
+ }
+ else if (!mRegionRetryTimer.hasExpired())
+ {
+ return false;
+ }
+ // else retry
+ }
if(mState > CACHE_POST && !mCanUseHTTP)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - state > cache_post");
//nowhere to get data, abort.
LL_WARNS(LOG_TXT) << mID << " abort, nowhere to get data" << LL_ENDL;
return true ;
@@ -1161,6 +1136,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == INIT)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - INIT");
mStateTimer.reset();
mFetchTimer.reset();
for(auto i : LOGGED_STATES)
@@ -1202,15 +1178,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_TEXTURE_CACHE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_TEXTURE_CACHE");
if (mCacheReadHandle == LLTextureCache::nullHandle())
{
- U32 cache_priority = mWorkPriority;
S32 offset = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
S32 size = mDesiredSize - offset;
if (size <= 0)
{
setState(CACHE_POST);
- return false;
+ return doWork(param);
+ // return false;
}
mFileSize = 0;
mLoaded = FALSE;
@@ -1219,35 +1196,28 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mUrl.compare(0, 7, "file://") == 0)
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
// read file from local disk
++mCacheReadCount;
std::string filename = mUrl.substr(7, std::string::npos);
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadTimer.reset();
- mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, cache_priority,
- offset, size, responder);
+ mCacheReadHandle = mFetcher->mTextureCache->readFromCache(filename, mID, offset, size, responder);
}
else if ((mUrl.empty() || mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache())
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
-
++mCacheReadCount;
CacheReadResponder* responder = new CacheReadResponder(mFetcher, mID, mFormattedImage);
mCacheReadTimer.reset();
- mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID, cache_priority,
+ mCacheReadHandle = mFetcher->mTextureCache->readFromCache(mID,
offset, size, responder);;
}
else if(!mUrl.empty() && mCanUseHTTP)
{
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(WAIT_HTTP_RESOURCE);
}
else
{
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(LOAD_FROM_NETWORK);
}
}
@@ -1280,6 +1250,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == CACHE_POST)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - CACHE_POST");
mCachedSize = mFormattedImage.notNull() ? mFormattedImage->getDataSize() : 0;
// Successfully loaded
if ((mCachedSize >= mDesiredSize) || mHaveAllData)
@@ -1321,6 +1292,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == LOAD_FROM_NETWORK)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - LOAD_FROM_NETWORK");
// Check for retries to previous server failures.
F32 wait_seconds;
if (mFetchRetryPolicy.shouldRetry(wait_seconds))
@@ -1341,16 +1313,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// if (mHost.isInvalid()) get_url = false;
if ( use_http && mCanUseHTTP && mUrl.empty())//get http url.
{
- LLViewerRegion* region = NULL;
- if (mHost.isInvalid())
- {
- region = gAgent.getRegion();
- }
- else if (LLWorld::instanceExists())
- {
- region = LLWorld::getInstance()->getRegion(mHost);
- }
-
+ LLViewerRegion* region = getRegion();
if (region)
{
std::string http_url = region->getViewerAssetUrl();
@@ -1358,24 +1321,32 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
if (mFTType != FTT_DEFAULT)
{
- LL_WARNS(LOG_TXT) << "trying to seek a non-default texture on the sim. Bad!" << LL_ENDL;
+ LL_WARNS(LOG_TXT) << "Trying to fetch a texture of non-default type by UUID. This probably won't work!" << LL_ENDL;
}
setUrl(http_url + "/?texture_id=" + mID.asString().c_str());
LL_DEBUGS(LOG_TXT) << "Texture URL: " << mUrl << LL_ENDL;
mWriteToCacheState = CAN_WRITE ; //because this texture has a fixed texture id.
+ mCanUseCapability = true;
+ mRegionRetryAttempt = 0;
+ mLastRegionId = region->getRegionID();
}
else
{
- mCanUseHTTP = false ;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
+ // ex: waiting for caps
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: empty URL." << LL_ENDL;
}
}
else
{
+ mCanUseCapability = false;
+ mRegionRetryAttempt++;
+ mRegionRetryTimer.setTimerExpirySec(CAP_MISSING_EXPIRATION_DELAY);
// This will happen if not logged in or if a region deoes not have HTTP Texture enabled
//LL_WARNS(LOG_TXT) << "Region not found for host: " << mHost << LL_ENDL;
- LL_WARNS(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
- mCanUseHTTP = false;
+ LL_INFOS_ONCE(LOG_TXT) << "Texture not available via HTTP: no region " << mUrl << LL_ENDL;
}
}
else if (mFTType == FTT_SERVER_BAKE)
@@ -1383,10 +1354,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
mWriteToCacheState = CAN_WRITE;
}
- if (mCanUseHTTP && !mUrl.empty())
+ if (mCanUseCapability && mCanUseHTTP && !mUrl.empty())
{
setState(WAIT_HTTP_RESOURCE);
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if(mWriteToCacheState != NOT_WRITE)
{
mWriteToCacheState = CAN_WRITE ;
@@ -1401,6 +1371,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_RESOURCE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE");
// NOTE:
// control the number of the http requests issued for:
// 1, not openning too many file descriptors at the same time;
@@ -1408,10 +1379,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
//
// If it looks like we're busy, keep this request here.
// Otherwise, advance into the HTTP states.
- if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
+
+ if (!mHttpHasResource && // sometimes we get into this state when we already have an http resource, go ahead and send the request in that case
+ (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore()))
{
setState(WAIT_HTTP_RESOURCE2);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
mFetcher->addHttpWaiter(this->mID);
++mResourceWaitCount;
return false;
@@ -1425,12 +1397,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_RESOURCE2)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_RESOURCE2");
// Just idle it if we make it to the head...
return false;
}
if (mState == SEND_HTTP_REQ)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - SEND_HTTP_REQ");
// Also used in llmeshrepository
static LLCachedControl<bool> disable_range_req(gSavedSettings, "HttpRangeRequestsDisable", false);
@@ -1451,7 +1425,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// We already have all the data, just decode it
mLoadedDiscard = mFormattedImage->getDiscardLevel();
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1459,7 +1432,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setState(DECODE_IMAGE);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1520,7 +1494,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
// by people with questionable ISPs or networking gear that
// doesn't handle these well.
mHttpHandle = mFetcher->mHttpRequest->requestGet(mHttpPolicyClass,
- mWorkPriority,
mUrl,
options,
mFetcher->mHttpHeaders,
@@ -1529,7 +1502,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
else
{
mHttpHandle = mFetcher->mHttpRequest->requestGetByteRange(mHttpPolicyClass,
- mWorkPriority,
mUrl,
mRequestedOffset,
(mRequestedOffset + mRequestedSize) > HTTP_REQUESTS_RANGE_END_MAX
@@ -1554,7 +1526,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
mHttpActive = true;
mFetcher->addToHTTPQueue(mID);
recordTextureStart(true);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
setState(WAIT_HTTP_REQ);
// fall through
@@ -1562,6 +1533,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_HTTP_REQ)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_HTTP_REQ");
// *NOTE: As stated above, all transitions out of this state should
// call releaseHttpSemaphore().
if (mLoaded)
@@ -1586,10 +1558,37 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
return true;
}
+
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // cap failure? try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_service_unavail == mGetStatus)
{
LL_INFOS_ONCE(LOG_TXT) << "Texture server busy (503): " << mUrl << LL_ENDL;
+ if (mCanUseHTTP && !mUrl.empty() && cur_size <= 0)
+ {
+ LLViewerRegion* region = getRegion();
+ if (!region || mLastRegionId != region->getRegionID())
+ {
+ // try on new region.
+ mUrl.clear();
+ ++mRetryAttempt;
+ mLastRegionId.setNull();
+ setState(INIT);
+ return false;
+ }
+ }
}
else if (http_not_sat == mGetStatus)
{
@@ -1604,7 +1603,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
<< LL_ENDL;
}
- if (mFTType != FTT_SERVER_BAKE)
+ if (mFTType != FTT_SERVER_BAKE && mFTType != FTT_MAP_TILE)
{
mUrl.clear();
}
@@ -1612,7 +1611,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
// Use available data
mLoadedDiscard = mFormattedImage->getDiscardLevel();
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
if (mLoadedDiscard < 0)
{
LL_WARNS(LOG_TXT) << mID << " mLoadedDiscard is " << mLoadedDiscard
@@ -1620,7 +1618,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
setState(DECODE_IMAGE);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
// Fail harder
@@ -1737,9 +1736,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
{
mWriteToCacheState = SHOULD_WRITE ;
}
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
releaseHttpSemaphore();
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1749,17 +1748,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
// an enormous amount of time to load textures. We'll revisit the
// various possible timeout components (total request time, connection
// time, I/O time, with and without retries, etc.) in the future.
-
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+
return false;
}
}
if (mState == DECODE_IMAGE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE");
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings, "TextureDecodeDisabled", false);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
if (textures_decode_disabled)
{
// for debug use, don't decode
@@ -1798,25 +1796,20 @@ bool LLTextureFetchWorker::doWork(S32 param)
mAuxImage = NULL;
llassert_always(mFormattedImage.notNull());
S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
- U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
mDecoded = FALSE;
setState(DECODE_IMAGE_UPDATE);
LL_DEBUGS(LOG_TXT) << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
<< " All Data: " << mHaveAllData << LL_ENDL;
- mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
+ mDecodeHandle = LLAppViewer::getImageDecodeThread()->decodeImage(mFormattedImage, discard, mNeedsAux,
new DecodeResponder(mFetcher, mID, this));
// fall though
}
if (mState == DECODE_IMAGE_UPDATE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DECODE_IMAGE_UPDATE");
if (mDecoded)
{
- if(mFetcher->getFetchDebugger() && !mInLocalCache)
- {
- mFetcher->getFetchDebugger()->addHistoryEntry(this);
- }
-
mDecodeTime = mDecodeTimer.getElapsedTimeF32();
if (mDecodedDiscard < 0)
@@ -1828,9 +1821,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
llassert_always(mDecodeHandle == 0);
mFormattedImage = NULL;
++mRetryAttempt;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(INIT);
- return false;
+ //return false;
+ return doWork(param);
}
else
{
@@ -1843,7 +1836,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
llassert_always(mRawImage.notNull());
LL_DEBUGS(LOG_TXT) << mID << ": Decoded. Discard: " << mDecodedDiscard
<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
setState(WRITE_TO_CACHE);
}
// fall through
@@ -1856,12 +1848,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WRITE_TO_CACHE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WRITE_TO_CACHE");
if (mWriteToCacheState != SHOULD_WRITE || mFormattedImage.isNull())
{
// If we're in a local cache or we didn't actually receive any new data,
// or we failed to load anything, skip
setState(DONE);
- return false;
+ //return false;
+ return doWork(param);
}
S32 datasize = mFormattedImage->getDataSize();
if(mFileSize < datasize)//This could happen when http fetching and sim fetching mixed.
@@ -1876,8 +1870,6 @@ bool LLTextureFetchWorker::doWork(S32 param)
}
}
llassert_always(datasize);
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
- U32 cache_priority = mWorkPriority;
mWritten = FALSE;
setState(WAIT_ON_WRITE);
++mCacheWriteCount;
@@ -1888,7 +1880,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// So make sure users of getRequestFinished() does not attempt to modify image while
// fetcher is working
mCacheWriteTimer.reset();
- mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
+ mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID,
mFormattedImage->getData(), datasize,
mFileSize, mRawImage, mDecodedDiscard, responder);
// fall through
@@ -1896,6 +1888,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == WAIT_ON_WRITE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - WAIT_ON_WRITE");
if (writeToCacheComplete())
{
mCacheWriteTime = mCacheWriteTimer.getElapsedTimeF32();
@@ -1917,6 +1910,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
if (mState == DONE)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_THREAD("tfwdw - DONE");
if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
{
// More data was requested, return to INIT
@@ -1924,12 +1918,11 @@ bool LLTextureFetchWorker::doWork(S32 param)
LL_DEBUGS(LOG_TXT) << mID << " more data requested, returning to INIT: "
<< " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
<< "<" << " mDecodedDiscard " << mDecodedDiscard << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
- return false;
+ // return false;
+ return doWork(param);
}
else
{
- setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
mFetchTime = mFetchTimer.getElapsedTimeF32();
return true;
}
@@ -1942,6 +1935,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
// virtual
void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<bool> log_to_viewer_log(gSavedSettings, "LogTextureDownloadsToViewerLog", false);
static LLCachedControl<bool> log_to_sim(gSavedSettings, "LogTextureDownloadsToSimulator", false);
static LLCachedControl<bool> log_texture_traffic(gSavedSettings, "LogTextureNetworkTraffic", false) ;
@@ -2051,9 +2045,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
// Threads: Tmain
void LLTextureFetchWorker::endWork(S32 param, bool aborted)
{
+ LL_PROFILE_ZONE_SCOPED;
if (mDecodeHandle != 0)
{
- mFetcher->mImageDecodeThread->abortRequest(mDecodeHandle, false);
+ // LL::ThreadPool has no operation to cancel a particular work item
mDecodeHandle = 0;
}
mFormattedImage = NULL;
@@ -2066,6 +2061,7 @@ void LLTextureFetchWorker::endWork(S32 param, bool aborted)
// virtual
void LLTextureFetchWorker::finishWork(S32 param, bool completed)
{
+ LL_PROFILE_ZONE_SCOPED;
// The following are required in case the work was aborted
if (mCacheReadHandle != LLTextureCache::nullHandle())
{
@@ -2262,7 +2258,6 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
}
mLoaded = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
return data_size ;
}
@@ -2273,6 +2268,7 @@ S32 LLTextureFetchWorker::callbackHttpGet(LLCore::HttpResponse * response,
void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* image,
S32 imagesize, BOOL islocal)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
LLMutexLock lock(&mWorkMutex); // +Mw
if (mState != LOAD_FROM_TEXTURE_CACHE)
{
@@ -2292,7 +2288,6 @@ void LLTextureFetchWorker::callbackCacheRead(bool success, LLImageFormatted* ima
}
}
mLoaded = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
// Threads: Ttc
@@ -2305,7 +2300,6 @@ void LLTextureFetchWorker::callbackCacheWrite(bool success)
return;
}
mWritten = TRUE;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
//////////////////////////////////////////////////////////////////////////////
@@ -2344,7 +2338,6 @@ void LLTextureFetchWorker::callbackDecoded(bool success, LLImageRaw* raw, LLImag
}
mDecoded = TRUE;
// LL_INFOS(LOG_TXT) << mID << " : DECODE COMPLETE " << LL_ENDL;
- setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
} // -Mw
//////////////////////////////////////////////////////////////////////////////
@@ -2407,7 +2400,17 @@ void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)
//////////////////////////////////////////////////////////////////////////////
// public
-LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
+std::string LLTextureFetch::getStateString(S32 state)
+{
+ if (state < 0 || state > sizeof(e_state_name) / sizeof(char*))
+ {
+ return llformat("%d", state);
+ }
+
+ return e_state_name[state];
+}
+
+LLTextureFetch::LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode)
: LLWorkerThread("TextureFetch", threaded, true),
mDebugCount(0),
mDebugPause(FALSE),
@@ -2416,7 +2419,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mQueueMutex(),
mNetworkQueueMutex(),
mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
mTextureBandwidth(0),
mHTTPTextureBits(0),
mTotalHTTPRequests(0),
@@ -2431,10 +2433,8 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mTotalCacheReadCount(0U),
mTotalCacheWriteCount(0U),
mTotalResourceWaitCount(0U),
- mFetchDebugger(NULL),
mFetchSource(LLTextureFetch::FROM_ALL),
mOriginFetchSource(LLTextureFetch::FROM_ALL),
- mFetcherLocked(FALSE),
mTextureInfoMainThread(false)
{
mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
@@ -2455,21 +2455,6 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
mHttpLowWater = HTTP_NONPIPE_REQUESTS_LOW_WATER;
mHttpSemaphore = 0;
- // Conditionally construct debugger object after 'this' is
- // fully initialized.
- LLTextureFetchDebugger::sDebuggerEnabled = gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
- if(LLTextureFetchDebugger::isEnabled())
- {
- mFetchDebugger = new LLTextureFetchDebugger(this, cache, imagedecodethread) ;
- mFetchSource = (e_tex_source)gSavedSettings.getS32("TextureFetchSource");
- if(mFetchSource < 0 && mFetchSource >= INVALID_SOURCE)
- {
- mFetchSource = LLTextureFetch::FROM_ALL;
- gSavedSettings.setS32("TextureFetchSource", 0);
- }
- mOriginFetchSource = mFetchSource;
- }
-
// If that test log has ben requested but not yet created, create it
if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
{
@@ -2498,22 +2483,16 @@ LLTextureFetch::~LLTextureFetch()
delete mHttpRequest;
mHttpRequest = NULL;
- delete mFetchDebugger;
- mFetchDebugger = NULL;
-
// ~LLQueuedThread() called here
}
-bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+S32 LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
{
- if(mFetcherLocked)
- {
- return false;
- }
+ LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
- return false;
+ return -1;
}
if (f_type == FTT_SERVER_BAKE)
@@ -2529,7 +2508,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
<< host << " != " << worker->mHost << LL_ENDL;
removeRequest(worker, true);
worker = NULL;
- return false;
+ return -1;
}
}
@@ -2582,9 +2561,14 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
{
if (worker->wasAborted())
{
- return false; // need to wait for previous aborted request to complete
+ return -1; // need to wait for previous aborted request to complete
}
worker->lockWorkMutex(); // +Mw
+ if (worker->mState == LLTextureFetchWorker::DONE && worker->mDesiredSize == llmax(desired_size, TEXTURE_CACHE_ENTRY_SIZE) && worker->mDesiredDiscard == desired_discard) {
+ worker->unlockWorkMutex(); // -Mw
+
+ return -1; // similar request has failed or is in a transitional state
+ }
worker->mActiveCount++;
worker->mNeedsAux = needs_aux;
worker->setImagePriority(priority);
@@ -2598,7 +2582,7 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setState(LLTextureFetchWorker::INIT);
worker->unlockWorkMutex(); // -Mw
- worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+ worker->addWork(0);
}
else
{
@@ -2618,18 +2602,17 @@ bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const
worker->setCanUseHTTP(can_use_http) ;
worker->unlockWorkMutex(); // -Mw
}
-
+
LL_DEBUGS(LOG_TXT) << "REQUESTED: " << id << " f_type " << fttype_to_string(f_type)
<< " Discard: " << desired_discard << " size " << desired_size << LL_ENDL;
- return true;
+ return desired_discard;
}
-
-
// Threads: T*
//
// protected
void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.insert(id);
mTotalHTTPRequests++;
@@ -2638,6 +2621,7 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
// Threads: T*
void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_size)
{
+ LL_PROFILE_ZONE_SCOPED;
LLMutexLock lock(&mNetworkQueueMutex); // +Mfnq
mHTTPTextureQueue.erase(id);
mHTTPTextureBits += received_size; // Approximate - does not include header bits
@@ -2650,6 +2634,7 @@ void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32Bytes received_siz
// Threads: T*
void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
{
+ LL_PROFILE_ZONE_SCOPED;
lockQueue(); // +Mfq
LLTextureFetchWorker* worker = getWorkerAfterLock(id);
if (worker)
@@ -2675,6 +2660,7 @@ void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
// Threads: T*
void LLTextureFetch::removeRequest(LLTextureFetchWorker* worker, bool cancel)
{
+ LL_PROFILE_ZONE_SCOPED;
if(!worker)
{
return;
@@ -2743,6 +2729,7 @@ U32 LLTextureFetch::getTotalNumHTTPRequests()
// Locks: Mfq
LLTextureFetchWorker* LLTextureFetch::getWorkerAfterLock(const LLUUID& id)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTextureFetchWorker* res = NULL;
map_t::iterator iter = mRequestMap.find(id);
if (iter != mRequestMap.end())
@@ -2766,6 +2753,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
LLPointer<LLImageRaw>& raw, LLPointer<LLImageRaw>& aux,
LLCore::HttpStatus& last_http_get_status)
{
+ LL_PROFILE_ZONE_SCOPED;
bool res = false;
LLTextureFetchWorker* worker = getWorker(id);
if (worker)
@@ -2780,7 +2768,7 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
if (!mDebugPause)
{
// LL_WARNS(LOG_TXT) << "Adding work for inactive worker: " << id << LL_ENDL;
- worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
+ worker->addWork(0);
}
}
else if (worker->checkWork())
@@ -2856,16 +2844,19 @@ bool LLTextureFetch::getRequestFinished(const LLUUID& id, S32& discard_level,
// Threads: T*
bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
{
- bool res = false;
- LLTextureFetchWorker* worker = getWorker(id);
- if (worker)
- {
- worker->lockWorkMutex(); // +Mw
- worker->setImagePriority(priority);
- worker->unlockWorkMutex(); // -Mw
- res = true;
- }
- return res;
+ LL_PROFILE_ZONE_SCOPED;
+ mRequestQueue.tryPost([=]()
+ {
+ LLTextureFetchWorker* worker = getWorker(id);
+ if (worker)
+ {
+ worker->lockWorkMutex(); // +Mw
+ worker->setImagePriority(priority);
+ worker->unlockWorkMutex(); // -Mw
+ }
+ });
+
+ return true;
}
// Replicates and expands upon the base class's
@@ -2882,16 +2873,17 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
//virtual
size_t LLTextureFetch::getPending()
{
- size_t res;
- lockData(); // +Ct
+ LL_PROFILE_ZONE_SCOPED;
+ size_t res;
+ lockData(); // +Ct
{
LLMutexLock lock(&mQueueMutex); // +Mfq
res = mRequestQueue.size();
res += mCommands.size();
} // -Mfq
- unlockData(); // -Ct
- return res;
+ unlockData(); // -Ct
+ return res;
}
// Locks: Ct
@@ -2915,7 +2907,7 @@ bool LLTextureFetch::runCondition()
} // -Mfq
return ! (have_no_commands
- && (mRequestQueue.empty() && mIdleThread)); // From base class
+ && (mRequestQueue.size() == 0 && mIdleThread)); // From base class
}
//////////////////////////////////////////////////////////////////////////////
@@ -2923,6 +2915,7 @@ bool LLTextureFetch::runCondition()
// Threads: Ttf
void LLTextureFetch::commonUpdate()
{
+ LL_PROFILE_ZONE_SCOPED;
// Update low/high water levels based on pipelining. We pick
// up setting eventually, so the semaphore/request level can
// fall outside the [0..HIGH_WATER] range. Expect that.
@@ -2959,6 +2952,7 @@ void LLTextureFetch::commonUpdate()
//virtual
size_t LLTextureFetch::update(F32 max_time_ms)
{
+ LL_PROFILE_ZONE_SCOPED;
static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS", 3000.0);
{
@@ -2978,11 +2972,6 @@ size_t LLTextureFetch::update(F32 max_time_ms)
commonUpdate();
}
- if (mFetchDebugger)
- {
- mFetchDebugger->tryToStopDebug(); //check if need to stop debugger.
- }
-
return res;
}
@@ -2998,18 +2987,6 @@ void LLTextureFetch::shutDownTextureCacheThread()
}
}
-// called in the MAIN thread after the ImageDecodeThread shuts down.
-//
-// Threads: Tmain
-void LLTextureFetch::shutDownImageDecodeThread()
-{
- if(mImageDecodeThread)
- {
- llassert_always(mImageDecodeThread->isQuitting() || mImageDecodeThread->isStopped()) ;
- mImageDecodeThread = NULL ;
- }
-}
-
// Threads: Ttf
void LLTextureFetch::startThread()
{
@@ -3031,6 +3008,7 @@ void LLTextureFetch::endThread()
// Threads: Ttf
void LLTextureFetch::threadedUpdate()
{
+ LL_PROFILE_ZONE_SCOPED;
llassert_always(mHttpRequest);
#if 0
@@ -3067,6 +3045,7 @@ void LLTextureFetch::threadedUpdate()
// Locks: Mw
bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
{
+ LL_PROFILE_ZONE_SCOPED;
mRequestedDeltaTimer.reset();
if (index >= mTotalPackets)
{
@@ -3099,6 +3078,7 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
void LLTextureFetchWorker::setState(e_state new_state)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mFTType == FTT_SERVER_BAKE)
{
// NOTE: turning on these log statements is a reliable way to get
@@ -3120,11 +3100,25 @@ void LLTextureFetchWorker::setState(e_state new_state)
mSkippedStatesTime += d_time;
}
}
-
+
mStateTimer.reset();
mState = new_state;
}
+LLViewerRegion* LLTextureFetchWorker::getRegion()
+{
+ LLViewerRegion* region = NULL;
+ if (mHost.isInvalid())
+ {
+ region = gAgent.getRegion();
+ }
+ else if (LLWorld::instanceExists())
+ {
+ region = LLWorld::getInstance()->getRegion(mHost);
+ }
+ return region;
+}
+
//////////////////////////////////////////////////////////////////////////////
// Threads: T*
@@ -3143,10 +3137,23 @@ BOOL LLTextureFetch::isFromLocalCache(const LLUUID& id)
return from_cache ;
}
+S32 LLTextureFetch::getFetchState(const LLUUID& id)
+{
+ S32 state = LLTextureFetchWorker::INVALID;
+ LLTextureFetchWorker* worker = getWorker(id);
+ if (worker && worker->haveWork())
+ {
+ state = worker->mState;
+ }
+
+ return state;
+}
+
// Threads: T*
S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http)
{
+ LL_PROFILE_ZONE_SCOPED;
S32 state = LLTextureFetchWorker::INVALID;
F32 data_progress = 0.0f;
F32 requested_priority = 0.0f;
@@ -3176,7 +3183,7 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
{
requested_priority = worker->mImagePriority;
}
- fetch_priority = worker->getPriority();
+ fetch_priority = worker->getImagePriority();
can_use_http = worker->getCanUseHTTP() ;
worker->unlockWorkMutex(); // -Mw
}
@@ -3190,19 +3197,6 @@ S32 LLTextureFetch::getFetchState(const LLUUID& id, F32& data_progress_p, F32& r
void LLTextureFetch::dump()
{
- LL_INFOS(LOG_TXT) << "LLTextureFetch REQUESTS:" << LL_ENDL;
- for (request_queue_t::iterator iter = mRequestQueue.begin();
- iter != mRequestQueue.end(); ++iter)
- {
- LLQueuedThread::QueuedRequest* qreq = *iter;
- LLWorkerThread::WorkRequest* wreq = (LLWorkerThread::WorkRequest*)qreq;
- LLTextureFetchWorker* worker = (LLTextureFetchWorker*)wreq->getWorkerClass();
- LL_INFOS(LOG_TXT) << " ID: " << worker->mID
- << " PRI: " << llformat("0x%08x",wreq->getPriority())
- << " STATE: " << sStateDescs[worker->mState]
- << LL_ENDL;
- }
-
LL_INFOS(LOG_TXT) << "LLTextureFetch ACTIVE_HTTP:" << LL_ENDL;
for (queue_t::const_iterator iter(mHTTPTextureQueue.begin());
mHTTPTextureQueue.end() != iter;
@@ -3269,6 +3263,7 @@ bool LLTextureFetch::isHttpWaiter(const LLUUID & tid)
// Locks: -Mw (must not hold any worker when called)
void LLTextureFetch::releaseHttpWaiters()
{
+ LL_PROFILE_ZONE_SCOPED;
// Use mHttpSemaphore rather than mHTTPTextureQueue.size()
// to avoid a lock.
if (mHttpSemaphore >= mHttpLowWater)
@@ -3365,7 +3360,6 @@ void LLTextureFetch::releaseHttpWaiters()
}
worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
- worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
worker->unlockWorkMutex(); // -Mw
removeHttpWaiter(worker->mID);
@@ -3455,6 +3449,7 @@ void LLTextureFetch::commandDataBreak()
// Threads: T*
void LLTextureFetch::cmdEnqueue(TFRequest * req)
{
+ LL_PROFILE_ZONE_SCOPED;
lockQueue(); // +Mfq
mCommands.push_back(req);
unlockQueue(); // -Mfq
@@ -3465,6 +3460,7 @@ void LLTextureFetch::cmdEnqueue(TFRequest * req)
// Threads: T*
LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
{
+ LL_PROFILE_ZONE_SCOPED;
TFRequest * ret = 0;
lockQueue(); // +Mfq
@@ -3481,6 +3477,7 @@ LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
// Threads: Ttf
void LLTextureFetch::cmdDoWork()
{
+ LL_PROFILE_ZONE_SCOPED;
if (mDebugPause)
{
return; // debug: don't do any work
@@ -3571,7 +3568,7 @@ TFReqSendMetrics::~TFReqSendMetrics()
bool
TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
{
- static const U32 report_priority(1);
+ LL_PROFILE_ZONE_SCOPED;
//if (! gViewerAssetStatsThread1)
// return true;
@@ -3614,7 +3611,6 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
// Don't care about handle, this is a fire-and-forget operation.
LLCoreHttpUtil::requestPostWithLLSD(&fetcher->getHttpRequest(),
fetcher->getMetricsPolicyClass(),
- report_priority,
mCapsURL,
mStatsSD,
LLCore::HttpOptions::ptr_t(),
@@ -3676,971 +3672,6 @@ truncate_viewer_metrics(int max_regions, LLSD & metrics)
} // end of anonymous namespace
-
-///////////////////////////////////////////////////////////////////////////////////////////
-//Start LLTextureFetchDebugger
-///////////////////////////////////////////////////////////////////////////////////////////
-//---------------------
-class LLDebuggerCacheReadResponder : public LLTextureCache::ReadResponder
-{
-public:
- LLDebuggerCacheReadResponder(LLTextureFetchDebugger* debugger, S32 id, LLImageFormatted* image)
- : mDebugger(debugger), mID(id)
- {
- setImage(image);
- }
- virtual void completed(bool success)
- {
- mDebugger->callbackCacheRead(mID, success, mFormattedImage, mImageSize, mImageLocal);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-class LLDebuggerCacheWriteResponder : public LLTextureCache::WriteResponder
-{
-public:
- LLDebuggerCacheWriteResponder(LLTextureFetchDebugger* debugger, S32 id)
- : mDebugger(debugger), mID(id)
- {
- }
- virtual void completed(bool success)
- {
- mDebugger->callbackCacheWrite(mID, success);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-class LLDebuggerDecodeResponder : public LLImageDecodeThread::Responder
-{
-public:
- LLDebuggerDecodeResponder(LLTextureFetchDebugger* debugger, S32 id)
- : mDebugger(debugger), mID(id)
- {
- }
- virtual void completed(bool success, LLImageRaw* raw, LLImageRaw* aux)
- {
- mDebugger->callbackDecoded(mID, success, raw, aux);
- }
-private:
- LLTextureFetchDebugger* mDebugger;
- S32 mID;
-};
-
-
-LLTextureFetchDebugger::LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) :
- LLCore::HttpHandler(),
- mFetcher(fetcher),
- mTextureCache(cache),
- mImageDecodeThread(imagedecodethread),
- mHttpHeaders(),
- mHttpPolicyClass(fetcher->getPolicyClass()),
- mNbCurlCompleted(0),
- mTempIndex(0),
- mHistoryListIndex(0)
-{
- init();
-}
-
-LLTextureFetchDebugger::~LLTextureFetchDebugger()
-{
- mFetchingHistory.clear();
- mStopDebug = TRUE;
- tryToStopDebug();
-}
-
-void LLTextureFetchDebugger::init()
-{
- setDebuggerState(IDLE);
-
- mCacheReadTime = -1.f;
- mCacheWriteTime = -1.f;
- mDecodingTime = -1.f;
- mHTTPTime = -1.f;
- mGLCreationTime = -1.f;
-
- mTotalFetchingTime = 0.f;
- mRefetchVisCacheTime = -1.f;
- mRefetchVisHTTPTime = -1.f;
- mRefetchAllCacheTime = -1.f;
- mRefetchAllHTTPTime = -1.f;
-
- mNumFetchedTextures = 0;
- mNumCacheHits = 0;
- mNumVisibleFetchedTextures = 0;
- mNumVisibleFetchingRequests = 0;
- mFetchedData = 0;
- mDecodedData = 0;
- mVisibleFetchedData = 0;
- mVisibleDecodedData = 0;
- mRenderedData = 0;
- mRenderedDecodedData = 0;
- mFetchedPixels = 0;
- mRenderedPixels = 0;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
-
- mFreezeHistory = FALSE;
- mStopDebug = FALSE;
- mClearHistory = FALSE;
- mRefetchNonVis = FALSE;
-
- mNbCurlRequests = 0;
-
- if (! mHttpHeaders)
- {
- mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
- mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_IMAGE_X_J2C);
- }
-}
-
-void LLTextureFetchDebugger::startWork(e_debug_state state)
-{
- switch(state)
- {
- case IDLE:
- break;
- case START_DEBUG:
- startDebug();
- break;
- case READ_CACHE:
- debugCacheRead();
- break;
- case WRITE_CACHE:
- debugCacheWrite();
- break;
- case DECODING:
- debugDecoder();
- break;
- case HTTP_FETCHING:
- debugHTTP();
- break;
- case GL_TEX:
- debugGLTextureCreation();
- break;
- case REFETCH_VIS_CACHE:
- debugRefetchVisibleFromCache();
- break;
- case REFETCH_VIS_HTTP:
- debugRefetchVisibleFromHTTP();
- break;
- case REFETCH_ALL_CACHE:
- debugRefetchAllFromCache();
- break;
- case REFETCH_ALL_HTTP:
- debugRefetchAllFromHTTP();
- break;
- default:
- break;
- }
- return;
-}
-
-void LLTextureFetchDebugger::startDebug()
-{
- //lock the fetcher
- mFetcher->lockFetcher(true);
- mFreezeHistory = TRUE;
- mFetcher->resetLoadSource();
-
- //clear the current fetching queue
- gTextureList.clearFetchingRequests();
-
- setDebuggerState(START_DEBUG);
-}
-
-bool LLTextureFetchDebugger::processStartDebug(F32 max_time)
-{
- mTimer.reset();
-
- //wait for all works to be done
- while(1)
- {
- S32 pending = 0;
- pending += LLAppViewer::getTextureCache()->update(1);
- pending += LLAppViewer::getImageDecodeThread()->update(1);
- // pending += LLAppViewer::getTextureFetch()->update(1); // This causes infinite recursion in some cases
- pending += mNbCurlRequests;
- if(!pending)
- {
- break;
- }
-
- if(mTimer.getElapsedTimeF32() > max_time)
- {
- return false;
- }
- }
-
- //collect statistics
- mTotalFetchingTime = gTextureTimer.getElapsedTimeF32() - mTotalFetchingTime;
-
- std::set<LLUUID> fetched_textures;
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size; i++)
- {
- bool in_list = true;
- if(fetched_textures.find(mFetchingHistory[i].mID) == fetched_textures.end())
- {
- fetched_textures.insert(mFetchingHistory[i].mID);
- in_list = false;
- }
-
- std::vector<LLViewerFetchedTexture*> textures;
- LLViewerTextureManager::findFetchedTextures(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- // fetched data will be counted for both ui and regular elements
- if (tex && tex->isJustBound()) //visible
- {
- if (!in_list)
- {
- mNumVisibleFetchedTextures++;
- }
- mNumVisibleFetchingRequests++;
-
- mVisibleFetchedData += mFetchingHistory[i].mFetchedSize;
- mVisibleDecodedData += mFetchingHistory[i].mDecodedSize;
-
- if (tex->getDiscardLevel() >= mFetchingHistory[i].mDecodedLevel)
- {
- mRenderedData += mFetchingHistory[i].mFetchedSize;
- mRenderedDecodedData += mFetchingHistory[i].mDecodedSize;
- mRenderedPixels += tex->getWidth() * tex->getHeight();
- }
- }
- }
- }
-
- mNumFetchedTextures = fetched_textures.size();
-
- return true;
-}
-
-void LLTextureFetchDebugger::tryToStopDebug()
-{
- if(!mStopDebug)
- {
- return;
- }
-
- //clear the current debug work
- S32 size = mFetchingHistory.size();
- switch(mDebuggerState)
- {
- case READ_CACHE:
- for(S32 i = 0 ; i < size; i++)
- {
- if (mFetchingHistory[i]. mCacheHandle != LLTextureCache::nullHandle())
- {
- mTextureCache->readComplete(mFetchingHistory[i].mCacheHandle, true);
- }
- }
- break;
- case WRITE_CACHE:
- for(S32 i = 0 ; i < size; i++)
- {
- if (mFetchingHistory[i].mCacheHandle != LLTextureCache::nullHandle())
- {
- mTextureCache->writeComplete(mFetchingHistory[i].mCacheHandle, true);
- }
- }
- break;
- case DECODING:
- break;
- case HTTP_FETCHING:
- break;
- case GL_TEX:
- break;
- case REFETCH_VIS_CACHE:
- break;
- case REFETCH_VIS_HTTP:
- break;
- case REFETCH_ALL_CACHE:
- mRefetchList.clear();
- break;
- case REFETCH_ALL_HTTP:
- mRefetchList.clear();
- break;
- default:
- break;
- }
-
- if(update(0.005f))
- {
- //unlock the fetcher
- mFetcher->lockFetcher(false);
- mFetcher->resetLoadSource();
- mFreezeHistory = FALSE;
- mStopDebug = FALSE;
-
- if(mClearHistory)
- {
- mFetchingHistory.clear();
- mHandleToFetchIndex.clear();
- init();
- mTotalFetchingTime = gTextureTimer.getElapsedTimeF32(); //reset
- }
- }
-}
-
-//called in the main thread and when the fetching queue is empty
-void LLTextureFetchDebugger::clearHistory()
-{
- mClearHistory = TRUE;
-}
-
-void LLTextureFetchDebugger::addHistoryEntry(LLTextureFetchWorker* worker)
-{
- if(worker->mRawImage.isNull() || worker->mFormattedImage.isNull())
- {
- return;
- }
-
- if(mFreezeHistory)
- {
- if(mDebuggerState == REFETCH_VIS_CACHE || mDebuggerState == REFETCH_VIS_HTTP)
- {
- mRefetchedVisPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
- mRefetchedVisData += worker->mFormattedImage->getDataSize();
- }
- else
- {
- mRefetchedAllPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
- mRefetchedAllData += worker->mFormattedImage->getDataSize();
-
- // refetch list only requests/creates normal images, so requesting ui='false'
- LLViewerFetchedTexture* tex = LLViewerTextureManager::findFetchedTexture(worker->mID, TEX_LIST_STANDARD);
- if(tex && mRefetchList[tex].begin() != mRefetchList[tex].end())
- {
- if(worker->mDecodedDiscard == mFetchingHistory[mRefetchList[tex][0]].mDecodedLevel)
- {
- mRefetchList[tex].erase(mRefetchList[tex].begin());
- }
- }
- }
- return;
- }
-
- if(worker->mInCache)
- {
- mNumCacheHits++;
- }
- mFetchedData += worker->mFormattedImage->getDataSize();
- mDecodedData += worker->mRawImage->getDataSize();
- mFetchedPixels += worker->mRawImage->getWidth() * worker->mRawImage->getHeight();
-
- mFetchingHistory.push_back(FetchEntry(worker->mID, worker->mDesiredSize, worker->mDecodedDiscard,
- worker->mFormattedImage->getDataSize(), worker->mRawImage->getDataSize()));
-}
-
-void LLTextureFetchDebugger::lockCache()
-{
-}
-
-void LLTextureFetchDebugger::unlockCache()
-{
-}
-
-void LLTextureFetchDebugger::debugCacheRead()
-{
- lockCache();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(READ_CACHE);
- mCacheReadTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- mFetchingHistory[i].mFormattedImage = NULL;
- mFetchingHistory[i].mCacheHandle = mTextureCache->readFromCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL, 0, mFetchingHistory[i].mFetchedSize,
- new LLDebuggerCacheReadResponder(this, i, mFetchingHistory[i].mFormattedImage));
- }
-}
-
-void LLTextureFetchDebugger::clearCache()
-{
- S32 size = mFetchingHistory.size();
- {
- std::set<LLUUID> deleted_list;
- for(S32 i = 0 ; i < size ; i++)
- {
- if(deleted_list.find(mFetchingHistory[i].mID) == deleted_list.end())
- {
- deleted_list.insert(mFetchingHistory[i].mID);
- mTextureCache->removeFromCache(mFetchingHistory[i].mID);
- }
- }
- }
-}
-
-void LLTextureFetchDebugger::debugCacheWrite()
-{
- //remove from cache
- clearCache();
-
- lockCache();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(WRITE_CACHE);
- mCacheWriteTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mFormattedImage.notNull())
- {
- mFetchingHistory[i].mCacheHandle = mTextureCache->writeToCache(mFetchingHistory[i].mID, LLWorkerThread::PRIORITY_NORMAL,
- mFetchingHistory[i].mFormattedImage->getData(), mFetchingHistory[i].mFetchedSize,
- mFetchingHistory[i].mDecodedLevel == 0 ? mFetchingHistory[i].mFetchedSize : mFetchingHistory[i].mFetchedSize + 1,
- NULL, 0, new LLDebuggerCacheWriteResponder(this, i));
- }
- }
-}
-
-void LLTextureFetchDebugger::lockDecoder()
-{
-}
-
-void LLTextureFetchDebugger::unlockDecoder()
-{
-}
-
-void LLTextureFetchDebugger::debugDecoder()
-{
- lockDecoder();
- llassert_always(mDebuggerState == IDLE);
- mTimer.reset();
- setDebuggerState(DECODING);
- mDecodingTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mFormattedImage.isNull())
- {
- continue;
- }
-
- mImageDecodeThread->decodeImage(mFetchingHistory[i].mFormattedImage, LLWorkerThread::PRIORITY_NORMAL,
- mFetchingHistory[i].mDecodedLevel, mFetchingHistory[i].mNeedsAux,
- new LLDebuggerDecodeResponder(this, i));
- }
-}
-
-void LLTextureFetchDebugger::debugHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
-
- LLViewerRegion* region = gAgent.getRegion();
- if (!region)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region undefined. Cannot fetch textures through HTTP." << LL_ENDL;
- return;
- }
-
- mHTTPUrl = region->getViewerAssetUrl();
- if (mHTTPUrl.empty())
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL;
- return;
- }
-
- mTimer.reset();
- setDebuggerState(HTTP_FETCHING);
- mHTTPTime = -1.f;
-
- S32 size = mFetchingHistory.size();
- for (S32 i = 0 ; i < size ; i++)
- {
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_NOT_DONE;
- mFetchingHistory[i].mCurlReceivedSize = 0;
- mFetchingHistory[i].mFormattedImage = NULL;
- }
- mNbCurlRequests = 0;
- mNbCurlCompleted = 0;
-
- fillCurlQueue();
-}
-
-S32 LLTextureFetchDebugger::fillCurlQueue()
-{
- if(mStopDebug) //stop
- {
- mNbCurlCompleted = mFetchingHistory.size();
- return 0;
- }
- if (mNbCurlRequests > HTTP_NONPIPE_REQUESTS_LOW_WATER)
- {
- return mNbCurlRequests;
- }
-
- S32 size = mFetchingHistory.size();
- for (S32 i = 0 ; i < size ; i++)
- {
- if (mFetchingHistory[i].mCurlState != FetchEntry::CURL_NOT_DONE)
- {
- continue;
- }
- std::string texture_url = mHTTPUrl + "/?texture_id=" + mFetchingHistory[i].mID.asString().c_str();
- S32 requestedSize = mFetchingHistory[i].mRequestedSize;
- // We request the whole file if the size was not set.
- requestedSize = llmax(0,requestedSize);
- // We request the whole file if the size was set to an absurdly high value (meaning all file)
- requestedSize = (requestedSize == 33554432 ? 0 : requestedSize);
-
- LLCore::HttpHandle handle = mFetcher->getHttpRequest().requestGetByteRange(mHttpPolicyClass,
- LLWorkerThread::PRIORITY_LOWBITS,
- texture_url,
- 0,
- requestedSize,
- LLCore::HttpOptions::ptr_t(),
- mHttpHeaders,
- LLCore::HttpHandler::ptr_t(this, &NoOpDeletor));
- if (LLCORE_HTTP_HANDLE_INVALID != handle)
- {
- mHandleToFetchIndex[handle] = i;
- mFetchingHistory[i].mHttpHandle = handle;
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_IN_PROGRESS;
- mNbCurlRequests++;
- if (mNbCurlRequests >= HTTP_NONPIPE_REQUESTS_HIGH_WATER) // emulate normal pipeline
- {
- break;
- }
- }
- else
- {
- // Failed to queue request, log it and mark it done.
- LLCore::HttpStatus status(mFetcher->getHttpRequest().getStatus());
-
- LL_WARNS(LOG_TXT) << "Couldn't issue HTTP request in debugger for texture "
- << mFetchingHistory[i].mID
- << ", status: " << status.toTerseString()
- << " reason: " << status.toString()
- << LL_ENDL;
- mFetchingHistory[i].mCurlState = FetchEntry::CURL_DONE;
- }
- }
- //LL_INFOS(LOG_TXT) << "Fetch Debugger : Having " << mNbCurlRequests << " requests through the curl thread." << LL_ENDL;
- return mNbCurlRequests;
-}
-
-void LLTextureFetchDebugger::debugGLTextureCreation()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(GL_TEX);
- mTempTexList.clear();
-
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- if(mFetchingHistory[i].mRawImage.notNull())
- {
- std::vector<LLViewerFetchedTexture*> textures;
- gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- if (tex && !tex->isForSculptOnly())
- {
- tex->destroyGLTexture();
- mTempTexList.push_back(tex);
- }
- }
- }
- }
-
- mGLCreationTime = -1.f;
- mTempIndex = 0;
- mHistoryListIndex = 0;
-
- return;
-}
-
-bool LLTextureFetchDebugger::processGLCreation(F32 max_time)
-{
- mTimer.reset();
-
- bool done = true;
- S32 size = mFetchingHistory.size();
- S32 size1 = mTempTexList.size();
- for(; mHistoryListIndex < size && mTempIndex < size1; mHistoryListIndex++)
- {
- if(mFetchingHistory[mHistoryListIndex].mRawImage.notNull())
- {
- if(mFetchingHistory[mHistoryListIndex].mID == mTempTexList[mTempIndex]->getID())
- {
- mTempTexList[mTempIndex]->createGLTexture(mFetchingHistory[mHistoryListIndex].mDecodedLevel,
- mFetchingHistory[mHistoryListIndex].mRawImage, 0, TRUE, mTempTexList[mTempIndex]->getBoostLevel());
- mTempIndex++;
- }
- }
-
- if(mTimer.getElapsedTimeF32() > max_time)
- {
- done = false;
- break;
- }
- }
-
- if(mGLCreationTime < 0.f)
- {
- mGLCreationTime = mTimer.getElapsedTimeF32() ;
- }
- else
- {
- mGLCreationTime += mTimer.getElapsedTimeF32() ;
- }
-
- return done;
-}
-
-//clear fetching results of all textures.
-void LLTextureFetchDebugger::clearTextures()
-{
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size ; i++)
- {
- std::vector<LLViewerFetchedTexture*> textures;
- gTextureList.findTexturesByID(mFetchingHistory[i].mID, textures);
- std::vector<LLViewerFetchedTexture*>::iterator iter = textures.begin();
- while (iter != textures.end())
- {
- LLViewerFetchedTexture* tex = *iter++;
- if (tex)
- {
- tex->clearFetchedResults();
- }
- }
- }
-}
-
-void LLTextureFetchDebugger::makeRefetchList()
-{
- mRefetchList.clear();
- S32 size = mFetchingHistory.size();
- for(S32 i = 0 ; i < size; i++)
- {
- LLViewerFetchedTexture* tex = LLViewerTextureManager::getFetchedTexture(mFetchingHistory[i].mID);
- if(tex && tex->isJustBound()) //visible
- {
- continue; //the texture fetch pipeline will take care of visible textures.
- }
-
- // todo: Will attempt to refetch icons and ui elements as normal images (boost_none)
- // thus will create unnecessary LLViewerFetchedTexture, consider supporting separate UI textures
- mRefetchList[tex].push_back(i);
- }
-}
-
-void LLTextureFetchDebugger::scanRefetchList()
-{
- if(mStopDebug)
- {
- return;
- }
- if(!mRefetchNonVis)
- {
- return;
- }
-
- for(std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> >::iterator iter = mRefetchList.begin();
- iter != mRefetchList.end(); )
- {
- if(iter->second.empty())
- {
- gTextureList.setDebugFetching(iter->first, -1);
- mRefetchList.erase(iter++); // This is the correct method to "erase and move on" in an std::map
- }
- else
- {
- gTextureList.setDebugFetching(iter->first, mFetchingHistory[iter->second[0]].mDecodedLevel);
- ++iter;
- }
- }
-}
-
-void LLTextureFetchDebugger::debugRefetchVisibleFromCache()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_VIS_CACHE);
-
- clearTextures();
- mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchVisCacheTime = -1.f;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
-}
-
-void LLTextureFetchDebugger::debugRefetchVisibleFromHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_VIS_HTTP);
-
- clearTextures();
- mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchVisHTTPTime = -1.f;
- mRefetchedVisData = 0;
- mRefetchedVisPixels = 0;
-}
-
-void LLTextureFetchDebugger::debugRefetchAllFromCache()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_ALL_CACHE);
-
- clearTextures();
- makeRefetchList();
- mFetcher->setLoadSource(LLTextureFetch::FROM_ALL);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchAllCacheTime = -1.f;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
- mRefetchNonVis = FALSE;
-}
-
-void LLTextureFetchDebugger::debugRefetchAllFromHTTP()
-{
- llassert_always(mDebuggerState == IDLE);
- setDebuggerState(REFETCH_ALL_HTTP);
-
- clearTextures();
- makeRefetchList();
- mFetcher->setLoadSource(LLTextureFetch::FROM_HTTP_ONLY);
-
- mTimer.reset();
- mFetcher->lockFetcher(false);
- mRefetchAllHTTPTime = -1.f;
- mRefetchedAllData = 0;
- mRefetchedAllPixels = 0;
- mRefetchNonVis = TRUE;
-}
-
-bool LLTextureFetchDebugger::update(F32 max_time)
-{
- switch(mDebuggerState)
- {
- case START_DEBUG:
- if(processStartDebug(max_time))
- {
- setDebuggerState(IDLE);
- }
- break;
- case READ_CACHE:
- if(!mTextureCache->update(1))
- {
- mCacheReadTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockCache();
- }
- break;
- case WRITE_CACHE:
- if(!mTextureCache->update(1))
- {
- mCacheWriteTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockCache();
- }
- break;
- case DECODING:
- if(!mImageDecodeThread->update(1))
- {
- mDecodingTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- unlockDecoder();
- }
- break;
- case HTTP_FETCHING:
- // Do some notifications...
- mFetcher->getHttpRequest().update(10);
- if (!fillCurlQueue() && mNbCurlCompleted == mFetchingHistory.size())
- {
- mHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- }
- break;
- case GL_TEX:
- if(processGLCreation(max_time))
- {
- setDebuggerState(IDLE);
- mTempTexList.clear();
- }
- break;
- case REFETCH_VIS_CACHE:
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchVisCacheTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- }
- break;
- case REFETCH_VIS_HTTP:
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchVisHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- }
- break;
- case REFETCH_ALL_CACHE:
- scanRefetchList();
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- if(!mRefetchNonVis)
- {
- mRefetchNonVis = TRUE; //start to fetch non-vis
- scanRefetchList();
- break;
- }
-
- mRefetchAllCacheTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- mRefetchList.clear();
- mRefetchNonVis = FALSE;
- }
- break;
- case REFETCH_ALL_HTTP:
- scanRefetchList();
- if (LLAppViewer::getTextureFetch()->getNumRequests() == 0)
- {
- mRefetchAllHTTPTime = mTimer.getElapsedTimeF32() ;
- setDebuggerState(IDLE);
- mFetcher->lockFetcher(true);
- mFetcher->resetLoadSource();
- mRefetchList.clear();
- mRefetchNonVis = FALSE;
- }
- break;
- default:
- setDebuggerState(IDLE);
- break;
- }
-
- return mDebuggerState == IDLE;
-}
-
-void LLTextureFetchDebugger::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
-{
- handle_fetch_map_t::iterator iter(mHandleToFetchIndex.find(handle));
- if (mHandleToFetchIndex.end() == iter)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Couldn't find handle " << handle << " in fetch list." << LL_ENDL;
- return;
- }
-
- S32 fetch_ind(iter->second);
- mHandleToFetchIndex.erase(iter);
- if (fetch_ind >= mFetchingHistory.size() || mFetchingHistory[fetch_ind].mHttpHandle != handle)
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : Handle and fetch object in disagreement. Punting." << LL_ENDL;
- }
- else
- {
- callbackHTTP(mFetchingHistory[fetch_ind], response);
- mFetchingHistory[fetch_ind].mHttpHandle = LLCORE_HTTP_HANDLE_INVALID; // Not valid after notification
- }
-}
-
-void LLTextureFetchDebugger::callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
- S32 imagesize, BOOL islocal)
-{
- if (success)
- {
- mFetchingHistory[id].mFormattedImage = image;
- }
- mTextureCache->readComplete(mFetchingHistory[id].mCacheHandle, false);
- mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
-}
-
-void LLTextureFetchDebugger::callbackCacheWrite(S32 id, bool success)
-{
- mTextureCache->writeComplete(mFetchingHistory[id].mCacheHandle);
- mFetchingHistory[id].mCacheHandle = LLTextureCache::nullHandle();
-}
-
-void LLTextureFetchDebugger::callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux)
-{
- if (success)
- {
- llassert_always(raw);
- mFetchingHistory[id].mRawImage = raw;
- }
-}
-
-void LLTextureFetchDebugger::callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response)
-{
- static const LLCore::HttpStatus par_status(HTTP_PARTIAL_CONTENT);
-
- LLCore::HttpStatus status(response->getStatus());
- mNbCurlRequests--;
- mNbCurlCompleted++;
- fetch.mCurlState = FetchEntry::CURL_DONE;
- if (status)
- {
- const bool partial(par_status == status);
- LLCore::BufferArray * ba(response->getBody()); // *Not* holding reference to body
-
- S32 data_size = ba ? ba->size() : 0;
- fetch.mCurlReceivedSize += data_size;
- //LL_INFOS(LOG_TXT) << "Fetch Debugger : got results for " << fetch.mID << ", data_size = " << data_size << ", received = " << fetch.mCurlReceivedSize << ", requested = " << fetch.mRequestedSize << ", partial = " << partial << LL_ENDL;
- if ((fetch.mCurlReceivedSize >= fetch.mRequestedSize) || !partial || (fetch.mRequestedSize == 600))
- {
- U8* d_buffer = (U8*)ll_aligned_malloc_16(data_size);
- if (ba)
- {
- ba->read(0, d_buffer, data_size);
- }
-
- llassert_always(fetch.mFormattedImage.isNull());
- {
- // For now, create formatted image based on extension
- std::string texture_url = mHTTPUrl + "/?texture_id=" + fetch.mID.asString().c_str();
- std::string extension = gDirUtilp->getExtension(texture_url);
- fetch.mFormattedImage = LLImageFormatted::createFromType(LLImageBase::getCodecFromExtension(extension));
- if (fetch.mFormattedImage.isNull())
- {
- fetch.mFormattedImage = new LLImageJ2C; // default
- }
- }
-
- fetch.mFormattedImage->setData(d_buffer, data_size);
- }
- }
- else //failed
- {
- LL_INFOS(LOG_TXT) << "Fetch Debugger : CURL GET FAILED, ID = " << fetch.mID
- << ", status: " << status.toTerseString()
- << " reason: " << status.toString() << LL_ENDL;
- }
-}
-
-
-//---------------------
-///////////////////////////////////////////////////////////////////////////////////////////
-//End LLTextureFetchDebugger
-///////////////////////////////////////////////////////////////////////////////////////////
-
LLTextureFetchTester::LLTextureFetchTester() : LLMetricPerformanceTesterBasic(sTesterName)
{
mTextureFetchTime = 0;
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 611a7d6419..9ff6468bb2 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -48,7 +48,6 @@ class LLTextureFetchWorker;
class LLImageDecodeThread;
class LLHost;
class LLViewerAssetStats;
-class LLTextureFetchDebugger;
class LLTextureCache;
class LLTextureFetchTester;
@@ -59,7 +58,9 @@ class LLTextureFetch : public LLWorkerThread
friend class LLTextureFetchWorker;
public:
- LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
+ static std::string getStateString(S32 state);
+
+ LLTextureFetch(LLTextureCache* cache, bool threaded, bool qa_mode);
~LLTextureFetch();
class TFRequest;
@@ -76,7 +77,7 @@ public:
void shutDownImageDecodeThread();
// Threads: T* (but Tmain mostly)
- bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+ S32 createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
// Requests that a fetch operation be deleted from the queue.
@@ -110,10 +111,11 @@ public:
// Threads: T*
BOOL isFromLocalCache(const LLUUID& id);
- // @return Magic number giving the internal state of the
- // request. We should make these codes public if we're
- // going to return them as a status value.
- //
+ // get the current fetch state, if any, from the given UUID
+ S32 getFetchState(const LLUUID& id);
+
+ // @return Fetch state of given image and associates statistics
+ // See also getStateString
// Threads: T*
S32 getFetchState(const LLUUID& id, F32& decode_progress_p, F32& requested_priority_p,
U32& fetch_priority_p, F32& fetch_dtime_p, F32& request_dtime_p, bool& can_use_http);
@@ -307,7 +309,6 @@ private:
LLMutex mNetworkQueueMutex; //to protect mHTTPTextureQueue
LLTextureCache* mTextureCache;
- LLImageDecodeThread* mImageDecodeThread;
// Map of all requests by UUID
typedef std::map<LLUUID,LLTextureFetchWorker*> map_t;
@@ -392,10 +393,6 @@ public:
static LLTextureFetchTester* sTesterp;
private:
- //debug use
- LLTextureFetchDebugger* mFetchDebugger;
- bool mFetcherLocked;
-
e_tex_source mFetchSource;
e_tex_source mOriginFetchSource;
@@ -403,10 +400,6 @@ private:
//LLAdaptiveRetryPolicy mFetchRetryPolicy;
public:
- //debug use
- LLTextureFetchDebugger* getFetchDebugger() { return mFetchDebugger;}
- void lockFetcher(bool lock) { mFetcherLocked = lock;}
-
void setLoadSource(e_tex_source source) {mFetchSource = source;}
void resetLoadSource() {mFetchSource = mOriginFetchSource;}
bool canLoadFromCache() { return mFetchSource != FROM_HTTP_ONLY;}
@@ -414,216 +407,6 @@ public:
//debug use
class LLViewerFetchedTexture;
-class LLTextureFetchDebugger : public LLCore::HttpHandler
-{
- friend class LLTextureFetch;
-public:
- LLTextureFetchDebugger(LLTextureFetch* fetcher, LLTextureCache* cache, LLImageDecodeThread* imagedecodethread) ;
- ~LLTextureFetchDebugger();
-
-public:
- enum e_debug_state
- {
- IDLE = 0,
- START_DEBUG,
- READ_CACHE,
- WRITE_CACHE,
- DECODING,
- HTTP_FETCHING,
- GL_TEX,
- REFETCH_VIS_CACHE,
- REFETCH_VIS_HTTP,
- REFETCH_ALL_CACHE,
- REFETCH_ALL_HTTP,
- INVALID
- };
-
-private:
- struct FetchEntry
- {
- enum e_curl_state
- {
- CURL_NOT_DONE = 0,
- CURL_IN_PROGRESS,
- CURL_DONE
- };
- LLUUID mID;
- S32 mRequestedSize;
- S32 mDecodedLevel;
- S32 mFetchedSize;
- S32 mDecodedSize;
- BOOL mNeedsAux;
- U32 mCacheHandle;
- LLPointer<LLImageFormatted> mFormattedImage;
- LLPointer<LLImageRaw> mRawImage;
- e_curl_state mCurlState;
- S32 mCurlReceivedSize;
- LLCore::HttpHandle mHttpHandle;
-
- FetchEntry() :
- mDecodedLevel(-1),
- mFetchedSize(0),
- mDecodedSize(0),
- mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
- {}
- FetchEntry(LLUUID& id, S32 r_size, /*S32 f_discard, S32 c,*/ S32 level, S32 f_size, S32 d_size) :
- mID(id),
- mRequestedSize(r_size),
- mDecodedLevel(level),
- mFetchedSize(f_size),
- mDecodedSize(d_size),
- mNeedsAux(false),
- mHttpHandle(LLCORE_HTTP_HANDLE_INVALID)
- {}
- };
- typedef std::vector<FetchEntry> fetch_list_t;
- fetch_list_t mFetchingHistory;
-
- typedef std::map<LLCore::HttpHandle, S32> handle_fetch_map_t;
- handle_fetch_map_t mHandleToFetchIndex;
-
- void setDebuggerState(e_debug_state new_state) { mDebuggerState = new_state; }
- e_debug_state mDebuggerState;
-
- F32 mCacheReadTime;
- F32 mCacheWriteTime;
- F32 mDecodingTime;
- F32 mHTTPTime;
- F32 mGLCreationTime;
-
- F32 mTotalFetchingTime;
- F32 mRefetchVisCacheTime;
- F32 mRefetchVisHTTPTime;
- F32 mRefetchAllCacheTime;
- F32 mRefetchAllHTTPTime;
-
- LLTimer mTimer;
-
- LLTextureFetch* mFetcher;
- LLTextureCache* mTextureCache;
- LLImageDecodeThread* mImageDecodeThread;
- LLCore::HttpHeaders::ptr_t mHttpHeaders;
- LLCore::HttpRequest::policy_t mHttpPolicyClass;
-
- S32 mNumFetchedTextures;
- S32 mNumCacheHits;
- S32 mNumVisibleFetchedTextures;
- S32 mNumVisibleFetchingRequests;
- U32 mFetchedData;
- U32 mDecodedData;
- U32 mVisibleFetchedData;
- U32 mVisibleDecodedData;
- U32 mRenderedData;
- U32 mRenderedDecodedData;
- U32 mFetchedPixels;
- U32 mRenderedPixels;
- U32 mRefetchedVisData;
- U32 mRefetchedVisPixels;
- U32 mRefetchedAllData;
- U32 mRefetchedAllPixels;
-
- BOOL mFreezeHistory;
- BOOL mStopDebug;
- BOOL mClearHistory;
- BOOL mRefetchNonVis;
-
- std::string mHTTPUrl;
- S32 mNbCurlRequests;
- S32 mNbCurlCompleted;
-
- std::map< LLPointer<LLViewerFetchedTexture>, std::vector<S32> > mRefetchList; // treats UI textures as normal textures
- std::vector< LLPointer<LLViewerFetchedTexture> > mTempTexList;
- S32 mTempIndex;
- S32 mHistoryListIndex;
-
-public:
- bool update(F32 max_time); //called in the main thread once per frame
-
- //fetching history
- void clearHistory();
- void addHistoryEntry(LLTextureFetchWorker* worker);
-
- // Inherited from LLCore::HttpHandler
- // Threads: Ttf
- virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
-
- void startWork(e_debug_state state);
- void setStopDebug() {mStopDebug = TRUE;}
- void tryToStopDebug(); //stop everything
- void callbackCacheRead(S32 id, bool success, LLImageFormatted* image,
- S32 imagesize, BOOL islocal);
- void callbackCacheWrite(S32 id, bool success);
- void callbackDecoded(S32 id, bool success, LLImageRaw* raw, LLImageRaw* aux);
- void callbackHTTP(FetchEntry & fetch, LLCore::HttpResponse * response);
-
- e_debug_state getState() {return mDebuggerState;}
- S32 getNumFetchedTextures() {return mNumFetchedTextures;}
- S32 getNumFetchingRequests() {return mFetchingHistory.size();}
- S32 getNumCacheHits() {return mNumCacheHits;}
- S32 getNumVisibleFetchedTextures() {return mNumVisibleFetchedTextures;}
- S32 getNumVisibleFetchingRequests() {return mNumVisibleFetchingRequests;}
- U32 getFetchedData() {return mFetchedData;}
- U32 getDecodedData() {return mDecodedData;}
- U32 getVisibleFetchedData() {return mVisibleFetchedData;}
- U32 getVisibleDecodedData() {return mVisibleDecodedData;}
- U32 getRenderedData() {return mRenderedData;}
- U32 getRenderedDecodedData() {return mRenderedDecodedData;}
- U32 getFetchedPixels() {return mFetchedPixels;}
- U32 getRenderedPixels() {return mRenderedPixels;}
- U32 getRefetchedVisData() {return mRefetchedVisData;}
- U32 getRefetchedVisPixels() {return mRefetchedVisPixels;}
- U32 getRefetchedAllData() {return mRefetchedAllData;}
- U32 getRefetchedAllPixels() {return mRefetchedAllPixels;}
-
- F32 getCacheReadTime() {return mCacheReadTime;}
- F32 getCacheWriteTime() {return mCacheWriteTime;}
- F32 getDecodeTime() {return mDecodingTime;}
- F32 getGLCreationTime() {return mGLCreationTime;}
- F32 getHTTPTime() {return mHTTPTime;}
- F32 getTotalFetchingTime() {return mTotalFetchingTime;}
- F32 getRefetchVisCacheTime() {return mRefetchVisCacheTime;}
- F32 getRefetchVisHTTPTime() {return mRefetchVisHTTPTime;}
- F32 getRefetchAllCacheTime() {return mRefetchAllCacheTime;}
- F32 getRefetchAllHTTPTime() {return mRefetchAllHTTPTime;}
-
-private:
- void init();
- void clearTextures();//clear fetching results of all textures.
- void clearCache();
- void makeRefetchList();
- void scanRefetchList();
-
- void lockFetcher();
- void unlockFetcher();
-
- void lockCache();
- void unlockCache();
-
- void lockDecoder();
- void unlockDecoder();
-
- S32 fillCurlQueue();
-
- void startDebug();
- void debugCacheRead();
- void debugCacheWrite();
- void debugHTTP();
- void debugDecoder();
- void debugGLTextureCreation();
- void debugRefetchVisibleFromCache();
- void debugRefetchVisibleFromHTTP();
- void debugRefetchAllFromCache();
- void debugRefetchAllFromHTTP();
-
- bool processStartDebug(F32 max_time);
- bool processGLCreation(F32 max_time);
-
-private:
- static bool sDebuggerEnabled;
-public:
- static bool isEnabled() {return sDebuggerEnabled;}
-};
-
class LLTextureFetchTester : public LLMetricPerformanceTesterBasic
{
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 84b61fc612..62703e3499 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -49,6 +49,8 @@
#include "llviewerobjectlist.h"
#include "llviewertexture.h"
#include "llviewertexturelist.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
#include "llvovolume.h"
#include "llviewerstats.h"
#include "llworld.h"
@@ -117,8 +119,8 @@ public:
LLTextureBar* bar2p = (LLTextureBar*)i2;
LLViewerFetchedTexture *i1p = bar1p->mImagep;
LLViewerFetchedTexture *i2p = bar2p->mImagep;
- F32 pri1 = i1p->getDecodePriority(); // i1p->mRequestedDownloadPriority
- F32 pri2 = i2p->getDecodePriority(); // i2p->mRequestedDownloadPriority
+ F32 pri1 = i1p->getMaxVirtualSize();
+ F32 pri2 = i2p->getMaxVirtualSize();
if (pri1 > pri2)
return true;
else if (pri2 > pri1)
@@ -173,11 +175,7 @@ void LLTextureBar::draw()
{
color = LLColor4::green4;
}
- else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_ALM)
- {
- color = LLColor4::magenta; // except none and alm
- }
- else if (mImagep->getDecodePriority() <= 0.0f)
+ else if (mImagep->getMaxVirtualSize() <= 0.0f)
{
color = LLColor4::grey; color[VALPHA] = .7f;
}
@@ -202,26 +200,13 @@ void LLTextureBar::draw()
std::string uuid_str;
mImagep->mID.toString(uuid_str);
uuid_str = uuid_str.substr(0,7);
- if (mTextureView->mOrderFetch)
- {
- tex_str = llformat("%s %7.0f %d(%d) 0x%08x(%8.0f)",
- uuid_str.c_str(),
- mImagep->mMaxVirtualSize,
- mImagep->mDesiredDiscardLevel,
- mImagep->mRequestedDiscardLevel,
- mImagep->mFetchPriority,
- mImagep->getDecodePriority());
- }
- else
- {
- tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)",
- uuid_str.c_str(),
- mImagep->mMaxVirtualSize,
- mImagep->mDesiredDiscardLevel,
- mImagep->mRequestedDiscardLevel,
- mImagep->getDecodePriority(),
- mImagep->mFetchPriority);
- }
+
+ tex_str = llformat("%s %7.0f %d(%d)",
+ uuid_str.c_str(),
+ mImagep->mMaxVirtualSize,
+ mImagep->mDesiredDiscardLevel,
+ mImagep->mRequestedDiscardLevel);
+
LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(),
color, LLFontGL::LEFT, LLFontGL::TOP);
@@ -499,10 +484,6 @@ private:
void LLGLTexMemBar::draw()
{
- S32Megabytes bound_mem = LLViewerTexture::sBoundTextureMemory;
- S32Megabytes max_bound_mem = LLViewerTexture::sMaxBoundTextureMemory;
- S32Megabytes total_mem = LLViewerTexture::sTotalTextureMemory;
- S32Megabytes max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
F32 cache_usage = LLAppViewer::getTextureCache()->getUsage().valueInUnits<LLUnits::Megabytes>();
F32 cache_max_usage = LLAppViewer::getTextureCache()->getMaxUsage().valueInUnits<LLUnits::Megabytes>();
@@ -548,15 +529,10 @@ void LLGLTexMemBar::draw()
U32 texFetchLatMed = U32(recording.getMean(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
U32 texFetchLatMax = U32(recording.getMax(LLTextureFetch::sTexFetchLatency).value() * 1000.0f);
- text = llformat("GL Tot: %d/%d MB GL Free: %d Sys Free: %d MB Bound: %4d/%4d MB FBO: %d MB Raw Tot: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
- total_mem.value(),
- max_total_mem.value(),
- LLImageGLThread::getFreeVRAMMegabytes(),
+ text = llformat("GL Free: %d MB Sys Free: %d MB FBO: %d MB Bias: %.2f Cache: %.1f/%.1f MB",
+ gViewerWindow->getWindow()->getAvailableVRAMMegabytes(),
LLMemory::getAvailableMemKB()/1024,
- bound_mem.value(),
- max_bound_mem.value(),
LLRenderTarget::sBytesAllocated/(1024*1024),
- LLImageRaw::sGlobalRawMemory >> 20,
discard_bias,
cache_usage,
cache_max_usage);
@@ -836,7 +812,7 @@ void LLTextureView::draw()
LL_INFOS() << imagep->getID()
<< "\t" << tex_mem
<< "\t" << imagep->getBoostLevel()
- << "\t" << imagep->getDecodePriority()
+ << "\t" << imagep->getMaxVirtualSize()
<< "\t" << imagep->getWidth()
<< "\t" << imagep->getHeight()
<< "\t" << cur_discard
@@ -856,7 +832,7 @@ void LLTextureView::draw()
}
else
{
- pri = imagep->getDecodePriority();
+ pri = imagep->getMaxVirtualSize();
}
pri = llclamp(pri, 0.0f, HIGH_PRIORITY-1.f);
diff --git a/indra/newview/llthumbnailctrl.cpp b/indra/newview/llthumbnailctrl.cpp
index 04130fc724..b558c249cb 100644
--- a/indra/newview/llthumbnailctrl.cpp
+++ b/indra/newview/llthumbnailctrl.cpp
@@ -57,7 +57,8 @@ LLThumbnailCtrl::LLThumbnailCtrl(const LLThumbnailCtrl::Params& p)
, mFallbackImagep(p.fallback_image)
, mInteractable(p.interactable())
, mShowLoadingPlaceholder(p.show_loading())
-, mPriority(LLGLTexture::BOOST_PREVIEW)
+, mInited(false)
+, mInitImmediately(true)
{
mLoadingPlaceholderString = LLTrans::getString("texture_loading");
@@ -84,6 +85,10 @@ LLThumbnailCtrl::~LLThumbnailCtrl()
void LLThumbnailCtrl::draw()
{
+ if (!mInited)
+ {
+ initImage();
+ }
LLRect draw_rect = getLocalRect();
if (mBorderVisible)
@@ -171,11 +176,19 @@ void LLThumbnailCtrl::draw()
LLUICtrl::draw();
}
+void LLThumbnailCtrl::setVisible(BOOL visible)
+{
+ if (!visible && mInited)
+ {
+ unloadImage();
+ }
+ LLUICtrl::setVisible(visible);
+}
+
void LLThumbnailCtrl::clearTexture()
{
- mImageAssetID = LLUUID::null;
- mTexturep = nullptr;
- mImagep = nullptr;
+ setValue(LLSD());
+ mInited = true; // nothing to do
}
// virtual
@@ -191,34 +204,55 @@ void LLThumbnailCtrl::setValue(const LLSD& value)
LLUICtrl::setValue(tvalue);
- mImageAssetID = LLUUID::null;
- mTexturep = nullptr;
- mImagep = nullptr;
-
- if (tvalue.isUUID())
- {
+ unloadImage();
+
+ if (mInitImmediately)
+ {
+ initImage();
+ }
+}
+
+BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask)
+{
+ if (mInteractable && getEnabled())
+ {
+ getWindow()->setCursor(UI_CURSOR_HAND);
+ return TRUE;
+ }
+ return LLUICtrl::handleHover(x, y, mask);
+}
+
+void LLThumbnailCtrl::initImage()
+{
+ if (mInited)
+ {
+ return;
+ }
+ mInited = true;
+ LLSD tvalue = getValue();
+
+ if (tvalue.isUUID())
+ {
mImageAssetID = tvalue.asUUID();
if (mImageAssetID.notNull())
{
// Should it support baked textures?
- mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-
- mTexturep->setBoostLevel(mPriority);
+ mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES, LLGLTexture::BOOST_THUMBNAIL);
+
mTexturep->forceToSaveRawImage(0);
-
- S32 desired_draw_width = mTexturep->getWidth();
- S32 desired_draw_height = mTexturep->getHeight();
-
+
+ S32 desired_draw_width = MAX_IMAGE_SIZE;
+ S32 desired_draw_height = MAX_IMAGE_SIZE;
mTexturep->setKnownDrawSize(desired_draw_width, desired_draw_height);
}
- }
+ }
else if (tvalue.isString())
{
mImagep = LLUI::getUIImage(tvalue.asString(), LLGLTexture::BOOST_UI);
if (mImagep)
{
LLViewerFetchedTexture* texture = dynamic_cast<LLViewerFetchedTexture*>(mImagep->getImage().get());
- if(texture)
+ if (texture)
{
mImageAssetID = texture->getID();
}
@@ -226,14 +260,12 @@ void LLThumbnailCtrl::setValue(const LLSD& value)
}
}
-BOOL LLThumbnailCtrl::handleHover(S32 x, S32 y, MASK mask)
+void LLThumbnailCtrl::unloadImage()
{
- if (mInteractable && getEnabled())
- {
- getWindow()->setCursor(UI_CURSOR_HAND);
- return TRUE;
- }
- return LLUICtrl::handleHover(x, y, mask);
+ mImageAssetID = LLUUID::null;
+ mTexturep = nullptr;
+ mImagep = nullptr;
+ mInited = false;
}
diff --git a/indra/newview/llthumbnailctrl.h b/indra/newview/llthumbnailctrl.h
index 686603b373..f84a583271 100644
--- a/indra/newview/llthumbnailctrl.h
+++ b/indra/newview/llthumbnailctrl.h
@@ -64,17 +64,24 @@ public:
virtual ~LLThumbnailCtrl();
virtual void draw() override;
+ void setVisible(BOOL visible) override;
virtual void setValue(const LLSD& value ) override;
+ void setInitImmediately(bool val) { mInitImmediately = val; }
void clearTexture();
virtual BOOL handleHover(S32 x, S32 y, MASK mask) override;
+
+protected:
+ void initImage();
+ void unloadImage();
private:
- S32 mPriority;
bool mBorderVisible;
bool mInteractable;
bool mShowLoadingPlaceholder;
+ bool mInited;
+ bool mInitImmediately;
std::string mLoadingPlaceholderString;
LLUUID mImageAssetID;
LLViewBorder* mBorder;
diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp
new file mode 100644
index 0000000000..999be07dba
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.cpp
@@ -0,0 +1,331 @@
+/**
+ * @file lltinygltfhelper.cpp
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltinygltfhelper.h"
+
+#include "llimage.h"
+#include "llviewertexture.h"
+#include "llviewertexturelist.h"
+
+void strip_alpha_channel(LLPointer<LLImageRaw>& img)
+{
+ if (img->getComponents() == 4)
+ {
+ LLImageRaw* tmp = new LLImageRaw(img->getWidth(), img->getHeight(), 3);
+ tmp->copyUnscaled4onto3(img);
+ img = tmp;
+ }
+}
+
+// copy red channel from src_img to dst_img
+// PRECONDITIONS:
+// dst_img must be 3 component
+// src_img and dst_image must have the same dimensions
+void copy_red_channel(LLPointer<LLImageRaw>& src_img, LLPointer<LLImageRaw>& dst_img)
+{
+ llassert(src_img->getWidth() == dst_img->getWidth() && src_img->getHeight() == dst_img->getHeight());
+ llassert(dst_img->getComponents() == 3);
+
+ U32 pixel_count = dst_img->getWidth() * dst_img->getHeight();
+ U8* src = src_img->getData();
+ U8* dst = dst_img->getData();
+ S8 src_components = src_img->getComponents();
+
+ for (U32 i = 0; i < pixel_count; ++i)
+ {
+ dst[i * 3] = src[i * src_components];
+ }
+}
+
+void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex)
+{
+ if (base_color_img)
+ {
+ base_color_tex = LLViewerTextureManager::getFetchedTexture(base_color_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (normal_img)
+ {
+ strip_alpha_channel(normal_img);
+ normal_tex = LLViewerTextureManager::getFetchedTexture(normal_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (mr_img)
+ {
+ strip_alpha_channel(mr_img);
+
+ if (occlusion_img && material.pbrMetallicRoughness.metallicRoughnessTexture.index != material.occlusionTexture.index)
+ {
+ // occlusion is a distinct texture from pbrMetallicRoughness
+ // pack into mr red channel
+ int occlusion_idx = material.occlusionTexture.index;
+ int mr_idx = material.pbrMetallicRoughness.metallicRoughnessTexture.index;
+ if (occlusion_idx != mr_idx)
+ {
+ //scale occlusion image to match resolution of mr image
+ occlusion_img->scale(mr_img->getWidth(), mr_img->getHeight());
+
+ copy_red_channel(occlusion_img, mr_img);
+ }
+ }
+ }
+ else if (occlusion_img)
+ {
+ //no mr but occlusion exists, make a white mr_img and copy occlusion red channel over
+ mr_img = new LLImageRaw(occlusion_img->getWidth(), occlusion_img->getHeight(), 3);
+ mr_img->clear(255, 255, 255);
+ copy_red_channel(occlusion_img, mr_img);
+ }
+
+ if (mr_img)
+ {
+ mr_tex = LLViewerTextureManager::getFetchedTexture(mr_img, FTType::FTT_LOCAL_FILE, true);
+ }
+
+ if (emissive_img)
+ {
+ strip_alpha_channel(emissive_img);
+ emissive_tex = LLViewerTextureManager::getFetchedTexture(emissive_img, FTType::FTT_LOCAL_FILE, true);
+ }
+}
+
+LLColor4 LLTinyGLTFHelper::getColor(const std::vector<double>& in)
+{
+ LLColor4 out;
+ for (S32 i = 0; i < llmin((S32)in.size(), 4); ++i)
+ {
+ out.mV[i] = in[i];
+ }
+
+ return out;
+}
+
+const tinygltf::Image * LLTinyGLTFHelper::getImageFromTextureIndex(const tinygltf::Model & model, S32 texture_index)
+{
+ if (texture_index >= 0)
+ {
+ S32 source_idx = model.textures[texture_index].source;
+ if (source_idx >= 0)
+ {
+ return &(model.images[source_idx]);
+ }
+ }
+
+ return nullptr;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index, std::string & name)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ name = image->name;
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ rawImage->optimizeAwayAlpha();
+ }
+
+ return rawImage;
+}
+
+LLImageRaw * LLTinyGLTFHelper::getTexture(const std::string & folder, const tinygltf::Model & model, S32 texture_index)
+{
+ const tinygltf::Image* image = getImageFromTextureIndex(model, texture_index);
+ LLImageRaw* rawImage = nullptr;
+
+ if (image != nullptr &&
+ image->bits == 8 &&
+ !image->image.empty() &&
+ image->component <= 4)
+ {
+ rawImage = new LLImageRaw(&image->image[0], image->width, image->height, image->component);
+ rawImage->verticalFlip();
+ }
+
+ return rawImage;
+}
+
+bool LLTinyGLTFHelper::loadModel(const std::string& filename, tinygltf::Model& model_in)
+{
+ std::string exten = gDirUtilp->getExtension(filename);
+
+ if (exten == "gltf" || exten == "glb")
+ {
+ tinygltf::TinyGLTF loader;
+ std::string error_msg;
+ std::string warn_msg;
+
+ std::string filename_lc = filename;
+ LLStringUtil::toLower(filename_lc);
+
+ // Load a tinygltf model fom a file. Assumes that the input filename has already been
+ // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish.
+ bool decode_successful = false;
+ if (std::string::npos == filename_lc.rfind(".gltf"))
+ { // file is binary
+ decode_successful = loader.LoadBinaryFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+ else
+ { // file is ascii
+ decode_successful = loader.LoadASCIIFromFile(&model_in, &error_msg, &warn_msg, filename_lc);
+ }
+
+ if (!decode_successful)
+ {
+ LL_WARNS("GLTF") << "Cannot load, error: Failed to decode" << error_msg
+ << ", warning:" << warn_msg
+ << " file: " << filename
+ << LL_ENDL;
+ return false;
+ }
+
+ if (model_in.materials.empty())
+ {
+ // materials are missing
+ LL_WARNS("GLTF") << "Cannot load. File has no materials " << filename << LL_ENDL;
+ return false;
+ }
+
+ return true;
+ }
+
+
+ return false;
+}
+
+bool LLTinyGLTFHelper::getMaterialFromModel(
+ const std::string& filename,
+ const tinygltf::Model& model_in,
+ S32 mat_index,
+ LLFetchedGLTFMaterial* material,
+ std::string& material_name)
+{
+ llassert(material);
+
+ if (model_in.materials.size() <= mat_index)
+ {
+ // materials are missing
+ LL_WARNS("GLTF") << "Cannot load Material, Material " << mat_index << " is missing, " << filename << LL_ENDL;
+ return false;
+ }
+
+ material->setFromModel(model_in, mat_index);
+
+ std::string folder = gDirUtilp->getDirName(filename);
+ tinygltf::Material material_in = model_in.materials[mat_index];
+
+ material_name = material_in.name;
+
+ // get base color texture
+ LLPointer<LLImageRaw> base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index);
+ // get normal map
+ LLPointer<LLImageRaw> normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index);
+ // get metallic-roughness texture
+ LLPointer<LLImageRaw> mr_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.metallicRoughnessTexture.index);
+ // get emissive texture
+ LLPointer<LLImageRaw> emissive_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.emissiveTexture.index);
+ // get occlusion map if needed
+ LLPointer<LLImageRaw> occlusion_img;
+ if (material_in.occlusionTexture.index != material_in.pbrMetallicRoughness.metallicRoughnessTexture.index)
+ {
+ occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index);
+ }
+
+ LLPointer<LLViewerFetchedTexture> base_color_tex;
+ LLPointer<LLViewerFetchedTexture> normal_tex;
+ LLPointer<LLViewerFetchedTexture> mr_tex;
+ LLPointer<LLViewerFetchedTexture> emissive_tex;
+
+ // todo: pass it into local bitmaps?
+ LLTinyGLTFHelper::initFetchedTextures(material_in,
+ base_img, normal_img, mr_img, emissive_img, occlusion_img,
+ base_color_tex, normal_tex, mr_tex, emissive_tex);
+
+ if (base_color_tex)
+ {
+ base_color_tex->addTextureStats(64.f * 64.f, TRUE);
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = base_color_tex->getID();
+ material->mBaseColorTexture = base_color_tex;
+ }
+ else
+ {
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = LLUUID::null;
+ material->mBaseColorTexture = nullptr;
+ }
+
+ if (normal_tex)
+ {
+ normal_tex->addTextureStats(64.f * 64.f, TRUE);
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = normal_tex->getID();
+ material->mNormalTexture = normal_tex;
+ }
+ else
+ {
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = LLUUID::null;
+ material->mNormalTexture = nullptr;
+ }
+
+ if (mr_tex)
+ {
+ mr_tex->addTextureStats(64.f * 64.f, TRUE);
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = mr_tex->getID();
+ material->mMetallicRoughnessTexture = mr_tex;
+ }
+ else
+ {
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = LLUUID::null;
+ material->mMetallicRoughnessTexture = nullptr;
+ }
+
+ if (emissive_tex)
+ {
+ emissive_tex->addTextureStats(64.f * 64.f, TRUE);
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = emissive_tex->getID();
+ material->mEmissiveTexture = emissive_tex;
+ }
+ else
+ {
+ material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = LLUUID::null;
+ material->mEmissiveTexture = nullptr;
+ }
+
+ return true;
+}
diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h
new file mode 100644
index 0000000000..256f6c854f
--- /dev/null
+++ b/indra/newview/lltinygltfhelper.h
@@ -0,0 +1,66 @@
+/**
+ * @file lltinygltfhelper.h
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2022, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+
+#pragma once
+
+#include "llgltfmaterial.h"
+#include "llgltfmateriallist.h"
+#include "llpointer.h"
+#include "tinygltf/tiny_gltf.h"
+
+class LLImageRaw;
+class LLViewerFetchedTexture;
+
+namespace LLTinyGLTFHelper
+{
+ LLColor4 getColor(const std::vector<double>& in);
+ const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name);
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
+
+ LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index);
+
+ bool loadModel(const std::string& filename, tinygltf::Model& model_out);
+
+ bool getMaterialFromModel(
+ const std::string& filename,
+ const tinygltf::Model& model,
+ S32 mat_index,
+ LLFetchedGLTFMaterial* material,
+ std::string& material_name);
+
+ void initFetchedTextures(tinygltf::Material& material,
+ LLPointer<LLImageRaw>& base_color_img,
+ LLPointer<LLImageRaw>& normal_img,
+ LLPointer<LLImageRaw>& mr_img,
+ LLPointer<LLImageRaw>& emissive_img,
+ LLPointer<LLImageRaw>& occlusion_img,
+ LLPointer<LLViewerFetchedTexture>& base_color_tex,
+ LLPointer<LLViewerFetchedTexture>& normal_tex,
+ LLPointer<LLViewerFetchedTexture>& mr_tex,
+ LLPointer<LLViewerFetchedTexture>& emissive_tex);
+}
+
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index d35833fac9..8bf078477a 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -295,7 +295,8 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
mLineEditor->setText(edit_text_contents);
std::string notif_name = mNotification->getName();
- if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) || ("CreateSubfolder" == notif_name))
+ if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name) ||
+ ("CreateSubfolder" == notif_name) || ("SaveMaterialAs" == notif_name))
{
mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
}
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 6d54a3770c..aaf2bacc7b 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -268,7 +268,8 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask)
BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask)
{
mMouseDown = TRUE;
- gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build"));
+ gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ FALSE, LLFloaterReg::instanceVisible("build"), FALSE,
+ gSavedSettings.getBOOL("SelectReflectionProbes"));;
return TRUE;
}
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 78e068f808..e7f96239fd 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -40,6 +40,7 @@
#include "llfloatertools.h"
#include "llgesturemgr.h"
#include "llgiveinventory.h"
+#include "llgltfmateriallist.h"
#include "llhudmanager.h"
#include "llhudeffecttrail.h"
#include "llimview.h"
@@ -257,7 +258,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
// |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------|
addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL));
- addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL));
+ addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL));
@@ -272,6 +274,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary()
addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL));
addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL));
+
// TODO: animation on self could play it? edit it?
// TODO: gesture on self could play it? edit it?
};
@@ -922,17 +925,19 @@ void LLToolDragAndDrop::pick(const LLPickInfo& pick_info)
}
// static
-BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
+BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id)
{
+ if (!item) return FALSE;
+
// Always succeed if....
- // texture is from the library
+ // material is from the library
// or already in the contents of the object
if (SOURCE_LIBRARY == source)
{
- // dropping a texture from the library always just works.
+ // dropping a material from the library always just works.
return TRUE;
}
@@ -945,33 +950,40 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
{
hit_obj->requestInventory();
LLSD args;
- args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
+ if (LLAssetType::AT_MATERIAL == item->getType())
+ {
+ args["ERROR_MESSAGE"] = "Unable to add material.\nPlease wait a few seconds and try again.";
+ }
+ else
+ {
+ args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
+ }
LLNotificationsUtil::add("ErrorMessage", args);
return FALSE;
}
- if (hit_obj->getInventoryItemByAsset(item->getAssetUUID()))
+ // Make sure to verify both id and type since 'null'
+ // is a shared default for some asset types.
+ if (hit_obj->getInventoryItemByAsset(item->getAssetUUID(), item->getType()))
{
// if the asset is already in the object's inventory
// then it can always be added to a side.
// This saves some work if the task's inventory is already loaded
- // and ensures that the texture item is only added once.
+ // and ensures that the asset item is only added once.
return TRUE;
}
-
- if (!item) return FALSE;
LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
if (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
{
- // Check that we can add the texture as inventory to the object
+ // Check that we can add the material as inventory to the object
if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
{
return FALSE;
}
- // make sure the object has the texture in it's inventory.
+ // make sure the object has the material in it's inventory.
if (SOURCE_AGENT == source)
{
- // Remove the texture from local inventory. The server
+ // Remove the material from local inventory. The server
// will actually remove the item from agent inventory.
gInventory.deleteObject(item->getUUID());
gInventory.notifyObservers();
@@ -992,38 +1004,64 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
return FALSE;
}
}
- // Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
- {
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
- }
+ // Add the asset item to the target object's inventory.
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
+ {
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ }
else
{
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
- // TODO: Check to see if adding the item was successful; if not, then
- // we should return false here.
+ // Force the object to update and refetch its inventory so it has this asset.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
}
else if (!item->getPermissions().allowOperationBy(PERM_TRANSFER,
gAgent.getID()))
{
- // Check that we can add the texture as inventory to the object
+ // Check that we can add the asset as inventory to the object
if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
{
return FALSE;
}
// *FIX: may want to make sure agent can paint hit_obj.
- // Add the texture item to the target object's inventory.
- if (LLAssetType::AT_TEXTURE == new_item->getType())
+ // Add the asset item to the target object's inventory.
+ if (LLAssetType::AT_TEXTURE == new_item->getType()
+ || LLAssetType::AT_MATERIAL == new_item->getType())
{
- hit_obj->updateTextureInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
else
{
hit_obj->updateInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
}
- // Force the object to update and refetch its inventory so it has this texture.
+ // Force the object to update and refetch its inventory so it has this asset.
+ hit_obj->dirtyInventory();
+ hit_obj->requestInventory();
+ // TODO: Check to see if adding the item was successful; if not, then
+ // we should return false here. This will requre a separate listener
+ // since without listener, we have no way to receive update
+ }
+ else if (LLAssetType::AT_MATERIAL == new_item->getType() &&
+ !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+ {
+ // Check that we can add the material as inventory to the object
+ if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE )
+ {
+ return FALSE;
+ }
+ // *FIX: may want to make sure agent can paint hit_obj.
+
+ // Add the material item to the target object's inventory.
+ hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true);
+
+ // Force the object to update and refetch its inventory so it has this material.
hit_obj->dirtyInventory();
hit_obj->requestInventory();
// TODO: Check to see if adding the item was successful; if not, then
@@ -1043,26 +1081,161 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no texture item." << LL_ENDL;
return;
}
+ S32 num_faces = hit_obj->getNumTEs();
+ bool has_non_pbr_faces = false;
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ if (hit_obj->getRenderMaterialID(face).isNull())
+ {
+ has_non_pbr_faces = true;
+ break;
+ }
+ }
+ if (!has_non_pbr_faces)
+ {
+ return;
+ }
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
}
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
add(LLStatViewer::EDIT_TEXTURE, 1);
- S32 num_faces = hit_obj->getNumTEs();
for( S32 face = 0; face < num_faces; face++ )
{
-
- // update viewer side image in anticipation of update from simulator
- hit_obj->setTEImage(face, image);
- dialog_refresh_all();
+ if (hit_obj->getRenderMaterialID(face).isNull())
+ {
+ // update viewer side image in anticipation of update from simulator
+ hit_obj->setTEImage(face, image);
+ dialog_refresh_all();
+ }
}
// send the update to the simulator
hit_obj->sendTEUpdate();
}
+void LLToolDragAndDrop::dropMaterial(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id,
+ bool all_faces)
+{
+ LLSelectNode* nodep = nullptr;
+ if (hit_obj->isSelected())
+ {
+ // update object's saved materials
+ nodep = LLSelectMgr::getInstance()->getSelection()->findNode(hit_obj);
+ }
+
+ // If user dropped a material onto face it implies
+ // applying texture now without cancel, save to selection
+ if (all_faces)
+ {
+ dropMaterialAllFaces(hit_obj, item, source, src_id);
+
+ if (nodep)
+ {
+ uuid_vec_t material_ids;
+ gltf_materials_vec_t override_materials;
+ S32 num_faces = hit_obj->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ material_ids.push_back(hit_obj->getRenderMaterialID(face));
+ override_materials.push_back(nullptr);
+ }
+ nodep->saveGLTFMaterials(material_ids, override_materials);
+ }
+ }
+ else
+ {
+ dropMaterialOneFace(hit_obj, hit_face, item, source, src_id);
+
+ // If user dropped a material onto face it implies
+ // applying texture now without cancel, save to selection
+ if (nodep
+ && gFloaterTools->getVisible()
+ && nodep->mSavedGLTFMaterialIds.size() > hit_face)
+ {
+ nodep->mSavedGLTFMaterialIds[hit_face] = hit_obj->getRenderMaterialID(hit_face);
+ nodep->mSavedGLTFOverrideMaterials[hit_face] = nullptr;
+ }
+ }
+}
+
+void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (hit_face == -1) return;
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL;
+ return;
+ }
+
+ // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance
+ // may be deleted if it is moved into task inventory
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+ if (!success)
+ {
+ return;
+ }
+
+ if (asset_id.isNull())
+ {
+ // use blank material
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
+ hit_obj->setRenderMaterialID(hit_face, asset_id);
+
+ dialog_refresh_all();
+
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
+void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ LLToolDragAndDrop::ESource source,
+ const LLUUID& src_id)
+{
+ if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL)
+ {
+ LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL;
+ return;
+ }
+
+ // SL-20013 must save asset_id before handleDropMaterialProtections since our item instance
+ // may be deleted if it is moved into task inventory
+ LLUUID asset_id = item->getAssetUUID();
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
+
+ if (!success)
+ {
+ return;
+ }
+
+ if (asset_id.isNull())
+ {
+ // use blank material
+ asset_id = LLGLTFMaterialList::BLANK_MATERIAL_ASSET_ID;
+ }
+
+ hit_obj->setRenderMaterialIDs(asset_id);
+ dialog_refresh_all();
+ // send the update to the simulator
+ hit_obj->sendTEUpdate();
+}
+
+
void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
@@ -1074,7 +1247,7 @@ void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj,
return;
}
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if(!success)
{
return;
@@ -1096,6 +1269,71 @@ void LLToolDragAndDrop::dropTextureOneFaceAvatar(LLVOAvatar* avatar, S32 hit_fac
avatar->userSetOptionalTE( hit_face, image);
}
*/
+void LLToolDragAndDrop::dropTexture(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id,
+ bool all_faces,
+ S32 tex_channel)
+{
+ LLSelectNode* nodep = nullptr;
+ if (hit_obj->isSelected())
+ {
+ // update object's saved textures
+ nodep = LLSelectMgr::getInstance()->getSelection()->findNode(hit_obj);
+ }
+
+ if (all_faces)
+ {
+ dropTextureAllFaces(hit_obj, item, source, src_id);
+
+ // If user dropped a texture onto face it implies
+ // applying texture now without cancel, save to selection
+ if (nodep)
+ {
+ uuid_vec_t texture_ids;
+ S32 num_faces = hit_obj->getNumTEs();
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ LLViewerTexture* tex = hit_obj->getTEImage(face);
+ if (tex != nullptr)
+ {
+ texture_ids.push_back(tex->getID());
+ }
+ else
+ {
+ texture_ids.push_back(LLUUID::null);
+ }
+ }
+ nodep->saveTextures(texture_ids);
+ }
+ }
+ else
+ {
+ dropTextureOneFace(hit_obj, hit_face, item, source, src_id);
+
+ // If user dropped a texture onto face it implies
+ // applying texture now without cancel, save to selection
+ LLPanelFace* panel_face = gFloaterTools->getPanelFace();
+ if (nodep
+ && gFloaterTools->getVisible()
+ && panel_face
+ && panel_face->getTextureDropChannel() == 0 /*texture*/
+ && nodep->mSavedTextures.size() > hit_face)
+ {
+ LLViewerTexture* tex = hit_obj->getTEImage(hit_face);
+ if (tex != nullptr)
+ {
+ nodep->mSavedTextures[hit_face] = tex->getID();
+ }
+ else
+ {
+ nodep->mSavedTextures[hit_face] = LLUUID::null;
+ }
+ }
+ }
+}
void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
S32 hit_face,
@@ -1110,8 +1348,12 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no texture item." << LL_ENDL;
return;
}
+ if (hit_obj->getRenderMaterialID(hit_face).notNull())
+ {
+ return;
+ }
LLUUID asset_id = item->getAssetUUID();
- BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id);
+ BOOL success = handleDropMaterialProtections(hit_obj, item, source, src_id);
if (!success)
{
return;
@@ -1126,7 +1368,7 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
if (gFloaterTools->getVisible() && panel_face)
{
- tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel();
+ tex_channel = (tex_channel > -1) ? tex_channel : panel_face->getTextureDropChannel();
switch (tex_channel)
{
@@ -1521,6 +1763,8 @@ EAcceptance LLToolDragAndDrop::willObjectAcceptInventory(LLViewerObject* obj, LL
BOOL unrestricted = ((perm.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED) ? TRUE : FALSE;
if(attached && !unrestricted)
{
+ // Attachments are in world and in inventory simultaneously,
+ // at the moment server doesn't support such a situation.
return ACCEPT_NO_LOCKED;
}
else if(modify && transfer && volume && !worn)
@@ -1633,6 +1877,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
case DAD_MESH:
case DAD_CATEGORY:
case DAD_SETTINGS:
+ case DAD_MATERIAL:
{
LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data;
if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID())
@@ -1968,25 +2213,80 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject(
{
return ACCEPT_NO_LOCKED;
}
- //If texture !copyable don't texture or you'll never get it back.
- if(!item->getPermissions().allowCopyBy(gAgent.getID()))
- {
- return ACCEPT_NO;
- }
+
+ if (cargo_type == DAD_TEXTURE)
+ {
+ if ((mask & MASK_SHIFT))
+ {
+ S32 num_faces = obj->getNumTEs();
+ bool has_non_pbr_faces = false;
+ for (S32 face = 0; face < num_faces; face++)
+ {
+ if (obj->getRenderMaterialID(face).isNull())
+ {
+ has_non_pbr_faces = true;
+ break;
+ }
+ }
+ if (!has_non_pbr_faces)
+ {
+ return ACCEPT_NO;
+ }
+ }
+ else if (obj->getRenderMaterialID(face).notNull())
+ {
+ return ACCEPT_NO;
+ }
+ }
if(drop && (ACCEPT_YES_SINGLE <= rv))
{
if (cargo_type == DAD_TEXTURE)
{
- if((mask & MASK_SHIFT))
- {
- dropTextureAllFaces(obj, item, mSource, mSourceID);
- }
- else
- {
- dropTextureOneFace(obj, face, item, mSource, mSourceID);
- }
- }
+ bool all_faces = mask & MASK_SHIFT;
+ if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ dropTexture(obj, face, item, mSource, mSourceID, all_faces);
+ }
+ else
+ {
+ ESource source = mSource;
+ LLUUID source_id = mSourceID;
+ LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces](const LLSD& notification, const LLSD& response)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
+ dropTexture(obj, face, item, source, source_id, all_faces);
+ });
+ }
+ }
+ else if (cargo_type == DAD_MATERIAL)
+ {
+ bool all_faces = mask & MASK_SHIFT;
+ if (item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()))
+ {
+ dropMaterial(obj, face, item, mSource, mSourceID, all_faces);
+ }
+ else
+ {
+ ESource source = mSource;
+ LLUUID source_id = mSourceID;
+ LLNotificationsUtil::add("ApplyInventoryToObject", LLSD(), LLSD(), [obj, face, item, source, source_id, all_faces](const LLSD& notification, const LLSD& response)
+ {
+ S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+ // if Cancel pressed
+ if (option == 1)
+ {
+ return;
+ }
+ dropMaterial(obj, face, item, source, source_id, all_faces);
+ });
+ }
+ }
else if (cargo_type == DAD_MESH)
{
dropMesh(obj, item, mSource, mSourceID);
@@ -2015,6 +2315,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject(
return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE);
}
+EAcceptance LLToolDragAndDrop::dad3dMaterialObject(
+ LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
+{
+ return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL);
+}
+
EAcceptance LLToolDragAndDrop::dad3dMeshObject(
LLViewerObject* obj, S32 face, MASK mask, BOOL drop)
{
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 4537d73332..7bdd2d1a49 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -94,7 +94,7 @@ public:
// deal with permissions of object, etc. returns TRUE if drop can
// proceed, otherwise FALSE.
- static BOOL handleDropTextureProtections(LLViewerObject* hit_obj,
+ static BOOL handleDropMaterialProtections(LLViewerObject* hit_obj,
LLInventoryItem* item,
LLToolDragAndDrop::ESource source,
const LLUUID& src_id);
@@ -168,6 +168,8 @@ protected:
MASK mask, BOOL drop);
EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
+ EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face,
+ MASK mask, BOOL drop);
EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face,
MASK mask, BOOL drop);
// EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face,
@@ -241,7 +243,15 @@ public:
BOOL active,
ESource source,
const LLUUID& src_id);
- static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face,
+ static void dropTexture(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id,
+ bool all_faces,
+ S32 tex_channel = -1);
+ static void dropTextureOneFace(LLViewerObject* hit_obj,
+ S32 hit_face,
LLInventoryItem* item,
ESource source,
const LLUUID& src_id,
@@ -250,6 +260,21 @@ public:
LLInventoryItem* item,
ESource source,
const LLUUID& src_id);
+ static void dropMaterial(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id,
+ bool all_faces);
+ static void dropMaterialOneFace(LLViewerObject* hit_obj,
+ S32 hit_face,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
+ static void dropMaterialAllFaces(LLViewerObject* hit_obj,
+ LLInventoryItem* item,
+ ESource source,
+ const LLUUID& src_id);
static void dropMesh(LLViewerObject* hit_obj,
LLInventoryItem* item,
ESource source,
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index 58011bbde2..83a707472e 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -114,7 +114,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseDownY = y;
LLTimer pick_timer;
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged);
+ LLPickInfo transparent_pick = gViewerWindow->pickImmediate(x, y, TRUE /*includes transparent*/, pick_rigged, FALSE, TRUE, FALSE);
LLPickInfo visible_pick = gViewerWindow->pickImmediate(x, y, FALSE, pick_rigged);
LLViewerObject *transp_object = transparent_pick.getObject();
LLViewerObject *visible_object = visible_pick.getObject();
@@ -128,11 +128,9 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
// left mouse down always picks transparent (but see handleMouseUp).
// Also see LLToolPie::handleHover() - priorities are a bit different there.
// Todo: we need a more consistent set of rules to work with
- if (transp_object == visible_object || !visible_object)
+ if (transp_object == visible_object || !visible_object ||
+ !transp_object) // avoid potential for null dereference below, don't make assumptions about behavior of pickImmediate
{
- // Note: if transparent object is null, then visible object is also null
- // since transparent pick includes non-tranpsarent one.
- // !transparent_object check will be covered by transparent_object == visible_object.
mPick = transparent_pick;
}
else
@@ -183,11 +181,15 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
// an item.
BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
{
+ BOOL pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
+
// don't pick transparent so users can't "pay" transparent objects
mPick = gViewerWindow->pickImmediate(x, y,
/*BOOL pick_transparent*/ FALSE,
/*BOOL pick_rigged*/ TRUE,
- /*BOOL pick_particle*/ TRUE);
+ /*BOOL pick_particle*/ TRUE,
+ /*BOOL pick_unselectable*/ TRUE,
+ pick_reflection_probe);
mPick.mKeyMask = mask;
// claim not handled so UI focus stays same
@@ -643,7 +645,6 @@ bool LLToolPie::walkToClickedLocation()
mPick = saved_pick;
return false;
}
- return true;
}
bool LLToolPie::teleportToClickedLocation()
@@ -747,18 +748,8 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
parent = object->getRootEdit();
}
- // Show screen-space highlight glow effect
- bool show_highlight = false;
-
- if (handleMediaHover(mHoverPick))
- {
- // *NOTE: If you think the hover glow conflicts with the media outline, you
- // could disable it here.
- show_highlight = true;
- // cursor set by media object
- LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
- }
- else if (!mMouseOutsideSlop
+ if (!handleMediaHover(mHoverPick)
+ && !mMouseOutsideSlop
&& mMouseButtonDown
// disable camera steering if click on land is not used for moving
&& gViewerInput.isMouseBindUsed(CLICK_LEFT, MASK_NONE, MODE_THIRD_PERSON))
@@ -791,7 +782,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
if (click_action_object && useClickAction(mask, click_action_object, click_action_object->getRootEdit()))
{
- show_highlight = true;
ECursorType cursor = cursorFromObject(click_action_object);
gViewerWindow->setCursor(cursor);
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
@@ -800,7 +790,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
else if ((object && !object->isAvatar() && object->flagUsePhysics())
|| (parent && !parent->isAvatar() && parent->flagUsePhysics()))
{
- show_highlight = true;
gViewerWindow->setCursor(UI_CURSOR_TOOLGRAB);
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
}
@@ -808,7 +797,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
&& ((object && object->flagHandleTouch()) || (parent && parent->flagHandleTouch()))
&& (!object || !object->isAvatar()))
{
- show_highlight = true;
gViewerWindow->setCursor(UI_CURSOR_HAND);
LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
}
@@ -824,15 +812,6 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
LLViewerMediaFocus::getInstance()->clearHover();
}
- static LLCachedControl<bool> enable_highlight(
- gSavedSettings, "RenderHoverGlowEnable", false);
- LLDrawable* drawable = NULL;
- if (enable_highlight && show_highlight && object)
- {
- drawable = object->mDrawable;
- }
- gPipeline.setHighlightObject(drawable);
-
return TRUE;
}
diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp
index e52bc0b015..f7455c6cb8 100644
--- a/indra/newview/lltoolselect.cpp
+++ b/indra/newview/lltoolselect.cpp
@@ -65,7 +65,10 @@ BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask)
{
// do immediate pick query
BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick");
- mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged);
+ BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects");
+ BOOL pick_reflection_probe = gSavedSettings.getBOOL("SelectReflectionProbes");
+
+ mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged, FALSE, TRUE, pick_reflection_probe);
// Pass mousedown to agent
LLTool::handleMouseDown(x, y, mask);
@@ -84,13 +87,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi
}
BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly");
BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly");
-
- // *NOTE: These settings must be cleaned up at bottom of function.
+
+ // *NOTE: These settings must be cleaned up at bottom of function.
if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar)
{
gSavedSettings.setBOOL("SelectOwnedOnly", FALSE);
gSavedSettings.setBOOL("SelectMovableOnly", FALSE);
- LLSelectMgr::getInstance()->setForceSelection(TRUE);
+ LLSelectMgr::getInstance()->setForceSelection(TRUE);
}
BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL);
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index ab4ad5817b..4c55ea1fc6 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -588,7 +588,7 @@ void LLTracker::renderBeacon(LLVector3d pos_global,
LLVector3 pos_agent = gAgent.getPosAgentFromGlobal(pos_global);
- LLGLSTracker gls_tracker; // default+ CULL_FACE + LIGHTING + GL_BLEND + GL_ALPHA_TEST
+ LLGLSTracker gls_tracker;
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDisable cull_face(GL_CULL_FACE);
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index 4804ef6ddc..481086f760 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -88,6 +88,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE));
addEntry(LLViewerAssetType::AT_SETTINGS, new ViewerAssetEntry(DAD_SETTINGS));
+ addEntry(LLViewerAssetType::AT_MATERIAL, new ViewerAssetEntry(DAD_MATERIAL));
};
EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type)
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 13491114b9..a2b0b04092 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -34,7 +34,6 @@
#include "lluuid.h"
#include "llvorbisencode.h"
#include "lluploaddialog.h"
-#include "llpreviewscript.h"
#include "llnotificationsutil.h"
#include "llagent.h"
#include "llfloaterreg.h"
@@ -554,7 +553,80 @@ LLSD LLNewFileResourceUploadInfo::exportTempFile()
}
//=========================================================================
-LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish) :
+LLNewBufferedResourceUploadInfo::LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish,
+ uploadFailure_f failure)
+ : LLResourceUploadInfo(name, description, compressionInfo,
+ destinationType, inventoryType,
+ nextOWnerPerms, groupPerms, everyonePerms, expectedCost, show_inventory)
+ , mBuffer(buffer)
+ , mFinishFn(finish)
+ , mFailureFn(failure)
+{
+ setAssetType(assetType);
+ setAssetId(asset_id);
+}
+
+LLSD LLNewBufferedResourceUploadInfo::prepareUpload()
+{
+ if (getAssetId().isNull())
+ generateNewAssetId();
+
+ LLSD result = exportTempFile();
+ if (result.has("error"))
+ return result;
+
+ return LLResourceUploadInfo::prepareUpload();
+}
+
+LLSD LLNewBufferedResourceUploadInfo::exportTempFile()
+{
+ std::string filename = gDirUtilp->getTempFilename();
+
+ // copy buffer to the cache for upload
+ LLFileSystem file(getAssetId(), getAssetType(), LLFileSystem::APPEND);
+ file.write((U8*) mBuffer.c_str(), mBuffer.size());
+
+ return LLSD();
+}
+
+LLUUID LLNewBufferedResourceUploadInfo::finishUpload(LLSD &result)
+{
+ LLUUID newItemId = LLResourceUploadInfo::finishUpload(result);
+
+ if (mFinishFn)
+ {
+ mFinishFn(result["new_asset"].asUUID(), result);
+ }
+
+ return newItemId;
+}
+
+bool LLNewBufferedResourceUploadInfo::failedUpload(LLSD &result, std::string &reason)
+{
+ if (mFailureFn)
+ {
+ return mFailureFn(getAssetId(), result, reason);
+ }
+
+ return false; // Not handled
+}
+
+//=========================================================================
+LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed) :
LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
0, 0, 0, 0),
mTaskUpload(false),
@@ -562,6 +634,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType:
mContents(buffer),
mInvnFinishFn(finish),
mTaskFinishFn(nullptr),
+ mFailureFn(failed),
mStoredToCache(false)
{
setItemId(itemId);
@@ -576,6 +649,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL
mContents(),
mInvnFinishFn(finish),
mTaskFinishFn(nullptr),
+ mFailureFn(nullptr),
mStoredToCache(false)
{
setItemId(itemId);
@@ -602,7 +676,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LL
mContents.assign((char *)image->getData(), imageSize);
}
-LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish) :
+LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish, uploadFailed_f failed) :
LLResourceUploadInfo(std::string(), std::string(), 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
0, 0, 0, 0),
mTaskUpload(true),
@@ -610,6 +684,7 @@ LLBufferedAssetUploadInfo::LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemI
mContents(buffer),
mInvnFinishFn(nullptr),
mTaskFinishFn(finish),
+ mFailureFn(failed),
mStoredToCache(false)
{
setItemId(itemId);
@@ -699,10 +774,19 @@ LLUUID LLBufferedAssetUploadInfo::finishUpload(LLSD &result)
return newAssetId;
}
+bool LLBufferedAssetUploadInfo::failedUpload(LLSD &result, std::string &reason)
+{
+ if (mFailureFn)
+ {
+ return mFailureFn(getItemId(), getTaskId(), result, reason);
+ }
+ return false;
+}
+
//=========================================================================
-LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish):
- LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish),
+LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed):
+ LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish, failed),
mExerienceId(),
mTargetType(MONO),
mIsRunning(false)
@@ -710,8 +794,8 @@ LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invn
}
LLScriptAssetUpload::LLScriptAssetUpload(LLUUID taskId, LLUUID itemId, TargetType_t targetType,
- bool isRunning, LLUUID exerienceId, std::string buffer, taskUploadFinish_f finish):
- LLBufferedAssetUploadInfo(taskId, itemId, LLAssetType::AT_LSL_TEXT, buffer, finish),
+ bool isRunning, LLUUID exerienceId, std::string buffer, taskUploadFinish_f finish, uploadFailed_f failed):
+ LLBufferedAssetUploadInfo(taskId, itemId, LLAssetType::AT_LSL_TEXT, buffer, finish, failed),
mExerienceId(exerienceId),
mTargetType(targetType),
mIsRunning(isRunning)
@@ -920,19 +1004,15 @@ void LLViewerAssetUpload::HandleUploadError(LLCore::HttpStatus status, LLSD &res
LLNotificationsUtil::add(label, args);
- // unfreeze script preview
- if (uploadInfo->getAssetType() == LLAssetType::AT_LSL_TEXT)
+ if (uploadInfo->failedUpload(result, reason))
{
- LLPreviewLSL* preview = LLFloaterReg::findTypedInstance<LLPreviewLSL>("preview_script",
- uploadInfo->getItemId());
- if (preview)
- {
- LLSD errors;
- errors.append(LLTrans::getString("UploadFailed") + reason);
- preview->callbackLSLCompileFailed(errors);
- }
+ // no further action required, already handled by a callback
+ // ex: do not trigger snapshot floater when failing material texture
+ return;
}
+ // Todo: move these floater specific actions into proper callbacks
+
// Let the Snapshot floater know we have failed uploading.
LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
if (floater_snapshot && floater_snapshot->isWaitingState())
diff --git a/indra/newview/llviewerassetupload.h b/indra/newview/llviewerassetupload.h
index e56ba7d8f7..7f7707f5bb 100644
--- a/indra/newview/llviewerassetupload.h
+++ b/indra/newview/llviewerassetupload.h
@@ -64,6 +64,9 @@ public:
virtual void logPreparedUpload();
virtual LLUUID finishUpload(LLSD &result);
+ // return true if no further action is need
+ virtual bool failedUpload(LLSD &result, std::string &reason) { return false; }
+
LLTransactionID getTransactionId() const { return mTransactionId; }
LLAssetType::EType getAssetType() const { return mAssetType; }
std::string getAssetTypeString() const;
@@ -168,19 +171,60 @@ private:
};
//-------------------------------------------------------------------------
+// use when you have a resource in memory and you want to make a new inventory item
+class LLNewBufferedResourceUploadInfo : public LLResourceUploadInfo
+{
+public:
+ typedef std::function<void(LLUUID newAssetId, LLSD response)> uploadFinish_f;
+ typedef std::function<bool(LLUUID assetId, LLSD response, std::string reason)> uploadFailure_f;
+
+ LLNewBufferedResourceUploadInfo(
+ const std::string& buffer,
+ const LLAssetID& asset_id,
+ std::string name,
+ std::string description,
+ S32 compressionInfo,
+ LLFolderType::EType destinationType,
+ LLInventoryType::EType inventoryType,
+ LLAssetType::EType assetType,
+ U32 nextOWnerPerms,
+ U32 groupPerms,
+ U32 everyonePerms,
+ S32 expectedCost,
+ bool show_inventory,
+ uploadFinish_f finish,
+ uploadFailure_f failure);
+
+ virtual LLSD prepareUpload();
+
+protected:
+
+ virtual LLSD exportTempFile();
+ virtual LLUUID finishUpload(LLSD &result);
+ virtual bool failedUpload(LLSD &result, std::string &reason);
+
+private:
+ uploadFinish_f mFinishFn;
+ uploadFailure_f mFailureFn;
+ std::string mBuffer;
+};
+
+//-------------------------------------------------------------------------
class LLBufferedAssetUploadInfo : public LLResourceUploadInfo
{
public:
typedef std::function<void(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD response)> invnUploadFinish_f;
typedef std::function<void(LLUUID itemId, LLUUID taskId, LLUUID newAssetId, LLSD response)> taskUploadFinish_f;
+ typedef std::function<bool(LLUUID itemId, LLUUID taskId, LLSD response, std::string reason)> uploadFailed_f;
- LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish);
+ LLBufferedAssetUploadInfo(LLUUID itemId, LLAssetType::EType assetType, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed);
LLBufferedAssetUploadInfo(LLUUID itemId, LLPointer<LLImageFormatted> image, invnUploadFinish_f finish);
- LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish);
+ LLBufferedAssetUploadInfo(LLUUID taskId, LLUUID itemId, LLAssetType::EType assetType, std::string buffer, taskUploadFinish_f finish, uploadFailed_f failed);
virtual LLSD prepareUpload();
virtual LLSD generatePostBody();
virtual LLUUID finishUpload(LLSD &result);
+ virtual bool failedUpload(LLSD &result, std::string &reason);
LLUUID getTaskId() const { return mTaskId; }
const std::string & getContents() const { return mContents; }
@@ -197,6 +241,7 @@ private:
std::string mContents;
invnUploadFinish_f mInvnFinishFn;
taskUploadFinish_f mTaskFinishFn;
+ uploadFailed_f mFailureFn;
bool mStoredToCache;
};
@@ -210,9 +255,9 @@ public:
MONO
};
- LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish);
+ LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed);
LLScriptAssetUpload(LLUUID taskId, LLUUID itemId, TargetType_t targetType,
- bool isRunning, LLUUID exerienceId, std::string buffer, taskUploadFinish_f finish);
+ bool isRunning, LLUUID exerienceId, std::string buffer, taskUploadFinish_f finish, uploadFailed_f failed);
virtual LLSD generatePostBody();
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 5d8e80cc41..b37f08283d 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -819,9 +819,13 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
return all_verts;
}
+extern BOOL gCubeSnapshot;
+
// changes local camera and broadcasts change
/* virtual */ void LLViewerCamera::setView(F32 vertical_fov_rads)
{
+ llassert(!gCubeSnapshot);
+
F32 old_fov = LLViewerCamera::getInstance()->getView();
// cap the FoV
@@ -847,6 +851,11 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
LLCamera::setView(vertical_fov_rads); // call base implementation
}
+void LLViewerCamera::setViewNoBroadcast(F32 vertical_fov_rads)
+{
+ LLCamera::setView(vertical_fov_rads);
+}
+
void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
{
vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 549778a841..78ca2b3076 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -47,15 +47,14 @@ public:
typedef enum
{
CAMERA_WORLD = 0,
- CAMERA_SHADOW0,
- CAMERA_SHADOW1,
- CAMERA_SHADOW2,
- CAMERA_SHADOW3,
- CAMERA_SHADOW4,
- CAMERA_SHADOW5,
+ CAMERA_SUN_SHADOW0,
+ CAMERA_SUN_SHADOW1,
+ CAMERA_SUN_SHADOW2,
+ CAMERA_SUN_SHADOW3,
+ CAMERA_SPOT_SHADOW0,
+ CAMERA_SPOT_SHADOW1,
CAMERA_WATER0,
CAMERA_WATER1,
- CAMERA_GI_SOURCE,
NUM_CAMERAS
} eCameraID;
@@ -88,8 +87,8 @@ public:
LLVector3 roundToPixel(const LLVector3 &pos_agent);
// Sets the current matrix
- /* virtual */ void setView(F32 vertical_fov_rads);
-
+ /* virtual */ void setView(F32 vertical_fov_rads); // NOTE: broadcasts to simulator
+ void setViewNoBroadcast(F32 vertical_fov_rads); // set FOV without broadcasting to simulator (for temporary local cameras)
void setDefaultFOV(F32 fov) ;
F32 getDefaultFOV() { return mCameraFOVDefault; }
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 50d48987ed..7738cb904e 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -51,7 +51,6 @@
#include "llviewerwindow.h"
#include "llvoavatarself.h"
#include "llvoiceclient.h"
-#include "llvosky.h"
#include "llvotree.h"
#include "llvovolume.h"
#include "llworld.h"
@@ -151,15 +150,7 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
if (gPipeline.isInit())
{
// ALM depends onto atmospheric shaders, state might have changed
- bool old_state = LLPipeline::sRenderDeferred;
LLPipeline::refreshCachedSettings();
- gPipeline.updateRenderDeferred();
- if (old_state != LLPipeline::sRenderDeferred)
- {
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- gPipeline.resetVertexBuffers();
- }
}
// else, leave terrain detail as is
@@ -167,20 +158,13 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
return true;
}
-static bool handleShadowDetailChanged(const LLSD& newvalue)
-{
- gPipeline.handleShadowDetailChanged();
- return true;
-}
-
static bool handleRenderPerfTestChanged(const LLSD& newvalue)
{
bool status = !newvalue.asBoolean();
if (!status)
{
gPipeline.clearRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_GRASS,
LLPipeline::RENDER_TYPE_TREE,
LLPipeline::RENDER_TYPE_WATER,
@@ -194,7 +178,6 @@ static bool handleRenderPerfTestChanged(const LLSD& newvalue)
else
{
gPipeline.setRenderTypeMask(LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_GROUND,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_GRASS,
LLPipeline::RENDER_TYPE_TREE,
@@ -215,10 +198,8 @@ bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
if (gPipeline.isInit())
{
gPipeline.updateRenderTransparentWater();
- gPipeline.updateRenderDeferred();
gPipeline.releaseGLBuffers();
gPipeline.createGLBuffers();
- gPipeline.resetVertexBuffers();
LLViewerShaderMgr::instance()->setShaders();
}
LLWorld::getInstance()->updateWaterObjects();
@@ -355,12 +336,6 @@ static bool handleMaxPartCountChanged(const LLSD& newvalue)
return true;
}
-static bool handleVideoMemoryChanged(const LLSD& newvalue)
-{
- gTextureList.updateMaxResidentTexMem(S32Megabytes(newvalue.asInteger()));
- return true;
-}
-
static bool handleChatFontSizeChanged(const LLSD& newvalue)
{
if(gConsole)
@@ -401,7 +376,7 @@ static bool handleJoystickChanged(const LLSD& newvalue)
static bool handleUseOcclusionChanged(const LLSD& newvalue)
{
- LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery
+ LLPipeline::sUseOcclusion = (newvalue.asBoolean()
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0;
return true;
}
@@ -422,15 +397,6 @@ static bool handleWLSkyDetailChanged(const LLSD&)
return true;
}
-static bool handleResetVertexBuffersChanged(const LLSD&)
-{
- if (gPipeline.isInit())
- {
- gPipeline.resetVertexBuffers();
- }
- return true;
-}
-
static bool handleRepartition(const LLSD&)
{
if (gPipeline.isInit())
@@ -448,47 +414,17 @@ static bool handleRenderDynamicLODChanged(const LLSD& newvalue)
return true;
}
-static bool handleRenderLocalLightsChanged(const LLSD& newvalue)
-{
- gPipeline.setLightingDetail(-1);
- return true;
-}
-
-static bool handleRenderDeferredChanged(const LLSD& newvalue)
+static bool handleReflectionProbeDetailChanged(const LLSD& newvalue)
{
- LLRenderTarget::sUseFBO = newvalue.asBoolean();
- if (gPipeline.isInit())
- {
- LLPipeline::refreshCachedSettings();
- gPipeline.updateRenderDeferred();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- gPipeline.resetVertexBuffers();
- if (LLPipeline::sRenderDeferred == (BOOL)LLRenderTarget::sUseFBO)
- {
- LLViewerShaderMgr::instance()->setShaders();
- }
- }
- return true;
-}
-
-// This looks a great deal like handleRenderDeferredChanged because
-// Advanced Lighting (Materials) implies bumps and shiny so disabling
-// bumps should further disable that feature.
-//
-static bool handleRenderBumpChanged(const LLSD& newval)
-{
- LLRenderTarget::sUseFBO = newval.asBoolean() && gSavedSettings.getBOOL("RenderDeferred");
- if (gPipeline.isInit())
- {
- gPipeline.updateRenderBump();
- gPipeline.updateRenderDeferred();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- gPipeline.resetVertexBuffers();
- LLViewerShaderMgr::instance()->setShaders();
- }
- return true;
+ if (gPipeline.isInit())
+ {
+ LLPipeline::refreshCachedSettings();
+ gPipeline.releaseGLBuffers();
+ gPipeline.createGLBuffers();
+ LLViewerShaderMgr::instance()->setShaders();
+ gPipeline.mReflectionMapManager.reset();
+ }
+ return true;
}
static bool handleRenderDebugPipelineChanged(const LLSD& newvalue)
@@ -650,8 +586,6 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
return true;
}
-void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
-
void handleTargetFPSChanged(const LLSD& newValue)
{
const auto targetFPS = gSavedSettings.getU32("TargetFPS");
@@ -696,12 +630,6 @@ void handleUserTargetDrawDistanceChanged(const LLSD& newValue)
LLPerfStats::tunables.userTargetDrawDistance = newval;
}
-void handleUserTargetReflectionsChanged(const LLSD& newValue)
-{
- const auto newval = gSavedSettings.getS32("UserTargetReflections");
- LLPerfStats::tunables.userTargetReflections = newval;
-}
-
void handlePerformanceStatsEnabledChanged(const LLSD& newValue)
{
const auto newval = gSavedSettings.getBOOL("PerfStatsCaptureEnabled");
@@ -763,10 +691,10 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "OctreeAlphaDistanceFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "OctreeAttachmentSizeFactor", handleRepartition);
setting_setup_signal_listener(gSavedSettings, "RenderMaxTextureIndex", handleSetShaderChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderUseTriStrips", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "RenderUIBuffer", handleWindowResized);
setting_setup_signal_listener(gSavedSettings, "RenderDepthOfField", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderFSAASamples", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderPostProcessingHDR", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResX", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularResY", handleLUTBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderSpecularExponent", handleLUTBufferChanged);
@@ -775,8 +703,8 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlow", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGlowResolutionPow", handleReleaseGLBufferChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderAvatarCloth", handleSetShaderChanged);
- setting_setup_signal_listener(gSavedSettings, "WindLightUseAtmosShaders", handleSetShaderChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowHDR", handleReleaseGLBufferChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderGlowNoise", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderGammaFull", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderVolumeLODFactor", handleVolumeLODChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarLODFactor", handleAvatarLODChanged);
@@ -788,21 +716,17 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "RenderFogRatio", handleFogRatioChanged);
setting_setup_signal_listener(gSavedSettings, "RenderMaxPartCount", handleMaxPartCountChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDynamicLOD", handleRenderDynamicLODChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderLocalLights", handleRenderLocalLightsChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderDebugTextureBind", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaDeferred", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderAutoMaskAlphaNonDeferred", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderObjectBump", handleRenderBumpChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderMaxVBOSize", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderVSyncEnable", handleVSyncChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredNoise", handleReleaseGLBufferChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDebugPipeline", handleRenderDebugPipelineChanged);
setting_setup_signal_listener(gSavedSettings, "RenderResolutionDivisor", handleRenderResolutionDivisorChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderDeferred", handleRenderDeferredChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleShadowDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeLevel", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderReflectionProbeDetail", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged);
+ setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged);
setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged);
- setting_setup_signal_listener(gSavedSettings, "TextureMemory", handleVideoMemoryChanged);
setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged);
setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged);
setting_setup_signal_listener(gSavedSettings, "ConsoleMaxLines", handleConsoleMaxLinesChanged);
@@ -824,11 +748,6 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "MuteVoice", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteAmbient", handleAudioVolumeChanged);
setting_setup_signal_listener(gSavedSettings, "MuteUI", handleAudioVolumeChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderVBOEnable", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderUseVAO", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderVBOMappingDisable", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderUseStreamVBO", handleResetVertexBuffersChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderPreferStreamDraw", handleResetVertexBuffersChanged);
setting_setup_signal_listener(gSavedSettings, "WLSkyDetail", handleWLSkyDetailChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis0", handleJoystickChanged);
setting_setup_signal_listener(gSavedSettings, "JoystickAxis1", handleJoystickChanged);
@@ -901,14 +820,12 @@ void settings_setup_listeners()
setting_setup_signal_listener(gSavedSettings, "SpellCheckDictionary", handleSpellCheckChanged);
setting_setup_signal_listener(gSavedSettings, "LoginLocation", handleLoginLocationChanged);
setting_setup_signal_listener(gSavedSettings, "DebugAvatarJoints", handleDebugAvatarJointsChanged);
- setting_setup_signal_listener(gSavedSettings, "RenderAutoMuteByteLimit", handleRenderAutoMuteByteLimitChanged);
setting_setup_signal_listener(gSavedSettings, "TargetFPS", handleTargetFPSChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneFPS", handleAutoTuneFPSChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneLock", handleAutoTuneLockChanged);
setting_setup_signal_listener(gSavedSettings, "RenderAvatarMaxART", handleRenderAvatarMaxARTChanged);
setting_setup_signal_listener(gSavedSettings, "PerfStatsCaptureEnabled", handlePerformanceStatsEnabledChanged);
- setting_setup_signal_listener(gSavedSettings, "UserTargetReflections", handleUserTargetReflectionsChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneRenderFarClipTarget", handleUserTargetDrawDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorFarAwayDistance", handleUserImpostorDistanceChanged);
setting_setup_signal_listener(gSavedSettings, "AutoTuneImpostorByDistEnabled", handleUserImpostorByDistEnabledChanged);
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index b40cf4acec..04ca62e0ec 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -31,6 +31,7 @@
#include "llgl.h"
#include "llrender.h"
#include "llglheaders.h"
+#include "llgltfmateriallist.h"
#include "llagent.h"
#include "llagentcamera.h"
#include "llviewercontrol.h"
@@ -98,6 +99,7 @@ BOOL gResizeScreenTexture = FALSE;
BOOL gResizeShadowTexture = FALSE;
BOOL gWindowResized = FALSE;
BOOL gSnapshot = FALSE;
+BOOL gCubeSnapshot = FALSE;
BOOL gShaderProfileFrame = FALSE;
// This is how long the sim will try to teleport you before giving up.
@@ -147,7 +149,6 @@ void display_startup()
static S32 frame_count = 0;
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
if (frame_count++ > 1) // make sure we have rendered a frame first
{
@@ -159,15 +160,13 @@ void display_startup()
}
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
LLGLSUIDefault gls_ui;
gPipeline.disableLights();
if (gViewerWindow)
gViewerWindow->setup2DRender();
- gGL.color4f(1,1,1,1);
if (gViewerWindow)
gViewerWindow->draw();
gGL.flush();
@@ -175,7 +174,6 @@ void display_startup()
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
if (gViewerWindow && gViewerWindow->getWindow())
gViewerWindow->getWindow()->swapBuffers();
@@ -183,26 +181,32 @@ void display_startup()
glClear(GL_DEPTH_BUFFER_BIT);
}
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_CAMERA("Update Camera");
-
void display_update_camera()
{
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_CAMERA);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Camera");
// TODO: cut draw distance down if customizing avatar?
// TODO: cut draw distance on per-parcel basis?
// Cut draw distance in half when customizing avatar,
// but on the viewer only.
F32 final_far = gAgentCamera.mDrawDistance;
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+ if (gCubeSnapshot)
+ {
+ final_far = gSavedSettings.getF32("RenderReflectionProbeDrawDistance");
+ }
+ else if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+
{
final_far *= 0.5f;
}
LLViewerCamera::getInstance()->setFar(final_far);
gViewerWindow->setup3DRender();
- // Update land visibility too
- LLWorld::getInstance()->setLandFarClip(final_far);
+ if (!gCubeSnapshot)
+ {
+ // Update land visibility too
+ LLWorld::getInstance()->setLandFarClip(final_far);
+ }
}
// Write some stats to LL_INFOS()
@@ -379,33 +383,17 @@ static void update_tp_display(bool minimized)
}
}
-static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
-static LLTrace::BlockTimerStatHandle FTM_RENDER("Render");
-static LLTrace::BlockTimerStatHandle FTM_RENDER_HUD("Render HUD");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_SKY("Update Sky");
-static LLTrace::BlockTimerStatHandle FTM_UPDATE_DYNAMIC_TEXTURES("Update Dynamic Textures");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE("Update Images");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_CLASS("Class");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_BUMP("Image Update Bump");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_LIST("List");
-static LLTrace::BlockTimerStatHandle FTM_IMAGE_UPDATE_DELETE("Delete");
-static LLTrace::BlockTimerStatHandle FTM_RESIZE_WINDOW("Resize Window");
-static LLTrace::BlockTimerStatHandle FTM_HUD_UPDATE("HUD Update");
-static LLTrace::BlockTimerStatHandle FTM_DISPLAY_UPDATE_GEOM("Update Geom");
-static LLTrace::BlockTimerStatHandle FTM_TEXTURE_UNBIND("Texture Unbind");
-static LLTrace::BlockTimerStatHandle FTM_TELEPORT_DISPLAY("Teleport Display");
-static LLTrace::BlockTimerStatHandle FTM_EEP_UPDATE("Env Update");
-
// Paint the display!
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
- LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering.
- LL_RECORD_BLOCK_TIME(FTM_RENDER);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Render");
+ LLPerfStats::RecordSceneTime T (LLPerfStats::StatType_t::RENDER_DISPLAY); // render time capture - This is the main stat for overall rendering.
+
if (gWindowResized)
{ //skip render on frames where window has been resized
LL_DEBUGS("Window") << "Resizing window" << LL_ENDL;
- LL_RECORD_BLOCK_TIME(FTM_RESIZE_WINDOW);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Resize Window");
gGL.flush();
glClear(GL_COLOR_BUFFER_BIT);
gViewerWindow->getWindow()->swapBuffers();
@@ -427,11 +415,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
for_snapshot = FALSE;
}
- if (LLPipeline::sRenderFrameTest)
- {
- send_agent_pause();
- }
-
gSnapshot = for_snapshot;
LLGLSDefault gls_default;
@@ -440,16 +423,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- stop_glerror();
-
gPipeline.disableLights();
-
- //reset vertex buffers if needed
- gPipeline.doResetVertexBuffers();
-
- stop_glerror();
// Don't draw if the window is hidden or minimized.
// In fact, must explicitly check the minimized state before drawing.
@@ -485,14 +460,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gViewerWindow->checkSettings();
{
- LL_RECORD_BLOCK_TIME(FTM_PICK);
- LLAppViewer::instance()->pingMainloopTimeout("Display:Pick");
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Picking");
gViewerWindow->performPick();
}
LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates");
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
//////////////////////////////////////////////////////////
//
@@ -564,7 +537,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gTeleportDisplay)
{
- LL_RECORD_BLOCK_TIME(FTM_TELEPORT_DISPLAY);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Teleport Display");
LLAppViewer::instance()->pingMainloopTimeout("Display:Teleport");
// Note: false = not minimized, do update the TP screen. HB
update_tp_display(false);
@@ -668,7 +641,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES))
{
LLAppViewer::instance()->pingMainloopTimeout("Display:DynamicTextures");
- LL_RECORD_BLOCK_TIME(FTM_UPDATE_DYNAMIC_TEXTURES);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Dynamic Textures");
if (LLViewerDynamicTexture::updateAllInstances())
{
gGL.setColorMask(true, true);
@@ -699,21 +672,21 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
{
- LL_RECORD_BLOCK_TIME(FTM_EEP_UPDATE);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Env Update");
// update all the sky/atmospheric/water settings
LLEnvironment::instance().update(LLViewerCamera::getInstance());
}
// *TODO: merge these two methods
{
- LL_RECORD_BLOCK_TIME(FTM_HUD_UPDATE);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("HUD Update");
LLHUDManager::getInstance()->updateEffects();
LLHUDObject::updateAll();
stop_glerror();
}
{
- LL_RECORD_BLOCK_TIME(FTM_DISPLAY_UPDATE_GEOM);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Update Geom");
const F32 max_geom_update_time = 0.005f*10.f*gFrameIntervalSeconds.value(); // 50 ms/second update time
gPipeline.createObjects(max_geom_update_time);
gPipeline.processPartitionQ();
@@ -741,7 +714,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gDepthDirty = FALSE;
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
static LLCullResult result;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
@@ -750,7 +722,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
stop_glerror();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
@@ -766,20 +737,18 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glClearColor(0,0,0,0);
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
if (!for_snapshot)
{
- if (gFrameCount > 1)
- { //for some reason, ATI 4800 series will error out if you
- //try to generate a shadow before the first frame is through
- gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
- }
+ if (gFrameCount > 1 && !for_snapshot)
+ { //for some reason, ATI 4800 series will error out if you
+ //try to generate a shadow before the first frame is through
+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
+ }
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
glh::matrix4f proj = get_current_projection();
glh::matrix4f mod = get_current_modelview();
@@ -796,25 +765,10 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gViewerWindow->setup3DViewport();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
-
}
- glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- }
-
- LLGLState::checkStates();
-
- //if (!for_snapshot)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("display - 3")
- LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
- gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
- gPipeline.generateHighlight(*LLViewerCamera::getInstance());
- gPipeline.renderPhysicsDisplay();
+ glClear(GL_DEPTH_BUFFER_BIT);
}
- LLGLState::checkStates();
-
//////////////////////////////////////
//
// Update images, using the image stats generated during object update/culling
@@ -825,33 +779,30 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:UpdateImages");
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE);
+ LL_PROFILE_ZONE_NAMED("Update Images");
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_CLASS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Class");
LLViewerTexture::updateClass();
}
- LLImageGLThread::updateClass();
-
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_BUMP);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Image Update Bump");
gBumpImageList.updateImages(); // must be called before gTextureList version so that it's textures are thrown out first.
}
{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_LIST);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("List");
F32 max_image_decode_time = 0.050f*gFrameIntervalSeconds.value(); // 50 ms/second decode time
max_image_decode_time = llclamp(max_image_decode_time, 0.002f, 0.005f ); // min 2ms/frame, max 5ms/frame)
gTextureList.updateImages(max_image_decode_time);
}
- /*{
- LL_RECORD_BLOCK_TIME(FTM_IMAGE_UPDATE_DELETE);
- //remove dead textures from GL
- LLImageGL::deleteDeadTextures();
- stop_glerror();
- }*/
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("GLTF Materials Cleanup");
+ //remove dead gltf materials
+ gGLTFMaterialList.flushMaterials();
+ }
}
LLGLState::checkStates();
@@ -899,7 +850,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
{
glClearColor(0.5f, 0.5f, 0.5f, 0.f);
glClear(GL_COLOR_BUFFER_BIT);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
@@ -951,19 +901,27 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
if (LLPipeline::sRenderDeferred)
{
- gPipeline.mDeferredScreen.bindTarget();
- glClearColor(1, 0, 1, 1);
- gPipeline.mDeferredScreen.clear();
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ F32 g = 0.5f;
+ glClearColor(g, g, g, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
}
else
{
- gPipeline.mScreen.bindTarget();
+ gPipeline.mRT->screen.bindTarget();
if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders())
{
const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
}
- gPipeline.mScreen.clear();
+ gPipeline.mRT->screen.clear();
}
gGL.setColorMask(true, false);
@@ -994,33 +952,15 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
gOcclusionProgram.unbind();
- }
-
- gGL.setColorMask(true, false);
- if (LLPipeline::sRenderDeferred)
- {
- gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
}
- else
- {
- gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE);
- }
-
- gGL.setColorMask(true, 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];
- gGLLastProjection[i] = gGLProjection[i];
- }
- stop_glerror();
+ gGL.setColorMask(true, true);
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true);
}
{
- LL_RECORD_BLOCK_TIME(FTM_TEXTURE_UNBIND);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Texture Unbind");
for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
{ //dummy cleanup of any currently bound textures
if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
@@ -1033,19 +973,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");
- LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen);
+ LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mRT->deferredScreen : gPipeline.mRT->screen);
rt.flush();
- if (rt.sUseFBO)
- {
- LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(),
- rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT,
- GL_NEAREST);
- }
-
if (LLPipeline::sRenderDeferred)
{
- gPipeline.renderDeferredLighting(&gPipeline.mScreen);
+ gPipeline.renderDeferredLighting();
}
LLPipeline::sUnderWaterRender = FALSE;
@@ -1065,20 +998,12 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLSpatialGroup::sNoDelete = FALSE;
gPipeline.clearReferences();
-
- gPipeline.rebuildGroups();
}
LLAppViewer::instance()->pingMainloopTimeout("Display:FrameStats");
stop_glerror();
- if (LLPipeline::sRenderFrameTest)
- {
- send_agent_resume();
- LLPipeline::sRenderFrameTest = FALSE;
- }
-
display_stats();
LLAppViewer::instance()->pingMainloopTimeout("Display:Done");
@@ -1092,6 +1017,119 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
+// WIP simplified copy of display() that does minimal work
+void display_cube_face()
+{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Render Cube Face");
+ LL_PROFILE_GPU_ZONE("display cube face");
+
+ llassert(!gSnapshot);
+ llassert(!gTeleportDisplay);
+ llassert(LLStartUp::getStartupState() >= STATE_PRECACHE);
+ llassert(!LLAppViewer::instance()->logoutRequestSent());
+ llassert(!gRestoreGL);
+
+ bool rebuild = false;
+
+ LLGLSDefault gls_default;
+ LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE, GL_LEQUAL);
+
+ LLVertexBuffer::unbind();
+
+ gPipeline.disableLights();
+
+ gPipeline.mBackfaceCull = TRUE;
+
+ gViewerWindow->setup3DViewport();
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ { //don't draw hud objects in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES))
+ { //don't draw hud particles in this frame
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD_PARTICLES);
+ }
+
+ display_update_camera();
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Env Update");
+ // update all the sky/atmospheric/water settings
+ LLEnvironment::instance().update(LLViewerCamera::getInstance());
+ }
+
+ LLSpatialGroup::sNoDelete = TRUE;
+
+ S32 occlusion = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0; // occlusion data is from main camera point of view, don't read or write it during cube snapshots
+ //gDepthDirty = TRUE; //let "real" render pipe know it can't trust the depth buffer for occlusion data
+
+ static LLCullResult result;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater();
+ gPipeline.updateCull(*LLViewerCamera::getInstance(), result);
+
+ gGL.setColorMask(true, true);
+
+ glClearColor(0, 0, 0, 0);
+ gPipeline.generateSunShadow(*LLViewerCamera::getInstance());
+
+ glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT);
+
+ {
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+ gPipeline.stateSort(*LLViewerCamera::getInstance(), result);
+
+ if (rebuild)
+ {
+ //////////////////////////////////////
+ //
+ // rebuildPools
+ //
+ //
+ gPipeline.rebuildPools();
+ stop_glerror();
+ }
+ }
+
+ LLPipeline::sUseOcclusion = occlusion;
+
+ LLAppViewer::instance()->pingMainloopTimeout("Display:RenderStart");
+
+ LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? TRUE : FALSE;
+
+ gGL.setColorMask(true, true);
+
+ gPipeline.mRT->deferredScreen.bindTarget();
+ if (gUseWireframe)
+ {
+ glClearColor(0.5f, 0.5f, 0.5f, 1.f);
+ }
+ else
+ {
+ glClearColor(1, 0, 1, 1);
+ }
+ gPipeline.mRT->deferredScreen.clear();
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+
+ gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance());
+
+ gPipeline.mRT->deferredScreen.flush();
+
+ gPipeline.renderDeferredLighting();
+
+ LLPipeline::sUnderWaterRender = FALSE;
+
+ // Finalize scene
+ //gPipeline.renderFinalize();
+
+ LLSpatialGroup::sNoDelete = FALSE;
+ gPipeline.clearReferences();
+}
+
void render_hud_attachments()
{
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_HUDS); // render time capture - Primary contributor to HUDs (though these end up in render batches)
@@ -1151,13 +1189,19 @@ void render_hud_attachments()
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
gPipeline.updateCull(hud_cam, result);
+ // Toggle render types
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_BUMP);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_SIMPLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_GLTF_PBR_ALPHA_MASK);
+
+ // Toggle render passes
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP);
@@ -1168,10 +1212,12 @@ void render_hud_attachments()
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE);
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR);
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK);
gPipeline.stateSort(hud_cam, result);
- gPipeline.renderGeom(hud_cam);
+ gPipeline.renderGeomPostDeferred(hud_cam);
LLSpatialGroup::sNoDelete = FALSE;
//gPipeline.clearReferences();
@@ -1288,7 +1334,7 @@ void render_ui(F32 zoom_factor, int subfield)
{
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_UI ); // render time capture - Primary UI stat can have HUD time overlap (TODO)
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
-
+ LL_PROFILE_GPU_ZONE("ui");
LLGLState::checkStates();
glh::matrix4f saved_view = get_current_modelview();
@@ -1309,70 +1355,66 @@ void render_ui(F32 zoom_factor, int subfield)
gGL.popMatrix();
}
- // Finalize scene
- gPipeline.renderFinalize();
+ // apply gamma correction and post effects
+ gPipeline.renderFinalize();
{
- // SL-15709
- // NOTE: Tracy only allows one ZoneScoped per function.
- // Solutions are:
- // 1. Use a new scope
- // 2. Use named zones
- // 3. Use transient zones
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD);
+ LLGLState::checkStates();
+
+
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD");
render_hud_elements();
+ LLGLState::checkStates();
render_hud_attachments();
+ LLGLState::checkStates();
+
LLGLSDefault gls_default;
LLGLSUIDefault gls_ui;
{
gPipeline.disableLights();
}
- {
- gGL.color4f(1,1,1,1);
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- if (!gDisconnected)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
- render_ui_3d();
- LLGLState::checkStates();
- }
- else
- {
- render_disconnected_background();
- }
-
- LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
- render_ui_2d();
- LLGLState::checkStates();
- }
- gGL.flush();
-
- gViewerWindow->setup2DRender();
- gViewerWindow->updateDebugText();
- gViewerWindow->drawDebugText();
+ bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ if (render_ui)
+ {
+ if (!gDisconnected)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 3D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_3D);
+ LLGLState::checkStates();
+ render_ui_3d();
+ LLGLState::checkStates();
+ }
+ else
+ {
+ render_disconnected_background();
+ }
+ }
- LLVertexBuffer::unbind();
- }
+ if (render_ui)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_UI("UI 2D"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI_2D);
+ LLHUDObject::renderAll();
+ render_ui_2d();
+ }
- if (!gSnapshot)
- {
- set_current_modelview(saved_view);
- gGL.popMatrix();
- }
+ gViewerWindow->setup2DRender();
+ gViewerWindow->updateDebugText();
+ gViewerWindow->drawDebugText();
+ }
- } // Tracy integration
+ if (!gSnapshot)
+ {
+ set_current_modelview(saved_view);
+ gGL.popMatrix();
+ }
}
-static LLTrace::BlockTimerStatHandle FTM_SWAP("Swap");
-
void swap()
{
LLPerfStats::RecordSceneTime T ( LLPerfStats::StatType_t::RENDER_SWAP ); // render time capture - Swap buffer time - can signify excessive data transfer to/from GPU
- LL_RECORD_BLOCK_TIME(FTM_SWAP);
-
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("Swap");
+ LL_PROFILE_GPU_ZONE("swap");
if (gDisplaySwapBuffers)
{
gViewerWindow->getWindow()->swapBuffers();
@@ -1470,6 +1512,7 @@ void render_ui_3d()
stop_glerror();
gUIProgram.bind();
+ gGL.color4f(1, 1, 1, 1);
// Coordinate axes
if (gSavedSettings.getBOOL("ShowAxes"))
@@ -1478,6 +1521,15 @@ void render_ui_3d()
}
gViewerWindow->renderSelections(FALSE, FALSE, TRUE); // Non HUD call in render_hud_elements
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // Render debugging beacons.
+ gObjectList.renderObjectBeacons();
+ gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
+ }
+
stop_glerror();
}
@@ -1513,6 +1565,7 @@ void render_ui_2d()
// render outline for HUD
if (isAgentAvatarValid() && gAgentCamera.mHUDCurZoom < 0.98f)
{
+ gUIProgram.bind();
gGL.pushMatrix();
S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
@@ -1523,6 +1576,7 @@ void render_ui_2d()
gGL.color4fv(LLColor4::white.mV);
gl_rect_2d(-half_width, half_height, half_width, -half_height, FALSE);
gGL.popMatrix();
+ gUIProgram.unbind();
stop_glerror();
}
@@ -1534,7 +1588,7 @@ void render_ui_2d()
LLView::sIsRectDirty = false;
LLRect t_rect;
- gPipeline.mUIScreen.bindTarget();
+ gPipeline.mRT->uiScreen.bindTarget();
gGL.setColorMask(true, true);
{
static const S32 pad = 8;
@@ -1566,7 +1620,7 @@ void render_ui_2d()
gViewerWindow->draw();
}
- gPipeline.mUIScreen.flush();
+ gPipeline.mRT->uiScreen.flush();
gGL.setColorMask(true, false);
LLView::sDirtyRect = t_rect;
@@ -1576,7 +1630,7 @@ void render_ui_2d()
LLGLDisable blend(GL_BLEND);
S32 width = gViewerWindow->getWindowWidthScaled();
S32 height = gViewerWindow->getWindowHeightScaled();
- gGL.getTexUnit(0)->bind(&gPipeline.mUIScreen);
+ gGL.getTexUnit(0)->bind(&gPipeline.mRT->uiScreen);
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.color4f(1,1,1,1);
gGL.texCoord2f(0, 0); gGL.vertex2i(0, 0);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 7bd50fa618..3a08f748d6 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -138,7 +138,6 @@
#include "llfloatertelehub.h"
#include "llfloatertestinspectors.h"
#include "llfloatertestlistview.h"
-#include "llfloatertexturefetchdebugger.h"
#include "llfloatertools.h"
#include "llfloatertopobjects.h"
#include "llfloatertos.h"
@@ -157,6 +156,7 @@
#include "llinspectobject.h"
#include "llinspectremoteobject.h"
#include "llinspecttoast.h"
+#include "llmaterialeditor.h"
#include "llmoveview.h"
#include "llfloaterimnearbychat.h"
#include "llpanelblockedlist.h"
@@ -398,10 +398,6 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("mem_leaking", "floater_mem_leaking.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMemLeak>);
- if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
- {
- LLFloaterReg::add("tex_fetch_debugger", "floater_texture_fetch_debugger.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterTextureFetchDebugger>);
- }
LLFloaterReg::add("media_settings", "floater_media_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMediaSettings>);
LLFloaterReg::add("marketplace_listings", "floater_marketplace_listings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceListings>);
LLFloaterReg::add("marketplace_validation", "floater_marketplace_validation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterMarketplaceValidation>);
@@ -451,6 +447,9 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("save_camera_preset", "floater_save_camera_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSaveCameraPreset>);
LLFloaterReg::add("script_colors", "floater_script_ed_prefs.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptEdPrefs>);
+ LLFloaterReg::add("material_editor", "floater_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
+ LLFloaterReg::add("live_material_editor", "floater_live_material_editor.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLMaterialEditor>);
+
LLFloaterReg::add("telehubs", "floater_telehub.xml",&LLFloaterReg::build<LLFloaterTelehub>);
LLFloaterReg::add("test_inspectors", "floater_test_inspectors.xml", &LLFloaterReg::build<LLFloaterTestInspectors>);
//LLFloaterReg::add("test_list_view", "floater_test_list_view.xml",&LLFloaterReg::build<LLFloaterTestListView>);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index f770db31dd..c8d4aae8fd 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -134,6 +134,7 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
addEntry(LLFolderType::FT_MY_OUTFITS, new ViewerFolderEntry("My Outfits", "Inv_SysOpen", "Inv_SysClosed", TRUE, true));
addEntry(LLFolderType::FT_MESH, new ViewerFolderEntry("Meshes", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
addEntry(LLFolderType::FT_SETTINGS, new ViewerFolderEntry("Settings", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
+ addEntry(LLFolderType::FT_MATERIAL, new ViewerFolderEntry("Materials", "Inv_SysOpen", "Inv_SysClosed", FALSE, true));
bool boxes_invisible = !gSavedSettings.getBOOL("InventoryOutboxMakeVisible");
addEntry(LLFolderType::FT_INBOX, new ViewerFolderEntry("Received Items", "Inv_SysOpen", "Inv_SysClosed", FALSE, boxes_invisible));
diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp
index 7d33fc0d84..aaa1313ff6 100644
--- a/indra/newview/llviewergenericmessage.cpp
+++ b/indra/newview/llviewergenericmessage.cpp
@@ -32,9 +32,10 @@
#include "lldispatcher.h"
#include "lluuid.h"
#include "message.h"
+#include "llgenericstreamingmessage.h"
#include "llagent.h"
-
+#include "llgltfmateriallist.h"
LLDispatcher gGenericDispatcher;
@@ -94,7 +95,17 @@ void process_generic_message(LLMessageSystem* msg, void**)
void process_generic_streaming_message(LLMessageSystem* msg, void**)
{
- // placeholder to suppress packet loss reports and log spam (SL-20473)
+ LLGenericStreamingMessage data;
+ data.unpack(msg);
+ switch (data.mMethod)
+ {
+ case LLGenericStreamingMessage::METHOD_GLTF_MATERIAL_OVERRIDE:
+ gGLTFMaterialList.applyOverrideMessage(msg, data.mData);
+ break;
+ default:
+ LL_WARNS_ONCE() << "Received unknown method" << LL_ENDL;
+ break;
+ }
}
void process_large_generic_message(LLMessageSystem* msg, void**)
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 907941eaf0..3e3a574988 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -147,6 +147,7 @@ LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
mInventoryItemsDict["New Gesture"] = LLTrans::getString("New Gesture");
+ mInventoryItemsDict["New Material"] = LLTrans::getString("New Material");
mInventoryItemsDict["New Script"] = LLTrans::getString("New Script");
mInventoryItemsDict["New Folder"] = LLTrans::getString("New Folder");
mInventoryItemsDict["New Note"] = LLTrans::getString("New Note");
@@ -1054,6 +1055,21 @@ void create_notecard_cb(const LLUUID& inv_item)
}
}
+void create_gltf_material_cb(const LLUUID& inv_item)
+{
+ if (!inv_item.isNull())
+ {
+ LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+ if (item)
+ {
+ set_default_permissions(item, "Materials");
+
+ gInventory.updateItem(item);
+ gInventory.notifyObservers();
+ }
+ }
+}
+
LLInventoryCallbackManager gInventoryCallbacks;
void create_inventory_item(
@@ -1677,6 +1693,67 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
}
}
+void move_or_copy_inventory_from_object(const LLUUID& destination_id,
+ const LLUUID& object_id,
+ const LLUUID& item_id,
+ LLPointer<LLInventoryCallback> cb)
+{
+ LLViewerObject* object = gObjectList.findObject(object_id);
+ if (!object)
+ {
+ return;
+ }
+ const LLInventoryItem* item = object->getInventoryItem(item_id);
+ if (!item)
+ {
+ return;
+ }
+
+ class LLItemAddedObserver : public LLInventoryObserver
+ {
+ public:
+ LLItemAddedObserver(const LLUUID& copied_asset_id, LLPointer<LLInventoryCallback> cb)
+ : LLInventoryObserver(),
+ mAssetId(copied_asset_id),
+ mCallback(cb)
+ {
+ }
+
+ void changed(U32 mask) override
+ {
+ if((mask & (LLInventoryObserver::ADD)) == 0)
+ {
+ return;
+ }
+ for (const LLUUID& changed_id : gInventory.getChangedIDs())
+ {
+ LLViewerInventoryItem* changed_item = gInventory.getItem(changed_id);
+ if (changed_item->getAssetUUID() == mAssetId)
+ {
+ changeComplete(changed_item->getUUID());
+ return;
+ }
+ }
+ }
+
+ private:
+ void changeComplete(const LLUUID& item_id)
+ {
+ mCallback->fire(item_id);
+ gInventory.removeObserver(this);
+ delete this;
+ }
+
+ LLUUID mAssetId;
+ LLPointer<LLInventoryCallback> mCallback;
+ };
+
+ const LLUUID& asset_id = item->getAssetUUID();
+ LLItemAddedObserver* observer = new LLItemAddedObserver(asset_id, cb);
+ gInventory.addObserver(observer);
+ object->moveInventory(destination_id, item_id);
+}
+
void create_new_item(const std::string& name,
const LLUUID& parent_id,
LLAssetType::EType asset_type,
@@ -1713,6 +1790,12 @@ void create_new_item(const std::string& name,
break;
}
+ case LLInventoryType::IT_MATERIAL:
+ {
+ cb = new LLBoostFuncInventoryCallback(create_gltf_material_cb);
+ next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials");
+ break;
+ }
default:
{
cb = new LLBoostFuncInventoryCallback();
@@ -1770,6 +1853,7 @@ void remove_folder_contents(const LLUUID& category, bool keep_outfit_links,
const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not)
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
+const std::string NEW_MATERIAL_NAME = "New Material"; // *TODO:Translate? (probably not)
// ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
@@ -1854,6 +1938,16 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLUUID dest_id, const L
PERM_ALL,
created_cb); // overridden in create_new_item
}
+ else if ("material" == type_name)
+ {
+ const LLUUID parent_id = dest_id.notNull() ? dest_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL);
+ create_new_item(NEW_MATERIAL_NAME,
+ parent_id,
+ LLAssetType::AT_MATERIAL,
+ LLInventoryType::IT_MATERIAL,
+ PERM_ALL,
+ created_cb); // overridden in create_new_item
+ }
else if (("sky" == type_name) || ("water" == type_name) || ("daycycle" == type_name))
{
LLSettingsType::type_e stype(LLSettingsType::ST_NONE);
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 6d3676ba2e..bce8da0a69 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -463,6 +463,10 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
const LLInventoryItem *src,
U32 callback_id = 0);
+void move_or_copy_inventory_from_object(const LLUUID& destination_id,
+ const LLUUID& object_id,
+ const LLUUID& item_id,
+ LLPointer<LLInventoryCallback> cb);
void menu_create_inventory_item(LLInventoryPanel* root,
LLFolderBridge* bridge,
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 489f90aabb..5d46c695b7 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -1,4 +1,4 @@
-/**
+ /**
* @file llviewerjointmesh.cpp
* @brief Implementation of LLViewerJointMesh class
*
@@ -39,7 +39,6 @@
#include "lldrawpoolbump.h"
#include "lldynamictexture.h"
#include "llface.h"
-#include "llgldbg.h"
#include "llglheaders.h"
#include "llviewertexlayer.h"
#include "llviewercamera.h"
@@ -63,10 +62,6 @@ extern PFNGLWEIGHTFVARBPROC glWeightfvARB;
extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB;
#endif
-static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_NORMAL |
- LLVertexBuffer::MAP_TEXCOORD0;
-
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// LLViewerJointMesh
@@ -231,16 +226,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
return 0;
}
- // render time capture
- // This path does not appear to have attachments. Prove this then remove.
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- auto vobj = mFace->getViewerObject();
- if( vobj && vobj->isAttachment() )
- {
- trackAttachments( vobj, mFace->isState(LLFace::RIGGED), &ratPtr );
- LL_WARNS("trackAttachments") << "Attachment render time is captuted." << LL_ENDL;
- }
-
U32 triangle_count = 0;
S32 diffuse_channel = LLDrawPoolAvatar::sDiffuseChannel;
@@ -298,8 +283,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT));
}
- U32 mask = sRenderMask;
-
U32 start = mMesh->mFaceVertexOffset;
U32 end = start + mMesh->mFaceVertexCount - 1;
U32 count = mMesh->mFaceIndexCount;
@@ -315,14 +298,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
{
uploadJointMatrices();
}
- mask = mask | LLVertexBuffer::MAP_WEIGHT;
- if (mFace->getPool()->getShaderLevel() > 1)
- {
- mask = mask | LLVertexBuffer::MAP_CLOTHWEIGHT;
- }
}
- buff->setBuffer(mask);
+ buff->setBuffer();
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
}
else
@@ -330,7 +308,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
gGL.pushMatrix();
LLMatrix4 jointToWorld = getWorldMatrix();
gGL.multMatrix((GLfloat*)jointToWorld.mMatrix);
- buff->setBuffer(mask);
+ buff->setBuffer();
buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
gGL.popMatrix();
}
@@ -517,7 +495,7 @@ void LLViewerJointMesh::updateGeometry(LLFace *mFace, LLPolyMesh *mMesh)
}
}
- buffer->flush();
+ buffer->unmapBuffer();
}
void LLViewerJointMesh::updateJointGeometry()
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 8570c0cd5d..02108e861a 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -79,6 +79,10 @@
#include <boost/bind.hpp> // for SkinFolder listener
#include <boost/signals2.hpp>
+extern BOOL gCubeSnapshot;
+
+// *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+constexpr BOOL USE_MIPMAPS = FALSE;
void init_threaded_picker_load_dialog(LLPluginClassMedia* plugin, LLFilePicker::ELoadFilter filter, bool get_multiple)
{
@@ -262,6 +266,7 @@ viewer_media_t LLViewerMedia::newMediaImpl(
viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self)
{
+ llassert(!gCubeSnapshot);
// Try to find media with the same media ID
viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID());
@@ -624,6 +629,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE);
+ llassert(!gCubeSnapshot);
+
// Enable/disable the plugin read thread
LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
@@ -1564,7 +1571,8 @@ LLViewerMediaImpl::LLViewerMediaImpl( const LLUUID& texture_id,
// connect this media_impl to the media texture, creating it if it doesn't exist.0
// This is necessary because we need to be able to use getMaxVirtualSize() even if the media plugin is not loaded.
- LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId);
+ // *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture(mTextureId, USE_MIPMAPS);
if(media_tex)
{
media_tex->setMediaImpl();
@@ -1658,13 +1666,14 @@ void LLViewerMediaImpl::destroyMediaSource()
cancelMimeTypeProbe();
- mLock.lock(); // Delay tear-down while bg thread is updating
- if(mMediaSource)
- {
- mMediaSource->setDeleteOK(true) ;
- mMediaSource = NULL; // shared pointer
- }
- mLock.unlock();
+ {
+ LLMutexLock lock(&mLock); // Delay tear-down while bg thread is updating
+ if(mMediaSource)
+ {
+ mMediaSource->setDeleteOK(true) ;
+ mMediaSource = NULL; // shared pointer
+ }
+ }
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2874,7 +2883,7 @@ void LLViewerMediaImpl::update()
if (preMediaTexUpdate(media_tex, data, data_width, data_height, x_pos, y_pos, width, height))
{
// Push update to worker thread
- auto main_queue = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ auto main_queue = LLImageGLThread::sEnabledMedia ? mMainQueue.lock() : nullptr;
if (main_queue)
{
mTextureUpdatePending = true;
@@ -2959,11 +2968,16 @@ bool LLViewerMediaImpl::preMediaTexUpdate(LLViewerMediaTexture*& media_tex, U8*&
void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* data, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, bool sync)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
- mLock.lock(); // don't allow media source tear-down during update
+ LLMutexLock lock(&mLock); // don't allow media source tear-down during update
// wrap "data" in an LLImageRaw but do NOT make a copy
LLPointer<LLImageRaw> raw = new LLImageRaw(data, media_tex->getWidth(), media_tex->getHeight(), media_tex->getComponents(), true);
-
+
+ // *NOTE: Recreating the GL texture each media update may seem wasteful
+ // (note the texture creation in preMediaTexUpdate), however, it apparently
+ // prevents GL calls from blocking, due to poor bookkeeping of state of
+ // updated textures by the OpenGL implementation. (Windows 10/Nvidia)
+ // -Cosmic,2023-04-04
// Allocate GL texture based on LLImageRaw but do NOT copy to GL
LLGLuint tex_name = 0;
media_tex->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER, true, &tex_name);
@@ -2983,8 +2997,6 @@ void LLViewerMediaImpl::doMediaTexUpdate(LLViewerMediaTexture* media_tex, U8* da
// release the data pointer before freeing raw so LLImageRaw destructor doesn't
// free memory at data pointer
raw->releaseData();
-
- mLock.unlock();
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2996,16 +3008,17 @@ void LLViewerMediaImpl::updateImagesMediaStreams()
LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA;
+ llassert(!gCubeSnapshot);
if (!mMediaSource)
{
return nullptr; // not ready for updating
}
- llassert(!mTextureId.isNull());
- LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId );
+ //llassert(!mTextureId.isNull());
+ // *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary.
+ LLViewerMediaTexture* media_tex = LLViewerTextureManager::getMediaTexture( mTextureId, USE_MIPMAPS );
if ( mNeedsNewTexture
- || media_tex->getUseMipMaps()
|| (media_tex->getWidth() != mMediaSource->getTextureWidth())
|| (media_tex->getHeight() != mMediaSource->getTextureHeight())
|| (mTextureUsedWidth != mMediaSource->getWidth())
@@ -3021,8 +3034,6 @@ LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage()
// MEDIAOPT: check to see if size actually changed before doing work
media_tex->destroyGLTexture();
- // MEDIAOPT: apparently just calling setUseMipMaps(FALSE) doesn't work?
- media_tex->reinit(FALSE); // probably not needed
// MEDIAOPT: seems insane that we actually have to make an imageraw then
// immediately discard it
@@ -3553,6 +3564,8 @@ void LLViewerMediaImpl::calculateInterest()
LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST);
LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId );
+ llassert(!gCubeSnapshot);
+
if(texture != NULL)
{
mInterest = texture->getMaxVirtualSize();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 8686fad3e6..553eaaf9b2 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -93,6 +93,7 @@
#include "llpanelblockedlist.h"
#include "llpanelmaininventory.h"
#include "llmarketplacefunctions.h"
+#include "llmaterialeditor.h"
#include "llmenuoptionpathfindingrebakenavmesh.h"
#include "llmoveview.h"
#include "llnavigationbar.h"
@@ -272,7 +273,6 @@ void handle_reset_view();
void handle_duplicate_in_place(void*);
-
void handle_object_owner_self(void*);
void handle_object_owner_permissive(void*);
void handle_object_lock(void*);
@@ -767,10 +767,6 @@ U32 render_type_from_string(std::string render_type)
{
return LLPipeline::RENDER_TYPE_WATER;
}
- else if ("ground" == render_type)
- {
- return LLPipeline::RENDER_TYPE_GROUND;
- }
else if ("volume" == render_type)
{
return LLPipeline::RENDER_TYPE_VOLUME;
@@ -1035,10 +1031,6 @@ U64 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_LOD_INFO;
}
- else if ("build queue" == info_display)
- {
- return LLPipeline::RENDER_DEBUG_BUILD_QUEUE;
- }
else if ("lights" == info_display)
{
return LLPipeline::RENDER_DEBUG_LIGHTS;
@@ -1095,6 +1087,14 @@ U64 info_display_from_string(std::string info_display)
{
return LLPipeline::RENDER_DEBUG_IMPOSTORS;
}
+ else if ("reflection probes" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
+ }
+ else if ("probe updates" == info_display)
+ {
+ return LLPipeline::RENDER_DEBUG_PROBE_UPDATES;
+ }
else
{
LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
@@ -1184,33 +1184,9 @@ class LLAdvancedCheckPeriodicSlowFrame : public view_listener_t
};
-
-////////////////
-// FRAME TEST //
-////////////////
-
-
-class LLAdvancedToggleFrameTest : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- LLPipeline::sRenderFrameTest = !(LLPipeline::sRenderFrameTest);
- return true;
- }
-};
-
-class LLAdvancedCheckFrameTest : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLPipeline::sRenderFrameTest;
- return new_value;
- }
-};
-
-
///////////////////////////
// SELECTED TEXTURE INFO //
+//
///////////////////////////
@@ -1232,24 +1208,6 @@ class LLAdvancedToggleWireframe : public view_listener_t
bool handleEvent(const LLSD& userdata)
{
gUseWireframe = !(gUseWireframe);
- gWindowResized = TRUE;
-
- LLPipeline::updateRenderDeferred();
-
- if (gUseWireframe)
- {
- gInitialDeferredModeForWireframe = LLPipeline::sRenderDeferred;
- }
-
- gPipeline.resetVertexBuffers();
-
- if (!gUseWireframe && !gInitialDeferredModeForWireframe && LLPipeline::sRenderDeferred != bool(gInitialDeferredModeForWireframe) && gPipeline.isInit())
- {
- LLPipeline::refreshCachedSettings();
- gPipeline.releaseGLBuffers();
- gPipeline.createGLBuffers();
- LLViewerShaderMgr::instance()->setShaders();
- }
return true;
}
@@ -1259,8 +1217,7 @@ class LLAdvancedCheckWireframe : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- bool new_value = gUseWireframe;
- return new_value;
+ return gUseWireframe;
}
};
@@ -2146,6 +2103,21 @@ class LLAdvancedPurgeDiskCache : public view_listener_t
};
+////////////////////////
+// PURGE SHADER CACHE //
+////////////////////////
+
+
+class LLAdvancedPurgeShaderCache : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLViewerShaderMgr::instance()->clearShaderCache();
+ LLViewerShaderMgr::instance()->setShaders();
+ return true;
+ }
+};
+
////////////////////
// EVENT Recorder //
///////////////////
@@ -2355,47 +2327,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t
}
};
-/////////////////////////////////////
-// Enable Object Object Occlusion ///
-/////////////////////////////////////
-class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
-
- bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString());
- return new_value;
-}
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering ///
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferred: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0;
- return new_value;
- }
-};
-
-/////////////////////////////////////
-// Enable Deferred Rendering sub-options
-/////////////////////////////////////
-class LLAdvancedEnableRenderDeferredOptions: public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- bool new_value = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 && gSavedSettings.getBOOL("RenderDeferred");
- return new_value;
- }
-};
-
-
-
//////////////////
// ADMIN STATUS //
//////////////////
@@ -2597,14 +2528,6 @@ class LLDevelopSetLoggingLevel : public view_listener_t
}
};
-class LLDevelopTextureFetchDebugger : public view_listener_t
-{
- bool handleEvent(const LLSD& userdata)
- {
- return gSavedSettings.getBOOL("TextureFetchDebuggerEnabled");
- }
-};
-
//////////////////
// ADMIN MENU //
//////////////////
@@ -2899,6 +2822,49 @@ bool enable_object_inspect()
return selected_objectp != NULL;
}
+struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor
+{
+ LLSelectedTEGetmatIdAndPermissions()
+ : mCanCopy(true)
+ , mCanModify(true)
+ , mCanTransfer(true)
+ , mHasNonPbrFaces(false)
+ {}
+ bool apply(LLViewerObject* objectp, S32 te_index)
+ {
+ mCanCopy &= (bool)objectp->permCopy();
+ mCanTransfer &= (bool)objectp->permTransfer();
+ mCanModify &= (bool)objectp->permModify();
+ LLUUID mat_id = objectp->getRenderMaterialID(te_index);
+ if (mat_id.notNull())
+ {
+ mMaterialId = mat_id;
+ }
+ else
+ {
+ mHasNonPbrFaces = true;
+ }
+ return true;
+ }
+ bool mCanCopy;
+ bool mCanModify;
+ bool mCanTransfer;
+ bool mHasNonPbrFaces;
+ LLUUID mMaterialId;
+};
+
+bool enable_object_edit_gltf_material()
+{
+ if (!LLMaterialEditor::capabilitiesAvailable())
+ {
+ return false;
+ }
+
+ LLSelectedTEGetmatIdAndPermissions func;
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
+ return func.mCanModify && !func.mHasNonPbrFaces;
+}
+
bool enable_object_open()
{
// Look for contents in root object, which is all the LLFloaterOpenObject
@@ -2964,37 +2930,42 @@ class LLObjectBuild : public view_listener_t
}
};
-void handle_object_edit()
+void update_camera()
{
- LLViewerParcelMgr::getInstance()->deselectLand();
+ LLViewerParcelMgr::getInstance()->deselectLand();
- if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
- {
- LLFloaterTools::sPreviousFocusOnAvatar = true;
- LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+ if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
+ {
+ LLFloaterTools::sPreviousFocusOnAvatar = true;
+ LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+
+ if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
+ {
+ // always freeze camera in space, even if camera doesn't move
+ // so, for example, follow cam scripts can't affect you when in build mode
+ gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ }
+ else
+ {
+ gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
+ LLViewerObject* selected_objectp = selection->getFirstRootObject();
+ if (selected_objectp)
+ {
+ // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
+ gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
+ gAgentCamera.cameraZoomIn(0.666f);
+ gAgentCamera.cameraOrbitOver(30.f * DEG_TO_RAD);
+ gViewerWindow->moveCursorToCenter();
+ }
+ }
+ }
+}
+
+void handle_object_edit()
+{
+ update_camera();
- if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
- {
- // always freeze camera in space, even if camera doesn't move
- // so, for example, follow cam scripts can't affect you when in build mode
- gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- }
- else
- {
- gAgentCamera.setFocusOnAvatar(FALSE, ANIMATE);
- LLViewerObject* selected_objectp = selection->getFirstRootObject();
- if (selected_objectp)
- {
- // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
- gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
- gAgentCamera.cameraZoomIn(0.666f);
- gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
- gViewerWindow->moveCursorToCenter();
- }
- }
- }
-
LLFloaterReg::showInstance("build");
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -3008,6 +2979,23 @@ void handle_object_edit()
return;
}
+void handle_object_edit_gltf_material()
+{
+ if (!LLFloaterReg::instanceVisible("build"))
+ {
+ handle_object_edit(); // does update_camera();
+ }
+ else
+ {
+ update_camera();
+
+ LLViewerJoystick::getInstance()->moveObjects(true);
+ LLViewerJoystick::getInstance()->setNeedsReset(true);
+ }
+
+ LLMaterialEditor::loadLive();
+}
+
void handle_attachment_edit(const LLUUID& inv_item_id)
{
if (isAgentAvatarValid())
@@ -7859,10 +7847,6 @@ class LLToggleShaderControl : public view_listener_t
BOOL checked = gSavedSettings.getBOOL( control_name );
gSavedSettings.setBOOL( control_name, !checked );
LLPipeline::refreshCachedSettings();
- //gPipeline.updateRenderDeferred();
- //gPipeline.releaseGLBuffers();
- //gPipeline.createGLBuffers();
- //gPipeline.resetVertexBuffers();
LLViewerShaderMgr::instance()->setShaders();
return !checked;
}
@@ -8143,6 +8127,30 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t
}
};
+class LLToolsSelectInvisibleObjects : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects");
+
+ gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val);
+
+ return true;
+ }
+};
+
+class LLToolsSelectReflectionProbes: public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ BOOL cur_val = gSavedSettings.getBOOL("SelectReflectionProbes");
+
+ gSavedSettings.setBOOL("SelectReflectionProbes", !cur_val);
+
+ return true;
+ }
+};
+
class LLToolsSelectBySurrounding : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -8558,7 +8566,6 @@ BOOL get_visibility(void* user_data)
return viewp->getVisible();
}
-// TomY TODO: Get rid of these?
class LLViewShowHoverTips : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -8577,13 +8584,14 @@ class LLViewCheckShowHoverTips : public view_listener_t
}
};
-// TomY TODO: Get rid of these?
class LLViewHighlightTransparent : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
- gPipeline.resetVertexBuffers();
+
+ // invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag
+ gPipeline.rebuildDrawInfo();
return true;
}
};
@@ -8925,6 +8933,12 @@ class LLWorldEnvSettings : public view_listener_t
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
}
+ else if (event_name == "legacy noon")
+ {
+ LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
+ LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
+ defocusEnvFloaters();
+ }
else if (event_name == "sunset")
{
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT);
@@ -8939,6 +8953,9 @@ class LLWorldEnvSettings : public view_listener_t
}
else if (event_name == "region")
{
+ // reset probe data when reverting back to region sky setting
+ gPipeline.mReflectionMapManager.reset();
+
LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
defocusEnvFloaters();
@@ -8993,6 +9010,10 @@ class LLWorldEnableEnvSettings : public view_listener_t
{
result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY);
}
+ else if (event_name == "legacy noon")
+ {
+ result = (skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY);
+ }
else if (event_name == "sunset")
{
result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET);
@@ -9387,6 +9408,8 @@ void initialize_menus()
view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
+ view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
+ view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes");
view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
@@ -9455,20 +9478,16 @@ void initialize_menus()
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
// Develop > Render
- view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred");
- view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame");
- view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest");
- view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest");
view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
+ view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
@@ -9598,11 +9617,9 @@ void initialize_menus()
view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
- //Develop (Texture Fetch Debug Console)
- view_listener_t::addMenu(new LLDevelopTextureFetchDebugger(), "Develop.SetTexFetchDebugger");
//Develop (clear cache immediately)
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
-
+
// Admin >Object
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
@@ -9681,11 +9698,14 @@ void initialize_menus()
commit.add("Object.Buy", boost::bind(&handle_buy));
commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.Edit", boost::bind(&handle_object_edit));
+ commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
commit.add("Object.Open", boost::bind(&handle_object_open));
commit.add("Object.Take", boost::bind(&handle_take));
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
enable.add("Object.EnableInspect", boost::bind(&enable_object_inspect));
+ enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index a90b32c984..7142763451 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -90,6 +90,8 @@ void handle_gestures(void*);
void handle_sit_down(void*);
void handle_object_build(void*);
void handle_object_touch();
+bool enable_object_edit_gltf_material();
+bool enable_object_save_gltf_material();
bool enable_object_open();
void handle_object_open();
@@ -108,6 +110,8 @@ void handle_zoom_to_object(LLUUID object_id);
void handle_object_return();
void handle_object_delete();
void handle_object_edit();
+void handle_object_edit_gltf_material();
+void handle_object_save_gltf_material();
void handle_attachment_edit(const LLUUID& inv_item_id);
void handle_attachment_touch(const LLUUID& inv_item_id);
@@ -131,7 +135,6 @@ bool anyone_copy_selection(LLSelectNode* nodep);
// *TODO: Move to separate file
bool for_sale_selection(LLSelectNode* nodep);
-void handle_save_snapshot(void *);
void handle_toggle_flycam();
void handle_object_sit_or_stand();
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 17e89e1850..e2791ba128 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -37,6 +37,8 @@
#include "llbuycurrencyhtml.h"
#include "llfloatermap.h"
#include "llfloatermodelpreview.h"
+#include "llmaterialeditor.h"
+#include "llfloaterperms.h"
#include "llfloatersnapshot.h"
#include "llfloatersimplesnapshot.h"
#include "llimage.h"
@@ -48,9 +50,9 @@
#include "llinventorymodel.h" // gInventory
#include "llpluginclassmedia.h"
#include "llresourcedata.h"
-#include "lltoast.h"
-#include "llfloaterperms.h"
#include "llstatusbar.h"
+#include "lltinygltfhelper.h"
+#include "lltoast.h"
#include "llviewercontrol.h" // gSavedSettings
#include "llviewertexturelist.h"
#include "lluictrlfactory.h"
@@ -101,6 +103,19 @@ class LLFileEnableUploadModel : public view_listener_t
}
};
+class LLFileEnableUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ if (gAgent.getRegionCapability("UpdateMaterialAgentInventory").empty())
+ {
+ return false;
+ }
+
+ return true;
+ }
+};
+
class LLMeshEnabled : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -312,6 +327,16 @@ LLFilePickerReplyThread::~LLFilePickerReplyThread()
delete mFailureSignal;
}
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, get_multiple, failure_cb))->getFile();
+}
+
+void LLFilePickerReplyThread::startPicker(const file_picked_signal_t::slot_type & cb, LLFilePicker::ESaveFilter filter, const std::string & proposed_name, const file_picked_signal_t::slot_type & failure_cb)
+{
+ (new LLFilePickerReplyThread(cb, filter, proposed_name, failure_cb))->getFile();
+}
+
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
if (filenames.empty())
@@ -360,6 +385,7 @@ static std::string SLOBJECT_EXTENSIONS = "slobject";
#endif
static std::string ALL_FILE_EXTENSIONS = "*.*";
static std::string MODEL_EXTENSIONS = "dae";
+static std::string MATERIAL_EXTENSIONS = "gltf glb";
std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
{
@@ -376,6 +402,8 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
return SLOBJECT_EXTENSIONS;
case LLFilePicker::FFLOAD_MODEL:
return MODEL_EXTENSIONS;
+ case LLFilePicker::FFLOAD_MATERIAL:
+ return MATERIAL_EXTENSIONS;
case LLFilePicker::FFLOAD_XML:
return XML_EXTENSIONS;
case LLFilePicker::FFLOAD_ALL:
@@ -522,19 +550,37 @@ void do_bulk_upload(std::vector<std::string> filenames, const LLSD& notification
if (LLResourceUploadInfo::findAssetTypeAndCodecOfExtension(ext, asset_type, codec) &&
LLAgentBenefitsMgr::current().findUploadCost(asset_type, expected_upload_cost))
{
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
- filename,
- asset_name,
- asset_name, 0,
- LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost));
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo);
+ }
- upload_new_resource(uploadInfo);
- }
-}
+ // gltf does not use normal upload procedure
+ if (ext == "gltf" || ext == "glb")
+ {
+ tinygltf::Model model;
+ if (LLTinyGLTFHelper::loadModel(filename, model))
+ {
+ S32 materials_in_file = model.materials.size();
+
+ for (S32 i = 0; i < materials_in_file; i++)
+ {
+ // Todo:
+ // 1. Decouple bulk upload from material editor
+ // 2. Take into account possiblity of identical textures
+ LLMaterialEditor::uploadMaterialFromModel(filename, model, i);
+ }
+ }
+ }
+ }
}
bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S32& total_cost, S32& file_count, S32& bvh_count)
@@ -562,6 +608,50 @@ bool get_bulk_upload_expected_cost(const std::vector<std::string>& filenames, S3
total_cost += cost;
file_count++;
}
+
+ if (ext == "gltf" || ext == "glb")
+ {
+ S32 texture_upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
+
+ tinygltf::Model model;
+
+ if (LLTinyGLTFHelper::loadModel(filename, model))
+ {
+ S32 materials_in_file = model.materials.size();
+
+ for (S32 i = 0; i < materials_in_file; i++)
+ {
+ LLPointer<LLFetchedGLTFMaterial> material = new LLFetchedGLTFMaterial();
+ std::string material_name;
+ bool decode_successful = LLTinyGLTFHelper::getMaterialFromModel(filename, model, i, material.get(), material_name);
+
+ if (decode_successful)
+ {
+ // Todo: make it account for possibility of same texture in different
+ // materials and even in scope of same material
+ S32 texture_count = 0;
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull())
+ {
+ texture_count++;
+ }
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull())
+ {
+ texture_count++;
+ }
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull())
+ {
+ texture_count++;
+ }
+ if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull())
+ {
+ texture_count++;
+ }
+ total_cost += texture_count * texture_upload_cost;
+ file_count++;
+ }
+ }
+ }
+ }
}
return file_count > 0;
@@ -631,7 +721,7 @@ class LLFileUploadImage : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false);
return true;
}
};
@@ -644,7 +734,16 @@ class LLFileUploadModel : public view_listener_t
return TRUE;
}
};
-
+
+class LLFileUploadMaterial : public view_listener_t
+{
+ bool handleEvent(const LLSD& userdata)
+ {
+ LLMaterialEditor::importMaterial();
+ return TRUE;
+ }
+};
+
class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@@ -653,7 +752,7 @@ class LLFileUploadSound : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false);
return true;
}
};
@@ -666,7 +765,7 @@ class LLFileUploadAnim : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false);
return true;
}
};
@@ -679,7 +778,7 @@ class LLFileUploadBulk : public view_listener_t
{
gAgentCamera.changeCameraToDefault();
}
- (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true);
return true;
}
};
@@ -1170,6 +1269,7 @@ void init_menu_file()
view_listener_t::addCommit(new LLFileUploadSound(), "File.UploadSound");
view_listener_t::addCommit(new LLFileUploadAnim(), "File.UploadAnim");
view_listener_t::addCommit(new LLFileUploadModel(), "File.UploadModel");
+ view_listener_t::addCommit(new LLFileUploadMaterial(), "File.UploadMaterial");
view_listener_t::addCommit(new LLFileUploadBulk(), "File.UploadBulk");
view_listener_t::addCommit(new LLFileCloseWindow(), "File.CloseWindow");
view_listener_t::addCommit(new LLFileCloseAllWindows(), "File.CloseAllWindows");
@@ -1180,6 +1280,7 @@ void init_menu_file()
view_listener_t::addEnable(new LLFileEnableUpload(), "File.EnableUpload");
view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel");
+ view_listener_t::addEnable(new LLFileEnableUploadMaterial(), "File.EnableUploadMaterial");
view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled");
view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel");
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 61572b9996..ff2ee693fd 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -118,14 +118,18 @@ class LLFilePickerReplyThread : public LLFilePickerThread
public:
typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
-
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
- ~LLFilePickerReplyThread();
+
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ static void startPicker(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
virtual void notify(const std::vector<std::string>& filenames);
private:
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ ~LLFilePickerReplyThread();
+
+private:
LLFilePicker::ELoadFilter mLoadFilter;
LLFilePicker::ESaveFilter mSaveFilter;
file_picked_signal_t* mFilePickedSignal;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f3288a5300..ada898b98c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -129,6 +129,8 @@
extern void on_new_message(const LLSD& msg);
+extern BOOL gCubeSnapshot;
+
//
// Constants
//
@@ -1425,7 +1427,8 @@ bool check_asset_previewable(const LLAssetType::EType asset_type)
(asset_type == LLAssetType::AT_TEXTURE) ||
(asset_type == LLAssetType::AT_ANIMATION) ||
(asset_type == LLAssetType::AT_SCRIPT) ||
- (asset_type == LLAssetType::AT_SOUND);
+ (asset_type == LLAssetType::AT_SOUND) ||
+ (asset_type == LLAssetType::AT_MATERIAL);
}
void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name)
@@ -1530,6 +1533,9 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam
case LLAssetType::AT_SOUND:
LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus);
break;
+ case LLAssetType::AT_MATERIAL:
+ // Explicitly do nothing -- we don't want to open the material editor every time you add a material to inventory
+ break;
default:
LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL;
break;
@@ -2964,8 +2970,6 @@ void process_teleport_finish(LLMessageSystem* msg, void**)
// Teleport is finished; it can't be cancelled now.
gViewerWindow->setProgressCancelButtonVisible(FALSE);
- gPipeline.doResetVertexBuffers(true);
-
// Do teleport effect for where you're leaving
// VEFFECT: TeleportStart
LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
@@ -3318,6 +3322,8 @@ const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater th
void send_agent_update(BOOL force_send, BOOL send_reliable)
{
LL_PROFILE_ZONE_SCOPED;
+ llassert(!gCubeSnapshot);
+
if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
{
// We don't care if they want to send an agent update, they're not allowed to until the simulator
@@ -4249,7 +4255,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
//if (!avatarp->mRootVolp->isAnySelected())
{
avatarp->updateVolumeGeom();
- avatarp->mRootVolp->recursiveMarkForUpdate(TRUE);
+ avatarp->mRootVolp->recursiveMarkForUpdate();
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index c0d569be01..d4346ee2d9 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -83,11 +83,10 @@
#include "llvoavatar.h"
#include "llvoavatarself.h"
#include "llvograss.h"
-#include "llvoground.h"
+#include "llvosky.h"
#include "llvolume.h"
#include "llvolumemessage.h"
#include "llvopartgroup.h"
-#include "llvosky.h"
#include "llvosurfacepatch.h"
#include "llvotree.h"
#include "llvovolume.h"
@@ -106,6 +105,7 @@
#include "llcleanup.h"
#include "llcallstack.h"
#include "llmeshrepository.h"
+#include "llgltfmateriallist.h"
#include "llgl.h"
//#define DEBUG_UPDATE_TYPE
@@ -161,7 +161,6 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
&& pcode != LL_VO_VOID_WATER
&& pcode != LL_VO_WL_SKY
&& pcode != LL_VO_SKY
- && pcode != LL_VO_GROUND
&& pcode != LL_VO_PART_GROUP
)
{
@@ -233,8 +232,6 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
res = new LLVOVoidWater(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_HUD_PART_GROUP:
@@ -245,6 +242,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco
LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL;
res = NULL; break;
}
+
return res;
}
@@ -258,7 +256,6 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
mTEImages(NULL),
mTENormalMaps(NULL),
mTESpecularMaps(NULL),
- mGLName(0),
mbCanSelect(TRUE),
mFlags(0),
mPhysicsShapeType(0),
@@ -343,6 +340,13 @@ LLViewerObject::~LLViewerObject()
{
deleteTEImages();
+ // unhook from reflection probe manager
+ if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe->mViewerObject = nullptr;
+ mReflectionProbe = nullptr;
+ }
+
if(mInventory)
{
mInventory->clear(); // will deref and delete entries
@@ -364,7 +368,7 @@ LLViewerObject::~LLViewerObject()
}
// Delete memory associated with extra parameters.
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
if(iter->second != NULL)
@@ -413,6 +417,7 @@ void LLViewerObject::markDead()
{
if (!mDead)
{
+ LL_PROFILE_ZONE_SCOPED;
//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
// Root object of this hierarchy unlinks itself.
@@ -512,6 +517,12 @@ void LLViewerObject::markDead()
LLFollowCamMgr::getInstance()->removeFollowCamParams(mID);
}
+ if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe->mViewerObject = nullptr;
+ mReflectionProbe = nullptr;
+ }
+
sNumZombieObjects++;
}
}
@@ -1040,7 +1051,7 @@ BOOL LLViewerObject::setDrawableParent(LLDrawable* parentp)
parentp->setState(LLDrawable::ACTIVE_CHILD);
}
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
if( (old_parent != parentp && old_parent)
|| (parentp && parentp->isActive()))
{
@@ -1142,6 +1153,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
const EObjectUpdateType update_type,
LLDataPacker *dp)
{
+ LL_PROFILE_ZONE_SCOPED;
LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
@@ -1258,7 +1270,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
LL_INFOS() << "Full:" << getID() << LL_ENDL;
#endif
//clear cost and linkset cost
- mCostStale = true;
+ setObjectCostStale();
if (isSelected())
{
gFloaterTools->dirty();
@@ -1544,7 +1556,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
unpackParticleSource(block_num, owner_id);
// Mark all extra parameters not used
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@@ -1814,7 +1826,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
#ifdef DEBUG_UPDATE_TYPE
LL_INFOS() << "CompFull:" << getID() << LL_ENDL;
#endif
- mCostStale = true;
+ setObjectCostStale();
if (isSelected())
{
@@ -1936,7 +1948,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
}
// Mark all extra parameters not used
- std::map<U16, ExtraParameter*>::iterator iter;
+ std::unordered_map<U16, ExtraParameter*>::iterator iter;
for (iter = mExtraParameterList.begin(); iter != mExtraParameterList.end(); ++iter)
{
iter->second->in_use = FALSE;
@@ -2493,7 +2505,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
{
// LL_DEBUGS() << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << LL_ENDL;
mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
- gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL);
}
}
@@ -3155,7 +3167,7 @@ void LLViewerObject::linkControlAvatar()
//if (!cav->mRootVolp->isAnySelected())
{
cav->updateVolumeGeom();
- cav->mRootVolp->recursiveMarkForUpdate(TRUE);
+ cav->mRootVolp->recursiveMarkForUpdate();
}
}
}
@@ -3492,31 +3504,52 @@ void LLViewerObject::removeInventory(const LLUUID& item_id)
++mExpectedInventorySerialNum;
}
-bool LLViewerObject::isTextureInInventory(LLViewerInventoryItem* item)
+bool LLViewerObject::isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type)
{
- bool result = false;
+ bool result = false;
- if (item && LLAssetType::AT_TEXTURE == item->getType())
- {
- std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
- std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
+ if (item)
+ {
+ // For now mPendingInventoryItemsIDs only stores textures and materials
+ // but if it gets to store more types, it will need to verify type as well
+ // since null can be a shared default id and it is fine to need a null
+ // script and a null material simultaneously.
+ std::list<LLUUID>::iterator begin = mPendingInventoryItemsIDs.begin();
+ std::list<LLUUID>::iterator end = mPendingInventoryItemsIDs.end();
- bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
- bool is_fetched = getInventoryItemByAsset(item->getAssetUUID()) != NULL;
+ bool is_fetching = std::find(begin, end, item->getAssetUUID()) != end;
- result = is_fetched || is_fetching;
- }
+ // null is the default asset for materials and default for scripts
+ // so need to check type as well
+ bool is_fetched = getInventoryItemByAsset(item->getAssetUUID(), type) != NULL;
- return result;
+ result = is_fetched || is_fetching;
+ }
+
+ return result;
}
-void LLViewerObject::updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
+void LLViewerObject::updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new)
{
- if (item && !isTextureInInventory(item))
- {
- mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
- updateInventory(item, key, is_new);
- }
+ if (!item)
+ {
+ return;
+ }
+ if (LLAssetType::AT_TEXTURE != item->getType()
+ && LLAssetType::AT_MATERIAL != item->getType())
+ {
+ // Not supported
+ return;
+ }
+
+ if (isAssetInInventory(item, item->getType()))
+ {
+ // already there
+ return;
+ }
+
+ mPendingInventoryItemsIDs.push_back(item->getAssetUUID());
+ updateInventory(item, key, is_new);
}
void LLViewerObject::updateInventory(
@@ -3586,6 +3619,17 @@ LLInventoryObject* LLViewerObject::getInventoryObject(const LLUUID& item_id)
return rv;
}
+LLInventoryItem* LLViewerObject::getInventoryItem(const LLUUID& item_id)
+{
+ LLInventoryObject* iobj = getInventoryObject(item_id);
+ if (!iobj || iobj->getType() == LLAssetType::AT_CATEGORY)
+ {
+ return NULL;
+ }
+ LLInventoryItem* item = dynamic_cast<LLInventoryItem*>(iobj);
+ return item;
+}
+
void LLViewerObject::getInventoryContents(LLInventoryObject::object_list_t& objects)
{
if(mInventory)
@@ -3641,6 +3685,44 @@ LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& ass
return rv;
}
+LLViewerInventoryItem* LLViewerObject::getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type)
+{
+ if (mInventoryDirty)
+ LL_WARNS() << "Peforming inventory lookup for object " << mID << " that has dirty inventory!" << LL_ENDL;
+
+ LLViewerInventoryItem* rv = NULL;
+ if (type == LLAssetType::AT_CATEGORY)
+ {
+ // Whatever called this shouldn't be trying to get a folder by asset
+ // categories don't have assets
+ llassert(0);
+ return rv;
+ }
+
+ if (mInventory)
+ {
+ LLViewerInventoryItem* item = NULL;
+
+ LLInventoryObject::object_list_t::iterator it = mInventory->begin();
+ LLInventoryObject::object_list_t::iterator end = mInventory->end();
+ for (; it != end; ++it)
+ {
+ LLInventoryObject* obj = *it;
+ if (obj->getType() == type)
+ {
+ // *FIX: gank-ass down cast!
+ item = (LLViewerInventoryItem*)obj;
+ if (item->getAssetUUID() == asset_id)
+ {
+ rv = item;
+ break;
+ }
+ }
+ }
+ }
+ return rv;
+}
+
void LLViewerObject::updateViewerInventoryAsset(
const LLViewerInventoryItem* item,
const LLUUID& new_asset)
@@ -3757,6 +3839,16 @@ void LLViewerObject::setScale(const LLVector3 &scale, BOOL damped)
}
}
+void LLViewerObject::setObjectCostStale()
+{
+ mCostStale = true;
+ // *NOTE: This is harmlessly redundant for Blinn-Phong material updates, as
+ // the root prim currently gets set stale anyway due to other property
+ // updates. But it is needed for GLTF material ID updates.
+ // -Cosmic,2023-06-27
+ getRootEdit()->mCostStale = true;
+}
+
void LLViewerObject::setObjectCost(F32 cost)
{
mObjectCost = cost;
@@ -3943,6 +4035,7 @@ U32 LLViewerObject::recursiveGetTriangleCount(S32* vcount) const
// prim's scale. Should revisit at some point.
F32 LLViewerObject::recursiveGetScaledSurfaceArea() const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
F32 area = 0.f;
const LLDrawable* drawable = mDrawable;
if (drawable)
@@ -4046,7 +4139,7 @@ void LLViewerObject::updateTextures()
void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
{
- if (isDead())
+ if (isDead() || !getVolume())
{
return;
}
@@ -4587,6 +4680,7 @@ BOOL LLViewerObject::lineSegmentIntersect(const LLVector4a& start, const LLVecto
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -4750,9 +4844,38 @@ void LLViewerObject::setNumTEs(const U8 num_tes)
{
deleteTEImages();
}
+
+ S32 original_tes = getNumTEs();
+
LLPrimitive::setNumTEs(num_tes);
setChanged(TEXTURE);
+ // touch up GLTF materials
+ if (original_tes > 0)
+ {
+ for (int i = original_tes; i < getNumTEs(); ++i)
+ {
+ LLTextureEntry* src = getTE(original_tes - 1);
+ LLTextureEntry* tep = getTE(i);
+ setRenderMaterialID(i, getRenderMaterialID(original_tes - 1), false);
+
+ if (tep)
+ {
+ LLGLTFMaterial* base_material = src->getGLTFMaterial();
+ LLGLTFMaterial* override_material = src->getGLTFMaterialOverride();
+ if (base_material && override_material)
+ {
+ tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material));
+
+ LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
+ *render_material = *base_material;
+ render_material->applyOverride(*override_material);
+ tep->setGLTFRenderMaterial(render_material);
+ }
+ }
+ }
+ }
+
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
@@ -4873,31 +4996,96 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID&
}
}
-void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
+
+void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry)
{
- LLUUID old_image_id;
- if (getTE(te))
- {
- old_image_id = getTE(te)->getID();
- }
-
- LLPrimitive::setTE(te, texture_entry);
+ LLUUID old_image_id;
+ if (getTE(te))
+ {
+ old_image_id = getTE(te)->getID();
+ }
- const LLUUID& image_id = getTE(te)->getID();
- LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
- mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ LLPrimitive::setTE(te, texture_entry);
-
- updateAvatarMeshVisibility(image_id,old_image_id);
+ const LLUUID& image_id = getTE(te)->getID();
+ LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id);
+ mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ updateAvatarMeshVisibility(image_id, old_image_id);
+
+ updateTEMaterialTextures(te);
+}
+
+void LLViewerObject::updateTEMaterialTextures(U8 te)
+{
if (getTE(te)->getMaterialParams().notNull())
{
const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID();
- mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
+ mTENormalMaps[te] = LLViewerTextureManager::getFetchedTexture(norm_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID();
- mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE);
+ mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
+
+ LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial();
+ llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(getTE(te)->getGLTFRenderMaterial()) != nullptr);
+ LLUUID mat_id = getRenderMaterialID(te);
+ if (mat == nullptr && mat_id.notNull())
+ {
+ mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id);
+ llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(gGLTFMaterialList.getMaterial(mat_id)) != nullptr);
+ if (mat->isFetching())
+ { // material is not loaded yet, rebuild draw info when the object finishes loading
+ mat->onMaterialComplete([id=getID()]
+ {
+ LLViewerObject* obj = gObjectList.findObject(id);
+ if (obj)
+ {
+ LLViewerRegion* region = obj->getRegion();
+ if(region)
+ {
+ region->loadCacheMiscExtras(obj->getLocalID());
+ }
+ obj->markForUpdate();
+ }
+ });
+ }
+ getTE(te)->setGLTFMaterial(mat);
+ }
+ else if (mat_id.isNull() && mat != nullptr)
+ {
+ mat = nullptr;
+ getTE(te)->setGLTFMaterial(nullptr);
+ }
+
+ auto fetch_texture = [this](const LLUUID& id)
+ {
+ LLViewerFetchedTexture* img = nullptr;
+ if (id.notNull())
+ {
+ if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id))
+ {
+ // TODO -- fall back to LLTextureEntry::mGLTFRenderMaterial when overriding with baked texture
+ LLViewerTexture* viewerTexture = getBakedTextureForMagicId(id);
+ img = viewerTexture ? dynamic_cast<LLViewerFetchedTexture*>(viewerTexture) : nullptr;
+ }
+ else
+ {
+ img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+ img->addTextureStats(64.f * 64.f, TRUE);
+ }
+ }
+
+ return img;
+ };
+
+ if (mat != nullptr)
+ {
+ mat->mBaseColorTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]);
+ mat->mNormalTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]);
+ mat->mMetallicRoughnessTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]);
+ mat->mEmissiveTexture= fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]);
+ }
}
void LLViewerObject::refreshBakeTexture()
@@ -5041,14 +5229,14 @@ S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
S32 LLViewerObject::setTENormalMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
return setTENormalMapCore(te, image);
}
S32 LLViewerObject::setTESpecularMap(const U8 te, const LLUUID& uuid)
{
LLViewerFetchedTexture *image = (uuid == LLUUID::null) ? NULL : LLViewerTextureManager::getFetchedTexture(
- uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
+ uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost());
return setTESpecularMapCore(te, image);
}
@@ -5092,7 +5280,7 @@ S32 LLViewerObject::setTEBumpmap(const U8 te, const U8 bump)
if (mDrawable.notNull() && retval)
{
gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
}
return retval;
@@ -5182,10 +5370,8 @@ S32 LLViewerObject::setTEMediaFlags(const U8 te, const U8 media_flags)
setChanged(TEXTURE);
if (mDrawable.notNull() && retval)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
gPipeline.markTextured(mDrawable);
- // JC - probably only need this if changes texture coords
- //gPipeline.markRebuild(mDrawable);
}
}
return retval;
@@ -5252,10 +5438,64 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri
setTENormalMap(te, (pMaterialParams) ? pMaterialParams->getNormalID() : LLUUID::null);
setTESpecularMap(te, (pMaterialParams) ? pMaterialParams->getSpecularID() : LLUUID::null);
- refreshMaterials();
return retval;
}
+S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat)
+{
+ LL_PROFILE_ZONE_SCOPED;
+ S32 retval = TEM_CHANGE_NONE;
+
+ LLTextureEntry* tep = getTE(te);
+ if (!tep)
+ { // this could happen if the object is not fully formed yet
+ // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later
+ return retval;
+ }
+
+ LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial();
+ llassert(src_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(tep->getGLTFMaterial()) != nullptr);
+ // if override mat exists, we must also have a source mat
+ if (!src_mat)
+ {
+ // we can get into this state if an override has arrived before the viewer has
+ // received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it
+ // should queue the update for later
+ return retval;
+ }
+
+ if(src_mat->isFetching())
+ {
+ // if still fetching, we need to wait until it is done and try again
+ return retval;
+ }
+
+ retval = tep->setGLTFMaterialOverride(override_mat);
+
+ if (retval)
+ {
+ if (override_mat)
+ {
+ LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat);
+ render_mat->applyOverride(*override_mat);
+ tep->setGLTFRenderMaterial(render_mat);
+ retval = TEM_CHANGE_TEXTURE;
+
+ for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture)
+ {
+ LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat);
+ }
+
+ }
+ else if (tep->setGLTFRenderMaterial(nullptr))
+ {
+ retval = TEM_CHANGE_TEXTURE;
+ }
+ }
+
+ return retval;
+}
+
void LLViewerObject::refreshMaterials()
{
setChanged(TEXTURE);
@@ -5337,6 +5577,7 @@ S32 LLViewerObject::setTERotation(const U8 te, const F32 r)
if (mDrawable.notNull() && retval)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
+ shrinkWrap();
}
return retval;
}
@@ -5438,7 +5679,6 @@ void LLViewerObject::fitFaceTexture(const U8 face)
LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL;
}
-
LLBBox LLViewerObject::getBoundingBoxAgent() const
{
LLVector3 position_agent;
@@ -5523,19 +5763,7 @@ S32 LLViewerObject::countInventoryContents(LLAssetType::EType type)
return count;
}
-
-void LLViewerObject::setCanSelect(BOOL canSelect)
-{
- mbCanSelect = canSelect;
- for (child_list_t::iterator iter = mChildList.begin();
- iter != mChildList.end(); iter++)
- {
- LLViewerObject* child = *iter;
- child->mbCanSelect = canSelect;
- }
-}
-
-void LLViewerObject::setDebugText(const std::string &utf8text)
+void LLViewerObject::setDebugText(const std::string &utf8text, const LLColor4& color)
{
if (utf8text.empty() && !mText)
{
@@ -5546,13 +5774,30 @@ void LLViewerObject::setDebugText(const std::string &utf8text)
{
initHudText();
}
- mText->setColor(LLColor4::white);
+ mText->setColor(color);
mText->setString(utf8text);
mText->setZCompare(FALSE);
mText->setDoFade(FALSE);
updateText();
}
+void LLViewerObject::appendDebugText(const std::string &utf8text)
+{
+ if (utf8text.empty() && !mText)
+ {
+ return;
+ }
+
+ if (!mText)
+ {
+ initHudText();
+ }
+ mText->addLine(utf8text, LLColor4::white);
+ mText->setZCompare(FALSE);
+ mText->setDoFade(FALSE);
+ updateText();
+}
+
void LLViewerObject::initHudText()
{
mText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
@@ -6038,6 +6283,16 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLExtendedMeshParams();
break;
}
+ case LLNetworkData::PARAMS_RENDER_MATERIAL:
+ {
+ new_block = new LLRenderMaterialParams();
+ break;
+ }
+ case LLNetworkData::PARAMS_REFLECTION_PROBE:
+ {
+ new_block = new LLReflectionProbeParams();
+ break;
+ }
default:
{
LL_INFOS_ONCE() << "Unknown param type: " << param_type << LL_ENDL;
@@ -6050,6 +6305,7 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
ExtraParameter* new_entry = new ExtraParameter;
new_entry->data = new_block;
new_entry->in_use = false; // not in use yet
+ llassert(mExtraParameterList[param_type] == nullptr); // leak -- redundantly allocated parameter entry
mExtraParameterList[param_type] = new_entry;
return new_entry;
}
@@ -6058,7 +6314,8 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
LLViewerObject::ExtraParameter* LLViewerObject::getExtraParameterEntry(U16 param_type) const
{
- std::map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VIEWER;
+ std::unordered_map<U16, ExtraParameter*>::const_iterator itor = mExtraParameterList.find(param_type);
if (itor != mExtraParameterList.end())
{
return itor->second;
@@ -6150,6 +6407,11 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
{
if (local_origin)
{
+ // *NOTE: Do not send the render material ID in this way as it will get
+ // out-of-sync with other sent client data.
+ // See LLViewerObject::setRenderMaterialID and LLGLTFMaterialList
+ llassert(param_type != LLNetworkData::PARAMS_RENDER_MATERIAL);
+
LLViewerRegion* regionp = getRegion();
if(!regionp) return;
@@ -6181,6 +6443,14 @@ void LLViewerObject::parameterChanged(U16 param_type, LLNetworkData* data, BOOL
LL_WARNS() << "Failed to send object extra parameters: " << param_type << LL_ENDL;
}
}
+ else
+ {
+ if (param_type == LLNetworkData::PARAMS_RENDER_MATERIAL)
+ {
+ const LLRenderMaterialParams* params = in_use ? (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL) : nullptr;
+ setRenderMaterialIDs(params, local_origin);
+ }
+ }
}
void LLViewerObject::setDrawableState(U32 state, BOOL recursive)
@@ -6433,35 +6703,27 @@ void LLViewerObject::updateVolume(const LLVolumeParams& volume_params)
{
// Transmit the update to the simulator
sendShapeUpdate();
- markForUpdate(TRUE);
+ markForUpdate();
}
}
-void LLViewerObject::recursiveMarkForUpdate(BOOL priority)
+void LLViewerObject::recursiveMarkForUpdate()
{
for (LLViewerObject::child_list_t::iterator iter = mChildList.begin();
iter != mChildList.end(); iter++)
{
LLViewerObject* child = *iter;
- child->markForUpdate(priority);
+ child->markForUpdate();
}
- markForUpdate(priority);
+ markForUpdate();
}
-void LLViewerObject::markForUpdate(BOOL priority)
+void LLViewerObject::markForUpdate()
{
if (mDrawable.notNull())
{
gPipeline.markTextured(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, priority);
- }
-}
-
-void LLViewerObject::markForUnload(BOOL priority)
-{
- if (mDrawable.notNull())
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::FOR_UNLOAD, priority);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
}
@@ -6608,7 +6870,7 @@ void LLViewerObject::setPhysicsShapeType(U8 type)
if (type != mPhysicsShapeType)
{
mPhysicsShapeType = type;
- mCostStale = true;
+ setObjectCostStale();
}
}
@@ -6687,7 +6949,7 @@ U32 LLViewerObject::getPartitionType() const
return LLViewerRegion::PARTITION_NONE;
}
-void LLViewerObject::dirtySpatialGroup(BOOL priority) const
+void LLViewerObject::dirtySpatialGroup() const
{
if (mDrawable)
{
@@ -6695,7 +6957,7 @@ void LLViewerObject::dirtySpatialGroup(BOOL priority) const
if (group)
{
group->dirtyGeom();
- gPipeline.markRebuild(group, priority);
+ gPipeline.markRebuild(group);
}
}
}
@@ -6705,11 +6967,6 @@ void LLViewerObject::dirtyMesh()
if (mDrawable)
{
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
- /*LLSpatialGroup* group = mDrawable->getSpatialGroup();
- if (group)
- {
- group->dirtyMesh();
- }*/
}
}
@@ -6718,7 +6975,7 @@ F32 LLAlphaObject::getPartSize(S32 idx)
return 0.f;
}
-void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst)
+void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst)
{
}
@@ -6730,7 +6987,7 @@ void LLStaticViewerObject::updateDrawable(BOOL force_damped)
if (mDrawable.notNull())
{
mDrawable->updateXform(TRUE);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
clearChanged(SHIFTED);
}
@@ -6979,6 +7236,221 @@ LLVOAvatar* LLViewerObject::getAvatar() const
return NULL;
}
+bool LLViewerObject::hasRenderMaterialParams() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL);
+}
+
+void LLViewerObject::setHasRenderMaterialParams(bool has_materials)
+{
+ bool had_materials = hasRenderMaterialParams();
+
+ if (had_materials != has_materials)
+ {
+ if (has_materials)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true);
+ }
+ }
+}
+
+const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const
+{
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (param_block)
+ {
+ return param_block->getMaterial(te);
+ }
+
+ return LLUUID::null;
+}
+
+void LLViewerObject::rebuildMaterial()
+{
+ llassert(!isDead());
+
+ faceMappingChanged();
+ gPipeline.markTextured(mDrawable);
+}
+
+void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool update_server, bool local_origin)
+{
+ // implementation is delicate
+
+ // if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed
+ // (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped)
+ // otherwise, should only null out the render material where ids or overrides have changed
+ // (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator, or synchronized
+ // updates with solely transform overrides)
+
+ llassert(!update_server || local_origin);
+
+ S32 start_idx = 0;
+ S32 end_idx = getNumTEs();
+
+ if (te_in != -1)
+ {
+ start_idx = te_in;
+ end_idx = start_idx + 1;
+ }
+
+ start_idx = llmax(start_idx, 0);
+ end_idx = llmin(end_idx, (S32) getNumTEs());
+
+ LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL);
+ if (!param_block && id.notNull())
+ { // block doesn't exist, but it will need to
+ param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data;
+ }
+
+
+ LLFetchedGLTFMaterial* new_material = nullptr;
+ if (id.notNull())
+ {
+ new_material = gGLTFMaterialList.getMaterial(id);
+ }
+
+ // update local state
+ for (S32 te = start_idx; te < end_idx; ++te)
+ {
+ LLTextureEntry* tep = getTE(te);
+
+ // If local_origin=false (i.e. it's from the server), we know the
+ // material has updated or been created, because extra params are
+ // checked for equality on unpacking. In that case, checking the
+ // material ID for inequality won't work, because the material ID has
+ // already been set.
+ bool material_changed = !local_origin || !param_block || id != param_block->getMaterial(te);
+
+ if (update_server)
+ {
+ // Clear most overrides so the render material better matches the material
+ // ID (preserve transforms). If overrides become passthrough, set the overrides
+ // to nullptr.
+ if (tep->setBaseMaterial())
+ {
+ material_changed = true;
+ }
+ }
+
+ if (update_server || material_changed)
+ {
+ tep->setGLTFRenderMaterial(nullptr);
+ }
+
+ if (new_material != tep->getGLTFMaterial())
+ {
+ tep->setGLTFMaterial(new_material, !update_server);
+ }
+
+ if (material_changed && new_material)
+ {
+ // Sometimes, the material may change out from underneath the overrides.
+ // This is usually due to the server sending a new material ID, but
+ // the overrides have not changed due to being only texture
+ // transforms. Re-apply the overrides to the render material here,
+ // if present.
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ if (override_material)
+ {
+ new_material->onMaterialComplete([obj_id = getID(), te]()
+ {
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (!obj) { return; }
+ LLTextureEntry* tep = obj->getTE(te);
+ if (!tep) { return; }
+ const LLGLTFMaterial* new_material = tep->getGLTFMaterial();
+ if (!new_material) { return; }
+ const LLGLTFMaterial* override_material = tep->getGLTFMaterialOverride();
+ if (!override_material) { return; }
+ LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial();
+ *render_material = *new_material;
+ render_material->applyOverride(*override_material);
+ tep->setGLTFRenderMaterial(render_material);
+ });
+ }
+ }
+ }
+
+ // signal to render pipe that render batches must be rebuilt for this object
+ if (!new_material)
+ {
+ rebuildMaterial();
+ }
+ else
+ {
+ new_material->onMaterialComplete([obj_id = getID()]()
+ {
+ LLViewerObject* obj = gObjectList.findObject(obj_id);
+ if (obj)
+ {
+ obj->rebuildMaterial();
+ }
+ });
+ }
+
+ // predictively update LLRenderMaterialParams (don't wait for server)
+ if (param_block)
+ { // update existing parameter block
+ for (S32 te = start_idx; te < end_idx; ++te)
+ {
+ param_block->setMaterial(te, id);
+ }
+ }
+
+ if (update_server)
+ {
+ // update via ModifyMaterialParams cap (server will echo back changes)
+ for (S32 te = start_idx; te < end_idx; ++te)
+ {
+ // This sends a cleared version of this object's current material
+ // override, but the override should already be cleared due to
+ // calling setBaseMaterial above.
+ LLGLTFMaterialList::queueApply(this, te, id);
+ }
+ }
+
+ if (!update_server)
+ {
+ // Land impact may have changed
+ setObjectCostStale();
+ }
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLUUID& id)
+{
+ setRenderMaterialID(-1, id);
+}
+
+void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin)
+{
+ if (!local_origin)
+ {
+ for (S32 te = 0; te < getNumTEs(); ++te)
+ {
+ const LLUUID& id = material_params ? material_params->getMaterial(te) : LLUUID::null;
+ // We know material_params has updated or been created, because
+ // extra params are checked for equality on unpacking.
+ setRenderMaterialID(te, id, false, false);
+ }
+ }
+}
+
+void LLViewerObject::shrinkWrap()
+{
+ if (!mShouldShrinkWrap)
+ {
+ mShouldShrinkWrap = true;
+ if (mDrawable)
+ { // we weren't shrink wrapped before but we are now, update the spatial partition
+ gPipeline.markPartitionMove(mDrawable);
+ }
+ }
+}
class ObjectPhysicsProperties : public LLHTTPNode
{
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 0005cdf14e..80da7b2f73 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -28,6 +28,7 @@
#define LL_LLVIEWEROBJECT_H
#include <map>
+#include <unordered_map>
#include "llassetstorage.h"
//#include "llhudicon.h"
@@ -43,6 +44,7 @@
#include "llvertexbuffer.h"
#include "llbbox.h"
#include "llrigginginfo.h"
+#include "llreflectionmap.h"
class LLAgent; // TODO: Get rid of this.
class LLAudioSource;
@@ -121,7 +123,7 @@ protected:
BOOL in_use;
LLNetworkData *data;
};
- std::map<U16, ExtraParameter*> mExtraParameterList;
+ std::unordered_map<U16, ExtraParameter*> mExtraParameterList;
public:
typedef std::list<LLPointer<LLViewerObject> > child_list_t;
@@ -178,6 +180,19 @@ public:
const std::string& getAttachmentItemName() const;
virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment
+
+ bool hasRenderMaterialParams() const;
+ void setHasRenderMaterialParams(bool has_params);
+
+ const LLUUID& getRenderMaterialID(U8 te) const;
+
+ // set the RenderMaterialID for the given TextureEntry
+ // te - TextureEntry index to set, or -1 for all TEs
+ // id - asset id of material asset
+ // update_server - if true, will send updates to server and clear most overrides
+ void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true, bool local_origin = true);
+ void setRenderMaterialIDs(const LLUUID& id);
+
virtual BOOL isHUDAttachment() const { return FALSE; }
virtual BOOL isTempAttachment() const;
@@ -199,6 +214,7 @@ public:
// Graphical stuff for objects - maybe broken out into render class later?
virtual void updateTextures();
+ virtual void faceMappingChanged() {}
virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object
virtual LLDrawable* createDrawable(LLPipeline *pipeline);
@@ -210,6 +226,8 @@ public:
F32 getRotTime() { return mRotTime; }
private:
void resetRotTime();
+ void setRenderMaterialIDs(const LLRenderMaterialParams* material_params, bool local_origin);
+ void rebuildMaterial();
public:
void resetRot();
void applyAngularVelocity(F32 dt);
@@ -238,6 +256,7 @@ public:
virtual BOOL isMesh() const { return FALSE; }
virtual BOOL isRiggedMesh() const { return FALSE; }
virtual BOOL hasLightTexture() const { return FALSE; }
+ virtual BOOL isReflectionProbe() const { return FALSE; }
// This method returns true if the object is over land owned by
// the agent, one of its groups, or it encroaches and
@@ -279,6 +298,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -318,6 +338,7 @@ public:
/*virtual*/ void setNumTEs(const U8 num_tes);
/*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry);
+ void updateTEMaterialTextures(U8 te);
/*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid);
/*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid);
@@ -342,6 +363,7 @@ public:
/*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
/*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
/*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
+ virtual S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat);
// Used by Materials update functions to properly kick off rebuilds
// of VBs etc when materials updates require changes.
@@ -356,7 +378,7 @@ public:
LLViewerTexture *getTEImage(const U8 te) const;
LLViewerTexture *getTENormalMap(const U8 te) const;
LLViewerTexture *getTESpecularMap(const U8 te) const;
-
+
bool isImageAlphaBlended(const U8 te) const;
void fitFaceTexture(const U8 face);
@@ -420,17 +442,15 @@ public:
void sendMaterialUpdate() const;
- void setCanSelect(BOOL canSelect);
-
- void setDebugText(const std::string &utf8text);
+ void setDebugText(const std::string &utf8text, const LLColor4& color = LLColor4::white);
+ void appendDebugText(const std::string &utf8text);
void initHudText();
void restoreHudText();
void setIcon(LLViewerTexture* icon_image);
void clearIcon();
- void recursiveMarkForUpdate(BOOL priority);
- virtual void markForUpdate(BOOL priority);
- void markForUnload(BOOL priority);
+ void recursiveMarkForUpdate();
+ virtual void markForUpdate();
void updateVolume(const LLVolumeParams& volume_params);
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
virtual F32 getBinRadius();
@@ -472,17 +492,17 @@ public:
// manager until we have better iterators.
void updateInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
void updateInventoryLocal(LLInventoryItem* item, U8 key); // Update without messaging.
- void updateTextureInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
+ void updateMaterialInventory(LLViewerInventoryItem* item, U8 key, bool is_new);
LLInventoryObject* getInventoryObject(const LLUUID& item_id);
+ LLInventoryItem* getInventoryItem(const LLUUID& item_id);
// Get content except for root category
void getInventoryContents(LLInventoryObject::object_list_t& objects);
LLInventoryObject* getInventoryRoot();
LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id);
+ LLViewerInventoryItem* getInventoryItemByAsset(const LLUUID& asset_id, LLAssetType::EType type);
S16 getInventorySerial() const { return mInventorySerialNum; }
- bool isTextureInInventory(LLViewerInventoryItem* item);
-
// These functions does viewer-side only object inventory modifications
void updateViewerInventoryAsset(
const LLViewerInventoryItem* item,
@@ -575,7 +595,7 @@ public:
virtual S32 getLOD() const { return 3; }
virtual U32 getPartitionType() const;
- virtual void dirtySpatialGroup(BOOL priority = FALSE) const;
+ void dirtySpatialGroup() const;
virtual void dirtyMesh();
virtual LLNetworkData* getParameterEntry(U16 param_type) const;
@@ -586,6 +606,14 @@ public:
virtual void parameterChanged(U16 param_type, bool local_origin);
virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+ bool isShrinkWrapped() const { return mShouldShrinkWrap; }
+
+ // Used to improve performance. If an object is likely to rebuild its vertex buffer often
+ // as a side effect of some update (color update, scale, etc), setting this to true
+ // will cause it to be pushed deeper into the octree and isolate it from other nodes
+ // so that nearby objects won't attempt to share a vertex buffer with this object.
+ void shrinkWrap();
+
friend class LLViewerObjectList;
friend class LLViewerMediaList;
@@ -611,6 +639,9 @@ public:
std::vector<LLVector3> mUnselectedChildrenPositions ;
private:
+ void setObjectCostStale();
+ bool isAssetInInventory(LLViewerInventoryItem* item, LLAssetType::EType type);
+
ExtraParameter* createNewParameterEntry(U16 param_type);
ExtraParameter* getExtraParameterEntry(U16 param_type) const;
ExtraParameter* getExtraParameterEntryCreate(U16 param_type);
@@ -645,7 +676,6 @@ public:
LL_VO_SKY = LL_PCODE_APP | 0x60,
LL_VO_VOID_WATER = LL_PCODE_APP | 0x70,
LL_VO_WATER = LL_PCODE_APP | 0x80,
- LL_VO_GROUND = LL_PCODE_APP | 0x90,
LL_VO_PART_GROUP = LL_PCODE_APP | 0xa0,
LL_VO_TRIANGLE_TORUS = LL_PCODE_APP | 0xb0,
LL_VO_HUD_PART_GROUP = LL_PCODE_APP | 0xc0,
@@ -674,10 +704,10 @@ public:
LLPointer<LLViewerTexture> *mTEImages;
LLPointer<LLViewerTexture> *mTENormalMaps;
LLPointer<LLViewerTexture> *mTESpecularMaps;
-
- // Selection, picking and rendering variables
- U32 mGLName; // GL "name" used by selection code
- BOOL mbCanSelect; // true if user can select this object by clicking
+
+ // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true)
+ // can likely be factored out
+ BOOL mbCanSelect;
private:
// Grabbed from UPDATE_FLAGS
@@ -847,6 +877,9 @@ protected:
F32 mLinksetCost;
F32 mPhysicsCost;
F32 mLinksetPhysicsCost;
+
+ // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap"
+ bool mShouldShrinkWrap = false;
bool mCostStale;
mutable bool mPhysicsShapeUnknown;
@@ -906,6 +939,15 @@ private:
LLUUID mAttachmentItemID; // ItemID of the associated object is in user inventory.
EObjectUpdateType mLastUpdateType;
BOOL mLastUpdateCached;
+
+public:
+ // reflection probe state
+ bool mIsReflectionProbe = false; // if true, this object should register itself with LLReflectionProbeManager
+ LLPointer<LLReflectionMap> mReflectionProbe = nullptr; // reflection probe coupled to this viewer object. If not null, should be deregistered when this object is destroyed
+
+ // the amount of GPU time (in ms) it took to render this object according to LLPipeline::profileAvatar
+ // -1.f if no profile data available
+ F32 mGPURenderTime = -1.f;
};
///////////////////
@@ -955,7 +997,7 @@ public:
LLStrider<LLColor4U>& emissivep,
LLStrider<U16>& indicesp) = 0;
- virtual void getBlendFunc(S32 face, U32& src, U32& dst);
+ virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst);
F32 mDepth;
};
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index c479afaa52..5bc7523be1 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -775,19 +775,43 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
max_value = llmin((S32) mObjects.size(), mCurLazyUpdateIndex + num_updates);
}
+ // Iterate through some of the objects and lazy update their texture priorities
+ for (i = mCurLazyUpdateIndex; i < max_value; i++)
+ {
+ objectp = mObjects[i];
+ if (!objectp->isDead())
+ {
+ // Update distance & gpw
+ objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
+ objectp->updateTextures(); // Update the image levels of textures for this object.
+ }
+ }
+ mCurLazyUpdateIndex = max_value;
+ if (mCurLazyUpdateIndex == mObjects.size())
+ {
+ // restart
+ mCurLazyUpdateIndex = 0;
+ mCurBin = 0; // keep in sync with index (mObjects.size() could have changed)
+ }
+ else
+ {
+ mCurBin = (mCurBin + 1) % NUM_BINS;
+ }
+
+#if 0
// Slam priorities for textures that we care about (hovered, selected, and focused)
// Hovered
// Assumes only one level deep of parenting
LLSelectNode* nodep = LLSelectMgr::instance().getHoverNode();
- if (nodep)
- {
- objectp = nodep->getObject();
- if (objectp)
- {
- objectp->boostTexturePriority();
- }
- }
+ if (nodep)
+ {
+ objectp = nodep->getObject();
+ if (objectp)
+ {
+ objectp->boostTexturePriority();
+ }
+ }
// Focused
objectp = gAgentCamera.getFocusObject();
@@ -795,6 +819,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
{
objectp->boostTexturePriority();
}
+#endif
// Selected
struct f : public LLSelectedObjectFunctor
@@ -810,30 +835,6 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
} func;
LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
- // Iterate through some of the objects and lazy update their texture priorities
- for (i = mCurLazyUpdateIndex; i < max_value; i++)
- {
- objectp = mObjects[i];
- if (!objectp->isDead())
- {
- // Update distance & gpw
- objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area
- objectp->updateTextures(); // Update the image levels of textures for this object.
- }
- }
-
- mCurLazyUpdateIndex = max_value;
- if (mCurLazyUpdateIndex == mObjects.size())
- {
- // restart
- mCurLazyUpdateIndex = 0;
- mCurBin = 0; // keep in sync with index (mObjects.size() could have changed)
- }
- else
- {
- mCurBin = (mCurBin + 1) % NUM_BINS;
- }
-
LLVOAvatar::cullAvatarsByPixelArea();
}
@@ -1327,40 +1328,16 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
}
// Don't clean up mObject references, these will be cleaned up more efficiently later!
- // Also, not cleaned up
- removeDrawable(objectp->mDrawable);
-
+
if(new_dead_object)
{
mNumDeadObjects++;
}
}
-void LLViewerObjectList::removeDrawable(LLDrawable* drawablep)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE;
-
- if (!drawablep)
- {
- return;
- }
-
- for (S32 i = 0; i < drawablep->getNumFaces(); i++)
- {
- LLFace* facep = drawablep->getFace(i) ;
- if(facep)
- {
- LLViewerObject* objectp = facep->getViewerObject();
- if(objectp)
- {
- mSelectPickList.erase(objectp);
- }
- }
- }
-}
-
BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
{
+ LL_PROFILE_ZONE_SCOPED;
// Don't ever kill gAgentAvatarp, just force it to the agent's region
// unless region is NULL which is assumed to mean you are logging out.
if ((objectp == gAgentAvatarp) && gAgent.getRegion())
@@ -1387,6 +1364,7 @@ BOOL LLViewerObjectList::killObject(LLViewerObject *objectp)
void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
{
+ LL_PROFILE_ZONE_SCOPED;
LLViewerObject *objectp;
@@ -1446,6 +1424,8 @@ void LLViewerObjectList::cleanDeadObjects(BOOL use_timer)
return;
}
+ LL_PROFILE_ZONE_SCOPED;
+
S32 num_removed = 0;
LLViewerObject *objectp;
@@ -1824,145 +1804,7 @@ void LLViewerObjectList::renderObjectBounds(const LLVector3 &center)
{
}
-void LLViewerObjectList::generatePickList(LLCamera &camera)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_UI;
-
- LLViewerObject *objectp;
- S32 i;
- // Reset all of the GL names to zero.
- for (vobj_list_t::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter)
- {
- (*iter)->mGLName = 0;
- }
-
- mSelectPickList.clear();
-
- std::vector<LLDrawable*> pick_drawables;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->cull(camera, &pick_drawables, TRUE);
- }
- }
- }
-
- for (std::vector<LLDrawable*>::iterator iter = pick_drawables.begin();
- iter != pick_drawables.end(); iter++)
- {
- LLDrawable* drawablep = *iter;
- if( !drawablep )
- continue;
-
- LLViewerObject* last_objectp = NULL;
- for (S32 face_num = 0; face_num < drawablep->getNumFaces(); face_num++)
- {
- LLFace * facep = drawablep->getFace(face_num);
- if (!facep) continue;
-
- LLViewerObject* objectp = facep->getViewerObject();
-
- if (objectp && objectp != last_objectp)
- {
- mSelectPickList.insert(objectp);
- last_objectp = objectp;
- }
- }
- }
-
- LLHUDNameTag::addPickable(mSelectPickList);
-
- for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
- iter != LLCharacter::sInstances.end(); ++iter)
- {
- objectp = (LLVOAvatar*) *iter;
- if (!objectp->isDead())
- {
- if (objectp->mDrawable.notNull() && objectp->mDrawable->isVisible())
- {
- mSelectPickList.insert(objectp);
- }
- }
- }
-
- // add all hud objects to pick list
- if (isAgentAvatarValid())
- {
- for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
- iter != gAgentAvatarp->mAttachmentPoints.end(); )
- {
- LLVOAvatar::attachment_map_t::iterator curiter = iter++;
- LLViewerJointAttachment* attachment = curiter->second;
- if (attachment->getIsHUDAttachment())
- {
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
- {
- if (LLViewerObject* attached_object = attachment_iter->get())
- {
- mSelectPickList.insert(attached_object);
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); iter++)
- {
- LLViewerObject* childp = *iter;
- if (childp)
- {
- mSelectPickList.insert(childp);
- }
- }
- }
- }
- }
- }
- }
-
- S32 num_pickables = (S32)mSelectPickList.size() + LLHUDIcon::getNumInstances();
-
- if (num_pickables != 0)
- {
- S32 step = (0x000fffff - GL_NAME_INDEX_OFFSET) / num_pickables;
-
- std::set<LLViewerObject*>::iterator pick_it;
- i = 0;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end();)
- {
- LLViewerObject* objp = (*pick_it);
- if (!objp || objp->isDead() || !objp->mbCanSelect)
- {
- mSelectPickList.erase(pick_it++);
- continue;
- }
-
- objp->mGLName = (i * step) + GL_NAME_INDEX_OFFSET;
- i++;
- ++pick_it;
- }
-
- LLHUDIcon::generatePickIDs(i * step, step);
- }
-}
-
-LLViewerObject *LLViewerObjectList::getSelectedObject(const U32 object_id)
-{
- std::set<LLViewerObject*>::iterator pick_it;
- for (pick_it = mSelectPickList.begin(); pick_it != mSelectPickList.end(); ++pick_it)
- {
- if ((*pick_it)->mGLName == object_id)
- {
- return (*pick_it);
- }
- }
- return NULL;
-}
+extern BOOL gCubeSnapshot;
void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
const std::string &string,
@@ -1970,6 +1812,7 @@ void LLViewerObjectList::addDebugBeacon(const LLVector3 &pos_agent,
const LLColor4 &text_color,
S32 line_width)
{
+ llassert(!gCubeSnapshot);
LLDebugBeacon beacon;
beacon.mPositionAgent = pos_agent;
beacon.mString = string;
@@ -2220,7 +2063,7 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port)
// Make the drawable visible again and set the drawable parent
childp->mDrawable->clearState(LLDrawable::FORCE_INVISIBLE);
childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans()
- gPipeline.markRebuild( childp->mDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ gPipeline.markRebuild( childp->mDrawable, LLDrawable::REBUILD_ALL);
}
// Make certain particles, icon and HUD aren't hidden
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 72b2b99004..f2cba8c259 100644
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -77,7 +77,6 @@ public:
BOOL killObject(LLViewerObject *objectp);
void killObjects(LLViewerRegion *regionp); // Kill all objects owned by a particular region.
void killAllObjects();
- void removeDrawable(LLDrawable* drawablep);
void cleanDeadObjects(const BOOL use_timer = TRUE); // Clean up the dead object list.
@@ -129,11 +128,6 @@ public:
void updateAvatarVisibility();
- // Selection related stuff
- void generatePickList(LLCamera &camera);
-
- LLViewerObject *getSelectedObject(const U32 object_id);
-
inline S32 getNumObjects() { return (S32) mObjects.size(); }
inline S32 getNumActiveObjects() { return (S32) mActiveObjects.size(); }
@@ -226,8 +220,6 @@ protected:
static std::map<U64, LLUUID> sIndexAndLocalIDToUUID;
- std::set<LLViewerObject *> mSelectPickList;
-
friend class LLViewerObject;
private:
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 36b2bd4c32..9d63241300 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -103,11 +103,11 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
}
//create a vertex buffer for efficiently rendering cubes
-LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask)
{
- LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage);
+ LLVertexBuffer* ret = new LLVertexBuffer(type_mask);
- ret->allocateBuffer(8, 64, true);
+ ret->allocateBuffer(8, 64);
LLStrider<LLVector3> pos;
LLStrider<U16> idx;
@@ -129,7 +129,7 @@ LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage)
idx[i] = sOcclusionIndices[i];
}
- ret->flush();
+ ret->unmapBuffer();
return ret;
}
@@ -627,13 +627,17 @@ void LLViewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntr
//virtual
void LLViewerOctreeGroup::handleDestruction(const TreeNode* node)
{
+ if (isDead())
+ {
+ return;
+ }
+ setState(DEAD);
for (OctreeNode::element_iter i = mOctreeNode->getDataBegin(); i != mOctreeNode->getDataEnd(); ++i)
{
LLViewerOctreeEntry* obj = *i;
if (obj && obj->getGroup() == this)
{
obj->nullGroup();
- //obj->setGroup(NULL);
}
}
mOctreeNode = NULL;
@@ -800,7 +804,7 @@ U32 LLOcclusionCullingGroup::getNewOcclusionQueryObjectName()
{
//seed 1024 query names into the free query pool
GLuint queries[1024];
- glGenQueriesARB(1024, queries);
+ glGenQueries(1024, queries);
for (int i = 0; i < 1024; ++i)
{
sFreeQueries.push(queries[i]);
@@ -870,6 +874,7 @@ LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctre
for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
{
mOcclusionQuery[i] = 0;
+ mOcclusionCheckCount[i] = 0;
mOcclusionIssued[i] = 0;
mOcclusionState[i] = parent ? SG_STATE_INHERIT_MASK & parent->mOcclusionState[i] : 0;
mVisible[i] = 0;
@@ -917,15 +922,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr
void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
{
- if (gGLManager.mHasOcclusionQuery)
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
{
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i)
+ if (mOcclusionQuery[i])
{
- if (mOcclusionQuery[i])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
}
}
}
@@ -1129,34 +1131,24 @@ void LLOcclusionCullingGroup::checkOcclusion()
GLuint available;
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available);
+ mOcclusionCheckCount[LLViewerCamera::sCurCameraID]++;
}
- if (available)
+ static LLCachedControl<S32> occlusion_timeout(gSavedSettings, "RenderOcclusionTimeout", 4);
+
+ if (available || mOcclusionCheckCount[LLViewerCamera::sCurCameraID] > occlusion_timeout)
{
+ mOcclusionCheckCount[LLViewerCamera::sCurCameraID] = 0;
GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result");
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result);
+ glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result);
}
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
-#if 0 // (12/2021) occasional false-negative occlusion tests produce water reflection errors, SL-16461
- // If/when water occlusion queries become 100% reliable, re-enable this optimization
-
- if (LLPipeline::RENDER_TYPE_WATER == mSpatialPartition->mDrawableType)
- {
- // Note any unoccluded water, for deciding on reflection/distortion passes
- // (If occlusion is disabled, these are set within LLDrawPoolWater::render)
- if (query_result > 0)
- {
- LLDrawPoolWater::sNeedsReflectionUpdate = TRUE;
- LLDrawPoolWater::sNeedsDistortionUpdate = TRUE;
- }
- }
-#endif
if (query_result > 0)
{
clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
@@ -1172,7 +1164,7 @@ void LLOcclusionCullingGroup::checkOcclusion()
else if (mSpatialPartition->isOcclusionEnabled() && isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
{ //check occlusion has been issued for occluded node that has not had a query issued
assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ //clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
assert_states_valid(this);
}
}
@@ -1197,7 +1189,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
OCCLUSION_FUDGE_Z = 1.;
}
- // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension
if (earlyFail(camera, bounds))
{
LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail");
@@ -1221,17 +1212,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// Depth clamp all water to avoid it being culled as a result of being
// behind the far clip plane, and in the case of edge water to avoid
// it being culled while still visible.
- bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
- (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
+ bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
- LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
+ LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
-#if !LL_DARWIN
- U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
-#else
- U32 mode = GL_SAMPLES_PASSED_ARB;
-#endif
+ U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED;
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
@@ -1250,7 +1236,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
//get an occlusion query that hasn't been used in awhile
releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
mOcclusionQuery[LLViewerCamera::sCurCameraID] = getNewOcclusionQueryObjectName();
- glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ glBeginQuery(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
}
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -1292,7 +1278,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
{
LL_PROFILE_ZONE_NAMED("glEndQuery");
- glEndQueryARB(mode);
+ glEndQuery(mode);
}
}
}
diff --git a/indra/newview/llvieweroctree.h b/indra/newview/llvieweroctree.h
index 7666062f99..353429d254 100644
--- a/indra/newview/llvieweroctree.h
+++ b/indra/newview/llvieweroctree.h
@@ -336,6 +336,7 @@ protected:
LLViewerOctreePartition* mSpatialPartition;
U32 mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
+ U32 mOcclusionCheckCount[LLViewerCamera::NUM_CAMERAS];
public:
static std::set<U32> sPendingQueries;
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 449fd4ba43..0f20076b04 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -264,7 +264,7 @@ BOOL LLViewerPartGroup::addPart(LLViewerPart* part, F32 desired_size)
return FALSE;
}
- gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL);
mParticles.push_back(part);
part->mSkipOffset=mSkippedTime;
@@ -426,7 +426,7 @@ void LLViewerPartGroup::updateParticles(const F32 lastdt)
// we removed one or more particles, so flag this group for update
if (mVOPartGroupp.notNull())
{
- gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mVOPartGroupp->mDrawable, LLDrawable::REBUILD_ALL);
}
LLViewerPartSim::decPartCount(removed);
}
@@ -766,7 +766,7 @@ void LLViewerPartSim::updateSimulation()
{
if (vobj && !vobj->isDead())
{
- gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(vobj->mDrawable, LLDrawable::REBUILD_ALL);
}
mViewerPartGroups[i]->updateParticles(dt * visirate);
mViewerPartGroups[i]->mSkippedTime=0.0f;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 84956d3b3d..452dcdd8fd 100755
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -53,6 +53,7 @@
#include "llfloatergodtools.h"
#include "llfloaterreporter.h"
#include "llfloaterregioninfo.h"
+#include "llgltfmateriallist.h"
#include "llhttpnode.h"
#include "llregioninfomodel.h"
#include "llsdutil.h"
@@ -221,6 +222,7 @@ public:
LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation.
LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation.
std::set<U32> mNonCacheableCreatedList; //list of local ids of all non-cacheable objects
+ LLVOCacheEntry::vocache_gltf_overrides_map_t mGLTFOverridesLLSD; // for materials
// time?
// LRU info?
@@ -722,6 +724,7 @@ static LLTrace::BlockTimerStatHandle FTM_SAVE_REGION_CACHE("Save Region Cache");
LLViewerRegion::~LLViewerRegion()
{
+ LL_PROFILE_ZONE_SCOPED;
mDead = TRUE;
mImpl->mActiveSet.clear();
mImpl->mVisibleEntries.clear();
@@ -790,7 +793,10 @@ void LLViewerRegion::loadObjectCache()
if(LLVOCache::instanceExists())
{
- LLVOCache::getInstance()->readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap) ;
+ LLVOCache & vocache = LLVOCache::instance();
+ vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap);
+ vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD);
+
if (mImpl->mCacheMap.empty())
{
mCacheDirty = TRUE;
@@ -815,14 +821,18 @@ void LLViewerRegion::saveObjectCache()
{
const F32 start_time_threshold = 600.0f; //seconds
bool removal_enabled = sVOCacheCullingEnabled && (mRegionTimer.getElapsedTimeF32() > start_time_threshold); //allow to remove invalid objects from object cache file.
-
- LLVOCache::getInstance()->writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled) ;
+
+ LLVOCache & instance = LLVOCache::instance();
+
+ instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled);
+ instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mCacheDirty, removal_enabled);
mCacheDirty = FALSE;
}
// Map of LLVOCacheEntry takes time to release, store map for cleanup on idle
sRegionCacheCleanup.insert(mImpl->mCacheMap.begin(), mImpl->mCacheMap.end());
mImpl->mCacheMap.clear();
+ // TODO - probably need to do the same for overrides cache
}
void LLViewerRegion::sendMessage()
@@ -1150,6 +1160,8 @@ void LLViewerRegion::killCacheEntry(LLVOCacheEntry* entry, bool for_rendering)
entry->setState(LLVOCacheEntry::INACTIVE);
entry->removeOctreeEntry();
entry->setValid(FALSE);
+
+ // TODO kill extras/material overrides cache too
}
//physically delete the cache entry
@@ -1250,6 +1262,46 @@ U32 LLViewerRegion::getNumOfVisibleGroups() const
return mImpl ? mImpl->mVisibleGroups.size() : 0;
}
+void LLViewerRegion::updateReflectionProbes()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ const F32 probe_spacing = 32.f;
+ const F32 probe_radius = sqrtf((probe_spacing * 0.5f) * (probe_spacing * 0.5f) * 3.f);
+ const F32 hover_height = 2.f;
+
+ F32 start = probe_spacing * 0.5f;
+
+ U32 grid_width = REGION_WIDTH_METERS / probe_spacing;
+
+ mReflectionMaps.resize(grid_width * grid_width);
+
+ F32 water_height = getWaterHeight();
+ LLVector3 origin = getOriginAgent();
+
+ for (U32 i = 0; i < grid_width; ++i)
+ {
+ F32 x = i * probe_spacing + start;
+ for (U32 j = 0; j < grid_width; ++j)
+ {
+ F32 y = j * probe_spacing + start;
+
+ U32 idx = i * grid_width + j;
+
+ if (mReflectionMaps[idx].isNull())
+ {
+ mReflectionMaps[idx] = gPipeline.mReflectionMapManager.addProbe();
+ }
+
+ LLVector3 probe_origin = LLVector3(x, y, llmax(water_height, mImpl->mLandp->resolveHeightRegion(x, y)));
+ probe_origin.mV[2] += hover_height;
+ probe_origin += origin;
+
+ mReflectionMaps[idx]->mOrigin.load3(probe_origin.mV);
+ mReflectionMaps[idx]->mRadius = probe_radius;
+ }
+ }
+}
+
void LLViewerRegion::addToVOCacheTree(LLVOCacheEntry* entry)
{
if(!sVOCacheCullingEnabled)
@@ -1547,6 +1599,7 @@ void LLViewerRegion::lightIdleUpdate()
void LLViewerRegion::idleUpdate(F32 max_update_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
F32 max_time;
@@ -1650,6 +1703,10 @@ BOOL LLViewerRegion::isViewerCameraStatic()
void LLViewerRegion::killInvisibleObjects(F32 max_time)
{
+#if 1 // TODO: kill this. This is ill-conceived, objects that aren't in the camera frustum should not be deleted from memory.
+ // because of this, every time you turn around the simulator sends a swarm of full object update messages from cache
+ // probe misses and objects have to be reloaded from scratch. From some reason, disabling this causes holes to
+ // appear in the scene when flying back and forth between regions
if(!sVOCacheCullingEnabled)
{
return;
@@ -1726,6 +1783,7 @@ void LLViewerRegion::killInvisibleObjects(F32 max_time)
}
return;
+#endif
}
void LLViewerRegion::killObject(LLVOCacheEntry* entry, std::vector<LLDrawable*>& delete_list)
@@ -1790,7 +1848,7 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
LLViewerObject* obj = NULL;
if(!entry->getEntry()->hasDrawable()) //not added to the rendering pipeline yet
- {
+ {
//add the object
obj = gObjectList.processObjectUpdateFromCache(entry, this);
if(obj)
@@ -1820,6 +1878,9 @@ LLViewerObject* LLViewerRegion::addNewObject(LLVOCacheEntry* entry)
//should not hit here any more, but does not hurt either, just put it back to active list
addActiveCacheEntry(entry);
}
+
+ loadCacheMiscExtras(entry->getLocalID());
+
return obj;
}
@@ -2565,7 +2626,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
LL_DEBUGS("AnimatedObjects") << " got update for local_id " << local_id << LL_ENDL;
dumpStack("AnimatedObjectsStack");
- // Update the cache entry
+ // Update the cache entry
entry->updateEntry(crc, dp);
decodeBoundingInfo(entry);
@@ -2582,7 +2643,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLDataPackerB
// Create new entry and add to map
result = CACHE_UPDATE_ADDED;
entry = new LLVOCacheEntry(local_id, crc, dp);
- record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0));
+ record(LLStatViewer::OBJECT_CACHE_HIT_RATE, LLUnits::Ratio::fromValue(0));
mImpl->mCacheMap[local_id] = entry;
@@ -2600,6 +2661,12 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec
return result;
}
+void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data)
+{
+ U32 local_id = override_data.mLocalId;
+ mImpl->mGLTFOverridesLLSD[local_id] = override_data;
+}
+
LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id)
{
if(!sVOCacheCullingEnabled)
@@ -2624,7 +2691,7 @@ LLVOCacheEntry* LLViewerRegion::getCacheEntry(U32 local_id, bool valid)
}
}
return NULL;
- }
+}
void LLViewerRegion::addCacheMiss(U32 id, LLViewerRegion::eCacheMissType cache_miss_type)
{
@@ -2694,6 +2761,9 @@ bool LLViewerRegion::probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss
entry->setValid();
decodeBoundingInfo(entry);
+
+ //loadCacheMiscExtras(local_id, entry, crc);
+
return true;
}
else
@@ -2808,6 +2878,7 @@ void LLViewerRegion::dumpCache()
{
LL_INFOS() << "Changes " << i << " " << change_bin[i] << LL_ENDL;
}
+ // TODO - add overrides cache too
}
void LLViewerRegion::unpackRegionHandshake()
@@ -3054,6 +3125,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("MapLayer");
capabilityNames.append("MapLayerGod");
capabilityNames.append("MeshUploadFlag");
+ capabilityNames.append("ModifyMaterialParams");
capabilityNames.append("NavMeshGenerationStatus");
capabilityNames.append("NewFileAgentInventory");
capabilityNames.append("ObjectAnimation");
@@ -3096,6 +3168,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
capabilityNames.append("UpdateSettingsAgentInventory");
capabilityNames.append("UpdateSettingsTaskInventory");
capabilityNames.append("UploadAgentProfileImage");
+ capabilityNames.append("UpdateMaterialAgentInventory");
+ capabilityNames.append("UpdateMaterialTaskInventory");
capabilityNames.append("UploadBakedTexture");
capabilityNames.append("UserInfo");
capabilityNames.append("ViewerAsset");
@@ -3581,3 +3655,30 @@ std::string LLViewerRegion::getSimHostName()
return std::string("...");
}
+void LLViewerRegion::loadCacheMiscExtras(U32 local_id)
+{
+ auto iter = mImpl->mGLTFOverridesLLSD.find(local_id);
+ if (iter != mImpl->mGLTFOverridesLLSD.end())
+ {
+ LLGLTFMaterialList::loadCacheOverrides(iter->second);
+ }
+}
+
+void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ llassert(obj);
+
+ U32 local_id = obj->getLocalID();
+ auto iter = mImpl->mGLTFOverridesLLSD.find(local_id);
+ if (iter != mImpl->mGLTFOverridesLLSD.end())
+ {
+ llassert(iter->second.mGLTFMaterial.size() == iter->second.mSides.size());
+
+ for (auto& side : iter->second.mGLTFMaterial)
+ {
+ obj->setTEGLTFMaterialOverride(side.first, side.second);
+ }
+ }
+}
+
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index 6956e9eb08..a409d837a4 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -42,6 +42,7 @@
#include "llcapabilityprovider.h"
#include "m4math.h" // LLMatrix4
#include "llframetimer.h"
+#include "llreflectionmap.h"
// Surface id's
#define LAND 1
@@ -68,6 +69,7 @@ class LLHost;
class LLBBox;
class LLSpatialGroup;
class LLDrawable;
+class LLGLTFOverrideCacheEntry;
class LLViewerRegionImpl;
class LLViewerOctreeGroup;
class LLVOCachePartition;
@@ -358,7 +360,10 @@ public:
// handle a full update message
eCacheUpdateResult cacheFullUpdate(LLDataPackerBinaryBuffer &dp, U32 flags);
- eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
+ eCacheUpdateResult cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp, U32 flags);
+
+ void cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data);
+
LLVOCacheEntry* getCacheEntryForOctree(U32 local_id);
LLVOCacheEntry* getCacheEntry(U32 local_id, bool valid = true);
bool probeCache(U32 local_id, U32 crc, U32 flags, U8 &cache_miss_type);
@@ -412,6 +417,9 @@ public:
static BOOL isNewObjectCreationThrottleDisabled() {return sNewObjectCreationThrottle < 0;}
+ // rebuild reflection probe list
+ void updateReflectionProbes();
+
private:
void addToVOCacheTree(LLVOCacheEntry* entry);
LLViewerObject* addNewObject(LLVOCacheEntry* entry);
@@ -427,6 +435,10 @@ private:
bool isNonCacheableObjectCreated(U32 local_id);
public:
+ void loadCacheMiscExtras(U32 local_id);
+
+ void applyCacheMiscExtras(LLViewerObject* obj);
+
struct CompareDistance
{
bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs)
@@ -596,6 +608,10 @@ public:
// how the server interest list works
std::string mInterestListMode;
+
+ // list of reflection maps being managed by this llviewer region
+ std::vector<LLPointer<LLReflectionMap> > mReflectionMaps;
+
};
inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 779837bcf0..cdf5e2875f 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -32,6 +32,7 @@
#include "llfeaturemanager.h"
#include "llviewershadermgr.h"
#include "llviewercontrol.h"
+#include "llversioninfo.h"
#include "llrender.h"
#include "llenvironment.h"
@@ -39,7 +40,6 @@
#include "llatmosphere.h"
#include "llworld.h"
#include "llsky.h"
-#include "llvosky.h"
#include "pipeline.h"
@@ -69,84 +69,39 @@ bool LLViewerShaderMgr::sSkipReload = false;
LLVector4 gShinyOrigin;
-//transform shaders
-LLGLSLShader gTransformPositionProgram;
-LLGLSLShader gTransformTexCoordProgram;
-LLGLSLShader gTransformNormalProgram;
-LLGLSLShader gTransformColorProgram;
-LLGLSLShader gTransformTangentProgram;
-
//utility shaders
LLGLSLShader gOcclusionProgram;
LLGLSLShader gSkinnedOcclusionProgram;
LLGLSLShader gOcclusionCubeProgram;
-LLGLSLShader gCustomAlphaProgram;
LLGLSLShader gGlowCombineProgram;
-LLGLSLShader gSplatTextureRectProgram;
+LLGLSLShader gReflectionMipProgram;
+LLGLSLShader gGaussianProgram;
+LLGLSLShader gRadianceGenProgram;
+LLGLSLShader gIrradianceGenProgram;
LLGLSLShader gGlowCombineFXAAProgram;
-LLGLSLShader gTwoTextureAddProgram;
LLGLSLShader gTwoTextureCompareProgram;
LLGLSLShader gOneTextureFilterProgram;
-LLGLSLShader gOneTextureNoColorProgram;
LLGLSLShader gDebugProgram;
LLGLSLShader gSkinnedDebugProgram;
LLGLSLShader gClipProgram;
-LLGLSLShader gDownsampleDepthProgram;
-LLGLSLShader gDownsampleDepthRectProgram;
LLGLSLShader gAlphaMaskProgram;
LLGLSLShader gBenchmarkProgram;
-
+LLGLSLShader gReflectionProbeDisplayProgram;
+LLGLSLShader gCopyProgram;
+LLGLSLShader gCopyDepthProgram;
//object shaders
-LLGLSLShader gObjectSimpleProgram;
-LLGLSLShader gSkinnedObjectSimpleProgram;
-LLGLSLShader gObjectSimpleImpostorProgram;
-LLGLSLShader gSkinnedObjectSimpleImpostorProgram;
LLGLSLShader gObjectPreviewProgram;
+LLGLSLShader gSkinnedObjectPreviewProgram;
LLGLSLShader gPhysicsPreviewProgram;
-LLGLSLShader gObjectSimpleWaterProgram;
-LLGLSLShader gSkinnedObjectSimpleWaterProgram;
-LLGLSLShader gObjectSimpleAlphaMaskProgram;
-LLGLSLShader gSkinnedObjectSimpleAlphaMaskProgram;
-LLGLSLShader gObjectSimpleWaterAlphaMaskProgram;
-LLGLSLShader gSkinnedObjectSimpleWaterAlphaMaskProgram;
-LLGLSLShader gObjectFullbrightProgram;
-LLGLSLShader gSkinnedObjectFullbrightProgram;
-LLGLSLShader gObjectFullbrightWaterProgram;
-LLGLSLShader gSkinnedObjectFullbrightWaterProgram;
-LLGLSLShader gObjectEmissiveProgram;
-LLGLSLShader gSkinnedObjectEmissiveProgram;
-LLGLSLShader gObjectEmissiveWaterProgram;
-LLGLSLShader gSkinnedObjectEmissiveWaterProgram;
LLGLSLShader gObjectFullbrightAlphaMaskProgram;
LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
-LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram;
-LLGLSLShader gSkinnedObjectFullbrightWaterAlphaMaskProgram;
-LLGLSLShader gObjectFullbrightShinyProgram;
-LLGLSLShader gSkinnedObjectFullbrightShinyProgram;
-LLGLSLShader gObjectFullbrightShinyWaterProgram;
-LLGLSLShader gSkinnedObjectFullbrightShinyWaterProgram;
-LLGLSLShader gObjectShinyProgram;
-LLGLSLShader gSkinnedObjectShinyProgram;
-LLGLSLShader gObjectShinyWaterProgram;
-LLGLSLShader gSkinnedObjectShinyWaterProgram;
LLGLSLShader gObjectBumpProgram;
LLGLSLShader gSkinnedObjectBumpProgram;
-LLGLSLShader gTreeProgram;
-LLGLSLShader gTreeWaterProgram;
-LLGLSLShader gObjectFullbrightNoColorProgram;
-LLGLSLShader gObjectFullbrightNoColorWaterProgram;
-
-LLGLSLShader gObjectSimpleNonIndexedTexGenProgram;
-LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram;
-LLGLSLShader gObjectAlphaMaskNonIndexedProgram;
-LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram;
LLGLSLShader gObjectAlphaMaskNoColorProgram;
LLGLSLShader gObjectAlphaMaskNoColorWaterProgram;
//environment shaders
-LLGLSLShader gTerrainProgram;
-LLGLSLShader gTerrainWaterProgram;
LLGLSLShader gWaterProgram;
LLGLSLShader gWaterEdgeProgram;
LLGLSLShader gUnderWaterProgram;
@@ -158,39 +113,25 @@ LLGLSLShader gHighlightNormalProgram;
LLGLSLShader gHighlightSpecularProgram;
LLGLSLShader gDeferredHighlightProgram;
-LLGLSLShader gDeferredHighlightNormalProgram;
-LLGLSLShader gDeferredHighlightSpecularProgram;
LLGLSLShader gPathfindingProgram;
LLGLSLShader gPathfindingNoNormalsProgram;
//avatar shader handles
LLGLSLShader gAvatarProgram;
-LLGLSLShader gAvatarWaterProgram;
LLGLSLShader gAvatarEyeballProgram;
-LLGLSLShader gAvatarPickProgram;
LLGLSLShader gImpostorProgram;
-// WindLight shader handles
-LLGLSLShader gWLSkyProgram;
-LLGLSLShader gWLCloudProgram;
-LLGLSLShader gWLSunProgram;
-LLGLSLShader gWLMoonProgram;
-
// Effects Shaders
LLGLSLShader gGlowProgram;
LLGLSLShader gGlowExtractProgram;
-LLGLSLShader gPostColorFilterProgram;
-LLGLSLShader gPostNightVisionProgram;
+LLGLSLShader gPostScreenSpaceReflectionProgram;
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram;
-LLGLSLShader gDeferredWaterProgram;
-LLGLSLShader gDeferredUnderWaterProgram;
LLGLSLShader gDeferredDiffuseProgram;
LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram;
-LLGLSLShader gDeferredNonIndexedDiffuseProgram;
LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram;
LLGLSLShader gDeferredSkinnedDiffuseProgram;
@@ -216,15 +157,17 @@ LLGLSLShader gDeferredSkinnedShadowProgram;
LLGLSLShader gDeferredShadowCubeProgram;
LLGLSLShader gDeferredShadowAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedShadowAlphaMaskProgram;
+LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedShadowGLTFAlphaMaskProgram;
+LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
+LLGLSLShader gDeferredSkinnedShadowGLTFAlphaBlendProgram;
LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
LLGLSLShader gDeferredAvatarShadowProgram;
LLGLSLShader gDeferredAvatarAlphaShadowProgram;
LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
-LLGLSLShader gDeferredAttachmentShadowProgram;
-LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
-LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
LLGLSLShader gDeferredAlphaProgram;
+LLGLSLShader gHUDAlphaProgram;
LLGLSLShader gDeferredSkinnedAlphaProgram;
LLGLSLShader gDeferredAlphaImpostorProgram;
LLGLSLShader gDeferredSkinnedAlphaImpostorProgram;
@@ -232,9 +175,15 @@ LLGLSLShader gDeferredAlphaWaterProgram;
LLGLSLShader gDeferredSkinnedAlphaWaterProgram;
LLGLSLShader gDeferredAvatarEyesProgram;
LLGLSLShader gDeferredFullbrightProgram;
+LLGLSLShader gHUDFullbrightProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
+LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
LLGLSLShader gDeferredFullbrightWaterProgram;
LLGLSLShader gDeferredSkinnedFullbrightWaterProgram;
+LLGLSLShader gDeferredFullbrightWaterAlphaProgram;
+LLGLSLShader gDeferredSkinnedFullbrightWaterAlphaProgram;
LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskWaterProgram;
LLGLSLShader gDeferredEmissiveProgram;
@@ -243,6 +192,10 @@ LLGLSLShader gDeferredPostProgram;
LLGLSLShader gDeferredCoFProgram;
LLGLSLShader gDeferredDoFCombineProgram;
LLGLSLShader gDeferredPostGammaCorrectProgram;
+LLGLSLShader gNoPostGammaCorrectProgram;
+LLGLSLShader gLegacyPostGammaCorrectProgram;
+LLGLSLShader gExposureProgram;
+LLGLSLShader gLuminanceProgram;
LLGLSLShader gFXAAProgram;
LLGLSLShader gDeferredPostNoDoFProgram;
LLGLSLShader gDeferredWLSkyProgram;
@@ -251,14 +204,28 @@ LLGLSLShader gDeferredWLSunProgram;
LLGLSLShader gDeferredWLMoonProgram;
LLGLSLShader gDeferredStarProgram;
LLGLSLShader gDeferredFullbrightShinyProgram;
+LLGLSLShader gHUDFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightShinyProgram;
LLGLSLShader gDeferredSkinnedFullbrightProgram;
LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskProgram;
+LLGLSLShader gDeferredSkinnedFullbrightAlphaMaskAlphaProgram;
LLGLSLShader gNormalMapGenProgram;
+LLGLSLShader gDeferredGenBrdfLutProgram;
+LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+LLGLSLShader gHUDPBROpaqueProgram;
+LLGLSLShader gPBRGlowProgram;
+LLGLSLShader gPBRGlowSkinnedProgram;
+LLGLSLShader gDeferredPBROpaqueProgram;
+LLGLSLShader gDeferredSkinnedPBROpaqueProgram;
+LLGLSLShader gHUDPBRAlphaProgram;
+LLGLSLShader gDeferredPBRAlphaProgram;
+LLGLSLShader gDeferredSkinnedPBRAlphaProgram;
+LLGLSLShader gDeferredPBRAlphaWaterProgram;
+LLGLSLShader gDeferredSkinnedPBRAlphaWaterProgram;
//helper for making a rigged variant of a given shader
bool make_rigged_variant(LLGLSLShader& shader, LLGLSLShader& riggedShader)
@@ -280,94 +247,65 @@ LLViewerShaderMgr::LLViewerShaderMgr() :
mShaderLevel(SHADER_COUNT, 0),
mMaxAvatarShaderLevel(0)
{
- /// Make sure WL Sky is the first program
//ONLY shaders that need WL Param management should be added here
- mShaderList.push_back(&gWLSkyProgram);
- mShaderList.push_back(&gWLCloudProgram);
- mShaderList.push_back(&gWLSunProgram);
- mShaderList.push_back(&gWLMoonProgram);
mShaderList.push_back(&gAvatarProgram);
- mShaderList.push_back(&gObjectShinyProgram);
- mShaderList.push_back(&gSkinnedObjectShinyProgram);
mShaderList.push_back(&gWaterProgram);
mShaderList.push_back(&gWaterEdgeProgram);
mShaderList.push_back(&gAvatarEyeballProgram);
- mShaderList.push_back(&gObjectSimpleProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleProgram);
- mShaderList.push_back(&gObjectSimpleImpostorProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleImpostorProgram);
- mShaderList.push_back(&gObjectPreviewProgram);
mShaderList.push_back(&gImpostorProgram);
- mShaderList.push_back(&gObjectFullbrightNoColorProgram);
- mShaderList.push_back(&gObjectFullbrightNoColorWaterProgram);
- mShaderList.push_back(&gObjectSimpleAlphaMaskProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleAlphaMaskProgram);
mShaderList.push_back(&gObjectBumpProgram);
mShaderList.push_back(&gSkinnedObjectBumpProgram);
- mShaderList.push_back(&gObjectEmissiveProgram);
- mShaderList.push_back(&gSkinnedObjectEmissiveProgram);
- mShaderList.push_back(&gObjectEmissiveWaterProgram);
- mShaderList.push_back(&gSkinnedObjectEmissiveWaterProgram);
- mShaderList.push_back(&gObjectFullbrightProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightProgram);
mShaderList.push_back(&gObjectFullbrightAlphaMaskProgram);
mShaderList.push_back(&gSkinnedObjectFullbrightAlphaMaskProgram);
- mShaderList.push_back(&gObjectFullbrightShinyProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightShinyProgram);
- mShaderList.push_back(&gObjectFullbrightShinyWaterProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightShinyWaterProgram);
- mShaderList.push_back(&gObjectSimpleNonIndexedTexGenProgram);
- mShaderList.push_back(&gObjectSimpleNonIndexedTexGenWaterProgram);
- mShaderList.push_back(&gObjectAlphaMaskNonIndexedProgram);
- mShaderList.push_back(&gObjectAlphaMaskNonIndexedWaterProgram);
mShaderList.push_back(&gObjectAlphaMaskNoColorProgram);
mShaderList.push_back(&gObjectAlphaMaskNoColorWaterProgram);
- mShaderList.push_back(&gTreeProgram);
- mShaderList.push_back(&gTreeWaterProgram);
- mShaderList.push_back(&gTerrainProgram);
- mShaderList.push_back(&gTerrainWaterProgram);
- mShaderList.push_back(&gObjectSimpleWaterProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleWaterProgram);
- mShaderList.push_back(&gObjectFullbrightWaterProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightWaterProgram);
- mShaderList.push_back(&gObjectSimpleWaterAlphaMaskProgram);
- mShaderList.push_back(&gSkinnedObjectSimpleWaterAlphaMaskProgram);
- mShaderList.push_back(&gObjectFullbrightWaterAlphaMaskProgram);
- mShaderList.push_back(&gSkinnedObjectFullbrightWaterAlphaMaskProgram);
- mShaderList.push_back(&gAvatarWaterProgram);
- mShaderList.push_back(&gObjectShinyWaterProgram);
- mShaderList.push_back(&gSkinnedObjectShinyWaterProgram);
mShaderList.push_back(&gUnderWaterProgram);
mShaderList.push_back(&gDeferredSunProgram);
mShaderList.push_back(&gDeferredSoftenProgram);
mShaderList.push_back(&gDeferredSoftenWaterProgram);
mShaderList.push_back(&gDeferredAlphaProgram);
+ mShaderList.push_back(&gHUDAlphaProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaProgram);
mShaderList.push_back(&gDeferredAlphaImpostorProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaImpostorProgram);
mShaderList.push_back(&gDeferredAlphaWaterProgram);
mShaderList.push_back(&gDeferredSkinnedAlphaWaterProgram);
mShaderList.push_back(&gDeferredFullbrightProgram);
+ mShaderList.push_back(&gHUDFullbrightProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gHUDFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredFullbrightAlphaMaskAlphaProgram);
+ mShaderList.push_back(&gHUDFullbrightAlphaMaskAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightWaterProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightWaterProgram);
+ mShaderList.push_back(&gDeferredFullbrightWaterAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightWaterAlphaProgram);
mShaderList.push_back(&gDeferredFullbrightAlphaMaskWaterProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
mShaderList.push_back(&gDeferredFullbrightShinyProgram);
+ mShaderList.push_back(&gHUDFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightShinyProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightProgram);
mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskProgram);
+ mShaderList.push_back(&gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
mShaderList.push_back(&gDeferredEmissiveProgram);
mShaderList.push_back(&gDeferredSkinnedEmissiveProgram);
mShaderList.push_back(&gDeferredAvatarEyesProgram);
- mShaderList.push_back(&gDeferredWaterProgram);
- mShaderList.push_back(&gDeferredUnderWaterProgram);
mShaderList.push_back(&gDeferredTerrainWaterProgram);
mShaderList.push_back(&gDeferredAvatarAlphaProgram);
mShaderList.push_back(&gDeferredWLSkyProgram);
mShaderList.push_back(&gDeferredWLCloudProgram);
mShaderList.push_back(&gDeferredWLMoonProgram);
- mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredWLSunProgram);
+ mShaderList.push_back(&gDeferredPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredPBRAlphaWaterProgram);
+ mShaderList.push_back(&gHUDPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram);
+ mShaderList.push_back(&gDeferredSkinnedPBRAlphaWaterProgram);
+ mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma
+ mShaderList.push_back(&gNoPostGammaCorrectProgram);
+ mShaderList.push_back(&gLegacyPostGammaCorrectProgram);
+
}
LLViewerShaderMgr::~LLViewerShaderMgr()
@@ -419,6 +357,7 @@ S32 LLViewerShaderMgr::getShaderLevel(S32 type)
void LLViewerShaderMgr::setShaders()
{
+ LL_PROFILE_ZONE_SCOPED;
//setShaders might be called redundantly by gSavedSettings, so return on reentrance
static bool reentrance = false;
@@ -434,23 +373,30 @@ void LLViewerShaderMgr::setShaders()
return;
}
- static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits, (S32) max_texture_index), 1);
+ {
+ static LLCachedControl<bool> shader_cache_enabled(gSavedSettings, "RenderShaderCacheEnabled", true);
+ static LLUUID old_cache_version;
+ static LLUUID current_cache_version;
+ if (current_cache_version.isNull())
+ {
+ HBXXH128 hash_obj;
+ hash_obj.update(LLVersionInfo::instance().getVersion());
+ current_cache_version = hash_obj.digest();
- //NEVER use more than 16 texture channels (work around for prevalent driver bug)
- LLGLSLShader::sIndexedTextureChannels = llmin(LLGLSLShader::sIndexedTextureChannels, 16);
+ old_cache_version = LLUUID(gSavedSettings.getString("RenderShaderCacheVersion"));
+ gSavedSettings.setString("RenderShaderCacheVersion", current_cache_version.asString());
+ }
- if (gGLManager.mGLSLVersionMajor < 1 ||
- (gGLManager.mGLSLVersionMajor == 1 && gGLManager.mGLSLVersionMinor <= 20))
- { //NEVER use indexed texture rendering when GLSL version is 1.20 or earlier
- LLGLSLShader::sIndexedTextureChannels = 1;
- }
+ initShaderCache(shader_cache_enabled, old_cache_version, current_cache_version);
+ }
+
+ static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
+
+ // when using indexed texture rendering, leave some texture units available for shadow and reflection maps
+ LLGLSLShader::sIndexedTextureChannels = llmax(llmin(gGLManager.mNumTextureImageUnits-12, (S32) max_texture_index), 1);
reentrance = true;
- //setup preprocessor definitions
- LLShaderMgr::instance()->mDefinitions["NUM_TEX_UNITS"] = llformat("%d", gGLManager.mNumTextureImageUnits);
-
// Make sure the compiled shader map is cleared before we recompile shaders.
mVertexShaderObjects.clear();
mFragmentShaderObjects.clear();
@@ -458,21 +404,15 @@ void LLViewerShaderMgr::setShaders()
initAttribsAndUniforms();
gPipeline.releaseGLBuffers();
- LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater;
+ unloadShaders();
+
LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow");
- LLPipeline::updateRenderDeferred();
- //hack to reset buffers that change behavior with shaders
- gPipeline.resetVertexBuffers();
-
if (gViewerWindow)
{
gViewerWindow->setCursor(UI_CURSOR_WAIT);
}
- // Lighting
- gPipeline.setLightingDetail(-1);
-
// Shaders
LL_INFOS("ShaderLoading") << "\n~~~~~~~~~~~~~~~~~~\n Loading Shaders:\n~~~~~~~~~~~~~~~~~~" << LL_ENDL;
LL_INFOS("ShaderLoading") << llformat("Using GLSL %d.%d", gGLManager.mGLSLVersionMajor, gGLManager.mGLSLVersionMinor) << LL_ENDL;
@@ -487,58 +427,15 @@ void LLViewerShaderMgr::setShaders()
llassert((gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 10));
- bool canRenderDeferred = LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
- bool hasWindLightShaders = LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders");
- S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
- bool doingWindLight = hasWindLightShaders && gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- bool useRenderDeferred = doingWindLight && canRenderDeferred && gSavedSettings.getBOOL("RenderDeferred");
-
+
S32 light_class = 3;
S32 interface_class = 2;
S32 env_class = 2;
S32 obj_class = 2;
S32 effect_class = 2;
- S32 wl_class = 1;
- S32 water_class = 2;
- S32 deferred_class = 0;
- S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0;
-
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
- if (!use_transform_feedback)
- {
- transform_class = 0;
- }
-
- if (useRenderDeferred)
- {
- //shadows
- switch (shadow_detail)
- {
- case 1:
- deferred_class = 2; // PCF shadows
- break;
-
- case 2:
- deferred_class = 2; // PCF shadows
- break;
-
- case 0:
- default:
- deferred_class = 1; // no shadows
- break;
- }
- }
-
- if (doingWindLight)
- {
- // user has disabled WindLight in their settings, downgrade
- // windlight shaders to stub versions.
- wl_class = 2;
- }
- else
- {
- light_class = 2;
- }
+ S32 wl_class = 2;
+ S32 water_class = 3;
+ S32 deferred_class = 3;
// Trigger a full rebuild of the fallback skybox / cubemap if we've toggled windlight shaders
if (!wl_class || (mShaderLevel[SHADER_WINDLIGHT] != wl_class && gSky.mVOSkyp.notNull()))
@@ -555,7 +452,6 @@ void LLViewerShaderMgr::setShaders()
mShaderLevel[SHADER_EFFECT] = effect_class;
mShaderLevel[SHADER_WINDLIGHT] = wl_class;
mShaderLevel[SHADER_DEFERRED] = deferred_class;
- mShaderLevel[SHADER_TRANSFORM] = transform_class;
std::string shader_name = loadBasicShaders();
if (shader_name.empty())
@@ -576,49 +472,20 @@ void LLViewerShaderMgr::setShaders()
gPipeline.mShadersLoaded = true;
- // Load all shaders to set max levels
- BOOL loaded = loadShadersEnvironment();
+ BOOL loaded = loadShadersWater();
if (loaded)
{
- LL_INFOS() << "Loaded environment shaders." << LL_ENDL;
+ LL_INFOS() << "Loaded water shaders." << LL_ENDL;
}
else
{
- LL_WARNS() << "Failed to load environment shaders." << LL_ENDL;
+ LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
llassert(loaded);
}
if (loaded)
{
- loaded = loadShadersWater();
- if (loaded)
- {
- LL_INFOS() << "Loaded water shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load water shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
- {
- loaded = loadShadersWindLight();
- if (loaded)
- {
- LL_INFOS() << "Loaded windlight shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load windlight shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
- {
loaded = loadShadersEffects();
if (loaded)
{
@@ -646,89 +513,33 @@ void LLViewerShaderMgr::setShaders()
}
if (loaded)
-
- {
- loaded = loadTransformShaders();
- if (loaded)
- {
- LL_INFOS() << "Loaded transform shaders." << LL_ENDL;
- }
- else
- {
- LL_WARNS() << "Failed to load transform shaders." << LL_ENDL;
- llassert(loaded);
- }
- }
-
- if (loaded)
{
// Load max avatar shaders to set the max level
mShaderLevel[SHADER_AVATAR] = 3;
mMaxAvatarShaderLevel = 3;
-
- if (loadShadersObject())
- { //hardware skinning is enabled and rigged attachment shaders loaded correctly
- BOOL avatar_cloth = gSavedSettings.getBOOL("RenderAvatarCloth");
+ if (loadShadersObject())
+ { //hardware skinning is enabled and rigged attachment shaders loaded correctly
// cloth is a class3 shader
- S32 avatar_class = avatar_cloth ? 3 : 1;
+ S32 avatar_class = 1;
// Set the actual level
mShaderLevel[SHADER_AVATAR] = avatar_class;
loaded = loadShadersAvatar();
llassert(loaded);
-
- if (mShaderLevel[SHADER_AVATAR] != avatar_class)
- {
- if(llmax(mShaderLevel[SHADER_AVATAR]-1,0) >= 3)
- {
- avatar_cloth = true;
- }
- else
- {
- avatar_cloth = false;
- }
- gSavedSettings.setBOOL("RenderAvatarCloth", avatar_cloth);
- }
}
else
{ //hardware skinning not possible, neither is deferred rendering
- mShaderLevel[SHADER_AVATAR] = 0;
- mShaderLevel[SHADER_DEFERRED] = 0;
-
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- gSavedSettings.setBOOL("RenderAvatarCloth", FALSE);
-
- loadShadersAvatar(); // unloads
-
- loaded = loadShadersObject();
- llassert(loaded);
+ llassert(false); // SHOULD NOT BE POSSIBLE
}
}
- if (!loaded)
- { //some shader absolutely could not load, try to fall back to a simpler setting
- if (gSavedSettings.getBOOL("WindLightUseAtmosShaders"))
- { //disable windlight and try again
- gSavedSettings.setBOOL("WindLightUseAtmosShaders", FALSE);
- LL_WARNS() << "Falling back to no windlight shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
- }
-
+ llassert(loaded);
+ loaded = loaded && loadShadersDeferred();
llassert(loaded);
- if (loaded && !loadShadersDeferred())
- { //everything else succeeded but deferred failed, disable deferred and try again
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LL_WARNS() << "Falling back to no deferred shaders." << LL_ENDL;
- reentrance = false;
- setShaders();
- return;
- }
+ persistShaderCacheMetadata();
if (gViewerWindow)
{
@@ -741,115 +552,11 @@ void LLViewerShaderMgr::setShaders()
void LLViewerShaderMgr::unloadShaders()
{
- gOcclusionProgram.unload();
- gSkinnedOcclusionProgram.unload();
- gOcclusionCubeProgram.unload();
- gDebugProgram.unload();
- gSkinnedDebugProgram.unload();
- gClipProgram.unload();
- gDownsampleDepthProgram.unload();
- gDownsampleDepthRectProgram.unload();
- gBenchmarkProgram.unload();
- gAlphaMaskProgram.unload();
- gUIProgram.unload();
- gPathfindingProgram.unload();
- gPathfindingNoNormalsProgram.unload();
- gCustomAlphaProgram.unload();
- gGlowCombineProgram.unload();
- gSplatTextureRectProgram.unload();
- gGlowCombineFXAAProgram.unload();
- gTwoTextureAddProgram.unload();
- gTwoTextureCompareProgram.unload();
- gOneTextureFilterProgram.unload();
- gOneTextureNoColorProgram.unload();
- gSolidColorProgram.unload();
-
- gObjectFullbrightNoColorProgram.unload();
- gObjectFullbrightNoColorWaterProgram.unload();
- gObjectSimpleProgram.unload();
- gSkinnedObjectSimpleProgram.unload();
- gObjectSimpleImpostorProgram.unload();
- gSkinnedObjectSimpleImpostorProgram.unload();
- gObjectPreviewProgram.unload();
- gPhysicsPreviewProgram.unload();
- gImpostorProgram.unload();
- gObjectSimpleAlphaMaskProgram.unload();
- gSkinnedObjectSimpleAlphaMaskProgram.unload();
- gObjectBumpProgram.unload();
- gSkinnedObjectBumpProgram.unload();
- gObjectSimpleWaterProgram.unload();
- gSkinnedObjectSimpleWaterProgram.unload();
- gObjectSimpleWaterAlphaMaskProgram.unload();
- gSkinnedObjectSimpleWaterAlphaMaskProgram.unload();
- gObjectFullbrightProgram.unload();
- gSkinnedObjectFullbrightProgram.unload();
- gObjectFullbrightWaterProgram.unload();
- gSkinnedObjectFullbrightWaterProgram.unload();
- gObjectEmissiveProgram.unload();
- gSkinnedObjectEmissiveProgram.unload();
- gObjectEmissiveWaterProgram.unload();
- gSkinnedObjectEmissiveWaterProgram.unload();
- gObjectFullbrightAlphaMaskProgram.unload();
- gSkinnedObjectFullbrightAlphaMaskProgram.unload();
- gObjectFullbrightWaterAlphaMaskProgram.unload();
- gSkinnedObjectFullbrightWaterAlphaMaskProgram.unload();
-
- gObjectShinyProgram.unload();
- gSkinnedObjectShinyProgram.unload();
- gObjectFullbrightShinyProgram.unload();
- gSkinnedObjectFullbrightShinyProgram.unload();
- gObjectFullbrightShinyWaterProgram.unload();
- gSkinnedObjectFullbrightShinyWaterProgram.unload();
- gObjectShinyWaterProgram.unload();
- gSkinnedObjectShinyWaterProgram.unload();
-
- gObjectSimpleNonIndexedTexGenProgram.unload();
- gObjectSimpleNonIndexedTexGenWaterProgram.unload();
- gObjectAlphaMaskNonIndexedProgram.unload();
- gObjectAlphaMaskNonIndexedWaterProgram.unload();
- gObjectAlphaMaskNoColorProgram.unload();
- gObjectAlphaMaskNoColorWaterProgram.unload();
- gTreeProgram.unload();
- gTreeWaterProgram.unload();
-
- gWaterProgram.unload();
- gWaterEdgeProgram.unload();
- gUnderWaterProgram.unload();
- gTerrainProgram.unload();
- gTerrainWaterProgram.unload();
- gGlowProgram.unload();
- gGlowExtractProgram.unload();
- gAvatarProgram.unload();
- gAvatarWaterProgram.unload();
- gAvatarEyeballProgram.unload();
- gAvatarPickProgram.unload();
- gHighlightProgram.unload();
- gSkinnedHighlightProgram.unload();
- gHighlightNormalProgram.unload();
- gHighlightSpecularProgram.unload();
-
- gWLSkyProgram.unload();
- gWLCloudProgram.unload();
- gWLSunProgram.unload();
- gWLMoonProgram.unload();
-
- gPostColorFilterProgram.unload();
- gPostNightVisionProgram.unload();
-
- gDeferredDiffuseProgram.unload();
- gDeferredDiffuseAlphaMaskProgram.unload();
- gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
- gDeferredNonIndexedDiffuseProgram.unload();
- gDeferredSkinnedDiffuseProgram.unload();
- gDeferredSkinnedBumpProgram.unload();
-
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
+ while (!LLGLSLShader::sInstances.empty())
+ {
+ LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
+ shader->unload();
+ }
mShaderLevel[SHADER_LIGHTING] = 0;
mShaderLevel[SHADER_OBJECT] = 0;
@@ -859,7 +566,6 @@ void LLViewerShaderMgr::unloadShaders()
mShaderLevel[SHADER_INTERFACE] = 0;
mShaderLevel[SHADER_EFFECT] = 0;
mShaderLevel[SHADER_WINDLIGHT] = 0;
- mShaderLevel[SHADER_TRANSFORM] = 0;
gPipeline.mShadersLoaded = false;
}
@@ -871,21 +577,6 @@ std::string LLViewerShaderMgr::loadBasicShaders()
S32 sum_lights_class = 3;
- // class one cards will get the lower sum lights
- // class zero we're not going to think about
- // since a class zero card COULD be a ridiculous new card
- // and old cards should have the features masked
- if(LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_1)
- {
- sum_lights_class = 2;
- }
-
- // If we have sun and moon only checked, then only sum those lights.
- if (gPipeline.getLightingDetail() == 0)
- {
- sum_lights_class = 1;
- }
-
#if LL_DARWIN
// Work around driver crashes on older Macs when using deferred rendering
// NORSPEC-59
@@ -913,42 +604,56 @@ std::string LLViewerShaderMgr::loadBasicShaders()
shaders.push_back( make_pair( "lighting/lightSpecularV.glsl", mShaderLevel[SHADER_LIGHTING] ) );
shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
shaders.push_back( make_pair( "windlight/atmosphericsV.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
+ shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) );
shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) );
+ shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) );
if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)
{
shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) );
}
shaders.push_back( make_pair( "objects/nonindexedTextureV.glsl", 1 ) );
- std::unordered_map<std::string, std::string> attribs;
+ std::map<std::string, std::string> attribs;
attribs["MAX_JOINTS_PER_MESH_OBJECT"] =
boost::lexical_cast<std::string>(LLSkinningUtil::getMaxJointCount());
- BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
- BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
- BOOL local_light_kill = gSavedSettings.getBOOL("LocalLightDisable");
+ BOOL ssr = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
- if (ambient_kill)
- {
- attribs["AMBIENT_KILL"] = "1";
- }
+ bool has_reflection_probes = gSavedSettings.getBOOL("RenderReflectionsEnabled") && gGLManager.mGLVersion > 3.99f;
+
+ S32 probe_level = llclamp(gSavedSettings.getS32("RenderReflectionProbeLevel"), 0, 3);
- if (sunlight_kill)
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+
+ if (shadow_detail >= 1)
{
- attribs["SUNLIGHT_KILL"] = "1";
+ attribs["SUN_SHADOW"] = "1";
+
+ if (shadow_detail >= 2)
+ {
+ attribs["SPOT_SHADOW"] = "1";
+ }
}
- if (local_light_kill)
+ if (ssr)
{
- attribs["LOCAL_LIGHT_KILL"] = "1";
+ attribs["SSR"] = "1";
}
+ if (has_reflection_probes)
+ {
+ attribs["REFMAP_LEVEL"] = std::to_string(probe_level);
+ attribs["REF_SAMPLE_COUNT"] = "32";
+ }
+
+ LLGLSLShader::sGlobalDefines = attribs;
+
// We no longer have to bind the shaders to global glhandles, they are automatically added to a map now.
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_VERTEX_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER_ARB, &attribs) == 0)
+ // Note usage of GL_VERTEX_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_VERTEX_SHADER, &attribs) == 0)
{
LL_WARNS("Shader") << "Failed to load vertex shader " << shaders[i].first << LL_ENDL;
return shaders[i].first;
@@ -963,9 +668,10 @@ std::string LLViewerShaderMgr::loadBasicShaders()
if (gGLManager.mGLSLVersionMajor > 1 || gGLManager.mGLSLVersionMinor >= 30)
{ //use indexed texture rendering for GLSL >= 1.30
- ch = llmax(LLGLSLShader::sIndexedTextureChannels-1, 1);
+ ch = llmax(LLGLSLShader::sIndexedTextureChannels, 1);
}
+
std::vector<S32> index_channels;
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsVarsWaterF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
@@ -973,42 +679,27 @@ std::string LLViewerShaderMgr::loadBasicShaders()
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/gammaF.glsl", mShaderLevel[SHADER_WINDLIGHT]) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsFuncs.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/atmosphericsF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "windlight/transportF.glsl", mShaderLevel[SHADER_WINDLIGHT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "environment/waterFogF.glsl", mShaderLevel[SHADER_WATER] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "environment/encodeNormF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "environment/srgbF.glsl", mShaderLevel[SHADER_ENVIRONMENT] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/deferredUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/shadowUtil.glsl", 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/aoUtil.glsl", 1) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/reflectionProbeF.glsl", has_reflection_probes ? 3 : 2) );
+ index_channels.push_back(-1); shaders.push_back( make_pair( "deferred/screenSpaceReflUtil.glsl", ssr ? 3 : 1) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightWaterNonIndexedAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(-1); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterNonIndexedF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightWaterAlphaMaskF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
- index_channels.push_back(ch); shaders.push_back( make_pair( "lighting/lightFullbrightShinyWaterF.glsl", mShaderLevel[SHADER_LIGHTING] ) );
-
+
for (U32 i = 0; i < shaders.size(); i++)
{
- // Note usage of GL_FRAGMENT_SHADER_ARB
- if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER_ARB, &attribs, index_channels[i]) == 0)
+ // Note usage of GL_FRAGMENT_SHADER
+ if (loadShaderFile(shaders[i].first, shaders[i].second, GL_FRAGMENT_SHADER, &attribs, index_channels[i]) == 0)
{
LL_WARNS("Shader") << "Failed to load fragment shader " << shaders[i].first << LL_ENDL;
return shaders[i].first;
@@ -1018,58 +709,20 @@ std::string LLViewerShaderMgr::loadBasicShaders()
return std::string();
}
-BOOL LLViewerShaderMgr::loadShadersEnvironment()
-{
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_ENVIRONMENT] == 0)
- {
- gTerrainProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gTerrainProgram.mName = "Terrain Shader";
- gTerrainProgram.mFeatures.calculatesLighting = true;
- gTerrainProgram.mFeatures.calculatesAtmospherics = true;
- gTerrainProgram.mFeatures.hasAtmospherics = true;
- gTerrainProgram.mFeatures.hasTransport = true;
- gTerrainProgram.mFeatures.hasGamma = true;
- gTerrainProgram.mFeatures.hasSrgb = true;
- gTerrainProgram.mFeatures.mIndexedTextureChannels = 0;
- gTerrainProgram.mFeatures.disableTextureIndex = true;
- gTerrainProgram.mFeatures.hasGamma = true;
- gTerrainProgram.mShaderFiles.clear();
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainProgram.mShaderFiles.push_back(make_pair("environment/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
- gTerrainProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
- success = gTerrainProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (!success)
- {
- mShaderLevel[SHADER_ENVIRONMENT] = 0;
- return FALSE;
- }
-
- LLWorld::getInstance()->updateWaterObjects();
-
- return TRUE;
-}
-
BOOL LLViewerShaderMgr::loadShadersWater()
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
BOOL terrainWaterSuccess = TRUE;
+
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
if (mShaderLevel[SHADER_WATER] == 0)
{
gWaterProgram.unload();
gWaterEdgeProgram.unload();
gUnderWaterProgram.unload();
- gTerrainWaterProgram.unload();
return TRUE;
}
@@ -1078,12 +731,26 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterProgram.mName = "Water Shader";
gWaterProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterProgram.mFeatures.hasAtmospherics = true;
+ gWaterProgram.mFeatures.hasWaterFog = true;
gWaterProgram.mFeatures.hasGamma = true;
- gWaterProgram.mFeatures.hasTransport = true;
- gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasSrgb = true;
+ gWaterProgram.mFeatures.hasReflectionProbes = true;
+ gWaterProgram.mFeatures.hasShadows = use_sun_shadow;
gWaterProgram.mShaderFiles.clear();
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ gWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
gWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterProgram.createShader(NULL, NULL);
@@ -1095,13 +762,26 @@ BOOL LLViewerShaderMgr::loadShadersWater()
// load water shader
gWaterEdgeProgram.mName = "Water Edge Shader";
gWaterEdgeProgram.mFeatures.calculatesAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasAtmospherics = true;
+ gWaterEdgeProgram.mFeatures.hasWaterFog = true;
gWaterEdgeProgram.mFeatures.hasGamma = true;
- gWaterEdgeProgram.mFeatures.hasTransport = true;
- gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasSrgb = true;
+ gWaterEdgeProgram.mFeatures.hasReflectionProbes = true;
+ gWaterEdgeProgram.mFeatures.hasShadows = use_sun_shadow;
gWaterEdgeProgram.mShaderFiles.clear();
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gWaterEdgeProgram.mShaderFiles.push_back(make_pair("environment/waterF.glsl", GL_FRAGMENT_SHADER));
+ gWaterEdgeProgram.clearPermutations();
gWaterEdgeProgram.addPermutation("WATER_EDGE", "1");
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gWaterEdgeProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
+
+ if (use_sun_shadow)
+ {
+ gWaterEdgeProgram.addPermutation("HAS_SUN_SHADOW", "1");
+ }
gWaterEdgeProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gWaterEdgeProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
success = gWaterEdgeProgram.createShader(NULL, NULL);
@@ -1115,41 +795,19 @@ BOOL LLViewerShaderMgr::loadShadersWater()
gUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
gUnderWaterProgram.mFeatures.hasWaterFog = true;
gUnderWaterProgram.mShaderFiles.clear();
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/waterV.glsl", GL_VERTEX_SHADER));
+ gUnderWaterProgram.mShaderFiles.push_back(make_pair("environment/underWaterF.glsl", GL_FRAGMENT_SHADER));
gUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_WATER];
gUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gUnderWaterProgram.clearPermutations();
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ gUnderWaterProgram.addPermutation("TRANSPARENT_WATER", "1");
+ }
success = gUnderWaterProgram.createShader(NULL, NULL);
llassert(success);
}
- if (success)
- {
- //load terrain water shader
- gTerrainWaterProgram.mName = "Terrain Water Shader";
- gTerrainWaterProgram.mFeatures.calculatesLighting = true;
- gTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
- gTerrainWaterProgram.mFeatures.hasAtmospherics = true;
- gTerrainWaterProgram.mFeatures.hasWaterFog = true;
- gTerrainWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gTerrainWaterProgram.mFeatures.disableTextureIndex = true;
- gTerrainWaterProgram.mShaderFiles.clear();
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterV.glsl", GL_VERTEX_SHADER_ARB));
- gTerrainWaterProgram.mShaderFiles.push_back(make_pair("environment/terrainWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_ENVIRONMENT];
- gTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
-
- gTerrainWaterProgram.clearPermutations();
-
- if (LLPipeline::RenderDeferred)
- {
- gTerrainWaterProgram.addPermutation("ALM", "1");
- }
-
- terrainWaterSuccess = gTerrainWaterProgram.createShader(NULL, NULL);
- llassert(terrainWaterSuccess);
- }
-
/// Keep track of water shader levels
if (gWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER]
|| gUnderWaterProgram.mShaderLevel != mShaderLevel[SHADER_WATER])
@@ -1173,19 +831,18 @@ BOOL LLViewerShaderMgr::loadShadersWater()
LLWorld::getInstance()->updateWaterObjects();
- return TRUE;
+ return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersEffects()
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
if (mShaderLevel[SHADER_EFFECT] == 0)
{
gGlowProgram.unload();
gGlowExtractProgram.unload();
- gPostColorFilterProgram.unload();
- gPostNightVisionProgram.unload();
return TRUE;
}
@@ -1193,8 +850,8 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
{
gGlowProgram.mName = "Glow Shader (Post)";
gGlowProgram.mShaderFiles.clear();
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowV.glsl", GL_VERTEX_SHADER));
+ gGlowProgram.mShaderFiles.push_back(make_pair("effects/glowF.glsl", GL_FRAGMENT_SHADER));
gGlowProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
success = gGlowProgram.createShader(NULL, NULL);
if (!success)
@@ -1205,11 +862,20 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
if (success)
{
- gGlowExtractProgram.mName = "Glow Extract Shader (Post)";
+ const bool use_glow_noise = gSavedSettings.getBOOL("RenderGlowNoise");
+ const std::string glow_noise_label = use_glow_noise ? " (+Noise)" : "";
+
+ gGlowExtractProgram.mName = llformat("Glow Extract Shader (Post)%s", glow_noise_label.c_str());
gGlowExtractProgram.mShaderFiles.clear();
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractV.glsl", GL_VERTEX_SHADER));
+ gGlowExtractProgram.mShaderFiles.push_back(make_pair("effects/glowExtractF.glsl", GL_FRAGMENT_SHADER));
gGlowExtractProgram.mShaderLevel = mShaderLevel[SHADER_EFFECT];
+
+ if (use_glow_noise)
+ {
+ gGlowExtractProgram.addPermutation("HAS_NOISE", "1");
+ }
+
success = gGlowExtractProgram.createShader(NULL, NULL);
if (!success)
{
@@ -1223,11 +889,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
BOOL LLViewerShaderMgr::loadShadersDeferred()
{
- bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1;
-
- BOOL ambient_kill = gSavedSettings.getBOOL("AmbientDisable");
- BOOL sunlight_kill = gSavedSettings.getBOOL("SunlightDisable");
- BOOL local_light_kill = gSavedSettings.getBOOL("LocalLightDisable");
+ LL_PROFILE_ZONE_SCOPED;
+ bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 &&
+ gSavedSettings.getS32("RenderShadowDetail") > 0;
if (mShaderLevel[SHADER_DEFERRED] == 0)
{
@@ -1235,14 +899,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTreeShadowProgram.unload();
gDeferredSkinnedTreeShadowProgram.unload();
gDeferredDiffuseProgram.unload();
+ gDeferredSkinnedDiffuseProgram.unload();
gDeferredDiffuseAlphaMaskProgram.unload();
gDeferredSkinnedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskProgram.unload();
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload();
- gDeferredNonIndexedDiffuseProgram.unload();
- gDeferredSkinnedDiffuseProgram.unload();
- gDeferredSkinnedBumpProgram.unload();
gDeferredBumpProgram.unload();
+ gDeferredSkinnedBumpProgram.unload();
gDeferredImpostorProgram.unload();
gDeferredTerrainProgram.unload();
gDeferredTerrainWaterProgram.unload();
@@ -1262,24 +925,30 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowCubeProgram.unload();
gDeferredShadowAlphaMaskProgram.unload();
gDeferredSkinnedShadowAlphaMaskProgram.unload();
+ gDeferredShadowGLTFAlphaMaskProgram.unload();
+ gDeferredSkinnedShadowGLTFAlphaMaskProgram.unload();
gDeferredShadowFullbrightAlphaMaskProgram.unload();
gDeferredSkinnedShadowFullbrightAlphaMaskProgram.unload();
gDeferredAvatarShadowProgram.unload();
gDeferredAvatarAlphaShadowProgram.unload();
gDeferredAvatarAlphaMaskShadowProgram.unload();
- gDeferredAttachmentShadowProgram.unload();
- gDeferredAttachmentAlphaShadowProgram.unload();
- gDeferredAttachmentAlphaMaskShadowProgram.unload();
gDeferredAvatarProgram.unload();
gDeferredAvatarAlphaProgram.unload();
gDeferredAlphaProgram.unload();
+ gHUDAlphaProgram.unload();
gDeferredSkinnedAlphaProgram.unload();
gDeferredAlphaWaterProgram.unload();
gDeferredSkinnedAlphaWaterProgram.unload();
gDeferredFullbrightProgram.unload();
+ gHUDFullbrightProgram.unload();
gDeferredFullbrightAlphaMaskProgram.unload();
+ gHUDFullbrightAlphaMaskProgram.unload();
+ gDeferredFullbrightAlphaMaskAlphaProgram.unload();
+ gHUDFullbrightAlphaMaskAlphaProgram.unload();
gDeferredFullbrightWaterProgram.unload();
gDeferredSkinnedFullbrightWaterProgram.unload();
+ gDeferredFullbrightWaterAlphaProgram.unload();
+ gDeferredSkinnedFullbrightWaterAlphaProgram.unload();
gDeferredFullbrightAlphaMaskWaterProgram.unload();
gDeferredSkinnedFullbrightAlphaMaskWaterProgram.unload();
gDeferredEmissiveProgram.unload();
@@ -1288,30 +957,45 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredPostProgram.unload();
gDeferredCoFProgram.unload();
gDeferredDoFCombineProgram.unload();
+ gExposureProgram.unload();
+ gLuminanceProgram.unload();
gDeferredPostGammaCorrectProgram.unload();
+ gNoPostGammaCorrectProgram.unload();
+ gLegacyPostGammaCorrectProgram.unload();
gFXAAProgram.unload();
- gDeferredWaterProgram.unload();
- gDeferredUnderWaterProgram.unload();
gDeferredWLSkyProgram.unload();
gDeferredWLCloudProgram.unload();
gDeferredWLSunProgram.unload();
gDeferredWLMoonProgram.unload();
gDeferredStarProgram.unload();
gDeferredFullbrightShinyProgram.unload();
+ gHUDFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightShinyProgram.unload();
gDeferredSkinnedFullbrightProgram.unload();
gDeferredSkinnedFullbrightAlphaMaskProgram.unload();
+ gDeferredSkinnedFullbrightAlphaMaskAlphaProgram.unload();
gDeferredHighlightProgram.unload();
- gDeferredHighlightNormalProgram.unload();
- gDeferredHighlightSpecularProgram.unload();
-
+
gNormalMapGenProgram.unload();
+ gDeferredGenBrdfLutProgram.unload();
+ gDeferredBufferVisualProgram.unload();
+
for (U32 i = 0; i < LLMaterial::SHADER_COUNT*2; ++i)
{
gDeferredMaterialProgram[i].unload();
gDeferredMaterialWaterProgram[i].unload();
}
+
+ gHUDPBROpaqueProgram.unload();
+ gPBRGlowProgram.unload();
+ gDeferredPBROpaqueProgram.unload();
+ gDeferredSkinnedPBROpaqueProgram.unload();
+ gDeferredPBRAlphaProgram.unload();
+ gDeferredSkinnedPBRAlphaProgram.unload();
+ gDeferredPBRAlphaWaterProgram.unload();
+ gDeferredSkinnedPBRAlphaWaterProgram.unload();
+
return TRUE;
}
@@ -1321,40 +1005,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredHighlightProgram.mName = "Deferred Highlight Shader";
gDeferredHighlightProgram.mShaderFiles.clear();
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gDeferredHighlightProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER));
gDeferredHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gDeferredHighlightProgram.createShader(NULL, NULL);
}
if (success)
{
- gDeferredHighlightNormalProgram.mName = "Deferred Highlight Normals Shader";
- gDeferredHighlightNormalProgram.mShaderFiles.clear();
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightNormalProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gHighlightNormalProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gDeferredHighlightSpecularProgram.mName = "Deferred Highlight Spec Shader";
- gDeferredHighlightSpecularProgram.mShaderFiles.clear();
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredHighlightSpecularProgram.mShaderFiles.push_back(make_pair("deferred/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDeferredHighlightSpecularProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gDeferredDiffuseProgram.mName = "Deferred Diffuse Shader";
gDeferredDiffuseProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseProgram.mFeatures.hasSrgb = true;
gDeferredDiffuseProgram.mShaderFiles.clear();
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseProgram, gDeferredSkinnedDiffuseProgram);
@@ -1366,8 +1030,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Alpha Mask Shader";
gDeferredDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskIndexedF.glsl", GL_FRAGMENT_SHADER));
gDeferredDiffuseAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredDiffuseAlphaMaskProgram, gDeferredSkinnedDiffuseAlphaMaskProgram);
@@ -1379,8 +1043,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredNonIndexedDiffuseAlphaMaskProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
gDeferredNonIndexedDiffuseAlphaMaskProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
@@ -1388,11 +1052,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask Shader";
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mName = "Deferred Diffuse Non-Indexed Alpha Mask No Color Shader";
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mFeatures.encodesNormal = true;
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseNoColorV.glsl", GL_VERTEX_SHADER));
+ gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("deferred/diffuseAlphaMaskNoColorF.glsl", GL_FRAGMENT_SHADER));
gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1400,24 +1064,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader";
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear();
- gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true;
- gDeferredNonIndexedDiffuseProgram.mFeatures.hasSrgb = true;
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
gDeferredBumpProgram.mName = "Deferred Bump Shader";
gDeferredBumpProgram.mFeatures.encodesNormal = true;
gDeferredBumpProgram.mShaderFiles.clear();
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpV.glsl", GL_VERTEX_SHADER));
+ gDeferredBumpProgram.mShaderFiles.push_back(make_pair("deferred/bumpF.glsl", GL_FRAGMENT_SHADER));
gDeferredBumpProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredBumpProgram, gDeferredSkinnedBumpProgram);
success = success && gDeferredBumpProgram.createShader(NULL, NULL);
@@ -1453,8 +1104,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
U32 alpha_mode = i & 0x3;
gDeferredMaterialProgram[i].mShaderFiles.clear();
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialProgram[i].clearPermutations();
@@ -1472,21 +1123,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialProgram[i].addPermutation("HAS_SPECULAR_MAP", "1");
}
- if (ambient_kill)
- {
- gDeferredMaterialProgram[i].addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredMaterialProgram[i].addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredMaterialProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
gDeferredMaterialProgram[i].addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
if (alpha_mode != 0)
@@ -1502,13 +1138,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
bool has_skin = i & 0x10;
gDeferredMaterialProgram[i].mFeatures.hasSrgb = true;
- gDeferredMaterialProgram[i].mFeatures.hasTransport = true;
gDeferredMaterialProgram[i].mFeatures.encodesNormal = true;
gDeferredMaterialProgram[i].mFeatures.calculatesAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasAtmospherics = true;
gDeferredMaterialProgram[i].mFeatures.hasGamma = true;
gDeferredMaterialProgram[i].mFeatures.hasShadows = use_sun_shadow;
-
+ gDeferredMaterialProgram[i].mFeatures.hasReflectionProbes = true;
+
if (has_skin)
{
gDeferredMaterialProgram[i].addPermutation("HAS_SKIN", "1");
@@ -1532,8 +1168,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
U32 alpha_mode = i & 0x3;
gDeferredMaterialWaterProgram[i].mShaderFiles.clear();
- gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialV.glsl", GL_VERTEX_SHADER));
+ gDeferredMaterialWaterProgram[i].mShaderFiles.push_back(make_pair("deferred/materialF.glsl", GL_FRAGMENT_SHADER));
gDeferredMaterialWaterProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMaterialWaterProgram[i].mShaderGroup = LLGLSLShader::SG_WATER;
@@ -1575,21 +1211,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
}
gDeferredMaterialWaterProgram[i].addPermutation("WATER_FOG","1");
- if (ambient_kill)
- {
- gDeferredMaterialWaterProgram[i].addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredMaterialWaterProgram[i].addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredMaterialWaterProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
+ gDeferredMaterialWaterProgram[i].mFeatures.hasReflectionProbes = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasWaterFog = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasSrgb = true;
gDeferredMaterialWaterProgram[i].mFeatures.encodesNormal = true;
@@ -1597,7 +1219,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[i].mFeatures.hasAtmospherics = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasGamma = true;
- gDeferredMaterialWaterProgram[i].mFeatures.hasTransport = true;
gDeferredMaterialWaterProgram[i].mFeatures.hasShadows = use_sun_shadow;
if (has_skin)
@@ -1628,14 +1249,196 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMaterialWaterProgram[9+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
gDeferredMaterialWaterProgram[13+LLMaterial::SHADER_COUNT].mFeatures.hasLighting = true;
+ if (success)
+ {
+ gDeferredPBROpaqueProgram.mName = "Deferred PBR Opaque Shader";
+ gDeferredPBROpaqueProgram.mFeatures.encodesNormal = true;
+ gDeferredPBROpaqueProgram.mFeatures.hasSrgb = true;
+
+ gDeferredPBROpaqueProgram.mShaderFiles.clear();
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredPBROpaqueProgram.clearPermutations();
+
+ success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram);
+ if (success)
+ {
+ success = gDeferredPBROpaqueProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gPBRGlowProgram.mName = " PBR Glow Shader";
+ gPBRGlowProgram.mFeatures.hasSrgb = true;
+ gPBRGlowProgram.mShaderFiles.clear();
+ gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowV.glsl", GL_VERTEX_SHADER));
+ gPBRGlowProgram.mShaderFiles.push_back(make_pair("deferred/pbrglowF.glsl", GL_FRAGMENT_SHADER));
+ gPBRGlowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+
+ success = make_rigged_variant(gPBRGlowProgram, gPBRGlowSkinnedProgram);
+ if (success)
+ {
+ success = gPBRGlowProgram.createShader(NULL, NULL);
+ }
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDPBROpaqueProgram.mName = "HUD PBR Opaque Shader";
+ gHUDPBROpaqueProgram.mFeatures.hasSrgb = true;
+ gHUDPBROpaqueProgram.mShaderFiles.clear();
+ gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER));
+ gHUDPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER));
+ gHUDPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDPBROpaqueProgram.clearPermutations();
+ gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1");
+
+ success = gHUDPBROpaqueProgram.createShader(NULL, NULL);
+
+ llassert(success);
+ }
+
+
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gDeferredPBRAlphaProgram;
+ shader->mName = "Deferred PBR Alpha Shader";
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.isDeferred = true; // include deferredUtils
+ shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ shader->addPermutation("HAS_NORMAL_MAP", "1");
+ shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
+ shader->addPermutation("HAS_EMISSIVE_MAP", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram);
+ if (success)
+ {
+ success = shader->createShader(NULL, NULL);
+ }
+ llassert(success);
+
+ // Alpha Shader Hack
+ // See: LLRender::syncMatrices()
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+
+ shader->mRiggedVariant->mFeatures.calculatesLighting = true;
+ shader->mRiggedVariant->mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gDeferredPBRAlphaWaterProgram;
+ shader->mName = "Deferred PBR Alpha Underwater Shader";
+
+ shader->mFeatures.calculatesLighting = false;
+ shader->mFeatures.hasLighting = false;
+ shader->mFeatures.isAlphaLighting = true;
+ shader->mFeatures.hasWaterFog = true;
+ shader->mFeatures.hasSrgb = true;
+ shader->mFeatures.encodesNormal = true;
+ shader->mFeatures.calculatesAtmospherics = true;
+ shader->mFeatures.hasAtmospherics = true;
+ shader->mFeatures.hasGamma = true;
+ shader->mFeatures.hasShadows = use_sun_shadow;
+ shader->mFeatures.isDeferred = true; // include deferredUtils
+ shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED];
+
+ shader->mShaderGroup = LLGLSLShader::SG_WATER;
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ U32 alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_BLEND;
+ shader->addPermutation("DIFFUSE_ALPHA_MODE", llformat("%d", alpha_mode));
+ shader->addPermutation("HAS_NORMAL_MAP", "1");
+ shader->addPermutation("HAS_SPECULAR_MAP", "1"); // PBR: Packed: Occlusion, Metal, Roughness
+ shader->addPermutation("HAS_EMISSIVE_MAP", "1");
+ shader->addPermutation("USE_VERTEX_COLOR", "1");
+ shader->addPermutation("WATER_FOG", "1");
+
+ if (use_sun_shadow)
+ {
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
+ }
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaWaterProgram);
+ if (success)
+ {
+ success = shader->createShader(NULL, NULL);
+ }
+ llassert(success);
+
+ // Alpha Shader Hack
+ // See: LLRender::syncMatrices()
+ shader->mFeatures.calculatesLighting = true;
+ shader->mFeatures.hasLighting = true;
+
+ shader->mRiggedVariant->mFeatures.calculatesLighting = true;
+ shader->mRiggedVariant->mFeatures.hasLighting = true;
+ }
+
+ if (success)
+ {
+ LLGLSLShader* shader = &gHUDPBRAlphaProgram;
+ shader->mName = "HUD PBR Alpha Shader";
+
+ shader->mFeatures.hasSrgb = true;
+
+ shader->mShaderFiles.clear();
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER));
+
+ shader->clearPermutations();
+
+ shader->addPermutation("IS_HUD", "1");
+
+ shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = shader->createShader(NULL, NULL);
+ llassert(success);
+ }
if (success)
{
gDeferredTreeProgram.mName = "Deferred Tree Shader";
gDeferredTreeProgram.mShaderFiles.clear();
gDeferredTreeProgram.mFeatures.encodesNormal = true;
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeProgram.mShaderFiles.push_back(make_pair("deferred/treeF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTreeProgram.createShader(NULL, NULL);
}
@@ -1644,10 +1447,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredTreeShadowProgram.mName = "Deferred Tree Shadow Shader";
gDeferredTreeShadowProgram.mShaderFiles.clear();
- gDeferredTreeShadowProgram.mFeatures.isDeferred = true;
- gDeferredTreeShadowProgram.mFeatures.hasShadows = true;
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTreeShadowProgram.mRiggedVariant = &gDeferredSkinnedTreeShadowProgram;
success = gDeferredTreeShadowProgram.createShader(NULL, NULL);
@@ -1658,11 +1459,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSkinnedTreeShadowProgram.mName = "Deferred Skinned Tree Shadow Shader";
gDeferredSkinnedTreeShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedTreeShadowProgram.mFeatures.isDeferred = true;
- gDeferredSkinnedTreeShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedTreeShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedTreeShadowProgram.mShaderFiles.push_back(make_pair("deferred/treeShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedTreeShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSkinnedTreeShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -1675,8 +1474,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredImpostorProgram.mFeatures.encodesNormal = true;
//gDeferredImpostorProgram.mFeatures.isDeferred = true;
gDeferredImpostorProgram.mShaderFiles.clear();
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorV.glsl", GL_VERTEX_SHADER));
+ gDeferredImpostorProgram.mShaderFiles.push_back(make_pair("deferred/impostorF.glsl", GL_FRAGMENT_SHADER));
gDeferredImpostorProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredImpostorProgram.createShader(NULL, NULL);
llassert(success);
@@ -1690,27 +1489,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredLightProgram.mFeatures.hasSrgb = true;
gDeferredLightProgram.mShaderFiles.clear();
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredLightProgram.clearPermutations();
- if (ambient_kill)
- {
- gDeferredLightProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredLightProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
success = gDeferredLightProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1726,26 +1510,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiLightProgram[i].clearPermutations();
gDeferredMultiLightProgram[i].mShaderFiles.clear();
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiLightProgram[i].mShaderFiles.push_back(make_pair("deferred/multiPointLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiLightProgram[i].mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredMultiLightProgram[i].addPermutation("LIGHT_COUNT", llformat("%d", i+1));
- if (ambient_kill)
- {
- gDeferredMultiLightProgram[i].addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredMultiLightProgram[i].addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredMultiLightProgram[i].addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
success = gDeferredMultiLightProgram[i].createShader(NULL, NULL);
llassert(success);
}
@@ -1760,25 +1529,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSpotLightProgram.mFeatures.hasShadows = true;
gDeferredSpotLightProgram.clearPermutations();
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (ambient_kill)
- {
- gDeferredSpotLightProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredSpotLightProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredSpotLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
success = gDeferredSpotLightProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1791,16 +1545,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredMultiSpotLightProgram.mFeatures.hasShadows = true;
gDeferredMultiSpotLightProgram.clearPermutations();
+ gDeferredMultiSpotLightProgram.addPermutation("MULTI_SPOTLIGHT", "1");
gDeferredMultiSpotLightProgram.mShaderFiles.clear();
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiPointLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/spotLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredMultiSpotLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (local_light_kill)
- {
- gDeferredMultiSpotLightProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
-
success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -1830,10 +1580,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSunProgram.mFeatures.hasShadows = true;
gDeferredSunProgram.mFeatures.hasAmbientOcclusion = use_ao;
- gDeferredSunProgram.mName = "Deferred Sun Shader";
- gDeferredSunProgram.mShaderFiles.clear();
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER_ARB));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
+ gDeferredSunProgram.mShaderFiles.clear();
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(vertex, GL_VERTEX_SHADER));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER));
gDeferredSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredSunProgram.createShader(NULL, NULL);
@@ -1846,8 +1595,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredBlurLightProgram.mFeatures.isDeferred = true;
gDeferredBlurLightProgram.mShaderFiles.clear();
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredBlurLightProgram.mShaderFiles.push_back(make_pair("deferred/blurLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredBlurLightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredBlurLightProgram.createShader(NULL, NULL);
@@ -1856,11 +1605,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- for (int i = 0; i < 2 && success; ++i)
+ for (int i = 0; i < 3 && success; ++i)
{
LLGLSLShader* shader = nullptr;
- bool rigged = i == 1;
- if (!rigged)
+ bool rigged = (i == 1);
+ bool hud = (i == 2);
+
+ if (hud)
+ {
+ shader = &gHUDAlphaProgram;
+ shader->mName = "HUD Alpha Shader";
+ }
+ else if (!rigged)
{
shader = &gDeferredAlphaProgram;
shader->mName = "Deferred Alpha Shader";
@@ -1882,21 +1638,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.calculatesAtmospherics = true;
shader->mFeatures.hasAtmospherics = true;
shader->mFeatures.hasGamma = true;
- shader->mFeatures.hasTransport = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.hasWaterFog = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_VERTEX_COLOR", "1");
@@ -1904,27 +1653,17 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->addPermutation("USE_INDEXED_TEX", "1");
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
- }
-
- if (ambient_kill)
- {
- shader->addPermutation("AMBIENT_KILL", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
- if (sunlight_kill)
- {
- shader->addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
+ if (rigged)
{
- shader->addPermutation("LOCAL_LIGHT_KILL", "1");
+ shader->addPermutation("HAS_SKIN", "1");
}
- if (rigged)
+ if (hud)
{
- shader->addPermutation("HAS_SKIN", "1");
+ shader->addPermutation("IS_HUD", "1");
}
shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -1960,19 +1699,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader->mFeatures.isAlphaLighting = true;
shader->mFeatures.encodesNormal = true;
shader->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader->mFeatures.hasReflectionProbes = true;
+ shader->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader->mShaderFiles.clear();
- shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader->clearPermutations();
shader->addPermutation("USE_INDEXED_TEX", "1");
@@ -1987,7 +1719,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (use_sun_shadow)
{
- shader->addPermutation("HAS_SHADOW", "1");
+ shader->addPermutation("HAS_SUN_SHADOW", "1");
}
shader->mRiggedVariant = &gDeferredSkinnedAlphaImpostorProgram;
@@ -2029,21 +1761,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->mFeatures.calculatesAtmospherics = true;
shader[i]->mFeatures.hasAtmospherics = true;
shader[i]->mFeatures.hasGamma = true;
- shader[i]->mFeatures.hasTransport = true;
shader[i]->mFeatures.hasShadows = use_sun_shadow;
-
- if (mShaderLevel[SHADER_DEFERRED] < 1)
- {
- shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- }
- else
- { //shave off some texture units for shadow maps
- shader[i]->mFeatures.mIndexedTextureChannels = llmax(LLGLSLShader::sIndexedTextureChannels - 6, 1);
- }
+ shader[i]->mFeatures.hasReflectionProbes = true;
+ shader[i]->mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
shader[i]->mShaderGroup = LLGLSLShader::SG_WATER;
shader[i]->mShaderFiles.clear();
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ shader[i]->mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
shader[i]->clearPermutations();
shader[i]->addPermutation("USE_INDEXED_TEX", "1");
@@ -2052,22 +1776,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
shader[i]->addPermutation("HAS_ALPHA_MASK", "1");
if (use_sun_shadow)
{
- shader[i]->addPermutation("HAS_SHADOW", "1");
- }
-
- if (ambient_kill)
- {
- shader[i]->addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- shader[i]->addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- shader[i]->addPermutation("LOCAL_LIGHT_KILL", "1");
+ shader[i]->addPermutation("HAS_SUN_SHADOW", "1");
}
if (i == 1)
@@ -2095,15 +1804,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarEyesProgram.mName = "Deferred Avatar Eyes Shader";
gDeferredAvatarEyesProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarEyesProgram.mFeatures.hasGamma = true;
- gDeferredAvatarEyesProgram.mFeatures.hasTransport = true;
+ gDeferredAvatarEyesProgram.mFeatures.hasAtmospherics = true;
gDeferredAvatarEyesProgram.mFeatures.disableTextureIndex = true;
gDeferredAvatarEyesProgram.mFeatures.hasSrgb = true;
gDeferredAvatarEyesProgram.mFeatures.encodesNormal = true;
gDeferredAvatarEyesProgram.mFeatures.hasShadows = true;
gDeferredAvatarEyesProgram.mShaderFiles.clear();
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/avatarEyesV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarEyesProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarEyesProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarEyesProgram.createShader(NULL, NULL);
llassert(success);
@@ -2114,29 +1823,48 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightProgram.mName = "Deferred Fullbright Shader";
gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightProgram.mFeatures.hasTransport = true;
- gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightProgram.mShaderFiles.clear();
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightProgram, gDeferredSkinnedFullbrightProgram);
success = gDeferredFullbrightProgram.createShader(NULL, NULL);
llassert(success);
}
+ if (success)
+ {
+ gHUDFullbrightProgram.mName = "HUD Fullbright Shader";
+ gHUDFullbrightProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightProgram.mShaderFiles.clear();
+ gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDFullbrightProgram.clearPermutations();
+ gHUDFullbrightProgram.addPermutation("IS_HUD", "1");
+ success = gHUDFullbrightProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredFullbrightAlphaMaskProgram.mName = "Deferred Fullbright Alpha Masking Shader";
gDeferredFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightAlphaMaskProgram.clearPermutations();
gDeferredFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredFullbrightAlphaMaskProgram, gDeferredSkinnedFullbrightAlphaMaskProgram);
@@ -2144,18 +1872,79 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
+ if (success)
+ {
+ gHUDFullbrightAlphaMaskProgram.mName = "HUD Fullbright Alpha Masking Shader";
+ gHUDFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.clear();
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightAlphaMaskProgram.clearPermutations();
+ gHUDFullbrightAlphaMaskProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gHUDFullbrightAlphaMaskProgram.addPermutation("IS_HUD", "1");
+ gHUDFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gHUDFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredFullbrightAlphaMaskAlphaProgram.mName = "Deferred Fullbright Alpha Masking Alpha Shader";
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightAlphaMaskAlphaProgram.clearPermutations();
+ gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gDeferredFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
+ gDeferredFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = make_rigged_variant(gDeferredFullbrightAlphaMaskAlphaProgram, gDeferredSkinnedFullbrightAlphaMaskAlphaProgram);
+ success = success && gDeferredFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gHUDFullbrightAlphaMaskAlphaProgram.mName = "HUD Fullbright Alpha Masking Alpha Shader";
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.isDeferred = true;
+ gHUDFullbrightAlphaMaskAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.clear();
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightAlphaMaskAlphaProgram.clearPermutations();
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("HAS_ALPHA_MASK", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_ALPHA", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.addPermutation("IS_HUD", "1");
+ gHUDFullbrightAlphaMaskAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = success && gHUDFullbrightAlphaMaskAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredFullbrightWaterProgram.mName = "Deferred Fullbright Underwater Shader";
gDeferredFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightWaterProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightWaterProgram.mFeatures.hasAtmospherics = true;
gDeferredFullbrightWaterProgram.mFeatures.hasWaterFog = true;
gDeferredFullbrightWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gDeferredFullbrightWaterProgram.addPermutation("WATER_FOG","1");
@@ -2164,20 +1953,44 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
llassert(success);
}
+ if (success)
+ {
+ gDeferredFullbrightWaterAlphaProgram.mName = "Deferred Fullbright Underwater Alpha Shader";
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.calculatesAtmospherics = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.hasGamma = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.hasAtmospherics = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.hasWaterFog = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.hasSrgb = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.isDeferred = true;
+ gDeferredFullbrightWaterAlphaProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gDeferredFullbrightWaterAlphaProgram.mShaderFiles.clear();
+ gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightWaterAlphaProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredFullbrightWaterAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightWaterAlphaProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightWaterAlphaProgram.clearPermutations();
+ gDeferredFullbrightWaterAlphaProgram.addPermutation("WATER_FOG", "1");
+ gDeferredFullbrightWaterAlphaProgram.addPermutation("IS_ALPHA", "1");
+ success = make_rigged_variant(gDeferredFullbrightWaterAlphaProgram, gDeferredSkinnedFullbrightWaterAlphaProgram);
+ success = success && gDeferredFullbrightWaterAlphaProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredFullbrightAlphaMaskWaterProgram.mName = "Deferred Fullbright Underwater Alpha Masking Shader";
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasTransport = true;
+ gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasAtmospherics = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasWaterFog = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.hasSrgb = true;
gDeferredFullbrightAlphaMaskWaterProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.clear();
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightAlphaMaskWaterProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightAlphaMaskWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredFullbrightAlphaMaskWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredFullbrightAlphaMaskWaterProgram.clearPermutations();
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("HAS_ALPHA_MASK","1");
gDeferredFullbrightAlphaMaskWaterProgram.addPermutation("WATER_FOG","1");
success = make_rigged_variant(gDeferredFullbrightAlphaMaskWaterProgram, gDeferredSkinnedFullbrightAlphaMaskWaterProgram);
@@ -2191,28 +2004,47 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
gDeferredFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
gDeferredFullbrightShinyProgram.mFeatures.hasGamma = true;
- gDeferredFullbrightShinyProgram.mFeatures.hasTransport = true;
gDeferredFullbrightShinyProgram.mFeatures.hasSrgb = true;
- gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels-1;
+ gDeferredFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredFullbrightShinyProgram.mShaderFiles.clear();
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gDeferredFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
gDeferredFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
success = make_rigged_variant(gDeferredFullbrightShinyProgram, gDeferredSkinnedFullbrightShinyProgram);
success = success && gDeferredFullbrightShinyProgram.createShader(NULL, NULL);
llassert(success);
}
+ if (success)
+ {
+ gHUDFullbrightShinyProgram.mName = "HUD FullbrightShiny Shader";
+ gHUDFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasAtmospherics = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasGamma = true;
+ gHUDFullbrightShinyProgram.mFeatures.hasSrgb = true;
+ gHUDFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
+ gHUDFullbrightShinyProgram.mShaderFiles.clear();
+ gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyV.glsl", GL_VERTEX_SHADER));
+ gHUDFullbrightShinyProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER));
+ gHUDFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gHUDFullbrightShinyProgram.mFeatures.hasReflectionProbes = true;
+ gHUDFullbrightShinyProgram.clearPermutations();
+ gHUDFullbrightShinyProgram.addPermutation("IS_HUD", "1");
+ success = gHUDFullbrightShinyProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredEmissiveProgram.mName = "Deferred Emissive Shader";
gDeferredEmissiveProgram.mFeatures.calculatesAtmospherics = true;
gDeferredEmissiveProgram.mFeatures.hasGamma = true;
- gDeferredEmissiveProgram.mFeatures.hasTransport = true;
+ gDeferredEmissiveProgram.mFeatures.hasAtmospherics = true;
gDeferredEmissiveProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredEmissiveProgram.mShaderFiles.clear();
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveV.glsl", GL_VERTEX_SHADER));
+ gDeferredEmissiveProgram.mShaderFiles.push_back(make_pair("deferred/emissiveF.glsl", GL_FRAGMENT_SHADER));
gDeferredEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = make_rigged_variant(gDeferredEmissiveProgram, gDeferredSkinnedEmissiveProgram);
success = success && gDeferredEmissiveProgram.createShader(NULL, NULL);
@@ -2221,80 +2053,31 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- // load water shader
- gDeferredWaterProgram.mName = "Deferred Water Shader";
- gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWaterProgram.mFeatures.hasGamma = true;
- gDeferredWaterProgram.mFeatures.hasTransport = true;
- gDeferredWaterProgram.mFeatures.encodesNormal = true;
- gDeferredWaterProgram.mFeatures.hasSrgb = true;
-
- gDeferredWaterProgram.mShaderFiles.clear();
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gDeferredWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- // load water shader
- gDeferredUnderWaterProgram.mName = "Deferred Under Water Shader";
- gDeferredUnderWaterProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredUnderWaterProgram.mFeatures.hasWaterFog = true;
- gDeferredUnderWaterProgram.mFeatures.hasGamma = true;
- gDeferredUnderWaterProgram.mFeatures.hasTransport = true;
- gDeferredUnderWaterProgram.mFeatures.hasSrgb = true;
- gDeferredUnderWaterProgram.mFeatures.encodesNormal = true;
- //gDeferredUnderWaterProgram.mFeatures.hasShadows = true;
-
- gDeferredUnderWaterProgram.mShaderFiles.clear();
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/waterV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredUnderWaterProgram.mShaderFiles.push_back(make_pair("deferred/underWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredUnderWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredUnderWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gDeferredUnderWaterProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
gDeferredSoftenProgram.mName = "Deferred Soften Shader";
gDeferredSoftenProgram.mShaderFiles.clear();
gDeferredSoftenProgram.mFeatures.hasSrgb = true;
gDeferredSoftenProgram.mFeatures.calculatesAtmospherics = true;
gDeferredSoftenProgram.mFeatures.hasAtmospherics = true;
- gDeferredSoftenProgram.mFeatures.hasTransport = true;
gDeferredSoftenProgram.mFeatures.hasGamma = true;
gDeferredSoftenProgram.mFeatures.isDeferred = true;
gDeferredSoftenProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
gDeferredSoftenProgram.clearPermutations();
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (ambient_kill)
- {
- gDeferredSoftenProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
+ if (use_sun_shadow)
{
- gDeferredSoftenProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredSoftenProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ gDeferredSoftenProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenProgram.mShaderLevel = llmax(gDeferredSoftenProgram.mShaderLevel, 2);
+ gDeferredSoftenProgram.addPermutation("HAS_SSAO", "1");
}
success = gDeferredSoftenProgram.createShader(NULL, NULL);
@@ -2305,8 +2088,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredSoftenWaterProgram.mName = "Deferred Soften Underwater Shader";
gDeferredSoftenWaterProgram.mShaderFiles.clear();
- gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightV.glsl", GL_VERTEX_SHADER));
+ gDeferredSoftenWaterProgram.mShaderFiles.push_back(make_pair("deferred/softenLightF.glsl", GL_FRAGMENT_SHADER));
gDeferredSoftenWaterProgram.clearPermutations();
gDeferredSoftenWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
@@ -2316,29 +2099,20 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSoftenWaterProgram.mFeatures.hasSrgb = true;
gDeferredSoftenWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredSoftenWaterProgram.mFeatures.hasAtmospherics = true;
- gDeferredSoftenWaterProgram.mFeatures.hasTransport = true;
gDeferredSoftenWaterProgram.mFeatures.hasGamma = true;
gDeferredSoftenWaterProgram.mFeatures.isDeferred = true;
gDeferredSoftenWaterProgram.mFeatures.hasShadows = use_sun_shadow;
+ gDeferredSoftenWaterProgram.mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED] > 2;
- if (ambient_kill)
- {
- gDeferredSoftenWaterProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
+ if (use_sun_shadow)
{
- gDeferredSoftenWaterProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredSoftenWaterProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
{ //if using SSAO, take screen space light map into account as if shadows are enabled
gDeferredSoftenWaterProgram.mShaderLevel = llmax(gDeferredSoftenWaterProgram.mShaderLevel, 2);
+ gDeferredSoftenWaterProgram.addPermutation("HAS_SSAO", "1");
}
success = gDeferredSoftenWaterProgram.createShader(NULL, NULL);
@@ -2348,17 +2122,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredShadowProgram.mName = "Deferred Shadow Shader";
- gDeferredShadowProgram.mFeatures.isDeferred = true;
- gDeferredShadowProgram.mFeatures.hasShadows = true;
gDeferredShadowProgram.mShaderFiles.clear();
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
- gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
+ gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram;
success = gDeferredShadowProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2370,13 +2138,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredSkinnedShadowProgram.mFeatures.hasShadows = true;
gDeferredSkinnedShadowProgram.mFeatures.hasObjectSkinning = true;
gDeferredSkinnedShadowProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER));
+ gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now
success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2387,12 +2152,9 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowCubeProgram.mFeatures.isDeferred = true;
gDeferredShadowCubeProgram.mFeatures.hasShadows = true;
gDeferredShadowCubeProgram.mShaderFiles.clear();
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER));
+ // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredShadowCubeProgram.createShader(NULL, NULL);
llassert(success);
@@ -2404,73 +2166,56 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram;
- success = gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredShadowFullbrightAlphaMaskProgram, gDeferredSkinnedShadowFullbrightAlphaMaskProgram);
+ success = success && gDeferredShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
}
if (success)
- {
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mName = "Deferred Skinned Shadow Fullbright Alpha Mask Shader";
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
-
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations();
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1");
- gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
{
gDeferredShadowAlphaMaskProgram.mName = "Deferred Shadow Alpha Mask Shader";
gDeferredShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
gDeferredShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram;
- success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
+ success = make_rigged_variant(gDeferredShadowAlphaMaskProgram, gDeferredSkinnedShadowAlphaMaskProgram);
+ success = success && gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL);
llassert(success);
}
+
if (success)
{
- gDeferredSkinnedShadowAlphaMaskProgram.mName = "Deferred Skinned Shadow Alpha Mask Shader";
- gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels;
- gDeferredSkinnedShadowAlphaMaskProgram.mFeatures.hasObjectSkinning = true;
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear();
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1");
- }
- gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL);
+ gDeferredShadowGLTFAlphaMaskProgram.mName = "Deferred GLTF Shadow Alpha Mask Shader";
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.clear();
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowGLTFAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowGLTFAlphaMaskProgram.clearPermutations();
+ success = make_rigged_variant(gDeferredShadowGLTFAlphaMaskProgram, gDeferredSkinnedShadowGLTFAlphaMaskProgram);
+ success = success && gDeferredShadowGLTFAlphaMaskProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gDeferredShadowGLTFAlphaBlendProgram.mName = "Deferred GLTF Shadow Alpha Blend Shader";
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.clear();
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaMaskV.glsl", GL_VERTEX_SHADER));
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderFiles.push_back(make_pair("deferred/pbrShadowAlphaBlendF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredShadowGLTFAlphaBlendProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ gDeferredShadowGLTFAlphaBlendProgram.clearPermutations();
+ success = make_rigged_variant(gDeferredShadowGLTFAlphaBlendProgram, gDeferredSkinnedShadowGLTFAlphaBlendProgram);
+ success = success && gDeferredShadowGLTFAlphaBlendProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2480,12 +2225,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarShadowProgram.mShaderFiles.clear();
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2496,22 +2237,19 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaShadowProgram.mName = "Deferred Avatar Alpha Shadow Shader";
gDeferredAvatarAlphaShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL);
llassert(success);
}
-
if (success)
{
gDeferredAvatarAlphaMaskShadowProgram.mName = "Deferred Avatar Alpha Mask Shadow Shader";
gDeferredAvatarAlphaMaskShadowProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL);
llassert(success);
@@ -2519,49 +2257,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAttachmentShadowProgram.mName = "Deferred Attachment Shadow Shader";
- gDeferredAttachmentShadowProgram.mFeatures.hasObjectSkinning = true;
-
- gDeferredAttachmentShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- if (gGLManager.mHasDepthClamp)
- {
- gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1");
- }
- gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAttachmentAlphaShadowProgram.mName = "Deferred Attachment Alpha Shadow Shader";
- gDeferredAttachmentAlphaShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
- gDeferredAttachmentAlphaMaskShadowProgram.mName = "Deferred Attachment Alpha Mask Shadow Shader";
- gDeferredAttachmentAlphaMaskShadowProgram.mFeatures.hasObjectSkinning = true;
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear();
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0");
- gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
- success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL);
- llassert(success);
- }
-
- if (success)
- {
gDeferredTerrainProgram.mName = "Deferred Terrain Shader";
gDeferredTerrainProgram.mFeatures.encodesNormal = true;
gDeferredTerrainProgram.mFeatures.hasSrgb = true;
@@ -2573,11 +2268,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainProgram.mFeatures.calculatesAtmospherics = true;
gDeferredTerrainProgram.mFeatures.hasAtmospherics = true;
gDeferredTerrainProgram.mFeatures.hasGamma = true;
- gDeferredTerrainProgram.mFeatures.hasTransport = true;
gDeferredTerrainProgram.mShaderFiles.clear();
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredTerrainProgram.createShader(NULL, NULL);
llassert(success);
@@ -2596,13 +2290,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredTerrainWaterProgram.mFeatures.calculatesAtmospherics = true;
gDeferredTerrainWaterProgram.mFeatures.hasAtmospherics = true;
gDeferredTerrainWaterProgram.mFeatures.hasGamma = true;
- gDeferredTerrainWaterProgram.mFeatures.hasTransport = true;
-
+
gDeferredTerrainWaterProgram.mShaderFiles.clear();
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainV.glsl", GL_VERTEX_SHADER));
+ gDeferredTerrainWaterProgram.mShaderFiles.push_back(make_pair("deferred/terrainF.glsl", GL_FRAGMENT_SHADER));
gDeferredTerrainWaterProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredTerrainWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
+ gDeferredTerrainWaterProgram.clearPermutations();
gDeferredTerrainWaterProgram.addPermutation("WATER_FOG", "1");
success = gDeferredTerrainWaterProgram.createShader(NULL, NULL);
llassert(success);
@@ -2610,12 +2304,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAvatarProgram.mName = "Avatar Shader";
+ gDeferredAvatarProgram.mName = "Deferred Avatar Shader";
gDeferredAvatarProgram.mFeatures.hasSkinning = true;
gDeferredAvatarProgram.mFeatures.encodesNormal = true;
gDeferredAvatarProgram.mShaderFiles.clear();
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarProgram.mShaderFiles.push_back(make_pair("deferred/avatarF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarProgram.createShader(NULL, NULL);
llassert(success);
@@ -2623,7 +2317,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredAvatarAlphaProgram.mName = "Avatar Alpha Shader";
+ gDeferredAvatarAlphaProgram.mName = "Deferred Avatar Alpha Shader";
gDeferredAvatarAlphaProgram.mFeatures.hasSkinning = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesLighting = false;
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = false;
@@ -2633,37 +2327,23 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.encodesNormal = true;
gDeferredAvatarAlphaProgram.mFeatures.calculatesAtmospherics = true;
gDeferredAvatarAlphaProgram.mFeatures.hasAtmospherics = true;
- gDeferredAvatarAlphaProgram.mFeatures.hasTransport = true;
gDeferredAvatarAlphaProgram.mFeatures.hasGamma = true;
gDeferredAvatarAlphaProgram.mFeatures.isDeferred = true;
gDeferredAvatarAlphaProgram.mFeatures.hasShadows = true;
+ gDeferredAvatarAlphaProgram.mFeatures.hasReflectionProbes = true;
gDeferredAvatarAlphaProgram.mShaderFiles.clear();
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaV.glsl", GL_VERTEX_SHADER));
+ gDeferredAvatarAlphaProgram.mShaderFiles.push_back(make_pair("deferred/alphaF.glsl", GL_FRAGMENT_SHADER));
gDeferredAvatarAlphaProgram.clearPermutations();
gDeferredAvatarAlphaProgram.addPermutation("USE_DIFFUSE_TEX", "1");
gDeferredAvatarAlphaProgram.addPermutation("IS_AVATAR_SKIN", "1");
if (use_sun_shadow)
{
- gDeferredAvatarAlphaProgram.addPermutation("HAS_SHADOW", "1");
+ gDeferredAvatarAlphaProgram.addPermutation("HAS_SUN_SHADOW", "1");
}
- if (ambient_kill)
- {
- gDeferredAvatarAlphaProgram.addPermutation("AMBIENT_KILL", "1");
- }
-
- if (sunlight_kill)
- {
- gDeferredAvatarAlphaProgram.addPermutation("SUNLIGHT_KILL", "1");
- }
-
- if (local_light_kill)
- {
- gDeferredAvatarAlphaProgram.addPermutation("LOCAL_LIGHT_KILL", "1");
- }
gDeferredAvatarAlphaProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredAvatarAlphaProgram.createShader(NULL, NULL);
@@ -2673,26 +2353,84 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredAvatarAlphaProgram.mFeatures.hasLighting = true;
}
+ if (success)
+ {
+ gExposureProgram.mName = "Exposure";
+ gExposureProgram.mFeatures.hasSrgb = true;
+ gExposureProgram.mFeatures.isDeferred = true;
+ gExposureProgram.mShaderFiles.clear();
+ gExposureProgram.clearPermutations();
+ gExposureProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gExposureProgram.mShaderFiles.push_back(make_pair("deferred/exposureF.glsl", GL_FRAGMENT_SHADER));
+ gExposureProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gExposureProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+ if (success)
+ {
+ gLuminanceProgram.mName = "Luminance";
+ gLuminanceProgram.mShaderFiles.clear();
+ gLuminanceProgram.clearPermutations();
+ gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gLuminanceProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER));
+ gLuminanceProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gLuminanceProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
if (success)
{
gDeferredPostGammaCorrectProgram.mName = "Deferred Gamma Correction Post Process";
gDeferredPostGammaCorrectProgram.mFeatures.hasSrgb = true;
gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true;
gDeferredPostGammaCorrectProgram.mShaderFiles.clear();
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostGammaCorrectProgram.clearPermutations();
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL);
llassert(success);
}
+
+ if (success)
+ {
+ gNoPostGammaCorrectProgram.mName = "No Post Gamma Correction Post Process";
+ gNoPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gNoPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gNoPostGammaCorrectProgram.mShaderFiles.clear();
+ gNoPostGammaCorrectProgram.clearPermutations();
+ gNoPostGammaCorrectProgram.addPermutation("NO_POST", "1");
+ gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gNoPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gNoPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gNoPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
- if (success)
+ if (success)
+ {
+ gLegacyPostGammaCorrectProgram.mName = "Legacy Gamma Correction Post Process";
+ gLegacyPostGammaCorrectProgram.mFeatures.hasSrgb = true;
+ gLegacyPostGammaCorrectProgram.mFeatures.isDeferred = true;
+ gLegacyPostGammaCorrectProgram.mShaderFiles.clear();
+ gLegacyPostGammaCorrectProgram.clearPermutations();
+ gLegacyPostGammaCorrectProgram.addPermutation("LEGACY_GAMMA", "1");
+ gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gLegacyPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER));
+ gLegacyPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gLegacyPostGammaCorrectProgram.createShader(NULL, NULL);
+ llassert(success);
+ }
+
+
+ if (success && gGLManager.mGLVersion > 3.9f)
{
gFXAAProgram.mName = "FXAA Shader";
gFXAAProgram.mFeatures.isDeferred = true;
gFXAAProgram.mShaderFiles.clear();
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB));
- gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER));
+ gFXAAProgram.mShaderFiles.push_back(make_pair("deferred/fxaaF.glsl", GL_FRAGMENT_SHADER));
gFXAAProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gFXAAProgram.createShader(NULL, NULL);
llassert(success);
@@ -2701,10 +2439,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
gDeferredPostProgram.mName = "Deferred Post Shader";
- gFXAAProgram.mFeatures.isDeferred = true;
+ gDeferredPostProgram.mFeatures.isDeferred = true;
gDeferredPostProgram.mShaderFiles.clear();
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostProgram.createShader(NULL, NULL);
llassert(success);
@@ -2715,8 +2453,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredCoFProgram.mName = "Deferred CoF Shader";
gDeferredCoFProgram.mShaderFiles.clear();
gDeferredCoFProgram.mFeatures.isDeferred = true;
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredCoFProgram.mShaderFiles.push_back(make_pair("deferred/cofF.glsl", GL_FRAGMENT_SHADER));
gDeferredCoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredCoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2727,8 +2465,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredDoFCombineProgram.mName = "Deferred DoFCombine Shader";
gDeferredDoFCombineProgram.mFeatures.isDeferred = true;
gDeferredDoFCombineProgram.mShaderFiles.clear();
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredDoFCombineProgram.mShaderFiles.push_back(make_pair("deferred/dofCombineF.glsl", GL_FRAGMENT_SHADER));
gDeferredDoFCombineProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredDoFCombineProgram.createShader(NULL, NULL);
llassert(success);
@@ -2736,11 +2474,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
- gDeferredPostNoDoFProgram.mName = "Deferred Post Shader";
+ gDeferredPostNoDoFProgram.mName = "Deferred Post NoDoF Shader";
gDeferredPostNoDoFProgram.mFeatures.isDeferred = true;
gDeferredPostNoDoFProgram.mShaderFiles.clear();
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredPostNoDoFProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoDoFF.glsl", GL_FRAGMENT_SHADER));
gDeferredPostNoDoFProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
success = gDeferredPostNoDoFProgram.createShader(NULL, NULL);
llassert(success);
@@ -2751,12 +2489,12 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLSkyProgram.mName = "Deferred Windlight Sky Shader";
gDeferredWLSkyProgram.mShaderFiles.clear();
gDeferredWLSkyProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLSkyProgram.mFeatures.hasTransport = true;
+ gDeferredWLSkyProgram.mFeatures.hasAtmospherics = true;
gDeferredWLSkyProgram.mFeatures.hasGamma = true;
gDeferredWLSkyProgram.mFeatures.hasSrgb = true;
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSkyProgram.mShaderFiles.push_back(make_pair("deferred/skyF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
@@ -2769,14 +2507,15 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
gDeferredWLCloudProgram.mName = "Deferred Windlight Cloud Program";
gDeferredWLCloudProgram.mShaderFiles.clear();
gDeferredWLCloudProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLCloudProgram.mFeatures.hasTransport = true;
+ gDeferredWLCloudProgram.mFeatures.hasAtmospherics = true;
gDeferredWLCloudProgram.mFeatures.hasGamma = true;
gDeferredWLCloudProgram.mFeatures.hasSrgb = true;
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLCloudProgram.mShaderFiles.push_back(make_pair("deferred/cloudsF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLCloudProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gDeferredWLCloudProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2785,15 +2524,14 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredWLSunProgram.mName = "Deferred Windlight Sun Program";
gDeferredWLSunProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLSunProgram.mFeatures.hasTransport = true;
+ gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
gDeferredWLSunProgram.mFeatures.hasGamma = true;
gDeferredWLSunProgram.mFeatures.hasAtmospherics = true;
- gDeferredWLSunProgram.mFeatures.isFullbright = true;
gDeferredWLSunProgram.mFeatures.disableTextureIndex = true;
gDeferredWLSunProgram.mFeatures.hasSrgb = true;
gDeferredWLSunProgram.mShaderFiles.clear();
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLSunProgram.mShaderFiles.push_back(make_pair("deferred/sunDiscF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLSunProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gDeferredWLSunProgram.createShader(NULL, NULL);
@@ -2804,18 +2542,18 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredWLMoonProgram.mName = "Deferred Windlight Moon Program";
gDeferredWLMoonProgram.mFeatures.calculatesAtmospherics = true;
- gDeferredWLMoonProgram.mFeatures.hasTransport = true;
+ gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
gDeferredWLMoonProgram.mFeatures.hasGamma = true;
gDeferredWLMoonProgram.mFeatures.hasAtmospherics = true;
gDeferredWLMoonProgram.mFeatures.hasSrgb = true;
- gDeferredWLMoonProgram.mFeatures.isFullbright = true;
gDeferredWLMoonProgram.mFeatures.disableTextureIndex = true;
gDeferredWLMoonProgram.mShaderFiles.clear();
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonV.glsl", GL_VERTEX_SHADER));
+ gDeferredWLMoonProgram.mShaderFiles.push_back(make_pair("deferred/moonF.glsl", GL_FRAGMENT_SHADER));
gDeferredWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredWLMoonProgram.addConstant( LLGLSLShader::SHADER_CONST_CLOUD_MOON_DEPTH ); // SL-14113
success = gDeferredWLMoonProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2824,10 +2562,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gDeferredStarProgram.mName = "Deferred Star Program";
gDeferredStarProgram.mShaderFiles.clear();
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsV.glsl", GL_VERTEX_SHADER));
+ gDeferredStarProgram.mShaderFiles.push_back(make_pair("deferred/starsF.glsl", GL_FRAGMENT_SHADER));
gDeferredStarProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gDeferredStarProgram.mShaderGroup = LLGLSLShader::SG_SKY;
+ gDeferredStarProgram.addConstant( LLGLSLShader::SHADER_CONST_STAR_DEPTH ); // SL-14113
success = gDeferredStarProgram.createShader(NULL, NULL);
llassert(success);
}
@@ -2836,87 +2575,73 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
{
gNormalMapGenProgram.mName = "Normal Map Generation Program";
gNormalMapGenProgram.mShaderFiles.clear();
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER_ARB));
- gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenV.glsl", GL_VERTEX_SHADER));
+ gNormalMapGenProgram.mShaderFiles.push_back(make_pair("deferred/normgenF.glsl", GL_FRAGMENT_SHADER));
gNormalMapGenProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
gNormalMapGenProgram.mShaderGroup = LLGLSLShader::SG_SKY;
success = gNormalMapGenProgram.createShader(NULL, NULL);
}
+ if (success)
+ {
+ gDeferredGenBrdfLutProgram.mName = "Brdf Gen Shader";
+ gDeferredGenBrdfLutProgram.mShaderFiles.clear();
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutV.glsl", GL_VERTEX_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderFiles.push_back(make_pair("deferred/genbrdflutF.glsl", GL_FRAGMENT_SHADER));
+ gDeferredGenBrdfLutProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredGenBrdfLutProgram.createShader(NULL, NULL);
+ }
+
+ if (success) {
+ gPostScreenSpaceReflectionProgram.mName = "Screen Space Reflection Post";
+ gPostScreenSpaceReflectionProgram.mShaderFiles.clear();
+ gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostV.glsl", GL_VERTEX_SHADER));
+ gPostScreenSpaceReflectionProgram.mShaderFiles.push_back(make_pair("deferred/screenSpaceReflPostF.glsl", GL_FRAGMENT_SHADER));
+ gPostScreenSpaceReflectionProgram.mFeatures.hasScreenSpaceReflections = true;
+ gPostScreenSpaceReflectionProgram.mFeatures.isDeferred = true;
+ gPostScreenSpaceReflectionProgram.mShaderLevel = 3;
+ success = gPostScreenSpaceReflectionProgram.createShader(NULL, NULL);
+ }
+
+ if (success) {
+ gDeferredBufferVisualProgram.mName = "Deferred Buffer Visualization Shader";
+ gDeferredBufferVisualProgram.mShaderFiles.clear();
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER));
+ gDeferredBufferVisualProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredVisualizeBuffers.glsl", GL_FRAGMENT_SHADER));
+ gDeferredBufferVisualProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED];
+ success = gDeferredBufferVisualProgram.createShader(NULL, NULL);
+ }
+
return success;
}
BOOL LLViewerShaderMgr::loadShadersObject()
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
- if (success)
- {
- gObjectSimpleNonIndexedTexGenProgram.mName = "Non indexed tex-gen Shader";
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasGamma = true;
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.hasLighting = true;
- gObjectSimpleNonIndexedTexGenProgram.mFeatures.disableTextureIndex = true;
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectSimpleNonIndexedTexGenProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectSimpleNonIndexedTexGenWaterProgram.mName = "Non indexed tex-gen Water Shader";
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasWaterFog = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.hasLighting = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.clear();
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleTexGenV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectSimpleNonIndexedTexGenWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectSimpleNonIndexedTexGenWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectAlphaMaskNonIndexedProgram.mName = "Non indexed alpha mask Shader";
- gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesLighting = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.calculatesAtmospherics = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.hasGamma = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAtmospherics = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.hasLighting = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.disableTextureIndex = true;
- gObjectAlphaMaskNonIndexedProgram.mFeatures.hasAlphaMask = true;
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectAlphaMaskNonIndexedProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectAlphaMaskNonIndexedProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectAlphaMaskNonIndexedWaterProgram.mName = "Non indexed alpha mask Water Shader";
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesLighting = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasWaterFog = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasLighting = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mFeatures.hasAlphaMask = true;
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNonIndexedV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectAlphaMaskNonIndexedWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectAlphaMaskNonIndexedWaterProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ gObjectBumpProgram.mName = "Bump Shader";
+ gObjectBumpProgram.mFeatures.encodesNormal = true;
+ gObjectBumpProgram.mShaderFiles.clear();
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER));
+ gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER));
+ gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
+ success = success && gObjectBumpProgram.createShader(NULL, NULL);
+ if (success)
+ { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
+ LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
+ for (int i = 0; i < 2; ++i)
+ {
+ shader[i]->bind();
+ shader[i]->uniform1i(sTexture0, 0);
+ shader[i]->uniform1i(sTexture1, 1);
+ shader[i]->unbind();
+ }
+ }
+ }
if (success)
{
@@ -2929,8 +2654,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gObjectAlphaMaskNoColorProgram.createShader(NULL, NULL);
}
@@ -2946,8 +2671,8 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gObjectAlphaMaskNoColorWaterProgram.mFeatures.disableTextureIndex = true;
gObjectAlphaMaskNoColorWaterProgram.mFeatures.hasAlphaMask = true;
gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.clear();
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleNoColorV.glsl", GL_VERTEX_SHADER));
+ gObjectAlphaMaskNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER));
gObjectAlphaMaskNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
gObjectAlphaMaskNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
success = gObjectAlphaMaskNoColorWaterProgram.createShader(NULL, NULL);
@@ -2955,99 +2680,28 @@ BOOL LLViewerShaderMgr::loadShadersObject()
if (success)
{
- gTreeProgram.mName = "Tree Shader";
- gTreeProgram.mFeatures.calculatesLighting = true;
- gTreeProgram.mFeatures.calculatesAtmospherics = true;
- gTreeProgram.mFeatures.hasGamma = true;
- gTreeProgram.mFeatures.hasAtmospherics = true;
- gTreeProgram.mFeatures.hasLighting = true;
- gTreeProgram.mFeatures.disableTextureIndex = true;
- gTreeProgram.mFeatures.hasAlphaMask = true;
- gTreeProgram.mShaderFiles.clear();
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gTreeProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gTreeProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gTreeWaterProgram.mName = "Tree Water Shader";
- gTreeWaterProgram.mFeatures.calculatesLighting = true;
- gTreeWaterProgram.mFeatures.calculatesAtmospherics = true;
- gTreeWaterProgram.mFeatures.hasWaterFog = true;
- gTreeWaterProgram.mFeatures.hasAtmospherics = true;
- gTreeWaterProgram.mFeatures.hasLighting = true;
- gTreeWaterProgram.mFeatures.disableTextureIndex = true;
- gTreeWaterProgram.mFeatures.hasAlphaMask = true;
- gTreeWaterProgram.mShaderFiles.clear();
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/treeV.glsl", GL_VERTEX_SHADER_ARB));
- gTreeWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gTreeWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gTreeWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gTreeWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightNoColorProgram.mName = "Non Indexed no color Fullbright Shader";
- gObjectFullbrightNoColorProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightNoColorProgram.mFeatures.hasGamma = true;
- gObjectFullbrightNoColorProgram.mFeatures.hasTransport = true;
- gObjectFullbrightNoColorProgram.mFeatures.isFullbright = true;
- gObjectFullbrightNoColorProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightNoColorProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightNoColorProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNoColorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = gObjectFullbrightNoColorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightNoColorWaterProgram.mName = "Non Indexed no color Fullbright Water Shader";
- gObjectFullbrightNoColorWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightNoColorWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightNoColorWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightNoColorWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightNoColorWaterProgram.mFeatures.disableTextureIndex = true;
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.clear();
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightNoColorV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightNoColorWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightNoColorWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightNoColorWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gObjectFullbrightNoColorWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gImpostorProgram.mName = "Impostor Shader";
gImpostorProgram.mFeatures.disableTextureIndex = true;
gImpostorProgram.mFeatures.hasSrgb = true;
gImpostorProgram.mShaderFiles.clear();
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER_ARB));
- gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorV.glsl", GL_VERTEX_SHADER));
+ gImpostorProgram.mShaderFiles.push_back(make_pair("objects/impostorF.glsl", GL_FRAGMENT_SHADER));
gImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gImpostorProgram.createShader(NULL, NULL);
}
if (success)
{
- gObjectPreviewProgram.mName = "Simple Shader";
- gObjectPreviewProgram.mFeatures.calculatesLighting = false;
- gObjectPreviewProgram.mFeatures.calculatesAtmospherics = false;
- gObjectPreviewProgram.mFeatures.hasGamma = false;
- gObjectPreviewProgram.mFeatures.hasAtmospherics = false;
- gObjectPreviewProgram.mFeatures.hasLighting = false;
- gObjectPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
+ gObjectPreviewProgram.mName = "Object Preview Shader";
gObjectPreviewProgram.mFeatures.disableTextureIndex = true;
gObjectPreviewProgram.mShaderFiles.clear();
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewV.glsl", GL_VERTEX_SHADER));
+ gObjectPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewF.glsl", GL_FRAGMENT_SHADER));
gObjectPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
+ success = make_rigged_variant(gObjectPreviewProgram, gSkinnedObjectPreviewProgram);
success = gObjectPreviewProgram.createShader(NULL, NULL);
gObjectPreviewProgram.mFeatures.hasLighting = true;
+ gSkinnedObjectPreviewProgram.mFeatures.hasLighting = true;
}
if (success)
@@ -3061,324 +2715,32 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gPhysicsPreviewProgram.mFeatures.mIndexedTextureChannels = 0;
gPhysicsPreviewProgram.mFeatures.disableTextureIndex = true;
gPhysicsPreviewProgram.mShaderFiles.clear();
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER_ARB));
- gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsV.glsl", GL_VERTEX_SHADER));
+ gPhysicsPreviewProgram.mShaderFiles.push_back(make_pair("objects/previewPhysicsF.glsl", GL_FRAGMENT_SHADER));
gPhysicsPreviewProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
success = gPhysicsPreviewProgram.createShader(NULL, NULL);
gPhysicsPreviewProgram.mFeatures.hasLighting = false;
}
- if (success)
- {
- gObjectSimpleProgram.mName = "Simple Shader";
- gObjectSimpleProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasGamma = true;
- gObjectSimpleProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleProgram.mFeatures.hasLighting = true;
- gObjectSimpleProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleProgram.mShaderFiles.clear();
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectSimpleProgram, gSkinnedObjectSimpleProgram);
- success = success && gObjectSimpleProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectSimpleImpostorProgram.mName = "Simple Impostor Shader";
- gObjectSimpleImpostorProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleImpostorProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleImpostorProgram.mFeatures.hasGamma = true;
- gObjectSimpleImpostorProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleImpostorProgram.mFeatures.hasLighting = true;
- gObjectSimpleImpostorProgram.mFeatures.mIndexedTextureChannels = 0;
- // force alpha mask version of lighting so we can weed out
- // transparent pixels from impostor temp buffer
- //
- gObjectSimpleImpostorProgram.mFeatures.hasAlphaMask = true;
- gObjectSimpleImpostorProgram.mShaderFiles.clear();
- gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleImpostorProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleImpostorProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectSimpleImpostorProgram, gSkinnedObjectSimpleImpostorProgram);
- success = success && gObjectSimpleImpostorProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectSimpleWaterProgram.mName = "Simple Water Shader";
- gObjectSimpleWaterProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleWaterProgram.mFeatures.hasWaterFog = true;
- gObjectSimpleWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleWaterProgram.mFeatures.hasLighting = true;
- gObjectSimpleWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleWaterProgram.mShaderFiles.clear();
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- make_rigged_variant(gObjectSimpleWaterProgram, gSkinnedObjectSimpleWaterProgram);
- success = gObjectSimpleWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectBumpProgram.mName = "Bump Shader";
- gObjectBumpProgram.mFeatures.encodesNormal = true;
- gObjectBumpProgram.mShaderFiles.clear();
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectBumpProgram.mShaderFiles.push_back(make_pair("objects/bumpF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectBumpProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectBumpProgram, gSkinnedObjectBumpProgram);
- success = success && gObjectBumpProgram.createShader(NULL, NULL);
- if (success)
- { //lldrawpoolbump assumes "texture0" has channel 0 and "texture1" has channel 1
- LLGLSLShader* shader[] = { &gObjectBumpProgram, &gSkinnedObjectBumpProgram };
- for (int i = 0; i < 2; ++i)
- {
- shader[i]->bind();
- shader[i]->uniform1i(sTexture0, 0);
- shader[i]->uniform1i(sTexture1, 1);
- shader[i]->unbind();
- }
- }
- }
-
-
- if (success)
- {
- gObjectSimpleAlphaMaskProgram.mName = "Simple Alpha Mask Shader";
- gObjectSimpleAlphaMaskProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.hasGamma = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.hasLighting = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.hasAlphaMask = true;
- gObjectSimpleAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectSimpleAlphaMaskProgram, gSkinnedObjectSimpleAlphaMaskProgram);
- success = success && gObjectSimpleAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectSimpleWaterAlphaMaskProgram.mName = "Simple Water Alpha Mask Shader";
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesLighting = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAtmospherics = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasLighting = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
- gObjectSimpleWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectSimpleWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectSimpleWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectSimpleWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectSimpleWaterAlphaMaskProgram, gSkinnedObjectSimpleWaterAlphaMaskProgram);
- success = success && gObjectSimpleWaterAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightProgram.mName = "Fullbright Shader";
- gObjectFullbrightProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightProgram.mFeatures.hasGamma = true;
- gObjectFullbrightProgram.mFeatures.hasTransport = true;
- gObjectFullbrightProgram.mFeatures.isFullbright = true;
- gObjectFullbrightProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightProgram.mShaderFiles.clear();
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectFullbrightProgram, gSkinnedObjectFullbrightProgram);
- success = success && gObjectFullbrightProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightWaterProgram.mName = "Fullbright Water Shader";
- gObjectFullbrightWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightWaterProgram.mShaderFiles.clear();
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectFullbrightWaterProgram, gSkinnedObjectFullbrightWaterProgram);
- success = success && gObjectFullbrightWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectEmissiveProgram.mName = "Emissive Shader";
- gObjectEmissiveProgram.mFeatures.calculatesAtmospherics = true;
- gObjectEmissiveProgram.mFeatures.hasGamma = true;
- gObjectEmissiveProgram.mFeatures.hasTransport = true;
- gObjectEmissiveProgram.mFeatures.isFullbright = true;
- gObjectEmissiveProgram.mFeatures.hasSrgb = true;
- gObjectEmissiveProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectEmissiveProgram.mShaderFiles.clear();
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectEmissiveProgram, gSkinnedObjectEmissiveProgram);
- success = success && gObjectEmissiveProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectEmissiveWaterProgram.mName = "Emissive Water Shader";
- gObjectEmissiveWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectEmissiveWaterProgram.mFeatures.isFullbright = true;
- gObjectEmissiveWaterProgram.mFeatures.hasWaterFog = true;
- gObjectEmissiveWaterProgram.mFeatures.hasTransport = true;
- gObjectEmissiveWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectEmissiveWaterProgram.mShaderFiles.clear();
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/emissiveV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectEmissiveWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectEmissiveWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectEmissiveWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectEmissiveWaterProgram, gSkinnedObjectEmissiveWaterProgram);
- success = success && gObjectEmissiveWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightAlphaMaskProgram.mName = "Fullbright Alpha Mask Shader";
- gObjectFullbrightAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.hasGamma = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.hasTransport = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.isFullbright = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.hasAlphaMask = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.hasSrgb = true;
- gObjectFullbrightAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectFullbrightAlphaMaskProgram, gSkinnedObjectFullbrightAlphaMaskProgram);
- success = success && gObjectFullbrightAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightWaterAlphaMaskProgram.mName = "Fullbright Water Alpha Mask Shader";
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.isFullbright = true;
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasTransport = true;
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.hasAlphaMask = true;
- gObjectFullbrightWaterAlphaMaskProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.clear();
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightWaterAlphaMaskProgram.mShaderFiles.push_back(make_pair("objects/fullbrightWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightWaterAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightWaterAlphaMaskProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectFullbrightWaterAlphaMaskProgram, gSkinnedObjectFullbrightWaterAlphaMaskProgram);
- success = success && gObjectFullbrightWaterAlphaMaskProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectShinyProgram.mName = "Shiny Shader";
- gObjectShinyProgram.mFeatures.calculatesAtmospherics = true;
- gObjectShinyProgram.mFeatures.calculatesLighting = true;
- gObjectShinyProgram.mFeatures.hasGamma = true;
- gObjectShinyProgram.mFeatures.hasAtmospherics = true;
- gObjectShinyProgram.mFeatures.isShiny = true;
- gObjectShinyProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectShinyProgram.mShaderFiles.clear();
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyProgram.mShaderFiles.push_back(make_pair("objects/shinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectShinyProgram, gSkinnedObjectShinyProgram);
- success = success && gObjectShinyProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectShinyWaterProgram.mName = "Shiny Water Shader";
- gObjectShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectShinyWaterProgram.mFeatures.calculatesLighting = true;
- gObjectShinyWaterProgram.mFeatures.isShiny = true;
- gObjectShinyWaterProgram.mFeatures.hasWaterFog = true;
- gObjectShinyWaterProgram.mFeatures.hasAtmospherics = true;
- gObjectShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectShinyWaterProgram.mShaderFiles.clear();
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/shinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectShinyWaterProgram, gSkinnedObjectShinyWaterProgram);
- success = success && gObjectShinyWaterProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightShinyProgram.mName = "Fullbright Shiny Shader";
- gObjectFullbrightShinyProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightShinyProgram.mShaderFiles.clear();
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- success = make_rigged_variant(gObjectFullbrightShinyProgram, gSkinnedObjectFullbrightShinyProgram);
- success = success && gObjectFullbrightShinyProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gObjectFullbrightShinyWaterProgram.mName = "Fullbright Shiny Water Shader";
- gObjectFullbrightShinyWaterProgram.mFeatures.calculatesAtmospherics = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isFullbright = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.isShiny = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasGamma = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasTransport = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.hasWaterFog = true;
- gObjectFullbrightShinyWaterProgram.mFeatures.mIndexedTextureChannels = 0;
- gObjectFullbrightShinyWaterProgram.mShaderFiles.clear();
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyV.glsl", GL_VERTEX_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderFiles.push_back(make_pair("objects/fullbrightShinyWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- gObjectFullbrightShinyWaterProgram.mShaderLevel = mShaderLevel[SHADER_OBJECT];
- gObjectFullbrightShinyWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = make_rigged_variant(gObjectFullbrightShinyWaterProgram, gSkinnedObjectFullbrightShinyWaterProgram);
- success = success && gObjectFullbrightShinyWaterProgram.createShader(NULL, NULL);
- }
+ if (!success)
+ {
+ mShaderLevel[SHADER_OBJECT] = 0;
+ return FALSE;
+ }
- if( !success )
- {
- mShaderLevel[SHADER_OBJECT] = 0;
- return FALSE;
- }
-
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersAvatar()
{
+ LL_PROFILE_ZONE_SCOPED;
+#if 1 // DEPRECATED -- forward rendering is deprecated
BOOL success = TRUE;
if (mShaderLevel[SHADER_AVATAR] == 0)
{
gAvatarProgram.unload();
- gAvatarWaterProgram.unload();
gAvatarEyeballProgram.unload();
- gAvatarPickProgram.unload();
return TRUE;
}
@@ -3394,31 +2756,11 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarProgram.mFeatures.hasAlphaMask = true;
gAvatarProgram.mFeatures.disableTextureIndex = true;
gAvatarProgram.mShaderFiles.clear();
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER));
+ gAvatarProgram.mShaderFiles.push_back(make_pair("avatar/avatarF.glsl", GL_FRAGMENT_SHADER));
gAvatarProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarProgram.createShader(NULL, NULL);
- if (success)
- {
- gAvatarWaterProgram.mName = "Avatar Water Shader";
- gAvatarWaterProgram.mFeatures.hasSkinning = true;
- gAvatarWaterProgram.mFeatures.calculatesAtmospherics = true;
- gAvatarWaterProgram.mFeatures.calculatesLighting = true;
- gAvatarWaterProgram.mFeatures.hasWaterFog = true;
- gAvatarWaterProgram.mFeatures.hasAtmospherics = true;
- gAvatarWaterProgram.mFeatures.hasLighting = true;
- gAvatarWaterProgram.mFeatures.hasAlphaMask = true;
- gAvatarWaterProgram.mFeatures.disableTextureIndex = true;
- gAvatarWaterProgram.mShaderFiles.clear();
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("avatar/avatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
- // Note: no cloth under water:
- gAvatarWaterProgram.mShaderLevel = llmin(mShaderLevel[SHADER_AVATAR], 1);
- gAvatarWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
- success = gAvatarWaterProgram.createShader(NULL, NULL);
- }
-
/// Keep track of avatar levels
if (gAvatarProgram.mShaderLevel != mShaderLevel[SHADER_AVATAR])
{
@@ -3428,18 +2770,6 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
if (success)
{
- gAvatarPickProgram.mName = "Avatar Pick Shader";
- gAvatarPickProgram.mFeatures.hasSkinning = true;
- gAvatarPickProgram.mFeatures.disableTextureIndex = true;
- gAvatarPickProgram.mShaderFiles.clear();
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarPickProgram.mShaderFiles.push_back(make_pair("avatar/pickAvatarF.glsl", GL_FRAGMENT_SHADER_ARB));
- gAvatarPickProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
- success = gAvatarPickProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gAvatarEyeballProgram.mName = "Avatar Eyeball Program";
gAvatarEyeballProgram.mFeatures.calculatesLighting = true;
gAvatarEyeballProgram.mFeatures.isSpecular = true;
@@ -3450,8 +2780,8 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
gAvatarEyeballProgram.mFeatures.hasAlphaMask = true;
gAvatarEyeballProgram.mFeatures.disableTextureIndex = true;
gAvatarEyeballProgram.mShaderFiles.clear();
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER_ARB));
- gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballV.glsl", GL_VERTEX_SHADER));
+ gAvatarEyeballProgram.mShaderFiles.push_back(make_pair("avatar/eyeballF.glsl", GL_FRAGMENT_SHADER));
gAvatarEyeballProgram.mShaderLevel = mShaderLevel[SHADER_AVATAR];
success = gAvatarEyeballProgram.createShader(NULL, NULL);
}
@@ -3462,20 +2792,21 @@ BOOL LLViewerShaderMgr::loadShadersAvatar()
mMaxAvatarShaderLevel = 0;
return FALSE;
}
-
+#endif
return TRUE;
}
BOOL LLViewerShaderMgr::loadShadersInterface()
{
+ LL_PROFILE_ZONE_SCOPED;
BOOL success = TRUE;
if (success)
{
gHighlightProgram.mName = "Highlight Shader";
gHighlightProgram.mShaderFiles.clear();
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightV.glsl", GL_VERTEX_SHADER));
+ gHighlightProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gHighlightProgram, gSkinnedHighlightProgram);
success = success && gHighlightProgram.createShader(NULL, NULL);
@@ -3485,8 +2816,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightNormalProgram.mName = "Highlight Normals Shader";
gHighlightNormalProgram.mShaderFiles.clear();
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightNormV.glsl", GL_VERTEX_SHADER));
+ gHighlightNormalProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightNormalProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightNormalProgram.createShader(NULL, NULL);
}
@@ -3495,8 +2826,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gHighlightSpecularProgram.mName = "Highlight Spec Shader";
gHighlightSpecularProgram.mShaderFiles.clear();
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER_ARB));
- gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightSpecV.glsl", GL_VERTEX_SHADER));
+ gHighlightSpecularProgram.mShaderFiles.push_back(make_pair("interface/highlightF.glsl", GL_FRAGMENT_SHADER));
gHighlightSpecularProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gHighlightSpecularProgram.createShader(NULL, NULL);
}
@@ -3505,8 +2836,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gUIProgram.mName = "UI Shader";
gUIProgram.mShaderFiles.clear();
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER_ARB));
- gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiV.glsl", GL_VERTEX_SHADER));
+ gUIProgram.mShaderFiles.push_back(make_pair("interface/uiF.glsl", GL_FRAGMENT_SHADER));
gUIProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gUIProgram.createShader(NULL, NULL);
}
@@ -3515,8 +2846,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingProgram.mName = "Pathfinding Shader";
gPathfindingProgram.mShaderFiles.clear();
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingV.glsl", GL_VERTEX_SHADER));
+ gPathfindingProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingProgram.createShader(NULL, NULL);
}
@@ -3525,44 +2856,18 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gPathfindingNoNormalsProgram.mName = "PathfindingNoNormals Shader";
gPathfindingNoNormalsProgram.mShaderFiles.clear();
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER_ARB));
- gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingNoNormalV.glsl", GL_VERTEX_SHADER));
+ gPathfindingNoNormalsProgram.mShaderFiles.push_back(make_pair("interface/pathfindingF.glsl", GL_FRAGMENT_SHADER));
gPathfindingNoNormalsProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gPathfindingNoNormalsProgram.createShader(NULL, NULL);
}
if (success)
{
- gCustomAlphaProgram.mName = "Custom Alpha Shader";
- gCustomAlphaProgram.mShaderFiles.clear();
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaV.glsl", GL_VERTEX_SHADER_ARB));
- gCustomAlphaProgram.mShaderFiles.push_back(make_pair("interface/customalphaF.glsl", GL_FRAGMENT_SHADER_ARB));
- gCustomAlphaProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gCustomAlphaProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
- gSplatTextureRectProgram.mName = "Splat Texture Rect Shader";
- gSplatTextureRectProgram.mShaderFiles.clear();
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER_ARB));
- gSplatTextureRectProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectF.glsl", GL_FRAGMENT_SHADER_ARB));
- gSplatTextureRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gSplatTextureRectProgram.createShader(NULL, NULL);
- if (success)
- {
- gSplatTextureRectProgram.bind();
- gSplatTextureRectProgram.uniform1i(sScreenMap, 0);
- gSplatTextureRectProgram.unbind();
- }
- }
-
- if (success)
- {
gGlowCombineProgram.mName = "Glow Combine Shader";
gGlowCombineProgram.mShaderFiles.clear();
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineProgram.mShaderFiles.push_back(make_pair("interface/glowcombineF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineProgram.createShader(NULL, NULL);
if (success)
@@ -3578,8 +2883,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gGlowCombineFXAAProgram.mName = "Glow CombineFXAA Shader";
gGlowCombineFXAAProgram.mShaderFiles.clear();
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER_ARB));
- gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAV.glsl", GL_VERTEX_SHADER));
+ gGlowCombineFXAAProgram.mShaderFiles.push_back(make_pair("interface/glowcombineFXAAF.glsl", GL_FRAGMENT_SHADER));
gGlowCombineFXAAProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gGlowCombineFXAAProgram.createShader(NULL, NULL);
if (success)
@@ -3591,30 +2896,13 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
}
}
-
- if (success)
- {
- gTwoTextureAddProgram.mName = "Two Texture Add Shader";
- gTwoTextureAddProgram.mShaderFiles.clear();
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureAddProgram.mShaderFiles.push_back(make_pair("interface/twotextureaddF.glsl", GL_FRAGMENT_SHADER_ARB));
- gTwoTextureAddProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gTwoTextureAddProgram.createShader(NULL, NULL);
- if (success)
- {
- gTwoTextureAddProgram.bind();
- gTwoTextureAddProgram.uniform1i(sTex0, 0);
- gTwoTextureAddProgram.uniform1i(sTex1, 1);
- }
- }
-
#ifdef LL_WINDOWS
if (success)
{
gTwoTextureCompareProgram.mName = "Two Texture Compare Shader";
gTwoTextureCompareProgram.mShaderFiles.clear();
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER_ARB));
- gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareV.glsl", GL_VERTEX_SHADER));
+ gTwoTextureCompareProgram.mShaderFiles.push_back(make_pair("interface/twotexturecompareF.glsl", GL_FRAGMENT_SHADER));
gTwoTextureCompareProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gTwoTextureCompareProgram.createShader(NULL, NULL);
if (success)
@@ -3630,8 +2918,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOneTextureFilterProgram.mName = "One Texture Filter Shader";
gOneTextureFilterProgram.mShaderFiles.clear();
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterV.glsl", GL_VERTEX_SHADER));
+ gOneTextureFilterProgram.mShaderFiles.push_back(make_pair("interface/onetexturefilterF.glsl", GL_FRAGMENT_SHADER));
gOneTextureFilterProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOneTextureFilterProgram.createShader(NULL, NULL);
if (success)
@@ -3644,25 +2932,10 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
if (success)
{
- gOneTextureNoColorProgram.mName = "One Texture No Color Shader";
- gOneTextureNoColorProgram.mShaderFiles.clear();
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
- gOneTextureNoColorProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorF.glsl", GL_FRAGMENT_SHADER_ARB));
- gOneTextureNoColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gOneTextureNoColorProgram.createShader(NULL, NULL);
- if (success)
- {
- gOneTextureNoColorProgram.bind();
- gOneTextureNoColorProgram.uniform1i(sTex0, 0);
- }
- }
-
- if (success)
- {
gSolidColorProgram.mName = "Solid Color Shader";
gSolidColorProgram.mShaderFiles.clear();
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER_ARB));
- gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorV.glsl", GL_VERTEX_SHADER));
+ gSolidColorProgram.mShaderFiles.push_back(make_pair("interface/solidcolorF.glsl", GL_FRAGMENT_SHADER));
gSolidColorProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSolidColorProgram.createShader(NULL, NULL);
if (success)
@@ -3677,8 +2950,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionProgram.mName = "Occlusion Shader";
gOcclusionProgram.mShaderFiles.clear();
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionV.glsl", GL_VERTEX_SHADER));
+ gOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
gOcclusionProgram.mRiggedVariant = &gSkinnedOcclusionProgram;
success = gOcclusionProgram.createShader(NULL, NULL);
@@ -3689,8 +2962,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
gSkinnedOcclusionProgram.mName = "Skinned Occlusion Shader";
gSkinnedOcclusionProgram.mFeatures.hasObjectSkinning = true;
gSkinnedOcclusionProgram.mShaderFiles.clear();
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
- gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionSkinnedV.glsl", GL_VERTEX_SHADER));
+ gSkinnedOcclusionProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gSkinnedOcclusionProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gSkinnedOcclusionProgram.createShader(NULL, NULL);
}
@@ -3699,8 +2972,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gOcclusionCubeProgram.mName = "Occlusion Cube Shader";
gOcclusionCubeProgram.mShaderFiles.clear();
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER_ARB));
- gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionCubeV.glsl", GL_VERTEX_SHADER));
+ gOcclusionCubeProgram.mShaderFiles.push_back(make_pair("interface/occlusionF.glsl", GL_FRAGMENT_SHADER));
gOcclusionCubeProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gOcclusionCubeProgram.createShader(NULL, NULL);
}
@@ -3709,8 +2982,8 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gDebugProgram.mName = "Debug Shader";
gDebugProgram.mShaderFiles.clear();
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER_ARB));
- gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugV.glsl", GL_VERTEX_SHADER));
+ gDebugProgram.mShaderFiles.push_back(make_pair("interface/debugF.glsl", GL_FRAGMENT_SHADER));
gDebugProgram.mRiggedVariant = &gSkinnedDebugProgram;
gDebugProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = make_rigged_variant(gDebugProgram, gSkinnedDebugProgram);
@@ -3721,232 +2994,128 @@ BOOL LLViewerShaderMgr::loadShadersInterface()
{
gClipProgram.mName = "Clip Shader";
gClipProgram.mShaderFiles.clear();
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER_ARB));
- gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipV.glsl", GL_VERTEX_SHADER));
+ gClipProgram.mShaderFiles.push_back(make_pair("interface/clipF.glsl", GL_FRAGMENT_SHADER));
gClipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gClipProgram.createShader(NULL, NULL);
}
if (success)
{
- gDownsampleDepthProgram.mName = "DownsampleDepth Shader";
- gDownsampleDepthProgram.mShaderFiles.clear();
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDownsampleDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDownsampleDepthProgram.createShader(NULL, NULL);
- }
-
- if (success)
- {
gBenchmarkProgram.mName = "Benchmark Shader";
gBenchmarkProgram.mShaderFiles.clear();
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER_ARB));
- gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkV.glsl", GL_VERTEX_SHADER));
+ gBenchmarkProgram.mShaderFiles.push_back(make_pair("interface/benchmarkF.glsl", GL_FRAGMENT_SHADER));
gBenchmarkProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gBenchmarkProgram.createShader(NULL, NULL);
}
- if (success)
- {
- gDownsampleDepthRectProgram.mName = "DownsampleDepthRect Shader";
- gDownsampleDepthRectProgram.mShaderFiles.clear();
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthV.glsl", GL_VERTEX_SHADER_ARB));
- gDownsampleDepthRectProgram.mShaderFiles.push_back(make_pair("interface/downsampleDepthRectF.glsl", GL_FRAGMENT_SHADER_ARB));
- gDownsampleDepthRectProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
- success = gDownsampleDepthRectProgram.createShader(NULL, NULL);
- }
+ if (success)
+ {
+ gReflectionProbeDisplayProgram.mName = "Reflection Probe Display Shader";
+ gReflectionProbeDisplayProgram.mFeatures.hasReflectionProbes = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasSrgb = true;
+ gReflectionProbeDisplayProgram.mFeatures.calculatesAtmospherics = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasAtmospherics = true;
+ gReflectionProbeDisplayProgram.mFeatures.hasGamma = true;
+ gReflectionProbeDisplayProgram.mFeatures.isDeferred = true;
+ gReflectionProbeDisplayProgram.mShaderFiles.clear();
+ gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeV.glsl", GL_VERTEX_SHADER));
+ gReflectionProbeDisplayProgram.mShaderFiles.push_back(make_pair("interface/reflectionprobeF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionProbeDisplayProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionProbeDisplayProgram.createShader(NULL, NULL);
+ }
+
+ if (success)
+ {
+ gCopyProgram.mName = "Copy Shader";
+ gCopyProgram.mShaderFiles.clear();
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyProgram.createShader(NULL, NULL);
+ }
+ if (success)
+ {
+ gCopyDepthProgram.mName = "Copy Depth Shader";
+ gCopyDepthProgram.mShaderFiles.clear();
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyV.glsl", GL_VERTEX_SHADER));
+ gCopyDepthProgram.mShaderFiles.push_back(make_pair("interface/copyF.glsl", GL_FRAGMENT_SHADER));
+ gCopyDepthProgram.clearPermutations();
+ gCopyDepthProgram.addPermutation("COPY_DEPTH", "1");
+ gCopyDepthProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gCopyDepthProgram.createShader(NULL, NULL);
+ }
+
if (success)
{
gAlphaMaskProgram.mName = "Alpha Mask Shader";
gAlphaMaskProgram.mShaderFiles.clear();
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER_ARB));
- gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskV.glsl", GL_VERTEX_SHADER));
+ gAlphaMaskProgram.mShaderFiles.push_back(make_pair("interface/alphamaskF.glsl", GL_FRAGMENT_SHADER));
gAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
success = gAlphaMaskProgram.createShader(NULL, NULL);
}
- if( !success )
- {
- mShaderLevel[SHADER_INTERFACE] = 0;
- return FALSE;
- }
-
- return TRUE;
-}
-
-BOOL LLViewerShaderMgr::loadShadersWindLight()
-{
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_WINDLIGHT] < 2)
- {
- gWLSkyProgram.unload();
- gWLCloudProgram.unload();
- gWLSunProgram.unload();
- gWLMoonProgram.unload();
- return TRUE;
- }
-
if (success)
{
- gWLSkyProgram.mName = "Windlight Sky Shader";
- gWLSkyProgram.mShaderFiles.clear();
- gWLSkyProgram.mFeatures.calculatesAtmospherics = true;
- gWLSkyProgram.mFeatures.hasTransport = true;
- gWLSkyProgram.mFeatures.hasGamma = true;
- gWLSkyProgram.mFeatures.hasSrgb = true;
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSkyProgram.mShaderFiles.push_back(make_pair("windlight/skyF.glsl", GL_FRAGMENT_SHADER_ARB));
- gWLSkyProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
- gWLSkyProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLSkyProgram.createShader(NULL, NULL);
+ gReflectionMipProgram.mName = "Reflection Mip Shader";
+ gReflectionMipProgram.mFeatures.isDeferred = true;
+ gReflectionMipProgram.mFeatures.hasGamma = true;
+ gReflectionMipProgram.mFeatures.hasAtmospherics = true;
+ gReflectionMipProgram.mFeatures.calculatesAtmospherics = true;
+ gReflectionMipProgram.mShaderFiles.clear();
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gReflectionMipProgram.mShaderFiles.push_back(make_pair("interface/reflectionmipF.glsl", GL_FRAGMENT_SHADER));
+ gReflectionMipProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gReflectionMipProgram.createShader(NULL, NULL);
}
if (success)
{
- gWLCloudProgram.mName = "Windlight Cloud Program";
- gWLCloudProgram.mShaderFiles.clear();
- gWLCloudProgram.mFeatures.calculatesAtmospherics = true;
- gWLCloudProgram.mFeatures.hasTransport = true;
- gWLCloudProgram.mFeatures.hasGamma = true;
- gWLCloudProgram.mFeatures.hasSrgb = true;
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsV.glsl", GL_VERTEX_SHADER_ARB));
- gWLCloudProgram.mShaderFiles.push_back(make_pair("windlight/cloudsF.glsl", GL_FRAGMENT_SHADER_ARB));
- gWLCloudProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
- gWLCloudProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLCloudProgram.createShader(NULL, NULL);
+ gGaussianProgram.mName = "Reflection Mip Shader";
+ gGaussianProgram.mFeatures.isDeferred = true;
+ gGaussianProgram.mFeatures.hasGamma = true;
+ gGaussianProgram.mFeatures.hasAtmospherics = true;
+ gGaussianProgram.mFeatures.calculatesAtmospherics = true;
+ gGaussianProgram.mShaderFiles.clear();
+ gGaussianProgram.mShaderFiles.push_back(make_pair("interface/splattexturerectV.glsl", GL_VERTEX_SHADER));
+ gGaussianProgram.mShaderFiles.push_back(make_pair("interface/gaussianF.glsl", GL_FRAGMENT_SHADER));
+ gGaussianProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gGaussianProgram.createShader(NULL, NULL);
}
- if (success)
+ if (success && gGLManager.mHasCubeMapArray)
{
- gWLSunProgram.mName = "Windlight Sun Program";
- gWLSunProgram.mShaderFiles.clear();
- gWLSunProgram.mFeatures.calculatesAtmospherics = true;
- gWLSunProgram.mFeatures.hasTransport = true;
- gWLSunProgram.mFeatures.hasGamma = true;
- gWLSunProgram.mFeatures.hasAtmospherics = true;
- gWLSunProgram.mFeatures.isFullbright = true;
- gWLSunProgram.mFeatures.disableTextureIndex = true;
- gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscV.glsl", GL_VERTEX_SHADER_ARB));
- gWLSunProgram.mShaderFiles.push_back(make_pair("windlight/sunDiscF.glsl", GL_FRAGMENT_SHADER_ARB));
- gWLSunProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
- gWLSunProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLSunProgram.createShader(NULL, NULL);
+ gRadianceGenProgram.mName = "Radiance Gen Shader";
+ gRadianceGenProgram.mShaderFiles.clear();
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenV.glsl", GL_VERTEX_SHADER));
+ gRadianceGenProgram.mShaderFiles.push_back(make_pair("interface/radianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gRadianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gRadianceGenProgram.createShader(NULL, NULL);
}
- if (success)
+ if (success && gGLManager.mHasCubeMapArray)
{
- gWLMoonProgram.mName = "Windlight Moon Program";
- gWLMoonProgram.mShaderFiles.clear();
- gWLMoonProgram.mFeatures.calculatesAtmospherics = true;
- gWLMoonProgram.mFeatures.hasTransport = true;
- gWLMoonProgram.mFeatures.hasGamma = true;
- gWLMoonProgram.mFeatures.hasAtmospherics = true;
- gWLMoonProgram.mFeatures.isFullbright = true;
- gWLMoonProgram.mFeatures.disableTextureIndex = true;
- gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonV.glsl", GL_VERTEX_SHADER_ARB));
- gWLMoonProgram.mShaderFiles.push_back(make_pair("windlight/moonF.glsl", GL_FRAGMENT_SHADER_ARB));
- gWLMoonProgram.mShaderLevel = mShaderLevel[SHADER_WINDLIGHT];
- gWLMoonProgram.mShaderGroup = LLGLSLShader::SG_SKY;
- success = gWLMoonProgram.createShader(NULL, NULL);
+ gIrradianceGenProgram.mName = "Irradiance Gen Shader";
+ gIrradianceGenProgram.mShaderFiles.clear();
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenV.glsl", GL_VERTEX_SHADER));
+ gIrradianceGenProgram.mShaderFiles.push_back(make_pair("interface/irradianceGenF.glsl", GL_FRAGMENT_SHADER));
+ gIrradianceGenProgram.mShaderLevel = mShaderLevel[SHADER_INTERFACE];
+ success = gIrradianceGenProgram.createShader(NULL, NULL);
}
- return success;
-}
-
-BOOL LLViewerShaderMgr::loadTransformShaders()
-{
- BOOL success = TRUE;
-
- if (mShaderLevel[SHADER_TRANSFORM] < 1)
- {
- gTransformPositionProgram.unload();
- gTransformTexCoordProgram.unload();
- gTransformNormalProgram.unload();
- gTransformColorProgram.unload();
- gTransformTangentProgram.unload();
- return TRUE;
- }
-
- if (success)
- {
- gTransformPositionProgram.mName = "Position Transform Shader";
- gTransformPositionProgram.mShaderFiles.clear();
- gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "position_out",
- "texture_index_out",
- };
-
- success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings);
- }
-
- if (success)
- {
- gTransformTexCoordProgram.mName = "TexCoord Transform Shader";
- gTransformTexCoordProgram.mShaderFiles.clear();
- gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "texcoord_out",
- };
-
- success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformNormalProgram.mName = "Normal Transform Shader";
- gTransformNormalProgram.mShaderFiles.clear();
- gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "normal_out",
- };
-
- success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
- {
- gTransformColorProgram.mName = "Color Transform Shader";
- gTransformColorProgram.mShaderFiles.clear();
- gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "color_out",
- };
-
- success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings);
- }
-
- if (success)
+ if( !success )
{
- gTransformTangentProgram.mName = "Binormal Transform Shader";
- gTransformTangentProgram.mShaderFiles.clear();
- gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER_ARB));
- gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM];
-
- const char* varyings[] = {
- "tangent_out",
- };
-
- success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings);
+ mShaderLevel[SHADER_INTERFACE] = 0;
+ return FALSE;
}
-
- return success;
+ return TRUE;
}
+
std::string LLViewerShaderMgr::getShaderDirPrefix(void)
{
return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class");
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index f8a261805b..b0b9719d76 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -58,11 +58,8 @@ public:
BOOL loadShadersDeferred();
BOOL loadShadersObject();
BOOL loadShadersAvatar();
- BOOL loadShadersEnvironment();
BOOL loadShadersWater();
BOOL loadShadersInterface();
- BOOL loadShadersWindLight();
- BOOL loadTransformShaders();
std::vector<S32> mShaderLevel;
S32 mMaxAvatarShaderLevel;
@@ -78,7 +75,6 @@ public:
SHADER_WINDLIGHT,
SHADER_WATER,
SHADER_DEFERRED,
- SHADER_TRANSFORM,
SHADER_COUNT
};
@@ -150,77 +146,38 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade
extern LLVector4 gShinyOrigin;
-//transform shaders
-extern LLGLSLShader gTransformPositionProgram;
-extern LLGLSLShader gTransformTexCoordProgram;
-extern LLGLSLShader gTransformNormalProgram;
-extern LLGLSLShader gTransformColorProgram;
-extern LLGLSLShader gTransformTangentProgram;
-
-
-
//utility shaders
extern LLGLSLShader gOcclusionProgram;
extern LLGLSLShader gOcclusionCubeProgram;
-extern LLGLSLShader gCustomAlphaProgram;
extern LLGLSLShader gGlowCombineProgram;
-extern LLGLSLShader gSplatTextureRectProgram;
+extern LLGLSLShader gReflectionMipProgram;
+extern LLGLSLShader gGaussianProgram;
+extern LLGLSLShader gRadianceGenProgram;
+extern LLGLSLShader gIrradianceGenProgram;
extern LLGLSLShader gGlowCombineFXAAProgram;
extern LLGLSLShader gDebugProgram;
extern LLGLSLShader gClipProgram;
-extern LLGLSLShader gDownsampleDepthProgram;
-extern LLGLSLShader gDownsampleDepthRectProgram;
extern LLGLSLShader gBenchmarkProgram;
+extern LLGLSLShader gReflectionProbeDisplayProgram;
+extern LLGLSLShader gCopyProgram;
+extern LLGLSLShader gCopyDepthProgram;
-//output tex0[tc0] + tex1[tc1]
-extern LLGLSLShader gTwoTextureAddProgram;
//output tex0[tc0] - tex1[tc1]
extern LLGLSLShader gTwoTextureCompareProgram;
//discard some fragments based on user-set color tolerance
extern LLGLSLShader gOneTextureFilterProgram;
-extern LLGLSLShader gOneTextureNoColorProgram;
//object shaders
-extern LLGLSLShader gObjectSimpleProgram;
-extern LLGLSLShader gObjectSimpleImpostorProgram;
-extern LLGLSLShader gObjectPreviewProgram;
-extern LLGLSLShader gPhysicsPreviewProgram;
-extern LLGLSLShader gObjectSimpleAlphaMaskProgram;
-extern LLGLSLShader gObjectSimpleWaterProgram;
-extern LLGLSLShader gObjectSimpleWaterAlphaMaskProgram;
-extern LLGLSLShader gObjectSimpleNonIndexedTexGenProgram;
-extern LLGLSLShader gObjectSimpleNonIndexedTexGenWaterProgram;
-extern LLGLSLShader gObjectAlphaMaskNonIndexedProgram;
-extern LLGLSLShader gObjectAlphaMaskNonIndexedWaterProgram;
-extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
-extern LLGLSLShader gObjectAlphaMaskNoColorWaterProgram;
-extern LLGLSLShader gObjectFullbrightProgram;
-extern LLGLSLShader gObjectFullbrightWaterProgram;
-extern LLGLSLShader gObjectFullbrightNoColorProgram;
-extern LLGLSLShader gObjectFullbrightNoColorWaterProgram;
-extern LLGLSLShader gObjectEmissiveProgram;
-extern LLGLSLShader gObjectEmissiveWaterProgram;
-extern LLGLSLShader gObjectFullbrightAlphaMaskProgram;
-extern LLGLSLShader gObjectFullbrightWaterAlphaMaskProgram;
-extern LLGLSLShader gObjectEmissiveNonIndexedProgram;
-extern LLGLSLShader gObjectEmissiveNonIndexedWaterProgram;
-extern LLGLSLShader gObjectBumpProgram;
-extern LLGLSLShader gTreeProgram;
-extern LLGLSLShader gTreeWaterProgram;
-
-extern LLGLSLShader gObjectSimpleLODProgram;
-extern LLGLSLShader gObjectFullbrightLODProgram;
-
-extern LLGLSLShader gObjectFullbrightShinyProgram;
-extern LLGLSLShader gObjectFullbrightShinyWaterProgram;
-
-extern LLGLSLShader gObjectShinyProgram;
-extern LLGLSLShader gObjectShinyWaterProgram;
+extern LLGLSLShader gObjectPreviewProgram;
+extern LLGLSLShader gPhysicsPreviewProgram;
+extern LLGLSLShader gSkinnedObjectFullbrightAlphaMaskProgram;
+extern LLGLSLShader gObjectBumpProgram;
+extern LLGLSLShader gSkinnedObjectBumpProgram;
+extern LLGLSLShader gObjectAlphaMaskNoColorProgram;
+extern LLGLSLShader gObjectAlphaMaskNoColorWaterProgram;
//environment shaders
-extern LLGLSLShader gTerrainProgram;
-extern LLGLSLShader gTerrainWaterProgram;
extern LLGLSLShader gWaterProgram;
extern LLGLSLShader gWaterEdgeProgram;
extern LLGLSLShader gUnderWaterProgram;
@@ -233,34 +190,20 @@ extern LLGLSLShader gHighlightNormalProgram;
extern LLGLSLShader gHighlightSpecularProgram;
extern LLGLSLShader gDeferredHighlightProgram;
-extern LLGLSLShader gDeferredHighlightNormalProgram;
-extern LLGLSLShader gDeferredHighlightSpecularProgram;
extern LLGLSLShader gPathfindingProgram;
extern LLGLSLShader gPathfindingNoNormalsProgram;
// avatar shader handles
extern LLGLSLShader gAvatarProgram;
-extern LLGLSLShader gAvatarWaterProgram;
extern LLGLSLShader gAvatarEyeballProgram;
-extern LLGLSLShader gAvatarPickProgram;
extern LLGLSLShader gImpostorProgram;
-// WindLight shader handles
-extern LLGLSLShader gWLSkyProgram;
-extern LLGLSLShader gWLCloudProgram;
-extern LLGLSLShader gWLSunProgram;
-extern LLGLSLShader gWLMoonProgram;
-
// Post Process Shaders
-extern LLGLSLShader gPostColorFilterProgram;
-extern LLGLSLShader gPostNightVisionProgram;
-
+extern LLGLSLShader gPostScreenSpaceReflectionProgram;
// Deferred rendering shaders
extern LLGLSLShader gDeferredImpostorProgram;
-extern LLGLSLShader gDeferredWaterProgram;
-extern LLGLSLShader gDeferredUnderWaterProgram;
extern LLGLSLShader gDeferredDiffuseProgram;
extern LLGLSLShader gDeferredDiffuseAlphaMaskProgram;
extern LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram;
@@ -283,6 +226,8 @@ extern LLGLSLShader gDeferredSoftenWaterProgram;
extern LLGLSLShader gDeferredShadowProgram;
extern LLGLSLShader gDeferredShadowCubeProgram;
extern LLGLSLShader gDeferredShadowAlphaMaskProgram;
+extern LLGLSLShader gDeferredShadowGLTFAlphaMaskProgram;
+extern LLGLSLShader gDeferredShadowGLTFAlphaBlendProgram;
extern LLGLSLShader gDeferredShadowFullbrightAlphaMaskProgram;
extern LLGLSLShader gDeferredPostProgram;
extern LLGLSLShader gDeferredCoFProgram;
@@ -290,18 +235,25 @@ extern LLGLSLShader gDeferredDoFCombineProgram;
extern LLGLSLShader gFXAAProgram;
extern LLGLSLShader gDeferredPostNoDoFProgram;
extern LLGLSLShader gDeferredPostGammaCorrectProgram;
+extern LLGLSLShader gNoPostGammaCorrectProgram;
+extern LLGLSLShader gLegacyPostGammaCorrectProgram;
+extern LLGLSLShader gExposureProgram;
+extern LLGLSLShader gLuminanceProgram;
extern LLGLSLShader gDeferredAvatarShadowProgram;
-extern LLGLSLShader gDeferredAttachmentShadowProgram;
-extern LLGLSLShader gDeferredAttachmentAlphaShadowProgram;
-extern LLGLSLShader gDeferredAttachmentAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaShadowProgram;
extern LLGLSLShader gDeferredAvatarAlphaMaskShadowProgram;
extern LLGLSLShader gDeferredAlphaProgram;
+extern LLGLSLShader gHUDAlphaProgram;
extern LLGLSLShader gDeferredAlphaImpostorProgram;
extern LLGLSLShader gDeferredFullbrightProgram;
+extern LLGLSLShader gHUDFullbrightProgram;
extern LLGLSLShader gDeferredFullbrightAlphaMaskProgram;
+extern LLGLSLShader gHUDFullbrightAlphaMaskProgram;
+extern LLGLSLShader gDeferredFullbrightAlphaMaskAlphaProgram;
+extern LLGLSLShader gHUDFullbrightAlphaMaskAlphaProgram;
extern LLGLSLShader gDeferredAlphaWaterProgram;
extern LLGLSLShader gDeferredFullbrightWaterProgram;
+extern LLGLSLShader gDeferredFullbrightWaterAlphaProgram;
extern LLGLSLShader gDeferredFullbrightAlphaMaskWaterProgram;
extern LLGLSLShader gDeferredEmissiveProgram;
extern LLGLSLShader gDeferredAvatarEyesProgram;
@@ -312,9 +264,19 @@ extern LLGLSLShader gDeferredWLSunProgram;
extern LLGLSLShader gDeferredWLMoonProgram;
extern LLGLSLShader gDeferredStarProgram;
extern LLGLSLShader gDeferredFullbrightShinyProgram;
+extern LLGLSLShader gHUDFullbrightShinyProgram;
extern LLGLSLShader gNormalMapGenProgram;
+extern LLGLSLShader gDeferredGenBrdfLutProgram;
+extern LLGLSLShader gDeferredBufferVisualProgram;
// Deferred materials shaders
extern LLGLSLShader gDeferredMaterialProgram[LLMaterial::SHADER_COUNT*2];
extern LLGLSLShader gDeferredMaterialWaterProgram[LLMaterial::SHADER_COUNT*2];
+
+extern LLGLSLShader gHUDPBROpaqueProgram;
+extern LLGLSLShader gPBRGlowProgram;
+extern LLGLSLShader gDeferredPBROpaqueProgram;
+extern LLGLSLShader gDeferredPBRAlphaProgram;
+extern LLGLSLShader gDeferredPBRAlphaWaterProgram;
+extern LLGLSLShader gHUDPBRAlphaProgram;
#endif
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 1607296194..6ac94fe4c4 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -67,6 +67,53 @@
#include "lluiusage.h"
#include "lltranslate.h"
+// "Minimal Vulkan" to get max API Version
+
+// Calls
+ #if defined(_WIN32)
+ #define VKAPI_ATTR
+ #define VKAPI_CALL __stdcall
+ #define VKAPI_PTR VKAPI_CALL
+ #else
+ #define VKAPI_ATTR
+ #define VKAPI_CALL
+ #define VKAPI_PTR
+ #endif // _WIN32
+
+// Macros
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // |31|30|29|28|27|26|25|24|23|22|21|20|19|18|17|16|15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0|
+ // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+ // <variant> <-------major-------><-----------minor-----------> <--------------patch-------------->
+ // 0x7 0x7F 0x3FF 0xFFF
+ #define VK_API_VERSION_MAJOR( version) (((uint32_t)(version) >> 22) & 0x07FU) // 7 bits
+ #define VK_API_VERSION_MINOR( version) (((uint32_t)(version) >> 12) & 0x3FFU) // 10 bits
+ #define VK_API_VERSION_PATCH( version) (((uint32_t)(version) ) & 0xFFFU) // 12 bits
+ #define VK_API_VERSION_VARIANT(version) (((uint32_t)(version) >> 29) & 0x007U) // 3 bits
+
+ // NOTE: variant is first parameter! This is to match vulkan/vulkan_core.h
+ #define VK_MAKE_API_VERSION(variant, major, minor, patch) (0\
+ | (((uint32_t)(major & 0x07FU)) << 22) \
+ | (((uint32_t)(minor & 0x3FFU)) << 12) \
+ | (((uint32_t)(patch & 0xFFFU)) ) \
+ | (((uint32_t)(variant & 0x007U)) << 29) )
+
+ #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object;
+
+// Types
+ VK_DEFINE_HANDLE(VkInstance);
+
+ typedef enum VkResult
+ {
+ VK_SUCCESS = 0,
+ VK_RESULT_MAX_ENUM = 0x7FFFFFFF
+ } VkResult;
+
+// Prototypes
+ typedef void (VKAPI_PTR *PFN_vkVoidFunction )(void);
+ typedef PFN_vkVoidFunction (VKAPI_PTR *PFN_vkGetInstanceProcAddr )(VkInstance instance, const char* pName);
+ typedef VkResult (VKAPI_PTR *PFN_vkEnumerateInstanceVersion)(uint32_t* pApiVersion);
+
namespace LLStatViewer
{
@@ -141,10 +188,10 @@ SimMeasurement<LLUnit<F64, LLUnits::Percent> >
LLTrace::SampleStatHandle<> FPS_SAMPLE("fpssample"),
NUM_IMAGES("numimagesstat"),
NUM_RAW_IMAGES("numrawimagesstat"),
+ NUM_MATERIALS("nummaterials"),
NUM_OBJECTS("numobjectsstat"),
NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"),
- LIGHTING_DETAIL("lightingdetail", "Lighting Detail"),
VISIBLE_AVATARS("visibleavatars", "Visible Avatars"),
SHADER_OBJECTS("shaderobjects", "Object Shaders"),
DRAW_DISTANCE("drawdistance", "Draw Distance"),
@@ -157,10 +204,7 @@ LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> >
static LLTrace::SampleStatHandle<bool>
CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled");
-LLTrace::SampleStatHandle<F64Megabytes > GL_TEX_MEM("gltexmemstat"),
- GL_BOUND_MEM("glboundmemstat"),
- RAW_MEM("rawmemstat"),
- FORMATTED_MEM("formattedmemstat");
+LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM("formattedmemstat");
LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting");
@@ -328,10 +372,10 @@ U32Bytes gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGOR
extern U32 gVisCompared;
extern U32 gVisTested;
-LLFrameTimer gTextureTimer;
-
void update_statistics()
{
+ LL_PROFILE_ZONE_SCOPED;
+
gTotalWorldData += gVLManager.getTotalBytes();
gTotalObjectData += gObjectData;
@@ -357,22 +401,13 @@ void update_statistics()
record(LLStatViewer::TRIANGLES_DRAWN_PER_FRAME, last_frame_recording.getSum(LLStatViewer::TRIANGLES_DRAWN));
sample(LLStatViewer::ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
- sample(LLStatViewer::LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
sample(LLStatViewer::DRAW_DISTANCE, (F64)gSavedSettings.getF32("RenderFarClip"));
sample(LLStatViewer::CHAT_BUBBLES, gSavedSettings.getBOOL("UseChatBubbles"));
typedef LLTrace::StatType<LLTrace::TimeBlockAccumulator>::instance_tracker_t stat_type_t;
- F64Seconds idle_secs = last_frame_recording.getSum(*stat_type_t::getInstance("Idle"));
- F64Seconds network_secs = last_frame_recording.getSum(*stat_type_t::getInstance("Network"));
-
record(LLStatViewer::FRAME_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Frame")));
- record(LLStatViewer::UPDATE_STACKTIME, idle_secs - network_secs);
- record(LLStatViewer::NETWORK_STACKTIME, network_secs);
- record(LLStatViewer::IMAGE_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Update Images")));
- record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Sort Draw State")));
- record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Render Geometry")));
-
+
if (gAgent.getRegion() && isAgentAvatarValid())
{
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
@@ -435,7 +470,7 @@ void update_statistics()
auto tot_frame_time_raw = LLPerfStats::StatsRecorder::getSceneStat(LLPerfStats::StatType_t::RENDER_FRAME);
// cumulative avatar time (includes idle processing, attachments and base av)
- auto tot_avatar_time_raw = LLPerfStats::StatsRecorder::getSum(LLPerfStats::ObjType_t::OT_AVATAR, LLPerfStats::StatType_t::RENDER_COMBINED);
+ auto tot_avatar_time_raw = LLPerfStats::us_to_raw(LLVOAvatar::getTotalGPURenderTime());
// cumulative avatar render specific time (a bit arbitrary as the processing is too.)
// auto tot_av_idle_time_raw = LLPerfStats::StatsRecorder::getSum(AvType, LLPerfStats::StatType_t::RENDER_IDLE);
// auto tot_avatar_render_time_raw = tot_avatar_time_raw - tot_av_idle_time_raw;
@@ -508,19 +543,6 @@ void update_statistics()
}
}
-void update_texture_time()
-{
- if (gTextureList.isPrioRequestsFetched())
- {
- gTextureTimer.pause();
- }
- else
- {
- gTextureTimer.unpause();
- }
-
- record(LLStatViewer::TEXTURE_FETCH_TIME, gTextureTimer.getElapsedTimeF32());
-}
/*
* The sim-side LLSD is in newsim/llagentinfo.cpp:forwardViewerStats.
*
@@ -642,14 +664,11 @@ void send_viewer_stats(bool include_preferences)
shader_level = 3;
}
}
- else if (gPipeline.canUseWindLightShadersOnObjects())
+ else
{
shader_level = 2;
}
- else if (gPipeline.shadersLoaded())
- {
- shader_level = 1;
- }
+
system["shader_level"] = shader_level;
@@ -711,19 +730,76 @@ void send_viewer_stats(bool include_preferences)
// detailed information on versions and extensions can come later.
static bool vulkan_oneshot = false;
static bool vulkan_detected = false;
+ static std::string vulkan_max_api_version( "0.0" ); // Unknown/None
if (!vulkan_oneshot)
{
- HMODULE vulkan_loader = LoadLibraryExA("vulkan-1.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
+ // The 32-bit and 64-bit versions normally exist in:
+ // C:\Windows\System32
+ // C:\Windows\SysWOW64
+ HMODULE vulkan_loader = LoadLibraryA("vulkan-1.dll");
if (NULL != vulkan_loader)
{
vulkan_detected = true;
+ vulkan_max_api_version = "1.0"; // We have at least 1.0. See the note about vkEnumerateInstanceVersion() below.
+
+ // We use Run-Time Dynamic Linking (via GetProcAddress()) instead of Load-Time Dynamic Linking (via directly calling vkGetInstanceProcAddr()).
+ // This allows us to:
+ // a) not need the header: #include <vulkan/vulkan.h>
+ // (and not need to set the corresponding "Additional Include Directories" as long as we provide the equivalent Vulkan types/prototypes/etc.)
+ // b) not need to link to: vulkan-1.lib
+ // (and not need to set the corresponding "Additional Library Directories")
+ // The former will allow Second Life to start and run even if the vulkan.dll is missing.
+ // The latter will require us to:
+ // a) link with vulkan-1.lib
+ // b) cause a System Error at startup if the .dll is not found:
+ // "The code execution cannot proceed because vulkan-1.dll was not found."
+ //
+ // See:
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/using-run-time-dynamic-linking
+ // https://docs.microsoft.com/en-us/windows/win32/dlls/run-time-dynamic-linking
+
+ // NOTE: Technically we can use GetProcAddress() as a replacement for vkGetInstanceProcAddr()
+ // but the canonical recommendation (mandate?) is to use vkGetInstanceProcAddr().
+ PFN_vkGetInstanceProcAddr pGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr) GetProcAddress(vulkan_loader, "vkGetInstanceProcAddr");
+ if(pGetInstanceProcAddr)
+ {
+ // Check for vkEnumerateInstanceVersion. If it exists then we have at least 1.1 and can query the max API version.
+ // NOTE: Each VkPhysicalDevice that supports Vulkan has its own VkPhysicalDeviceProperties.apiVersion which is separate from the max API version!
+ // See: https://www.lunarg.com/wp-content/uploads/2019/02/Vulkan-1.1-Compatibility-Statement_01_19.pdf
+ PFN_vkEnumerateInstanceVersion pEnumerateInstanceVersion = (PFN_vkEnumerateInstanceVersion) pGetInstanceProcAddr(NULL, "vkEnumerateInstanceVersion");
+ if(pEnumerateInstanceVersion)
+ {
+ uint32_t version = VK_MAKE_API_VERSION(0,1,1,0); // e.g. 4202631 = 1.2.135.0
+ VkResult status = pEnumerateInstanceVersion( &version );
+ if (status != VK_SUCCESS)
+ {
+ LL_INFOS("Vulkan") << "Failed to get Vulkan version. Assuming 1.0" << LL_ENDL;
+ }
+ else
+ {
+ // https://www.khronos.org/registry/vulkan/specs/1.2-extensions/html/vkspec.html#extendingvulkan-coreversions-versionnumbers
+ int major = VK_API_VERSION_MAJOR ( version );
+ int minor = VK_API_VERSION_MINOR ( version );
+ int patch = VK_API_VERSION_PATCH ( version );
+ int variant = VK_API_VERSION_VARIANT( version );
+
+ vulkan_max_api_version = llformat( "%d.%d.%d.%d", major, minor, patch, variant );
+ LL_INFOS("Vulkan") << "Vulkan API version: " << vulkan_max_api_version << ", Raw version: " << version << LL_ENDL;
+ }
+ }
+ }
+ else
+ {
+ LL_WARNS("Vulkan") << "FAILED to get Vulkan vkGetInstanceProcAddr()!" << LL_ENDL;
+ }
FreeLibrary(vulkan_loader);
}
vulkan_oneshot = true;
}
misc["string_1"] = vulkan_detected ? llformat("Vulkan driver is detected") : llformat("No Vulkan driver detected");
+ misc["VulkanMaxApiVersion"] = vulkan_max_api_version;
#else
misc["string_1"] = llformat("Unused");
@@ -751,12 +827,11 @@ void send_viewer_stats(bool include_preferences)
LL_INFOS("LogViewerStatsPacket") << "Sending viewer statistics: " << body << LL_ENDL;
- if (debugLoggingEnabled("LogViewerStatsPacket"))
- {
- std::string filename("viewer_stats_packet.xml");
- llofstream of(filename.c_str());
- LLSDSerialize::toPrettyXML(body,of);
- }
+ LL_DEBUGS("LogViewerStatsPacket");
+ std::string filename("viewer_stats_packet.xml");
+ llofstream of(filename.c_str());
+ LLSDSerialize::toPrettyXML(body,of);
+ LL_ENDL;
// The session ID token must never appear in logs
body["session_id"] = gAgentSessionID;
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 017c79b2e3..4f0f4f8813 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -180,6 +180,7 @@ extern LLTrace::SampleStatHandle<> FPS_SAMPLE,
NUM_IMAGES,
NUM_RAW_IMAGES,
NUM_OBJECTS,
+ NUM_MATERIALS,
NUM_ACTIVE_OBJECTS,
ENABLE_VBO,
LIGHTING_DETAIL,
@@ -191,10 +192,8 @@ extern LLTrace::SampleStatHandle<> FPS_SAMPLE,
extern LLTrace::SampleStatHandle<LLUnit<F32, LLUnits::Percent> > PACKETS_LOST_PERCENT;
-extern LLTrace::SampleStatHandle<F64Megabytes > GL_TEX_MEM,
- GL_BOUND_MEM,
- RAW_MEM,
- FORMATTED_MEM;
+extern LLTrace::SampleStatHandle<F64Megabytes > FORMATTED_MEM;
+
extern LLTrace::SampleStatHandle<F64Kilobytes > DELTA_BANDWIDTH,
MAX_BANDWIDTH;
extern SimMeasurement<F64Milliseconds > SIM_FRAME_TIME,
@@ -296,7 +295,6 @@ void update_statistics();
void send_viewer_stats(bool include_preferences);
void update_texture_time();
-extern LLFrameTimer gTextureTimer;
extern U32Bytes gTotalTextureData;
extern U32Bytes gTotalObjectData;
extern U32Bytes gTotalTextureBytesPerBoostLevel[] ;
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index c28fed9ca4..fa6b6dc156 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -43,6 +43,7 @@
#include "lllandmark.h"
#include "lllandmarkactions.h"
#include "lllandmarklist.h"
+#include "llmaterialeditor.h"
#include "llmemorystream.h"
#include "llmenugl.h"
#include "llnotecard.h"
@@ -558,6 +559,7 @@ LLUIImagePtr LLEmbeddedItems::getItemImage(llwchar ext_char) const
case LLAssetType::AT_GESTURE: img_name = "Inv_Gesture"; break;
case LLAssetType::AT_MESH: img_name = "Inv_Mesh"; break;
case LLAssetType::AT_SETTINGS: img_name = "Inv_Settings"; break;
+ case LLAssetType::AT_MATERIAL: img_name = "Inv_Material"; break;
default: img_name = "Inv_Invalid"; break; // use the Inv_Invalid icon for undefined object types (see MAINT-3981)
}
@@ -895,6 +897,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask,
case DAD_ANIMATION:
case DAD_GESTURE:
case DAD_MESH:
+ case DAD_MATERIAL:
{
supported = true;
break;
@@ -1142,6 +1145,9 @@ BOOL LLViewerTextEditor::openEmbeddedItem(LLPointer<LLInventoryItem> item, llwch
case LLAssetType::AT_SETTINGS:
openEmbeddedSetting(item, wc);
return TRUE;
+ case LLAssetType::AT_MATERIAL:
+ openEmbeddedGLTFMaterial(item, wc);
+ return TRUE;
case LLAssetType::AT_NOTECARD:
case LLAssetType::AT_LSL_TEXT:
case LLAssetType::AT_CLOTHING:
@@ -1232,6 +1238,26 @@ void LLViewerTextEditor::openEmbeddedSetting(LLInventoryItem* item, llwchar wc)
}
}
+void LLViewerTextEditor::openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc)
+{
+ if (!item)
+ {
+ return;
+ }
+
+ LLSD floater_key;
+ floater_key["objectid"] = mObjectID;
+ floater_key["notecardid"] = mNotecardInventoryID;
+ LLMaterialEditor* preview = LLFloaterReg::getTypedInstance<LLMaterialEditor>("material_editor", floater_key);
+ if (preview)
+ {
+ preview->setAuxItem(item);
+ preview->setNotecardInfo(mNotecardInventoryID, mObjectID);
+ preview->openFloater(floater_key);
+ preview->setFocus(TRUE);
+ }
+}
+
void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
{
LLSD payload;
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index a6d7fef409..6170d476b8 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -108,6 +108,7 @@ private:
void openEmbeddedLandmark( LLPointer<LLInventoryItem> item_ptr, llwchar wc );
void openEmbeddedCallingcard( LLInventoryItem* item, llwchar wc);
void openEmbeddedSetting(LLInventoryItem* item, llwchar wc);
+ void openEmbeddedGLTFMaterial(LLInventoryItem* item, llwchar wc);
void showCopyToInvDialog( LLInventoryItem* item, llwchar wc );
void showUnsavedAlertDialog( LLInventoryItem* item );
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index c458c75a40..ec6f2c848f 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -58,6 +58,8 @@
#include "llvovolume.h"
#include "llviewermedia.h"
#include "lltexturecache.h"
+#include "llviewerwindow.h"
+#include "llwindow.h"
///////////////////////////////////////////////////////////////////////////////
// extern
@@ -74,8 +76,11 @@ LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sWhiteImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sSmokeImagep = NULL;
LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+LLPointer<LLViewerFetchedTexture> LLViewerFetchedTexture::sDefaultIrradiancePBRp;
LLViewerMediaTexture::media_map_t LLViewerMediaTexture::sMediaMap;
LLTexturePipelineTester* LLViewerTextureManager::sTesterp = NULL;
+F32 LLViewerFetchedTexture::sMaxVirtualSize = 8192.f*8192.f;
+
const std::string sTesterName("TextureTester");
S32 LLViewerTexture::sImageCount = 0;
@@ -84,28 +89,19 @@ S32 LLViewerTexture::sAuxCount = 0;
LLFrameTimer LLViewerTexture::sEvaluationTimer;
F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
-S32Bytes LLViewerTexture::sBoundTextureMemory;
-S32Bytes LLViewerTexture::sTotalTextureMemory;
-S32Megabytes LLViewerTexture::sMaxBoundTextureMemory;
-S32Megabytes LLViewerTexture::sMaxTotalTextureMem;
-S32Bytes LLViewerTexture::sMaxDesiredTextureMem;
-S8 LLViewerTexture::sCameraMovingDiscardBias = 0;
-F32 LLViewerTexture::sCameraMovingBias = 0.0f;
S32 LLViewerTexture::sMaxSculptRez = 128; //max sculpt image size
const S32 MAX_CACHED_RAW_IMAGE_AREA = 64 * 64;
const S32 MAX_CACHED_RAW_SCULPT_IMAGE_AREA = LLViewerTexture::sMaxSculptRez * LLViewerTexture::sMaxSculptRez;
const S32 MAX_CACHED_RAW_TERRAIN_IMAGE_AREA = 128 * 128;
-const S32 DEFAULT_ICON_DIMENTIONS = 32;
+const S32 DEFAULT_ICON_DIMENSIONS = 32;
+const S32 DEFAULT_THUMBNAIL_DIMENSIONS = 256;
U32 LLViewerTexture::sMinLargeImageSize = 65536; //256 * 256.
U32 LLViewerTexture::sMaxSmallImageSize = MAX_CACHED_RAW_IMAGE_AREA;
bool LLViewerTexture::sFreezeImageUpdates = false;
F32 LLViewerTexture::sCurrentTime = 0.0f;
-F32 LLViewerTexture::sTexelPixelRatio = 1.0f;
LLViewerTexture::EDebugTexels LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
-const F32 desired_discard_bias_min = -2.0f; // -max number of levels to improve image quality by
-const F32 desired_discard_bias_max = (F32)MAX_DISCARD_LEVEL; // max number of levels to reduce image quality by
const F64 log_2 = log(2.0);
#if ADDRESS_SIZE == 32
@@ -287,6 +283,13 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
return tex;
}
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps)
+{
+ LLViewerFetchedTexture* ret = new LLViewerFetchedTexture(raw, type, usemipmaps);
+ gTextureList.addImage(ret, TEX_LIST_STANDARD);
+ return ret;
+}
+
LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
const LLUUID &image_id,
FTType f_type,
@@ -449,6 +452,7 @@ void LLViewerTextureManager::cleanup()
LLViewerFetchedTexture::sWhiteImagep = NULL;
LLViewerFetchedTexture::sFlatNormalImagep = NULL;
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = NULL;
LLViewerMediaTexture::cleanUpClass();
}
@@ -461,16 +465,9 @@ void LLViewerTextureManager::cleanup()
void LLViewerTexture::initClass()
{
LLImageGL::sDefaultGLTexture = LLViewerFetchedTexture::sDefaultImagep->getGLTexture();
-
- if(gSavedSettings.getBOOL("TextureFetchDebuggerEnabled"))
- {
- sTexelPixelRatio = gSavedSettings.getF32("TexelPixelRatio");
- }
}
// tuning params
-const F32 discard_bias_delta = .25f;
-const F32 discard_delta_time = 0.5f;
const F32 GPU_MEMORY_CHECK_WAIT_TIME = 1.0f;
// non-const (used externally
F32 texmem_lower_bound_scale = 0.85f;
@@ -490,21 +487,7 @@ bool LLViewerTexture::isMemoryForTextureLow()
S32Megabytes physical;
getGPUMemoryForTextures(gpu, physical);
- return (gpu < MIN_FREE_TEXTURE_MEMORY) || (physical < MIN_FREE_MAIN_MEMORY);
-}
-
-//static
-bool LLViewerTexture::isMemoryForTextureSuficientlyFree()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- const S32Megabytes DESIRED_FREE_TEXTURE_MEMORY(50);
- const S32Megabytes DESIRED_FREE_MAIN_MEMORY(200);
-
- S32Megabytes gpu;
- S32Megabytes physical;
- getGPUMemoryForTextures(gpu, physical);
-
- return (gpu > DESIRED_FREE_TEXTURE_MEMORY) && (physical > DESIRED_FREE_MAIN_MEMORY);
+ return (gpu < MIN_FREE_TEXTURE_MEMORY); // || (physical < MIN_FREE_MAIN_MEMORY);
}
//static
@@ -525,9 +508,9 @@ void LLViewerTexture::getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &p
timer.reset();
{
- gpu_res = (S32Megabytes) LLImageGLThread::getFreeVRAMMegabytes();
+ gpu_res = (S32Megabytes)gViewerWindow->getWindow()->getAvailableVRAMMegabytes();
- //check main memory, only works for windows.
+ //check main memory, only works for windows and macos.
LLMemory::updateMemoryInfo();
physical_res = LLMemory::getAvailableMemKB();
@@ -550,51 +533,29 @@ void LLViewerTexture::updateClass()
LLViewerMediaTexture::updateClass();
- sBoundTextureMemory = LLImageGL::sBoundTextureMemory;
- sTotalTextureMemory = LLImageGL::sGlobalTextureMemory;
- sMaxBoundTextureMemory = gTextureList.getMaxResidentTexMem();
- sMaxTotalTextureMem = gTextureList.getMaxTotalTextureMem();
- sMaxDesiredTextureMem = sMaxTotalTextureMem; //in Bytes, by default and when total used texture memory is small.
+ static LLCachedControl<U32> max_vram_budget(gSavedSettings, "RenderMaxVRAMBudget", 0);
- if (sBoundTextureMemory >= sMaxBoundTextureMemory ||
- sTotalTextureMemory >= sMaxTotalTextureMem)
- {
- //when texture memory overflows, lower down the threshold to release the textures more aggressively.
- sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, F32Bytes(gMaxVideoRam));
-
- // If we are using more texture memory than we should,
- // scale up the desired discard level
- if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
- {
- sDesiredDiscardBias += discard_bias_delta;
- sEvaluationTimer.reset();
- }
- }
- else if(isMemoryForTextureLow())
- {
- // Note: isMemoryForTextureLow() uses 1s delay, make sure we waited enough for it to recheck
- if (sEvaluationTimer.getElapsedTimeF32() > GPU_MEMORY_CHECK_WAIT_TIME)
- {
- sDesiredDiscardBias += discard_bias_delta;
- sEvaluationTimer.reset();
- }
- }
- else if (sDesiredDiscardBias > 0.0f
- && sBoundTextureMemory < sMaxBoundTextureMemory * texmem_lower_bound_scale
- && sTotalTextureMemory < sMaxTotalTextureMem * texmem_lower_bound_scale
- && isMemoryForTextureSuficientlyFree())
- {
- // If we are using less texture memory than we should,
- // scale down the desired discard level
- if (sEvaluationTimer.getElapsedTimeF32() > discard_delta_time)
- {
- sDesiredDiscardBias -= discard_bias_delta;
- sEvaluationTimer.reset();
- }
- }
- sDesiredDiscardBias = llclamp(sDesiredDiscardBias, desired_discard_bias_min, desired_discard_bias_max);
+ F64 texture_bytes_alloc = LLImageGL::getTextureBytesAllocated() / 1024.0 / 512.0;
+ F64 vertex_bytes_alloc = LLVertexBuffer::getBytesAllocated() / 1024.0 / 512.0;
+
+ // get an estimate of how much video memory we're using
+ // NOTE: our metrics miss about half the vram we use, so this biases high but turns out to typically be within 5% of the real number
+ F32 used = (F32)ll_round(texture_bytes_alloc + vertex_bytes_alloc);
+
+ F32 budget = max_vram_budget == 0 ? gGLManager.mVRAM : max_vram_budget;
+
+ // try to leave half a GB for everyone else, but keep at least 768MB for ourselves
+ F32 target = llmax(budget - 512.f, 768.f);
+
+ F32 over_pct = llmax((used-target) / target, 0.f);
+ sDesiredDiscardBias = llmax(sDesiredDiscardBias, 1.f + over_pct);
+
+ if (sDesiredDiscardBias > 1.f)
+ {
+ sDesiredDiscardBias -= gFrameIntervalSeconds * 0.01;
+ }
- LLViewerTexture::sFreezeImageUpdates = sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);
+ LLViewerTexture::sFreezeImageUpdates = false; // sDesiredDiscardBias > (desired_discard_bias_max - 1.0f);
}
//end of static functions
@@ -647,11 +608,9 @@ LLViewerTexture::~LLViewerTexture()
// virtual
void LLViewerTexture::init(bool firstinit)
{
- mSelectedTime = 0.f;
mMaxVirtualSize = 0.f;
mMaxVirtualSizeResetInterval = 1;
mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;
- mAdditionalDecodePriority = 0.f;
mParcelMedia = NULL;
memset(&mNumVolumes, 0, sizeof(U32)* LLRender::NUM_VOLUME_TEXTURE_CHANNELS);
@@ -677,7 +636,10 @@ S8 LLViewerTexture::getType() const
void LLViewerTexture::cleanup()
{
- notifyAboutMissingAsset();
+ if (LLAppViewer::getTextureFetch())
+ {
+ LLAppViewer::getTextureFetch()->updateRequestPriority(mID, 0.f);
+ }
mFaceList[LLRender::DIFFUSE_MAP].clear();
mFaceList[LLRender::NORMAL_MAP].clear();
@@ -686,30 +648,6 @@ void LLViewerTexture::cleanup()
mVolumeList[LLRender::SCULPT_TEX].clear();
}
-void LLViewerTexture::notifyAboutCreatingTexture()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- for(U32 f = 0; f < mNumFaces[ch]; f++)
- {
- mFaceList[ch][f]->notifyAboutCreatingTexture(this);
- }
- }
-}
-
-void LLViewerTexture::notifyAboutMissingAsset()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- for(U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- for(U32 f = 0; f < mNumFaces[ch]; f++)
- {
- mFaceList[ch][f]->notifyAboutMissingAsset(this);
- }
- }
-}
-
// virtual
void LLViewerTexture::dump()
{
@@ -727,19 +665,19 @@ void LLViewerTexture::setBoostLevel(S32 level)
{
mBoostLevel = level;
if(mBoostLevel != LLViewerTexture::BOOST_NONE &&
- mBoostLevel != LLViewerTexture::BOOST_ALM &&
mBoostLevel != LLViewerTexture::BOOST_SELECTED &&
- mBoostLevel != LLViewerTexture::BOOST_ICON)
+ mBoostLevel != LLViewerTexture::BOOST_ICON &&
+ mBoostLevel != LLViewerTexture::BOOST_THUMBNAIL)
{
setNoDelete();
}
}
- if (mBoostLevel == LLViewerTexture::BOOST_SELECTED)
- {
- mSelectedTime = gFrameTimeSeconds;
- }
-
+ // strongly encourage anything boosted to load at full res
+ if (mBoostLevel >= LLViewerTexture::BOOST_HIGH)
+ {
+ mMaxVirtualSize = 2048.f * 2048.f;
+ }
}
bool LLViewerTexture::isActiveFetching()
@@ -817,16 +755,9 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
mNeedsGLTexture = TRUE;
}
- virtual_size *= sTexelPixelRatio;
- if(!mMaxVirtualSizeResetCounter)
- {
- //flag to reset the values because the old values are used.
- resetMaxVirtualSizeResetCounter();
- mMaxVirtualSize = virtual_size;
- mAdditionalDecodePriority = 0.f;
- mNeedsGLTexture = needs_gltexture;
- }
- else if (virtual_size > mMaxVirtualSize)
+ virtual_size = llmin(virtual_size, LLViewerFetchedTexture::sMaxVirtualSize);
+
+ if (virtual_size > mMaxVirtualSize)
{
mMaxVirtualSize = virtual_size;
}
@@ -835,7 +766,6 @@ void LLViewerTexture::addTextureStats(F32 virtual_size, BOOL needs_gltexture) co
void LLViewerTexture::resetTextureStats()
{
mMaxVirtualSize = 0.0f;
- mAdditionalDecodePriority = 0.f;
mMaxVirtualSizeResetCounter = 0;
}
@@ -1054,6 +984,19 @@ const std::string& fttype_to_string(const FTType& fttype)
//start of LLViewerFetchedTexture
//----------------------------------------------------------------------------------------------
+//static
+LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage()
+{
+ if (sSmokeImagep.isNull())
+ {
+ sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE);
+ }
+
+ sSmokeImagep->addTextureStats(1024.f * 1024.f);
+
+ return sSmokeImagep;
+}
+
LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
: LLViewerTexture(id, usemipmaps),
mTargetHost(host)
@@ -1104,7 +1047,6 @@ void LLViewerFetchedTexture::init(bool firstinit)
if (firstinit)
{
- mDecodePriority = 0.f;
mInImageList = 0;
}
@@ -1153,6 +1095,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
LLViewerFetchedTexture::~LLViewerFetchedTexture()
{
+ assert_main_thread();
//*NOTE getTextureFetch can return NULL when Viewer is shutting down.
// This is due to LLWearableList is singleton and is destroyed after
// LLAppViewer::cleanup() was called. (see ticket EXT-177)
@@ -1239,8 +1182,19 @@ void LLViewerFetchedTexture::loadFromFastCache()
{
// Shouldn't do anything usefull since texures in fast cache are 16x16,
// it is here in case fast cache changes.
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+ if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
+ {
+ // scale oversized icon, no need to give more work to gl
+ mRawImage->scale(expected_width, expected_height);
+ }
+ }
+
+ if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+ {
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
{
// scale oversized icon, no need to give more work to gl
@@ -1349,10 +1303,7 @@ void LLViewerFetchedTexture::dump()
void LLViewerFetchedTexture::destroyTexture()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(LLImageGL::sGlobalTextureMemory < sMaxDesiredTextureMem * 0.95f)//not ready to release unused memory.
- {
- return ;
- }
+
if (mNeedsCreateTexture)//return if in the process of generating a new texture.
{
return;
@@ -1588,6 +1539,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
void LLViewerFetchedTexture::postCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (!mNeedsCreateTexture)
{
return;
@@ -1596,8 +1548,6 @@ void LLViewerFetchedTexture::postCreateTexture()
mGLTexturep->checkActiveThread();
#endif
- notifyAboutCreatingTexture();
-
setActive();
if (!needsToSaveRawImage())
@@ -1611,6 +1561,8 @@ void LLViewerFetchedTexture::postCreateTexture()
void LLViewerFetchedTexture::scheduleCreateTexture()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+
if (!mNeedsCreateTexture)
{
mNeedsCreateTexture = true;
@@ -1628,7 +1580,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
}
#endif
mNeedsCreateTexture = true;
- auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
+ auto mainq = LLImageGLThread::sEnabledTextures ? mMainQueue.lock() : nullptr;
if (mainq)
{
ref();
@@ -1687,6 +1639,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
//virtual
void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(mKnownDrawWidth < width || mKnownDrawHeight < height)
{
mKnownDrawWidth = llmax(mKnownDrawWidth, width);
@@ -1698,9 +1651,31 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
addTextureStats((F32)(mKnownDrawWidth * mKnownDrawHeight));
}
+void LLViewerFetchedTexture::setDebugText(const std::string& text)
+{
+ for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
+ {
+ llassert(mNumFaces[ch] <= mFaceList[ch].size());
+
+ for (U32 i = 0; i < mNumFaces[ch]; i++)
+ {
+ LLFace* facep = mFaceList[ch][i];
+ if (facep)
+ {
+ LLDrawable* drawable = facep->getDrawable();
+ if (drawable)
+ {
+ drawable->getVObj()->setDebugText(text);
+ }
+ }
+ }
+ }
+}
+
//virtual
void LLViewerFetchedTexture::processTextureStats()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(mFullyLoaded)
{
if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
@@ -1708,6 +1683,7 @@ void LLViewerFetchedTexture::processTextureStats()
mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel);
mFullyLoaded = FALSE;
}
+ //setDebugText("fully loaded");
}
else
{
@@ -1719,11 +1695,7 @@ void LLViewerFetchedTexture::processTextureStats()
{
mDesiredDiscardLevel = 0;
}
- else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
- {
- mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
- }
- else if (mDontDiscard && mBoostLevel == LLGLTexture::BOOST_ICON)
+ else if (mDontDiscard && (mBoostLevel == LLGLTexture::BOOST_ICON || mBoostLevel == LLGLTexture::BOOST_THUMBNAIL))
{
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
{
@@ -1778,247 +1750,11 @@ void LLViewerFetchedTexture::processTextureStats()
}
}
-const F32 MAX_PRIORITY_PIXEL = 999.f; //pixel area
-const F32 PRIORITY_BOOST_LEVEL_FACTOR = 1000.f; //boost level
-const F32 PRIORITY_DELTA_DISCARD_LEVEL_FACTOR = 100000.f; //delta discard
-const S32 MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY = 4;
-const F32 PRIORITY_ADDITIONAL_FACTOR = 1000000.f; //additional
-const S32 MAX_ADDITIONAL_LEVEL_FOR_PRIORITY = 8;
-const F32 PRIORITY_BOOST_HIGH_FACTOR = 10000000.f;//boost high
-F32 LLViewerFetchedTexture::calcDecodePriority()
-{
-#ifndef LL_RELEASE_FOR_DOWNLOAD
- if (mID == LLAppViewer::getTextureFetch()->mDebugID)
- {
- LLAppViewer::getTextureFetch()->mDebugCount++; // for setting breakpoints
- }
-#endif
-
- if (mNeedsCreateTexture)
- {
- return mDecodePriority; // no change while waiting to create
- }
- if(mFullyLoaded && !mForceToSaveRawImage)//already loaded for static texture
- {
- return -1.0f; //alreay fetched
- }
-
- S32 cur_discard = getCurrentDiscardLevelForFetching();
- bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel));
- F32 pixel_priority = (F32) sqrt(mMaxVirtualSize);
-
- F32 priority = 0.f;
-
- if (mIsMissingAsset)
- {
- priority = 0.0f;
- }
- else if(mDesiredDiscardLevel >= cur_discard && cur_discard > -1)
- {
- priority = -2.0f;
- }
- else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel)
- {
- priority = -3.0f;
- }
- else if (mDesiredDiscardLevel > getMaxDiscardLevel())
- {
- // Don't decode anything we don't need
- priority = -4.0f;
- }
- else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
- {
- priority = 1.f;
- }
- else if (pixel_priority < 0.001f && !have_all_data)
- {
- // Not on screen but we might want some data
- if (mBoostLevel > BOOST_SELECTED)
- {
- // Always want high boosted images
- priority = 1.f;
- }
- else
- {
- priority = -5.f; //stop fetching
- }
- }
- else if (cur_discard < 0)
- {
- //texture does not have any data, so we don't know the size of the image, treat it like 32 * 32.
- // priority range = 100,000 - 500,000
- static const F64 log_2 = log(2.0);
- F32 desired = (F32)(log(32.0/pixel_priority) / log_2);
- S32 ddiscard = MAX_DISCARD_LEVEL - (S32)desired;
- ddiscard = llclamp(ddiscard, 0, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
- priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
- setAdditionalDecodePriority(0.1f);//boost the textures without any data so far.
- }
- else if ((mMinDiscardLevel > 0) && (cur_discard <= mMinDiscardLevel))
- {
- // larger mips are corrupted
- priority = -6.0f;
- }
- else
- {
- // priority range = 100,000 - 500,000
- S32 desired_discard = mDesiredDiscardLevel;
- if (!isJustBound() && mCachedRawImageReady)
- {
- if(mBoostLevel < BOOST_HIGH)
- {
- // We haven't rendered this in a while, de-prioritize it
- desired_discard += 2;
- }
- else
- {
- // We haven't rendered this in the last half second, and we have a cached raw image, leave the desired discard as-is
- desired_discard = cur_discard;
- }
- }
-
- S32 ddiscard = cur_discard - desired_discard;
- ddiscard = llclamp(ddiscard, -1, MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY);
- priority = (ddiscard + 1) * PRIORITY_DELTA_DISCARD_LEVEL_FACTOR;
- }
-
- // Priority Formula:
- // BOOST_HIGH + ADDITIONAL PRI + DELTA DISCARD + BOOST LEVEL + PIXELS
- // [10,000,000] + [1,000,000-9,000,000] + [100,000-500,000] + [1-20,000] + [0-999]
- if (priority > 0.0f)
- {
- bool large_enough = mCachedRawImageReady && ((S32)mTexelsPerImage > sMinLargeImageSize);
- if(large_enough)
- {
- //Note:
- //to give small, low-priority textures some chance to be fetched,
- //cut the priority in half if the texture size is larger than 256 * 256 and has a 64*64 ready.
- priority *= 0.5f;
- }
-
- pixel_priority = llclamp(pixel_priority, 0.0f, MAX_PRIORITY_PIXEL);
-
- priority += pixel_priority + PRIORITY_BOOST_LEVEL_FACTOR * mBoostLevel;
-
- if ( mBoostLevel > BOOST_HIGH)
- {
- if(mBoostLevel > BOOST_SUPER_HIGH)
- {
- //for very important textures, always grant the highest priority.
- priority += PRIORITY_BOOST_HIGH_FACTOR;
- }
- else if(mCachedRawImageReady)
- {
- //Note:
- //to give small, low-priority textures some chance to be fetched,
- //if high priority texture has a 64*64 ready, lower its fetching priority.
- setAdditionalDecodePriority(0.5f);
- }
- else
- {
- priority += PRIORITY_BOOST_HIGH_FACTOR;
- }
- }
-
- if(mAdditionalDecodePriority > 0.0f)
- {
- // priority range += 1,000,000.f-9,000,000.f
- F32 additional = PRIORITY_ADDITIONAL_FACTOR * (1.0 + mAdditionalDecodePriority * MAX_ADDITIONAL_LEVEL_FOR_PRIORITY);
- if(large_enough)
- {
- //Note:
- //to give small, low-priority textures some chance to be fetched,
- //cut the additional priority to a quarter if the texture size is larger than 256 * 256 and has a 64*64 ready.
- additional *= 0.25f;
- }
- priority += additional;
- }
- }
- return priority;
-}
-
-//static
-F32 LLViewerFetchedTexture::maxDecodePriority()
-{
- static const F32 max_priority = PRIORITY_BOOST_HIGH_FACTOR + //boost_high
- PRIORITY_ADDITIONAL_FACTOR * (MAX_ADDITIONAL_LEVEL_FOR_PRIORITY + 1) + //additional (view dependent factors)
- PRIORITY_DELTA_DISCARD_LEVEL_FACTOR * (MAX_DELTA_DISCARD_LEVEL_FOR_PRIORITY + 1) + //delta discard
- PRIORITY_BOOST_LEVEL_FACTOR * (BOOST_MAX_LEVEL - 1) + //boost level
- MAX_PRIORITY_PIXEL + 1.0f; //pixel area.
-
- return max_priority;
-}
-
//============================================================================
-void LLViewerFetchedTexture::setDecodePriority(F32 priority)
-{
- mDecodePriority = priority;
-
- if(mDecodePriority < F_ALMOST_ZERO)
- {
- mStopFetchingTimer.reset();
- }
-}
-
-void LLViewerFetchedTexture::setAdditionalDecodePriority(F32 priority)
-{
- priority = llclamp(priority, 0.f, 1.f);
- if(mAdditionalDecodePriority < priority)
- {
- mAdditionalDecodePriority = priority;
- }
-}
-
void LLViewerFetchedTexture::updateVirtualSize()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- if(!mMaxVirtualSizeResetCounter)
- {
- addTextureStats(0.f, FALSE);//reset
- }
-
- for (U32 ch = 0; ch < LLRender::NUM_TEXTURE_CHANNELS; ++ch)
- {
- llassert(mNumFaces[ch] <= mFaceList[ch].size());
-
- for(U32 i = 0; i < mNumFaces[ch]; i++)
- {
- LLFace* facep = mFaceList[ch][i];
- if( facep )
- {
- LLDrawable* drawable = facep->getDrawable();
- if (drawable)
- {
- if(drawable->isRecentlyVisible())
- {
- if ((getBoostLevel() == LLViewerTexture::BOOST_NONE || getBoostLevel() == LLViewerTexture::BOOST_ALM)
- && drawable->getVObj()
- && drawable->getVObj()->isSelected())
- {
- setBoostLevel(LLViewerTexture::BOOST_SELECTED);
- }
- addTextureStats(facep->getVirtualSize());
- setAdditionalDecodePriority(facep->getImportanceToCamera());
- }
- }
- }
- }
- }
- //reset whether or not a face was selected after 10 seconds
- const F32 SELECTION_RESET_TIME = 10.f;
-
- if (getBoostLevel() == LLViewerTexture::BOOST_SELECTED &&
- gFrameTimeSeconds - mSelectedTime > SELECTION_RESET_TIME)
- {
- // Could have been BOOST_ALM, but if user was working with this texture, better keep it as NONE
- setBoostLevel(LLViewerTexture::BOOST_NONE);
- }
-
- if(mMaxVirtualSizeResetCounter > 0)
- {
- mMaxVirtualSizeResetCounter--;
- }
reorganizeFaceList();
reorganizeVolumeList();
}
@@ -2062,14 +1798,22 @@ bool LLViewerFetchedTexture::isActiveFetching()
return mFetchState > 7 && mFetchState < 10 && monitor_enabled; //in state of WAIT_HTTP_REQ or DECODE_IMAGE.
}
+void LLViewerFetchedTexture::setBoostLevel(S32 level)
+{
+ LLViewerTexture::setBoostLevel(level);
+
+ if (level >= LLViewerTexture::BOOST_HIGH)
+ {
+ mDesiredDiscardLevel = 0;
+ }
+}
+
bool LLViewerFetchedTexture::updateFetch()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
static LLCachedControl<bool> textures_decode_disabled(gSavedSettings,"TextureDecodeDisabled", false);
- static LLCachedControl<F32> sCameraMotionThreshold(gSavedSettings,"TextureCameraMotionThreshold", 0.2);
- static LLCachedControl<S32> sCameraMotionBoost(gSavedSettings,"TextureCameraMotionBoost", 3);
- if(textures_decode_disabled ||
- (gUseWireframe && mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED_SELF)) // don't fetch the surface textures in wireframe mode
+
+ if(textures_decode_disabled) // don't fetch the surface textures in wireframe mode
{
return false;
}
@@ -2088,31 +1832,40 @@ bool LLViewerFetchedTexture::updateFetch()
if (mNeedsCreateTexture)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - needs create");
// We may be fetching still (e.g. waiting on write)
// but don't check until we've processed the raw data we have
return false;
}
if (mIsMissingAsset)
{
- llassert_always(!mHasFetcher);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - missing asset");
+ llassert(!mHasFetcher);
return false; // skip
}
if (!mLoadedCallbackList.empty() && mRawImage.notNull())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - callback pending");
return false; // process any raw image data in callbacks before replacing
}
if(mInFastCacheList)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - in fast cache");
return false;
}
+ if (mGLTexturep.isNull())
+ { // fix for crash inside getCurrentDiscardLevelForFetching (shouldn't happen but appears to be happening)
+ llassert(false);
+ return false;
+ }
S32 current_discard = getCurrentDiscardLevelForFetching();
S32 desired_discard = getDesiredDiscardLevel();
- F32 decode_priority = getDecodePriority();
- decode_priority = llclamp(decode_priority, 0.0f, maxDecodePriority());
+ F32 decode_priority = mMaxVirtualSize;
if (mIsFetching)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - is fetching");
// Sets mRawDiscardLevel, mRawImage, mAuxRawImage
S32 fetch_discard = current_discard;
@@ -2130,6 +1883,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (finished)
{
mIsFetching = FALSE;
+ mLastFetchState = -1;
mLastPacketTimer.reset();
}
else
@@ -2141,6 +1895,7 @@ bool LLViewerFetchedTexture::updateFetch()
// We may have data ready regardless of whether or not we are finished (e.g. waiting on write)
if (mRawImage.notNull())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - has raw image");
LLTexturePipelineTester* tester = (LLTexturePipelineTester*)LLMetricPerformanceTesterBasic::getTester(sTesterName);
if (tester)
{
@@ -2151,6 +1906,7 @@ bool LLViewerFetchedTexture::updateFetch()
if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) &&
(current_discard < 0 || mRawDiscardLevel < current_discard))
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data good");
mFullWidth = mRawImage->getWidth() << mRawDiscardLevel;
mFullHeight = mRawImage->getHeight() << mRawDiscardLevel;
setTexelsPerImage();
@@ -2173,8 +1929,20 @@ bool LLViewerFetchedTexture::updateFetch()
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+ if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
+ {
+ // scale oversized icon, no need to give more work to gl
+ // since we got mRawImage from thread worker and image may be in use (ex: writing cache), make a copy
+ mRawImage = mRawImage->scaled(expected_width, expected_height);
+ }
+ }
+
+ if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+ {
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
{
// scale oversized icon, no need to give more work to gl
@@ -2187,6 +1955,7 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - data not needed");
// Data is ready but we don't need it
// (received it already while fetcher was writing to disk)
destroyRawImage();
@@ -2219,13 +1988,13 @@ bool LLViewerFetchedTexture::updateFetch()
if(current_discard >= 0)
{
mMinDiscardLevel = current_discard;
- desired_discard = current_discard;
+ //desired_discard = current_discard;
}
else
{
S32 dis_level = getDiscardLevel();
mMinDiscardLevel = dis_level;
- desired_discard = dis_level;
+ //desired_discard = dis_level;
}
}
destroyRawImage();
@@ -2239,12 +2008,6 @@ bool LLViewerFetchedTexture::updateFetch()
}
else
{
-// // Useful debugging code for undesired deprioritization of textures.
-// if (decode_priority <= 0.0f && desired_discard >= 0 && desired_discard < current_discard)
-// {
-// LL_INFOS() << "Calling updateRequestPriority() with decode_priority = 0.0f" << LL_ENDL;
-// calcDecodePriority();
-// }
static const F32 MAX_HOLD_TIME = 5.0f; //seconds to wait before canceling fecthing if decode_priority is 0.f.
if(decode_priority > 0.0f || mStopFetchingTimer.getElapsedTimeF32() > MAX_HOLD_TIME)
{
@@ -2254,21 +2017,27 @@ bool LLViewerFetchedTexture::updateFetch()
}
}
+ desired_discard = llmin(desired_discard, getMaxDiscardLevel());
+
bool make_request = true;
if (decode_priority <= 0)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - priority <= 0");
make_request = false;
}
else if(mDesiredDiscardLevel > getMaxDiscardLevel())
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - desired > max");
make_request = false;
}
- else if (mNeedsCreateTexture || mIsMissingAsset)
+ else if (mNeedsCreateTexture || mIsMissingAsset)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - create or missing");
make_request = false;
}
else if (current_discard >= 0 && current_discard <= mMinDiscardLevel)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current < min");
make_request = false;
}
else if(mCachedRawImage.notNull() // can be empty
@@ -2278,41 +2047,24 @@ bool LLViewerFetchedTexture::updateFetch()
make_request = false;
switchToCachedImage(); //use the cached raw data first
}
- //else if (!isJustBound() && mCachedRawImageReady)
- //{
- // make_request = false;
- //}
if (make_request)
{
- // Load the texture progressively: we try not to rush to the desired discard too fast.
- // If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
- // This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
- S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_ALM) ? 2 : 1;
- if (current_discard < 0)
- {
- desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
- }
- else if (LLViewerTexture::sCameraMovingBias < sCameraMotionThreshold)
- {
- desired_discard = llmax(desired_discard, current_discard - sCameraMotionBoost);
- }
- else
- {
- desired_discard = llmax(desired_discard, current_discard - delta_level);
- }
-
if (mIsFetching)
{
+ // already requested a higher resolution mip
if (mRequestedDiscardLevel <= desired_discard)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - requested < desired");
make_request = false;
}
}
else
{
+ // already at a higher resolution mip, don't discard
if (current_discard >= 0 && current_discard <= desired_discard)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - current <= desired");
make_request = false;
}
}
@@ -2320,6 +2072,7 @@ bool LLViewerFetchedTexture::updateFetch()
if (make_request)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - make request");
S32 w=0, h=0, c=0;
if (getDiscardLevel() >= 0)
{
@@ -2335,28 +2088,34 @@ bool LLViewerFetchedTexture::updateFetch()
}
// bypass texturefetch directly by pulling from LLTextureCache
- bool fetch_request_created = false;
- fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
+ S32 fetch_request_discard = -1;
+ fetch_request_discard = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
w, h, c, desired_discard, needsAux(), mCanUseHTTP);
- if (fetch_request_created)
+ if (fetch_request_discard >= 0)
{
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vftuf - request created");
mHasFetcher = TRUE;
mIsFetching = TRUE;
- mRequestedDiscardLevel = desired_discard;
+ // in some cases createRequest can modify discard, as an example
+ // bake textures are always at discard 0
+ mRequestedDiscardLevel = llmin(desired_discard, fetch_request_discard);
mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority,
mFetchPriority, mFetchDeltaTime, mRequestDeltaTime, mCanUseHTTP);
}
- // if createRequest() failed, we're finishing up a request for this UUID,
- // wait for it to complete
+ // If createRequest() failed, that means one of two things:
+ // 1. We're finishing up a request for this UUID, so we
+ // should wait for it to complete
+ // 2. We've failed a request for this UUID, so there is
+ // no need to create another request
}
else if (mHasFetcher && !mIsFetching)
{
// Only delete requests that haven't received any network data
// for a while. Note - this is the normal mechanism for
// deleting requests, not just a place to handle timeouts.
- const F32 FETCH_IDLE_TIME = 5.f;
+ const F32 FETCH_IDLE_TIME = 0.1f;
if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
{
LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << LL_ENDL;
@@ -2365,7 +2124,8 @@ bool LLViewerFetchedTexture::updateFetch()
}
}
- llassert_always(mRawImage.notNull() || (!mNeedsCreateTexture && !mIsRawImageValid));
+ llassert(mRawImage.notNull() || !mIsRawImageValid);
+ llassert(mRawImage.notNull() || !mNeedsCreateTexture);
return mIsFetching ? true : false;
}
@@ -2407,8 +2167,6 @@ void LLViewerFetchedTexture::setIsMissingAsset(BOOL is_missing)
}
if (is_missing)
{
- notifyAboutMissingAsset();
-
if (mUrl.empty())
{
LL_WARNS() << mID << ": Marking image as missing" << LL_ENDL;
@@ -2666,7 +2424,7 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
LL_INFOS() << "baked texture: " << mID << "clears all call backs due to inactivity." << LL_ENDL;
LL_INFOS() << mUrl << LL_ENDL;
LL_INFOS() << "current discard: " << getDiscardLevel() << " current discard for fetch: " << getCurrentDiscardLevelForFetching() <<
- " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << getDecodePriority() << LL_ENDL;
+ " Desired discard: " << getDesiredDiscardLevel() << "decode Pri: " << mMaxVirtualSize << LL_ENDL;
}
clearCallbackEntryList() ; //remove all callbacks.
@@ -2794,8 +2552,8 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
destroyRawImage();
reloadRawImage(mLoadedCallbackDesiredDiscardLevel);
- llassert_always(mRawImage.notNull());
- llassert_always(!mNeedsAux || mAuxRawImage.notNull());
+ llassert(mRawImage.notNull());
+ llassert(!mNeedsAux || mAuxRawImage.notNull());
}
//
@@ -2819,7 +2577,6 @@ bool LLViewerFetchedTexture::doLoadedCallbacks()
// we're going to call them.
mLastCallBackActiveTime = sCurrentTime;
- //llassert_always(mRawImage.notNull());
if(mNeedsAux && mAuxRawImage.isNull())
{
LL_WARNS() << "Raw Image with no Aux Data for callback" << LL_ENDL;
@@ -2897,7 +2654,7 @@ void LLViewerFetchedTexture::forceImmediateUpdate()
return;
}
//if already called forceImmediateUpdate()
- if(mInImageList && mDecodePriority == LLViewerFetchedTexture::maxDecodePriority())
+ if(mInImageList && mMaxVirtualSize == LLViewerFetchedTexture::sMaxVirtualSize)
{
return;
}
@@ -2908,9 +2665,9 @@ void LLViewerFetchedTexture::forceImmediateUpdate()
LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
{
- llassert_always(mGLTexturep.notNull());
- llassert_always(discard_level >= 0);
- llassert_always(mComponents > 0);
+ llassert(mGLTexturep.notNull());
+ llassert(discard_level >= 0);
+ llassert(mComponents > 0);
if (mRawImage.notNull())
{
@@ -2920,7 +2677,9 @@ LLImageRaw* LLViewerFetchedTexture::reloadRawImage(S8 discard_level)
if(mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= discard_level)
{
- if (mSavedRawDiscardLevel != discard_level && mBoostLevel != BOOST_ICON)
+ if (mSavedRawDiscardLevel != discard_level
+ && mBoostLevel != BOOST_ICON
+ && mBoostLevel != BOOST_THUMBNAIL)
{
mRawImage = new LLImageRaw(getWidth(discard_level), getHeight(discard_level), getComponents());
mRawImage->copy(getSavedRawImage());
@@ -2966,6 +2725,7 @@ bool LLViewerFetchedTexture::needsToSaveRawImage()
void LLViewerFetchedTexture::destroyRawImage()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (mAuxRawImage.notNull() && !needsToSaveRawImage())
{
sAuxCount--;
@@ -3026,8 +2786,22 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
{
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+ if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+ {
+ mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
+ mCachedRawImage->copyScaled(imageraw);
+ }
+ else
+ {
+ mCachedRawImage = imageraw;
+ }
+ }
+ else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+ {
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
{
mCachedRawImage = new LLImageRaw(expected_width, expected_height, imageraw->getComponents());
@@ -3049,6 +2823,7 @@ void LLViewerFetchedTexture::setCachedRawImage(S32 discard_level, LLImageRaw* im
void LLViewerFetchedTexture::setCachedRawImage()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(mRawImage == mCachedRawImage)
{
return;
@@ -3124,6 +2899,7 @@ void LLViewerFetchedTexture::checkCachedRawSculptImage()
void LLViewerFetchedTexture::saveRawImage()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if(mRawImage.isNull() || mRawImage == mSavedRawImage || (mSavedRawDiscardLevel >= 0 && mSavedRawDiscardLevel <= mRawDiscardLevel))
{
return;
@@ -3132,8 +2908,22 @@ void LLViewerFetchedTexture::saveRawImage()
mSavedRawDiscardLevel = mRawDiscardLevel;
if (mBoostLevel == LLGLTexture::BOOST_ICON)
{
- S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
- S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENSIONS;
+ if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+ {
+ mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
+ mSavedRawImage->copyScaled(mRawImage);
+ }
+ else
+ {
+ mSavedRawImage = new LLImageRaw(mRawImage->getData(), mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents());
+ }
+ }
+ else if (mBoostLevel == LLGLTexture::BOOST_THUMBNAIL)
+ {
+ S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_THUMBNAIL_DIMENSIONS;
+ S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_THUMBNAIL_DIMENSIONS;
if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
{
mSavedRawImage = new LLImageRaw(expected_width, expected_height, mRawImage->getComponents());
@@ -3304,10 +3094,6 @@ void LLViewerLODTexture::processTextureStats()
if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
}
- else if (!LLPipeline::sRenderDeferred && mBoostLevel == LLGLTexture::BOOST_ALM)
- {
- mDesiredDiscardLevel = MAX_DISCARD_LEVEL + 1;
- }
else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
{
// If the image has not been significantly visible in a while, we don't want it
@@ -3317,99 +3103,70 @@ void LLViewerLODTexture::processTextureStats()
{
mDesiredDiscardLevel = getMaxDiscardLevel();
}
- else
- {
- //static const F64 log_2 = log(2.0);
- static const F64 log_4 = log(4.0);
+ else
+ {
+ //static const F64 log_2 = log(2.0);
+ static const F64 log_4 = log(4.0);
- F32 discard_level = 0.f;
+ F32 discard_level = 0.f;
- // If we know the output width and height, we can force the discard
- // level to the correct value, and thus not decode more texture
- // data than we need to.
- if (mKnownDrawWidth && mKnownDrawHeight)
- {
- S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight;
- draw_texels = llclamp(draw_texels, MIN_IMAGE_AREA, MAX_IMAGE_AREA);
+ // If we know the output width and height, we can force the discard
+ // level to the correct value, and thus not decode more texture
+ // data than we need to.
+ if (mKnownDrawWidth && mKnownDrawHeight)
+ {
+ S32 draw_texels = mKnownDrawWidth * mKnownDrawHeight;
+ draw_texels = llclamp(draw_texels, MIN_IMAGE_AREA, MAX_IMAGE_AREA);
- // Use log_4 because we're in square-pixel space, so an image
- // with twice the width and twice the height will have mTexelsPerImage
- // 4 * draw_size
- discard_level = (F32)(log(mTexelsPerImage/draw_texels) / log_4);
- }
- else
- {
- if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 0.3f)
- {
- //if is a big image and not being used recently, nor close to the view point, do not load hi-res data.
- mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerTexture::sMinLargeImageSize);
- }
+ // Use log_4 because we're in square-pixel space, so an image
+ // with twice the width and twice the height will have mTexelsPerImage
+ // 4 * draw_size
+ discard_level = (F32)(log(mTexelsPerImage / draw_texels) / log_4);
+ }
+ else
+ {
+ // Calculate the required scale factor of the image using pixels per texel
+ discard_level = (F32)(log(mTexelsPerImage / mMaxVirtualSize) / log_4);
+ mDiscardVirtualSize = mMaxVirtualSize;
+ mCalculatedDiscardLevel = discard_level;
+ }
+ if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
+ {
+ discard_level *= sDesiredDiscardScale; // scale (default 1.1f)
+ }
+ discard_level = floorf(discard_level);
- if ((mCalculatedDiscardLevel >= 0.f) &&
- (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f))
- {
- // < 20% change in virtual size = no change in desired discard
- discard_level = mCalculatedDiscardLevel;
- }
- else
- {
- // Calculate the required scale factor of the image using pixels per texel
- discard_level = (F32)(log(mTexelsPerImage/mMaxVirtualSize) / log_4);
- mDiscardVirtualSize = mMaxVirtualSize;
- mCalculatedDiscardLevel = discard_level;
- }
- }
- if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
- {
- discard_level += sDesiredDiscardBias;
- discard_level *= sDesiredDiscardScale; // scale
- discard_level += sCameraMovingDiscardBias;
- }
- discard_level = floorf(discard_level);
+ F32 min_discard = 0.f;
+ U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+ if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
+ {
+ desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
+ }
+ if (mFullWidth > desired_size || mFullHeight > desired_size)
+ min_discard = 1.f;
- F32 min_discard = 0.f;
- U32 desired_size = MAX_IMAGE_SIZE_DEFAULT; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
- if (mBoostLevel <= LLGLTexture::BOOST_SCULPTED)
- {
- desired_size = DESIRED_NORMAL_TEXTURE_SIZE;
- }
- if (mFullWidth > desired_size || mFullHeight > desired_size)
- min_discard = 1.f;
+ discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
- discard_level = llclamp(discard_level, min_discard, (F32)MAX_DISCARD_LEVEL);
-
- // Can't go higher than the max discard level
- mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level);
- // Clamp to min desired discard
- mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel);
+ // Can't go higher than the max discard level
+ mDesiredDiscardLevel = llmin(getMaxDiscardLevel() + 1, (S32)discard_level);
+ // Clamp to min desired discard
+ mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, mDesiredDiscardLevel);
- //
- // At this point we've calculated the quality level that we want,
- // if possible. Now we check to see if we have it, and take the
- // proper action if we don't.
- //
+ //
+ // At this point we've calculated the quality level that we want,
+ // if possible. Now we check to see if we have it, and take the
+ // proper action if we don't.
+ //
- S32 current_discard = getDiscardLevel();
- if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0)
- {
- if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
- {
- //needs to release texture memory urgently
- scaleDown();
- }
- // Limit the amount of GL memory bound each frame
- else if ( sBoundTextureMemory > sMaxBoundTextureMemory * texmem_middle_bound_scale &&
- (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
- {
- scaleDown();
- }
- // Only allow GL to have 2x the video card memory
- else if ( sTotalTextureMemory > sMaxTotalTextureMem * texmem_middle_bound_scale &&
- (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel))
- {
- scaleDown();
- }
- }
+ S32 current_discard = getDiscardLevel();
+ if (mBoostLevel < LLGLTexture::BOOST_AVATAR_BAKED &&
+ current_discard >= 0)
+ {
+ if (current_discard < (mDesiredDiscardLevel-1) && !mForceToSaveRawImage)
+ { // should scale down
+ scaleDown();
+ }
+ }
if (isUpdateFrozen() // we are out of memory and nearing max allowed bias
&& mBoostLevel < LLGLTexture::BOOST_SCULPTED
@@ -3424,6 +3181,16 @@ void LLViewerLODTexture::processTextureStats()
{
mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
}
+
+ // decay max virtual size over time
+ mMaxVirtualSize *= 0.8f;
+
+ // selection manager will immediately reset BOOST_SELECTED but never unsets it
+ // unset it immediately after we consume it
+ if (getBoostLevel() == BOOST_SELECTED)
+ {
+ setBoostLevel(BOOST_NONE);
+ }
}
bool LLViewerLODTexture::scaleDown()
@@ -4189,7 +3956,6 @@ void LLTexturePipelineTester::compareTestSessions(llofstream* os)
*os << llformat("%s\n", getTesterName().c_str());
*os << llformat("AggregateResults\n");
- compareTestResults(os, "TotalFetchingTime", base_sessionp->mTotalFetchingTime, current_sessionp->mTotalFetchingTime);
compareTestResults(os, "TotalGrayTime", base_sessionp->mTotalGrayTime, current_sessionp->mTotalGrayTime);
compareTestResults(os, "TotalStablizingTime", base_sessionp->mTotalStablizingTime, current_sessionp->mTotalStablizingTime);
compareTestResults(os, "StartTimeLoadingSculpties", base_sessionp->mStartTimeLoadingSculpties, current_sessionp->mStartTimeLoadingSculpties);
@@ -4249,7 +4015,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
return NULL;
}
- F32 total_fetching_time = 0.f;
F32 total_gray_time = 0.f;
F32 total_stablizing_time = 0.f;
F32 total_loading_sculpties_time = 0.f;
@@ -4284,7 +4049,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
F32 cur_time = (*log)[label]["Time"].asReal();
if(start_time - start_fetching_time > F_ALMOST_ZERO) //fetching has paused for a while
{
- sessionp->mTotalFetchingTime += total_fetching_time;
sessionp->mTotalGrayTime += total_gray_time;
sessionp->mTotalStablizingTime += total_stablizing_time;
@@ -4292,14 +4056,12 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
sessionp->mTotalTimeLoadingSculpties += total_loading_sculpties_time;
start_fetching_time = start_time;
- total_fetching_time = 0.0f;
total_gray_time = 0.f;
total_stablizing_time = 0.f;
total_loading_sculpties_time = 0.f;
}
else
{
- total_fetching_time = cur_time - start_time;
total_gray_time = (*log)[label]["TotalGrayTime"].asReal();
total_stablizing_time = (*log)[label]["TotalStablizingTime"].asReal();
@@ -4345,7 +4107,6 @@ LLMetricPerformanceTesterWithSession::LLTestSession* LLTexturePipelineTester::lo
in_log = (*log).has(currentLabel);
}
- sessionp->mTotalFetchingTime += total_fetching_time;
sessionp->mTotalGrayTime += total_gray_time;
sessionp->mTotalStablizingTime += total_stablizing_time;
@@ -4367,8 +4128,6 @@ LLTexturePipelineTester::LLTextureTestSession::~LLTextureTestSession()
}
void LLTexturePipelineTester::LLTextureTestSession::reset()
{
- mTotalFetchingTime = 0.0f;
-
mTotalGrayTime = 0.0f;
mTotalStablizingTime = 0.0f;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 2f5e0d01df..35fb0a2237 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -135,7 +135,7 @@ public:
/*virtual*/ bool isActiveFetching();
/*virtual*/ const LLUUID& getID() const { return mID; }
- void setBoostLevel(S32 level);
+ virtual void setBoostLevel(S32 level);
S32 getBoostLevel() { return mBoostLevel; }
void setTextureListType(S32 tex_type) { mTextureListType = tex_type; }
S32 getTextureListType() { return mTextureListType; }
@@ -178,10 +178,7 @@ protected:
void cleanup() ;
void init(bool firstinit) ;
void reorganizeFaceList() ;
- void reorganizeVolumeList() ;
-
- void notifyAboutMissingAsset();
- void notifyAboutCreatingTexture();
+ void reorganizeVolumeList();
private:
friend class LLBumpImageList;
@@ -189,19 +186,18 @@ private:
virtual void switchToCachedImage();
- static bool isMemoryForTextureLow() ;
- static bool isMemoryForTextureSuficientlyFree();
static void getGPUMemoryForTextures(S32Megabytes &gpu, S32Megabytes &physical);
+public:
+ static bool isMemoryForTextureLow();
protected:
+ friend class LLViewerTextureList;
LLUUID mID;
S32 mTextureListType; // along with mID identifies where to search for this texture in TextureList
- F32 mSelectedTime; // time texture was last selected
- mutable F32 mMaxVirtualSize; // The largest virtual size of the image, in pixels - how much data to we need?
- mutable S32 mMaxVirtualSizeResetCounter ;
+ mutable F32 mMaxVirtualSize = 0.f; // The largest virtual size of the image, in pixels - how much data to we need?
+ mutable S32 mMaxVirtualSizeResetCounter;
mutable S32 mMaxVirtualSizeResetInterval;
- mutable F32 mAdditionalDecodePriority; // priority add to mDecodePriority.
LLFrameTimer mLastReferencedTimer;
ll_face_list_t mFaceList[LLRender::NUM_TEXTURE_CHANNELS]; //reverse pointer pointing to the faces using this image as texture
@@ -218,7 +214,6 @@ protected:
LL::WorkQueue::weak_t mMainQueue;
LL::WorkQueue::weak_t mImageQueue;
- static F32 sTexelPixelRatio;
public:
static const U32 sCurrentFileVersion;
static S32 sImageCount;
@@ -227,13 +222,6 @@ public:
static LLFrameTimer sEvaluationTimer;
static F32 sDesiredDiscardBias;
static F32 sDesiredDiscardScale;
- static S32Bytes sBoundTextureMemory;
- static S32Bytes sTotalTextureMemory;
- static S32Megabytes sMaxBoundTextureMemory;
- static S32Megabytes sMaxTotalTextureMem;
- static S32Bytes sMaxDesiredTextureMem ;
- static S8 sCameraMovingDiscardBias;
- static F32 sCameraMovingBias;
static S32 sMaxSculptRez ;
static U32 sMinLargeImageSize ;
static U32 sMaxSmallImageSize ;
@@ -286,7 +274,6 @@ public:
LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
public:
- static F32 maxDecodePriority();
struct Compare
{
@@ -295,9 +282,10 @@ public:
{
const LLViewerFetchedTexture* lhsp = (const LLViewerFetchedTexture*)lhs;
const LLViewerFetchedTexture* rhsp = (const LLViewerFetchedTexture*)rhs;
+
// greater priority is "less"
- const F32 lpriority = lhsp->getDecodePriority();
- const F32 rpriority = rhsp->getDecodePriority();
+ const F32 lpriority = lhsp->mMaxVirtualSize;
+ const F32 rpriority = rhsp->mMaxVirtualSize;
if (lpriority > rpriority) // higher priority
return true;
if (lpriority < rpriority)
@@ -307,10 +295,10 @@ public:
};
public:
- /*virtual*/ S8 getType() const ;
+ /*virtual*/ S8 getType() const override;
FTType getFTType() const;
- /*virtual*/ void forceImmediateUpdate() ;
- /*virtual*/ void dump() ;
+ /*virtual*/ void forceImmediateUpdate() override;
+ /*virtual*/ void dump() override;
// Set callbacks to get called when the image gets updated with higher
// resolution versions.
@@ -336,7 +324,6 @@ public:
void destroyTexture() ;
virtual void processTextureStats() ;
- F32 calcDecodePriority() ;
BOOL needsAux() const { return mNeedsAux; }
@@ -344,20 +331,12 @@ public:
void setTargetHost(LLHost host) { mTargetHost = host; }
LLHost getTargetHost() const { return mTargetHost; }
- // Set the decode priority for this image...
- // DON'T CALL THIS UNLESS YOU KNOW WHAT YOU'RE DOING, it can mess up
- // the priority list, and cause horrible things to happen.
- void setDecodePriority(F32 priority = -1.0f);
- F32 getDecodePriority() const { return mDecodePriority; };
- F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
-
- void setAdditionalDecodePriority(F32 priority) ;
-
void updateVirtualSize() ;
S32 getDesiredDiscardLevel() { return mDesiredDiscardLevel; }
void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); }
+ void setBoostLevel(S32 level) override;
bool updateFetch();
bool setDebugFetching(S32 debug_level);
bool isInDebug() const { return mInDebug; }
@@ -370,10 +349,14 @@ public:
// Override the computation of discard levels if we know the exact output
// size of the image. Used for UI textures to not decode, even if we have
// more data.
- /*virtual*/ void setKnownDrawSize(S32 width, S32 height);
+ /*virtual*/ void setKnownDrawSize(S32 width, S32 height) override;
+
+ // Set the debug text of all Viewer Objects associated with this texture
+ // to the specified text
+ void setDebugText(const std::string& text);
void setIsMissingAsset(BOOL is_missing = true);
- /*virtual*/ BOOL isMissingAsset() const { return mIsMissingAsset; }
+ /*virtual*/ BOOL isMissingAsset() const override { return mIsMissingAsset; }
// returns dimensions of original image for local files (before power of two scaling)
// and returns 0 for all asset system images
@@ -416,7 +399,7 @@ public:
BOOL isRawImageValid()const { return mIsRawImageValid ; }
void forceToSaveRawImage(S32 desired_discard = 0, F32 kept_time = 0.f) ;
void forceToRefetchTexture(S32 desired_discard = 0, F32 kept_time = 60.f);
- /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
+ /*virtual*/ void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) override;
void destroySavedRawImage() ;
LLImageRaw* getSavedRawImage() ;
BOOL hasSavedRawImage() const ;
@@ -432,10 +415,10 @@ public:
void setInFastCacheList(bool in_list) { mInFastCacheList = in_list; }
bool isInFastCacheList() { return mInFastCacheList; }
- /*virtual*/bool isActiveFetching(); //is actively in fetching by the fetching pipeline.
+ /*virtual*/bool isActiveFetching() override; //is actively in fetching by the fetching pipeline.
protected:
- /*virtual*/ void switchToCachedImage();
+ /*virtual*/ void switchToCachedImage() override;
S32 getCurrentDiscardLevelForFetching() ;
private:
@@ -473,11 +456,11 @@ protected:
S32 mRequestedDiscardLevel;
F32 mRequestedDownloadPriority;
S32 mFetchState;
+ S32 mLastFetchState = -1; // DEBUG
U32 mFetchPriority;
F32 mDownloadProgress;
F32 mFetchDeltaTime;
F32 mRequestDeltaTime;
- F32 mDecodePriority; // The priority for decoding this image.
S32 mMinDiscardLevel;
S8 mDesiredDiscardLevel; // The discard level we'd LIKE to have - if we have it and there's space
S8 mMinDesiredDiscardLevel; // The minimum discard level we'd like to have
@@ -501,7 +484,7 @@ protected:
F32 mLastCallBackActiveTime;
LLPointer<LLImageRaw> mRawImage;
- S32 mRawDiscardLevel;
+ S32 mRawDiscardLevel = -1;
// Used ONLY for cloth meshes right now. Make SURE you know what you're
// doing if you use it for anything else! - djs
@@ -537,11 +520,16 @@ protected:
BOOL mIsFetched ; //is loaded from remote or from cache, not generated locally.
public:
+ static F32 sMaxVirtualSize; //maximum possible value of mMaxVirtualSize
static LLPointer<LLViewerFetchedTexture> sMissingAssetImagep; // Texture to show for an image asset that is not in the database
static LLPointer<LLViewerFetchedTexture> sWhiteImagep; // Texture to show NOTHING (whiteness)
static LLPointer<LLViewerFetchedTexture> sDefaultImagep; // "Default" texture for error cases, the only case of fetched texture which is generated in local.
- static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
static LLPointer<LLViewerFetchedTexture> sFlatNormalImagep; // Flat normal map denoting no bumpiness on a surface
+ static LLPointer<LLViewerFetchedTexture> sDefaultIrradiancePBRp; // PBR: irradiance
+
+ // not sure why, but something is iffy about the loading of this particular texture, use the accessor instead of accessing directly
+ static LLPointer<LLViewerFetchedTexture> sSmokeImagep; // Old "Default" translucent texture
+ static LLViewerFetchedTexture* getSmokeImage();
};
//
@@ -671,6 +659,8 @@ public:
static LLPointer<LLViewerTexture> getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
+ static LLViewerFetchedTexture* getFetchedTexture(const LLImageRaw* raw, FTType type, bool usemipmaps);
+
static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,
FTType f_type = FTT_DEFAULT,
BOOL usemipmap = TRUE,
@@ -775,7 +765,6 @@ private:
void reset() ;
- F32 mTotalFetchingTime ;
F32 mTotalGrayTime ;
F32 mTotalStablizingTime ;
F32 mStartTimeLoadingSculpties ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index f9fe8054a4..f898fb7142 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -61,6 +61,7 @@
#include "llviewerdisplay.h"
#include "llviewerwindow.h"
#include "llprogressview.h"
+
////////////////////////////////////////////////////////////////////////////
void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
@@ -71,7 +72,7 @@ LLViewerTextureList gTextureList;
ETexListType get_element_type(S32 priority)
{
- return (priority == LLViewerFetchedTexture::BOOST_ICON) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
+ return (priority == LLViewerFetchedTexture::BOOST_ICON || priority == LLViewerFetchedTexture::BOOST_THUMBNAIL) ? TEX_LIST_SCALE : TEX_LIST_STANDARD;
}
///////////////////////////////////////////////////////////////////////////////
@@ -91,8 +92,6 @@ LLTextureKey::LLTextureKey(LLUUID id, ETexListType tex_type)
LLViewerTextureList::LLViewerTextureList()
: mForceResetTextureStats(FALSE),
- mMaxResidentTexMemInMegaBytes(0),
- mMaxTotalTextureMemInMegaBytes(0),
mInitialized(FALSE)
{
}
@@ -101,12 +100,6 @@ void LLViewerTextureList::init()
{
mInitialized = TRUE ;
sNumImages = 0;
- mMaxResidentTexMemInMegaBytes = (U32Bytes)0;
- mMaxTotalTextureMemInMegaBytes = (U32Bytes)0;
-
- // Update how much texture RAM we're allowed to use.
- updateMaxResidentTexMem(S32Megabytes(0)); // 0 = use current
-
doPreloadImages();
}
@@ -130,7 +123,10 @@ void LLViewerTextureList::doPreloadImages()
// Set the default flat normal map
LLViewerFetchedTexture::sFlatNormalImagep = LLViewerTextureManager::getFetchedTextureFromFile("flatnormal.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_BUMP);
-
+
+ // PBR: irradiance
+ LLViewerFetchedTexture::sDefaultIrradiancePBRp = LLViewerTextureManager::getFetchedTextureFromFile("default_irradiance.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+
image_list->initFromFile();
// turn off clamping and bilinear filtering for uv picking images
@@ -208,8 +204,6 @@ static std::string get_texture_list_name()
void LLViewerTextureList::doPrefetchImages()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- gTextureTimer.start();
- gTextureTimer.pause();
// todo: do not load without getViewerAssetUrl()
// either fail login without caps or provide this
@@ -368,7 +362,7 @@ void LLViewerTextureList::dump()
{
LLViewerFetchedTexture* image = *it;
- LL_INFOS() << "priority " << image->getDecodePriority()
+ LL_INFOS() << "priority " << image->getMaxVirtualSize()
<< " boost " << image->getBoostLevel()
<< " size " << image->getWidth() << "x" << image->getHeight()
<< " discard " << image->getDiscardLevel()
@@ -498,7 +492,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
{
imagep->dontDiscard();
}
- if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+ if (boost_priority == LLViewerFetchedTexture::BOOST_ICON
+ || boost_priority == LLViewerFetchedTexture::BOOST_THUMBNAIL)
{
// Agent and group Icons are downloadable content, nothing manages
// icon deletion yet, so they should not persist
@@ -542,12 +537,6 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id, get_element_type(boost_priority));
if (!imagep.isNull())
{
- if (boost_priority != LLViewerTexture::BOOST_ALM && imagep->getBoostLevel() == LLViewerTexture::BOOST_ALM)
- {
- // Workaround: we need BOOST_ALM texture for something, 'rise' to NONE
- imagep->setBoostLevel(LLViewerTexture::BOOST_NONE);
- }
-
LLViewerFetchedTexture *texture = imagep.get();
if (request_from_host.isOk() &&
!texture->getTargetHost().isOk())
@@ -616,7 +605,8 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
{
imagep->dontDiscard();
}
- if (boost_priority == LLViewerFetchedTexture::BOOST_ICON)
+ if (boost_priority == LLViewerFetchedTexture::BOOST_ICON
+ || boost_priority == LLViewerFetchedTexture::BOOST_THUMBNAIL)
{
// Agent and group Icons are downloadable content, nothing manages
// icon deletion yet, so they should not persist.
@@ -693,13 +683,14 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
assert_main_thread();
llassert_always(mInitialized) ;
llassert(image);
+ image->validateRefCount();
S32 count = 0;
if (image->isInImageList())
{
count = mImageList.erase(image) ;
if(count != 1)
- {
+ {
LL_INFOS() << "Image " << image->getID()
<< " had mInImageList set but mImageList.erase() returned " << count
<< LL_ENDL;
@@ -725,6 +716,7 @@ void LLViewerTextureList::removeImageFromList(LLViewerFetchedTexture *image)
LL_INFOS() << "Image " << image->getID() << " was in mUUIDMap with same pointer" << LL_ENDL ;
}
count = mImageList.erase(image) ;
+ llassert(count != 0);
if(count != 0)
{ // it was in the list already?
LL_WARNS() << "Image " << image->getID()
@@ -810,23 +802,23 @@ void LLViewerTextureList::updateImages(F32 max_time)
using namespace LLStatViewer;
sample(NUM_IMAGES, sNumImages);
sample(NUM_RAW_IMAGES, LLImageRaw::sRawImageCount);
- sample(GL_TEX_MEM, LLImageGL::sGlobalTextureMemory);
- sample(GL_BOUND_MEM, LLImageGL::sBoundTextureMemory);
- sample(RAW_MEM, F64Bytes(LLImageRaw::sGlobalRawMemory));
sample(FORMATTED_MEM, F64Bytes(LLImageFormatted::sGlobalFormattedMemory));
}
- //loading from fast cache
- max_time -= updateImagesLoadingFastCache(max_time);
-
- updateImagesDecodePriorities();
-
- F32 total_max_time = max_time;
+ // make sure each call below gets at least its "fair share" of time
+ F32 min_time = max_time * 0.33f;
+ F32 remaining_time = max_time;
- max_time -= updateImagesFetchTextures(max_time);
-
- max_time = llmax(max_time, total_max_time*.50f); // at least 50% of max_time
- max_time -= updateImagesCreateTextures(max_time);
+ //loading from fast cache
+ remaining_time -= updateImagesLoadingFastCache(remaining_time);
+ remaining_time = llmax(remaining_time, min_time);
+
+ //dispatch to texture fetch threads
+ remaining_time -= updateImagesFetchTextures(remaining_time);
+ remaining_time = llmax(remaining_time, min_time);
+
+ //handle results from decode threads
+ updateImagesCreateTextures(remaining_time);
if (!mDirtyTextureList.empty())
{
@@ -851,7 +843,6 @@ void LLViewerTextureList::updateImages(F32 max_time)
didone = image->doLoadedCallbacks();
}
}
-
updateImagesUpdateStats();
}
@@ -874,120 +865,142 @@ void LLViewerTextureList::clearFetchingRequests()
}
}
-void LLViewerTextureList::updateImagesDecodePriorities()
+static void touch_texture(LLViewerFetchedTexture* tex, F32 vsize)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- // Update the decode priority for N images each frame
- {
- F32 lazy_flush_timeout = 30.f; // stop decoding
- F32 max_inactive_time = 20.f; // actually delete
- S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
-
- //reset imagep->getLastReferencedTimer() when screen is showing the progress view to avoid removing pre-fetched textures too soon.
- bool reset_timer = gViewerWindow->getProgressView()->getVisible();
-
- static const S32 MAX_PRIO_UPDATES = gSavedSettings.getS32("TextureFetchUpdatePriorities"); // default: 32
- const size_t max_update_count = llmin((S32) (MAX_PRIO_UPDATES*MAX_PRIO_UPDATES*gFrameIntervalSeconds.value()) + 1, MAX_PRIO_UPDATES);
- S32 update_counter = llmin(max_update_count, mUUIDMap.size());
- uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
- while ((update_counter-- > 0) && !mUUIDMap.empty())
- {
- if (iter == mUUIDMap.end())
- {
- iter = mUUIDMap.begin();
+ if (tex)
+ {
+ tex->addTextureStats(vsize);
+ }
+}
+
+extern BOOL gCubeSnapshot;
+
+void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep)
+{
+ if (imagep->isInDebug() || imagep->isUnremovable())
+ {
+ //update_counter--;
+ return; //is in debug, ignore.
+ }
+
+ llassert(!gCubeSnapshot);
+
+ static LLCachedControl<F32> bias_distance_scale(gSavedSettings, "TextureBiasDistanceScale", 1.f);
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE
+ {
+ for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
+ {
+ for (U32 fi = 0; fi < imagep->getNumFaces(i); ++fi)
+ {
+ LLFace* face = (*(imagep->getFaceList(i)))[fi];
+
+ if (face && face->getViewerObject() && face->getTextureEntry())
+ {
+ F32 vsize = face->getPixelArea();
+
+#if LL_DARWIN
+ vsize /= 1.f + LLViewerTexture::sDesiredDiscardBias*(1.f+face->getDrawable()->mDistanceWRTCamera*bias_distance_scale);
+#else
+ vsize /= LLViewerTexture::sDesiredDiscardBias;
+ vsize /= llmax(1.f, (LLViewerTexture::sDesiredDiscardBias-1.f) * (1.f + face->getDrawable()->mDistanceWRTCamera * bias_distance_scale));
+
+ F32 radius;
+ F32 cos_angle_to_view_dir;
+ BOOL in_frustum = face->calcPixelArea(cos_angle_to_view_dir, radius);
+ if (!in_frustum || !face->getDrawable()->isVisible())
+ { // further reduce by discard bias when off screen or occluded
+ vsize /= LLViewerTexture::sDesiredDiscardBias;
+ }
+#endif
+ // if a GLTF material is present, ignore that face
+ // as far as this texture stats go, but update the GLTF material
+ // stats
+ const LLTextureEntry* te = face->getTextureEntry();
+ LLFetchedGLTFMaterial* mat = te ? (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial() : nullptr;
+ llassert(mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(te->getGLTFRenderMaterial()) != nullptr);
+ if (mat)
+ {
+ touch_texture(mat->mBaseColorTexture, vsize);
+ touch_texture(mat->mNormalTexture, vsize);
+ touch_texture(mat->mMetallicRoughnessTexture, vsize);
+ touch_texture(mat->mEmissiveTexture, vsize);
+ }
+ else
+ {
+ imagep->addTextureStats(vsize);
+ }
+ }
}
- mLastUpdateKey = iter->first;
- LLPointer<LLViewerFetchedTexture> imagep = iter->second;
- ++iter; // safe to increment now
+ }
+ }
- if(imagep->isInDebug() || imagep->isUnremovable())
- {
- update_counter--;
- continue; //is in debug, ignore.
- }
+ //imagep->setDebugText(llformat("%.3f - %d", sqrtf(imagep->getMaxVirtualSize()), imagep->getBoostLevel()));
- //
- // Flush formatted images using a lazy flush
- //
- S32 num_refs = imagep->getNumRefs();
- if (num_refs == min_refs)
- {
- if(reset_timer)
- {
- imagep->getLastReferencedTimer()->reset();
- }
- else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
- {
- // Remove the unused image from the image list
- deleteImage(imagep);
- imagep = NULL; // should destroy the image
- }
- continue;
- }
- else
- {
- if(imagep->hasSavedRawImage())
- {
- if(imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
- {
- imagep->destroySavedRawImage() ;
- }
- }
-
- if(imagep->isDeleted())
- {
- continue ;
- }
- else if(imagep->isDeletionCandidate())
- {
- imagep->destroyTexture() ;
- continue ;
- }
- else if(imagep->isInactive())
- {
- if(reset_timer)
- {
- imagep->getLastReferencedTimer()->reset();
- }
- else if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
- {
- imagep->setDeletionCandidate() ;
- }
- continue ;
- }
- else
- {
- imagep->getLastReferencedTimer()->reset();
-
- //reset texture state.
- imagep->setInactive() ;
- }
- }
+ F32 lazy_flush_timeout = 30.f; // stop decoding
+ F32 max_inactive_time = 20.f; // actually delete
+ S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference
- if (!imagep->isInImageList())
- {
- continue;
- }
- if(imagep->isInFastCacheList())
- {
- continue; //wait for loading from the fast cache.
- }
+ //
+ // Flush formatted images using a lazy flush
+ //
+ S32 num_refs = imagep->getNumRefs();
+ if (num_refs == min_refs)
+ {
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > lazy_flush_timeout)
+ {
+ // Remove the unused image from the image list
+ deleteImage(imagep);
+ imagep = NULL; // should destroy the image
+ }
+ return;
+ }
+ else
+ {
+ if (imagep->hasSavedRawImage())
+ {
+ if (imagep->getElapsedLastReferencedSavedRawImageTime() > max_inactive_time)
+ {
+ imagep->destroySavedRawImage();
+ }
+ }
- imagep->processTextureStats();
- F32 old_priority = imagep->getDecodePriority();
- F32 old_priority_test = llmax(old_priority, 0.0f);
- F32 decode_priority = imagep->calcDecodePriority();
- F32 decode_priority_test = llmax(decode_priority, 0.0f);
- // Ignore < 20% difference
- if ((decode_priority_test < old_priority_test * .8f) ||
- (decode_priority_test > old_priority_test * 1.25f))
- {
- mImageList.erase(imagep) ;
- imagep->setDecodePriority(decode_priority);
- mImageList.insert(imagep);
- }
- }
- }
+ if (imagep->isDeleted())
+ {
+ return;
+ }
+ else if (imagep->isDeletionCandidate())
+ {
+ imagep->destroyTexture();
+ return;
+ }
+ else if (imagep->isInactive())
+ {
+ if (imagep->getLastReferencedTimer()->getElapsedTimeF32() > max_inactive_time)
+ {
+ imagep->setDeletionCandidate();
+ }
+ return;
+ }
+ else
+ {
+ imagep->getLastReferencedTimer()->reset();
+
+ //reset texture state.
+ imagep->setInactive();
+ }
+ }
+
+ if (!imagep->isInImageList())
+ {
+ return;
+ }
+ if (imagep->isInFastCacheList())
+ {
+ return; //wait for loading from the fast cache.
+ }
+
+ imagep->processTextureStats();
}
void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level)
@@ -999,46 +1012,11 @@ void LLViewerTextureList::setDebugFetching(LLViewerFetchedTexture* tex, S32 debu
}
const F32 DEBUG_PRIORITY = 100000.f;
- F32 old_priority_test = llmax(tex->getDecodePriority(), 0.0f);
- F32 decode_priority_test = DEBUG_PRIORITY;
-
- // Ignore < 20% difference
- if ((decode_priority_test < old_priority_test * .8f) ||
- (decode_priority_test > old_priority_test * 1.25f))
- {
- removeImageFromList(tex);
- tex->setDecodePriority(decode_priority_test);
- addImageToList(tex);
- }
+ removeImageFromList(tex);
+ tex->mMaxVirtualSize = DEBUG_PRIORITY;
+ addImageToList(tex);
}
-/*
- static U8 get_image_type(LLViewerFetchedTexture* imagep, LLHost target_host)
- {
- // Having a target host implies this is a baked image. I don't
- // believe that boost level has been set at this point. JC
- U8 type_from_host = (target_host.isOk()
- ? LLImageBase::TYPE_AVATAR_BAKE
- : LLImageBase::TYPE_NORMAL);
- S32 boost_level = imagep->getBoostLevel();
- U8 type_from_boost = ( (boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED
- || boost_level == LLViewerFetchedTexture::BOOST_AVATAR_BAKED_SELF)
- ? LLImageBase::TYPE_AVATAR_BAKE
- : LLImageBase::TYPE_NORMAL);
- if (type_from_host == LLImageBase::TYPE_NORMAL
- && type_from_boost == LLImageBase::TYPE_AVATAR_BAKE)
- {
- LL_WARNS() << "TAT: get_image_type() type_from_host doesn't match type_from_boost"
- << " host " << target_host
- << " boost " << imagep->getBoostLevel()
- << " imageid " << imagep->getID()
- << LL_ENDL;
- imagep->dump();
- }
- return type_from_host;
- }
- */
-
F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
@@ -1059,10 +1037,11 @@ F32 LLViewerTextureList::updateImagesCreateTextures(F32 max_time)
LLViewerFetchedTexture *imagep = *curiter;
imagep->createTexture();
imagep->postCreateTexture();
- if (create_timer.getElapsedTimeF32() > max_time)
- {
- break;
- }
+
+ if (create_timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
}
mCreateTextureList.erase(mCreateTextureList.begin(), enditer);
return create_timer.getElapsedTimeF32();
@@ -1090,10 +1069,6 @@ F32 LLViewerTextureList::updateImagesLoadingFastCache(F32 max_time)
enditer = iter;
LLViewerFetchedTexture *imagep = *curiter;
imagep->loadFromFastCache();
- if (timer.getElapsedTimeF32() > max_time)
- {
- break;
- }
}
mFastCacheList.erase(mFastCacheList.begin(), enditer);
return timer.getElapsedTimeF32();
@@ -1112,8 +1087,7 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
}
imagep->processTextureStats();
- F32 decode_priority = LLViewerFetchedTexture::maxDecodePriority() ;
- imagep->setDecodePriority(decode_priority);
+ imagep->sMaxVirtualSize = LLViewerFetchedTexture::sMaxVirtualSize;
addImageToList(imagep);
return ;
@@ -1122,77 +1096,65 @@ void LLViewerTextureList::forceImmediateUpdate(LLViewerFetchedTexture* imagep)
F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- LLTimer image_op_timer;
-
- // Update fetch for N images each frame
- static const S32 MAX_HIGH_PRIO_COUNT = gSavedSettings.getS32("TextureFetchUpdateHighPriority"); // default: 32
- static const S32 MAX_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMaxMediumPriority"); // default: 256
- static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinMediumPriority"); // default: 32
- static const F32 MIN_PRIORITY_THRESHOLD = gSavedSettings.getF32("TextureFetchUpdatePriorityThreshold"); // default: 0.0
- static const bool SKIP_LOW_PRIO = gSavedSettings.getBOOL("TextureFetchUpdateSkipLowPriority"); // default: false
-
- size_t max_priority_count = llmin((S32) (MAX_HIGH_PRIO_COUNT*MAX_HIGH_PRIO_COUNT*gFrameIntervalSeconds.value())+1, MAX_HIGH_PRIO_COUNT);
- max_priority_count = llmin(max_priority_count, mImageList.size());
-
- size_t total_update_count = mUUIDMap.size();
- size_t max_update_count = llmin((S32) (MAX_UPDATE_COUNT*MAX_UPDATE_COUNT*gFrameIntervalSeconds.value())+1, MAX_UPDATE_COUNT);
- max_update_count = llmin(max_update_count, total_update_count);
-
- // MAX_HIGH_PRIO_COUNT high priority entries
- typedef std::vector<LLViewerFetchedTexture*> entries_list_t;
- entries_list_t entries;
- size_t update_counter = max_priority_count;
- image_priority_list_t::iterator iter1 = mImageList.begin();
- while(update_counter > 0)
- {
- entries.push_back(*iter1);
-
- ++iter1;
- update_counter--;
- }
-
- // MAX_UPDATE_COUNT cycled entries
- update_counter = max_update_count;
- if(update_counter > 0)
- {
- uuid_map_t::iterator iter2 = mUUIDMap.upper_bound(mLastFetchKey);
- while ((update_counter > 0) && (total_update_count > 0))
- {
- if (iter2 == mUUIDMap.end())
- {
- iter2 = mUUIDMap.begin();
- }
- LLViewerFetchedTexture* imagep = iter2->second;
- // Skip the textures where there's really nothing to do so to give some times to others. Also skip the texture if it's already in the high prio set.
- if (!SKIP_LOW_PRIO || (SKIP_LOW_PRIO && ((imagep->getDecodePriority() > MIN_PRIORITY_THRESHOLD) || imagep->hasFetcher())))
+ typedef std::vector<LLPointer<LLViewerFetchedTexture> > entries_list_t;
+ entries_list_t entries;
+
+ // update N textures at beginning of mImageList
+ U32 update_count = 0;
+ static const S32 MIN_UPDATE_COUNT = gSavedSettings.getS32("TextureFetchUpdateMinCount"); // default: 32
+ // WIP -- dumb code here
+ //update MIN_UPDATE_COUNT or 5% of other textures, whichever is greater
+ update_count = llmax((U32) MIN_UPDATE_COUNT, (U32) mUUIDMap.size()/20);
+ update_count = llmin(update_count, (U32) mUUIDMap.size());
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("vtluift - copy");
+
+ // copy entries out of UUID map for updating
+ entries.reserve(update_count);
+ uuid_map_t::iterator iter = mUUIDMap.upper_bound(mLastUpdateKey);
+ while (update_count-- > 0)
+ {
+ if (iter == mUUIDMap.end())
+ {
+ iter = mUUIDMap.begin();
+ }
+
+ if (iter->second->getGLTexture())
{
- entries.push_back(imagep);
- update_counter--;
+ entries.push_back(iter->second);
}
+ ++iter;
+ }
+ }
- iter2++;
- total_update_count--;
- }
- }
+ LLTimer timer;
- size_t min_update_count = llmin(MIN_UPDATE_COUNT,(S32)(entries.size()-max_priority_count));
- S32 min_count = max_priority_count + min_update_count;
- for (entries_list_t::iterator iter3 = entries.begin();
- iter3 != entries.end(); )
- {
- LLViewerFetchedTexture* imagep = *iter3++;
- imagep->updateFetch();
+ LLPointer<LLViewerTexture> last_imagep = nullptr;
- if (min_count <= min_update_count)
- {
- mLastFetchKey = LLTextureKey(imagep->getID(), (ETexListType)imagep->getTextureListType());
- }
- if ((min_count-- <= 0) && (image_op_timer.getElapsedTimeF32() > max_time))
- {
- break;
- }
- }
- return image_op_timer.getElapsedTimeF32();
+ for (auto& imagep : entries)
+ {
+ if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating)
+
+ {
+ updateImageDecodePriority(imagep);
+ imagep->updateFetch();
+ }
+
+ last_imagep = imagep;
+
+ if (timer.getElapsedTimeF32() > max_time)
+ {
+ break;
+ }
+ }
+
+ if (last_imagep)
+ {
+ mLastUpdateKey = LLTextureKey(last_imagep->getID(), (ETexListType)last_imagep->getTextureListType());
+ }
+
+ return timer.getElapsedTimeF32();
}
void LLViewerTextureList::updateImagesUpdateStats()
@@ -1235,8 +1197,6 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
{
LLViewerFetchedTexture* imagep = *iter;
imagep->processTextureStats();
- F32 decode_priority = imagep->calcDecodePriority();
- imagep->setDecodePriority(decode_priority);
addImageToList(imagep);
}
image_list.clear();
@@ -1248,7 +1208,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
LLViewerFetchedTexture* imagep = *iter++;
imagep->updateFetch();
}
- std::shared_ptr<LL::WorkQueue> main_queue = LLImageGLThread::sEnabled ? LL::WorkQueue::getInstance("mainloop") : NULL;
+ std::shared_ptr<LL::WorkQueue> main_queue = LLImageGLThread::sEnabledTextures ? LL::WorkQueue::getInstance("mainloop") : NULL;
// Run threads
S32 fetch_pending = 0;
while (1)
@@ -1257,7 +1217,7 @@ void LLViewerTextureList::decodeAllImages(F32 max_time)
LLAppViewer::instance()->getImageDecodeThread()->update(1); // unpauses the image thread
fetch_pending = LLAppViewer::instance()->getTextureFetch()->update(1); // unpauses the texture fetch thread
- if (LLImageGLThread::sEnabled)
+ if (LLImageGLThread::sEnabledTextures)
{
main_queue->runFor(std::chrono::milliseconds(1));
fetch_pending += main_queue->size();
@@ -1394,7 +1354,7 @@ BOOL LLViewerTextureList::createUploadFile(const std::string& filename,
}
// note: modifies the argument raw_image!!!!
-LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_square)
+LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImageRaw> raw_image, const S32 max_image_dimentions, bool force_square, bool force_lossless)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
if (force_square)
@@ -1410,9 +1370,12 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
}
LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C();
- if (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
- (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF))
- compressedImage->setReversible(TRUE);
+ if (force_lossless ||
+ (gSavedSettings.getBOOL("LosslessJ2CUpload") &&
+ (raw_image->getWidth() * raw_image->getHeight() <= LL_IMAGE_REZ_LOSSLESS_CUTOFF * LL_IMAGE_REZ_LOSSLESS_CUTOFF)))
+ {
+ compressedImage->setReversible(TRUE);
+ }
if (gSavedSettings.getBOOL("Jpeg2000AdvancedCompression"))
@@ -1437,156 +1400,6 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
return compressedImage;
}
-// Returns min setting for TextureMemory (in MB)
-S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
- //min texture mem sets to 64M if total physical mem is more than 1.5GB
- return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
-}
-
-//static
-// Returns max setting for TextureMemory (in MB)
-S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, float mem_multiplier)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- S32Megabytes max_texmem;
- if (gGLManager.mVRAM != 0)
- {
- // Treat any card with < 32 MB (shudder) as having 32 MB
- // - it's going to be swapping constantly regardless
- S32Megabytes max_vram(gGLManager.mVRAM);
-
- if(gGLManager.mIsAMD)
- {
- //shrink the availabe vram for ATI cards because some of them do not handel texture swapping well.
- max_vram = max_vram * 0.75f;
- }
-
- max_vram = llmax(max_vram, getMinVideoRamSetting());
- max_texmem = max_vram;
- if (!get_recommended)
- max_texmem *= 2;
- }
- else
- {
- if (!get_recommended)
- {
- max_texmem = (S32Megabytes)512;
- }
- else if (gSavedSettings.getBOOL("NoHardwareProbe")) //did not do hardware detection at startup
- {
- max_texmem = (S32Megabytes)512;
- }
- else
- {
- max_texmem = (S32Megabytes)128;
- }
- }
-
- S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
- //LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL;
- if (get_recommended)
- max_texmem = llmin(max_texmem, system_ram/2);
- else
- max_texmem = llmin(max_texmem, system_ram);
-
- // limit the texture memory to a multiple of the default if we've found some cards to behave poorly otherwise
- max_texmem = llmin(max_texmem, (S32Megabytes) (mem_multiplier * max_texmem));
-
- max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), gMaxVideoRam);
-
- return max_texmem;
-}
-
-bool LLViewerTextureList::isPrioRequestsFetched()
-{
- static LLCachedControl<F32> prio_threshold(gSavedSettings, "TextureFetchUpdatePriorityThreshold", 0.0f);
- static LLCachedControl<F32> fetching_textures_threshold(gSavedSettings, "TextureListFetchingThreshold", 0.97f);
- S32 fetching_tex_count = 0;
- S32 tex_count_threshold = gTextureList.mImageList.size() * (1 - fetching_textures_threshold);
-
- for (LLViewerTextureList::image_priority_list_t::iterator iter = gTextureList.mImageList.begin();
- iter != gTextureList.mImageList.end(); )
- {
- LLPointer<LLViewerFetchedTexture> imagep = *iter++;
- if (imagep->getDecodePriority() > prio_threshold)
- {
- if (imagep->hasFetcher() || imagep->isFetching())
- {
- fetching_tex_count++;
- if (fetching_tex_count >= tex_count_threshold)
- {
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-const S32Megabytes VIDEO_CARD_FRAMEBUFFER_MEM(12);
-const S32Megabytes MIN_MEM_FOR_NON_TEXTURE(512);
-void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
- // Initialize the image pipeline VRAM settings
- S32Megabytes cur_mem(gSavedSettings.getS32("TextureMemory"));
- F32 mem_multiplier = gSavedSettings.getF32("RenderTextureMemoryMultiple");
- S32Megabytes default_mem = getMaxVideoRamSetting(true, mem_multiplier); // recommended default
- if (mem == (S32Bytes)0)
- {
- mem = cur_mem > (S32Bytes)0 ? cur_mem : default_mem;
- }
- else if (mem < (S32Bytes)0)
- {
- mem = default_mem;
- }
-
- mem = llclamp(mem, getMinVideoRamSetting(), getMaxVideoRamSetting(false, mem_multiplier));
- if (mem != cur_mem)
- {
- gSavedSettings.setS32("TextureMemory", mem.value());
- return; //listener will re-enter this function
- }
-
- if (gGLManager.mVRAM == 0)
- {
- LL_WARNS() << "VRAM amount not detected, defaulting to " << mem << " MB" << LL_ENDL;
- }
-
- // TODO: set available resident texture mem based on use by other subsystems
- // currently max(12MB, VRAM/4) assumed...
-
- S32Megabytes vb_mem = mem;
- S32Megabytes fb_mem = llmax(VIDEO_CARD_FRAMEBUFFER_MEM, vb_mem/4);
- mMaxResidentTexMemInMegaBytes = (vb_mem - fb_mem) ; //in MB
-
- mMaxTotalTextureMemInMegaBytes = mMaxResidentTexMemInMegaBytes * 2;
- if (mMaxResidentTexMemInMegaBytes > (S32Megabytes)640)
- {
- mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes / 4);
- }
-
- //system mem
- S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
-
- //minimum memory reserved for non-texture use.
- //if system_raw >= 1GB, reserve at least 512MB for non-texture use;
- //otherwise reserve half of the system_ram for non-texture use.
- S32Megabytes min_non_texture_mem = llmin(system_ram / 2, MIN_MEM_FOR_NON_TEXTURE) ;
-
- if (mMaxTotalTextureMemInMegaBytes > system_ram - min_non_texture_mem)
- {
- mMaxTotalTextureMemInMegaBytes = system_ram - min_non_texture_mem ;
- }
-
- LL_INFOS() << "Total Video Memory set to: " << vb_mem << " MB" << LL_ENDL;
- LL_INFOS() << "Available Texture Memory set to: " << (vb_mem - fb_mem) << " MB" << LL_ENDL;
-}
-
///////////////////////////////////////////////////////////////////////////////
// We've been that the asset server does not contain the requested image id.
@@ -1699,8 +1512,9 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
LLUIImagePtr new_imagep = new LLUIImage(name, imagep);
new_imagep->setScaleStyle(scale_style);
- if (imagep->getBoostLevel() != LLGLTexture::BOOST_ICON &&
- imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW)
+ if (imagep->getBoostLevel() != LLGLTexture::BOOST_ICON
+ && imagep->getBoostLevel() != LLGLTexture::BOOST_THUMBNAIL
+ && imagep->getBoostLevel() != LLGLTexture::BOOST_PREVIEW)
{
// Don't add downloadable content into this list
// all UI images are non-deletable and list does not support deletion
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 82dec6b329..e8dd96daee 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -1,10 +1,10 @@
/**
- * @file llviewertexturelinumimagest.h
+ * @file llviewertexturelist.h
* @brief Object for managing the list of images within a region
*
- * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
* Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
+ * Copyright (C) 2022, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -104,7 +104,8 @@ public:
bool force_square = false);
static LLPointer<LLImageJ2C> convertToUploadFile(LLPointer<LLImageRaw> raw_image,
const S32 max_image_dimentions = LLViewerFetchedTexture::MAX_IMAGE_SIZE_DEFAULT,
- bool force_square = false);
+ bool force_square = false,
+ bool force_lossless = false);
static void processImageNotInDatabase( LLMessageSystem *msg, void **user_data );
public:
@@ -133,12 +134,9 @@ public:
void handleIRCallback(void **data, const S32 number);
- S32Megabytes getMaxResidentTexMem() const { return mMaxResidentTexMemInMegaBytes; }
- S32Megabytes getMaxTotalTextureMem() const { return mMaxTotalTextureMemInMegaBytes;}
S32 getNumImages() { return mImageList.size(); }
- void updateMaxResidentTexMem(S32Megabytes mem);
-
+ // Local UI images
// Local UI images
void doPreloadImages();
// Network images. Needs caps and cache to work
@@ -147,13 +145,12 @@ public:
void clearFetchingRequests();
void setDebugFetching(LLViewerFetchedTexture* tex, S32 debug_level);
- static S32Megabytes getMinVideoRamSetting();
- static S32Megabytes getMaxVideoRamSetting(bool get_recommended, float mem_multiplier);
-
- static bool isPrioRequestsFetched();
-
private:
- void updateImagesDecodePriorities();
+ // do some book keeping on the specified texture
+ // - updates decode priority
+ // - updates desired discard level
+ // - cleans up textures that haven't been referenced in awhile
+ void updateImageDecodePriority(LLViewerFetchedTexture* imagep);
F32 updateImagesCreateTextures(F32 max_time);
F32 updateImagesFetchTextures(F32 max_time);
void updateImagesUpdateStats();
@@ -226,17 +223,14 @@ private:
typedef std::map< LLTextureKey, LLPointer<LLViewerFetchedTexture> > uuid_map_t;
uuid_map_t mUUIDMap;
LLTextureKey mLastUpdateKey;
- LLTextureKey mLastFetchKey;
- typedef std::set<LLPointer<LLViewerFetchedTexture>, LLViewerFetchedTexture::Compare> image_priority_list_t;
+ typedef std::set < LLPointer<LLViewerFetchedTexture> > image_priority_list_t;
image_priority_list_t mImageList;
// simply holds on to LLViewerFetchedTexture references to stop them from being purged too soon
std::set<LLPointer<LLViewerFetchedTexture> > mImagePreloads;
BOOL mInitialized ;
- S32Megabytes mMaxResidentTexMemInMegaBytes;
- S32Megabytes mMaxTotalTextureMemInMegaBytes;
LLFrameTimer mForceDecodeTimer;
private:
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index e8fd74b37b..ba2b6e1c7c 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -228,6 +228,7 @@ extern BOOL gDebugClicks;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDepthDirty;
extern BOOL gResizeScreenTexture;
+extern BOOL gCubeSnapshot;
LLViewerWindow *gViewerWindow = NULL;
@@ -495,24 +496,12 @@ public:
if (gSavedSettings.getBOOL("DebugShowTime"))
{
- {
- const U32 y_inc2 = 15;
- LLFrameTimer& timer = gTextureTimer;
- F32 time = timer.getElapsedTimeF32();
- S32 hours = (S32)(time / (60*60));
- S32 mins = (S32)((time - hours*(60*60)) / 60);
- S32 secs = (S32)((time - hours*(60*60) - mins*60));
- addText(xpos, ypos, llformat("Texture: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc2;
- }
-
- {
F32 time = gFrameTimeSeconds;
S32 hours = (S32)(time / (60*60));
S32 mins = (S32)((time - hours*(60*60)) / 60);
S32 secs = (S32)((time - hours*(60*60) - mins*60));
addText(xpos, ypos, llformat("Time: %d:%02d:%02d", hours,mins,secs)); ypos += y_inc;
}
- }
if (gSavedSettings.getBOOL("DebugShowMemory"))
{
@@ -611,29 +600,6 @@ public:
{
LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording();
- if (gGLManager.mHasATIMemInfo)
- {
- S32 meminfo[4];
- glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
-
- addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
-
- if (gGLManager.mHasVertexBufferObject)
- {
- glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo);
- addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f));
- ypos += y_inc;
- }
- }
- else if (gGLManager.mHasNVXMemInfo)
- {
- S32 free_memory;
- glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory);
- addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f));
- ypos += y_inc;
- }
-
//show streaming cost/triangle count of known prims in current region OR selection
{
F32 cost = 0.f;
@@ -693,24 +659,6 @@ public:
}
- addText(xpos, ypos, llformat("%d MB Index Data (%d MB Pooled, %d KIndices)", LLVertexBuffer::sAllocatedIndexBytes/(1024*1024), LLVBOPool::sIndexBytesPooled/(1024*1024), LLVertexBuffer::sIndexCount/1024));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%d MB Vertex Data (%d MB Pooled, %d KVerts)", LLVertexBuffer::sAllocatedBytes/(1024*1024), LLVBOPool::sBytesPooled/(1024*1024), LLVertexBuffer::sVertexCount/1024));
- ypos += y_inc;
-
- addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount));
- ypos += y_inc;
-
- 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;
@@ -785,9 +733,7 @@ public:
ypos += y_inc;
}
- LLVertexBuffer::sBindCount = LLImageGL::sBindCount =
- LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount =
- gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
+ gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0;
}
if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo"))
{
@@ -1915,6 +1861,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
U32 fsaa_samples)
*/
// create window
+
+ U32 max_core_count = gSavedSettings.getU32("EmulateCoreCount");
+ U32 max_vram = gSavedSettings.getU32("RenderMaxVRAMBudget");
+ F32 max_gl_version = gSavedSettings.getF32("RenderMaxOpenGLVersion");
+
mWindow = LLWindowManager::createWindow(this,
p.title, p.name, p.x, p.y, p.width, p.height, 0,
p.fullscreen,
@@ -1922,7 +1873,10 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.getBOOL("RenderVSyncEnable"),
!gHeadlessClient,
p.ignore_pixel_depth,
- gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
+ 0,
+ max_core_count,
+ max_vram,
+ max_gl_version); //don't use window level anti-aliasing
if (NULL == mWindow)
{
@@ -2001,12 +1955,7 @@ LLViewerWindow::LLViewerWindow(const Params& p)
LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL;
// Initialize OpenGL Renderer
- if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") ||
- !gGLManager.mHasVertexBufferObject)
- {
- gSavedSettings.setBOOL("RenderVBOEnable", FALSE);
- }
- LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable"));
+ LLVertexBuffer::initClass(mWindow);
LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ;
gGL.init(true);
@@ -2019,11 +1968,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE);
}
- if (!gGLManager.mHasDepthClamp)
- {
- LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL;
- }
-
// If we crashed while initializng GL stuff last time, disable certain features
if (gSavedSettings.getBOOL("RenderInitError"))
{
@@ -2033,8 +1977,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
}
// Init the image list. Must happen after GL is initialized and before the images that
- // LLViewerWindow needs are requested.
- LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreaded"));
+ // LLViewerWindow needs are requested, as well as before LLViewerMedia starts updating images.
+ LLImageGL::initClass(mWindow, LLViewerTexture::MAX_GL_IMAGE_CATEGORY, false, gSavedSettings.getBOOL("RenderGLMultiThreadedTextures"), gSavedSettings.getBOOL("RenderGLMultiThreadedMedia"));
gTextureList.init();
LLViewerTextureManager::init() ;
gBumpImageList.init();
@@ -2684,10 +2628,10 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
void LLViewerWindow::drawDebugText()
{
+ gUIProgram.bind();
gGL.color4f(1,1,1,1);
gGL.pushMatrix();
gGL.pushUIMatrix();
- gUIProgram.bind();
{
// scale view by UI global scale factor and aspect ratio correction factor
gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
@@ -2744,6 +2688,7 @@ void LLViewerWindow::draw()
// No translation needed, this view is glued to 0,0
gUIProgram.bind();
+ gGL.color4f(1, 1, 1, 1);
gGL.pushMatrix();
LLUI::pushMatrix();
@@ -3399,7 +3344,7 @@ void LLViewerWindow::updateUI()
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST))
{
gDebugRaycastFaceHit = -1;
- gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE,
+ gDebugRaycastObject = cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, FALSE,
&gDebugRaycastFaceHit,
&gDebugRaycastIntersection,
&gDebugRaycastTexCoord,
@@ -4274,17 +4219,18 @@ void LLViewerWindow::pickAsync( S32 x,
void (*callback)(const LLPickInfo& info),
BOOL pick_transparent,
BOOL pick_rigged,
- BOOL pick_unselectable)
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probes)
{
- BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
- {
- // build mode allows interaction with all transparent objects
- // "Show Debug Alpha" means no object actually transparent
- pick_transparent = TRUE;
- }
+ // "Show Debug Alpha" means no object actually transparent
+ BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
+ if (LLDrawPoolAlpha::sShowDebugAlpha
+ || (in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")))
+ {
+ pick_transparent = TRUE;
+ }
- LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback);
+ LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, pick_reflection_probes, pick_unselectable, TRUE, callback);
schedulePick(pick_info);
}
@@ -4340,10 +4286,10 @@ void LLViewerWindow::returnEmptyPicks()
}
// Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable, BOOL pick_reflection_probe)
{
BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
- if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
+ if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha)
{
// build mode allows interaction with all transparent objects
// "Show Debug Alpha" means no object actually transparent
@@ -4352,7 +4298,7 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transp
// shortcut queueing in mPicks and just update mLastPick in place
MASK key_mask = gKeyboard->currentMask(TRUE);
- mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, TRUE, FALSE, NULL);
+ mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_rigged, pick_particle, pick_reflection_probe, TRUE, FALSE, NULL);
mLastPick.fetchResults();
return mLastPick;
@@ -4389,6 +4335,8 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
S32 this_face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
+ BOOL pick_reflection_probe,
S32* face_hit,
LLVector4a *intersection,
LLVector2 *uv,
@@ -4459,7 +4407,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
{
if (this_object->isHUDAttachment()) // is a HUD object?
{
- if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged,
+ if (this_object->lineSegmentIntersect(mh_start, mh_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4467,7 +4415,8 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
}
else // is a world object
{
- if (this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged,
+ if ((pick_reflection_probe || !this_object->isReflectionProbe())
+ && this_object->lineSegmentIntersect(mw_start, mw_end, this_face, pick_transparent, pick_rigged, pick_unselectable,
face_hit, intersection, uv, normal, tangent))
{
found = this_object;
@@ -4481,7 +4430,7 @@ LLViewerObject* LLViewerWindow::cursorIntersect(S32 mouse_x, S32 mouse_y, F32 de
if (!found) // if not found in HUD, look in world:
{
- found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged,
+ found = gPipeline.lineSegmentIntersectInWorld(mw_start, mw_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe,
face_hit, intersection, uv, normal, tangent);
if (found && !pick_transparent)
{
@@ -4739,8 +4688,8 @@ void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
else
pick_type = LLFilePicker::FFSAVE_ALL;
- (new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
- boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
+ LLFilePickerReplyThread::startPicker(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
+ boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb));
}
else
{
@@ -4954,7 +4903,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
// PRE SNAPSHOT
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
// Hide all the UI widgets first and draw a frame
@@ -5006,10 +4955,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
(image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
{
U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA;
- if (scratch_space.allocate(image_width, image_height, color_fmt, true, true))
+ if (scratch_space.allocate(image_width, image_height, color_fmt, true))
{
- original_width = gPipeline.mDeferredScreen.getWidth();
- original_height = gPipeline.mDeferredScreen.getHeight();
+ original_width = gPipeline.mRT->deferredScreen.getWidth();
+ original_height = gPipeline.mRT->deferredScreen.getHeight();
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
@@ -5088,8 +5037,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
F32 depth_conversion_factor_1 = (LLViewerCamera::getInstance()->getFar() + LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
F32 depth_conversion_factor_2 = (LLViewerCamera::getInstance()->getFar() - LLViewerCamera::getInstance()->getNear()) / (2.f * LLViewerCamera::getInstance()->getFar() * LLViewerCamera::getInstance()->getNear());
- gObjectList.generatePickList(*LLViewerCamera::getInstance());
-
// Subimages are in fact partial rendering of the final view. This happens when the final view is bigger than the screen.
// In most common cases, scale_factor is 1 and there's no more than 1 iteration on x and y
for (int subimage_y = 0; subimage_y < scale_factor; ++subimage_y)
@@ -5252,9 +5199,10 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
gDisplaySwapBuffers = FALSE;
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
setCursor(UI_CURSOR_WAIT);
BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
@@ -5263,17 +5211,20 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
}
- LLPipeline::sShowHUDAttachments = FALSE;
+ BOOL hide_hud = LLPipeline::sShowHUDAttachments;
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = FALSE;
+ }
+
LLRect window_rect = getWorldViewRectRaw();
- S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
- S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mDeferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
+ S32 original_width = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getWidth() : gViewerWindow->getWorldViewWidthRaw();
+ S32 original_height = LLPipeline::sRenderDeferred ? gPipeline.mRT->deferredScreen.getHeight() : gViewerWindow->getWorldViewHeightRaw();
LLRenderTarget scratch_space;
U32 color_fmt = GL_RGBA;
- const bool use_depth_buffer = true;
- const bool use_stencil_buffer = true;
- if (scratch_space.allocate(image_width, image_height, color_fmt, use_depth_buffer, use_stencil_buffer))
+ if (scratch_space.allocate(image_width, image_height, color_fmt, true))
{
if (gPipeline.allocateScreenBuffer(image_width, image_height))
{
@@ -5335,7 +5286,10 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
}
}
- LLPipeline::sShowHUDAttachments = TRUE;
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = TRUE;
+ }
setCursor(UI_CURSOR_ARROW);
@@ -5348,6 +5302,157 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_
return true;
}
+void display_cube_face();
+
+BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render)
+{
+ // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_APP;
+ LL_PROFILE_GPU_ZONE("cubeSnapshot");
+ llassert(LLPipeline::sRenderDeferred);
+ llassert(!gCubeSnapshot); //assert a snapshot isn't already in progress
+
+ U32 res = gPipeline.mRT->deferredScreen.getWidth();
+
+ //llassert(res <= gPipeline.mRT->deferredScreen.getWidth());
+ //llassert(res <= gPipeline.mRT->deferredScreen.getHeight());
+
+ // save current view/camera settings so we can restore them afterwards
+ S32 old_occlusion = LLPipeline::sUseOcclusion;
+
+ // set new parameters specific to the 360 requirements
+ LLPipeline::sUseOcclusion = 0;
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ LLViewerCamera saved_camera = LLViewerCamera::instance();
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_mod = get_current_modelview();
+
+ // camera constants for the square, cube map capture image
+ camera->setAspect(1.0); // must set aspect ratio first to avoid undesirable clamping of vertical FoV
+ camera->setViewNoBroadcast(F_PI_BY_TWO);
+ camera->yaw(0.0);
+ camera->setOrigin(origin);
+ camera->setNear(near_clip);
+
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // stencil buffer is deprecated | GL_STENCIL_BUFFER_BIT);
+
+ U32 dynamic_render_types[] = {
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_CONTROL_AV,
+ LLPipeline::RENDER_TYPE_PARTICLES
+ };
+ constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32);
+ bool prev_dynamic_render_type[dynamic_render_type_count];
+
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ prev_dynamic_render_type[i] = gPipeline.hasRenderType(dynamic_render_types[i]);
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE;
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+
+ BOOL hide_hud = LLPipeline::sShowHUDAttachments;
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = FALSE;
+ }
+ LLRect window_rect = getWorldViewRectRaw();
+
+ mWorldViewRectRaw.set(0, res, res, 0);
+
+ // these are the 6 directions we will point the camera, see LLCubeMapArray::sTargets
+ LLVector3 look_dirs[6] = {
+ LLVector3(1, 0, 0),
+ LLVector3(-1, 0, 0),
+ LLVector3(0, 1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1)
+ };
+
+ LLVector3 look_upvecs[6] = {
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0),
+ LLVector3(0, 0, 1),
+ LLVector3(0, 0, -1),
+ LLVector3(0, -1, 0),
+ LLVector3(0, -1, 0)
+ };
+
+ // for each of six sides of cubemap
+ //for (int i = 0; i < 6; ++i)
+ int i = face;
+ {
+ // set up camera to look in each direction
+ camera->lookDir(look_dirs[i], look_upvecs[i]);
+
+ // turning this flag off here prohibits the screen swap
+ // to present the new page to the viewer - this stops
+ // the black flash in between captures when the number
+ // of render passes is more than 1. We need to also
+ // set it here because code in LLViewerDisplay resets
+ // it to TRUE each time.
+ gDisplaySwapBuffers = FALSE;
+
+ // actually render the scene
+ gCubeSnapshot = TRUE;
+ display_cube_face();
+ gCubeSnapshot = FALSE;
+ }
+
+ gDisplaySwapBuffers = TRUE;
+
+ if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ if (prev_draw_ui != false)
+ {
+ LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI);
+ }
+ }
+
+ if (!dynamic_render)
+ {
+ for (int i = 0; i < dynamic_render_type_count; ++i)
+ {
+ if (prev_dynamic_render_type[i])
+ {
+ gPipeline.toggleRenderType(dynamic_render_types[i]);
+ }
+ }
+ }
+
+ if (hide_hud)
+ {
+ LLPipeline::sShowHUDAttachments = TRUE;
+ }
+
+ gPipeline.resetDrawOrders();
+ mWorldViewRectRaw = window_rect;
+
+ // restore original view/camera/avatar settings settings
+ *camera = saved_camera;
+ set_current_modelview(saved_mod);
+ set_current_projection(saved_proj);
+ setup3DViewport();
+ LLPipeline::sUseOcclusion = old_occlusion;
+
+ // ====================================================
+ return true;
+}
+
void LLViewerWindow::destroyWindow()
{
if (mWindow)
@@ -5570,7 +5675,6 @@ void LLViewerWindow::stopGL(BOOL save_state)
// Pause texture decode threads (will get unpaused during main loop)
LLAppViewer::getTextureCache()->pause();
- LLAppViewer::getImageDecodeThread()->pause();
LLAppViewer::getTextureFetch()->pause();
gSky.destroyGL();
@@ -5617,8 +5721,6 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLGLSLShader* shader = *(LLGLSLShader::sInstances.begin());
shader->unload();
}
-
- LL_INFOS() << "Remaining allocated texture memory: " << LLImageGL::sGlobalTextureMemory.value() << " bytes" << LL_ENDL;
}
}
@@ -5644,7 +5746,6 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gSky.restoreGL();
gPipeline.restoreGL();
- LLDrawPoolWater::restoreGL();
LLManipTranslate::restoreGL();
gBumpImageList.restoreGL();
@@ -5987,30 +6088,32 @@ LLPickInfo::LLPickInfo()
{
}
-LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
- MASK keyboard_mask,
- BOOL pick_transparent,
- BOOL pick_rigged,
- BOOL pick_particle,
- BOOL pick_uv_coords,
- BOOL pick_unselectable,
- void (*pick_callback)(const LLPickInfo& pick_info))
- : mMousePt(mouse_pos),
- mKeyMask(keyboard_mask),
- mPickCallback(pick_callback),
- mPickType(PICK_INVALID),
- mWantSurfaceInfo(pick_uv_coords),
- mObjectFace(-1),
- mUVCoords(-1.f, -1.f),
- mSTCoords(-1.f, -1.f),
- mXYCoords(-1, -1),
- mNormal(),
- mTangent(),
- mBinormal(),
- mHUDIcon(NULL),
- mPickTransparent(pick_transparent),
- mPickRigged(pick_rigged),
- mPickParticle(pick_particle),
+LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
+ MASK keyboard_mask,
+ BOOL pick_transparent,
+ BOOL pick_rigged,
+ BOOL pick_particle,
+ BOOL pick_reflection_probe,
+ BOOL pick_uv_coords,
+ BOOL pick_unselectable,
+ void (*pick_callback)(const LLPickInfo& pick_info))
+ : mMousePt(mouse_pos),
+ mKeyMask(keyboard_mask),
+ mPickCallback(pick_callback),
+ mPickType(PICK_INVALID),
+ mWantSurfaceInfo(pick_uv_coords),
+ mObjectFace(-1),
+ mUVCoords(-1.f, -1.f),
+ mSTCoords(-1.f, -1.f),
+ mXYCoords(-1, -1),
+ mNormal(),
+ mTangent(),
+ mBinormal(),
+ mHUDIcon(NULL),
+ mPickTransparent(pick_transparent),
+ mPickRigged(pick_rigged),
+ mPickParticle(pick_particle),
+ mPickReflectionProbe(pick_reflection_probe),
mPickUnselectable(pick_unselectable)
{
}
@@ -6041,7 +6144,7 @@ void LLPickInfo::fetchResults()
}
LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
- NULL, -1, mPickTransparent, mPickRigged, &face_hit,
+ NULL, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe, &face_hit,
&intersection, &uv, &normal, &tangent, &start, &end);
mPickPt = mMousePt;
@@ -6186,7 +6289,7 @@ void LLPickInfo::getSurfaceInfo()
if (objectp)
{
if (gViewerWindow->cursorIntersect(ll_round((F32)mMousePt.mX), ll_round((F32)mMousePt.mY), 1024.f,
- objectp, -1, mPickTransparent, mPickRigged,
+ objectp, -1, mPickTransparent, mPickRigged, mPickUnselectable, mPickReflectionProbe,
&mObjectFace,
&intersection,
&mSTCoords,
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 92905ef21a..6e8a5b2f4e 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -68,6 +68,8 @@ class LLWindowListener;
class LLViewerWindowListener;
class LLVOPartGroup;
class LLPopupView;
+class LLCubeMap;
+class LLCubeMapArray;
#define PICK_HALF_WIDTH 5
#define PICK_DIAMETER (2 * PICK_HALF_WIDTH + 1)
@@ -92,6 +94,7 @@ public:
BOOL pick_transparent,
BOOL pick_rigged,
BOOL pick_particle,
+ BOOL pick_reflection_probe,
BOOL pick_surface_info,
BOOL pick_unselectable,
void (*pick_callback)(const LLPickInfo& pick_info));
@@ -128,6 +131,7 @@ public:
BOOL mPickRigged;
BOOL mPickParticle;
BOOL mPickUnselectable;
+ BOOL mPickReflectionProbe = FALSE;
void getSurfaceInfo();
private:
@@ -362,6 +366,20 @@ public:
BOOL simpleSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, const int num_render_passes);
+
+
+ // take a cubemap snapshot
+ // origin - vantage point to take the snapshot from
+ // cubearray - cubemap array for storing the results
+ // index - cube index in the array to use (cube index, not face-layer)
+ // face - which cube face to update
+ // near_clip - near clip setting to use
+ BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars);
+
+
+ // special implementation of simpleSnapshot for reflection maps
+ BOOL reflectionSnapshot(LLImageRaw* raw, S32 image_width, S32 image_height, const int num_render_passes);
+
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL show_hud, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
@@ -390,8 +408,9 @@ public:
void (*callback)(const LLPickInfo& pick_info),
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
- BOOL pick_unselectable = FALSE);
- LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE);
+ BOOL pick_unselectable = FALSE,
+ BOOL pick_reflection_probes = FALSE);
+ LLPickInfo pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_rigged = FALSE, BOOL pick_particle = FALSE, BOOL pick_unselectable = TRUE, BOOL pick_reflection_probe = FALSE);
LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
LLVector4a* intersection);
@@ -400,6 +419,8 @@ public:
S32 this_face = -1,
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
+ BOOL pick_reflection_probe = TRUE,
S32* face_hit = NULL,
LLVector4a *intersection = NULL,
LLVector2 *uv = NULL,
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index 0e6734f6e0..001fab7755 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -287,7 +287,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ;
if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later.
{
- if (mDetailTextures[i]->getDecodePriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
+ if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage())
{
mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP);
mDetailTextures[i]->forceToRefetchTexture(ddiscard);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a0e5733b18..fee00eb6f4 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1448,7 +1448,7 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
continue;
}
}
- if (vol && vol->isRiggedMesh())
+ if (vol && vol->isRiggedMeshFast())
{
continue;
}
@@ -1794,6 +1794,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1871,7 +1872,7 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
LLDrawable* drawable = attached_object->mDrawable;
if (drawable->isState(LLDrawable::RIGGED))
{ //regenerate octree for rigged attachment
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED);
}
}
}
@@ -1900,6 +1901,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -1930,7 +1932,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
{
LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, face_hit, &local_intersection, tex_coord, normal, tangent))
+ if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, pick_rigged, pick_unselectable, face_hit, &local_intersection, tex_coord, normal, tangent))
{
local_end = local_intersection;
if (intersection)
@@ -2287,7 +2289,7 @@ void LLVOAvatar::restoreMeshData()
}
// force mesh update as LOD might not have changed to trigger this
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
//-----------------------------------------------------------------------------
@@ -2360,15 +2362,15 @@ void LLVOAvatar::updateMeshData()
LLVertexBuffer* buff = facep->getVertexBuffer();
if(!facep->getVertexBuffer())
{
- buff = new LLVertexBufferAvatar();
- if (!buff->allocateBuffer(num_vertices, num_indices, TRUE))
+ buff = new LLVertexBuffer(LLDrawPoolAvatar::VERTEX_DATA_MASK);
+ if (!buff->allocateBuffer(num_vertices, num_indices))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to "
<< num_vertices << " vertices and "
<< num_indices << " indices" << LL_ENDL;
// Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
facep->setSize(1, 3);
- buff->allocateBuffer(1, 3, true);
+ buff->allocateBuffer(1, 3);
memset((U8*) buff->getMappedData(), 0, buff->getSize());
memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
}
@@ -2383,12 +2385,13 @@ void LLVOAvatar::updateMeshData()
}
else
{
- if (!buff->resizeBuffer(num_vertices, num_indices))
- {
+ buff = new LLVertexBuffer(buff->getTypeMask());
+ if (!buff->allocateBuffer(num_vertices, num_indices))
+ {
LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL;
// Attempt to create a dummy triangle (one vertex, 3 indices, all 0)
facep->setSize(1, 3);
- buff->resizeBuffer(1, 3);
+ buff->allocateBuffer(1, 3);
memset((U8*) buff->getMappedData(), 0, buff->getSize());
memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize());
}
@@ -2425,7 +2428,7 @@ void LLVOAvatar::updateMeshData()
}
stop_glerror();
- buff->flush();
+ buff->unmapBuffer();
if(!f_num)
{
@@ -2559,7 +2562,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
return;
}
// record time and refresh "tooSlow" status
- LLPerfStats::RecordAvatarTime T(getID(), LLPerfStats::StatType_t::RENDER_IDLE); // per avatar "idle" time.
updateTooSlow();
static LLCachedControl<bool> disable_all_render_types(gSavedSettings, "DisableAllRenderTypes");
@@ -2570,7 +2572,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
{
idleUpdateNameTag( mLastRootPos );
}
- return;
+ return;
}
// Update should be happening max once per frame.
@@ -2694,6 +2696,10 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, const F64 &time)
if ((LLFrameTimer::getFrameCount() + mID.mData[0]) % compl_upd_freq == 0)
{
+ // DEPRECATED
+ // replace with LLPipeline::profileAvatar?
+ // Avatar profile takes ~ 0.5ms while idleUpdateRenderComplexity takes ~5ms
+ // (both are unacceptably costly)
idleUpdateRenderComplexity();
}
idleUpdateDebugInfo();
@@ -5057,7 +5063,7 @@ U32 LLVOAvatar::renderSkinned()
LLVertexBuffer* vb = face->getVertexBuffer();
if (vb)
{
- vb->flush();
+ vb->unmapBuffer();
}
}
}
@@ -5106,9 +5112,6 @@ U32 LLVOAvatar::renderSkinned()
// render all geometry attached to the skeleton
//--------------------------------------------------------------------
- bool should_alpha_mask = shouldAlphaMask();
- LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
-
BOOL first_pass = TRUE;
if (!LLDrawPoolAvatar::sSkipOpaque)
{
@@ -5158,7 +5161,6 @@ U32 LLVOAvatar::renderSkinned()
if (!LLDrawPoolAvatar::sSkipTransparent || LLPipeline::sImpostorRender)
{
LLGLState blend(GL_BLEND, !mIsDummy);
- LLGLState test(GL_ALPHA_TEST, !mIsDummy);
num_indices += renderTransparent(first_pass);
}
@@ -5297,8 +5299,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
gGL.flush();
}
{
- LLGLEnable test(GL_ALPHA_TEST);
- gGL.flush();
+ gGL.flush();
gGL.color4ubv(color.mV);
gGL.getTexUnit(diffuse_channel)->bind(&mImpostor);
@@ -5687,7 +5688,6 @@ void LLVOAvatar::checkTextureLoading()
}
const F32 SELF_ADDITIONAL_PRI = 0.75f ;
-const F32 ADDITIONAL_PRI = 0.5f;
void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel_area, F32 texel_area_ratio, S32 boost_level)
{
//Note:
@@ -5702,15 +5702,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
mMinPixelArea = llmin(pixel_area, mMinPixelArea);
imagep->addTextureStats(pixel_area / texel_area_ratio);
imagep->setBoostLevel(boost_level);
-
- if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
- {
- imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
- }
- else
- {
- imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
- }
}
//virtual
@@ -7080,6 +7071,7 @@ void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
size.mul(0.5f);
mImpostorPixelArea = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance());
+ mPixelArea = mImpostorPixelArea;
F32 range = mDrawable->mDistanceWRTCamera;
@@ -7580,6 +7572,85 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
}
}
+bool LLVOAvatar::hasPendingAttachedMeshes()
+{
+ for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+ iter != mAttachmentPoints.end();
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ if (attachment)
+ {
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* objectp = attachment_iter->get();
+ if (objectp)
+ {
+ LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+ iter1 != child_list.end(); ++iter1)
+ {
+ LLViewerObject* objectchild = *iter1;
+ if (objectchild && objectchild->getVolume())
+ {
+ const LLUUID& mesh_id = objectchild->getVolume()->getParams().getSculptID();
+ if (mesh_id.isNull())
+ {
+ // No mesh nor skin info needed
+ continue;
+ }
+
+ if (objectchild->getVolume()->isMeshAssetUnavaliable())
+ {
+ // Mesh failed to load, do not expect it
+ continue;
+ }
+
+ if (objectchild->mDrawable)
+ {
+ LLVOVolume* pvobj = objectchild->mDrawable->getVOVolume();
+ if (pvobj)
+ {
+ if (!pvobj->isMesh())
+ {
+ // Not a mesh
+ continue;
+ }
+
+ if (!objectchild->getVolume()->isMeshAssetLoaded())
+ {
+ // Waiting for mesh
+ return true;
+ }
+
+ const LLMeshSkinInfo* skin_data = pvobj->getSkinInfo();
+ if (skin_data)
+ {
+ // Skin info present, done
+ continue;
+ }
+
+ if (pvobj->isSkinInfoUnavaliable())
+ {
+ // Load failed or info not present, don't expect it
+ continue;
+ }
+ }
+
+ // objectchild is not ready
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+}
+
//-----------------------------------------------------------------------------
// detachObject()
//-----------------------------------------------------------------------------
@@ -8156,6 +8227,7 @@ BOOL LLVOAvatar::updateIsFullyLoaded()
|| (mLoadedCallbackTextures < mCallbackTextureList.size() && mLastTexCallbackAddedTime.getElapsedTimeF32() < MAX_TEXTURE_WAIT_TIME_SEC)
|| !mPendingAttachment.empty()
|| (rez_status < 3 && !isFullyBaked())
+ || hasPendingAttachedMeshes()
);
}
updateRezzedStatusTimers(rez_status);
@@ -8308,14 +8380,6 @@ bool LLVOAvatar::isTooSlow() const
return mTooSlow;
}
-// use Avatar Render Time as complexity metric
-// markARTStale - Mark stale and set the frameupdate to now so that we can wait at least one frame to get a revised number.
-void LLVOAvatar::markARTStale()
-{
- mARTStale=true;
- mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
-}
-
// Udpate Avatar state based on render time
void LLVOAvatar::updateTooSlow()
{
@@ -8326,41 +8390,9 @@ void LLVOAvatar::updateTooSlow()
// mTooSlow - Is the avatar flagged as being slow (includes shadow time)
// mTooSlowWithoutShadows - Is the avatar flagged as being slow even with shadows removed.
- // mARTStale - the rendertime we have is stale because of an update. We need to force a re-render to re-assess slowness
-
- if( mARTStale )
- {
- if ( LLFrameTimer::getFrameCount() - mLastARTUpdateFrame < 5 )
- {
- // LL_INFOS() << this->getFullname() << " marked stale " << LL_ENDL;
- // we've not had a chance to update yet (allow a few to be certain a full frame has passed)
- return;
- }
-
- mARTStale = false;
- mTooSlow = false;
- mTooSlowWithoutShadows = false;
- // LL_INFOS() << this->getFullname() << " refreshed ART combined = " << mRenderTime << " @ " << mLastARTUpdateFrame << LL_ENDL;
- }
-
- // Either we're not stale or we've updated.
-
- U64 render_time_raw;
- U64 render_geom_time_raw;
-
- if( !mTooSlow )
- {
- // we are fully rendered, so we use the live values
- std::lock_guard<std::mutex> lock{LLPerfStats::bufferToggleLock};
- render_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_COMBINED);
- render_geom_time_raw = LLPerfStats::StatsRecorder::get(LLPerfStats::ObjType_t::OT_AVATAR, id, LLPerfStats::StatType_t::RENDER_GEOMETRY);
- }
- else
- {
- // use the cached values.
- render_time_raw = mRenderTime;
- render_geom_time_raw = mGeomTime;
- }
+
+ // get max render time in ms
+ F32 max_art_ms = (F32) (LLPerfStats::renderAvatarMaxART_ns / 1000000.0);
bool autotune = LLPerfStats::tunables.userAutoTuneEnabled && !mIsControlAvatar && !isSelf();
@@ -8376,19 +8408,13 @@ void LLVOAvatar::updateTooSlow()
}
bool exceeds_max_ART =
- ((LLPerfStats::renderAvatarMaxART_ns > 0) && (LLPerfStats::raw_to_ns(render_time_raw) >= LLPerfStats::renderAvatarMaxART_ns));
+ ((LLPerfStats::renderAvatarMaxART_ns > 0) &&
+ (mGPURenderTime >= max_art_ms)); // NOTE: don't use getGPURenderTime accessor here to avoid "isTooSlow" feedback loop
if (exceeds_max_ART && !ignore_tune)
{
- if( !mTooSlow ) // if we were previously not slow (with or without shadows.)
- {
- // if we weren't capped, we are now
- mLastARTUpdateFrame = LLFrameTimer::getFrameCount();
- mRenderTime = render_time_raw;
- mGeomTime = render_geom_time_raw;
- mARTStale = false;
- mTooSlow = true;
- }
+ mTooSlow = true;
+
if(!mTooSlowWithoutShadows) // if we were not previously above the full impostor cap
{
bool render_friend_or_exception = ( alwaysRenderFriends && LLAvatarTracker::instance().isBuddy( id ) ) ||
@@ -8396,13 +8422,12 @@ void LLVOAvatar::updateTooSlow()
if( (!isSelf() || allowSelfImpostor) && !render_friend_or_exception )
{
// Note: slow rendering Friends still get their shadows zapped.
- mTooSlowWithoutShadows = (LLPerfStats::raw_to_ns(render_geom_time_raw) >= LLPerfStats::renderAvatarMaxART_ns);
+ mTooSlowWithoutShadows = getGPURenderTime()*2.f >= max_art_ms; // NOTE: assumes shadow rendering doubles render time
}
}
}
else
{
- // LL_INFOS() << this->getFullname() << " ("<< (combined?"combined":"geometry") << ") good render time = " << LLPerfStats::raw_to_ns(render_time_raw) << " vs ("<< LLVOAvatar::sRenderTimeCap_ns << " set @ " << mLastARTUpdateFrame << LL_ENDL;
mTooSlow = false;
mTooSlowWithoutShadows = false;
@@ -10839,6 +10864,7 @@ void LLVOAvatar::updateVisualComplexity()
mVisualComplexityStale = true;
}
+
// Account for the complexity of a single top-level object associated
// with an avatar. This will be either an attached object or an animated
// object.
@@ -10850,144 +10876,146 @@ void LLVOAvatar::accountRenderComplexityForObject(
hud_complexity_list_t& hud_complexity_list,
object_complexity_list_t& object_complexity_list)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (attached_object && !attached_object->isHUDAttachment())
- {
+ {
mAttachmentVisibleTriangleCount += attached_object->recursiveGetTriangleCount();
mAttachmentEstTriangleCount += attached_object->recursiveGetEstTrianglesMax();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
- textures.clear();
- const LLDrawable* drawable = attached_object->mDrawable;
- if (drawable)
- {
- const LLVOVolume* volume = drawable->getVOVolume();
- if (volume)
- {
- F32 attachment_total_cost = 0;
- F32 attachment_volume_cost = 0;
- F32 attachment_texture_cost = 0;
- F32 attachment_children_cost = 0;
+ textures.clear();
+ const LLDrawable* drawable = attached_object->mDrawable;
+ if (drawable)
+ {
+ const LLVOVolume* volume = drawable->getVOVolume();
+ if (volume)
+ {
+ F32 attachment_total_cost = 0;
+ F32 attachment_volume_cost = 0;
+ F32 attachment_texture_cost = 0;
+ F32 attachment_children_cost = 0;
const F32 animated_object_attachment_surcharge = 1000;
- if (attached_object->isAnimatedObject())
+ if (volume->isAnimatedObjectFast())
{
attachment_volume_cost += animated_object_attachment_surcharge;
}
- attachment_volume_cost += volume->getRenderCost(textures);
+ attachment_volume_cost += volume->getRenderCost(textures);
- const_child_list_t children = volume->getChildren();
- for (const_child_list_t::const_iterator child_iter = children.begin();
- child_iter != children.end();
- ++child_iter)
- {
- LLViewerObject* child_obj = *child_iter;
- LLVOVolume *child = dynamic_cast<LLVOVolume*>( child_obj );
- if (child)
- {
- attachment_children_cost += child->getRenderCost(textures);
- }
- }
+ const_child_list_t children = volume->getChildren();
+ for (const_child_list_t::const_iterator child_iter = children.begin();
+ child_iter != children.end();
+ ++child_iter)
+ {
+ LLViewerObject* child_obj = *child_iter;
+ LLVOVolume* child = dynamic_cast<LLVOVolume*>(child_obj);
+ if (child)
+ {
+ attachment_children_cost += child->getRenderCost(textures);
+ }
+ }
- for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
- volume_texture != textures.end();
- ++volume_texture)
- {
- // add the cost of each individual texture in the linkset
- attachment_texture_cost += volume_texture->second;
- }
- attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
- LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
- << " total: " << attachment_total_cost
- << ", volume: " << attachment_volume_cost
- << ", " << textures.size()
- << " textures: " << attachment_texture_cost
- << ", " << volume->numChildren()
- << " children: " << attachment_children_cost
- << LL_ENDL;
- // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
- cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
-
- if (isSelf())
- {
- LLObjectComplexity object_complexity;
- object_complexity.objectName = attached_object->getAttachmentItemName();
- object_complexity.objectId = attached_object->getAttachmentItemID();
- object_complexity.objectCost = attachment_total_cost;
- object_complexity_list.push_back(object_complexity);
- }
- }
- }
- }
- if (isSelf()
- && attached_object
- && attached_object->isHUDAttachment()
- && !attached_object->isTempAttachment()
- && attached_object->mDrawable)
+ for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+ volume_texture != textures.end();
+ ++volume_texture)
+ {
+ // add the cost of each individual texture in the linkset
+ attachment_texture_cost += LLVOVolume::getTextureCost(*volume_texture);
+ }
+ attachment_total_cost = attachment_volume_cost + attachment_texture_cost + attachment_children_cost;
+ LL_DEBUGS("ARCdetail") << "Attachment costs " << attached_object->getAttachmentItemID()
+ << " total: " << attachment_total_cost
+ << ", volume: " << attachment_volume_cost
+ << ", " << textures.size()
+ << " textures: " << attachment_texture_cost
+ << ", " << volume->numChildren()
+ << " children: " << attachment_children_cost
+ << LL_ENDL;
+ // Limit attachment complexity to avoid signed integer flipping of the wearer's ACI
+ cost += (U32)llclamp(attachment_total_cost, MIN_ATTACHMENT_COMPLEXITY, max_attachment_complexity);
+
+ if (isSelf())
{
- textures.clear();
- BOOL is_rigged_mesh = attached_object->isRiggedMesh();
+ LLObjectComplexity object_complexity;
+ object_complexity.objectName = attached_object->getAttachmentItemName();
+ object_complexity.objectId = attached_object->getAttachmentItemID();
+ object_complexity.objectCost = attachment_total_cost;
+ object_complexity_list.push_back(object_complexity);
+ }
+ }
+ }
+ }
+ if (isSelf()
+ && attached_object
+ && attached_object->isHUDAttachment()
+ && !attached_object->isTempAttachment()
+ && attached_object->mDrawable)
+ {
+ textures.clear();
mAttachmentSurfaceArea += attached_object->recursiveGetScaledSurfaceArea();
- const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
- if (volume)
- {
- LLHUDComplexity hud_object_complexity;
- hud_object_complexity.objectName = attached_object->getAttachmentItemName();
- hud_object_complexity.objectId = attached_object->getAttachmentItemID();
- std::string joint_name;
- gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
- hud_object_complexity.jointName = joint_name;
- // get cost and individual textures
- hud_object_complexity.objectsCost += volume->getRenderCost(textures);
- hud_object_complexity.objectsCount++;
-
- LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
- for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
- iter != child_list.end(); ++iter)
- {
- LLViewerObject* childp = *iter;
- is_rigged_mesh |= childp->isRiggedMesh();
- const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
- if (chld_volume)
- {
- // get cost and individual textures
- hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
- hud_object_complexity.objectsCount++;
- }
- }
- if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
- {
- LLSD args;
- LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
- args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
- args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
- LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
+ const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
+ if (volume)
+ {
+ BOOL is_rigged_mesh = volume->isRiggedMeshFast();
+ LLHUDComplexity hud_object_complexity;
+ hud_object_complexity.objectName = attached_object->getAttachmentItemName();
+ hud_object_complexity.objectId = attached_object->getAttachmentItemID();
+ std::string joint_name;
+ gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
+ hud_object_complexity.jointName = joint_name;
+ // get cost and individual textures
+ hud_object_complexity.objectsCost += volume->getRenderCost(textures);
+ hud_object_complexity.objectsCount++;
+
+ LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+ for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+ iter != child_list.end(); ++iter)
+ {
+ LLViewerObject* childp = *iter;
+ const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
+ if (chld_volume)
+ {
+ is_rigged_mesh = is_rigged_mesh || chld_volume->isRiggedMeshFast();
+ // get cost and individual textures
+ hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
+ hud_object_complexity.objectsCount++;
+ }
+ }
+ if (is_rigged_mesh && !attached_object->mRiggedAttachedWarned)
+ {
+ LLSD args;
+ LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
+ args["NAME"] = itemp ? itemp->getName() : LLTrans::getString("Unknown");
+ args["POINT"] = LLTrans::getString(getTargetAttachmentPoint(attached_object)->getName());
+ LLNotificationsUtil::add("RiggedMeshAttachedToHUD", args);
- attached_object->mRiggedAttachedWarned = true;
- }
+ attached_object->mRiggedAttachedWarned = true;
+ }
- hud_object_complexity.texturesCount += textures.size();
+ hud_object_complexity.texturesCount += textures.size();
- for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
- volume_texture != textures.end();
- ++volume_texture)
- {
- // add the cost of each individual texture (ignores duplicates)
- hud_object_complexity.texturesCost += volume_texture->second;
- LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
- if (tex)
- {
- // Note: Texture memory might be incorect since texture might be still loading.
- hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
- if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
- {
- hud_object_complexity.largeTexturesCount++;
- }
- }
- }
- hud_complexity_list.push_back(hud_object_complexity);
+ for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+ volume_texture != textures.end();
+ ++volume_texture)
+ {
+ // add the cost of each individual texture (ignores duplicates)
+ hud_object_complexity.texturesCost += LLVOVolume::getTextureCost(*volume_texture);
+ const LLViewerTexture* img = *volume_texture;
+ if (img->getType() == LLViewerTexture::FETCHED_TEXTURE)
+ {
+ LLViewerFetchedTexture* tex = (LLViewerFetchedTexture*)img;
+ // Note: Texture memory might be incorect since texture might be still loading.
+ hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
+ if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
+ {
+ hud_object_complexity.largeTexturesCount++;
}
}
+ }
+ hud_complexity_list.push_back(hud_object_complexity);
+ }
+ }
}
// Calculations for mVisualComplexity value
@@ -10999,16 +11027,18 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
* everyone. If you have suggested improvements, submit them to
* the official viewer for consideration.
*****************************************************************/
- static const U32 COMPLEXITY_BODY_PART_COST = 200;
- static LLCachedControl<F32> max_complexity_setting(gSavedSettings,"MaxAttachmentComplexity");
- F32 max_attachment_complexity = max_complexity_setting;
- max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
-
- // Diagnostic list of all textures on our avatar
- static std::set<LLUUID> all_textures;
-
if (mVisualComplexityStale)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ static const U32 COMPLEXITY_BODY_PART_COST = 200;
+ static LLCachedControl<F32> max_complexity_setting(gSavedSettings, "MaxAttachmentComplexity");
+ F32 max_attachment_complexity = max_complexity_setting;
+ max_attachment_complexity = llmax(max_attachment_complexity, DEFAULT_MAX_ATTACHMENT_COMPLEXITY);
+
+ // Diagnostic list of all textures on our avatar
+ static std::unordered_set<const LLViewerTexture*> all_textures;
+
U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
LLVOVolume::texture_cost_t textures;
hud_complexity_list_t hud_complexity_list;
@@ -11076,44 +11106,6 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
}
}
- // Diagnostic output to identify all avatar-related textures.
- // Does not affect rendering cost calculation.
- if (isSelf() && debugLoggingEnabled("ARCdetail"))
- {
- // print any attachment textures we didn't already know about.
- for (LLVOVolume::texture_cost_t::iterator it = textures.begin(); it != textures.end(); ++it)
- {
- LLUUID image_id = it->first;
- if( ! (image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- && (all_textures.find(image_id) == all_textures.end()))
- {
- // attachment texture not previously seen.
- LL_DEBUGS("ARCdetail") << "attachment_texture: " << image_id.asString() << LL_ENDL;
- all_textures.insert(image_id);
- }
- }
-
- // print any avatar textures we didn't already know about
- for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearance::getDictionary()->getTextures().begin();
- iter != LLAvatarAppearance::getDictionary()->getTextures().end();
- ++iter)
- {
- const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
- // TODO: MULTI-WEARABLE: handle multiple textures for self
- const LLViewerTexture* te_image = getImage(iter->first,0);
- if (!te_image)
- continue;
- LLUUID image_id = te_image->getID();
- if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
- continue;
- if (all_textures.find(image_id) == all_textures.end())
- {
- LL_DEBUGS("ARCdetail") << "local_texture: " << texture_dict->mName << ": " << image_id << LL_ENDL;
- all_textures.insert(image_id);
- }
- }
- }
-
if ( cost != mVisualComplexity )
{
LL_DEBUGS("AvatarRender") << "Avatar "<< getID()
@@ -11141,6 +11133,21 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
// HUD complexity
LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
}
+
+ //schedule an update to ART next frame if needed
+ if (LLPerfStats::tunables.userAutoTuneEnabled &&
+ LLPerfStats::tunables.userFPSTuningStrategy != LLPerfStats::TUNE_SCENE_ONLY &&
+ !isVisuallyMuted())
+ {
+ LLUUID id = getID(); // <== use id to make sure this avatar didn't get deleted between frames
+ LL::WorkQueue::getInstance("mainloop")->post([this, id]()
+ {
+ if (gObjectList.findObject(id) != nullptr)
+ {
+ gPipeline.profileAvatar(this);
+ }
+ });
+ }
}
}
@@ -11475,3 +11482,113 @@ BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type,
// non-self avatars don't have wearables
return FALSE;
}
+
+void LLVOAvatar::placeProfileQuery()
+{
+ if (mGPUTimerQuery == 0)
+ {
+ glGenQueries(1, &mGPUTimerQuery);
+ }
+
+ glBeginQuery(GL_TIME_ELAPSED, mGPUTimerQuery);
+}
+
+void LLVOAvatar::readProfileQuery(S32 retries)
+{
+ if (!mGPUProfilePending)
+ {
+ glEndQuery(GL_TIME_ELAPSED);
+ mGPUProfilePending = true;
+ }
+
+ GLuint64 result = 0;
+ glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT_AVAILABLE, &result);
+
+ if (result == GL_TRUE || --retries <= 0)
+ { // query available, readback result
+ GLuint64 time_elapsed = 0;
+ glGetQueryObjectui64v(mGPUTimerQuery, GL_QUERY_RESULT, &time_elapsed);
+ mGPURenderTime = time_elapsed / 1000000.f;
+ mGPUProfilePending = false;
+
+ setDebugText(llformat("%d", (S32)(mGPURenderTime * 1000.f)));
+
+ }
+ else
+ { // wait until next frame
+ LLUUID id = getID();
+
+ LL::WorkQueue::getInstance("mainloop")->post([id, retries] {
+ LLVOAvatar* avatar = (LLVOAvatar*) gObjectList.findObject(id);
+ if(avatar)
+ {
+ avatar->readProfileQuery(retries);
+ }
+ });
+ }
+}
+
+
+F32 LLVOAvatar::getGPURenderTime()
+{
+ return isVisuallyMuted() ? 0.f : mGPURenderTime;
+}
+
+// static
+F32 LLVOAvatar::getTotalGPURenderTime()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ F32 ret = 0.f;
+
+ for (LLCharacter* iter : LLCharacter::sInstances)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*) iter;
+ ret += inst->getGPURenderTime();
+ }
+
+ return ret;
+}
+
+F32 LLVOAvatar::getMaxGPURenderTime()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ F32 ret = 0.f;
+
+ for (LLCharacter* iter : LLCharacter::sInstances)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*)iter;
+ ret = llmax(inst->getGPURenderTime(), ret);
+ }
+
+ return ret;
+}
+
+F32 LLVOAvatar::getAverageGPURenderTime()
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
+
+ F32 ret = 0.f;
+
+ S32 count = 0;
+
+ for (LLCharacter* iter : LLCharacter::sInstances)
+ {
+ LLVOAvatar* inst = (LLVOAvatar*)iter;
+ if (!inst->isTooSlow())
+ {
+ ret += inst->getGPURenderTime();
+ ++count;
+ }
+ }
+
+ if (count > 0)
+ {
+ ret /= count;
+ }
+
+ return ret;
+}
+
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 970ca523a5..48bfd5293a 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -164,6 +164,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -174,6 +175,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -303,8 +305,33 @@ public:
static const U32 VISUAL_COMPLEXITY_UNKNOWN;
void updateVisualComplexity();
- U32 getVisualComplexity() { return mVisualComplexity; }; // Numbers calculated here by rendering AV
- F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; }; // estimated surface area of attachments
+ void placeProfileQuery();
+ void readProfileQuery(S32 retries);
+
+ // get the GPU time in ms of rendering this avatar including all attachments
+ // returns 0.f if this avatar has not been profiled using gPipeline.profileAvatar
+ // or the avatar is visually muted
+ F32 getGPURenderTime();
+
+ // get the total GPU render time in ms of all avatars that have been benched
+ static F32 getTotalGPURenderTime();
+
+ // get the max GPU render time in ms of all avatars that have been benched
+ static F32 getMaxGPURenderTime();
+
+ // get the average GPU render time in ms of all avatars that have been benched
+ static F32 getAverageGPURenderTime();
+
+ // get the CPU time in ms of rendering this avatar including all attachments
+ // return 0.f if this avatar has not been profiled using gPipeline.mProfileAvatar
+ F32 getCPURenderTime() { return mCPURenderTime; }
+
+
+ // avatar render cost
+ U32 getVisualComplexity() { return mVisualComplexity; };
+
+ // surface area calculation
+ F32 getAttachmentSurfaceArea() { return mAttachmentSurfaceArea; };
U32 getReportedVisualComplexity() { return mReportedVisualComplexity; }; // Numbers as reported by the SL server
void setReportedVisualComplexity(U32 value) { mReportedVisualComplexity = value; };
@@ -384,8 +411,7 @@ public:
void logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
void calcMutedAVColor();
- void markARTStale();
-
+
protected:
LLViewerStats::PhaseMap& getPhases() { return mPhases; }
BOOL updateIsFullyLoaded();
@@ -406,11 +432,6 @@ private:
LLFrameTimer mFullyLoadedTimer;
LLFrameTimer mRuthTimer;
- U32 mLastARTUpdateFrame{0};
- U64 mRenderTime{0};
- U64 mGeomTime{0};
- bool mARTStale{true};
- bool mARTCapped{false};
// variables to hold "slowness" status
bool mTooSlow{false};
bool mTooSlowWithoutShadows{false};
@@ -521,6 +542,7 @@ public:
S32 mSpecialRenderMode; // special lighting
private:
+ friend class LLPipeline;
AvatarOverallAppearance mOverallAppearance;
F32 mAttachmentSurfaceArea; //estimated surface area of attachments
U32 mAttachmentVisibleTriangleCount;
@@ -533,7 +555,20 @@ private:
S32 mUpdatePeriod;
S32 mNumInitFaces; //number of faces generated when creating the avatar drawable, does not inculde splitted faces due to long vertex buffer.
+ // profile handle
+ U32 mGPUTimerQuery = 0;
+
+ // profile results
+
+ // GPU render time in ms
+ F32 mGPURenderTime = 0.f;
+ bool mGPUProfilePending = false;
+
+ // CPU render time in ms
+ F32 mCPURenderTime = 0.f;
+
// the isTooComplex method uses these mutable values to avoid recalculating too frequently
+ // DEPRECATED -- obsolete avatar render cost values
mutable U32 mVisualComplexity;
mutable bool mVisualComplexityStale;
U32 mReportedVisualComplexity; // from other viewers through the simulator
@@ -882,6 +917,7 @@ public:
virtual BOOL detachObject(LLViewerObject *viewer_object);
static bool getRiggedMeshID( LLViewerObject* pVO, LLUUID& mesh_id );
void cleanupAttachedMesh( LLViewerObject* pVO );
+ bool hasPendingAttachedMeshes();
static LLVOAvatar* findAvatarFromAttachment(LLViewerObject* obj);
/*virtual*/ BOOL isWearingWearableType(LLWearableType::EType type ) const;
LLViewerObject * findAttachmentByID( const LLUUID & target_id ) const;
@@ -1172,8 +1208,6 @@ public:
// COF version of last appearance message received for this av.
S32 mLastUpdateReceivedCOFVersion;
- U64 getLastART() const { return mRenderTime; }
-
/** Diagnostics
** **
*******************************************************************************/
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index b03d32d291..7b24b9ee02 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1038,7 +1038,7 @@ void LLVOAvatarSelf::restoreMeshData()
updateAttachmentVisibility(gAgentCamera.getCameraMode());
// force mesh update as LOD might not have changed to trigger this
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
@@ -1155,6 +1155,7 @@ LLViewerObject* LLVOAvatarSelf::getWornAttachment(const LLUUID& inv_item_id)
bool LLVOAvatarSelf::getAttachedPointName(const LLUUID& inv_item_id, std::string& name) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR;
if (!gInventory.getItem(inv_item_id))
{
name = "ATTACHMENT_MISSING_ITEM";
@@ -1847,7 +1848,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
}
else
{
- const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+ LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
LL_INFOS() << "LocTex " << name << ": "
<< "Discard " << image->getDiscardLevel() << ", "
@@ -1857,7 +1858,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
// makes textures easier to steal
<< image->getID() << " "
#endif
- << "Priority: " << image->getDecodePriority()
+ << "Priority: " << image->getMaxVirtualSize()
<< LL_ENDL;
}
}
@@ -2096,8 +2097,7 @@ const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLV
<< " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
<< " discard: " << image->getDiscardLevel()
<< " desired: " << image->getDesiredDiscardLevel()
- << " decode: " << image->getDecodePriority()
- << " addl: " << image->getAdditionalDecodePriority()
+ << " vsize: " << image->getMaxVirtualSize()
<< " ts: " << image->getTextureState()
<< " bl: " << image->getBoostLevel()
<< " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
@@ -2475,7 +2475,6 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
imagep->setBoostLevel(getAvatarBoostLevel());
- imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
imagep->resetTextureStats();
imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
imagep->addTextureStats( desired_pixels / texel_area_ratio );
@@ -2848,7 +2847,6 @@ void LLVOAvatarSelf::deleteScratchTextures()
LL_DEBUGS() << "Clearing Scratch Textures " << (S32Kilobytes)sScratchTexBytes << LL_ENDL;
delete_and_clear(sScratchTexNames);
- LLImageGL::sGlobalTextureMemory -= sScratchTexBytes;
sScratchTexBytes = S32Bytes(0);
}
}
diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp
index 8d1f5b5f5b..dd5b9f9fd5 100644
--- a/indra/newview/llvocache.cpp
+++ b/indra/newview/llvocache.cpp
@@ -26,15 +26,13 @@
#include "llviewerprecompiledheaders.h"
#include "llvocache.h"
-#include "llerror.h"
#include "llregionhandle.h"
#include "llviewercontrol.h"
#include "llviewerobjectlist.h"
#include "lldrawable.h"
#include "llviewerregion.h"
-#include "pipeline.h"
#include "llagentcamera.h"
-#include "llmemory.h"
+#include "llsdserialize.h"
//static variables
U32 LLVOCacheEntry::sMinFrameRange = 0;
@@ -57,6 +55,97 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes)
return apr_file->write(src, n_bytes) == n_bytes ;
}
+bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+
+ llassert(data.has("local_id"));
+ llassert(data.has("object_id"));
+ llassert(data.has("region_handle_x") && data.has("region_handle_y"));
+
+ if (!data.has("local_id"))
+ {
+ return false;
+ }
+
+ if (data.has("region_handle_x") && data.has("region_handle_y"))
+ {
+ // TODO start requiring this once server sends this for all messages
+ U32 region_handle_y = data["region_handle_y"].asInteger();
+ U32 region_handle_x = data["region_handle_x"].asInteger();
+ mRegionHandle = to_region_handle(region_handle_x, region_handle_y);
+ }
+ else
+ {
+ return false;
+ }
+
+ mLocalId = data["local_id"].asInteger();
+ mObjectId = data["object_id"];
+
+ // message should be interpreted thusly:
+ /// sides is a list of face indices
+ // gltf_llsd is a list of corresponding GLTF override LLSD
+ // any side not represented in "sides" has no override
+ if (data.has("sides") && data.has("gltf_llsd"))
+ {
+ LLSD const& sides = data.get("sides");
+ LLSD const& gltf_llsd = data.get("gltf_llsd");
+
+ if (sides.isArray() && gltf_llsd.isArray() &&
+ sides.size() != 0 &&
+ sides.size() == gltf_llsd.size())
+ {
+ for (int i = 0; i < sides.size(); ++i)
+ {
+ S32 side_idx = sides[i].asInteger();
+ mSides[side_idx] = gltf_llsd[i];
+ LLGLTFMaterial* override_mat = new LLGLTFMaterial();
+ override_mat->applyOverrideLLSD(gltf_llsd[i]);
+ mGLTFMaterial[side_idx] = override_mat;
+ }
+ }
+ else
+ {
+ LL_WARNS_IF(sides.size() != 0, "GLTF") << "broken override cache entry" << LL_ENDL;
+ }
+ }
+
+ llassert(mSides.size() == mGLTFMaterial.size());
+#ifdef SHOW_ASSERT
+ for (auto const & side : mSides)
+ {
+ // check that mSides and mGLTFMaterial have exactly the same keys present
+ llassert(mGLTFMaterial.count(side.first) == 1);
+ }
+#endif
+
+ return true;
+}
+
+LLSD LLGLTFOverrideCacheEntry::toLLSD() const
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK;
+ LLSD data;
+ U32 region_handle_x, region_handle_y;
+ from_region_handle(mRegionHandle, &region_handle_x, &region_handle_y);
+ data["region_handle_y"] = LLSD::Integer(region_handle_y);
+ data["region_handle_x"] = LLSD::Integer(region_handle_x);
+
+ data["object_id"] = mObjectId;
+ data["local_id"] = (LLSD::Integer) mLocalId;
+
+ llassert(mSides.size() == mGLTFMaterial.size());
+ for (auto const & side : mSides)
+ {
+ // check that mSides and mGLTFMaterial have exactly the same keys present
+ llassert(mGLTFMaterial.count(side.first) == 1);
+ data["sides"].append(LLSD::Integer(side.first));
+ data["gltf_llsd"].append(side.second);
+ }
+
+ return data;
+}
//---------------------------------------------------------------------------
// LLVOCacheEntry
@@ -170,7 +259,7 @@ LLVOCacheEntry::~LLVOCacheEntry()
}
void LLVOCacheEntry::updateEntry(U32 crc, LLDataPackerBinaryBuffer &dp)
-{
+{
if(mCRC != crc)
{
mCRC = crc;
@@ -356,6 +445,7 @@ S32 LLVOCacheEntry::writeToBuffer(U8 *data_buffer) const
return ENTRY_HEADER_SIZE + size;
}
+#ifndef LL_TEST
//static
void LLVOCacheEntry::updateDebugSettings()
{
@@ -408,6 +498,7 @@ void LLVOCacheEntry::updateDebugSettings()
const U32 clamped_frames = inv_obj_time ? llclamp((U32) inv_obj_time, MIN_FRAMES, MAX_FRAMES) : MAX_FRAMES; // [10, 64], with zero => 64
sMinFrameRange = MIN_FRAMES + ((clamped_frames - MIN_FRAMES) * adjust_factor);
}
+#endif // LL_TEST
//static
F32 LLVOCacheEntry::getSquaredPixelThreshold(bool is_front)
@@ -879,6 +970,7 @@ void LLVOCachePartition::selectBackObjects(LLCamera &camera, F32 pixel_threshold
return;
}
+#ifndef LL_TEST
S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
{
static LLCachedControl<bool> use_object_cache_occlusion(gSavedSettings,"UseObjectCacheOcclusion");
@@ -945,6 +1037,7 @@ S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion)
}
return 1;
}
+#endif // LL_TEST
void LLVOCachePartition::setCullHistory(BOOL has_new_object)
{
@@ -1018,8 +1111,9 @@ void LLVOCachePartition::removeOccluder(LLVOCacheGroup* group)
//-------------------------------------------------------------------
//LLVOCache
//-------------------------------------------------------------------
-// Format string used to construct filename for the object cache
+// Format strings used to construct filename for the object cache
static const char OBJECT_CACHE_FILENAME[] = "objects_%d_%d.slc";
+static const char OBJECT_CACHE_EXTRAS_FILENAME[] = "objects_%d_%d_extras.slec";
const U32 MAX_NUM_OBJECT_ENTRIES = 128 ;
const U32 MIN_ENTRIES_TO_PURGE = 16 ;
@@ -1032,9 +1126,12 @@ LLVOCache::LLVOCache(bool read_only) :
mInitialized(false),
mReadOnly(read_only),
mNumEntries(0),
- mCacheSize(1)
+ mCacheSize(1),
+ mEnabled(true)
{
+#ifndef LL_TEST
mEnabled = gSavedSettings.getBOOL("ObjectCacheEnabled");
+#endif
mLocalAPRFilePoolp = new LLVolatileAPRPool() ;
}
@@ -1214,6 +1311,15 @@ void LLVOCache::getObjectCacheFilename(U64 handle, std::string& filename)
return ;
}
+std::string LLVOCache::getObjectCacheExtrasFilename(U64 handle)
+{
+ U32 region_x, region_y;
+
+ grid_from_region_handle(handle, &region_x, &region_y);
+ return gDirUtilp->getExpandedFilename(LL_PATH_CACHE, object_cache_dirname,
+ llformat(OBJECT_CACHE_EXTRAS_FILENAME, region_x, region_y));
+}
+
void LLVOCache::removeFromCache(HeaderEntryInfo* entry)
{
if(mReadOnly)
@@ -1438,7 +1544,83 @@ void LLVOCache::readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::voca
return ;
}
-
+
+void LLVOCache::readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map)
+{
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not reading cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return ;
+ }
+ llassert_always(mInitialized);
+
+ handle_entry_map_t::iterator iter = mHandleEntryMap.find(handle) ;
+ if(iter == mHandleEntryMap.end()) //no cache
+ {
+ LL_WARNS() << "No handle map entry for " << handle << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llifstream in(filename, std::ios::in | std::ios::binary);
+
+ std::string line;
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+
+ if(!LLUUID::validate(line))
+ {
+ LL_WARNS() << "Failed reading extras cache for handle" << handle << ". invalid uuid line: '" << line << "'" << LL_ENDL;
+ return;
+ }
+
+ LLUUID cache_id(line);
+ if(cache_id != id)
+ {
+ LL_INFOS() << "Cache ID doesn't match for this region, discarding" << LL_ENDL;
+ return;
+ }
+
+ U32 num_entries; // if removal was enabled during write num_entries might be wrong
+ std::getline(in, line);
+ if(!in.good()) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << LL_ENDL;
+ return;
+ }
+ try {
+ num_entries = std::stol(line);
+ }
+ catch(std::logic_error&) // either invalid_argument or out_of_range
+ {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ". unreadable num_entries" << LL_ENDL;
+ return;
+ }
+
+ LL_DEBUGS("GLTF") << "Beginning reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+
+ LLSD entry_llsd;
+ for (U32 i = 0; i < num_entries && !in.eof(); i++)
+ {
+ static const U32 max_size = 4096;
+ bool success = LLSDSerialize::deserialize(entry_llsd, in, max_size);
+ // check bool(in) this time since eof is not a failure condition here
+ if(!success || !in) {
+ LL_WARNS() << "Failed reading extras cache for handle " << handle << ", entry number " << i << LL_ENDL;
+ return;
+ }
+
+ LLGLTFOverrideCacheEntry entry;
+ entry.fromLLSD(entry_llsd);
+ U32 local_id = entry_llsd["local_id"].asInteger();
+ cache_extras_entry_map[local_id] = entry;
+ }
+
+ LL_DEBUGS("GLTF") << "Completed reading extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+}
+
void LLVOCache::purgeEntries(U32 size)
{
while(mHeaderEntryQueue.size() > size)
@@ -1449,6 +1631,7 @@ void LLVOCache::purgeEntries(U32 size)
mHeaderEntryQueue.erase(iter) ;
removeFromCache(entry) ;
delete entry;
+ // TODO also delete extras
}
mNumEntries = mHandleEntryMap.size() ;
}
@@ -1575,3 +1758,62 @@ void LLVOCache::writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry:
return ;
}
+
+void LLVOCache::writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled)
+{
+ if(!mEnabled)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently disabled." << LL_ENDL;
+ return;
+ }
+ llassert_always(mInitialized);
+
+ if(mReadOnly)
+ {
+ LL_WARNS() << "Not writing extras cache for handle " << handle << "): Cache is currently in read-only mode." << LL_ENDL;
+ return;
+ }
+
+ std::string filename(getObjectCacheExtrasFilename(handle));
+ llofstream out(filename, std::ios::out | std::ios::binary);
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ out << id << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ U32 num_entries = cache_extras_entry_map.size();
+ out << num_entries << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+
+ for (auto const & entry : cache_extras_entry_map)
+ {
+ S32 local_id = entry.first;
+ LLSD entry_llsd = entry.second.toLLSD();
+ entry_llsd["local_id"] = local_id;
+ LLSDSerialize::serialize(entry_llsd, out, LLSDSerialize::LLSD_XML);
+ out << '\n';
+ if(!out.good())
+ {
+ LL_WARNS() << "Failed writing extras cache for handle " << handle << LL_ENDL;
+ return;
+ // TODO - clean up broken cache file
+ }
+ }
+
+ LL_DEBUGS("GLTF") << "Completed writing extras cache for handle " << handle << ", " << num_entries << " entries" << LL_ENDL;
+}
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 55a13d934d..8525edd121 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -32,11 +32,27 @@
#include "lldir.h"
#include "llvieweroctree.h"
#include "llapr.h"
+#include "llgltfmaterial.h"
+
+#include <unordered_map>
//---------------------------------------------------------------------------
// Cache entries
class LLCamera;
+class LLGLTFOverrideCacheEntry
+{
+public:
+ bool fromLLSD(const LLSD& data);
+ LLSD toLLSD() const;
+
+ LLUUID mObjectId;
+ U32 mLocalId = 0;
+ std::unordered_map<S32, LLSD> mSides; //override LLSD per side
+ std::unordered_map<S32, LLPointer<LLGLTFMaterial> > mGLTFMaterial; //GLTF material per side
+ U64 mRegionHandle = 0;
+};
+
class LLVOCacheEntry
: public LLViewerOctreeEntryData
{
@@ -79,6 +95,13 @@ public:
}
}
};
+
+ struct ExtrasEntry
+ {
+ LLSD extras;
+ std::string extras_raw;
+ };
+
protected:
~LLVOCacheEntry();
public:
@@ -142,7 +165,9 @@ private:
public:
typedef std::map<U32, LLPointer<LLVOCacheEntry> > vocache_entry_map_t;
typedef std::set<LLVOCacheEntry*> vocache_entry_set_t;
- typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
+ typedef std::set<LLVOCacheEntry*, CompareVOCacheEntry> vocache_entry_priority_list_t;
+
+ typedef std::unordered_map<U32, LLGLTFOverrideCacheEntry> vocache_gltf_overrides_map_t;
S32 mLastCameraUpdated;
protected:
@@ -265,7 +290,10 @@ public:
void removeCache(ELLPath location, bool started = false) ;
void readFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_entry_map_t& cache_entry_map) ;
+ void readGenericExtrasFromCache(U64 handle, const LLUUID& id, LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map);
+
void writeToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_entry_map_t& cache_entry_map, BOOL dirty_cache, bool removal_enabled);
+ void writeGenericExtrasToCache(U64 handle, const LLUUID& id, const LLVOCacheEntry::vocache_gltf_overrides_map_t& cache_extras_entry_map, BOOL dirty_cache, bool removal_enabled);
void removeEntry(U64 handle) ;
U32 getCacheEntries() { return mNumEntries; }
@@ -275,6 +303,7 @@ private:
void setDirNames(ELLPath location);
// determine the cache filename for the region from the region handle
void getObjectCacheFilename(U64 handle, std::string& filename);
+ std::string getObjectCacheExtrasFilename(U64 handle);
void removeFromCache(HeaderEntryInfo* entry);
void readCacheHeader();
void writeCacheHeader();
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 9a41eedb54..b814f15232 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -38,7 +38,6 @@
#include "llsky.h"
#include "llsurface.h"
#include "llsurfacepatch.h"
-#include "llvosky.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
#include "llviewerregion.h"
@@ -265,7 +264,7 @@ U32 LLVOGrass::processUpdateMessage(LLMessageSystem *mesgsys,
if (mDrawable)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
return retval;
@@ -291,12 +290,12 @@ void LLVOGrass::idleUpdate(LLAgent &agent, const F64 &time)
if (!LLVOTree::isTreeRenderingStopped() && !mNumBlades)//restart grass rendering
{
mNumBlades = GRASS_MAX_BLADES;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
return;
}
if (mPatch && (mLastPatchUpdateTime != mPatch->getLastUpdateTime()))
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
return;
@@ -349,7 +348,7 @@ BOOL LLVOGrass::updateLOD()
{
mNumBlades = 0 ;
face->setSize(0, 0);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
return TRUE ;
}
@@ -374,7 +373,7 @@ BOOL LLVOGrass::updateLOD()
{
face->setSize(mNumBlades*8, mNumBlades*12);
}
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
else if (num_blades <= (mNumBlades >> 1))
{
@@ -387,7 +386,7 @@ BOOL LLVOGrass::updateLOD()
{
face->setSize(mNumBlades*8, mNumBlades*12);
}
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
return TRUE;
}
@@ -594,7 +593,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -602,13 +601,10 @@ LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
mDepthMask = TRUE;
mSlopRatio = 0.1f;
mRenderPass = LLRenderPass::PASS_GRASS;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
- group->mBufferUsage = mBufferUsage;
-
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
@@ -624,11 +620,6 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count
LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
obj->mDepth = 0.f;
- if (drawablep->isAnimating())
- {
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
- }
-
U32 count = 0;
for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
{
@@ -707,8 +698,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
S32 idx = draw_vec.size()-1;
- BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
- F32 vsize = facep->getVirtualSize();
+ bool fullbright = facep->isState(LLFace::FULLBRIGHT);
if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
draw_vec[idx]->mTexture == facep->getTexture() &&
@@ -719,7 +709,6 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
}
else
{
@@ -731,17 +720,13 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
//facep->getTexture(),
buffer, object->isSelected(), fullbright);
- const LLVector4a* exts = group->getObjectExtents();
- info->mExtents[0] = exts[0];
- info->mExtents[1] = exts[1];
- info->mVSize = vsize;
draw_vec.push_back(info);
//for alpha sorting
facep->setDrawInfo(info);
}
}
- buffer->flush();
+ buffer->unmapBuffer();
mFaceList.clear();
}
@@ -752,13 +737,13 @@ void LLVOGrass::updateDrawable(BOOL force_damped)
if (mDrawable.notNull())
{
mDrawable->updateXform(TRUE);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
clearChanged(SHIFTED);
}
// virtual
-BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOGrass::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
diff --git a/indra/newview/llvograss.h b/indra/newview/llvograss.h
index 5634e048eb..63876dc099 100644
--- a/indra/newview/llvograss.h
+++ b/indra/newview/llvograss.h
@@ -79,6 +79,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp
deleted file mode 100644
index 52a6395618..0000000000
--- a/indra/newview/llvoground.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
-/**
- * @file llvoground.cpp
- * @brief LLVOGround class implementation
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llvoground.h"
-#include "lldrawpoolground.h"
-
-#include "llviewercontrol.h"
-
-#include "lldrawable.h"
-#include "llface.h"
-#include "llsky.h"
-#include "llviewercamera.h"
-#include "llviewerregion.h"
-#include "pipeline.h"
-
-LLVOGround::LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-: LLStaticViewerObject(id, pcode, regionp, TRUE)
-{
- mbCanSelect = FALSE;
-}
-
-
-LLVOGround::~LLVOGround()
-{
-}
-
-void LLVOGround::idleUpdate(LLAgent &agent, const F64 &time)
-{
-}
-
-
-void LLVOGround::updateTextures()
-{
-}
-
-
-LLDrawable *LLVOGround::createDrawable(LLPipeline *pipeline)
-{
- pipeline->allocDrawable(this);
- mDrawable->setLit(FALSE);
-
- mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GROUND);
- LLDrawPoolGround *poolp = (LLDrawPoolGround*) gPipeline.getPool(LLDrawPool::POOL_GROUND);
-
- mDrawable->addFace(poolp, NULL);
-
- return mDrawable;
-}
-
-// TO DO - this always returns TRUE,
-BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
-{
- LLStrider<LLVector3> verticesp;
- LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texCoordsp;
- LLStrider<U16> indicesp;
- S32 index_offset;
- LLFace *face;
-
- LLDrawPoolGround *poolp = (LLDrawPoolGround*) gPipeline.getPool(LLDrawPool::POOL_GROUND);
-
- if (drawable->getNumFaces() < 1)
- drawable->addFace(poolp, NULL);
- face = drawable->getFace(0);
- if (!face)
- return TRUE;
-
- if (!face->getVertexBuffer())
- {
- face->setSize(5, 12);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
- {
- LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to "
- << face->getGeomCount() << " vertices and "
- << face->getIndicesCount() << " indices" << LL_ENDL;
- }
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
- face->setVertexBuffer(buff);
- }
-
- index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
- if (-1 == index_offset)
- {
- return TRUE;
- }
-
- ///////////////////////////////////////
- //
- //
- //
- LLVector3 at_dir = LLViewerCamera::getInstance()->getAtAxis();
- at_dir.mV[VZ] = 0.f;
- if (at_dir.normVec() < 0.01)
- {
- // We really don't care, as we're not looking anywhere near the horizon.
- }
- LLVector3 left_dir = LLViewerCamera::getInstance()->getLeftAxis();
- left_dir.mV[VZ] = 0.f;
- left_dir.normVec();
-
- // Our center top point
- LLColor4 ground_color = gSky.getSkyFogColor();
- ground_color.mV[3] = 1.f;
- face->setFaceColor(ground_color);
-
- *(verticesp++) = LLVector3(64, 64, 0);
- *(verticesp++) = LLVector3(-64, 64, 0);
- *(verticesp++) = LLVector3(-64, -64, 0);
- *(verticesp++) = LLVector3(64, -64, 0);
- *(verticesp++) = LLVector3(0, 0, -1024);
-
-
- // Triangles for each side
- *indicesp++ = index_offset + 0;
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 4;
-
- *indicesp++ = index_offset + 1;
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 4;
-
- *indicesp++ = index_offset + 2;
- *indicesp++ = index_offset + 3;
- *indicesp++ = index_offset + 4;
-
- *indicesp++ = index_offset + 3;
- *indicesp++ = index_offset + 0;
- *indicesp++ = index_offset + 4;
-
- *(texCoordsp++) = LLVector2(0.f, 0.f);
- *(texCoordsp++) = LLVector2(1.f, 0.f);
- *(texCoordsp++) = LLVector2(1.f, 1.f);
- *(texCoordsp++) = LLVector2(0.f, 1.f);
- *(texCoordsp++) = LLVector2(0.5f, 0.5f);
-
- face->getVertexBuffer()->flush();
- LLPipeline::sCompiles++;
- return TRUE;
-}
diff --git a/indra/newview/llvoground.h b/indra/newview/llvoground.h
deleted file mode 100644
index e7033290c7..0000000000
--- a/indra/newview/llvoground.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/**
- * @file llvoground.h
- * @brief LLVOGround class header file
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLVOGROUND_H
-#define LL_LLVOGROUND_H
-
-#include "stdtypes.h"
-#include "v3color.h"
-#include "v4coloru.h"
-#include "llviewertexture.h"
-#include "llviewerobject.h"
-
-class LLVOGround : public LLStaticViewerObject
-{
-protected:
- ~LLVOGround();
-
-public:
- LLVOGround(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
-
- /*virtual*/ void idleUpdate(LLAgent &agent, const F64 &time);
-
- // Graphical stuff for objects - maybe broken out into render class
- // later?
- /*virtual*/ void updateTextures();
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
-
-};
-
-#endif // LL_LLVOGROUND_H
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 6e08a2ff12..34e561174c 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -356,7 +356,7 @@ void LLVoiceVisualizer::render()
//---------------------------------------------------------------
LLGLSPipelineAlpha alpha_blend;
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- LLGLDisable gls_stencil(GL_STENCIL_TEST);
+ //LLGLDisable gls_stencil(GL_STENCIL_TEST);
//-------------------------------------------------------------
// create coordinates of the geometry for the dot
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 51cf5f20c6..99874b8185 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -46,18 +46,8 @@
extern U64MicrosecondsImplicit gFrameTime;
-LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
-S32 LLVOPartGroup::sVBSlotFree[];
-S32* LLVOPartGroup::sVBSlotCursor = NULL;
-
void LLVOPartGroup::initClass()
{
- for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
- {
- sVBSlotFree[i] = i;
- }
-
- sVBSlotCursor = sVBSlotFree;
}
//static
@@ -65,9 +55,10 @@ void LLVOPartGroup::restoreGL()
{
//TODO: optimize out binormal mask here. Specular and normal coords as well.
- sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW_ARB);
+#if 0
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
U32 count = LL_MAX_PARTICLE_COUNT;
- if (!sVB->allocateBuffer(count*4, count*6, true))
+ if (!sVB->allocateBuffer(count*4, count*6))
{
LL_WARNS() << "Failed to allocate Vertex Buffer to "
<< count*4 << " vertices and "
@@ -117,27 +108,14 @@ void LLVOPartGroup::restoreGL()
*texcoordsp++ = LLVector2(1.f, 0.f);
}
- sVB->flush();
+ sVB->unmapBuffer();
+#endif
}
//static
void LLVOPartGroup::destroyGL()
{
- sVB = NULL;
-}
-
-//static
-S32 LLVOPartGroup::findAvailableVBSlot()
-{
- if (sVBSlotCursor >= sVBSlotFree + LL_MAX_PARTICLE_COUNT)
- { //no more available slots
- return -1;
- }
-
- S32 ret = *sVBSlotCursor;
- sVBSlotCursor++;
- return ret;
}
bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
@@ -155,20 +133,6 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
return false;
}
-//static
-void LLVOPartGroup::freeVBSlot(S32 idx)
-{
- llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
- //llassert(sVBSlotCursor > sVBSlotFree);
- //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
-
- if (sVBSlotCursor > sVBSlotFree)
- {
- sVBSlotCursor--;
- *sVBSlotCursor = idx;
- }
-}
-
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLAlphaObject(id, pcode, regionp),
mViewerPartGroupp(NULL)
@@ -291,13 +255,13 @@ F32 LLVOPartGroup::getPartSize(S32 idx)
return 0.f;
}
-void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst)
+void LLVOPartGroup::getBlendFunc(S32 idx, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst)
{
if (idx < (S32) mViewerPartGroupp->mParticles.size())
{
LLViewerPart* part = mViewerPartGroupp->mParticles[idx];
- src = part->mBlendFuncSource;
- dst = part->mBlendFuncDest;
+ src = (LLRender::eBlendFactor) part->mBlendFuncSource;
+ dst = (LLRender::eBlendFactor) part->mBlendFuncDest;
}
}
@@ -323,7 +287,7 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
if (group && group->isVisible())
{
- dirtySpatialGroup(TRUE);
+ dirtySpatialGroup();
}
if (!num_parts)
@@ -485,6 +449,7 @@ BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -607,7 +572,7 @@ void LLVOPartGroup::getGeometry(const LLViewerPart& part,
up.setCross3(right, at);
up.normalize3fast();
- if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK)
+ if (part.mFlags & LLPartData::LL_PART_FOLLOW_VELOCITY_MASK && !part.mVelocity.isExactlyZero())
{
LLVector4a normvel;
normvel.load3(part.mVelocity.mV);
@@ -737,7 +702,7 @@ U32 LLVOPartGroup::getPartitionType() const
}
LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, regionp)
{
mRenderPass = LLRenderPass::PASS_ALPHA;
mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES;
@@ -756,32 +721,69 @@ LLHUDParticlePartition::LLHUDParticlePartition(LLViewerRegion* regionp) :
void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED;
- if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
- {
- return;
- }
+ LL_PROFILE_GPU_ZONE("particle vbo");
+ if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ return;
+ }
- if (group->changeLOD())
- {
- group->mLastUpdateDistance = group->mDistance;
- group->mLastUpdateViewAngle = group->mViewAngle;
- }
-
- group->clearDrawMap();
-
- //get geometry count
- U32 index_count = 0;
- U32 vertex_count = 0;
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ group->mLastUpdateViewAngle = group->mViewAngle;
+ }
- addGeometryCount(group, vertex_count, index_count);
-
+ group->clearDrawMap();
+
+ //get geometry count
+ U32 index_count = 0;
+ U32 vertex_count = 0;
- if (vertex_count > 0 && index_count > 0 && LLVOPartGroup::sVB)
- {
- group->mBuilt = 1.f;
- //use one vertex buffer for all groups
- group->mVertexBuffer = LLVOPartGroup::sVB;
- getGeometry(group);
+ addGeometryCount(group, vertex_count, index_count);
+
+
+ if (vertex_count > 0 && index_count > 0)
+ {
+ group->mBuilt = 1.f;
+ if (group->mVertexBuffer.isNull() ||
+ group->mVertexBuffer->getNumVerts() < vertex_count || group->mVertexBuffer->getNumIndices() < index_count)
+ {
+ group->mVertexBuffer = new LLVertexBuffer(LLVOPartGroup::VERTEX_DATA_MASK);
+ group->mVertexBuffer->allocateBuffer(vertex_count, index_count);
+
+ // initialize index and texture coordinates only when buffer is reallocated
+ U16* indicesp = (U16*)group->mVertexBuffer->mapIndexBuffer(0, index_count);
+
+ U16 geom_idx = 0;
+ for (U32 i = 0; i < index_count; i += 6)
+ {
+ *indicesp++ = geom_idx + 0;
+ *indicesp++ = geom_idx + 1;
+ *indicesp++ = geom_idx + 2;
+
+ *indicesp++ = geom_idx + 1;
+ *indicesp++ = geom_idx + 3;
+ *indicesp++ = geom_idx + 2;
+
+ geom_idx += 4;
+ }
+
+ LLStrider<LLVector2> texcoordsp;
+
+ group->mVertexBuffer->getTexCoord0Strider(texcoordsp);
+
+ for (U32 i = 0; i < vertex_count; i += 4)
+ {
+ *texcoordsp++ = LLVector2(0.f, 1.f);
+ *texcoordsp++ = LLVector2(0.f, 0.f);
+ *texcoordsp++ = LLVector2(1.f, 1.f);
+ *texcoordsp++ = LLVector2(1.f, 0.f);
+ }
+
+ }
+
+
+ getGeometry(group);
}
else
{
@@ -795,8 +797,6 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
- group->mBufferUsage = mBufferUsage;
-
mFaceList.clear();
LLViewerCamera* camera = LLViewerCamera::getInstance();
@@ -849,10 +849,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLVertexBuffer* buffer = group->mVertexBuffer;
- LLStrider<U16> indicesp;
LLStrider<LLVector4a> verticesp;
LLStrider<LLVector3> normalsp;
- LLStrider<LLVector2> texcoordsp;
LLStrider<LLColor4U> colorsp;
LLStrider<LLColor4U> emissivep;
@@ -861,7 +859,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
buffer->getColorStrider(colorsp);
buffer->getEmissiveStrider(emissivep);
-
+ S32 geom_idx = 0;
+ S32 indices_idx = 0;
+
LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
@@ -869,55 +869,44 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- if (!facep->isState(LLFace::PARTICLE))
- { //set the indices of this face
- S32 idx = LLVOPartGroup::findAvailableVBSlot();
- if (idx >= 0)
- {
- facep->setGeomIndex(idx*4);
- facep->setIndicesIndex(idx*6);
- facep->setVertexBuffer(LLVOPartGroup::sVB);
- facep->setPoolType(LLDrawPool::POOL_ALPHA);
- facep->setState(LLFace::PARTICLE);
- }
- else
- {
- continue; //out of space in particle buffer
- }
- }
-
- S32 geom_idx = (S32) facep->getGeomIndex();
+ facep->setGeomIndex(geom_idx);
+ facep->setIndicesIndex(indices_idx);
- LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
- LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
LLStrider<LLColor4U> cur_glow = emissivep + geom_idx;
+ // not actually used
+ LLStrider<LLVector2> cur_tc;
+ LLStrider<U16> cur_idx;
+
+
+ geom_idx += 4;
+ indices_idx += 6;
+
LLColor4U* start_glow = cur_glow.get();
object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx);
- BOOL has_glow = FALSE;
+ bool has_glow = FALSE;
if (cur_glow.get() != start_glow)
{
- has_glow = TRUE;
+ has_glow = true;
}
llassert(facep->getGeomCount() == 4);
llassert(facep->getIndicesCount() == 6);
-
+
S32 idx = draw_vec.size()-1;
- BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
- F32 vsize = facep->getVirtualSize();
-
+ bool fullbright = facep->isState(LLFace::FULLBRIGHT);
+
bool batched = false;
- U32 bf_src = LLRender::BF_SOURCE_ALPHA;
- U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
+ LLRender::eBlendFactor bf_src = LLRender::BF_SOURCE_ALPHA;
+ LLRender::eBlendFactor bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;
object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst);
@@ -937,7 +926,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
batched = true;
info->mCount += facep->getIndicesCount();
info->mEnd += facep->getGeomCount();
- info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
}
else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
{
@@ -945,12 +933,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
info->mCount += facep->getIndicesCount();
info->mStart -= facep->getGeomCount();
info->mOffset = facep->getIndicesStart();
- info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
}
}
}
-
if (!batched)
{
U32 start = facep->getGeomIndex();
@@ -958,23 +944,18 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
- //facep->getTexture(),
- buffer, object->isSelected(), fullbright);
+ buffer, fullbright);
- const LLVector4a* exts = group->getObjectExtents();
- info->mExtents[0] = exts[0];
- info->mExtents[1] = exts[1];
- info->mVSize = vsize;
info->mBlendFuncDst = bf_dst;
info->mBlendFuncSrc = bf_src;
info->mHasGlow = has_glow;
- info->mParticle = TRUE;
draw_vec.push_back(info);
//for alpha sorting
facep->setDrawInfo(info);
}
}
+ buffer->unmapBuffer();
mFaceList.clear();
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 4e4d6e609d..4d471134d4 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -40,16 +40,9 @@ class LLVOPartGroup : public LLAlphaObject
{
public:
- //vertex buffer for holding all particles
- static LLPointer<LLVertexBuffer> sVB;
- static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
- static S32 *sVBSlotCursor;
-
static void initClass();
static void restoreGL();
static void destroyGL();
- static S32 findAvailableVBSlot();
- static void freeVBSlot(S32 idx);
enum
{
@@ -74,6 +67,7 @@ public:
S32 face,
BOOL pick_transparent,
BOOL pick_rigged,
+ BOOL pick_unselectable,
S32* face_hit,
LLVector4a* intersection,
LLVector2* tex_coord,
@@ -98,7 +92,7 @@ public:
void updateFaceSize(S32 idx) { }
F32 getPartSize(S32 idx);
- void getBlendFunc(S32 idx, U32& src, U32& dst);
+ void getBlendFunc(S32 idx, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst);
LLUUID getPartOwner(S32 idx);
LLUUID getPartSource(S32 idx);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 909588367b..20621665fa 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -531,7 +531,7 @@ void LLVOSky::initCubeMap()
images.push_back(mShinyTex[side].getImageRaw());
}
- if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
mCubeMap = new LLCubeMap(false);
}
@@ -576,7 +576,7 @@ void LLVOSky::restoreGL()
updateDirections(psky);
- if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps)
+ if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps)
{
initCubeMap();
}
@@ -585,7 +585,7 @@ void LLVOSky::restoreGL()
if (mDrawable)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
}
@@ -692,7 +692,7 @@ bool LLVOSky::updateSky()
LLHeavenBody::setInterpVal( mInterpVal );
updateDirections(psky);
- if (!mCubeMap)
+ if (!mCubeMap || LLPipeline::sReflectionProbesEnabled)
{
mCubeMapUpdateStage = NUM_CUBEMAP_FACES;
mForceUpdate = FALSE;
@@ -715,7 +715,7 @@ bool LLVOSky::updateSky()
mForceUpdate = FALSE;
}
}
- else if (mCubeMapUpdateStage == NUM_CUBEMAP_FACES)
+ else if (mCubeMapUpdateStage == NUM_CUBEMAP_FACES && !LLPipeline::sReflectionProbesEnabled)
{
LL_PROFILE_ZONE_NAMED("updateSky - forced");
LLSkyTex::stepCurrent();
@@ -767,16 +767,15 @@ bool LLVOSky::updateSky()
mForceUpdate = FALSE;
mForceUpdateThrottle.setTimerExpirySec(UPDATE_EXPRY);
- gPipeline.markRebuild(gSky.mVOGroundp->mDrawable, LLDrawable::REBUILD_ALL, TRUE);
if (mDrawable.notNull() && mDrawable->getFace(0) && !mDrawable->getFace(0)->getVertexBuffer())
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
mCubeMapUpdateStage = -1;
}
// run 0 to 5 faces, each face in own frame
- else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES)
+ else if (mCubeMapUpdateStage >= 0 && mCubeMapUpdateStage < NUM_CUBEMAP_FACES && !LLPipeline::sReflectionProbesEnabled)
{
LL_PROFILE_ZONE_NAMED("updateSky - create");
S32 side = mCubeMapUpdateStage;
@@ -1010,8 +1009,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
face->setSize(4, 6);
face->setGeomIndex(0);
face->setIndicesIndex(0);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- buff->allocateBuffer(4, 6, TRUE);
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
+ buff->allocateBuffer(4, 6);
face->setVertexBuffer(buff);
index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
@@ -1046,7 +1045,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable)
*indicesp++ = index_offset + 3;
*indicesp++ = index_offset + 2;
- buff->flush();
+ buff->unmapBuffer();
}
}
@@ -1139,8 +1138,8 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
if (!facep->getVertexBuffer())
{
facep->setSize(4, 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE))
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK);
+ if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount()))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
<< facep->getGeomCount() << " vertices and "
@@ -1179,7 +1178,7 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const
*indicesp++ = index_offset + 2;
*indicesp++ = index_offset + 3;
- facep->getVertexBuffer()->flush();
+ facep->getVertexBuffer()->unmapBuffer();
return TRUE;
}
@@ -1379,8 +1378,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
if (!face->getVertexBuffer() || quads*4 != face->getGeomCount())
{
face->setSize(quads * 4, quads * 6);
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
- if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK);
+ if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount()))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to "
<< face->getGeomCount() << " vertices and "
@@ -1523,7 +1522,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H,
}
}
- face->getVertexBuffer()->flush();
+ face->getVertexBuffer()->unmapBuffer();
}
}
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index 5cb7e7478b..15fabf0414 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -45,26 +45,6 @@
F32 LLVOSurfacePatch::sLODFactor = 1.f;
-//============================================================================
-
-class LLVertexBufferTerrain : public LLVertexBuffer
-{
-public:
- LLVertexBufferTerrain() :
- LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW_ARB)
- {
- //texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1
- };
-
- // virtual
- void setupVertexBuffer(U32 data_mask)
- {
- LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3));
- }
-};
-
-//============================================================================
-
LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLStaticViewerObject(id, pcode, regionp),
mDirtiedPatch(FALSE),
@@ -170,7 +150,7 @@ BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable)
{
LL_PROFILE_ZONE_SCOPED;
- dirtySpatialGroup(TRUE);
+ dirtySpatialGroup();
S32 min_comp, max_comp, range;
min_comp = lltrunc(mPatchp->getMinComposition());
@@ -798,7 +778,7 @@ void LLVOSurfacePatch::dirtyGeom()
{
if (mDrawable)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
LLFace* facep = mDrawable->getFace(0);
if (facep)
{
@@ -873,7 +853,7 @@ void LLVOSurfacePatch::getGeomSizesEast(const S32 stride, const S32 east_stride,
}
}
-BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOSurfacePatch::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -994,7 +974,7 @@ U32 LLVOSurfacePatch::getPartitionType() const
}
LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, regionp)
{
mOcclusionEnabled = FALSE;
mInfiniteFarClip = TRUE;
@@ -1002,11 +982,6 @@ LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp)
mPartitionType = LLViewerRegion::PARTITION_TERRAIN;
}
-LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage)
-{
- return new LLVertexBufferTerrain();
-}
-
void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED;
@@ -1044,7 +1019,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
index_offset += facep->getGeomCount();
}
- buffer->flush();
+ buffer->unmapBuffer();
mFaceList.clear();
}
diff --git a/indra/newview/llvosurfacepatch.h b/indra/newview/llvosurfacepatch.h
index 884dbb3be3..aed67162d1 100644
--- a/indra/newview/llvosurfacepatch.h
+++ b/indra/newview/llvosurfacepatch.h
@@ -85,6 +85,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 493162b47b..36e6da802b 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -376,11 +376,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
if (mReferenceBuffer.isNull())
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
else if (trunk_LOD != mTrunkLOD)
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, FALSE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
else
{
@@ -538,8 +538,8 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
max_vertices += sLODVertexCount[lod];
}
- mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0);
- if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE))
+ mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
+ if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on update to "
<< max_vertices << " vertices and "
@@ -862,7 +862,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
slices /= 2;
}
- mReferenceBuffer->flush();
+ mReferenceBuffer->unmapBuffer();
llassert(vertex_count == max_vertices);
llassert(index_count == max_indices);
}
@@ -921,19 +921,19 @@ void LLVOTree::updateMesh()
LLFace* facep = mDrawable->getFace(0);
if (!facep) return;
- LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
- if (!buff->allocateBuffer(vert_count, index_count, TRUE))
+ LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
+ if (!buff->allocateBuffer(vert_count, index_count))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to "
<< vert_count << " vertices and "
<< index_count << " indices" << LL_ENDL;
- buff->allocateBuffer(1, 3, true);
+ buff->allocateBuffer(1, 3);
memset((U8*)buff->getMappedData(), 0, buff->getSize());
memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize());
facep->setSize(1, 3);
facep->setVertexBuffer(buff);
- mReferenceBuffer->flush();
- buff->flush();
+ mReferenceBuffer->unmapBuffer();
+ buff->unmapBuffer();
return;
}
@@ -954,8 +954,8 @@ void LLVOTree::updateMesh()
genBranchPipeline(vertices, normals, tex_coords, colors, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha);
- mReferenceBuffer->flush();
- buff->flush();
+ mReferenceBuffer->unmapBuffer();
+ buff->unmapBuffer();
}
void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
@@ -1170,7 +1170,7 @@ void LLVOTree::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
mDrawable->setPositionGroup(pos);
}
-BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOTree::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -1226,7 +1226,7 @@ U32 LLVOTree::getPartitionType() const
}
LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, regionp)
{
mDrawableType = LLPipeline::RENDER_TYPE_TREE;
mPartitionType = LLViewerRegion::PARTITION_TREE;
diff --git a/indra/newview/llvotree.h b/indra/newview/llvotree.h
index 93c22d2da3..996e970cf8 100644
--- a/indra/newview/llvotree.h
+++ b/indra/newview/llvotree.h
@@ -111,6 +111,7 @@ public:
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 269c5666cc..ec2f490742 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -88,14 +88,13 @@
#include "llcallstack.h"
#include "llsculptidsize.h"
#include "llavatarappearancedefines.h"
-#include "llperfstats.h"
+#include "llgltfmateriallist.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1;
BOOL gAnimateTextures = TRUE;
-//extern BOOL gHideSelectedObjects;
F32 LLVOVolume::sLODFactor = 1.f;
F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop
@@ -106,6 +105,8 @@ S32 LLVOVolume::mRenderComplexity_current = 0;
LLPointer<LLObjectMediaDataClient> LLVOVolume::sObjectMediaClient = NULL;
LLPointer<LLObjectMediaNavigateClient> LLVOVolume::sObjectMediaNavigateClient = NULL;
+extern BOOL gCubeSnapshot;
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
@@ -229,7 +230,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mColorChanged = FALSE;
mSpotLightPriority = 0.f;
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = NULL;
mMediaImplList.resize(getNumTEs());
@@ -243,6 +244,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
LLVOVolume::~LLVOVolume()
{
+ LL_PROFILE_ZONE_SCOPED;
delete mTextureAnimp;
mTextureAnimp = NULL;
delete mVolumeImpl;
@@ -266,6 +268,7 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
+ LL_PROFILE_ZONE_SCOPED;
if (getVolume())
{
LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
@@ -409,7 +412,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
if (setVolume(volume_params, 0))
{
- markForUpdate(TRUE);
+ markForUpdate();
}
}
@@ -420,10 +423,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
//
S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
- if (result & teDirtyBits)
- {
- updateTEData();
- }
+
if (result & TEM_CHANGE_MEDIA)
{
retval |= MEDIA_FLAGS_CHANGED;
@@ -445,7 +445,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
if (setVolume(volume_params, 0))
{
- markForUpdate(TRUE);
+ markForUpdate();
}
S32 res2 = unpackTEMessage(*dp);
if (TEM_INVALID == res2)
@@ -463,10 +463,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
else
{
- if (res2 & teDirtyBits)
- {
- updateTEData();
- }
if (res2 & TEM_CHANGE_MEDIA)
{
retval |= MEDIA_FLAGS_CHANGED;
@@ -528,7 +524,10 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
S32 result = unpackTEMessage(tdp);
if (result & teDirtyBits)
{
- updateTEData();
+ if (mDrawable)
+ { //on the fly TE updates break batches, isolate in octree
+ shrinkWrap();
+ }
}
if (result & TEM_CHANGE_MEDIA)
{
@@ -588,6 +587,7 @@ void LLVOVolume::animateTextures()
{
if (!mDead)
{
+ shrinkWrap();
F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f;
S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot);
@@ -700,26 +700,8 @@ void LLVOVolume::animateTextures()
void LLVOVolume::updateTextures()
{
- const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
- if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
- {
- updateTextureVirtualSize();
-
- if (mDrawable.notNull() && !isVisible() && !mDrawable->isActive())
- { //delete vertex buffer to free up some VRAM
- LLSpatialGroup* group = mDrawable->getSpatialGroup();
- if (group && (group->mVertexBuffer.notNull() || !group->mBufferMap.empty() || !group->mDrawMap.empty()))
- {
- group->destroyGL(true);
-
- //flag the group as having changed geometry so it gets a rebuild next time
- //it becomes visible
- group->setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
- }
- }
-
-
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE;
+ updateTextureVirtualSize();
}
BOOL LLVOVolume::isVisible() const
@@ -748,7 +730,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
// Update the pixel area of all faces
- if (mDrawable.isNull())
+ if (mDrawable.isNull() || gCubeSnapshot)
{
return;
}
@@ -792,6 +774,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
const S32 num_faces = mDrawable->getNumFaces();
F32 min_vsize=999999999.f, max_vsize=0.f;
LLViewerCamera* camera = LLViewerCamera::getInstance();
+ std::stringstream debug_text;
for (S32 i = 0; i < num_faces; i++)
{
LLFace* face = mDrawable->getFace(i);
@@ -803,7 +786,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
{
continue;
}
-
+
F32 vsize;
F32 old_size = face->getVirtualSize();
@@ -820,31 +803,30 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
vsize = face->getTextureVirtualSize();
}
- mPixelArea = llmax(mPixelArea, face->getPixelArea());
+ mPixelArea = llmax(mPixelArea, face->getPixelArea());
+ // if the face has gotten small enough to turn off texture animation and texture
+ // animation is running, rebuild the render batch for this face to turn off
+ // texture animation
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);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD);
}
}
- if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
- {
- if (vsize < min_vsize) min_vsize = vsize;
- if (vsize > max_vsize) max_vsize = vsize;
- }
- else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
LLViewerFetchedTexture* img = LLViewerTextureManager::staticCastToFetchedTexture(imagep) ;
if(img)
{
- F32 pri = img->getDecodePriority();
+ debug_text << img->getDiscardLevel() << ":" << img->getDesiredDiscardLevel() << ":" << img->getWidth() << ":" << (S32) sqrtf(vsize) << ":" << (S32) sqrtf(img->getMaxVirtualSize()) << "\n";
+ /*F32 pri = img->getDecodePriority();
pri = llmax(pri, 0.0f);
if (pri < min_vsize) min_vsize = pri;
- if (pri > max_vsize) max_vsize = pri;
+ if (pri > max_vsize) max_vsize = pri;*/
}
}
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
@@ -873,14 +855,6 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
F32 lodf = ((F32)(lod + 1.0f)/4.f);
F32 tex_size = lodf * LLViewerTexture::sMaxSculptRez ;
mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE);
-
- //if the sculpty very close to the view point, load first
- {
- LLVector3 lookAt = getPositionAgent() - camera->getOrigin();
- F32 dist = lookAt.normVec() ;
- F32 cos_angle_to_view_dir = lookAt * camera->getXAxis() ;
- mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ;
- }
}
S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture
@@ -890,7 +864,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
(texture_discard < current_discard || //texture has more data than last rebuild
current_discard < 0)) //no previous rebuild
{
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
mSculptChanged = TRUE;
}
@@ -908,7 +882,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
{
LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
LLUUID id = params->getLightTexture();
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM);
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
if (mLightTexture.notNull())
{
F32 rad = getLightRadius();
@@ -924,7 +898,8 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
}
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY))
{
- setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+ //setDebugText(llformat("%.0f:%.0f", (F32) sqrt(min_vsize),(F32) sqrt(max_vsize)));
+ setDebugText(debug_text.str());
}
else if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_AREA))
{
@@ -971,7 +946,12 @@ void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped)
//since drawable transforms do not include scale, changing volume scale
//requires an immediate rebuild of volume verts.
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
+
+ if (mDrawable)
+ {
+ shrinkWrap();
+ }
}
}
@@ -1011,7 +991,12 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
// Add it to the pipeline mLightSet
gPipeline.setLight(mDrawable, TRUE);
}
-
+
+ if (isReflectionProbe())
+ {
+ updateReflectionProbePtr();
+ }
+
updateRadius();
bool force_update = true; // avoid non-alpha mDistance update being optimized away
mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
@@ -1101,7 +1086,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
if (mSkinInfo && mSkinInfo->mMeshID != volume_params.getSculptID())
{
mSkinInfo = NULL;
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
}
if (!getVolume()->isMeshAssetLoaded())
@@ -1114,13 +1099,24 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
- if (!mSkinInfo && !mSkinInfoFailed)
+ if (!mSkinInfo && !mSkinInfoUnavaliable)
{
- const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(volume_params.getSculptID(), this);
- if (skin_info)
- {
- notifySkinInfoLoaded(skin_info);
- }
+ LLUUID mesh_id = volume_params.getSculptID();
+ if (gMeshRepo.hasHeader(mesh_id) && !gMeshRepo.hasSkinInfo(mesh_id))
+ {
+ // If header is present but has no data about skin,
+ // no point fetching
+ mSkinInfoUnavaliable = true;
+ }
+
+ if (!mSkinInfoUnavaliable)
+ {
+ const LLMeshSkinInfo* skin_info = gMeshRepo.getSkinInfo(mesh_id, this);
+ if (skin_info)
+ {
+ notifySkinInfoLoaded(skin_info);
+ }
+ }
}
}
else // otherwise is sculptie
@@ -1132,27 +1128,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
}
}
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject &&
- (!mVolumeImpl || !mVolumeImpl->isVolumeUnique());
-
- if (cache_in_vram)
- { //this volume might be used as source data for a transform object, put it in vram
- LLVolume* volume = getVolume();
- for (S32 i = 0; i < volume->getNumFaces(); ++i)
- {
- const LLVolumeFace& face = volume->getVolumeFace(i);
- if (face.mVertexBuffer.notNull())
- { //already cached
- break;
- }
- volume->genTangents(i);
- LLFace::cacheFaceInVRAM(face);
- }
- }
-
- return TRUE;
+ return TRUE;
}
else if (NO_LOD == lod)
{
@@ -1175,7 +1151,7 @@ void LLVOVolume::updateSculptTexture()
mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
}
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = NULL;
}
else
@@ -1214,7 +1190,17 @@ void LLVOVolume::updateVisualComplexity()
void LLVOVolume::notifyMeshLoaded()
{
mSculptChanged = TRUE;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY);
+
+ if (!mSkinInfo && !mSkinInfoUnavaliable)
+ {
+ // Header was loaded, update skin info state from header
+ LLUUID mesh_id = getVolume()->getParams().getSculptID();
+ if (!gMeshRepo.hasSkinInfo(mesh_id))
+ {
+ mSkinInfoUnavaliable = true;
+ }
+ }
LLVOAvatar *av = getAvatar();
if (av && !isAnimatedObject())
@@ -1233,7 +1219,7 @@ void LLVOVolume::notifyMeshLoaded()
void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
{
- mSkinInfoFailed = false;
+ mSkinInfoUnavaliable = false;
mSkinInfo = skin;
notifyMeshLoaded();
@@ -1241,7 +1227,7 @@ void LLVOVolume::notifySkinInfoLoaded(const LLMeshSkinInfo* skin)
void LLVOVolume::notifySkinInfoUnavailable()
{
- mSkinInfoFailed = true;
+ mSkinInfoUnavaliable = true;
mSkinInfo = nullptr;
}
@@ -1345,7 +1331,7 @@ void LLVOVolume::sculpt()
LLVOVolume* volume = (*(mSculptTexture->getVolumeList(LLRender::SCULPT_TEX)))[i];
if (volume != this && volume->getVolume() == getVolume())
{
- gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY, FALSE);
+ gPipeline.markRebuild(volume->mDrawable, LLDrawable::REBUILD_GEOMETRY);
}
}
}
@@ -1567,7 +1553,9 @@ BOOL LLVOVolume::updateLOD()
{
return FALSE;
}
-
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
BOOL lod_changed = FALSE;
if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
@@ -1581,17 +1569,7 @@ BOOL LLVOVolume::updateLOD()
if (lod_changed)
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (isAnimatedObject() && isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", this);
- F32 est_tris = getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " updateLOD to " << getLOD() << ", tris " << est_tris << LL_ENDL;
- }
- }
-
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
mLODChanged = TRUE;
}
else
@@ -1620,7 +1598,7 @@ BOOL LLVOVolume::setDrawableParent(LLDrawable* parentp)
if (!mDrawable->isRoot())
{
// rebuild vertices in parent relative space
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
if (mDrawable->isActive() && !parentp->isActive())
{
@@ -1672,7 +1650,7 @@ BOOL LLVOVolume::setParent(LLViewerObject* parent)
if (ret && mDrawable)
{
gPipeline.markMoved(mDrawable);
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
onReparent(old_parent, parent);
}
@@ -2060,7 +2038,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
LLSpatialGroup* group = drawable->getSpatialGroup();
if (group)
{
- group->dirtyMesh();
+ group->dirtyMesh();
}
updateRelativeXform();
@@ -2077,7 +2055,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
if (mVolumeChanged || mFaceMappingChanged)
{
- dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+ dirtySpatialGroup();
bool was_regen_faces = false;
should_update_octree_bounds = true;
@@ -2099,7 +2077,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
}
else if (mLODChanged || mSculptChanged || mColorChanged)
{
- dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
+ dirtySpatialGroup();
compiled = TRUE;
lodOrSculptChanged(drawable, compiled, should_update_octree_bounds);
@@ -2209,7 +2187,8 @@ void LLVOVolume::setNumTEs(const U8 num_tes)
return ;
}
-//virtual
+
+//virtual
void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep)
{
BOOL changed = (mTEImages[index] != imagep);
@@ -2237,7 +2216,12 @@ S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid)
S32 res = LLViewerObject::setTETexture(te, uuid);
if (res)
{
- gPipeline.markTextured(mDrawable);
+ if (mDrawable)
+ {
+ // dynamic texture changes break batches, isolate in octree
+ shrinkWrap();
+ gPipeline.markTextured(mDrawable);
+ }
mFaceMappingChanged = TRUE;
}
return res;
@@ -2264,7 +2248,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
gPipeline.markTextured(mDrawable);
//treat this alpha change as an LoD update since render batches may need to get rebuilt
mLODChanged = TRUE;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
}
retval = LLPrimitive::setTEColor(te, color);
if (mDrawable.notNull() && retval)
@@ -2272,6 +2256,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
// These should only happen on updates which are not the initial update.
mColorChanged = TRUE;
mDrawable->setState(LLDrawable::REBUILD_COLOR);
+ shrinkWrap();
dirtyMesh();
}
}
@@ -2361,7 +2346,11 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
S32 res = LLViewerObject::setTEGlow(te, glow);
if (res)
{
- gPipeline.markTextured(mDrawable);
+ if (mDrawable)
+ {
+ gPipeline.markTextured(mDrawable);
+ shrinkWrap();
+ }
mFaceMappingChanged = TRUE;
}
return res;
@@ -2407,243 +2396,11 @@ S32 LLVOVolume::setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID)
return res;
}
-bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
-{ //Ok, here we have confirmation about texture creation, check our wait-list
- //and make changes, or return false
-
- std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
-
- typedef std::map<U8, LLMaterialPtr> map_te_material;
- map_te_material new_material;
-
- for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
- {
- LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
-
- //here we just interesting in DIFFUSE_MAP only!
- if(NULL != cur_material.get() && LLRender::DIFFUSE_MAP == range_it->second.map && GL_RGBA != texture->getPrimaryFormat())
- { //ok let's check the diffuse mode
- switch(cur_material->getDiffuseAlphaMode())
- {
- case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
- case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
- case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
- { //uups... we have non 32 bit texture with LLMaterial::DIFFUSE_ALPHA_MODE_* => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
-
- LLMaterialPtr mat = NULL;
- map_te_material::iterator it = new_material.find(range_it->second.te);
- if(new_material.end() == it) {
- mat = new LLMaterial(cur_material->asLLSD());
- new_material.insert(map_te_material::value_type(range_it->second.te, mat));
- } else {
- mat = it->second;
- }
-
- mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
-
- } break;
- } //switch
- } //if
- } //for
-
- //setup new materials
- for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
- {
- LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
- LLViewerObject::setTEMaterialParams(it->first, it->second);
- }
-
- //clear wait-list
- mWaitingTextureInfo.erase(range.first, range.second);
-
- return 0 != new_material.size();
-}
-
-bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
-{ //Ok, here if we wait information about texture and it's missing
- //then depending from the texture map (diffuse, normal, or specular)
- //make changes in material and confirm it. If not return false.
- std::pair<mmap_UUID_MAP_t::iterator, mmap_UUID_MAP_t::iterator> range = mWaitingTextureInfo.equal_range(texture->getID());
- if(range.first == range.second) return false;
-
- typedef std::map<U8, LLMaterialPtr> map_te_material;
- map_te_material new_material;
-
- for(mmap_UUID_MAP_t::iterator range_it = range.first; range_it != range.second; ++range_it)
- {
- LLMaterialPtr cur_material = getTEMaterialParams(range_it->second.te);
- if (cur_material.isNull())
- continue;
-
- switch(range_it->second.map)
- {
- case LLRender::DIFFUSE_MAP:
- {
- if(LLMaterial::DIFFUSE_ALPHA_MODE_NONE != cur_material->getDiffuseAlphaMode())
- { //missing texture + !LLMaterial::DIFFUSE_ALPHA_MODE_NONE => LLMaterial::DIFFUSE_ALPHA_MODE_NONE
- LLMaterialPtr mat = NULL;
- map_te_material::iterator it = new_material.find(range_it->second.te);
- if(new_material.end() == it) {
- mat = new LLMaterial(cur_material->asLLSD());
- new_material.insert(map_te_material::value_type(range_it->second.te, mat));
- } else {
- mat = it->second;
- }
-
- mat->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
- }
- } break;
- case LLRender::NORMAL_MAP:
- { //missing texture => reset material texture id
- LLMaterialPtr mat = NULL;
- map_te_material::iterator it = new_material.find(range_it->second.te);
- if(new_material.end() == it) {
- mat = new LLMaterial(cur_material->asLLSD());
- new_material.insert(map_te_material::value_type(range_it->second.te, mat));
- } else {
- mat = it->second;
- }
-
- mat->setNormalID(LLUUID::null);
- } break;
- case LLRender::SPECULAR_MAP:
- { //missing texture => reset material texture id
- LLMaterialPtr mat = NULL;
- map_te_material::iterator it = new_material.find(range_it->second.te);
- if(new_material.end() == it) {
- mat = new LLMaterial(cur_material->asLLSD());
- new_material.insert(map_te_material::value_type(range_it->second.te, mat));
- } else {
- mat = it->second;
- }
-
- mat->setSpecularID(LLUUID::null);
- } break;
- case LLRender::NUM_TEXTURE_CHANNELS:
- //nothing to do, make compiler happy
- break;
- } //switch
- } //for
-
- //setup new materials
- for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
- {
- LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
- LLViewerObject::setTEMaterialParams(it->first, it->second);
- }
-
- //clear wait-list
- mWaitingTextureInfo.erase(range.first, range.second);
-
- return 0 != new_material.size();
-}
-
S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams)
{
- LLMaterialPtr pMaterial = const_cast<LLMaterialPtr&>(pMaterialParams);
+ S32 res = LLViewerObject::setTEMaterialParams(te, pMaterialParams);
- if(pMaterialParams)
- { //check all of them according to material settings
-
- LLViewerTexture *img_diffuse = getTEImage(te);
- LLViewerTexture *img_normal = getTENormalMap(te);
- LLViewerTexture *img_specular = getTESpecularMap(te);
-
- llassert(NULL != img_diffuse);
-
- LLMaterialPtr new_material = NULL;
-
- //diffuse
- if(NULL != img_diffuse)
- { //guard
- if(0 == img_diffuse->getPrimaryFormat() && !img_diffuse->isMissingAsset())
- { //ok here we don't have information about texture, let's belief and leave material settings
- //but we remember this case
- mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(img_diffuse->getID(), material_info(LLRender::DIFFUSE_MAP, te)));
- }
- else
- {
- bool bSetDiffuseNone = false;
- if(img_diffuse->isMissingAsset())
- {
- bSetDiffuseNone = true;
- }
- else
- {
- switch(pMaterialParams->getDiffuseAlphaMode())
- {
- case LLMaterial::DIFFUSE_ALPHA_MODE_BLEND:
- case LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE:
- case LLMaterial::DIFFUSE_ALPHA_MODE_MASK:
- { //all of them modes available only for 32 bit textures
- LLTextureEntry* tex_entry = getTE(te);
- bool bIsBakedImageId = false;
- if (tex_entry && LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(tex_entry->getID()))
- {
- bIsBakedImageId = true;
- }
- if (GL_RGBA != img_diffuse->getPrimaryFormat() && !bIsBakedImageId)
- {
- bSetDiffuseNone = true;
- }
- } break;
- }
- } //else
-
-
- if(bSetDiffuseNone)
- { //upps... we should substitute this material with LLMaterial::DIFFUSE_ALPHA_MODE_NONE
- new_material = new LLMaterial(pMaterialParams->asLLSD());
- new_material->setDiffuseAlphaMode(LLMaterial::DIFFUSE_ALPHA_MODE_NONE);
- }
- }
- }
-
- //normal
- if(LLUUID::null != pMaterialParams->getNormalID())
- {
- if(img_normal && img_normal->isMissingAsset() && img_normal->getID() == pMaterialParams->getNormalID())
- {
- if(!new_material) {
- new_material = new LLMaterial(pMaterialParams->asLLSD());
- }
- new_material->setNormalID(LLUUID::null);
- }
- else if(NULL == img_normal || 0 == img_normal->getPrimaryFormat())
- { //ok here we don't have information about texture, let's belief and leave material settings
- //but we remember this case
- mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getNormalID(), material_info(LLRender::NORMAL_MAP,te)));
- }
-
- }
-
-
- //specular
- if(LLUUID::null != pMaterialParams->getSpecularID())
- {
- if(img_specular && img_specular->isMissingAsset() && img_specular->getID() == pMaterialParams->getSpecularID())
- {
- if(!new_material) {
- new_material = new LLMaterial(pMaterialParams->asLLSD());
- }
- new_material->setSpecularID(LLUUID::null);
- }
- else if(NULL == img_specular || 0 == img_specular->getPrimaryFormat())
- { //ok here we don't have information about texture, let's belief and leave material settings
- //but we remember this case
- mWaitingTextureInfo.insert(mmap_UUID_MAP_t::value_type(pMaterialParams->getSpecularID(), material_info(LLRender::SPECULAR_MAP, te)));
- }
- }
-
- if(new_material) {
- pMaterial = new_material;
- LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial);
- }
- }
-
- S32 res = LLViewerObject::setTEMaterialParams(te, pMaterial);
-
- LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterial) ? pMaterial->asLLSD() : LLSD("null")) << " res " << res
+ LL_DEBUGS("MaterialTEs") << "te " << (S32)te << " material " << ((pMaterialParams) ? pMaterialParams->asLLSD() : LLSD("null")) << " res " << res
<< ( LLSelectMgr::getInstance()->getSelection()->contains(const_cast<LLVOVolume*>(this), te) ? " selected" : " not selected" )
<< LL_ENDL;
setChanged(ALL_CHANGED);
@@ -2656,6 +2413,24 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
return TEM_CHANGE_TEXTURE;
}
+S32 LLVOVolume::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat)
+{
+ S32 retval = LLViewerObject::setTEGLTFMaterialOverride(te, mat);
+
+ if (retval == TEM_CHANGE_TEXTURE)
+ {
+ if (!mDrawable.isNull())
+ {
+ gPipeline.markTextured(mDrawable);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
+ }
+ mFaceMappingChanged = TRUE;
+ }
+
+ return retval;
+}
+
+
S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
{
S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -2689,15 +2464,6 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
return res;
}
-void LLVOVolume::updateTEData()
-{
- /*if (mDrawable.notNull())
- {
- mFaceMappingChanged = TRUE;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE);
- }*/
-}
-
bool LLVOVolume::hasMedia() const
{
bool result = false;
@@ -3364,7 +3130,13 @@ void LLVOVolume::setLightCutoff(F32 cutoff)
BOOL LLVOVolume::getIsLight() const
{
- return getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ mIsLight = getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT);
+ return mIsLight;
+}
+
+bool LLVOVolume::getIsLightFast() const
+{
+ return mIsLight;
}
LLColor3 LLVOVolume::getLightSRGBBaseColor() const
@@ -3441,6 +3213,11 @@ F32 LLVOVolume::getSpotLightPriority() const
void LLVOVolume::updateSpotLightPriority()
{
+ if (gCubeSnapshot)
+ {
+ return;
+ }
+
F32 r = getLightRadius();
LLVector3 pos = mDrawable->getPositionAgent();
@@ -3456,7 +3233,6 @@ void LLVOVolume::updateSpotLightPriority()
if (mLightTexture.notNull())
{
mLightTexture->addTextureStats(mSpotLightPriority);
- mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);
}
}
@@ -3480,7 +3256,7 @@ LLViewerTexture* LLVOVolume::getLightTexture()
{
if (mLightTexture.isNull() || id != mLightTexture->getID())
{
- mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM);
+ mLightTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE);
}
}
else
@@ -3543,6 +3319,143 @@ F32 LLVOVolume::getLightCutoff() const
}
}
+BOOL LLVOVolume::isReflectionProbe() const
+{
+ return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE);
+}
+
+bool LLVOVolume::setIsReflectionProbe(BOOL is_probe)
+{
+ BOOL was_probe = isReflectionProbe();
+ if (is_probe != was_probe)
+ {
+ if (is_probe)
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, TRUE, true);
+ }
+ else
+ {
+ setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, FALSE, true);
+ }
+ }
+
+ updateReflectionProbePtr();
+
+ return was_probe != is_probe;
+}
+
+bool LLVOVolume::setReflectionProbeAmbiance(F32 ambiance)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getAmbiance() != ambiance)
+ {
+ param_block->setAmbiance(ambiance);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLVOVolume::setReflectionProbeNearClip(F32 near_clip)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getClipDistance() != near_clip)
+ {
+ param_block->setClipDistance(near_clip);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLVOVolume::setReflectionProbeIsBox(bool is_box)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsBox() != is_box)
+ {
+ param_block->setIsBox(is_box);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic)
+{
+ LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ if (param_block->getIsDynamic() != is_dynamic)
+ {
+ param_block->setIsDynamic(is_dynamic);
+ parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+F32 LLVOVolume::getReflectionProbeAmbiance() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getAmbiance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+F32 LLVOVolume::getReflectionProbeNearClip() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getClipDistance();
+ }
+ else
+ {
+ return 0.f;
+ }
+}
+
+bool LLVOVolume::getReflectionProbeIsBox() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsBox();
+ }
+
+ return false;
+}
+
+bool LLVOVolume::getReflectionProbeIsDynamic() const
+{
+ const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE);
+ if (param_block)
+ {
+ return param_block->getIsDynamic();
+ }
+
+ return false;
+}
+
U32 LLVOVolume::getVolumeInterfaceID() const
{
if (mVolumeImpl)
@@ -3609,6 +3522,31 @@ BOOL LLVOVolume::hasLightTexture() const
return FALSE;
}
+bool LLVOVolume::isFlexibleFast() const
+{
+ return mVolumep && mVolumep->getParams().getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE;
+}
+
+bool LLVOVolume::isSculptedFast() const
+{
+ return mVolumep && mVolumep->getParams().isSculpt();
+}
+
+bool LLVOVolume::isMeshFast() const
+{
+ return mVolumep && mVolumep->getParams().isMeshSculpt();
+}
+
+bool LLVOVolume::isRiggedMeshFast() const
+{
+ return mSkinInfo.notNull();
+}
+
+bool LLVOVolume::isAnimatedObjectFast() const
+{
+ return mIsAnimatedObject;
+}
+
BOOL LLVOVolume::isVolumeGlobal() const
{
if (mVolumeImpl)
@@ -3668,7 +3606,7 @@ BOOL LLVOVolume::setIsFlexible(BOOL is_flexible)
res = setVolume(volume_params, 1);
if (res)
{
- markForUpdate(TRUE);
+ markForUpdate();
}
}
return res;
@@ -3716,7 +3654,7 @@ void LLVOVolume::onSetExtendedMeshFlags(U32 flags)
if (/*!getRootEdit()->isAnySelected() &&*/ mDrawable.notNull())
{
// Need to trigger rebuildGeom(), which is where control avatars get created/removed
- getRootEdit()->recursiveMarkForUpdate(TRUE);
+ getRootEdit()->recursiveMarkForUpdate();
}
if (isAttachment() && getAvatarAncestor())
{
@@ -3769,8 +3707,8 @@ bool LLVOVolume::canBeAnimatedObject() const
bool LLVOVolume::isAnimatedObject() const
{
LLVOVolume *root_vol = (LLVOVolume*)getRootEdit();
- bool root_is_animated_flag = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
- return root_is_animated_flag;
+ mIsAnimatedObject = root_vol->getExtendedMeshFlags() & LLExtendedMeshParams::ANIMATED_MESH_ENABLED_FLAG;
+ return mIsAnimatedObject;
}
// Called any time parenting changes for a volume. Update flags and
@@ -3957,12 +3895,41 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
return mDrawable->getWorldMatrix();
}
+//static
+S32 LLVOVolume::getTextureCost(const LLViewerTexture* img)
+{
+ static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
+
+ S32 texture_cost = 0;
+ S8 type = img->getType();
+ if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ {
+ const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
+ if (fetched_texturep
+ && fetched_texturep->getFTType() == FTT_LOCAL_FILE
+ && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
+ )
+ {
+ // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
+ // Hardcode cost from larger one to not cause random complexity changes
+ texture_cost = 320;
+ }
+ }
+ if (texture_cost == 0)
+ {
+ texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ }
+
+ return texture_cost;
+}
+
// Returns a base cost and adds textures to passed in set.
// total cost is returned value + 5 * size of the resulting set.
// Cannot include cost of textures, as they may be re-used in linked
// children, and cost should only be increased for unique textures -Nyx
U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
/*****************************************************************
* This calculation should not be modified by third party viewers,
* since it is used to limit rendering and should be uniform for
@@ -3972,17 +3939,16 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Get access to params we'll need at various points.
// Skip if this is object doesn't have a volume (e.g. is an avatar).
- BOOL has_volume = (getVolume() != NULL);
- LLVolumeParams volume_params;
- LLPathParams path_params;
- LLProfileParams profile_params;
+ if (getVolume() == NULL)
+ {
+ return 0;
+ }
U32 num_triangles = 0;
// per-prim costs
static const U32 ARC_PARTICLE_COST = 1; // determined experimentally
static const U32 ARC_PARTICLE_MAX = 2048; // default values
- static const U32 ARC_TEXTURE_COST = 16; // multiplier for texture resolution - performance tested
static const U32 ARC_LIGHT_COST = 500; // static cost for light-producing prims
static const U32 ARC_MEDIA_FACE_COST = 1500; // static cost per media-enabled face
@@ -4017,45 +3983,41 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
const LLDrawable* drawablep = mDrawable;
U32 num_faces = drawablep->getNumFaces();
- if (has_volume)
- {
- volume_params = getVolume()->getParams();
- path_params = volume_params.getPathParams();
- profile_params = volume_params.getProfileParams();
+ const LLVolumeParams& volume_params = getVolume()->getParams();
- LLMeshCostData costs;
- if (getCostData(costs))
- {
- if (isAnimatedObject() && isRiggedMesh())
- {
- // Scaling here is to make animated object vs
- // non-animated object ARC proportional to the
- // corresponding calculations for streaming cost.
- num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
- }
- else
- {
- F32 radius = getScale().length()*0.5f;
- num_triangles = costs.getRadiusWeightedTris(radius);
- }
- }
+ LLMeshCostData costs;
+ if (getCostData(costs))
+ {
+ if (isAnimatedObjectFast() && isRiggedMeshFast())
+ {
+ // Scaling here is to make animated object vs
+ // non-animated object ARC proportional to the
+ // corresponding calculations for streaming cost.
+ num_triangles = (ANIMATED_OBJECT_COST_PER_KTRI * 0.001 * costs.getEstTrisForStreamingCost())/0.06;
+ }
+ else
+ {
+ F32 radius = getScale().length()*0.5f;
+ num_triangles = costs.getRadiusWeightedTris(radius);
+ }
}
+
if (num_triangles <= 0)
{
num_triangles = 4;
}
- if (isSculpted())
+ if (isSculptedFast())
{
- if (isMesh())
+ if (isMeshFast())
{
// base cost is dependent on mesh complexity
// note that 3 is the highest LOD as of the time of this coding.
S32 size = gMeshRepo.getMeshSize(volume_params.getSculptID(), getLOD());
if ( size > 0)
{
- if (isRiggedMesh())
+ if (isRiggedMeshFast())
{
// weighted attachment - 1 point for every 3 bytes
weighted_mesh = 1;
@@ -4069,21 +4031,15 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
}
else
{
- const LLSculptParams *sculpt_params = (LLSculptParams *) getParameterEntry(LLNetworkData::PARAMS_SCULPT);
- LLUUID sculpt_id = sculpt_params->getSculptTexture();
- if (textures.find(sculpt_id) == textures.end())
+ LLViewerFetchedTexture* texture = mSculptTexture;
+ if (texture && textures.find(texture) == textures.end())
{
- LLViewerFetchedTexture *texture = LLViewerTextureManager::getFetchedTexture(sculpt_id);
- if (texture)
- {
- S32 texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (texture->getFullHeight() / 128.f + texture->getFullWidth() / 128.f));
- textures.insert(texture_cost_t::value_type(sculpt_id, texture_cost));
- }
+ textures.insert(texture);
}
}
}
- if (isFlexible())
+ if (isFlexibleFast())
{
flexi = 1;
}
@@ -4092,85 +4048,66 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
particles = 1;
}
- if (getIsLight())
+ if (getIsLightFast())
{
produces_light = 1;
}
- for (S32 i = 0; i < num_faces; ++i)
- {
- const LLFace* face = drawablep->getFace(i);
- if (!face) continue;
- const LLTextureEntry* te = face->getTextureEntry();
- const LLViewerTexture* img = face->getTexture();
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_VOLUME("ARC - face list");
+ for (S32 i = 0; i < num_faces; ++i)
+ {
+ const LLFace* face = drawablep->getFace(i);
+ if (!face) continue;
+ const LLTextureEntry* te = face->getTextureEntry();
+ const LLViewerTexture* img = face->getTexture();
- if (img)
- {
- if (textures.find(img->getID()) == textures.end())
- {
- S32 texture_cost = 0;
- S8 type = img->getType();
- if (type == LLViewerTexture::FETCHED_TEXTURE || type == LLViewerTexture::LOD_TEXTURE)
+ if (img)
+ {
+ textures.insert(img);
+ }
+
+ if (face->isInAlphaPool())
+ {
+ alpha = 1;
+ }
+ else if (img && img->getPrimaryFormat() == GL_ALPHA)
+ {
+ invisi = 1;
+ }
+ if (face->hasMedia())
+ {
+ media_faces++;
+ }
+
+ if (te)
+ {
+ if (te->getBumpmap())
{
- const LLViewerFetchedTexture* fetched_texturep = static_cast<const LLViewerFetchedTexture*>(img);
- if (fetched_texturep
- && fetched_texturep->getFTType() == FTT_LOCAL_FILE
- && (img->getID() == IMG_ALPHA_GRAD_2D || img->getID() == IMG_ALPHA_GRAD)
- )
- {
- // These two textures appear to switch between each other, but are of different sizes (4x256 and 256x256).
- // Hardcode cost from larger one to not cause random complexity changes
- texture_cost = 320;
- }
+ // bump is a multiplier, don't add per-face
+ bump = 1;
}
- if (texture_cost == 0)
+ if (te->getShiny())
{
- texture_cost = 256 + (S32)(ARC_TEXTURE_COST * (img->getFullHeight() / 128.f + img->getFullWidth() / 128.f));
+ // shiny is a multiplier, don't add per-face
+ shiny = 1;
}
- textures.insert(texture_cost_t::value_type(img->getID(), texture_cost));
- }
- }
-
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
- {
- alpha = 1;
- }
- else if (img && img->getPrimaryFormat() == GL_ALPHA)
- {
- invisi = 1;
- }
- if (face->hasMedia())
- {
- media_faces++;
- }
-
- if (te)
- {
- if (te->getBumpmap())
- {
- // bump is a multiplier, don't add per-face
- bump = 1;
- }
- if (te->getShiny())
- {
- // shiny is a multiplier, don't add per-face
- shiny = 1;
- }
- if (te->getGlow() > 0.f)
- {
- // glow is a multiplier, don't add per-face
- glow = 1;
- }
- if (face->mTextureMatrix != NULL)
- {
- animtex = 1;
- }
- if (te->getTexGen())
- {
- planar = 1;
- }
- }
- }
+ if (te->getGlow() > 0.f)
+ {
+ // glow is a multiplier, don't add per-face
+ glow = 1;
+ }
+ if (face->mTextureMatrix != NULL)
+ {
+ animtex = 1;
+ }
+ if (te->getTexGen())
+ {
+ planar = 1;
+ }
+ }
+ }
+ }
// shame currently has the "base" cost of 1 point per 15 triangles, min 2.
shame = num_triangles * 5.f;
@@ -4249,7 +4186,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
// Streaming cost for animated objects includes a fixed cost
// per linkset. Add a corresponding charge here translated into
// triangles, but not weighted by any graphics properties.
- if (isAnimatedObject() && isRootEdit())
+ if (isAnimatedObjectFast() && isRootEdit())
{
shame += (ANIMATED_OBJECT_BASE_COST/0.06) * 5.0f;
}
@@ -4264,7 +4201,7 @@ U32 LLVOVolume::getRenderCost(texture_cost_t &textures) const
F32 LLVOVolume::getEstTrianglesMax() const
{
- if (isMesh() && getVolume())
+ if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesMax(getVolume()->getParams().getSculptID());
}
@@ -4273,7 +4210,7 @@ F32 LLVOVolume::getEstTrianglesMax() const
F32 LLVOVolume::getEstTrianglesStreamingCost() const
{
- if (isMesh() && getVolume())
+ if (isMeshFast() && getVolume())
{
return gMeshRepo.getEstTrianglesStreamingCost(getVolume()->getParams().getSculptID());
}
@@ -4288,7 +4225,7 @@ F32 LLVOVolume::getStreamingCost() const
LLMeshCostData costs;
if (getCostData(costs))
{
- if (isAnimatedObject() && isRootEdit())
+ if (isRootEdit() && isAnimatedObject())
{
// Root object of an animated object has this to account for skeleton overhead.
linkset_base_cost = ANIMATED_OBJECT_BASE_COST;
@@ -4318,7 +4255,9 @@ F32 LLVOVolume::getStreamingCost() const
// virtual
bool LLVOVolume::getCostData(LLMeshCostData& costs) const
{
- if (isMesh())
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+
+ if (isMeshFast())
{
return gMeshRepo.getCostData(getVolume()->getParams().getSculptID(), costs);
}
@@ -4328,11 +4267,11 @@ bool LLVOVolume::getCostData(LLMeshCostData& costs) const
S32 counts[4];
LLVolume::getLoDTriangleCounts(volume->getParams(), counts);
- LLSD header;
- header["lowest_lod"]["size"] = counts[0] * 10;
- header["low_lod"]["size"] = counts[1] * 10;
- header["medium_lod"]["size"] = counts[2] * 10;
- header["high_lod"]["size"] = counts[3] * 10;
+ LLMeshHeader header;
+ header.mLodSize[0] = counts[0] * 10;
+ header.mLodSize[1] = counts[1] * 10;
+ header.mLodSize[2] = counts[2] * 10;
+ header.mLodSize[3] = counts[3] * 10;
return gMeshRepo.getCostData(header, costs);
}
@@ -4428,6 +4367,23 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u
gPipeline.setLight(mDrawable, is_light);
}
}
+
+ updateReflectionProbePtr();
+}
+
+void LLVOVolume::updateReflectionProbePtr()
+{
+ if (isReflectionProbe())
+ {
+ if (mReflectionProbe.isNull())
+ {
+ mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this);
+ }
+ }
+ else if (mReflectionProbe.notNull())
+ {
+ mReflectionProbe = nullptr;
+ }
}
void LLVOVolume::setSelected(BOOL sel)
@@ -4435,13 +4391,13 @@ void LLVOVolume::setSelected(BOOL sel)
LLViewerObject::setSelected(sel);
if (isAnimatedObject())
{
- getRootEdit()->recursiveMarkForUpdate(TRUE);
+ getRootEdit()->recursiveMarkForUpdate();
}
else
{
if (mDrawable.notNull())
{
- markForUpdate(TRUE);
+ markForUpdate();
}
}
}
@@ -4453,83 +4409,61 @@ void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
F32 LLVOVolume::getBinRadius()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- F32 radius;
-
- F32 scale = 1.f;
+ F32 radius;
- static LLCachedControl<S32> octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3);
- static LLCachedControl<S32> octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4);
- static LLCachedControl<LLVector3> octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f));
- static LLCachedControl<LLVector3> octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f));
+ static LLCachedControl<S32> octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3);
+ static LLCachedControl<S32> octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4);
+ static LLCachedControl<LLVector3> octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f));
+ static LLCachedControl<LLVector3> octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f));
- S32 size_factor = llmax((S32)octree_size_factor, 1);
- S32 attachment_size_factor = llmax((S32)octree_attachment_size_factor, 1);
- LLVector3 distance_factor = octree_distance_factor;
- LLVector3 alpha_distance_factor = octree_alpha_distance_factor;
+ S32 size_factor = llmax((S32)octree_size_factor, 1);
+ LLVector3 alpha_distance_factor = octree_alpha_distance_factor;
- const LLVector4a* ext = mDrawable->getSpatialExtents();
-
- BOOL shrink_wrap = mDrawable->isAnimating();
- BOOL alpha_wrap = FALSE;
+ //const LLVector4a* ext = mDrawable->getSpatialExtents();
- if (!isHUDAttachment())
- {
- for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
- {
- LLFace* face = mDrawable->getFace(i);
- if (!face) continue;
- if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
- !face->canRenderAsMask())
- {
- alpha_wrap = TRUE;
- break;
- }
- }
- }
- else
- {
- shrink_wrap = FALSE;
- }
+ bool shrink_wrap = mShouldShrinkWrap || mDrawable->isAnimating();
+ bool alpha_wrap = FALSE;
- if (alpha_wrap)
- {
- LLVector3 bounds = getScale();
- radius = llmin(bounds.mV[1], bounds.mV[2]);
- radius = llmin(radius, bounds.mV[0]);
- radius *= 0.5f;
- radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1];
- radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0];
- }
- else if (shrink_wrap)
- {
- LLVector4a rad;
- rad.setSub(ext[1], ext[0]);
-
- radius = rad.getLength3().getF32()*0.5f;
- }
- else if (mDrawable->isStatic())
- {
- F32 szf = size_factor;
-
- radius = llmax(mDrawable->getRadius(), szf);
-
- radius = powf(radius, 1.f+szf/radius);
+ if (!isHUDAttachment() && mDrawable->mDistanceWRTCamera < alpha_distance_factor[2])
+ {
+ for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
+ {
+ LLFace* face = mDrawable->getFace(i);
+ if (!face) continue;
+ if (face->isInAlphaPool() &&
+ !face->canRenderAsMask())
+ {
+ alpha_wrap = TRUE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ shrink_wrap = FALSE;
+ }
- radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1];
- radius += mDrawable->mDistanceWRTCamera * distance_factor[0];
- }
- else if (mDrawable->getVObj()->isAttachment())
- {
- radius = llmax((S32) mDrawable->getRadius(),1)*attachment_size_factor;
- }
- else
- {
- radius = mDrawable->getRadius();
- radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1];
- radius += mDrawable->mDistanceWRTCamera * distance_factor[0];
- }
+ if (alpha_wrap)
+ {
+ LLVector3 bounds = getScale();
+ radius = llmin(bounds.mV[1], bounds.mV[2]);
+ radius = llmin(radius, bounds.mV[0]);
+ radius *= 0.5f;
+ //radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1];
+ //radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0];
+ }
+ else if (shrink_wrap)
+ {
+ radius = mDrawable->getRadius() * 0.25f;
+ }
+ else
+ {
+ F32 szf = size_factor;
+ radius = llmax(mDrawable->getRadius(), szf);
+ //radius = llmax(radius, mDrawable->mDistanceWRTCamera * distance_factor[0]);
+ }
- return llclamp(radius*scale, 0.5f, 256.f);
+ return llclamp(radius, 0.5f, 256.f);
}
const LLVector3 LLVOVolume::getPivotPositionAgent() const
@@ -4560,19 +4494,14 @@ const LLMatrix4& LLVOVolume::getWorldMatrix(LLXformMatrix* xform) const
return xform->getWorldMatrix();
}
-void LLVOVolume::markForUpdate(BOOL priority)
+void LLVOVolume::markForUpdate()
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
+ if (mDrawable)
{
- if (isAnimatedObject() && isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", this);
- F32 est_tris = getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markForUpdate, tris " << est_tris << LL_ENDL;
- }
+ shrinkWrap();
}
- LLViewerObject::markForUpdate(priority);
+ LLViewerObject::markForUpdate();
mVolumeChanged = TRUE;
}
@@ -4627,7 +4556,7 @@ LLVector3 LLVOVolume::volumeDirectionToAgent(const LLVector3& dir) const
}
-BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, S32 *face_hitp,
+BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end, S32 face, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_unselectable, S32 *face_hitp,
LLVector4a* intersection,LLVector2* tex_coord, LLVector4a* normal, LLVector4a* tangent)
{
@@ -4638,6 +4567,14 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
return FALSE;
}
+ if (!pick_unselectable)
+ {
+ if (!LLSelectMgr::instance().canSelectObject(this, TRUE))
+ {
+ return FALSE;
+ }
+ }
+
BOOL ret = FALSE;
LLVolume* volume = getVolume();
@@ -4714,7 +4651,12 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
end_face = face+1;
}
pick_transparent |= isHiglightedOrBeacon();
- bool special_cursor = specialHoverCursor();
+
+ // we *probably* shouldn't care about special cursor at all, but we *definitely*
+ // don't care about special cursor for reflection probes -- makes alt-zoom
+ // go through reflection probes on vehicles
+ bool special_cursor = mReflectionProbe.isNull() && specialHoverCursor();
+
for (S32 i = start_face; i < end_face; ++i)
{
if (!special_cursor && !pick_transparent && getTE(i) && getTE(i)->getColor().mV[3] == 0.f)
@@ -4887,7 +4829,12 @@ void LLVOVolume::updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::
mRiggedVolume->update(skin, avatar, volume, face_index, rebuild_face_octrees);
}
-void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* volume, FaceIndex face_index, bool rebuild_face_octrees)
+void LLRiggedVolume::update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* volume,
+ FaceIndex face_index,
+ bool rebuild_face_octrees)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
bool copy = false;
@@ -5071,7 +5018,7 @@ U32 LLVOVolume::getPartitionType() const
}
LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp)
-: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB, regionp),
+: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, regionp),
LLVolumeGeometryManager()
{
mLODPeriod = 32;
@@ -5079,7 +5026,6 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_VOLUME;
mSlopRatio = 0.25f;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp)
@@ -5091,8 +5037,6 @@ LLVolumeGeometryManager()
mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
- mBufferUsage = GL_DYNAMIC_DRAW_ARB;
-
mSlopRatio = 0.25f;
}
@@ -5156,6 +5100,11 @@ bool can_batch_texture(LLFace* facep)
return false;
}
+ if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr)
+ { // PBR materials break indexed texture batching
+ return false;
+ }
+
return true;
}
@@ -5167,6 +5116,7 @@ LLFace** LLVolumeGeometryManager::sSimpleFaces[2] = { NULL };
LLFace** LLVolumeGeometryManager::sNormFaces[2] = { NULL };
LLFace** LLVolumeGeometryManager::sSpecFaces[2] = { NULL };
LLFace** LLVolumeGeometryManager::sNormSpecFaces[2] = { NULL };
+LLFace** LLVolumeGeometryManager::sPbrFaces[2] = { NULL };
LLFace** LLVolumeGeometryManager::sAlphaFaces[2] = { NULL };
LLVolumeGeometryManager::LLVolumeGeometryManager()
@@ -5203,6 +5153,7 @@ void LLVolumeGeometryManager::allocateFaces(U32 pMaxFaceCount)
sNormFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
sSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
sNormSpecFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
+ sPbrFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
sAlphaFaces[i] = static_cast<LLFace**>(ll_aligned_malloc<64>(pMaxFaceCount * sizeof(LLFace*)));
}
}
@@ -5217,6 +5168,7 @@ void LLVolumeGeometryManager::freeFaces()
ll_aligned_free<64>(sNormFaces[i]);
ll_aligned_free<64>(sSpecFaces[i]);
ll_aligned_free<64>(sNormSpecFaces[i]);
+ ll_aligned_free<64>(sPbrFaces[i]);
ll_aligned_free<64>(sAlphaFaces[i]);
sFullbrightFaces[i] = NULL;
@@ -5225,6 +5177,7 @@ void LLVolumeGeometryManager::freeFaces()
sNormFaces[i] = NULL;
sSpecFaces[i] = NULL;
sNormSpecFaces[i] = NULL;
+ sPbrFaces[i] = NULL;
sAlphaFaces[i] = NULL;
}
}
@@ -5247,6 +5200,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
return;
}
+ LL_LABEL_VERTEX_BUFFER(facep->getVertexBuffer(), LLRenderPass::lookupPassName(type));
+
U32 passType = type;
bool rigged = facep->isState(LLFace::RIGGED);
@@ -5262,14 +5217,17 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
S32 idx = draw_vec.size()-1;
- BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
+ bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
(type == LLRenderPass::PASS_INVISIBLE) ||
(type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) ||
(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) ||
(facep->getTextureEntry()->getFullbright());
- if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
+ if (!fullbright &&
+ type != LLRenderPass::PASS_GLOW &&
+ !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_NORMAL))
{
+ llassert(false);
LL_WARNS() << "Non fullbright face has no normals!" << LL_ENDL;
return;
}
@@ -5311,8 +5269,28 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U8 index = facep->getTextureIndex();
- LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get();
- LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID();
+ LLMaterial* mat = nullptr;
+
+ LLUUID mat_id;
+
+ auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial();
+ llassert(gltf_mat == nullptr || dynamic_cast<LLFetchedGLTFMaterial*>(facep->getTextureEntry()->getGLTFRenderMaterial()) != nullptr);
+ if (gltf_mat != nullptr)
+ {
+ mat_id = gltf_mat->getHash(); // TODO: cache this hash
+ if (!facep->hasMedia())
+ { // no media texture, face texture will be unused
+ tex = nullptr;
+ }
+ }
+ else
+ {
+ mat = facep->getTextureEntry()->getMaterialParams().get();
+ if (mat)
+ {
+ mat_id = facep->getTextureEntry()->getMaterialParams()->getHash();
+ }
+ }
bool batchable = false;
@@ -5331,11 +5309,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
- F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale?
-
if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0)
{
- if (mat || draw_vec[idx]->mMaterial)
+ if (mat || gltf_mat || draw_vec[idx]->mMaterial)
{ //can't batch textures when materials are present (yet)
batchable = false;
}
@@ -5345,12 +5321,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{
batchable = true;
draw_vec[idx]->mTextureList[index] = tex;
- draw_vec[idx]->mTextureListVSize[index] = vsize;
}
else if (draw_vec[idx]->mTextureList[index] == tex)
{ //this face's texture index can be used with this batch
batchable = true;
- draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]);
}
}
else
@@ -5359,40 +5333,35 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
}
- if (idx >= 0 &&
- draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&
- draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ LLDrawInfo* info = idx >= 0 ? draw_vec[idx] : nullptr;
+
+ if (info &&
+ info->mVertexBuffer == facep->getVertexBuffer() &&
+ info->mEnd == facep->getGeomIndex()-1 &&
(LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex || batchable) &&
#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 &&
+ info->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
+ info->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
#endif
- //draw_vec[idx]->mMaterial == mat &&
- draw_vec[idx]->mMaterialID == mat_id &&
- draw_vec[idx]->mFullbright == fullbright &&
- draw_vec[idx]->mBump == bump &&
- (!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
- draw_vec[idx]->mTextureMatrix == tex_mat &&
- draw_vec[idx]->mModelMatrix == model_mat &&
- draw_vec[idx]->mShaderMask == shader_mask &&
- draw_vec[idx]->mSelected == selected &&
- draw_vec[idx]->mAvatar == facep->mAvatar &&
- draw_vec[idx]->getSkinHash() == facep->getSkinHash())
- {
- draw_vec[idx]->mCount += facep->getIndicesCount();
- draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
-
- if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size())
- {
- draw_vec[idx]->mTextureList.resize(index+1);
- draw_vec[idx]->mTextureList[index] = tex;
- draw_vec[idx]->mTextureListVSize.resize(index + 1);
- draw_vec[idx]->mTextureListVSize[index] = vsize;
- }
- draw_vec[idx]->validate();
- update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
- update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
+ info->mMaterialID == mat_id &&
+ info->mFullbright == fullbright &&
+ info->mBump == bump &&
+ (!mat || (info->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
+ info->mTextureMatrix == tex_mat &&
+ info->mModelMatrix == model_mat &&
+ info->mShaderMask == shader_mask &&
+ info->mAvatar == facep->mAvatar &&
+ info->getSkinHash() == facep->getSkinHash())
+ {
+ info->mCount += facep->getIndicesCount();
+ info->mEnd += facep->getGeomCount();
+
+ if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= info->mTextureList.size())
+ {
+ info->mTextureList.resize(index+1);
+ info->mTextureList[index] = tex;
+ }
+ info->validate();
}
else
{
@@ -5400,10 +5369,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
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->getVertexBuffer(), selected, fullbright, bump);
- draw_info->mGroup = group;
- draw_info->mVSize = vsize;
+ LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
+ facep->getVertexBuffer(), fullbright, bump);
+
+ info = draw_info;
+
draw_vec.push_back(draw_info);
draw_info->mTextureMatrix = tex_mat;
draw_info->mModelMatrix = model_mat;
@@ -5424,11 +5394,17 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_info->mEnvIntensity = spec;
draw_info->mSpecularMap = NULL;
draw_info->mMaterial = mat;
+ draw_info->mGLTFMaterial = gltf_mat;
draw_info->mShaderMask = shader_mask;
draw_info->mAvatar = facep->mAvatar;
draw_info->mSkinInfo = facep->mSkinInfo;
- if (mat)
+ if (gltf_mat)
+ {
+ // just remember the material ID, render pools will reference the GLTF material
+ draw_info->mMaterialID = mat_id;
+ }
+ else if (mat)
{
draw_info->mMaterialID = mat_id;
@@ -5466,23 +5442,24 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
{ //for alpha sorting
facep->setDrawInfo(draw_info);
}
- draw_info->mExtents[0] = facep->mExtents[0];
- draw_info->mExtents[1] = facep->mExtents[1];
-
- if (LLPipeline::sUseTriStrips)
- {
- draw_info->mDrawMode = LLRender::TRIANGLE_STRIP;
- }
if (index < FACE_DO_NOT_BATCH_TEXTURES)
{ //initialize texture list for texture batching
draw_info->mTextureList.resize(index+1);
draw_info->mTextureList[index] = tex;
- draw_info->mTextureListVSize.resize(index + 1);
- draw_info->mTextureListVSize[index] = vsize;
}
draw_info->validate();
}
+
+ llassert(info->mGLTFMaterial == nullptr || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0);
+ llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR || info->mGLTFMaterial != nullptr);
+ llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED || info->mGLTFMaterial != nullptr);
+ llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK || info->mGLTFMaterial != nullptr);
+ llassert(type != LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED || info->mGLTFMaterial != nullptr);
+
+ llassert(type != LLRenderPass::PASS_BUMP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TANGENT) != 0);
+ llassert(type != LLRenderPass::PASS_NORMSPEC || info->mNormalMap.notNull());
+ llassert(type != LLRenderPass::PASS_SPECMAP || (info->mVertexBuffer->getTypeMask() & LLVertexBuffer::MAP_TEXCOORD2) != 0);
}
void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
@@ -5490,81 +5467,6 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
}
-void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)
-{
- static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
-
- if (0 != render_auto_mute_byte_limit)
- {
- //for unload
- LLSculptIDSize::container_BY_SIZE_view::iterator
- itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().lower_bound(render_auto_mute_byte_limit),
- itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
-
- for (; itL != itU; ++itL)
- {
- const LLSculptIDSize::Info &nfo = *itL;
- LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
- if (pVVol
- && !pVVol->isDead()
- && pVVol->isAttachment()
- && !pVVol->getAvatar()->isSelf()
- && LLVOVolume::NO_LOD != pVVol->getLOD()
- )
- {
- //postponed
- pVVol->markForUnload();
- LLSculptIDSize::instance().addToUnloaded(nfo.getSculptId());
- }
- }
-
- //for load if it was unload
- itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin();
- itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().upper_bound(render_auto_mute_byte_limit);
-
- for (; itL != itU; ++itL)
- {
- const LLSculptIDSize::Info &nfo = *itL;
- LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
- if (pVVol
- && !pVVol->isDead()
- && pVVol->isAttachment()
- && !pVVol->getAvatar()->isSelf()
- && LLVOVolume::NO_LOD == pVVol->getLOD()
- )
- {
- LLSculptIDSize::instance().remFromUnloaded(nfo.getSculptId());
- pVVol->updateLOD();
- pVVol->markForUpdate(TRUE);
- }
- }
- }
- else
- {
- LLSculptIDSize::instance().clearUnloaded();
-
- LLSculptIDSize::container_BY_SIZE_view::iterator
- itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin(),
- itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
-
- for (; itL != itU; ++itL)
- {
- const LLSculptIDSize::Info &nfo = *itL;
- LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
- if (pVVol
- && !pVVol->isDead()
- && pVVol->isAttachment()
- && !pVVol->getAvatar()->isSelf()
- && LLVOVolume::NO_LOD == pVVol->getLOD()
- )
- {
- pVVol->updateLOD();
- pVVol->markForUpdate(TRUE);
- }
- }
- }
-}
-
// add a face pointer to a list of face pointers without going over MAX_COUNT faces
template<typename T>
static inline void add_face(T*** list, U32* count, T* face)
@@ -5590,6 +5492,7 @@ static inline void add_face(T*** list, U32* count, T* face)
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
+ llassert(!gCubeSnapshot);
if (group->changeLOD())
{
@@ -5600,7 +5503,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (!group->hasState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
{
- if (group->hasState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
+ if (group->hasState(LLSpatialGroup::MESH_DIRTY))
{
rebuildMesh(group);
}
@@ -5639,8 +5542,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 norm_count[2] = { 0 };
U32 spec_count[2] = { 0 };
U32 normspec_count[2] = { 0 };
-
- U32 useage = group->getSpatialPartition()->mBufferUsage;
+ U32 pbr_count[2] = { 0 };
static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
static LLCachedControl<S32> max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536);
@@ -5663,7 +5565,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
LL_PROFILE_ZONE_NAMED("rebuildGeom - face list");
//get all the faces into a list
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin();
drawable_iter != group->getDataEnd(); ++drawable_iter)
{
@@ -5674,11 +5575,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- useage = GL_STREAM_DRAW_ARB;
- }
-
LLVOVolume* vobj = drawablep->getVOVolume();
if (!vobj)
@@ -5686,18 +5582,32 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
continue;
}
+ // HACK -- brute force this check every time a drawable gets rebuilt
+ for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
+ {
+ vobj->updateTEMaterialTextures(i);
+ }
+
+ // apply any pending material overrides
+ gGLTFMaterialList.applyQueuedOverrides(vobj);
+
std::string vobj_name = llformat("Vol%p", vobj);
bool is_mesh = vobj->isMesh();
- if (is_mesh &&
- ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
- {
- continue;
- }
-
- if(vobj->isAttachment())
+ if (is_mesh)
{
- trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED),&ratPtr);
+ if ((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded())
+ || !gMeshRepo.meshRezEnabled())
+ {
+ // Waiting for asset to fetch
+ continue;
+ }
+
+ if (!vobj->getSkinInfo() && !vobj->isSkinInfoUnavaliable())
+ {
+ // Waiting for skin info to fetch
+ continue;
+ }
}
LLVolume* volume = vobj->getVolume();
@@ -5762,7 +5672,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
rigged = rigged || (vobj->isAnimatedObject() && vobj->isRiggedMesh() &&
vobj->getControlAvatar() && vobj->getControlAvatar()->mPlaying);
- bool bake_sunlight = LLPipeline::sBakeSunlight && drawablep->isStatic();
bool any_rigged_face = false;
//for each face
@@ -5773,6 +5682,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
continue;
}
+#if 0
+#if LL_RELEASE_WITH_DEBUG_INFO
+ const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" );
+ const LLUUID obj_id( vobj->getID() );
+ bool is_pbr = (obj_id == pbr_id);
+#else
+ bool is_pbr = false;
+#endif
+#else
+ LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial();
+ bool is_pbr = gltf_mat != nullptr;
+#endif
//ALWAYS null out vertex buffer on rebuild -- if the face lands in a render
// batch, it will recover its vertex buffer reference from the spatial group
@@ -5824,7 +5745,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
const LLTextureEntry* te = facep->getTextureEntry();
LLViewerTexture* tex = facep->getTexture();
- if (te->getGlow() >= 1.f/255.f)
+ if (te->getGlow() > 0.f)
{
emissive = true;
}
@@ -5839,13 +5760,18 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
BOOL force_simple = (facep->getPixelArea() < FORCE_SIMPLE_RENDER_AREA);
U32 type = gPipeline.getPoolTypeFromTE(te, tex);
+ if (is_pbr && gltf_mat && gltf_mat->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ type = LLDrawPool::POOL_GLTF_PBR;
+ }
+ else
if (type != LLDrawPool::POOL_ALPHA && force_simple)
{
type = LLDrawPool::POOL_SIMPLE;
}
facep->setPoolType(type);
- if (vobj->isHUDAttachment())
+ if (vobj->isHUDAttachment() && !is_pbr)
{
facep->setState(LLFace::FULLBRIGHT);
}
@@ -5882,7 +5808,16 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
else
{
- if (te->getColor().mV[3] > 0.f || te->getGlow() > 0.f)
+ F32 alpha;
+ if (is_pbr)
+ {
+ alpha = gltf_mat ? gltf_mat->mBaseColor.mV[3] : 1.0;
+ }
+ else
+ {
+ alpha = te->getColor().mV[3];
+ }
+ if (alpha > 0.f || te->getGlow() > 0.f)
{ //only treat as alpha in the pipeline if < 100% transparent
drawablep->setState(LLDrawable::HAS_ALPHA);
add_face(sAlphaFaces, alpha_count, facep);
@@ -5905,31 +5840,39 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
facep->mLastUpdateTime = gFrameTimeSeconds;
}
- if (gPipeline.canUseWindLightShadersOnObjects()
- && LLPipeline::sRenderBump)
{
- if (LLPipeline::sRenderDeferred && te->getMaterialParams().notNull() && !te->getMaterialID().isNull())
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
+
+ if (gltf_mat != nullptr || (te->getMaterialParams().notNull()))
{
- LLMaterial* mat = te->getMaterialParams().get();
- if (mat->getNormalID().notNull())
- {
- if (mat->getSpecularID().notNull())
- { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
- add_face(sNormSpecFaces, normspec_count, facep);
- }
- else
- { //has normal map (needs texcoord1 and tangent)
- add_face(sNormFaces, norm_count, facep);
- }
- }
- else if (mat->getSpecularID().notNull())
- { //has specular map but no normal map, needs texcoord2
- add_face(sSpecFaces, spec_count, facep);
- }
- else
- { //has neither specular map nor normal map, only needs texcoord0
- add_face(sSimpleFaces, simple_count, facep);
- }
+ if (gltf_mat != nullptr)
+ {
+ add_face(sPbrFaces, pbr_count, facep);
+ }
+ else
+ {
+ LLMaterial* mat = te->getMaterialParams().get();
+ if (mat->getNormalID().notNull() || // <-- has a normal map, needs tangents
+ (te->getBumpmap() && (te->getBumpmap() < 18))) // <-- has an emboss bump map, needs tangents
+ {
+ if (mat->getSpecularID().notNull())
+ { //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
+ add_face(sNormSpecFaces, normspec_count, facep);
+ }
+ else
+ { //has normal map (needs texcoord1 and tangent)
+ add_face(sNormFaces, norm_count, facep);
+ }
+ }
+ else if (mat->getSpecularID().notNull())
+ { //has specular map but no normal map, needs texcoord2
+ add_face(sSpecFaces, spec_count, facep);
+ }
+ else
+ { //has neither specular map nor normal map, only needs texcoord0
+ add_face(sSimpleFaces, simple_count, facep);
+ }
+ }
}
else if (te->getBumpmap())
{ //needs normal + tangent
@@ -5945,23 +5888,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
add_face(sFullbrightFaces, fullbright_count, facep);
}
}
- else
- {
- if (te->getBumpmap() && LLPipeline::sRenderBump)
- { //needs normal + tangent
- add_face(sBumpFaces, bump_count, facep);
- }
- else if ((te->getShiny() && LLPipeline::sRenderBump) ||
- !(te->getFullbright() || bake_sunlight))
- { //needs normal
- add_face(sSimpleFaces, simple_count, facep);
- }
- else
- { //doesn't need normal
- facep->setState(LLFace::FULLBRIGHT);
- add_face(sFullbrightFaces, fullbright_count, facep);
- }
- }
}
}
else
@@ -5994,8 +5920,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
}
- group->mBufferUsage = useage;
-
//PROCESS NON-ALPHA FACES
U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
@@ -6006,6 +5930,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
U32 normspec_mask = norm_mask | LLVertexBuffer::MAP_TEXCOORD2;
U32 spec_mask = simple_mask | LLVertexBuffer::MAP_TEXCOORD2;
+ U32 pbr_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TANGENT;
+
if (emissive)
{ //emissive faces are present, include emissive byte to preserve batching
simple_mask = simple_mask | LLVertexBuffer::MAP_EMISSIVE;
@@ -6015,6 +5941,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
norm_mask = norm_mask | LLVertexBuffer::MAP_EMISSIVE;
normspec_mask = normspec_mask | LLVertexBuffer::MAP_EMISSIVE;
spec_mask = spec_mask | LLVertexBuffer::MAP_EMISSIVE;
+ pbr_mask = pbr_mask | LLVertexBuffer::MAP_EMISSIVE;
}
BOOL batch_textures = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 1;
@@ -6045,6 +5972,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
geometryBytes += genDrawInfo(group, norm_mask | extra_mask, sNormFaces[i], norm_count[i], FALSE, FALSE, rigged);
geometryBytes += genDrawInfo(group, spec_mask | extra_mask, sSpecFaces[i], spec_count[i], FALSE, FALSE, rigged);
geometryBytes += genDrawInfo(group, normspec_mask | extra_mask, sNormSpecFaces[i], normspec_count[i], FALSE, FALSE, rigged);
+ geometryBytes += genDrawInfo(group, pbr_mask | extra_mask, sPbrFaces[i], pbr_count[i], FALSE, FALSE, rigged);
// for rigged set, add weights and disable alpha sorting (rigged items use depth buffer)
extra_mask |= LLVertexBuffer::MAP_WEIGHT4;
@@ -6053,7 +5981,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mGeometryBytes = geometryBytes;
- if (!LLPipeline::sDelayVBUpdate)
{
//drawables have been rebuilt, clear rebuild status
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
@@ -6069,12 +5996,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
group->mLastUpdateTime = gFrameTimeSeconds;
group->mBuilt = 1.f;
group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
-
- if (LLPipeline::sDelayVBUpdate)
- {
- group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
- }
-
}
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
@@ -6088,15 +6009,12 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
group->mBuilt = 1.f;
- S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
-
const U32 MAX_BUFFER_COUNT = 4096;
LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
U32 buffer_count = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr{};
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
+ for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
@@ -6106,20 +6024,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (!vobj) continue;
- if (vobj->isAttachment())
- {
- trackAttachments( vobj, drawablep->isState(LLDrawable::RIGGED), &ratPtr );
- }
-
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- if (vobj->isAnimatedObject() && vobj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vobj);
- F32 est_tris = vobj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " rebuildMesh, tris " << est_tris << LL_ENDL;
- }
- }
if (vobj->isNoLOD()) continue;
vobj->preRebuild();
@@ -6139,18 +6043,20 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLVertexBuffer* buff = face->getVertexBuffer();
if (buff)
{
- if (!face->getGeometryVolume(*volume, face->getTEOffset(),
- vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex()))
- { //something's gone wrong with the vertex buffer accounting, rebuild this group
- group->dirtyGeom();
- gPipeline.markRebuild(group, TRUE);
- }
-
-
- if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
- {
- locked_buffer[buffer_count++] = buff;
- }
+ if (!face->getGeometryVolume(*volume, // volume
+ face->getTEOffset(), // face_index
+ vobj->getRelativeXform(), // mat_vert_in
+ vobj->getRelativeXformInvTrans(), // mat_norm_in
+ face->getGeomIndex(), // index_offset
+ false, // force_rebuild
+ true)) // no_debug_assert
+ { // Something's gone wrong with the vertex buffer accounting,
+ // rebuild this group with no debug assert because MESH_DIRTY
+ group->dirtyGeom();
+ gPipeline.markRebuild(group);
+ }
+
+ buff->unmapBuffer();
}
}
}
@@ -6168,44 +6074,17 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LL_PROFILE_ZONE_NAMED("rebuildMesh - flush");
for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
{
- (*iter)->flush();
+ (*iter)->unmapBuffer();
}
// don't forget alpha
if(group != NULL &&
- !group->mVertexBuffer.isNull() &&
- group->mVertexBuffer->isLocked())
+ !group->mVertexBuffer.isNull())
{
- group->mVertexBuffer->flush();
+ group->mVertexBuffer->unmapBuffer();
}
}
-
- //if not all buffers are unmapped
- if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)
- {
- LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ;
- for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
- {
- LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable();
- if(!drawablep)
- {
- continue;
- }
- for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
- {
- LLFace* face = drawablep->getFace(i);
- if (face)
- {
- LLVertexBuffer* buff = face->getVertexBuffer();
- if (buff && buff->isLocked())
- {
- buff->flush();
- }
- }
- }
- }
- }
-
+
group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO);
}
}
@@ -6226,7 +6105,7 @@ struct CompareBatchBreaker
{
return lte->getFullbright() < rte->getFullbright();
}
- else if (LLPipeline::sRenderDeferred && lte->getMaterialID() != rte->getMaterialID())
+ else if (lte->getMaterialID() != rte->getMaterialID())
{
return lte->getMaterialID() < rte->getMaterialID();
}
@@ -6272,28 +6151,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
U32 geometryBytes = 0;
- U32 buffer_usage = group->mBufferUsage;
-
- static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
-
- if (use_transform_feedback &&
- gTransformPositionProgram.mProgramObject && //transform shaders are loaded
- buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
- !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
- {
- buffer_usage = GL_DYNAMIC_COPY_ARB;
- }
-
-#if LL_DARWIN
- // HACK from Leslie:
- // Disable VBO usage for alpha on Mac OS X because it kills the framerate
- // due to implicit calls to glTexSubImage that are beyond our control.
- // (this works because the only calls here that sort by distance are alpha)
- if (distance_sort)
- {
- buffer_usage = 0x0;
- }
-#endif
//calculate maximum number of vertices to store in a single buffer
static LLCachedControl<S32> max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512);
@@ -6338,16 +6195,12 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
texture_index_channels = LLGLSLShader::sIndexedTextureChannels-1; //always reserve one for shiny for now just for simplicity;
}
- if (LLPipeline::sRenderDeferred && distance_sort)
+ if (distance_sort)
{
texture_index_channels = gDeferredAlphaProgram.mFeatures.mIndexedTextureChannels;
}
- static LLCachedControl<U32> max_texture_index(gSavedSettings, "RenderMaxTextureIndex", 16);
- texture_index_channels = llmin(texture_index_channels, (S32) max_texture_index);
-
- //NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
- texture_index_channels = llmin(texture_index_channels, 16);
+ texture_index_channels = LLGLSLShader::sIndexedTextureChannels;
bool flexi = false;
@@ -6503,19 +6356,13 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
-
- if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
- {
- buffer_usage = GL_STREAM_DRAW_ARB;
- }
-
//create vertex buffer
LLPointer<LLVertexBuffer> buffer;
{
LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate");
- buffer = createVertexBuffer(mask, buffer_usage);
- if(!buffer->allocateBuffer(geom_count, index_count, TRUE))
+ buffer = new LLVertexBuffer(mask);
+ if(!buffer->allocateBuffer(geom_count, index_count))
{
LL_WARNS() << "Failed to allocate group Vertex Buffer to "
<< geom_count << " vertices and "
@@ -6535,16 +6382,11 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
U32 indices_index = 0;
U16 index_offset = 0;
- std::unique_ptr<LLPerfStats::RecordAttachmentTime> ratPtr;
while (face_iter < i)
{
//update face indices for new buffer
facep = *face_iter;
- LLViewerObject* vobj = facep->getViewerObject();
- if(vobj && vobj->isAttachment())
- {
- trackAttachments(vobj, LLPipeline::sShadowRender, &ratPtr);
- }
+
if (buffer.isNull())
{
// Bulk allocation failed
@@ -6566,7 +6408,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
//for debugging, set last time face was updated vs moved
facep->updateRebuildFlags();
- if (!LLPipeline::sDelayVBUpdate)
{ //copy face geometry into vertex buffer
LLDrawable* drawablep = facep->getDrawable();
LLVOVolume* vobj = drawablep->getVOVolume();
@@ -6604,37 +6445,65 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
fullbright = TRUE;
}
- if (hud_group)
+ const LLTextureEntry* te = facep->getTextureEntry();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
+
+ if (hud_group && gltf_mat == nullptr)
{ //all hud attachments are fullbright
fullbright = TRUE;
}
-
- const LLTextureEntry* te = facep->getTextureEntry();
+
tex = facep->getTexture();
BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
-
- LLMaterial* mat = te->getMaterialParams().get();
- bool can_be_shiny = true;
- if (mat)
- {
- U8 mode = mat->getDiffuseAlphaMode();
- can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
- mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
- }
+ LLMaterial* mat = nullptr;
+ bool can_be_shiny = false;
+
+ // ignore traditional material if GLTF material is present
+ if (gltf_mat == nullptr)
+ {
+ mat = te->getMaterialParams().get();
+
+ can_be_shiny = true;
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+ can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
+ }
+ }
- F32 te_alpha = te->getColor().mV[3];
+ F32 blinn_phong_alpha = te->getColor().mV[3];
bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
- bool opaque = te_alpha >= 0.999f;
- bool transparent = te_alpha < 0.999f;
+ bool blinn_phong_opaque = blinn_phong_alpha >= 0.999f;
+ bool blinn_phong_transparent = blinn_phong_alpha < 0.999f;
- is_alpha = (is_alpha || transparent) ? TRUE : FALSE;
+ if (!gltf_mat)
+ {
+ is_alpha = (is_alpha || blinn_phong_transparent) ? TRUE : FALSE;
+ }
- if (mat && LLPipeline::sRenderDeferred && !hud_group)
+ if (gltf_mat || (mat && !hud_group))
{
bool material_pass = false;
+ if (gltf_mat)
+ { // all other parameters ignored if gltf material is present
+ if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_ALPHA);
+ }
+ else if (gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_GLTF_PBR);
+ }
+ }
+ else
// do NOT use 'fullbright' for this logic or you risk sending
// things without normals down the materials pipeline and will
// render poorly if not crash NORSPEC-240,314
@@ -6643,7 +6512,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
- if (opaque)
+ if (blinn_phong_opaque)
{
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
}
@@ -6664,7 +6533,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
else
{
- if (opaque)
+ if (blinn_phong_opaque)
{
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
@@ -6675,12 +6544,13 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
}
- else if (transparent)
+ else if (blinn_phong_transparent)
{
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
else if (use_legacy_bump)
{
+ llassert(mask & LLVertexBuffer::MAP_TANGENT);
// we have a material AND legacy bump settings, but no normal map
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
@@ -6711,12 +6581,28 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
- U32 mask = mat->getShaderMask(LLMaterial::DIFFUSE_ALPHA_MODE_DEFAULT, is_alpha);
+ U32 alpha_mode = mat->getDiffuseAlphaMode();
+ if (!distance_sort && alpha_mode == LLMaterial::DIFFUSE_ALPHA_MODE_BLEND)
+ { // HACK - this should never happen, but sometimes we get a material that thinks it has alpha blending when it ought not
+ alpha_mode = LLMaterial::DIFFUSE_ALPHA_MODE_NONE;
+ }
+ U32 mask = mat->getShaderMask(alpha_mode, is_alpha);
+
+ U32 vb_mask = facep->getVertexBuffer()->getTypeMask();
+
+ // HACK - this should also never happen, but sometimes we get here and the material thinks it has a specmap now
+ // even though it didn't appear to have a specmap when the face was added to the list of faces
+ if ((mask & 0x4) && !(vb_mask & LLVertexBuffer::MAP_TEXCOORD2))
+ {
+ mask &= ~0x4;
+ }
llassert(mask < sizeof(pass)/sizeof(U32));
mask = llmin(mask, (U32)(sizeof(pass)/sizeof(U32)-1));
+ // if this is going into alpha pool, distance sort MUST be true
+ llassert(pass[mask] == LLRenderPass::PASS_ALPHA ? distance_sort : true);
registerFace(group, facep, pass[mask]);
}
}
@@ -6740,7 +6626,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
registerFace(group, facep, LLRenderPass::PASS_ALPHA);
}
else if (gPipeline.shadersLoaded()
- && LLPipeline::sRenderBump
&& te->getShiny()
&& can_be_shiny)
{
@@ -6758,7 +6643,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{ //100% transparent, don't render unless we're highlighting transparent
registerFace(group, facep, LLRenderPass::PASS_ALPHA_INVISIBLE);
}
- else if (facep->canRenderAsMask())
+ else if (facep->canRenderAsMask() && !hud_group)
{
if (te->getFullbright() || LLPipeline::sNoAlpha)
{
@@ -6775,7 +6660,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
}
else if (gPipeline.shadersLoaded()
- && LLPipeline::sRenderBump
&& te->getShiny()
&& can_be_shiny)
{ //shiny
@@ -6784,7 +6668,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
}
- else if (LLPipeline::sRenderDeferred && !hud_group)
+ else if (!hud_group)
{ //deferred rendering
if (te->getFullbright())
{ //register in post deferred fullbright shiny pass
@@ -6796,6 +6680,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
}
else if (use_legacy_bump)
{ //register in deferred bump pass
+ llassert(mask& LLVertexBuffer::MAP_TANGENT);
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
@@ -6829,15 +6714,16 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
{
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
- if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
+ if (!hud_group && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
}
}
else
{
- if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && use_legacy_bump)
+ if (use_legacy_bump)
{ //non-shiny or fullbright deferred bump
+ llassert(mask& LLVertexBuffer::MAP_TANGENT);
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
@@ -6857,28 +6743,35 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
if (!gPipeline.shadersLoaded() &&
!is_alpha &&
- te->getShiny() &&
- LLPipeline::sRenderBump)
+ te->getShiny())
{ //shiny as an extra pass when shaders are disabled
registerFace(group, facep, LLRenderPass::PASS_SHINY);
}
}
//not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010
- if (!is_alpha && (hud_group || !LLPipeline::sRenderDeferred))
+ if (!is_alpha && hud_group)
{
llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
- if (!force_simple && LLPipeline::sRenderBump && use_legacy_bump)
+ if (!force_simple && use_legacy_bump)
{
+ llassert(mask & LLVertexBuffer::MAP_TANGENT);
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
}
if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
{
- registerFace(group, facep, LLRenderPass::PASS_GLOW);
+ if (gltf_mat)
+ {
+ registerFace(group, facep, LLRenderPass::PASS_GLTF_GLOW);
+ }
+ else
+ {
+ registerFace(group, facep, LLRenderPass::PASS_GLOW);
+ }
}
++face_iter;
@@ -6886,7 +6779,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
if (buffer)
{
- buffer->flush();
+ buffer->unmapBuffer();
}
}
@@ -6901,9 +6794,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace
void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
- //initialize to default usage for this partition
- U32 usage = group->getSpatialPartition()->mBufferUsage;
-
//for each drawable
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
@@ -6913,23 +6803,13 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte
{
continue;
}
-
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
- }
}
-
- group->mBufferUsage = usage;
}
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME;
- //initialize to default usage for this partition
- U32 usage = group->getSpatialPartition()->mBufferUsage;
-
//clear off any old faces
mFaceList.clear();
@@ -6943,11 +6823,6 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
continue;
}
- if (drawablep->isAnimating())
- { //fall back to stream draw for animating verts
- usage = GL_STREAM_DRAW_ARB;
- }
-
//for each face
for (S32 i = 0; i < drawablep->getNumFaces(); i++)
{
@@ -6972,8 +6847,6 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
}
}
}
-
- group->mBufferUsage = usage;
}
LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 59599ddc0c..aadc1fbcf3 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -34,8 +34,8 @@
#include "lllocalbitmaps.h"
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
-#include <map>
-#include <set>
+#include <unordered_map>
+#include <unordered_set>
class LLViewerTextureAnim;
@@ -68,7 +68,12 @@ public:
using FaceIndex = S32;
static const FaceIndex UPDATE_ALL_FACES = -1;
static const FaceIndex DO_NOT_UPDATE_FACES = -2;
- void update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, const LLVolume* src_volume, FaceIndex face_index = UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
+ void update(
+ const LLMeshSkinInfo* skin,
+ LLVOAvatar* avatar,
+ const LLVolume* src_volume,
+ FaceIndex face_index = UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
std::string mExtraDebugText;
};
@@ -117,49 +122,51 @@ public:
};
public:
- LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
- /*virtual*/ void markDead(); // Override (and call through to parent) to clean up media references
+ LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp);
+ void markDead() override; // Override (and call through to parent) to clean up media references
- /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
+ LLDrawable* createDrawable(LLPipeline *pipeline) override;
void deleteFaces();
void animateTextures();
BOOL isVisible() const ;
- /*virtual*/ BOOL isActive() const;
- /*virtual*/ BOOL isAttachment() const;
- /*virtual*/ BOOL isRootEdit() const; // overridden for sake of attachments treating themselves as a root object
- /*virtual*/ BOOL isHUDAttachment() const;
+ BOOL isActive() const override;
+ BOOL isAttachment() const override;
+ BOOL isRootEdit() const override; // overridden for sake of attachments treating themselves as a root object
+ BOOL isHUDAttachment() const override;
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
- /*virtual*/ BOOL setParent(LLViewerObject* parent);
- S32 getLOD() const { return mLOD; }
+ /*virtual*/ BOOL setParent(LLViewerObject* parent) override;
+ S32 getLOD() const override { return mLOD; }
void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
bool isNoLOD() const { return NO_LOD == mLOD; }
- const LLVector3 getPivotPositionAgent() const;
+ const LLVector3 getPivotPositionAgent() const override;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
- /*virtual*/ const LLMatrix4 getRenderMatrix() const;
- typedef std::map<LLUUID, S32> texture_cost_t;
+ /*virtual*/ const LLMatrix4 getRenderMatrix() const override;
+ typedef std::unordered_set<const LLViewerTexture*> texture_cost_t;
+ static S32 getTextureCost(const LLViewerTexture* img);
U32 getRenderCost(texture_cost_t &textures) const;
- /*virtual*/ F32 getEstTrianglesMax() const;
- /*virtual*/ F32 getEstTrianglesStreamingCost() const;
- /* virtual*/ F32 getStreamingCost() const;
- /*virtual*/ bool getCostData(LLMeshCostData& costs) const;
+ /*virtual*/ F32 getEstTrianglesMax() const override;
+ /*virtual*/ F32 getEstTrianglesStreamingCost() const override;
+ /* virtual*/ F32 getStreamingCost() const override;
+ /*virtual*/ bool getCostData(LLMeshCostData& costs) const override;
- /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const;
- /*virtual*/ U32 getHighLODTriangleCount();
+ /*virtual*/ U32 getTriangleCount(S32* vcount = NULL) const override;
+ /*virtual*/ U32 getHighLODTriangleCount() override;
/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
S32 face = -1, // which face to check, -1 = ALL_SIDES
BOOL pick_transparent = FALSE,
BOOL pick_rigged = FALSE,
+ BOOL pick_unselectable = TRUE,
S32* face_hit = NULL, // which face was hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
LLVector4a* normal = NULL, // return the surface normal at the intersection point
LLVector4a* tangent = NULL // return the surface tangent at the intersection point
- );
+ ) override;
LLVector3 agentPositionToVolume(const LLVector3& pos) const;
LLVector3 agentDirectionToVolume(const LLVector3& dir) const;
@@ -169,55 +176,58 @@ public:
BOOL getVolumeChanged() const { return mVolumeChanged; }
- /*virtual*/ F32 getRadius() const { return mVObjRadius; };
- const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
+ F32 getVObjRadius() const override { return mVObjRadius; };
+ const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const override;
- void markForUpdate(BOOL priority);
- void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
- void faceMappingChanged() { mFaceMappingChanged=TRUE; };
+ void markForUpdate() override;
+ void faceMappingChanged() override { mFaceMappingChanged=TRUE; }
- /*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
+ /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts
- /*virtual*/ void parameterChanged(U16 param_type, bool local_origin);
- /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin);
+ /*virtual*/ void parameterChanged(U16 param_type, bool local_origin) override;
+ /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin) override;
+
+ // update mReflectionProbe based on isReflectionProbe()
+ void updateReflectionProbePtr();
/*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys,
void **user_data,
U32 block_num, const EObjectUpdateType update_type,
- LLDataPacker *dp);
-
- /*virtual*/ void setSelected(BOOL sel);
- /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp);
-
- /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped);
-
- /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) ;
- /*virtual*/ void setNumTEs(const U8 num_tes);
- /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep);
- /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color);
- /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color);
- /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny);
- /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright);
- /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump);
- /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags);
- /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow);
- /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID);
+ LLDataPacker *dp) override;
+
+ /*virtual*/ void setSelected(BOOL sel) override;
+ /*virtual*/ BOOL setDrawableParent(LLDrawable* parentp) override;
+
+ /*virtual*/ void setScale(const LLVector3 &scale, BOOL damped) override;
+
+ /*virtual*/ void changeTEImage(S32 index, LLViewerTexture* new_image) override;
+ /*virtual*/ void setNumTEs(const U8 num_tes) override;
+ /*virtual*/ void setTEImage(const U8 te, LLViewerTexture *imagep) override;
+ /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor3 &color) override;
+ /*virtual*/ S32 setTEColor(const U8 te, const LLColor4 &color) override;
+ /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny) override;
+ /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright) override;
+ /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump) override;
+ /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags) override;
+ /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow) override;
+ /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID) override;
static void setTEMaterialParamsCallbackTE(const LLUUID& objectID, const LLMaterialID& pMaterialID, const LLMaterialPtr pMaterialParams, U32 te);
- /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams);
- /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t);
- /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s);
- /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t);
- /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen);
- /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media);
- /*virtual*/ BOOL setMaterial(const U8 material);
+ /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams) override;
+ S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat) override;
+ /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t) override;
+ /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s) override;
+ /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t) override;
+ /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen) override;
+ /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media) override;
+ /*virtual*/ BOOL setMaterial(const U8 material) override;
void setTexture(const S32 face);
S32 getIndexInTex(U32 ch) const {return mIndexInTex[ch];}
- /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
+ /*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false) override;
void updateSculptTexture();
void setIndexInTex(U32 ch, S32 index) { mIndexInTex[ch] = index ;}
void sculpt();
@@ -226,21 +236,21 @@ public:
void* user_data, S32 status, LLExtStat ext_status);
void updateRelativeXform(bool force_identity = false);
- /*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
- /*virtual*/ void updateFaceSize(S32 idx);
- /*virtual*/ BOOL updateLOD();
- void updateRadius();
- /*virtual*/ void updateTextures();
+ /*virtual*/ BOOL updateGeometry(LLDrawable *drawable) override;
+ /*virtual*/ void updateFaceSize(S32 idx) override;
+ /*virtual*/ BOOL updateLOD() override;
+ void updateRadius() override;
+ /*virtual*/ void updateTextures() override;
void updateTextureVirtualSize(bool forced = false);
void updateFaceFlags();
void regenFaces();
BOOL genBBoxes(BOOL force_global, BOOL should_update_octree_bounds = TRUE);
void preRebuild();
- virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
- virtual F32 getBinRadius();
+ virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max) override;
+ virtual F32 getBinRadius() override;
- virtual U32 getPartitionType() const;
+ virtual U32 getPartitionType() const override;
// For Lights
void setIsLight(BOOL is_light);
@@ -257,6 +267,7 @@ public:
void setSpotLightParams(LLVector3 params);
BOOL getIsLight() const;
+ bool getIsLightFast() const;
// Get the light color in sRGB color space NOT scaled by intensity.
@@ -283,21 +294,43 @@ public:
F32 getLightRadius() const;
F32 getLightFalloff(const F32 fudge_factor = 1.f) const;
F32 getLightCutoff() const;
-
+
+ // Reflection Probes
+ bool setIsReflectionProbe(BOOL is_probe);
+ bool setReflectionProbeAmbiance(F32 ambiance);
+ bool setReflectionProbeNearClip(F32 near_clip);
+ bool setReflectionProbeIsBox(bool is_box);
+ bool setReflectionProbeIsDynamic(bool is_dynamic);
+
+ BOOL isReflectionProbe() const override;
+ F32 getReflectionProbeAmbiance() const;
+ F32 getReflectionProbeNearClip() const;
+ bool getReflectionProbeIsBox() const;
+ bool getReflectionProbeIsDynamic() const;
+
// Flexible Objects
U32 getVolumeInterfaceID() const;
- virtual BOOL isFlexible() const;
- virtual BOOL isSculpted() const;
- virtual BOOL isMesh() const;
- virtual BOOL isRiggedMesh() const;
- virtual BOOL hasLightTexture() const;
+ virtual BOOL isFlexible() const override;
+ virtual BOOL isSculpted() const override;
+ virtual BOOL isMesh() const override;
+ virtual BOOL isRiggedMesh() const override;
+ virtual BOOL hasLightTexture() const override;
+
+ // fast variants above that use state that is filled in later
+ // not reliable early in the life of an object, but should be used after
+ // object is loaded
+ bool isFlexibleFast() const;
+ bool isSculptedFast() const;
+ bool isMeshFast() const;
+ bool isRiggedMeshFast() const;
+ bool isAnimatedObjectFast() const;
-
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
const LLMeshSkinInfo* getSkinInfo() const;
+ const bool isSkinInfoUnavaliable() const { return mSkinInfoUnavaliable; }
//convenience accessor for mesh ID (which is stored in sculpt id for legacy reasons)
const LLUUID& getMeshID() const { return getVolume()->getParams().getSculptID(); }
@@ -307,12 +340,12 @@ public:
void onSetExtendedMeshFlags(U32 flags);
void setExtendedMeshFlags(U32 flags);
bool canBeAnimatedObject() const;
- bool isAnimatedObject() const;
- virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent);
- virtual void afterReparent();
+ bool isAnimatedObject() const override;
+ virtual void onReparent(LLViewerObject *old_parent, LLViewerObject *new_parent) override;
+ virtual void afterReparent() override;
//virtual
- void updateRiggingInfo();
+ void updateRiggingInfo() override;
S32 mLastRiggingInfoLOD;
// Functions that deal with media, or media navigation
@@ -369,7 +402,10 @@ public:
// Rigged volume update (for raycasting)
// By default, this updates the bounding boxes of all the faces and builds an octree for precise per-triangle raycasting
- void updateRiggedVolume(bool force_treat_as_rigged, LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES, bool rebuild_face_octrees = true);
+ void updateRiggedVolume(
+ bool force_treat_as_rigged,
+ LLRiggedVolume::FaceIndex face_index = LLRiggedVolume::UPDATE_ALL_FACES,
+ bool rebuild_face_octrees = true);
LLRiggedVolume* getRiggedVolume();
//returns true if volume should be treated as a rigged volume
@@ -386,8 +422,7 @@ protected:
S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
- void updateTEData();
-
+
// stats tracking for render complexity
static S32 mRenderComplexity_last;
static S32 mRenderComplexity_current;
@@ -435,11 +470,18 @@ private:
S32 mIndexInTex[LLRender::NUM_VOLUME_TEXTURE_CHANNELS];
S32 mMDCImplCount;
+ // cached value of getIsLight to avoid redundant map lookups
+ // accessed by getIsLightFast
+ mutable bool mIsLight = false;
+
+ // cached value of getIsAnimatedObject to avoid redundant map lookups
+ // accessed by getIsAnimatedObjectFast
+ mutable bool mIsAnimatedObject = false;
bool mResetDebugText;
LLPointer<LLRiggedVolume> mRiggedVolume;
- bool mSkinInfoFailed;
+ bool mSkinInfoUnavaliable;
LLConstPointer<LLMeshSkinInfo> mSkinInfo;
// statics
public:
@@ -449,31 +491,10 @@ public:
static LLPointer<LLObjectMediaDataClient> sObjectMediaClient;
static LLPointer<LLObjectMediaNavigateClient> sObjectMediaNavigateClient;
-
protected:
static S32 sNumLODChanges;
friend class LLVolumeImplFlexible;
-
-public:
- bool notifyAboutCreatingTexture(LLViewerTexture *texture);
- bool notifyAboutMissingAsset(LLViewerTexture *texture);
-
-private:
- struct material_info
- {
- LLRender::eTexIndex map;
- U8 te;
-
- material_info(LLRender::eTexIndex map_, U8 te_)
- : map(map_)
- , te(te_)
- {}
- };
-
- typedef std::multimap<LLUUID, material_info> mmap_UUID_MAP_t;
- mmap_UUID_MAP_t mWaitingTextureInfo;
-
};
#endif // LL_LLVOVOLUME_H
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 089a7712c0..77ad967cef 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -35,7 +35,6 @@
#include "llface.h"
#include "llsky.h"
#include "llsurface.h"
-#include "llvosky.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
#include "llviewerregion.h"
@@ -143,17 +142,26 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
static const unsigned int vertices_per_quad = 4;
static const unsigned int indices_per_quad = 6;
- const S32 size = LLPipeline::sRenderTransparentWater ? 16 : 1;
+ S32 size_x = LLPipeline::sRenderTransparentWater ? 8 : 1;
+ S32 size_y = LLPipeline::sRenderTransparentWater ? 8 : 1;
- const S32 num_quads = size * size;
+ const LLVector3& scale = getScale();
+ size_x *= llmin(llround(scale.mV[0] / 256.f), 8);
+ size_y *= llmin(llround(scale.mV[1] / 256.f), 8);
+
+ const S32 num_quads = size_x * size_y;
face->setSize(vertices_per_quad * num_quads,
indices_per_quad * num_quads);
LLVertexBuffer* buff = face->getVertexBuffer();
- if (!buff || !buff->isWriteable())
+ if (!buff ||
+ buff->getNumIndices() != face->getIndicesCount() ||
+ buff->getNumVerts() != face->getGeomCount() ||
+ face->getIndicesStart() != 0 ||
+ face->getGeomIndex() != 0)
{
- buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
- if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE))
+ buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK);
+ if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount()))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on water update to "
<< face->getGeomCount() << " vertices and "
@@ -163,13 +171,6 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
face->setGeomIndex(0);
face->setVertexBuffer(buff);
}
- else
- {
- if (!buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount()))
- {
- LL_WARNS() << "Failed to resize Vertex Buffer" << LL_ENDL;
- }
- }
index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
@@ -179,41 +180,37 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
face->mCenterLocal = position_agent;
S32 x, y;
- F32 step_x = getScale().mV[0] / size;
- F32 step_y = getScale().mV[1] / size;
+ F32 step_x = getScale().mV[0] / size_x;
+ F32 step_y = getScale().mV[1] / size_y;
const LLVector3 up(0.f, step_y * 0.5f, 0.f);
const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
const LLVector3 normal(0.f, 0.f, 1.f);
- F32 size_inv = 1.f / size;
-
- F32 z_fudge = 0.f;
+ F32 size_inv_x = 1.f / size_x;
+ F32 size_inv_y = 1.f / size_y;
- if (getIsEdgePatch())
- { //bump edge patches down 10 cm to prevent aliasing along edges
- z_fudge = -0.1f;
- }
-
- for (y = 0; y < size; y++)
+ for (y = 0; y < size_y; y++)
{
- for (x = 0; x < size; x++)
+ for (x = 0; x < size_x; x++)
{
- S32 toffset = index_offset + 4*(y*size + x);
+ S32 toffset = index_offset + 4*(y*size_x + x);
position_agent = getPositionAgent() - getScale() * 0.5f;
position_agent.mV[VX] += (x + 0.5f) * step_x;
position_agent.mV[VY] += (y + 0.5f) * step_y;
- position_agent.mV[VZ] += z_fudge;
+
+ position_agent.mV[VX] = llround(position_agent.mV[VX]);
+ position_agent.mV[VY] = llround(position_agent.mV[VY]);
*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);
+ *texCoordsp++ = LLVector2(x*size_inv_x, (y+1)*size_inv_y);
+ *texCoordsp++ = LLVector2(x*size_inv_x, y*size_inv_y);
+ *texCoordsp++ = LLVector2((x+1)*size_inv_x, (y+1)*size_inv_y);
+ *texCoordsp++ = LLVector2((x+1)*size_inv_x, y*size_inv_y);
*normalsp++ = normal;
*normalsp++ = normal;
@@ -230,7 +227,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
}
}
- buff->flush();
+ buff->unmapBuffer();
mDrawable->movePartition();
LLPipeline::sCompiles++;
@@ -295,7 +292,7 @@ U32 LLVOVoidWater::getPartitionType() const
}
LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
-: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW_ARB, regionp)
+: LLSpatialPartition(0, FALSE, regionp)
{
mInfiniteFarClip = TRUE;
mDrawableType = LLPipeline::RENDER_TYPE_WATER;
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index d1f584cbca..9b2871c6a9 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -124,7 +124,7 @@ void LLVOWLSky::resetVertexBuffers()
mStarsVerts = nullptr;
mFsSkyVerts = nullptr;
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
void LLVOWLSky::cleanupGL()
@@ -139,7 +139,7 @@ void LLVOWLSky::cleanupGL()
void LLVOWLSky::restoreGL()
{
LLDrawPoolWLSky::restoreGL();
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL, TRUE);
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_ALL);
}
BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
@@ -151,9 +151,9 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
if (mFsSkyVerts.isNull())
{
- mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK);
- if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE))
+ if (!mFsSkyVerts->allocateBuffer(4, 6))
{
LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL;
}
@@ -184,7 +184,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
*indices++ = 3;
*indices++ = 2;
- mFsSkyVerts->flush();
+ mFsSkyVerts->unmapBuffer();
}
{
@@ -216,7 +216,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
for (U32 i = 0; i < strips_segments ;++i)
{
- LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW_ARB);
+ LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK);
mStripsVerts[i] = segment;
U32 num_stacks_this_seg = stacks_per_seg;
@@ -237,7 +237,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
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);
- bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE);
+ bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg);
#if RELEASE_SHOW_WARNS
if( !allocated )
{
@@ -267,7 +267,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable)
buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices, dome_radius, verts_per_stack, total_stacks);
// and unlock the buffer
- segment->flush();
+ segment->unmapBuffer();
}
#if RELEASE_SHOW_DEBUG
@@ -288,7 +288,7 @@ void LLVOWLSky::drawStars(void)
// render the stars as a sphere centered at viewer camera
if (mStarsVerts.notNull())
{
- mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
+ mStarsVerts->setBuffer();
mStarsVerts->drawArrays(LLRender::TRIANGLES, 0, getStarsNumVerts()*4);
}
}
@@ -302,9 +302,9 @@ void LLVOWLSky::drawFsSky(void)
LLGLDisable disable_blend(GL_BLEND);
- mFsSkyVerts->setBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK);
+ mFsSkyVerts->setBuffer();
mFsSkyVerts->drawRange(LLRender::TRIANGLES, 0, mFsSkyVerts->getNumVerts() - 1, mFsSkyVerts->getNumIndices(), 0);
- gPipeline.addTrianglesDrawn(mFsSkyVerts->getNumIndices(), LLRender::TRIANGLES);
+ gPipeline.addTrianglesDrawn(mFsSkyVerts->getNumIndices());
LLVertexBuffer::unbind();
}
@@ -317,21 +317,19 @@ void LLVOWLSky::drawDome(void)
LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
- const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK;
-
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);
+ strips_segment->setBuffer();
strips_segment->drawRange(
LLRender::TRIANGLE_STRIP,
0, strips_segment->getNumVerts()-1, strips_segment->getNumIndices(),
0);
- gPipeline.addTrianglesDrawn(strips_segment->getNumIndices(), LLRender::TRIANGLE_STRIP);
+ gPipeline.addTrianglesDrawn(strips_segment->getNumIndices());
}
LLVertexBuffer::unbind();
@@ -518,10 +516,10 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
LLStrider<LLColor4U> colorsp;
LLStrider<LLVector2> texcoordsp;
- if (mStarsVerts.isNull() || !mStarsVerts->isWriteable())
+ if (mStarsVerts.isNull())
{
- mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW);
- if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE))
+ mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK);
+ if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0))
{
LL_WARNS() << "Failed to allocate Vertex Buffer for Sky to " << getStarsNumVerts() * 6 << " vertices" << LL_ENDL;
}
@@ -578,6 +576,6 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable)
*(colorsp++) = LLColor4U(mStarColors[vtx]);
}
- mStarsVerts->flush();
+ mStarsVerts->unmapBuffer();
return TRUE;
}
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 1266011e0a..709a457862 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -39,6 +39,7 @@
#include "llglheaders.h"
#include "llhttpnode.h"
#include "llregionhandle.h"
+#include "llsky.h"
#include "llsurface.h"
#include "lltrans.h"
#include "llviewercamera.h"
@@ -110,7 +111,7 @@ LLWorld::LLWorld() :
gGL.getTexUnit(0)->bind(mDefaultWaterTexturep);
mDefaultWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
- LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled");
+ LLViewerRegion::sVOCacheCullingEnabled = gSavedSettings.getBOOL("RequestFullRegionCache") && gSavedSettings.getBOOL("ObjectCacheEnabled");
}
@@ -118,6 +119,7 @@ void LLWorld::resetClass()
{
mHoleWaterObjects.clear();
gObjectList.destroy();
+ gSky.cleanup(); // references an object
for(region_list_t::iterator region_it = mRegionList.begin(); region_it != mRegionList.end(); )
{
LLViewerRegion* region_to_delete = *region_it++;
@@ -679,6 +681,7 @@ static LLTrace::SampleStatHandle<> sNumActiveCachedObjects("numactivecachedobjec
void LLWorld::updateRegions(F32 max_update_time)
{
+ LL_PROFILE_ZONE_SCOPED;
LLTimer update_timer;
mNumOfActiveCachedObjects = 0;
@@ -817,7 +820,7 @@ void LLWorld::updateNetStats()
void LLWorld::printPacketsLost()
{
- LL_INFOS() << "Simulators:" << LL_ENDL;
+ LL_INFOS() << "Simulators:" << LL_ENDL;
LL_INFOS() << "----------" << LL_ENDL;
LLCircuitData *cdp = NULL;
@@ -852,6 +855,7 @@ F32 LLWorld::getLandFarClip() const
void LLWorld::setLandFarClip(const F32 far_clip)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_ENVIRONMENT;
static S32 const rwidth = (S32)REGION_WIDTH_U32;
S32 const n1 = (llceil(mLandFarClip) - 1) / rwidth;
S32 const n2 = (llceil(far_clip) - 1) / rwidth;
@@ -1421,10 +1425,10 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
}
}
-S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs)
+F32 LLWorld::getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs)
{
static LLCachedControl<F32> render_far_clip(gSavedSettings, "RenderFarClip", 64);
- S32 nearby_max_complexity = 0;
+ F32 nearby_max_complexity = 0;
F32 radius = render_far_clip * render_far_clip;
std::vector<LLCharacter*>::iterator char_iter = LLCharacter::sInstances.begin();
while (char_iter != LLCharacter::sInstances.end())
@@ -1438,8 +1442,12 @@ S32 LLWorld::getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_av
char_iter++;
continue;
}
- avatar->calculateUpdateRenderComplexity();
- nearby_max_complexity = llmax(nearby_max_complexity, (S32)avatar->getVisualComplexity());
+
+ if (!avatar->isTooSlow())
+ {
+ gPipeline.profileAvatar(avatar);
+ }
+ nearby_max_complexity = llmax(nearby_max_complexity, avatar->getGPURenderTime());
valid_nearby_avs.push_back(*char_iter);
}
char_iter++;
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index b2be36d72c..f78cbcaa48 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -172,7 +172,9 @@ public:
// or if the circuit to this simulator had been lost.
bool isRegionListed(const LLViewerRegion* region) const;
- S32 getNearbyAvatarsAndCompl(std::vector<LLCharacter*> &valid_nearby_avs);
+ // profile nearby avatars using gPipeline.profileAvatar and update their render times
+ // return max GPU time
+ F32 getNearbyAvatarsAndMaxGPUTime(std::vector<LLCharacter*> &valid_nearby_avs);
private:
void clearHoleWaterObjects();
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 6dd58518c5..cc947c87d5 100755
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -399,28 +399,17 @@ void LLWorldMapView::draw()
S32 level = LLWorldMipmap::scaleToLevel(mMapScale);
LLLocalClipRect clip(getLocalRect());
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- // Clear the background alpha to 0
- gGL.flush();
- gGL.setColorMask(false, true);
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_REPLACE);
- gGL.color4f(0.0f, 0.0f, 0.0f, 0.0f);
- gl_rect_2d(0, height, width, 0);
- }
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.flush();
- gGL.setColorMask(true, true);
+ // Draw background rectangle
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.color4fv(mBackgroundColor.mV);
+ gl_rect_2d(0, height, width, 0);
// Draw the image tiles
drawMipmap(width, height);
- gGL.flush();
-
- gGL.setColorMask(true, true);
// Draw per sim overlayed information (names, mature, offline...)
for (LLWorldMap::sim_info_map_t::const_iterator it = LLWorldMap::getInstance()->getRegionMap().begin();
@@ -465,7 +454,6 @@ void LLWorldMapView::draw()
if (info->isDown())
{
// Draw a transparent red square over down sims
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_SOURCE_ALPHA);
gGL.color4f(0.2f, 0.0f, 0.0f, 0.4f);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -476,26 +464,7 @@ void LLWorldMapView::draw()
gGL.vertex2f(right, top);
gGL.end();
}
- // As part of the AO project, we no longer want to draw access indicators;
- // it's too complicated to get all the rules straight and will only
- // cause confusion.
- /**********************
- else if (!info->isPG() && gAgent.isTeen())
- {
- // If this is a mature region, and you are not, draw a line across it
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.color3f(1.f, 0.f, 0.f);
- gGL.begin(LLRender::LINES);
- gGL.vertex2f(left, top);
- gGL.vertex2f(right, bottom);
- gGL.vertex2f(left, bottom);
- gGL.vertex2f(right, top);
- gGL.end();
- }
- **********************/
- else if (gSavedSettings.getBOOL("MapShowLandForSale") && (level <= DRAW_LANDFORSALE_THRESHOLD))
+ else if (gSavedSettings.getBOOL("MapShowLandForSale") && (level <= DRAW_LANDFORSALE_THRESHOLD))
{
// Draw the overlay image "Land for Sale / Land for Auction"
LLViewerFetchedTexture* overlayimage = info->getLandForSaleImage();
@@ -507,7 +476,6 @@ void LLWorldMapView::draw()
// Draw something whenever we have enough info
if (overlayimage->hasGLTexture())
{
- gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA);
gGL.getTexUnit(0)->bind(overlayimage);
gGL.color4f(1.f, 1.f, 1.f, 1.f);
gGL.begin(LLRender::QUADS);
@@ -557,21 +525,6 @@ void LLWorldMapView::draw()
}
}
-
-
- // Draw background rectangle
- LLGLSUIDefault gls_ui;
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.flush();
- gGL.blendFunc(LLRender::BF_ONE_MINUS_DEST_ALPHA, LLRender::BF_DEST_ALPHA);
- gGL.color4fv( mBackgroundColor.mV );
- gl_rect_2d(0, height, width, 0);
- }
-
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
// Draw item infos if we're not zoomed out too much and there's something to draw
if ((level <= DRAW_SIMINFO_THRESHOLD) && (gSavedSettings.getBOOL("MapShowInfohubs") ||
gSavedSettings.getBOOL("MapShowTelehubs") ||
@@ -772,7 +725,6 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load
gGL.getTexUnit(0)->bind(simimage.get());
simimage->setAddressMode(LLTexUnit::TAM_CLAMP);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.color4f(1.f, 1.0f, 1.0f, 1.0f);
gGL.begin(LLRender::QUADS);
@@ -811,8 +763,6 @@ bool LLWorldMapView::drawMipmapLevel(S32 width, S32 height, S32 level, bool load
// Used for debug only
void LLWorldMapView::drawTileOutline(S32 level, F32 top, F32 left, F32 bottom, F32 right)
{
- gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
-
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
if (level == 1)
gGL.color3f(1.f, 0.f, 0.f); // red
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 8ea07fcee0..ba7e8d7298 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -51,6 +51,12 @@
#else
#include <xmlrpc-epi/xmlrpc.h>
#endif
+// <xmlrpc-epi/queue.h> contains a harmful #define queue xmlrpc_queue. This
+// breaks any use of std::queue. Ditch that #define: if any of our code wants
+// to reference xmlrpc_queue, let it reference it directly.
+#if defined(queue)
+#undef queue
+#endif
#include "llappviewer.h"
#include "lltrans.h"
@@ -411,7 +417,7 @@ void LLXMLRPCTransaction::Impl::init(XMLRPC_REQUEST request, bool useGzip, const
mHandler = LLXMLRPCTransaction::Handler::ptr_t(new Handler( mHttpRequest, this ));
- mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID, 0,
+ mPostH = mHttpRequest->requestPost(LLCore::HttpRequest::DEFAULT_POLICY_ID,
mURI, body.get(), httpOpts, httpHeaders, mHandler);
}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bbff6c889f..9266c84540 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -56,7 +56,6 @@
#include "lldrawable.h"
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
-#include "lldrawpoolground.h"
#include "lldrawpoolbump.h"
#include "lldrawpooltree.h"
#include "lldrawpoolwater.h"
@@ -64,7 +63,6 @@
#include "llfeaturemanager.h"
#include "llfloatertelehub.h"
#include "llfloaterreg.h"
-#include "llgldbg.h"
#include "llhudmanager.h"
#include "llhudnametag.h"
#include "llhudtext.h"
@@ -87,7 +85,6 @@
#include "llviewerwindow.h" // For getSpinAxis
#include "llvoavatarself.h"
#include "llvocache.h"
-#include "llvoground.h"
#include "llvosky.h"
#include "llvowlsky.h"
#include "llvotree.h"
@@ -119,27 +116,7 @@
#include "llenvironment.h"
#include "llsettingsvo.h"
-#ifdef _DEBUG
-// Debug indices is disabled for now for debug performance - djs 4/24/02
-//#define DEBUG_INDICES
-#else
-//#define DEBUG_INDICES
-#endif
-
-// Expensive and currently broken
-//
-#define MATERIALS_IN_REFLECTIONS 0
-
-// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
-// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
-// const S32 WATER_REFLECT_NONE_WATER_OPAQUE = -2;
- const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT = -1;
- const S32 WATER_REFLECT_MINIMAL = 0;
-// const S32 WATER_REFLECT_TERRAIN = 1;
- const S32 WATER_REFLECT_STATIC_OBJECTS = 2;
- const S32 WATER_REFLECT_AVATARS = 3;
- const S32 WATER_REFLECT_EVERYTHING = 4;
-
+extern BOOL gSnapshot;
bool gShiftFrame = false;
//cached settings
@@ -153,7 +130,6 @@ S32 LLPipeline::RenderShadowDetail;
S32 LLPipeline::RenderShadowSplits;
bool LLPipeline::RenderDeferredSSAO;
F32 LLPipeline::RenderShadowResolutionScale;
-bool LLPipeline::RenderLocalLights;
bool LLPipeline::RenderDelayCreation;
bool LLPipeline::RenderAnimateRes;
bool LLPipeline::FreezeTime;
@@ -172,7 +148,6 @@ LLColor4 LLPipeline::PreviewSpecular2;
LLVector3 LLPipeline::PreviewDirection0;
LLVector3 LLPipeline::PreviewDirection1;
LLVector3 LLPipeline::PreviewDirection2;
-F32 LLPipeline::RenderGlowMinLuminance;
F32 LLPipeline::RenderGlowMaxExtractAlpha;
F32 LLPipeline::RenderGlowWarmthAmount;
LLVector3 LLPipeline::RenderGlowLumWeights;
@@ -181,6 +156,7 @@ S32 LLPipeline::RenderGlowResolutionPow;
S32 LLPipeline::RenderGlowIterations;
F32 LLPipeline::RenderGlowWidth;
F32 LLPipeline::RenderGlowStrength;
+bool LLPipeline::RenderGlowNoise;
bool LLPipeline::RenderDepthOfField;
bool LLPipeline::RenderDepthOfFieldInEditMode;
F32 LLPipeline::CameraFocusTransitionTime;
@@ -205,11 +181,7 @@ F32 LLPipeline::RenderEdgeNormCutoff;
LLVector3 LLPipeline::RenderShadowGaussian;
F32 LLPipeline::RenderShadowBlurDistFactor;
bool LLPipeline::RenderDeferredAtmospheric;
-S32 LLPipeline::RenderReflectionDetail;
F32 LLPipeline::RenderHighlightFadeTime;
-LLVector3 LLPipeline::RenderShadowClipPlanes;
-LLVector3 LLPipeline::RenderShadowOrthoClipPlanes;
-LLVector3 LLPipeline::RenderShadowNearDist;
F32 LLPipeline::RenderFarClip;
LLVector3 LLPipeline::RenderShadowSplitExponent;
F32 LLPipeline::RenderShadowErrorCutoff;
@@ -218,10 +190,19 @@ bool LLPipeline::CameraOffset;
F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
+bool LLPipeline::RenderScreenSpaceReflections;
+S32 LLPipeline::RenderScreenSpaceReflectionIterations;
+F32 LLPipeline::RenderScreenSpaceReflectionRayStep;
+F32 LLPipeline::RenderScreenSpaceReflectionDistanceBias;
+F32 LLPipeline::RenderScreenSpaceReflectionDepthRejectBias;
+F32 LLPipeline::RenderScreenSpaceReflectionAdaptiveStepMultiplier;
+S32 LLPipeline::RenderScreenSpaceReflectionGlossySamples;
+S32 LLPipeline::RenderBufferVisualization;
LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
+const F32 ALPHA_BLEND_CUTOFF = 0.598f;
const F32 DEFERRED_LIGHT_FALLOFF = 0.5f;
const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
@@ -229,6 +210,7 @@ extern S32 gBoxFrame;
//extern BOOL gHideSelectedObjects;
extern BOOL gDisplaySwapBuffers;
extern BOOL gDebugGL;
+extern BOOL gCubeSnapshot;
bool gAvatarBacklight = false;
@@ -282,34 +264,11 @@ static LLStaticHashedString sKern("kern");
static LLStaticHashedString sKernScale("kern_scale");
//----------------------------------------
-std::string gPoolNames[] =
-{
- // Correspond to LLDrawpool enum render type
- "NONE",
- "POOL_SIMPLE",
- "POOL_GROUND",
- "POOL_FULLBRIGHT",
- "POOL_BUMP",
- "POOL_MATERIALS",
- "POOL_TERRAIN,"
- "POOL_SKY",
- "POOL_WL_SKY",
- "POOL_TREE",
- "POOL_ALPHA_MASK",
- "POOL_FULLBRIGHT_ALPHA_MASK",
- "POOL_GRASS",
- "POOL_INVISIBLE",
- "POOL_AVATAR",
- "POOL_VOIDWATER",
- "POOL_WATER",
- "POOL_GLOW",
- "POOL_ALPHA"
-};
void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
-LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
+LLVertexBuffer* ll_create_cube_vb(U32 type_mask);
void display_update_camera();
//----------------------------------------
@@ -330,17 +289,13 @@ bool LLPipeline::sRenderHighlight = true;
LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
bool LLPipeline::sForceOldBakedUpload = false;
S32 LLPipeline::sUseOcclusion = 0;
-bool LLPipeline::sDelayVBUpdate = true;
bool LLPipeline::sAutoMaskAlphaDeferred = true;
bool LLPipeline::sAutoMaskAlphaNonDeferred = false;
bool LLPipeline::sRenderTransparentWater = true;
-bool LLPipeline::sRenderBump = true;
bool LLPipeline::sBakeSunlight = false;
bool LLPipeline::sNoAlpha = false;
-bool LLPipeline::sUseTriStrips = true;
bool LLPipeline::sUseFarClip = true;
bool LLPipeline::sShadowRender = false;
-bool LLPipeline::sWaterReflections = false;
bool LLPipeline::sRenderGlow = false;
bool LLPipeline::sReflectionRender = false;
bool LLPipeline::sDistortionRender = false;
@@ -348,10 +303,10 @@ bool LLPipeline::sImpostorRender = false;
bool LLPipeline::sImpostorRenderAlphaDepthPass = false;
bool LLPipeline::sUnderWaterRender = false;
bool LLPipeline::sTextureBindTest = false;
-bool LLPipeline::sRenderFrameTest = false;
bool LLPipeline::sRenderAttachedLights = true;
bool LLPipeline::sRenderAttachedParticles = true;
bool LLPipeline::sRenderDeferred = false;
+bool LLPipeline::sReflectionProbesEnabled = false;
S32 LLPipeline::sVisibleLightCount = 0;
bool LLPipeline::sRenderingHUDs;
F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f;
@@ -365,11 +320,13 @@ void validate_framebuffer_object();
// Add color attachments for deferred rendering
// target -- RenderTarget to add attachments to
-// for_impostor -- whether or not these render targets are for an impostor (if true, avoids implicit sRGB conversions)
bool addDeferredAttachments(LLRenderTarget& target, bool for_impostor = false)
{
- return target.addColorAttachment(for_impostor ? GL_RGBA : GL_SRGB8_ALPHA8) && //specular
- target.addColorAttachment(GL_RGB10_A2); //normal+z
+ bool valid = true
+ && target.addColorAttachment(GL_RGBA) // frag-data[1] specular OR PBR ORM
+ && target.addColorAttachment(GL_RGBA16F) // frag_data[2] normal+z+fogmask, See: class1\deferred\materialF.glsl & softenlight
+ && target.addColorAttachment(GL_RGB16F); // frag_data[3] PBR emissive
+ return valid;
}
LLPipeline::LLPipeline() :
@@ -378,6 +335,7 @@ LLPipeline::LLPipeline() :
mTextureMatrixOps(0),
mNumVisibleNodes(0),
mNumVisibleFaces(0),
+ mPoissonOffset(0),
mInitialized(false),
mShadersLoaded(false),
@@ -387,29 +345,10 @@ LLPipeline::LLPipeline() :
mOldRenderDebugMask(0),
mMeshDirtyQueryObject(0),
mGroupQ1Locked(false),
- mGroupQ2Locked(false),
mResetVertexBuffers(false),
mLastRebuildPool(NULL),
- mAlphaPool(NULL),
- mSkyPool(NULL),
- mTerrainPool(NULL),
- mWaterPool(NULL),
- mGroundPool(NULL),
- mSimplePool(NULL),
- mGrassPool(NULL),
- mAlphaMaskPool(NULL),
- mFullbrightAlphaMaskPool(NULL),
- mFullbrightPool(NULL),
- mInvisiblePool(NULL),
- mGlowPool(NULL),
- mBumpPool(NULL),
- mMaterialsPool(NULL),
- mWLSkyPool(NULL),
mLightMask(0),
- mLightMovingMask(0),
- mLightingDetail(0),
- mScreenWidth(0),
- mScreenHeight(0)
+ mLightMovingMask(0)
{
mNoiseMap = 0;
mTrueNoiseMap = 0;
@@ -438,32 +377,31 @@ void LLPipeline::init()
{
refreshCachedSettings();
+ mRT = &mMainRT;
+
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
- LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
- LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
- LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
- mInitialized = true;
+ mInitialized = true;
stop_glerror();
//create render pass pools
- getPool(LLDrawPool::POOL_ALPHA);
+ getPool(LLDrawPool::POOL_ALPHA_PRE_WATER);
+ getPool(LLDrawPool::POOL_ALPHA_POST_WATER);
getPool(LLDrawPool::POOL_SIMPLE);
getPool(LLDrawPool::POOL_ALPHA_MASK);
getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
getPool(LLDrawPool::POOL_GRASS);
getPool(LLDrawPool::POOL_FULLBRIGHT);
- getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
+ getPool(LLDrawPool::POOL_GLTF_PBR);
+ getPool(LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK);
resetFrameStats();
@@ -488,12 +426,6 @@ void LLPipeline::init()
else
{
setAllRenderTypes(); // By default, all rendering types start enabled
- // Don't turn on ground when this is set
- // Mac Books with intel 950s need this
- if(!gSavedSettings.getBOOL("RenderGround"))
- {
- toggleRenderType(RENDER_TYPE_GROUND);
- }
}
// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -508,14 +440,9 @@ void LLPipeline::init()
mBackfaceCull = true;
- stop_glerror();
-
// Enable features
-
LLViewerShaderMgr::instance()->setShaders();
- stop_glerror();
-
for (U32 i = 0; i < 2; ++i)
{
mSpotLightFade[i] = 1.f;
@@ -523,13 +450,25 @@ void LLPipeline::init()
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
}
- mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
- mDeferredVB->allocateBuffer(8, 0, true);
- setLightingDetail(-1);
-
+ mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK);
+ mDeferredVB->allocateBuffer(8, 0);
+
+ {
+ mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX);
+ mScreenTriangleVB->allocateBuffer(3, 0);
+ LLStrider<LLVector3> vert;
+ mScreenTriangleVB->getVertexStrider(vert);
+
+ vert[0].set(-1, 1, 0);
+ vert[1].set(-1, -3, 0);
+ vert[2].set(3, 1, 0);
+
+ mScreenTriangleVB->unmapBuffer();
+ }
+
//
// Update all settings to trigger a cached settings refresh
//
@@ -537,10 +476,9 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderAutoMaskAlphaNonDeferred");
connectRefreshCachedSettingsSafe("RenderUseFarClip");
connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors");
- connectRefreshCachedSettingsSafe("RenderDelayVBUpdate");
connectRefreshCachedSettingsSafe("UseOcclusion");
- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
- connectRefreshCachedSettingsSafe("RenderDeferred");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders");
+ // DEPRECATED -- connectRefreshCachedSettingsSafe("RenderDeferred");
connectRefreshCachedSettingsSafe("RenderDeferredSunWash");
connectRefreshCachedSettingsSafe("RenderFSAASamples");
connectRefreshCachedSettingsSafe("RenderResolutionDivisor");
@@ -549,7 +487,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderShadowSplits");
connectRefreshCachedSettingsSafe("RenderDeferredSSAO");
connectRefreshCachedSettingsSafe("RenderShadowResolutionScale");
- connectRefreshCachedSettingsSafe("RenderLocalLights");
connectRefreshCachedSettingsSafe("RenderDelayCreation");
connectRefreshCachedSettingsSafe("RenderAnimateRes");
connectRefreshCachedSettingsSafe("FreezeTime");
@@ -568,7 +505,6 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("PreviewDirection0");
connectRefreshCachedSettingsSafe("PreviewDirection1");
connectRefreshCachedSettingsSafe("PreviewDirection2");
- connectRefreshCachedSettingsSafe("RenderGlowMinLuminance");
connectRefreshCachedSettingsSafe("RenderGlowMaxExtractAlpha");
connectRefreshCachedSettingsSafe("RenderGlowWarmthAmount");
connectRefreshCachedSettingsSafe("RenderGlowLumWeights");
@@ -577,6 +513,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderGlowIterations");
connectRefreshCachedSettingsSafe("RenderGlowWidth");
connectRefreshCachedSettingsSafe("RenderGlowStrength");
+ connectRefreshCachedSettingsSafe("RenderGlowNoise");
connectRefreshCachedSettingsSafe("RenderDepthOfField");
connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
@@ -600,11 +537,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderShadowGaussian");
connectRefreshCachedSettingsSafe("RenderShadowBlurDistFactor");
connectRefreshCachedSettingsSafe("RenderDeferredAtmospheric");
- connectRefreshCachedSettingsSafe("RenderReflectionDetail");
connectRefreshCachedSettingsSafe("RenderHighlightFadeTime");
- connectRefreshCachedSettingsSafe("RenderShadowClipPlanes");
- connectRefreshCachedSettingsSafe("RenderShadowOrthoClipPlanes");
- connectRefreshCachedSettingsSafe("RenderShadowNearDist");
connectRefreshCachedSettingsSafe("RenderFarClip");
connectRefreshCachedSettingsSafe("RenderShadowSplitExponent");
connectRefreshCachedSettingsSafe("RenderShadowErrorCutoff");
@@ -613,6 +546,14 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("CameraMaxCoF");
connectRefreshCachedSettingsSafe("CameraDoFResScale");
connectRefreshCachedSettingsSafe("RenderAutoHideSurfaceAreaLimit");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflections");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionIterations");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionRayStep");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionDistanceBias");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionDepthRejectBias");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
+ connectRefreshCachedSettingsSafe("RenderScreenSpaceReflectionGlossySamples");
+ connectRefreshCachedSettingsSafe("RenderBufferVisualization");
gSavedSettings.getControl("RenderAutoHideSurfaceAreaLimit")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings));
}
@@ -625,7 +566,6 @@ void LLPipeline::cleanup()
assertInitialized();
mGroupQ1.clear() ;
- mGroupQ2.clear() ;
for(pool_set_t::iterator iter = mPools.begin();
iter != mPools.end(); )
@@ -659,22 +599,20 @@ void LLPipeline::cleanup()
LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
}
- delete mAlphaPool;
- mAlphaPool = NULL;
+ delete mAlphaPoolPreWater;
+ mAlphaPoolPreWater = nullptr;
+ delete mAlphaPoolPostWater;
+ mAlphaPoolPostWater = nullptr;
delete mSkyPool;
mSkyPool = NULL;
delete mTerrainPool;
mTerrainPool = NULL;
delete mWaterPool;
mWaterPool = NULL;
- delete mGroundPool;
- mGroundPool = NULL;
delete mSimplePool;
mSimplePool = NULL;
delete mFullbrightPool;
mFullbrightPool = NULL;
- delete mInvisiblePool;
- mInvisiblePool = NULL;
delete mGlowPool;
mGlowPool = NULL;
delete mBumpPool;
@@ -694,8 +632,11 @@ void LLPipeline::cleanup()
mInitialized = false;
mDeferredVB = NULL;
+ mScreenTriangleVB = nullptr;
mCubeVB = NULL;
+
+ mReflectionMapManager.cleanup();
}
//============================================================================
@@ -708,18 +649,11 @@ void LLPipeline::destroyGL()
resetDrawOrders();
- resetVertexBuffers();
-
releaseGLBuffers();
- if (LLVertexBuffer::sEnableVBOs)
- {
- LLVertexBuffer::sEnableVBOs = FALSE;
- }
-
if (mMeshDirtyQueryObject)
{
- glDeleteQueriesARB(1, &mMeshDirtyQueryObject);
+ glDeleteQueries(1, &mMeshDirtyQueryObject);
mMeshDirtyQueryObject = 0;
}
}
@@ -736,8 +670,9 @@ void LLPipeline::requestResizeShadowTexture()
void LLPipeline::resizeShadowTexture()
{
- releaseShadowTargets();
- allocateShadowBuffer(mScreenWidth, mScreenHeight);
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
+ allocateShadowBuffer(mRT->width, mRT->height);
gResizeShadowTexture = FALSE;
}
@@ -748,70 +683,37 @@ void LLPipeline::resizeScreenTexture()
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
- if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ if (gResizeScreenTexture || (resX != mRT->screen.getWidth()) || (resY != mRT->screen.getHeight()))
{
releaseScreenBuffers();
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
allocateScreenBuffer(resX,resY);
gResizeScreenTexture = FALSE;
}
}
}
-void LLPipeline::allocatePhysicsBuffer()
-{
- GLuint resX = gViewerWindow->getWorldViewWidthRaw();
- GLuint resY = gViewerWindow->getWorldViewHeightRaw();
-
- if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY)
- {
- mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- }
-}
-
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- bool save_settings = sRenderDeferred;
- if (save_settings)
- {
- // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets
- gSavedSettings.setBOOL("RenderInitError", TRUE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
eFBOStatus ret = doAllocateScreenBuffer(resX, resY);
- if (save_settings)
- {
- // don't disable shaders on next session
- gSavedSettings.setBOOL("RenderInitError", FALSE);
- gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
- }
-
- if (ret == FBO_FAILURE)
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
- //NOTE: if the session closes successfully after this call, deferred rendering will be
- // disabled on future sessions
- if (LLPipeline::sRenderDeferred)
- {
- gSavedSettings.setBOOL("RenderDeferred", FALSE);
- LLPipeline::refreshCachedSettings();
- }
- }
-
return ret == FBO_SUCCESS_FULLRES;
}
LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
// try to allocate screen buffers at requested resolution and samples
// - on failure, shrink number of samples and try again
// - if not multisampled, shrink resolution and try again (favor X resolution over Y)
// Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state
+ // refresh cached settings here to protect against inconsistent event handling order
+ refreshCachedSettings();
+
U32 samples = RenderFSAASamples;
eFBOStatus ret = FBO_SUCCESS_FULLRES;
@@ -860,11 +762,21 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
- refreshCachedSettings();
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ if (mRT == &mMainRT && sReflectionProbesEnabled)
+ { // hacky -- allocate auxillary buffer
+ gCubeSnapshot = TRUE;
+ mReflectionMapManager.initReflectionMaps();
+ mRT = &mAuxillaryRT;
+ U32 res = mReflectionMapManager.mProbeResolution * 4; //multiply by 4 because probes will be 16x super sampled
+ allocateScreenBuffer(res, res, samples);
+ mRT = &mMainRT;
+ gCubeSnapshot = FALSE;
+ }
// remember these dimensions
- mScreenWidth = resX;
- mScreenHeight = resY;
+ mRT->width = resX;
+ mRT->height = resY;
U32 res_mod = RenderResolutionDivisor;
@@ -874,86 +786,68 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
resY /= res_mod;
}
+ if (LLPipeline::sRenderTransparentWater)
+ { //water reflection texture
+ mWaterDis.allocate(resX, resY, GL_RGBA, true);
+ }
+
if (RenderUIBuffer)
{
- if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE))
+ if (!mRT->uiScreen.allocate(resX,resY, GL_RGBA))
{
return false;
}
}
- if (LLPipeline::sRenderDeferred)
- {
- S32 shadow_detail = RenderShadowDetail;
- bool ssao = RenderDeferredSSAO;
+ S32 shadow_detail = RenderShadowDetail;
+ bool ssao = RenderDeferredSSAO;
- const U32 occlusion_divisor = 3;
-
- //allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (!addDeferredAttachments(mDeferredScreen)) return false;
+ //allocate deferred rendering color buffers
+ if (!mRT->deferredScreen.allocate(resX, resY, GL_RGBA, true)) return false;
+ if (!addDeferredAttachments(mRT->deferredScreen)) return false;
- GLuint screenFormat = GL_RGBA16;
- if (gGLManager.mIsAMD)
- {
- screenFormat = GL_RGBA12;
- }
-
- if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
- {
- screenFormat = GL_RGBA16F_ARB;
- }
+ GLuint screenFormat = GL_RGBA16F;
- if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
- if (samples > 0)
- {
- if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
- }
- else
- {
- mFXAABuffer.release();
- }
+ if (!mRT->screen.allocate(resX, resY, screenFormat)) return false;
+
+ mRT->deferredScreen.shareDepthBuffer(mRT->screen);
+
+ if (samples > 0)
+ {
+ if (!mRT->fxaaBuffer.allocate(resX, resY, GL_RGBA)) return false;
+ }
+ else
+ {
+ mRT->fxaaBuffer.release();
+ }
- if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
- { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa
- if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
- }
- else
- {
- mDeferredLight.release();
- }
+ if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)
+ { //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa
+ if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16F)) return false;
+ }
+ else
+ {
+ mRT->deferredLight.release();
+ }
- allocateShadowBuffer(resX, resY);
+ allocateShadowBuffer(resX, resY);
- //HACK make screenbuffer allocations start failing after 30 seconds
- if (gSavedSettings.getBOOL("SimulateFBOFailure"))
- {
- return false;
- }
- }
- else
+ if (!gCubeSnapshot && RenderScreenSpaceReflections) // hack to not allocate mSceneMap for cube snapshots
{
- mDeferredLight.release();
+ mSceneMap.allocate(resX, resY, GL_RGB, true);
+ }
- releaseShadowTargets();
+ const bool post_hdr = gSavedSettings.getBOOL("RenderPostProcessingHDR");
+ const U32 post_color_fmt = post_hdr ? GL_RGBA16F : GL_RGBA;
+ mPostMap.allocate(resX, resY, post_color_fmt);
- mFXAABuffer.release();
- mScreen.release();
- mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
- mDeferredDepth.release();
- mOcclusionDepth.release();
-
- if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
- }
-
- if (LLPipeline::sRenderDeferred)
- { //share depth buffer between deferred targets
- mDeferredScreen.shareDepthBuffer(mScreen);
- }
+ //HACK make screenbuffer allocations start failing after 30 seconds
+ if (gSavedSettings.getBOOL("SimulateFBOFailure"))
+ {
+ return false;
+ }
- gGL.getTexUnit(0)->disable();
+ gGL.getTexUnit(0)->disable();
stop_glerror();
@@ -965,68 +859,89 @@ inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0
bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY)
{
- refreshCachedSettings();
-
- if (LLPipeline::sRenderDeferred)
- {
- S32 shadow_detail = RenderShadowDetail;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
+ S32 shadow_detail = RenderShadowDetail;
- const U32 occlusion_divisor = 3;
+ F32 scale = llmax(0.f, RenderShadowResolutionScale);
+ U32 sun_shadow_map_width = BlurHappySize(resX, scale);
+ U32 sun_shadow_map_height = BlurHappySize(resY, scale);
- F32 scale = llmax(0.f,RenderShadowResolutionScale);
- U32 sun_shadow_map_width = BlurHappySize(resX, scale);
- U32 sun_shadow_map_height = BlurHappySize(resY, scale);
+ if (shadow_detail > 0)
+ { //allocate 4 sun shadow maps
+ for (U32 i = 0; i < 4; i++)
+ {
+ if (!mRT->shadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, true))
+ {
+ return false;
+ }
+ }
+ }
+ else
+ {
+ for (U32 i = 0; i < 4; i++)
+ {
+ releaseSunShadowTarget(i);
+ }
+ }
- if (shadow_detail > 0)
- { //allocate 4 sun shadow maps
- for (U32 i = 0; i < 4; i++)
- {
- if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
- {
- return false;
- }
+ if (!gCubeSnapshot) // hack to not allocate spot shadow maps during ReflectionMapManager init
+ {
+ U32 width = (U32)(resX * scale);
+ U32 height = width;
- if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ if (shadow_detail > 1)
+ { //allocate two spot shadow maps
+ U32 spot_shadow_map_width = width;
+ U32 spot_shadow_map_height = height;
+ for (U32 i = 0; i < 2; i++)
+ {
+ if (!mSpotShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, true))
{
return false;
}
- }
- }
- else
- {
- for (U32 i = 0; i < 4; i++)
- {
- releaseShadowTarget(i);
- }
- }
+ }
+ }
+ else
+ {
+ releaseSpotShadowTargets();
+ }
+ }
- U32 width = (U32) (resX*scale);
- U32 height = width;
- if (shadow_detail > 1)
- { //allocate two spot shadow maps
- U32 spot_shadow_map_width = width;
- U32 spot_shadow_map_height = height;
- for (U32 i = 4; i < 6; i++)
- {
- if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE))
- {
- return false;
- }
- if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE))
- {
- return false;
- }
- }
+ // set up shadow map filtering and compare modes
+ if (shadow_detail > 0)
+ {
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLRenderTarget* shadow_target = getSunShadowTarget(i);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(0)->bind(getSunShadowTarget(i), TRUE);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ }
}
- else
- {
- for (U32 i = 4; i < 6; i++)
- {
- releaseShadowTarget(i);
- }
- }
- }
+ }
+
+ if (shadow_detail > 1 && !gCubeSnapshot)
+ {
+ for (U32 i = 0; i < 2; i++)
+ {
+ LLRenderTarget* shadow_target = getSpotShadowTarget(i);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(0)->bind(shadow_target, TRUE);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
+ }
+ }
+ }
return true;
}
@@ -1037,50 +952,31 @@ void LLPipeline::updateRenderTransparentWater()
sRenderTransparentWater = gSavedSettings.getBOOL("RenderTransparentWater");
}
-//static
-void LLPipeline::updateRenderBump()
-{
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
-}
-
-// static
-void LLPipeline::updateRenderDeferred()
-{
- sRenderDeferred = !gUseWireframe &&
- RenderDeferred &&
- LLRenderTarget::sUseFBO &&
- LLPipeline::sRenderBump &&
- WindLightUseAtmosShaders &&
- (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");
-}
-
// static
void LLPipeline::refreshCachedSettings()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY;
LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
LLVOAvatar::sMaxNonImpostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
LLVOAvatar::updateImpostorRendering(LLVOAvatar::sMaxNonImpostors);
- LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
LLPipeline::sUseOcclusion =
(!gUseWireframe
&& LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gSavedSettings.getBOOL("UseOcclusion")
- && gGLManager.mHasOcclusionQuery) ? 2 : 0;
+ && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0;
- WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
- RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders");
+ RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
- RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
+ RenderFSAASamples = LLFeatureManager::getInstance()->isFeatureAvailable("RenderFSAASamples") ? gSavedSettings.getU32("RenderFSAASamples") : 0;
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer");
RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail");
RenderShadowSplits = gSavedSettings.getS32("RenderShadowSplits");
RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO");
RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale");
- RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights");
RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation");
RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes");
FreezeTime = gSavedSettings.getBOOL("FreezeTime");
@@ -1099,7 +995,6 @@ void LLPipeline::refreshCachedSettings()
PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0");
PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1");
PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2");
- RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance");
RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha");
RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount");
RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights");
@@ -1108,6 +1003,7 @@ void LLPipeline::refreshCachedSettings()
RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations");
RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
+ RenderGlowNoise = gSavedSettings.getBOOL("RenderGlowNoise");
RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
@@ -1131,11 +1027,7 @@ void LLPipeline::refreshCachedSettings()
RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian");
RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric");
- RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail");
RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime");
- RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes");
- RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes");
- RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist");
RenderFarClip = gSavedSettings.getF32("RenderFarClip");
RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent");
RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff");
@@ -1144,8 +1036,16 @@ void LLPipeline::refreshCachedSettings()
CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF");
CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale");
RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit");
+ RenderScreenSpaceReflections = gSavedSettings.getBOOL("RenderScreenSpaceReflections");
+ RenderScreenSpaceReflectionIterations = gSavedSettings.getS32("RenderScreenSpaceReflectionIterations");
+ RenderScreenSpaceReflectionRayStep = gSavedSettings.getF32("RenderScreenSpaceReflectionRayStep");
+ RenderScreenSpaceReflectionDistanceBias = gSavedSettings.getF32("RenderScreenSpaceReflectionDistanceBias");
+ RenderScreenSpaceReflectionDepthRejectBias = gSavedSettings.getF32("RenderScreenSpaceReflectionDepthRejectBias");
+ RenderScreenSpaceReflectionAdaptiveStepMultiplier = gSavedSettings.getF32("RenderScreenSpaceReflectionAdaptiveStepMultiplier");
+ RenderScreenSpaceReflectionGlossySamples = gSavedSettings.getS32("RenderScreenSpaceReflectionGlossySamples");
+ RenderBufferVisualization = gSavedSettings.getS32("RenderBufferVisualization");
+ sReflectionProbesEnabled = LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionsEnabled") && gSavedSettings.getBOOL("RenderReflectionsEnabled");
RenderSpotLight = nullptr;
- updateRenderDeferred();
if (gNonInteractive)
{
@@ -1172,11 +1072,13 @@ void LLPipeline::releaseGLBuffers()
releaseLUTBuffers();
- mWaterRef.release();
mWaterDis.release();
mBake.release();
- mHighlight.release();
+ mSceneMap.release();
+
+ mPostMap.release();
+
for (U32 i = 0; i < 3; i++)
{
mGlow[i].release();
@@ -1195,58 +1097,63 @@ void LLPipeline::releaseLUTBuffers()
LLImageGL::deleteTextures(1, &mLightFunc);
mLightFunc = 0;
}
+
+ mPbrBrdfLut.release();
+
+ mExposureMap.release();
+ mLuminanceMap.release();
+ mLastExposure.release();
+
}
void LLPipeline::releaseShadowBuffers()
{
- releaseShadowTargets();
+ releaseSunShadowTargets();
+ releaseSpotShadowTargets();
}
void LLPipeline::releaseScreenBuffers()
{
- mUIScreen.release();
- mScreen.release();
- mFXAABuffer.release();
- mPhysicsDisplay.release();
- mDeferredScreen.release();
- mDeferredDepth.release();
- mDeferredLight.release();
- mOcclusionDepth.release();
+ mRT->uiScreen.release();
+ mRT->screen.release();
+ mRT->fxaaBuffer.release();
+ mRT->deferredScreen.release();
+ mRT->deferredLight.release();
}
-
-
-void LLPipeline::releaseShadowTarget(U32 index)
+
+void LLPipeline::releaseSunShadowTarget(U32 index)
{
- mShadow[index].release();
- mShadowOcclusion[index].release();
+ llassert(index < 4);
+ mRT->shadow[index].release();
}
-void LLPipeline::releaseShadowTargets()
+void LLPipeline::releaseSunShadowTargets()
{
- for (U32 i = 0; i < 6; i++)
+ for (U32 i = 0; i < 4; i++)
{
- releaseShadowTarget(i);
+ releaseSunShadowTarget(i);
}
}
+void LLPipeline::releaseSpotShadowTargets()
+{
+ if (!gCubeSnapshot) // hack to avoid freeing spot shadows during ReflectionMapManager init
+ {
+ for (U32 i = 0; i < 2; i++)
+ {
+ mSpotShadow[i].release();
+ }
+ }
+}
+
void LLPipeline::createGLBuffers()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
stop_glerror();
assertInitialized();
- updateRenderDeferred();
- if (LLPipeline::sWaterReflections)
- { //water reflection texture
- U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
- mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
- mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE);
- }
-
// Use FBO for bake tex
- mBake.allocate(512, 512, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, true); // SL-12781 Build > Upload > Model; 3D Preview
-
- mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
+ mBake.allocate(512, 512, GL_RGBA, true); // SL-12781 Build > Upload > Model; 3D Preview
stop_glerror();
@@ -1255,55 +1162,55 @@ void LLPipeline::createGLBuffers()
// allocate screen space glow buffers
const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow")));
+ const bool glow_hdr = gSavedSettings.getBOOL("RenderGlowHDR");
+ const U32 glow_color_fmt = glow_hdr ? GL_RGBA16F : GL_RGBA;
for (U32 i = 0; i < 3; i++)
{
- mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE);
+ mGlow[i].allocate(512, glow_res, glow_color_fmt);
}
allocateScreenBuffer(resX, resY);
- mScreenWidth = 0;
- mScreenHeight = 0;
+ mRT->width = 0;
+ mRT->height = 0;
- if (sRenderDeferred)
- {
- if (!mNoiseMap)
- {
- const U32 noiseRes = 128;
- LLVector3 noise[noiseRes*noiseRes];
+
+ if (!mNoiseMap)
+ {
+ const U32 noiseRes = 128;
+ LLVector3 noise[noiseRes*noiseRes];
- F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
- for (U32 i = 0; i < noiseRes*noiseRes; ++i)
- {
- noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
- noise[i].normVec();
- noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
- }
+ F32 scaler = gSavedSettings.getF32("RenderDeferredNoise")/100.f;
+ for (U32 i = 0; i < noiseRes*noiseRes; ++i)
+ {
+ noise[i] = LLVector3(ll_frand()-0.5f, ll_frand()-0.5f, 0.f);
+ noise[i].normVec();
+ noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
+ }
- LLImageGL::generateTextures(1, &mNoiseMap);
+ LLImageGL::generateTextures(1, &mNoiseMap);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
- if (!mTrueNoiseMap)
+ if (!mTrueNoiseMap)
+ {
+ const U32 noiseRes = 128;
+ F32 noise[noiseRes*noiseRes*3];
+ for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
{
- const U32 noiseRes = 128;
- F32 noise[noiseRes*noiseRes*3];
- for (U32 i = 0; i < noiseRes*noiseRes*3; i++)
- {
- noise[i] = ll_frand()*2.0-1.0;
- }
-
- LLImageGL::generateTextures(1, &mTrueNoiseMap);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ noise[i] = ll_frand()*2.0-1.0;
}
- createLUTBuffers();
+ LLImageGL::generateTextures(1, &mTrueNoiseMap);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
+ createLUTBuffers();
+
gBumpImageList.restoreGL();
}
@@ -1314,55 +1221,78 @@ F32 lerpf(F32 a, F32 b, F32 w)
void LLPipeline::createLUTBuffers()
{
- if (sRenderDeferred)
+ if (!mLightFunc)
{
- if (!mLightFunc)
+ U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
+ U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
+ F32* ls = new F32[lightResX*lightResY];
+ F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
+ for (U32 y = 0; y < lightResY; ++y)
{
- U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
- U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- F32* ls = new F32[lightResX*lightResY];
- F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
- // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
- for (U32 y = 0; y < lightResY; ++y)
+ for (U32 x = 0; x < lightResX; ++x)
{
- for (U32 x = 0; x < lightResX; ++x)
- {
- ls[y*lightResX+x] = 0;
- F32 sa = (F32) x/(lightResX-1);
- F32 spec = (F32) y/(lightResY-1);
- F32 n = spec * spec * specExp;
+ ls[y*lightResX+x] = 0;
+ F32 sa = (F32) x/(lightResX-1);
+ F32 spec = (F32) y/(lightResY-1);
+ F32 n = spec * spec * specExp;
- // Nothing special here. Just your typical blinn-phong term.
- spec = powf(sa, n);
+ // Nothing special here. Just your typical blinn-phong term.
+ spec = powf(sa, n);
- // Apply our normalization function.
- // Note: This is the full equation that applies the full normalization curve, not an approximation.
- // This is fine, given we only need to create our LUT once per buffer initialization.
- spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
-
- // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
- // Though some older drivers may not like this, newer drivers shouldn't have this problem.
- ls[y*lightResX+x] = spec;
- }
+ // Apply our normalization function.
+ // Note: This is the full equation that applies the full normalization curve, not an approximation.
+ // This is fine, given we only need to create our LUT once per buffer initialization.
+ spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
}
+ }
- U32 pix_format = GL_R16F;
+ U32 pix_format = GL_R16F;
#if LL_DARWIN
- // Need to work around limited precision with 10.6.8 and older drivers
- //
- pix_format = GL_R32F;
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
#endif
- LLImageGL::generateTextures(1, &mLightFunc);
- gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
- gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ LLImageGL::generateTextures(1, &mLightFunc);
+ gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
+ gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- delete [] ls;
- }
+ delete [] ls;
}
+
+ mPbrBrdfLut.allocate(512, 512, GL_RG16F);
+ mPbrBrdfLut.bindTarget();
+ gDeferredGenBrdfLutProgram.bind();
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.vertex2f(-1, -1);
+ gGL.vertex2f(-1, 1);
+ gGL.vertex2f(1, -1);
+ gGL.vertex2f(1, 1);
+ gGL.end();
+ gGL.flush();
+
+ gDeferredGenBrdfLutProgram.unbind();
+ mPbrBrdfLut.flush();
+
+ mExposureMap.allocate(1, 1, GL_R16F);
+ mExposureMap.bindTarget();
+ glClearColor(1, 1, 1, 0);
+ mExposureMap.clear();
+ glClearColor(0, 0, 0, 0);
+ mExposureMap.flush();
+
+ mLuminanceMap.allocate(256, 256, GL_R16F, false, LLTexUnit::TT_TEXTURE, LLTexUnit::TMG_AUTO);
+
+ mLastExposure.allocate(1, 1, GL_R16F);
}
@@ -1394,14 +1324,7 @@ bool LLPipeline::shadersLoaded()
bool LLPipeline::canUseWindLightShaders() const
{
- return (gWLSkyProgram.mProgramObject != 0 &&
- LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
-}
-
-bool LLPipeline::canUseWindLightShadersOnObjects() const
-{
- return (canUseWindLightShaders()
- && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
+ return true;
}
bool LLPipeline::canUseAntiAliasing() const
@@ -1427,39 +1350,6 @@ void LLPipeline::enableShadows(const bool enable_shadows)
//should probably do something here to wrangle shadows....
}
-S32 LLPipeline::getMaxLightingDetail() const
-{
- /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
- {
- return 3;
- }
- else*/
- {
- return 1;
- }
-}
-
-S32 LLPipeline::setLightingDetail(S32 level)
-{
- refreshCachedSettings();
-
- if (level < 0)
- {
- if (RenderLocalLights)
- {
- level = 1;
- }
- else
- {
- level = 0;
- }
- }
- level = llclamp(level, 0, getMaxLightingDetail());
- mLightingDetail = level;
-
- return mLightingDetail;
-}
-
class LLOctreeDirtyTexture : public OctreeTraveler
{
public:
@@ -1556,10 +1446,6 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mFullbrightPool;
break;
- case LLDrawPool::POOL_INVISIBLE:
- poolp = mInvisiblePool;
- break;
-
case LLDrawPool::POOL_GLOW:
poolp = mGlowPool;
break;
@@ -1578,9 +1464,12 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_MATERIALS:
poolp = mMaterialsPool;
break;
- case LLDrawPool::POOL_ALPHA:
- poolp = mAlphaPool;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ poolp = mAlphaPoolPreWater;
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ poolp = mAlphaPoolPostWater;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -1594,14 +1483,17 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mWaterPool;
break;
- case LLDrawPool::POOL_GROUND:
- poolp = mGroundPool;
- break;
-
case LLDrawPool::POOL_WL_SKY:
poolp = mWLSkyPool;
break;
+ case LLDrawPool::POOL_GLTF_PBR:
+ poolp = mPBROpaquePool;
+ break;
+ case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
+ poolp = mPBRAlphaMaskPool;
+ break;
+
default:
llassert(0);
LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
@@ -1643,6 +1535,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
LLMaterial* mat = te->getMaterialParams().get();
+ LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial();
bool color_alpha = te->getColor().mV[3] < 0.999f;
bool alpha = color_alpha;
@@ -1668,7 +1561,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
}
}
- if (alpha)
+ if (alpha || (gltf_mat && gltf_mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_BLEND))
{
return LLDrawPool::POOL_ALPHA;
}
@@ -1676,6 +1569,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
{
return LLDrawPool::POOL_BUMP;
}
+ else if (gltf_mat)
+ {
+ return LLDrawPool::POOL_GLTF_PBR;
+ }
else if (mat && !alpha)
{
return LLDrawPool::POOL_MATERIALS;
@@ -1752,14 +1649,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
}
- HighlightItem item(drawablep);
- mHighlightSet.erase(item);
-
- if (mHighlightObject == drawablep)
- {
- mHighlightObject = NULL;
- }
-
for (U32 i = 0; i < 2; ++i)
{
if (mShadowSpotLight[i] == drawablep)
@@ -1854,7 +1743,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
vobj->setDrawableParent(NULL); // LLPipeline::addObject 2
}
- markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE);
+ markRebuild(drawablep, LLDrawable::REBUILD_ALL);
if (drawablep->getVOVolume() && RenderAnimateRes)
{
@@ -1970,10 +1859,10 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
{ //will likely not receive any future world matrix updates
// -- this keeps attachments from getting stuck in space and falling off your avatar
drawablep->clearState(LLDrawable::ANIMATED_CHILD);
- markRebuild(drawablep, LLDrawable::REBUILD_VOLUME, TRUE);
+ markRebuild(drawablep, LLDrawable::REBUILD_VOLUME);
if (drawablep->getVObj())
{
- drawablep->getVObj()->dirtySpatialGroup(TRUE);
+ drawablep->getVObj()->dirtySpatialGroup();
}
}
iter = moved_list.erase(curiter);
@@ -2035,6 +1924,7 @@ void LLPipeline::updateMove()
//static
F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera)
{
+ llassert(!gCubeSnapshot); // shouldn't be doing ANY of this during cube snap shots
LLVector3 lookAt = center - camera.getOrigin();
F32 dist = lookAt.length();
@@ -2327,23 +2217,46 @@ bool LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
}
LLViewerCamera::sCurCameraID = saved_camera_id;
-
return res;
}
static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
-void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep)
+// static
+bool LLPipeline::isWaterClip()
{
- static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
- static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
- && gGLManager.mHasOcclusionQuery;
+ return (!sRenderTransparentWater || gCubeSnapshot) && !sRenderingHUDs;
+}
+void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result)
+{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL);
+ LL_PROFILE_GPU_ZONE("updateCull"); // should always be zero GPU time, but drop a timer to flush stuff out
+
+ bool water_clip = isWaterClip();
- if (planep != nullptr)
+ if (water_clip)
{
- camera.setUserClipPlane(*planep);
+
+ LLVector3 pnorm;
+
+ F32 water_height = LLEnvironment::instance().getWaterHeight();
+
+ if (sUnderWaterRender)
+ {
+ //camera is below water, cull above water
+ pnorm.setVec(0, 0, 1);
+ }
+ else
+ {
+ //camera is above water, cull below water
+ pnorm = LLVector3(0, 0, -1);
+ }
+
+ LLPlane plane;
+ plane.setVec(LLVector3(0, 0, water_height), pnorm);
+
+ camera.setUserClipPlane(plane);
}
else
{
@@ -2354,56 +2267,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
sCull->clear();
- bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.shadersLoaded();
-
- if (to_texture)
- {
- if (LLPipeline::sRenderDeferred && can_use_occlusion)
- {
- mOcclusionDepth.bindTarget();
- }
- else
- {
- mScreen.bindTarget();
- }
- }
-
- if (sUseOcclusion > 1)
- {
- gGL.setColorMask(false, false);
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadMatrix(gGLLastProjection);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLLastModelView);
-
- LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
-
- bool bound_shader = false;
- if (gPipeline.shadersLoaded() && LLGLSLShader::sCurBoundShader == 0)
- { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can
- // (shadow render uses a special shader that clamps to clip planes)
- bound_shader = true;
- gOcclusionCubeProgram.bind();
- }
-
- if (sUseOcclusion > 1)
- {
- if (mCubeVB.isNull())
- { //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
- }
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- }
-
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -2425,16 +2288,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
LLVOCachePartition* vo_part = region->getVOCachePartition();
if(vo_part)
{
- bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe;
- vo_part->cull(camera, do_occlusion_cull);
+ vo_part->cull(camera, sUseOcclusion > 0);
}
}
- if (bound_shader)
- {
- gOcclusionCubeProgram.unbind();
- }
-
if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) &&
gSky.mVOSkyp.notNull() &&
gSky.mVOSkyp->mDrawable.notNull())
@@ -2445,17 +2302,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
stop_glerror();
}
- if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) &&
- !gPipeline.canUseWindLightShaders() &&
- gSky.mVOGroundp.notNull() &&
- gSky.mVOGroundp->mDrawable.notNull() &&
- !LLPipeline::sWaterReflections)
- {
- gSky.mVOGroundp->mDrawable->setVisible(camera);
- sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
- }
-
-
if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
gPipeline.canUseWindLightShaders() &&
gSky.mVOWLSkyp.notNull() &&
@@ -2471,28 +2317,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* pla
{
LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
}
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- if (sUseOcclusion > 1)
- {
- gGL.setColorMask(true, false);
- }
-
- if (to_texture)
- {
- if (LLPipeline::sRenderDeferred && can_use_occlusion)
- {
- mOcclusionDepth.flush();
- }
- else
- {
- mScreen.flush();
- }
- }
}
void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
@@ -2504,7 +2328,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
group->setVisible();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
group->updateDistance(camera);
}
@@ -2520,6 +2344,13 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
sCull->pushVisibleGroup(group);
}
+ if (group->needsUpdate() ||
+ group->getVisible(LLViewerCamera::sCurCameraID) < LLDrawable::getCurrentFrame() - 1)
+ {
+ // include this group in occlusion groups, not because it is an occluder, but because we want to run
+ // an occlusion query to find out if it's an occluder
+ markOccluder(group);
+ }
mNumVisibleNodes++;
}
@@ -2546,124 +2377,61 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
-void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+void LLPipeline::doOcclusion(LLCamera& camera)
{
- LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
-
- LLGLSLShader* shader = NULL;
-
- if (scratch_space)
- {
- GLint bits = 0;
- bits |= (source.hasStencil() && dest.hasStencil()) ? GL_STENCIL_BUFFER_BIT : 0;
- bits |= GL_DEPTH_BUFFER_BIT;
- scratch_space->copyContents(source,
- 0, 0, source.getWidth(), source.getHeight(),
- 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), bits, GL_NEAREST);
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("doOcclusion");
+ llassert(!gCubeSnapshot);
- dest.bindTarget();
- dest.clear(GL_DEPTH_BUFFER_BIT);
+ if (sReflectionProbesEnabled && sUseOcclusion > 1 && !LLPipeline::sShadowRender && !gCubeSnapshot)
+ {
+ gGL.setColorMask(false, false);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ LLGLDisable cull(GL_CULL_FACE);
- LLStrider<LLVector3> vert;
- mDeferredVB->getVertexStrider(vert);
- LLStrider<LLVector2> tc0;
-
- vert[0].set(-1,1,0);
- vert[1].set(-1,-3,0);
- vert[2].set(3,1,0);
-
- if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
- {
- shader = &gDownsampleDepthRectProgram;
- shader->bind();
- shader->uniform2f(sDelta, 1.f, 1.f);
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
- }
- else
- {
- shader = &gDownsampleDepthProgram;
- shader->bind();
- shader->uniform2f(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight());
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
- }
+ gOcclusionCubeProgram.bind();
- gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+ if (mCubeVB.isNull())
+ { //cube VB will be used for issuing occlusion queries
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
+ }
+ mCubeVB->setBuffer();
- {
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- }
-
- dest.flush();
-
- if (last_shader)
- {
- last_shader->bind();
- }
- else
- {
- shader->unbind();
- }
-}
+ mReflectionMapManager.doOcclusion();
+ gOcclusionCubeProgram.unbind();
-void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
-{
- downsampleDepthBuffer(source, dest, scratch_space);
- dest.bindTarget();
- doOcclusion(camera);
- dest.flush();
-}
+ gGL.setColorMask(true, true);
+ }
-void LLPipeline::doOcclusion(LLCamera& camera)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
+ if (LLPipeline::sUseOcclusion > 1 &&
(sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION))
- {
- gGL.setColorMask(true, false, false, false);
- }
- else
- {
- gGL.setColorMask(false, false);
- }
+ gGL.setColorMask(false, false);
+
LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
LLGLDisable cull(GL_CULL_FACE);
-
- bool bind_shader = (LLGLSLShader::sCurBoundShader == 0);
- if (bind_shader)
- {
- if (LLPipeline::sShadowRender)
- {
- gDeferredShadowCubeProgram.bind();
- }
- else
- {
- gOcclusionCubeProgram.bind();
- }
- }
+ gOcclusionCubeProgram.bind();
if (mCubeVB.isNull())
{ //cube VB will be used for issuing occlusion queries
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
}
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer();
for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
- group->doOcclusion(&camera);
- group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+ if (!group->isDead())
+ {
+ group->doOcclusion(&camera);
+ group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
+ }
}
//apply occlusion culling to object cache tree
@@ -2677,25 +2445,13 @@ void LLPipeline::doOcclusion(LLCamera& camera)
}
}
- if (bind_shader)
- {
- if (LLPipeline::sShadowRender)
- {
- gDeferredShadowCubeProgram.unbind();
- }
- else
- {
- gOcclusionCubeProgram.unbind();
- }
- }
-
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, true);
}
}
-bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep, bool priority)
+bool LLPipeline::updateDrawableGeom(LLDrawable* drawablep)
{
- bool update_complete = drawablep->updateGeometry(priority);
+ bool update_complete = drawablep->updateGeometry();
if (update_complete && assertInitialized())
{
drawablep->setState(LLDrawable::BUILT);
@@ -2715,10 +2471,6 @@ void LLPipeline::updateGL()
LLGLUpdate::sGLQ.pop_front();
}
}
-
- { //seed VBO Pools
- LLVertexBuffer::seedPools();
- }
}
void LLPipeline::clearRebuildGroups()
@@ -2751,33 +2503,6 @@ void LLPipeline::clearRebuildGroups()
// Copy the saved HUD groups back in
mGroupQ1.assign(hudGroups.begin(), hudGroups.end());
mGroupQ1Locked = false;
-
- // Clear the HUD groups
- hudGroups.clear();
-
- mGroupQ2Locked = true;
- for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin();
- iter != mGroupQ2.end(); ++iter)
- {
- LLSpatialGroup* group = *iter;
-
- // If the group contains HUD objects, save the group
- if (group->isHUDGroup())
- {
- hudGroups.push_back(group);
- }
- // Else, no HUD objects so clear the build state
- else
- {
- group->clearState(LLSpatialGroup::IN_BUILD_Q2);
- }
- }
- // Clear the group
- mGroupQ2.clear();
-
- // Copy the saved HUD groups back in
- mGroupQ2.assign(hudGroups.begin(), hudGroups.end());
- mGroupQ2Locked = false;
}
void LLPipeline::clearRebuildDrawables()
@@ -2789,24 +2514,11 @@ void LLPipeline::clearRebuildDrawables()
LLDrawable* drawablep = *iter;
if (drawablep && !drawablep->isDead())
{
- drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
- drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q);
}
}
mBuildQ1.clear();
- // clear drawables on the non-priority build queue
- for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin();
- iter != mBuildQ2.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
- if (!drawablep->isDead())
- {
- drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
- }
- }
- mBuildQ2.clear();
-
//clear all moving bridges
for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin();
iter != mMovedBridge.end(); ++iter)
@@ -2837,6 +2549,8 @@ void LLPipeline::clearRebuildDrawables()
void LLPipeline::rebuildPriorityGroups()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("rebuildPriorityGroups");
+
LLTimer update_timer;
assertInitialized();
@@ -2858,58 +2572,16 @@ void LLPipeline::rebuildPriorityGroups()
}
-void LLPipeline::rebuildGroups()
-{
- if (mGroupQ2.empty())
- {
- return;
- }
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- mGroupQ2Locked = true;
- // Iterate through some drawables on the non-priority build queue
- S32 size = (S32) mGroupQ2.size();
- S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size);
-
- S32 count = 0;
-
- std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency());
-
- LLSpatialGroup::sg_vector_t::iterator iter;
- LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin();
-
- for (iter = mGroupQ2.begin();
- iter != mGroupQ2.end() && count <= min_count; ++iter)
- {
- LLSpatialGroup* group = *iter;
- last_iter = iter;
-
- if (!group->isDead())
- {
- group->rebuildGeom();
-
- if (group->getSpatialPartition()->mRenderByGroup)
- {
- count++;
- }
- }
-
- group->clearState(LLSpatialGroup::IN_BUILD_Q2);
- }
-
- mGroupQ2.erase(mGroupQ2.begin(), ++last_iter);
-
- mGroupQ2Locked = false;
-
- updateMovedList(mMovedBridge);
-}
-
void LLPipeline::updateGeom(F32 max_dtime)
{
LLTimer update_timer;
LLPointer<LLDrawable> drawablep;
LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
+ if (gCubeSnapshot)
+ {
+ return;
+ }
assertInitialized();
@@ -2925,25 +2597,15 @@ void LLPipeline::updateGeom(F32 max_dtime)
LLDrawable* drawablep = *curiter;
if (drawablep && !drawablep->isDead())
{
- if (drawablep->isState(LLDrawable::IN_REBUILD_Q2))
- {
- drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
- LLDrawable::drawable_list_t::iterator find = std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep);
- if (find != mBuildQ2.end())
- {
- mBuildQ2.erase(find);
- }
- }
-
if (drawablep->isUnload())
{
drawablep->unload();
drawablep->clearState(LLDrawable::FOR_UNLOAD);
}
- if (updateDrawableGeom(drawablep, TRUE))
+ if (updateDrawableGeom(drawablep))
{
- drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q);
mBuildQ1.erase(curiter);
}
}
@@ -2952,54 +2614,6 @@ void LLPipeline::updateGeom(F32 max_dtime)
mBuildQ1.erase(curiter);
}
}
-
- // Iterate through some drawables on the non-priority build queue
- S32 min_count = 16;
- S32 size = (S32) mBuildQ2.size();
- if (size > 1024)
- {
- min_count = llclamp((S32) (size * (F32) size/4096), 16, size);
- }
-
- S32 count = 0;
-
- max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, F32SecondsImplicit(max_dtime));
- LLSpatialGroup* last_group = NULL;
- LLSpatialBridge* last_bridge = NULL;
-
- for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin();
- iter != mBuildQ2.end(); )
- {
- LLDrawable::drawable_list_t::iterator curiter = iter++;
- LLDrawable* drawablep = *curiter;
-
- LLSpatialBridge* bridge = drawablep->isRoot() ? drawablep->getSpatialBridge() :
- drawablep->getParent()->getSpatialBridge();
-
- if (drawablep->getSpatialGroup() != last_group &&
- (!last_bridge || bridge != last_bridge) &&
- (update_timer.getElapsedTimeF32() >= max_dtime) && count > min_count)
- {
- break;
- }
-
- //make sure updates don't stop in the middle of a spatial group
- //to avoid thrashing (objects are enqueued by group)
- last_group = drawablep->getSpatialGroup();
- last_bridge = bridge;
-
- bool update_complete = true;
- if (!drawablep->isDead())
- {
- update_complete = updateDrawableGeom(drawablep, FALSE);
- count++;
- }
- if (update_complete)
- {
- drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
- mBuildQ2.erase(curiter);
- }
- }
updateMovedList(mMovedBridge);
}
@@ -3149,6 +2763,8 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
}
}
+ mReflectionMapManager.shift(offseta);
+
LLHUDText::shiftAll(offset);
LLHUDNameTag::shiftAll(offset);
@@ -3204,79 +2820,31 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group)
mMeshDirtyGroup.push_back(group);
}
-void LLPipeline::markRebuild(LLSpatialGroup* group, bool priority)
+void LLPipeline::markRebuild(LLSpatialGroup* group)
{
if (group && !group->isDead() && group->getSpatialPartition())
{
- if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD)
- {
- priority = true;
- }
-
- if (priority)
- {
- if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
- {
- llassert_always(!mGroupQ1Locked);
-
- mGroupQ1.push_back(group);
- group->setState(LLSpatialGroup::IN_BUILD_Q1);
-
- if (group->hasState(LLSpatialGroup::IN_BUILD_Q2))
- {
- LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);
- if (iter != mGroupQ2.end())
- {
- mGroupQ2.erase(iter);
- }
- group->clearState(LLSpatialGroup::IN_BUILD_Q2);
- }
- }
- }
- else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
+ if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
{
- llassert_always(!mGroupQ2Locked);
- mGroupQ2.push_back(group);
- group->setState(LLSpatialGroup::IN_BUILD_Q2);
+ llassert_always(!mGroupQ1Locked);
+ mGroupQ1.push_back(group);
+ group->setState(LLSpatialGroup::IN_BUILD_Q1);
}
}
}
-void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, bool priority)
+void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag)
{
if (drawablep && !drawablep->isDead() && assertInitialized())
{
- if (debugLoggingEnabled("AnimatedObjectsLinkset"))
- {
- LLVOVolume *vol_obj = drawablep->getVOVolume();
- if (vol_obj && vol_obj->isAnimatedObject() && vol_obj->isRiggedMesh())
- {
- std::string vobj_name = llformat("Vol%p", vol_obj);
- F32 est_tris = vol_obj->getEstTrianglesMax();
- LL_DEBUGS("AnimatedObjectsLinkset") << vobj_name << " markRebuild, tris " << est_tris
- << " priority " << (S32) priority << " flag " << std::hex << flag << LL_ENDL;
- }
- }
-
- if (!drawablep->isState(LLDrawable::BUILT))
- {
- priority = true;
- }
- if (priority)
+ if (!drawablep->isState(LLDrawable::IN_REBUILD_Q))
{
- if (!drawablep->isState(LLDrawable::IN_REBUILD_Q1))
- {
- mBuildQ1.push_back(drawablep);
- drawablep->setState(LLDrawable::IN_REBUILD_Q1); // mark drawable as being in priority queue
- }
+ mBuildQ1.push_back(drawablep);
+ drawablep->setState(LLDrawable::IN_REBUILD_Q); // mark drawable as being in priority queue
}
- else if (!drawablep->isState(LLDrawable::IN_REBUILD_Q2))
- {
- mBuildQ2.push_back(drawablep);
- drawablep->setState(LLDrawable::IN_REBUILD_Q2); // need flag here because it is just a list
- }
- if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
+
+ if (flag & (LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
{
drawablep->getVObj()->setChanged(LLXform::SILHOUETTE);
}
@@ -3287,10 +2855,10 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("stateSort");
if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
LLPipeline::RENDER_TYPE_CONTROL_AV,
- LLPipeline::RENDER_TYPE_GROUND,
LLPipeline::RENDER_TYPE_TERRAIN,
LLPipeline::RENDER_TYPE_TREE,
LLPipeline::RENDER_TYPE_SKY,
@@ -3308,6 +2876,10 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
for (LLCullResult::sg_iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
+ if (group->isDead())
+ {
+ continue;
+ }
group->checkOcclusion();
if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
@@ -3322,14 +2894,13 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
markVisible(drawablep, camera);
}
- if (!sDelayVBUpdate)
{ //rebuild mesh as soon as we know it's visible
group->rebuildMesh();
}
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
LLSpatialGroup* last_group = NULL;
BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
@@ -3368,6 +2939,10 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
{
LLSpatialGroup* group = *iter;
+ if (group->isDead())
+ {
+ continue;
+ }
group->checkOcclusion();
if (sUseOcclusion > 1 && group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
@@ -3378,7 +2953,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
group->setVisible();
stateSort(group, camera);
- if (!sDelayVBUpdate)
{ //rebuild mesh as soon as we know it's visible
group->rebuildMesh();
}
@@ -3411,7 +2985,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
stateSort(drawablep, camera);
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{ //avoid redundant stateSort calls
group->mLastUpdateDistance = group->mDistance;
}
@@ -3480,7 +3054,7 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
//if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here
{
@@ -3528,7 +3102,12 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
{
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
- for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
+ LLSpatialGroup* group = *i;
+ if (group->isDead())
+ {
+ continue;
+ }
+ for (LLSpatialGroup::element_iter j = group->getDataBegin(); j != group->getDataEnd(); ++j)
{
if((*j)->hasDrawable())
{
@@ -3574,424 +3153,400 @@ void renderScriptedBeacons(LLDrawable* drawablep)
}
}
-void renderScriptedTouchBeacons(LLDrawable* drawablep)
+void renderScriptedTouchBeacons(LLDrawable *drawablep)
{
- LLViewerObject *vobj = drawablep->getVObj();
- if (vobj
- && !vobj->isAvatar()
- && !vobj->getParent()
- && vobj->flagScripted()
- && vobj->flagHandleTouch())
- {
- if (gPipeline.sRenderBeacons)
- {
- gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
- }
+ LLViewerObject *vobj = drawablep->getVObj();
+ if (vobj && !vobj->isAvatar() && !vobj->getParent() && vobj->flagScripted() && vobj->flagHandleTouch())
+ {
+ if (gPipeline.sRenderBeacons)
+ {
+ gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLPipeline::DebugBeaconLineWidth);
+ }
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
-}
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace *facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
-void renderPhysicalBeacons(LLDrawable* drawablep)
+void renderPhysicalBeacons(LLDrawable *drawablep)
{
- LLViewerObject *vobj = drawablep->getVObj();
- if (vobj
- && !vobj->isAvatar()
- //&& !vobj->getParent()
- && vobj->flagUsePhysics())
- {
- if (gPipeline.sRenderBeacons)
- {
- gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
- }
+ LLViewerObject *vobj = drawablep->getVObj();
+ if (vobj &&
+ !vobj->isAvatar()
+ //&& !vobj->getParent()
+ && vobj->flagUsePhysics())
+ {
+ if (gPipeline.sRenderBeacons)
+ {
+ gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLPipeline::DebugBeaconLineWidth);
+ }
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
-}
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace *facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
-void renderMOAPBeacons(LLDrawable* drawablep)
+void renderMOAPBeacons(LLDrawable *drawablep)
{
- LLViewerObject *vobj = drawablep->getVObj();
+ LLViewerObject *vobj = drawablep->getVObj();
- if(!vobj || vobj->isAvatar())
- return;
+ if (!vobj || vobj->isAvatar())
+ return;
- bool beacon=false;
- U8 tecount=vobj->getNumTEs();
- for(int x=0;x<tecount;x++)
- {
- if(vobj->getTE(x)->hasMedia())
- {
- beacon=true;
- break;
- }
- }
- if(beacon)
- {
- if (gPipeline.sRenderBeacons)
- {
- gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
- }
+ bool beacon = false;
+ U8 tecount = vobj->getNumTEs();
+ for (int x = 0; x < tecount; x++)
+ {
+ if (vobj->getTE(x)->hasMedia())
+ {
+ beacon = true;
+ break;
+ }
+ }
+ if (beacon)
+ {
+ if (gPipeline.sRenderBeacons)
+ {
+ gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLPipeline::DebugBeaconLineWidth);
+ }
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
-}
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace *facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
-void renderParticleBeacons(LLDrawable* drawablep)
+void renderParticleBeacons(LLDrawable *drawablep)
{
- // Look for attachments, objects, etc.
- LLViewerObject *vobj = drawablep->getVObj();
- if (vobj
- && vobj->isParticleSource())
- {
- if (gPipeline.sRenderBeacons)
- {
- LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f);
- gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth);
- }
+ // Look for attachments, objects, etc.
+ LLViewerObject *vobj = drawablep->getVObj();
+ if (vobj && vobj->isParticleSource())
+ {
+ if (gPipeline.sRenderBeacons)
+ {
+ LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f);
+ gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f),
+ LLPipeline::DebugBeaconLineWidth);
+ }
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
-}
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace *facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
-void renderSoundHighlights(LLDrawable* drawablep)
+void renderSoundHighlights(LLDrawable *drawablep)
{
- // Look for attachments, objects, etc.
- LLViewerObject *vobj = drawablep->getVObj();
- if (vobj && vobj->isAudioSource())
- {
- if (gPipeline.sRenderHighlight)
- {
- S32 face_id;
- S32 count = drawablep->getNumFaces();
- for (face_id = 0; face_id < count; face_id++)
- {
- LLFace * facep = drawablep->getFace(face_id);
- if (facep)
- {
- gPipeline.mHighlightFaces.push_back(facep);
- }
- }
- }
-}
+ // Look for attachments, objects, etc.
+ LLViewerObject *vobj = drawablep->getVObj();
+ if (vobj && vobj->isAudioSource())
+ {
+ if (gPipeline.sRenderHighlight)
+ {
+ S32 face_id;
+ S32 count = drawablep->getNumFaces();
+ for (face_id = 0; face_id < count; face_id++)
+ {
+ LLFace *facep = drawablep->getFace(face_id);
+ if (facep)
+ {
+ gPipeline.mHighlightFaces.push_back(facep);
+ }
+ }
+ }
+ }
}
-void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize)
+void LLPipeline::postSort(LLCamera &camera)
{
- if (tex)
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+ assertInitialized();
+
+ LL_PUSH_CALLSTACKS();
+
+ if (!gCubeSnapshot)
{
- LLImageGL* gl_tex = tex->getGLTexture();
- if (gl_tex && gl_tex->updateBindStats(gl_tex->mTextureMemory))
+ // rebuild drawable geometry
+ for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
{
- tex->setActive();
- tex->addTextureStats(vsize);
+ LLSpatialGroup *group = *i;
+ if (group->isDead())
+ {
+ continue;
+ }
+ if (!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
+ {
+ group->rebuildGeom();
+ }
}
+ LL_PUSH_CALLSTACKS();
+ // rebuild groups
+ sCull->assertDrawMapsEmpty();
+
+ rebuildPriorityGroups();
}
+ LL_PUSH_CALLSTACKS();
-}
-void LLPipeline::touchTextures(LLDrawInfo* info)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- for (int i = 0; i < info->mTextureList.size(); ++i)
+ // build render map
+ for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
- touchTexture(info->mTextureList[i], info->mTextureListVSize[i]);
- }
+ LLSpatialGroup *group = *i;
- touchTexture(info->mTexture, info->mVSize);
- touchTexture(info->mSpecularMap, info->mVSize);
- touchTexture(info->mNormalMap, info->mVSize);
-}
+ if (group->isDead())
+ {
+ continue;
+ }
-void LLPipeline::postSort(LLCamera& camera)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ if ((sUseOcclusion && group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
+ (RenderAutoHideSurfaceAreaLimit > 0.f &&
+ group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit * llmax(group->mObjectBoxSize, 10.f)))
+ {
+ continue;
+ }
- assertInitialized();
+ if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY) && !gCubeSnapshot)
+ { // no way this group is going to be drawable without a rebuild
+ group->rebuildGeom();
+ }
- LL_PUSH_CALLSTACKS();
- //rebuild drawable geometry
- for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
- {
- LLSpatialGroup* group = *i;
- if (!sUseOcclusion ||
- !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
- {
- group->rebuildGeom();
- }
- }
- LL_PUSH_CALLSTACKS();
- //rebuild groups
- sCull->assertDrawMapsEmpty();
+ for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
+ {
+ LLSpatialGroup::drawmap_elem_t &src_vec = j->second;
+ if (!hasRenderType(j->first))
+ {
+ continue;
+ }
- rebuildPriorityGroups();
- LL_PUSH_CALLSTACKS();
+ for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
+ {
+ LLDrawInfo *info = *k;
-
- //build render map
- for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
- {
- LLSpatialGroup* group = *i;
- if ((sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
- (RenderAutoHideSurfaceAreaLimit > 0.f &&
- group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
- {
- continue;
- }
+ sCull->pushDrawInfo(j->first, info);
+ if (!sShadowRender && !sReflectionRender && !gCubeSnapshot)
+ {
+ addTrianglesDrawn(info->mCount);
+ }
+ }
+ }
- if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
- { //no way this group is going to be drawable without a rebuild
- group->rebuildGeom();
- }
+ if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
+ {
+ LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
- for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j)
- {
- LLSpatialGroup::drawmap_elem_t& src_vec = j->second;
- if (!hasRenderType(j->first))
- {
- continue;
- }
-
- for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k)
- {
- LLDrawInfo* info = *k;
-
- sCull->pushDrawInfo(j->first, info);
- if (!sShadowRender && !sReflectionRender)
+ if (alpha != group->mDrawMap.end())
+ { // store alpha groups for sorting
+ LLSpatialBridge *bridge = group->getSpatialPartition()->asBridge();
+ if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && !gCubeSnapshot)
{
- touchTextures(info);
- addTrianglesDrawn(info->mCount, info->mDrawMode);
+ if (bridge)
+ {
+ LLCamera trans_camera = bridge->transformCamera(camera);
+ group->updateDistance(trans_camera);
+ }
+ else
+ {
+ group->updateDistance(camera);
+ }
}
- }
- }
- if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA))
- {
- LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA);
-
- if (alpha != group->mDrawMap.end())
- { //store alpha groups for sorting
- LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
- if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
- {
- if (bridge)
- {
- LLCamera trans_camera = bridge->transformCamera(camera);
- group->updateDistance(trans_camera);
- }
- else
- {
- group->updateDistance(camera);
- }
- }
-
- if (hasRenderType(LLDrawPool::POOL_ALPHA))
- {
- sCull->pushAlphaGroup(group);
- }
- }
+ if (hasRenderType(LLDrawPool::POOL_ALPHA))
+ {
+ sCull->pushAlphaGroup(group);
+ }
+ }
LLSpatialGroup::draw_map_t::iterator rigged_alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA_RIGGED);
if (rigged_alpha != group->mDrawMap.end())
- { //store rigged alpha groups for LLDrawPoolAlpha prepass (skip distance update, rigged attachments use depth buffer)
+ { // store rigged alpha groups for LLDrawPoolAlpha prepass (skip distance update, rigged attachments use depth buffer)
if (hasRenderType(LLDrawPool::POOL_ALPHA))
{
sCull->pushRiggedAlphaGroup(group);
}
}
- }
- }
-
- //flush particle VB
- if (LLVOPartGroup::sVB)
- {
- LLVOPartGroup::sVB->flush();
- }
- else
- {
- LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL;
- }
+ }
+ }
- /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty();
+ /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty();
- if (use_transform_feedback)
- { //place a query around potential transform feedback code for synchronization
- mTransformFeedbackPrimitives = 0;
+ if (use_transform_feedback)
+ { //place a query around potential transform feedback code for synchronization
+ mTransformFeedbackPrimitives = 0;
- if (!mMeshDirtyQueryObject)
- {
- glGenQueriesARB(1, &mMeshDirtyQueryObject);
- }
+ if (!mMeshDirtyQueryObject)
+ {
+ glGenQueries(1, &mMeshDirtyQueryObject);
+ }
-
- glBeginQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
- }*/
- //pack vertex buffers for groups that chose to delay their updates
- for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
- {
- (*iter)->rebuildMesh();
- }
+ glBeginQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, mMeshDirtyQueryObject);
+ }*/
- /*if (use_transform_feedback)
- {
- glEndQueryARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
- }*/
-
- mMeshDirtyGroup.clear();
+ // pack vertex buffers for groups that chose to delay their updates
+ {
+ LL_PROFILE_GPU_ZONE("rebuildMesh");
+ for (LLSpatialGroup::sg_vector_t::iterator iter = mMeshDirtyGroup.begin(); iter != mMeshDirtyGroup.end(); ++iter)
+ {
+ (*iter)->rebuildMesh();
+ }
+ }
- if (!sShadowRender)
- {
+ /*if (use_transform_feedback)
+ {
+ glEndQuery(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN);
+ }*/
+
+ mMeshDirtyGroup.clear();
+
+ if (!sShadowRender)
+ {
// order alpha groups by distance
- std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
+ std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
// order rigged alpha groups by avatar attachment order
std::sort(sCull->beginRiggedAlphaGroups(), sCull->endRiggedAlphaGroups(), LLSpatialGroup::CompareRenderOrder());
- }
+ }
- LL_PUSH_CALLSTACKS();
- // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
- if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
- {
- if (sRenderScriptedTouchBeacons)
- {
- // Only show the beacon on the root object.
- forAllVisibleDrawables(renderScriptedTouchBeacons);
- }
- else
- if (sRenderScriptedBeacons)
- {
- // Only show the beacon on the root object.
- forAllVisibleDrawables(renderScriptedBeacons);
- }
+ LL_PUSH_CALLSTACKS();
+ // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
+ if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender && !gCubeSnapshot)
+ {
+ if (sRenderScriptedTouchBeacons)
+ {
+ // Only show the beacon on the root object.
+ forAllVisibleDrawables(renderScriptedTouchBeacons);
+ }
+ else if (sRenderScriptedBeacons)
+ {
+ // Only show the beacon on the root object.
+ forAllVisibleDrawables(renderScriptedBeacons);
+ }
- if (sRenderPhysicalBeacons)
- {
- // Only show the beacon on the root object.
- forAllVisibleDrawables(renderPhysicalBeacons);
- }
+ if (sRenderPhysicalBeacons)
+ {
+ // Only show the beacon on the root object.
+ forAllVisibleDrawables(renderPhysicalBeacons);
+ }
- if(sRenderMOAPBeacons)
- {
- forAllVisibleDrawables(renderMOAPBeacons);
- }
+ if (sRenderMOAPBeacons)
+ {
+ forAllVisibleDrawables(renderMOAPBeacons);
+ }
- if (sRenderParticleBeacons)
- {
- forAllVisibleDrawables(renderParticleBeacons);
- }
+ if (sRenderParticleBeacons)
+ {
+ forAllVisibleDrawables(renderParticleBeacons);
+ }
- // If god mode, also show audio cues
- if (sRenderSoundBeacons && gAudiop)
- {
- // 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)
- {
- LLAudioSource *sourcep = iter->second;
+ // If god mode, also show audio cues
+ if (sRenderSoundBeacons && gAudiop)
+ {
+ // 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)
+ {
+ LLAudioSource *sourcep = iter->second;
- LLVector3d pos_global = sourcep->getPositionGlobal();
- LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global);
- if (gPipeline.sRenderBeacons)
- {
- //pos += LLVector3(0.f, 0.f, 0.2f);
- gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth);
- }
- }
- // now deal with highlights for all those seeable sound sources
- forAllVisibleDrawables(renderSoundHighlights);
- }
- }
- LL_PUSH_CALLSTACKS();
- // If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
- if (LLFloaterTelehub::renderBeacons() && !sShadowRender)
- {
- LLFloaterTelehub::addBeacons();
- }
+ LLVector3d pos_global = sourcep->getPositionGlobal();
+ LLVector3 pos = gAgent.getPosAgentFromGlobal(pos_global);
+ if (gPipeline.sRenderBeacons)
+ {
+ // pos += LLVector3(0.f, 0.f, 0.2f);
+ gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth);
+ }
+ }
+ // now deal with highlights for all those seeable sound sources
+ forAllVisibleDrawables(renderSoundHighlights);
+ }
+ }
+ LL_PUSH_CALLSTACKS();
+ // If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
+ if (LLFloaterTelehub::renderBeacons() && !sShadowRender && !gCubeSnapshot)
+ {
+ LLFloaterTelehub::addBeacons();
+ }
- if (!sShadowRender)
- {
- mSelectedFaces.clear();
+ if (!sShadowRender && !gCubeSnapshot)
+ {
+ mSelectedFaces.clear();
- if (!gNonInteractive)
- {
- LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
- }
+ if (!gNonInteractive)
+ {
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+ }
- // Draw face highlights for selected faces.
- if (LLSelectMgr::getInstance()->getTEMode())
- {
- struct f : public LLSelectedTEFunctor
- {
- virtual bool apply(LLViewerObject* object, S32 te)
- {
- if (object->mDrawable)
- {
- LLFace * facep = object->mDrawable->getFace(te);
- if (facep)
- {
- gPipeline.mSelectedFaces.push_back(facep);
- }
- }
- return true;
- }
- } func;
- LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
- }
- }
+ // Draw face highlights for selected faces.
+ if (LLSelectMgr::getInstance()->getTEMode())
+ {
+ struct f : public LLSelectedTEFunctor
+ {
+ virtual bool apply(LLViewerObject *object, S32 te)
+ {
+ if (object->mDrawable)
+ {
+ LLFace *facep = object->mDrawable->getFace(te);
+ if (facep)
+ {
+ gPipeline.mSelectedFaces.push_back(facep);
+ }
+ }
+ return true;
+ }
+ } func;
+ LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
+ }
+ }
- //LLSpatialGroup::sNoDelete = FALSE;
- LL_PUSH_CALLSTACKS();
+ // LLSpatialGroup::sNoDelete = FALSE;
+ LL_PUSH_CALLSTACKS();
}
@@ -4000,22 +3555,19 @@ void render_hud_elements()
LL_PROFILE_ZONE_SCOPED_CATEGORY_UI; //LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
- LLGLDisable fog(GL_FOG);
LLGLSUIDefault gls_ui;
- LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
- glStencilMask(0xFFFFFFFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
-
- gGL.color4f(1,1,1,1);
+ //LLGLEnable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_ALWAYS, 255, 0xFFFFFFFF);
+ //glStencilMask(0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
gUIProgram.bind();
+ gGL.color4f(1, 1, 1, 1);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
{
- LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d()
// Draw the tracking overlays
@@ -4028,9 +3580,6 @@ void render_hud_elements()
}
LLViewerParcelMgr::getInstance()->render();
LLViewerParcelMgr::getInstance()->renderParcelCollision();
-
- // Render name tags.
- LLHUDObject::renderAll();
}
else if (gForceRenderLandFence)
{
@@ -4043,7 +3592,6 @@ void render_hud_elements()
}
gUIProgram.unbind();
- gGL.flush();
}
void LLPipeline::renderHighlights()
@@ -4054,109 +3602,8 @@ void LLPipeline::renderHighlights()
// Render highlighted faces.
LLGLSPipelineAlpha gls_pipeline_alpha;
LLColor4 color(1.f, 1.f, 1.f, 0.5f);
- LLGLEnable color_mat(GL_COLOR_MATERIAL);
disableLights();
- if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty())
- { //draw blurry highlight image over screen
- LLGLEnable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- LLGLDisable test(GL_ALPHA_TEST);
-
- LLGLEnable stencil(GL_STENCIL_TEST);
- gGL.flush();
- glStencilMask(0xFFFFFFFF);
- glClearStencil(1);
- glClear(GL_STENCIL_BUFFER_BIT);
-
- glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
-
- gGL.setColorMask(false, false);
-
- gHighlightProgram.bind();
-
- for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter)
- {
- renderHighlight(iter->mItem->getVObj(), 1.f);
- }
- gGL.setColorMask(true, false);
-
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
-
- //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
-
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- gGL.getTexUnit(0)->bind(&mHighlight);
-
- LLVector2 tc1;
- LLVector2 tc2;
-
- tc1.setVec(0,0);
- tc2.setVec(2,2);
-
- gGL.begin(LLRender::TRIANGLES);
-
- F32 scale = RenderHighlightBrightness;
- LLColor4 color = RenderHighlightColor;
- F32 thickness = RenderHighlightThickness;
-
- for (S32 pass = 0; pass < 2; ++pass)
- {
- if (pass == 0)
- {
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- }
- else
- {
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
-
- for (S32 i = 0; i < 8; ++i)
- {
- for (S32 j = 0; j < 8; ++j)
- {
- LLVector2 tc(i-4+0.5f, j-4+0.5f);
-
- F32 dist = 1.f-(tc.length()/sqrtf(32.f));
- dist *= scale/64.f;
-
- tc *= thickness;
- tc.mV[0] = (tc.mV[0])/mHighlight.getWidth();
- tc.mV[1] = (tc.mV[1])/mHighlight.getHeight();
-
- gGL.color4f(color.mV[0],
- color.mV[1],
- color.mV[2],
- color.mV[3]*dist);
-
- gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]);
- gGL.vertex2f(-1,3);
-
- gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]);
- gGL.vertex2f(-1,-1);
-
- gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]);
- gGL.vertex2f(3,-1);
- }
- }
- }
-
- gGL.end();
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- //gGL.setSceneBlendType(LLRender::BT_ALPHA);
- }
-
if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightProgram.bind();
@@ -4274,268 +3721,44 @@ void LLPipeline::renderHighlights()
//debug use
U32 LLPipeline::sCurRenderPoolType = 0 ;
-void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
+void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
-
- assertInitialized();
-
- F32 saved_modelview[16];
- F32 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];
- }
- }
-
- ///////////////////////////////////////////
- //
- // Sync and verify GL state
- //
- //
-
- stop_glerror();
-
- LLVertexBuffer::unbind();
-
- // Do verification of GL state
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
- if (mRenderDebugMask & RENDER_DEBUG_VERIFY)
- {
- if (!verify())
- {
- LL_ERRS() << "Pipeline verification failed!" << LL_ENDL;
- }
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO");
-
- // Initialize lots of GL state to "safe" values
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.matrixMode(LLRender::MM_TEXTURE);
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
-
- LLGLSPipeline gls_pipeline;
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
- LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2);
-
- // Toggle backface culling for debugging
- LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0);
- // Set fog
- 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;
- }
-
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep);
- LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP);
-
-
- //////////////////////////////////////////////
- //
- // Actually render all of the geometry
- //
- //
- stop_glerror();
-
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools");
-
- for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
- {
- LLDrawPool *poolp = *iter;
- if (hasRenderType(poolp->getType()))
- {
- poolp->prerender();
- }
- }
-
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pools"); //LL_RECORD_BLOCK_TIME(FTM_POOLS);
-
- // HACK: don't calculate local lights if we're rendering the HUD!
- // Removing this check will cause bad flickering when there are
- // HUD elements being rendered AND the user is in flycam mode -nyx
- if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- calcNearbyLights(camera);
- setupHWLights(NULL);
- }
-
- bool occlude = sUseOcclusion > 1;
- U32 cur_type = 0;
-
- pool_set_t::iterator iter1 = mPools.begin();
- while ( iter1 != mPools.end() )
- {
- LLDrawPool *poolp = *iter1;
-
- cur_type = poolp->getType();
-
- //debug use
- sCurRenderPoolType = cur_type ;
-
- if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
- {
- occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- LLGLSLShader::bindNoShader();
- doOcclusion(camera);
- }
-
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pool render"); //LL_RECORD_BLOCK_TIME(FTM_POOLRENDER);
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- for( S32 i = 0; i < poolp->getNumPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginRenderPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
-
- if ( !p->getSkipRenderFlag() ) { p->render(i); }
- }
- poolp->endRenderPass(i);
- LLVertexBuffer::unbind();
- if (gDebugGL)
- {
- std::string msg = llformat("pass %d", i);
- LLGLState::checkStates(msg);
- //LLGLState::checkTextureChannels(msg);
- //LLGLState::checkClientArrays(msg);
- }
- }
- }
- else
- {
- // Skip all pools of this type
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
- }
- }
- iter1 = iter2;
- stop_glerror();
- }
-
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd");
-
- LLVertexBuffer::unbind();
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- if (occlude)
- {
- occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- LLGLSLShader::bindNoShader();
- doOcclusion(camera);
- }
- }
-
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
-
- if (!LLPipeline::sImpostorRender)
- {
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights");
-
- if (!sReflectionRender)
- {
- renderHighlights();
- }
+ LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
+ LL_PROFILE_GPU_ZONE("renderGeomDeferred");
- // Contains a list of the faces of objects that are physical or
- // have touch-handlers.
- mHighlightFaces.clear();
+ llassert(!sRenderingHUDs);
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug");
-
- renderDebug();
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
- LLVertexBuffer::unbind();
-
- if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred)
- {
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- gObjectList.resetObjectBeacons();
- gSky.addSunMoonBeacons();
- }
- else
- {
- // Make sure particle effects disappear
- LLHUDObject::renderAllForTimer();
- }
- }
- else
- {
- // Make sure particle effects disappear
- LLHUDObject::renderAllForTimer();
- }
+ if (&camera == LLViewerCamera::getInstance())
+ { // a bit hacky, this is the start of the main render frame, figure out delta between last modelview matrix and
+ // current modelview matrix
+ glh::matrix4f last_modelview(gGLLastModelView);
+ glh::matrix4f cur_modelview(gGLModelView);
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd");
+ // goal is to have a matrix here that goes from the last frame's camera space to the current frame's camera space
+ glh::matrix4f m = last_modelview.inverse(); // last camera space to world space
+ m.mult_left(cur_modelview); // world space to camera space
- //HACK: preserve/restore matrices around HUD render
- if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
- {
- for (U32 i = 0; i < 16; i++)
- {
- gGLModelView[i] = saved_modelview[i];
- gGLProjection[i] = saved_projection[i];
- }
- }
- }
+ glh::matrix4f n = m.inverse();
- LLVertexBuffer::unbind();
+ for (U32 i = 0; i < 16; ++i)
+ {
+ gGLDeltaModelView[i] = m.m[i];
+ gGLInverseDeltaModelView[i] = n.m[i];
+ }
+ }
- LLGLState::checkStates();
-// LLGLState::checkTextureChannels();
-// LLGLState::checkClientArrays();
-}
+ bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion && !LLGLSLShader::sProfileEnabled;
-void LLPipeline::renderGeomDeferred(LLCamera& camera)
-{
- LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
+ setupHWLights();
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
{
- // SL-15709 -- NOTE: Tracy only allows one ZoneScoped per function.
- // Solutions are:
- // 1. Use a new scope
- // 2. Use named zones
- // 3. Use transient zones
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pools");
LLGLEnable cull(GL_CULL_FACE);
@@ -4548,12 +3771,15 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
}
}
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+
+ if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1)
+ {
+ //update reflection probe uniform
+ mReflectionMapManager.updateUniforms();
+ }
U32 cur_type = 0;
@@ -4567,10 +3793,19 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
cur_type = poolp->getType();
+ if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
+ {
+ llassert(!gCubeSnapshot); // never do occlusion culling on cube snapshots
+ occlude = false;
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+ doOcclusion(camera);
+ }
+
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render"); //LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred pool render");
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4621,24 +3856,39 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
} // Tracy ZoneScoped
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LL_PROFILE_GPU_ZONE("renderGeomPostDeferred");
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
+
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
calcNearbyLights(camera);
- setupHWLights(NULL);
+ setupHWLights();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- bool occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
+
+ if (gDebugGL || gDebugPipeline)
+ {
+ LLGLState::checkStates(GL_FALSE);
+ }
while ( iter1 != mPools.end() )
{
@@ -4646,20 +3896,10 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
cur_type = poolp->getType();
- if (occlude && cur_type >= LLDrawPool::POOL_GRASS)
- {
- occlude = false;
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
- LLGLSLShader::bindNoShader();
- doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
- gGL.setColorMask(true, false);
- }
-
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender"); //LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("deferred poolrender");
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4683,7 +3923,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
if (gDebugGL || gDebugPipeline)
{
- LLGLState::checkStates();
+ LLGLState::checkStates(GL_FALSE);
}
}
}
@@ -4707,20 +3947,25 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(gGLModelView);
- if (occlude)
- {
- occlude = false;
- LLGLSLShader::bindNoShader();
- doOcclusion(camera);
- gGLLastMatrix = NULL;
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.loadMatrix(gGLModelView);
- }
+ if (!gCubeSnapshot)
+ {
+ // debug displays
+ renderHighlights();
+ mHighlightFaces.clear();
+
+ renderDebug();
+ }
+
+ if (gUseWireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
}
void LLPipeline::renderGeomShadow(LLCamera& camera)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderGeomShadow");
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4759,8 +4004,6 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
}
poolp->endShadowPass(i);
LLVertexBuffer::unbind();
-
- LLGLState::checkStates();
}
}
else
@@ -4784,28 +4027,19 @@ void LLPipeline::renderGeomShadow(LLCamera& camera)
}
-void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- assertInitialized();
- S32 count = 0;
- if (render_type == LLRender::TRIANGLE_STRIP)
- {
- count = index_count-2;
- }
- else
- {
- count = index_count/3;
- }
+static U32 sIndicesDrawnCount = 0;
- record(sStatBatchSize, count);
- add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count));
+void LLPipeline::addTrianglesDrawn(S32 index_count)
+{
+ sIndicesDrawnCount += index_count;
+}
- if (LLPipeline::sRenderFrameTest)
- {
- gViewerWindow->getWindow()->swapBuffers();
- ms_sleep(16);
- }
+void LLPipeline::recordTrianglesDrawn()
+{
+ assertInitialized();
+ U32 count = sIndicesDrawnCount / 3;
+ sIndicesDrawnCount = 0;
+ add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count));
}
void LLPipeline::renderPhysicsDisplay()
@@ -4815,46 +4049,64 @@ void LLPipeline::renderPhysicsDisplay()
return;
}
- allocatePhysicsBuffer();
+ gGL.flush();
+ gDebugProgram.bind();
- gGL.flush();
- mPhysicsDisplay.bindTarget();
- glClearColor(0,0,0,1);
- gGL.setColorMask(true, true);
- mPhysicsDisplay.clear();
- glClearColor(0,0,0,0);
+ LLGLEnable(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(3.f, 3.f);
+ glLineWidth(3.f);
+ LLGLEnable blend(GL_BLEND);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
- gGL.setColorMask(true, false);
+ for (int pass = 0; pass < 3; ++pass)
+ {
+ // pass 0 - depth write enabled, color write disabled, fill
+ // pass 1 - depth write disabled, color write enabled, fill
+ // pass 2 - depth write disabled, color write enabled, wireframe
+ gGL.setColorMask(pass >= 1, false);
+ LLGLDepthTest depth(GL_TRUE, pass == 0);
- gDebugProgram.bind();
+ bool wireframe = (pass == 2);
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- if (hasRenderType(part->mDrawableType))
- {
- part->renderPhysicsShapes();
- }
- }
- }
- }
+ if (wireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ }
- gGL.flush();
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ part->renderPhysicsShapes(wireframe);
+ }
+ }
+ }
+ }
+ gGL.flush();
+ if (wireframe)
+ {
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ }
+ }
+ glLineWidth(1.f);
gDebugProgram.unbind();
- mPhysicsDisplay.flush();
+
}
extern std::set<LLSpatialGroup*> visible_selected_groups;
void LLPipeline::renderDebug()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
assertInitialized();
bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD);
@@ -4920,7 +4172,7 @@ void LLPipeline::renderDebug()
const LLColor4 clearColor = gSavedSettings.getColor4("PathfindingNavMeshClear");
gGL.setColorMask(true, true);
glClearColor(clearColor.mV[0],clearColor.mV[1],clearColor.mV[2],0);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // no stencil -- deprecated | GL_STENCIL_BUFFER_BIT);
gGL.setColorMask(true, false);
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
@@ -5134,8 +4386,6 @@ void LLPipeline::renderDebug()
}
}
- gGL.color4f(1,1,1,1);
-
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
gGL.setColorMask(true, false);
@@ -5144,6 +4394,7 @@ void LLPipeline::renderDebug()
if (!hud_only && !mDebugBlips.empty())
{ //render debug blips
gUIProgram.bind();
+ gGL.color4f(1, 1, 1, 1);
gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true);
@@ -5175,7 +4426,6 @@ void LLPipeline::renderDebug()
glPointSize(1.f);
}
-
// Debug stuff.
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -5229,6 +4479,27 @@ void LLPipeline::renderDebug()
visible_selected_groups.clear();
+ //draw reflection probes and links between them
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_REFLECTION_PROBES) && !hud_only)
+ {
+ mReflectionMapManager.renderDebug();
+ }
+
+ if (gSavedSettings.getBOOL("RenderReflectionProbeVolumes") && !hud_only)
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("probe debug display");
+
+ bindDeferredShader(gReflectionProbeDisplayProgram, NULL);
+ mScreenTriangleVB->setBuffer();
+
+ LLGLEnable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_FALSE);
+
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ unbindDeferredShader(gReflectionProbeDisplayProgram);
+ }
+
gUIProgram.bind();
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
@@ -5264,7 +4535,7 @@ void LLPipeline::renderDebug()
}
}
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !hud_only)
{
LLVertexBuffer::unbind();
@@ -5435,63 +4706,6 @@ void LLPipeline::renderDebug()
}
}
- if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE)
- {
- U32 count = 0;
- U32 size = mGroupQ2.size();
- LLColor4 col;
-
- LLVertexBuffer::unbind();
- LLGLEnable blend(GL_BLEND);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
-
- gGL.pushMatrix();
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
-
- for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter)
- {
- LLSpatialGroup* group = *iter;
- if (group->isDead())
- {
- continue;
- }
-
- LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
-
- if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead()))
- {
- continue;
- }
-
- if (bridge)
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- }
-
- F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f);
-
-
- LLVector2 c(1.f-alpha, alpha);
- c.normVec();
-
-
- ++count;
- col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f);
- group->drawObjectBox(col);
-
- if (bridge)
- {
- gGL.popMatrix();
- }
- }
-
- gGL.popMatrix();
- }
-
gGL.flush();
gUIProgram.unbind();
}
@@ -5599,18 +4813,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
- case LLDrawPool::POOL_INVISIBLE:
- if (mInvisiblePool)
- {
- llassert(0);
- LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
- }
- else
- {
- mInvisiblePool = (LLRenderPass*) new_poolp;
- }
- break;
-
case LLDrawPool::POOL_GLOW:
if (mGlowPool)
{
@@ -5653,17 +4855,28 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
mMaterialsPool = new_poolp;
}
break;
- case LLDrawPool::POOL_ALPHA:
- if( mAlphaPool )
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ if( mAlphaPoolPreWater )
{
llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pre-water pool" << LL_ENDL;
}
else
{
- mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
+ mAlphaPoolPreWater = (LLDrawPoolAlpha*) new_poolp;
}
break;
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ if (mAlphaPoolPostWater)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha post-water pool" << LL_ENDL;
+ }
+ else
+ {
+ mAlphaPoolPostWater = (LLDrawPoolAlpha*)new_poolp;
+ }
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5693,18 +4906,6 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
- case LLDrawPool::POOL_GROUND:
- if( mGroundPool )
- {
- llassert(0);
- LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << LL_ENDL;
- }
- else
- {
- mGroundPool = new_poolp;
- }
- break;
-
case LLDrawPool::POOL_WL_SKY:
if( mWLSkyPool )
{
@@ -5717,6 +4918,31 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_GLTF_PBR:
+ if( mPBROpaquePool )
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Opaque Pool" << LL_ENDL;
+ }
+ else
+ {
+ mPBROpaquePool = new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
+ if (mPBRAlphaMaskPool)
+ {
+ llassert(0);
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate PBR Alpha Mask Pool" << LL_ENDL;
+ }
+ else
+ {
+ mPBRAlphaMaskPool = new_poolp;
+ }
+ break;
+
+
default:
llassert(0);
LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
@@ -5762,11 +4988,6 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mFullbrightPool = NULL;
break;
- case LLDrawPool::POOL_INVISIBLE:
- llassert(mInvisiblePool == poolp);
- mInvisiblePool = NULL;
- break;
-
case LLDrawPool::POOL_WL_SKY:
llassert(mWLSkyPool == poolp);
mWLSkyPool = NULL;
@@ -5809,10 +5030,15 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mMaterialsPool = NULL;
break;
- case LLDrawPool::POOL_ALPHA:
- llassert( poolp == mAlphaPool );
- mAlphaPool = NULL;
+ case LLDrawPool::POOL_ALPHA_PRE_WATER:
+ llassert( poolp == mAlphaPoolPreWater );
+ mAlphaPoolPreWater = nullptr;
break;
+
+ case LLDrawPool::POOL_ALPHA_POST_WATER:
+ llassert(poolp == mAlphaPoolPostWater);
+ mAlphaPoolPostWater = nullptr;
+ break;
case LLDrawPool::POOL_AVATAR:
case LLDrawPool::POOL_CONTROL_AV:
@@ -5828,10 +5054,15 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mWaterPool = NULL;
break;
- case LLDrawPool::POOL_GROUND:
- llassert( poolp == mGroundPool );
- mGroundPool = NULL;
- break;
+ case LLDrawPool::POOL_GLTF_PBR:
+ llassert( poolp == mPBROpaquePool );
+ mPBROpaquePool = NULL;
+ break;
+
+ case LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK:
+ llassert(poolp == mPBRAlphaMaskPool);
+ mPBRAlphaMaskPool = NULL;
+ break;
default:
llassert(0);
@@ -5949,6 +5180,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_dist)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
F32 inten = light->getLightIntensity();
if (inten < .001f)
{
@@ -5972,14 +5204,17 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
void LLPipeline::calcNearbyLights(LLCamera& camera)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
- if (LLPipeline::sReflectionRender)
+ if (LLPipeline::sReflectionRender || gCubeSnapshot || LLPipeline::sRenderingHUDs)
{
return;
}
- if (mLightingDetail >= 1)
+ static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
+
+ if (local_light_count >= 1)
{
// mNearbyLight (and all light_set_t's) are sorted such that
// begin() == the closest light and rbegin() == the farthest light
@@ -6066,7 +5301,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// FIND NEW LIGHTS THAT ARE IN RANGE
light_set_t new_nearby_lights;
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin();
+ for (LLDrawable::ordered_drawable_set_t::iterator iter = mLights.begin();
iter != mLights.end(); ++iter)
{
LLDrawable* drawable = *iter;
@@ -6155,16 +5390,31 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
}
}
-void LLPipeline::setupHWLights(LLDrawPool* pool)
+void LLPipeline::setupHWLights()
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
assertInitialized();
+ if (LLPipeline::sRenderingHUDs)
+ {
+ return;
+ }
+
+ F32 light_scale = 1.f;
+
+ if (gCubeSnapshot)
+ { //darken local lights when probe ambiance is above 1
+ light_scale = mReflectionMapManager.mLightScale;
+ }
+
+
LLEnvironment& environment = LLEnvironment::instance();
LLSettingsSky::ptr_t psky = environment.getCurrentSky();
// Ambient
LLColor4 ambient = psky->getTotalAmbient();
- gGL.setAmbientLightColor(ambient);
+
+ gGL.setAmbientLightColor(ambient);
bool sun_up = environment.getIsSunUp();
bool moon_up = environment.getIsMoonUp();
@@ -6231,7 +5481,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
mLightMovingMask = 0;
- if (mLightingDetail >= 1)
+ static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
+
+ if (local_light_count >= 1)
{
for (light_set_t::iterator iter = mNearbyLights.begin();
iter != mNearbyLights.end(); ++iter)
@@ -6257,7 +5509,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
//send linear light color to shader
- LLColor4 light_color = light->getLightLinearColor();
+ LLColor4 light_color = light->getLightLinearColor() * light_scale;
light_color.mV[3] = 0.0f;
F32 fade = iter->fade;
@@ -6302,6 +5554,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
light_state->setDiffuse(light_color);
light_state->setAmbient(LLColor4::black);
light_state->setConstantAttenuation(0.f);
+ light_state->setSize(light->getLightRadius() * 1.5f);
+ light_state->setFalloff(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+
if (sRenderDeferred)
{
light_state->setLinearAttenuation(linatten);
@@ -6371,10 +5626,6 @@ void LLPipeline::enableLights(U32 mask)
{
assertInitialized();
- if (mLightingDetail == 0)
- {
- mask &= 0xf003; // sun and backlight only (and fullbright bit)
- }
if (mLightMask != mask)
{
stop_glerror();
@@ -6402,28 +5653,13 @@ void LLPipeline::enableLights(U32 mask)
}
}
-void LLPipeline::enableLightsStatic()
-{
- assertInitialized();
- U32 mask = 0x01; // Sun
- if (mLightingDetail >= 2)
- {
- mask |= mLightMovingMask; // Hardware moving lights
- }
- else
- {
- mask |= 0xff & (~2); // Hardware local lights
- }
- enableLights(mask);
-}
-
void LLPipeline::enableLightsDynamic()
{
assertInitialized();
U32 mask = 0xff & (~2); // Local lights
enableLights(mask);
- if (isAgentAvatarValid() && getLightingDetail() <= 0)
+ if (isAgentAvatarValid())
{
if (gAgentAvatarp->mSpecialRenderMode == 0) // normal
{
@@ -6553,11 +5789,7 @@ void LLPipeline::findReferences(LLDrawable *drawablep)
{
LL_INFOS() << "In mBuildQ1" << LL_ENDL;
}
- if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end())
- {
- LL_INFOS() << "In mBuildQ2" << LL_ENDL;
- }
-
+
S32 count;
count = gObjectList.findReferences(drawablep);
@@ -6718,15 +5950,6 @@ void LLPipeline::toggleRenderType(U32 type)
//static
void LLPipeline::toggleRenderTypeControl(U32 type)
{
- U32 bit = (1<<type);
- if (gPipeline.hasRenderType(type))
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
- }
- else
- {
- LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
- }
gPipeline.toggleRenderType(type);
}
@@ -6972,7 +6195,7 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, FALSE, TRUE, FALSE, face_hit, &position, NULL, NULL, NULL);
if (hit)
{
drawable = hit;
@@ -7000,6 +6223,8 @@ LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start,
LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
+ bool pick_reflection_probe,
S32* face_hit,
LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
@@ -7033,7 +6258,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7090,7 +6315,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_AVATAR);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, face_hit, &position, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, pick_rigged, pick_unselectable, pick_reflection_probe, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
LLVector4a delta;
@@ -7178,7 +6403,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, c
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, face_hit, intersection, tex_coord, normal, tangent);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, FALSE, TRUE, FALSE, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -7223,187 +6448,153 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
}
}
-void LLPipeline::resetVertexBuffers()
-{
- mResetVertexBuffers = true;
-}
-
-void LLPipeline::doResetVertexBuffers(bool forced)
+void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
- if (!mResetVertexBuffers)
- {
- return;
- }
- if(!forced && LLSpatialPartition::sTeleportRequested)
- {
- if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
- {
- return; //wait for teleporting to finish
- }
- else
- {
- //teleporting aborted
- LLSpatialPartition::sTeleportRequested = FALSE;
- mResetVertexBuffers = false;
- return;
- }
- }
-
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
- mResetVertexBuffers = false;
-
- mCubeVB = NULL;
- mDeferredVB = NULL;
-
- for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
- iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
- {
- LLViewerRegion* region = *iter;
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
- {
- LLSpatialPartition* part = region->getSpatialPartition(i);
- if (part)
- {
- part->resetVertexBuffers();
- }
- }
- }
- if(LLSpatialPartition::sTeleportRequested)
- {
- LLSpatialPartition::sTeleportRequested = FALSE;
-
- LLWorld::getInstance()->clearAllVisibleObjects();
- clearRebuildDrawables();
- }
-
- resetDrawOrders();
-
- gSky.resetVertexBuffers();
-
- LLVOPartGroup::destroyGL();
-
- if ( LLPathingLib::getInstance() )
- {
- LLPathingLib::getInstance()->cleanupVBOManager();
- }
- LLVOPartGroup::destroyGL();
- gGL.resetVertexBuffer();
-
- SUBSYSTEM_CLEANUP(LLVertexBuffer);
-
- if (LLVertexBuffer::sGLCount != 0)
- {
- LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
- }
-
- LLVertexBuffer::unbind();
-
- updateRenderBump();
- updateRenderDeferred();
-
- sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
- LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
- LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
- LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
- LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable");
- LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ;
- sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
- sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
- LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
-
- LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
- gGL.initVertexBuffer();
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
- mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0);
- mDeferredVB->allocateBuffer(8, 0, true);
+ if (rigged)
+ {
+ mSimplePool->pushRiggedBatches(type + 1, texture, batch_texture);
+ }
+ else
+ {
+ mSimplePool->pushBatches(type, texture, batch_texture);
+ }
- LLVOPartGroup::restoreGL();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
}
-void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
+void LLPipeline::renderGLTFObjects(U32 type, bool texture, bool rigged)
{
- assertInitialized();
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+
if (rigged)
{
- mSimplePool->pushRiggedBatches(type + 1, mask, texture, batch_texture);
+ mSimplePool->pushRiggedGLTFBatches(type + 1, texture);
}
else
{
- mSimplePool->pushBatches(type, mask, texture, batch_texture);
+ mSimplePool->pushGLTFBatches(type, texture);
}
- gGL.loadMatrix(gGLModelView);
- gGLLastMatrix = NULL;
+
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
}
-void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged)
+// Currently only used for shadows -Cosmic,2023-04-19
+void LLPipeline::renderAlphaObjects(bool rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
+ S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0;
+ U32 target_width = LLRenderTarget::sCurResX;
U32 type = LLRenderPass::PASS_ALPHA;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
- for (LLCullResult::drawinfo_iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)
+ auto* begin = gPipeline.beginRenderMap(type);
+ auto* end = gPipeline.endRenderMap(type);
+
+ for (LLCullResult::drawinfo_iterator i = begin; i != end; )
{
LLDrawInfo* pparams = *i;
- if (pparams)
+ LLCullResult::increment_iterator(i, end);
+
+ if (rigged != (pparams->mAvatar != nullptr))
{
- if (rigged)
+ // Pool contains both rigged and non-rigged DrawInfos. Only draw
+ // the objects we're interested in in this pass.
+ continue;
+ }
+
+ if (rigged)
+ {
+ if (pparams->mGLTFMaterial)
{
- if (pparams->mAvatar != nullptr)
+ gDeferredShadowGLTFAlphaBlendProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+ mSimplePool->pushRiggedGLTFBatch(*pparams, lastAvatar, lastMeshId);
+ }
+ else
+ {
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+ if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
{
- if (lastAvatar != pparams->mAvatar || lastMeshId != pparams->mSkinInfo->mHash)
- {
- mSimplePool->uploadMatrixPalette(*pparams);
- lastAvatar = pparams->mAvatar;
- lastMeshId = pparams->mSkinInfo->mHash;
- }
-
- mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture);
+ mSimplePool->uploadMatrixPalette(*pparams);
+ lastAvatar = pparams->mAvatar;
+ lastMeshId = pparams->mSkinInfo->mHash;
}
+
+ mSimplePool->pushBatch(*pparams, true, true);
+ }
+ }
+ else
+ {
+ if (pparams->mGLTFMaterial)
+ {
+ gDeferredShadowGLTFAlphaBlendProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+ mSimplePool->pushGLTFBatch(*pparams);
}
- else if (pparams->mAvatar == nullptr)
+ else
{
- mSimplePool->pushBatch(*pparams, mask, texture, batch_texture);
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+ mSimplePool->pushBatch(*pparams, true, true);
}
}
}
+
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
-void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
+// Currently only used for shadows -Cosmic,2023-04-19
+void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
if (rigged)
{
- mAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture);
+ mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
}
else
{
- mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
}
-void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged)
+// Currently only used for shadows -Cosmic,2023-04-19
+void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged)
{
assertInitialized();
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
if (rigged)
{
- mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture);
+ mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture);
}
else
{
- mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture);
}
gGL.loadMatrix(gGLModelView);
gGLLastMatrix = NULL;
@@ -7471,642 +6662,849 @@ void LLPipeline::bindScreenToTexture()
static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
-void LLPipeline::renderFinalize()
+void LLPipeline::visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex)
{
- LLVertexBuffer::unbind();
- LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+ dst->bindTarget();
+ gDeferredBufferVisualProgram.bind();
+ gDeferredBufferVisualProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_BILINEAR, bufferIndex);
- assertInitialized();
+ static LLStaticHashedString mipLevel("mipLevel");
+ if (RenderBufferVisualization != 4)
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 0);
+ else
+ gDeferredBufferVisualProgram.uniform1f(mipLevel, 8);
- if (gUseWireframe)
- {
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredBufferVisualProgram.unbind();
+ dst->flush();
+}
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2);
+void LLPipeline::generateLuminance(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ // luminance sample and mipmap generation
+ {
+ LL_PROFILE_GPU_ZONE("luminance sample");
- LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
- gGL.color4f(1, 1, 1, 1);
- LLGLDepthTest depth(GL_FALSE);
- LLGLDisable blend(GL_BLEND);
- LLGLDisable cull(GL_CULL_FACE);
+ dst->bindTarget();
- enableLightsFullbright();
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ gLuminanceProgram.bind();
- LLGLDisable test(GL_ALPHA_TEST);
+ S32 channel = 0;
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE);
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
- gGL.setColorMask(true, true);
- glClearColor(0, 0, 0, 0);
+ channel = gLuminanceProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mGlow[1].bindTexture(0, channel);
+ }
- if (sRenderGlow)
- {
- mGlow[2].bindTarget();
- mGlow[2].clear();
-
- gGlowExtractProgram.bind();
- F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f);
- F32 maxAlpha = RenderGlowMaxExtractAlpha;
- F32 warmthAmount = RenderGlowWarmthAmount;
- LLVector3 lumWeights = RenderGlowLumWeights;
- LLVector3 warmthWeights = RenderGlowWarmthWeights;
-
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
- lumWeights.mV[2]);
- gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
- warmthWeights.mV[2]);
- gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
-
- {
- LLGLEnable blend_on(GL_BLEND);
- LLGLEnable test(GL_ALPHA_TEST);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ dst->flush();
- gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+ // note -- unbind AFTER the glGenerateMipMap so time in generatemipmap can be profiled under "Luminance"
+ // also note -- keep an eye on the performance of glGenerateMipmap, might need to replace it with a mip generation shader
+ gLuminanceProgram.unbind();
+ }
+}
- mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT);
+void LLPipeline::generateExposure(LLRenderTarget* src, LLRenderTarget* dst) {
+ // exposure sample
+ {
+ LL_PROFILE_GPU_ZONE("exposure sample");
- gGL.color4f(1, 1, 1, 1);
- gPipeline.enableLightsFullbright();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ {
+ // copy last frame's exposure into mLastExposure
+ mLastExposure.bindTarget();
+ gCopyProgram.bind();
+ gGL.getTexUnit(0)->bind(dst);
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ mLastExposure.flush();
+ }
- gGL.end();
+ dst->bindTarget();
- gGL.getTexUnit(0)->unbind(mScreen.getUsage());
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- mGlow[2].flush();
+ gExposureProgram.bind();
- tc1.setVec(0, 0);
- tc2.setVec(2, 2);
- }
+ S32 channel = gExposureProgram.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE);
+ if (channel > -1)
+ {
+ mLuminanceMap.bindTexture(0, channel, LLTexUnit::TFO_TRILINEAR);
+ }
- // power of two between 1 and 1024
- U32 glowResPow = RenderGlowResolutionPow;
- const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
+ channel = gExposureProgram.enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
+ {
+ mLastExposure.bindTexture(0, channel);
+ }
- S32 kernel = RenderGlowIterations * 2;
- F32 delta = 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 = RenderGlowStrength;
+ static LLStaticHashedString dt("dt");
+ static LLStaticHashedString noiseVec("noiseVec");
+ static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params");
+ static LLCachedControl<F32> dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f);
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
- gGlowProgram.bind();
- gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
+ LLSettingsSky::ptr_t sky = LLEnvironment::instance().getCurrentSky();
- for (S32 i = 0; i < kernel; i++)
+ F32 probe_ambiance = LLEnvironment::instance().getCurrentSky()->getReflectionProbeAmbiance(should_auto_adjust);
+ F32 exp_min = 1.f;
+ F32 exp_max = 1.f;
+
+ if (probe_ambiance > 0.f)
{
- mGlow[i % 2].bindTarget();
- mGlow[i % 2].clear();
+ F32 hdr_scale = sqrtf(LLEnvironment::instance().getCurrentSky()->getGamma())*2.f;
- if (i == 0)
- {
- gGL.getTexUnit(0)->bind(&mGlow[2]);
- }
- else
+ if (hdr_scale > 1.f)
{
- gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]);
+ exp_min = 1.f / hdr_scale;
+ exp_max = hdr_scale;
}
+ }
+ gExposureProgram.uniform1f(dt, gFrameIntervalSeconds);
+ gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0);
+ gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, exp_min, exp_max);
- if (i % 2 == 0)
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
- }
- else
- {
- gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gGL.getTexUnit(channel)->unbind(mLastExposure.getUsage());
+ gExposureProgram.unbind();
+ dst->flush();
+ }
+}
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+void LLPipeline::gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst) {
+ dst->bindTarget();
+ // gamma correct lighting
+ {
+ LL_PROFILE_GPU_ZONE("gamma correct");
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ static LLCachedControl<bool> no_post(gSavedSettings, "RenderDisablePostProcessing", false);
- gGL.end();
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
- mGlow[i % 2].flush();
- }
+ // Apply gamma correction to the frame here.
- gGlowProgram.unbind();
- }
- else // !sRenderGlow, skip the glow ping-pong and just clear the result target
- {
- mGlow[1].bindTarget();
- mGlow[1].clear();
- mGlow[1].flush();
- }
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ LLGLSLShader& shader = no_post && gFloaterTools->isAvailable() ? gNoPostGammaCorrectProgram : // no post (no gamma, no exposure, no tonemapping)
+ psky->getReflectionProbeAmbiance(should_auto_adjust) == 0.f ? gLegacyPostGammaCorrectProgram :
+ gDeferredPostGammaCorrectProgram;
+
+ shader.bind();
- tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight());
+ S32 channel = 0;
- gGL.flush();
+ shader.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, false, LLTexUnit::TFO_POINT);
- LLVertexBuffer::unbind();
+ shader.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap);
- if (LLPipeline::sRenderDeferred)
- {
+ shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, src->getWidth(), src->getHeight());
- bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
- RenderDepthOfField;
+ static LLCachedControl<F32> exposure(gSavedSettings, "RenderExposure", 1.f);
- bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete();
+ F32 e = llclamp(exposure(), 0.5f, 4.f);
- gViewerWindow->setup3DViewport();
+ static LLStaticHashedString s_exposure("exposure");
- if (dof_enabled)
- {
- LLGLSLShader *shader = &gDeferredPostProgram;
- LLGLDisable blend(GL_BLEND);
+ shader.uniform1f(s_exposure, e);
- // depth of field focal plane calculations
- static F32 current_distance = 16.f;
- static F32 start_distance = 16.f;
- static F32 transition_time = 1.f;
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- LLVector3 focus_point;
+ gGL.getTexUnit(channel)->unbind(src->getUsage());
+ shader.unbind();
+ }
+ dst->flush();
+}
- LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
- if (obj && obj->mDrawable && obj->isSelected())
- { // focus on selected media object
- S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
- if (obj && obj->mDrawable)
- {
- LLFace *face = obj->mDrawable->getFace(face_idx);
- if (face)
- {
- focus_point = face->getPositionAgent();
- }
- }
- }
+void LLPipeline::copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst)
+{
- if (focus_point.isExactlyZero())
- {
- if (LLViewerJoystick::getInstance()->getOverrideCamera())
- { // focus on point under cursor
- focus_point.set(gDebugRaycastIntersection.getF32ptr());
- }
- else if (gAgentCamera.cameraMouselook())
- { // focus on point under mouselook crosshairs
- LLVector4a result;
- result.clear();
+ if (RenderScreenSpaceReflections && !gCubeSnapshot)
+ {
+ LL_PROFILE_GPU_ZONE("ssr copy");
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
- gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result);
+ LLRenderTarget& depth_src = mRT->deferredScreen;
- focus_point.set(result.getF32ptr());
- }
- else
- {
- // focus on alt-zoom target
- LLViewerRegion *region = gAgent.getRegion();
- if (region)
- {
- focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
- }
- }
- }
+ dst->bindTarget();
+ dst->clear();
+ gCopyDepthProgram.bind();
+
+ S32 diff_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DIFFUSE_MAP);
+ S32 depth_map = gCopyDepthProgram.getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+
+ gGL.getTexUnit(diff_map)->bind(src);
+ gGL.getTexUnit(depth_map)->bind(&depth_src, true);
+
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst->flush();
+ }
+}
+
+void LLPipeline::generateGlow(LLRenderTarget* src)
+{
+ if (sRenderGlow)
+ {
+ LL_PROFILE_GPU_ZONE("glow");
+ mGlow[2].bindTarget();
+ mGlow[2].clear();
+
+ gGlowExtractProgram.bind();
+ F32 maxAlpha = RenderGlowMaxExtractAlpha;
+ F32 warmthAmount = RenderGlowWarmthAmount;
+ LLVector3 lumWeights = RenderGlowLumWeights;
+ LLVector3 warmthWeights = RenderGlowWarmthWeights;
- LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
- F32 target_distance = 16.f;
- if (!focus_point.isExactlyZero())
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, 9999);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1],
+ lumWeights.mV[2]);
+ gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1],
+ warmthWeights.mV[2]);
+ gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount);
+
+ if (RenderGlowNoise)
+ {
+ S32 channel = gGlowExtractProgram.enableTexture(LLShaderMgr::GLOW_NOISE_MAP);
+ if (channel > -1)
{
- target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
+ gGlowExtractProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES,
+ mGlow[2].getWidth(),
+ mGlow[2].getHeight());
+ }
- if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
- { // large shift happened, interpolate smoothly to new target distance
- transition_time = 0.f;
- start_distance = current_distance;
- }
- else if (transition_time < 1.f)
- { // currently in a transition, continue interpolating
- transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
- transition_time = llmin(transition_time, 1.f);
+ {
+ LLGLEnable blend_on(GL_BLEND);
- F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
- current_distance = start_distance + (target_distance - start_distance) * t;
- }
- else
- { // small or no change, just snap to target distance
- current_distance = target_distance;
- }
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
- // convert to mm
- F32 subject_distance = current_distance * 1000.f;
- F32 fnumber = CameraFNumber;
- F32 default_focal_length = CameraFocalLength;
+ gGlowExtractProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, src);
- F32 fov = LLViewerCamera::getInstance()->getView();
+ gGL.color4f(1, 1, 1, 1);
+ gPipeline.enableLightsFullbright();
- const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+ mGlow[2].flush();
+ }
- F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
+ gGlowExtractProgram.unbind();
- F32 focal_length = dv / (2 * tanf(fov / 2.f));
+ // power of two between 1 and 1024
+ U32 glowResPow = RenderGlowResolutionPow;
+ const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow));
- // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+ S32 kernel = RenderGlowIterations * 2;
+ F32 delta = 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 = RenderGlowStrength;
- // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
- // where N = fnumber
- // s2 = dot distance
- // s1 = subject distance
- // f = focal length
- //
+ gGlowProgram.bind();
+ gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength);
- F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
- blur_constant /= 1000.f; // convert to meters for shader
- F32 magnification = focal_length / (subject_distance - focal_length);
+ for (S32 i = 0; i < kernel; i++)
+ {
+ mGlow[i % 2].bindTarget();
+ mGlow[i % 2].clear();
- { // build diffuse+bloom+CoF
- mDeferredLight.bindTarget();
- shader = &gDeferredCoFProgram;
+ if (i == 0)
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[2]);
+ }
+ else
+ {
+ gGlowProgram.bindTexture(LLShaderMgr::DIFFUSE_MAP, &mGlow[(i - 1) % 2]);
+ }
- bindDeferredShader(*shader);
+ if (i % 2 == 0)
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0);
+ }
+ else
+ {
+ gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta);
+ }
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
- shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
- shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
- shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ mGlow[i % 2].flush();
+ }
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gGlowProgram.unbind();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ }
+ else // !sRenderGlow, skip the glow ping-pong and just clear the result target
+ {
+ mGlow[1].bindTarget();
+ mGlow[1].clear();
+ mGlow[1].flush();
+ }
+}
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+void LLPipeline::applyFXAA(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ {
+ llassert(!gCubeSnapshot);
+ bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete();
+ LLGLSLShader* shader = &gGlowCombineProgram;
- gGL.end();
+ S32 width = dst->getWidth();
+ S32 height = dst->getHeight();
- unbindDeferredShader(*shader);
- mDeferredLight.flush();
- }
+ // Present everything.
+ if (multisample)
+ {
+ LL_PROFILE_GPU_ZONE("aa");
+ // bake out texture2D with RGBL for FXAA shader
+ mRT->fxaaBuffer.bindTarget();
- U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale);
- U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale);
+ shader = &gGlowCombineFXAAProgram;
+ shader->bind();
- { // perform DoF sampling at half-res (preserve alpha channel)
- mScreen.bindTarget();
- glViewport(0, 0, dof_width, dof_height);
- gGL.setColorMask(true, false);
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ if (channel > -1)
+ {
+ src->bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
- shader = &gDeferredPostProgram;
- bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
- if (channel > -1)
- {
- mDeferredLight.bindTexture(0, channel);
- }
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage());
+ shader->unbind();
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ mRT->fxaaBuffer.flush();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ dst->bindTarget();
+ shader = &gFXAAProgram;
+ shader->bind();
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage());
+ if (channel > -1)
+ {
+ mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
+ }
- gGL.end();
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- unbindDeferredShader(*shader);
- mScreen.flush();
- gGL.setColorMask(true, true);
- }
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- { // combine result based on alpha
- if (multisample)
- {
- mDeferredLight.bindTarget();
- glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
- }
- else
- {
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
- }
+ F32 scale_x = (F32)width / mRT->fxaaBuffer.getWidth();
+ F32 scale_y = (F32)height / mRT->fxaaBuffer.getHeight();
+ shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
+ shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
+ 0.5f / width * scale_x, 0.5f / height * scale_y);
+ shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
+ 2.f / width * scale_x, 2.f / height * scale_y);
- shader = &gDeferredDoFCombineProgram;
- bindDeferredShader(*shader);
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ S32 depth_channel = shader->getTextureChannel(LLShaderMgr::DEFERRED_DEPTH);
+ gGL.getTexUnit(depth_channel)->bind(&mRT->deferredScreen, true);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
- shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1);
- shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1);
+ shader->unbind();
+ dst->flush();
+ }
+ else {
+ copyRenderTarget(src, dst);
+ }
+ }
+}
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+void LLPipeline::copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst)
+{
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ LL_PROFILE_GPU_ZONE("copyRenderTarget");
+ dst->bindTarget();
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ gDeferredPostNoDoFProgram.bind();
- gGL.end();
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
- unbindDeferredShader(*shader);
+ {
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- if (multisample)
- {
- mDeferredLight.flush();
- }
- }
- }
- else
- {
- if (multisample)
- {
- mDeferredLight.bindTarget();
- }
- LLGLSLShader *shader = &gDeferredPostNoDoFProgram;
+ gDeferredPostNoDoFProgram.unbind();
- bindDeferredShader(*shader);
+ dst->flush();
+}
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
- if (channel > -1)
- {
- mScreen.bindTexture(0, channel);
- }
+void LLPipeline::combineGlow(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ // Go ahead and do our glow combine here in our destination. We blit this later into the front buffer.
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ dst->bindTarget();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ {
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ gGlowCombineProgram.bind();
- gGL.end();
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src);
+ gGlowCombineProgram.bindTexture(LLShaderMgr::DEFERRED_EMISSIVE, &mGlow[1]);
- unbindDeferredShader(*shader);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
- if (multisample)
- {
- mDeferredLight.flush();
- }
- }
+ dst->flush();
+}
- if (multisample)
- {
- // bake out texture2D with RGBL for FXAA shader
- mFXAABuffer.bindTarget();
+void LLPipeline::renderDoF(LLRenderTarget* src, LLRenderTarget* dst)
+{
+ {
+ bool dof_enabled =
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
+ RenderDepthOfField &&
+ !gCubeSnapshot;
- S32 width = mScreen.getWidth();
- S32 height = mScreen.getHeight();
- glViewport(0, 0, width, height);
+ gViewerWindow->setup3DViewport();
- LLGLSLShader *shader = &gGlowCombineFXAAProgram;
+ if (dof_enabled)
+ {
+ LL_PROFILE_GPU_ZONE("dof");
+ LLGLDisable blend(GL_BLEND);
- shader->bind();
- shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
+ // depth of field focal plane calculations
+ static F32 current_distance = 16.f;
+ static F32 start_distance = 16.f;
+ static F32 transition_time = 1.f;
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
- if (channel > -1)
- {
- mDeferredLight.bindTexture(0, channel);
- }
+ LLVector3 focus_point;
+
+ LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject();
+ if (obj && obj->mDrawable && obj->isSelected())
+ { // focus on selected media object
+ S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace();
+ if (obj && obj->mDrawable)
+ {
+ LLFace* face = obj->mDrawable->getFace(face_idx);
+ if (face)
+ {
+ focus_point = face->getPositionAgent();
+ }
+ }
+ }
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1, -1);
- gGL.vertex2f(-1, 3);
- gGL.vertex2f(3, -1);
- gGL.end();
+ if (focus_point.isExactlyZero())
+ {
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ { // focus on point under cursor
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
+ }
+ else if (gAgentCamera.cameraMouselook())
+ { // focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
- gGL.flush();
+ gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, TRUE, NULL, &result);
+
+ focus_point.set(result.getF32ptr());
+ }
+ else
+ {
+ // focus on alt-zoom target
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal());
+ }
+ }
+ }
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
- shader->unbind();
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ F32 target_distance = 16.f;
+ if (!focus_point.isExactlyZero())
+ {
+ target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye);
+ }
- mFXAABuffer.flush();
+ if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f)
+ { // large shift happened, interpolate smoothly to new target distance
+ transition_time = 0.f;
+ start_distance = current_distance;
+ }
+ else if (transition_time < 1.f)
+ { // currently in a transition, continue interpolating
+ transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value();
+ transition_time = llmin(transition_time, 1.f);
- shader = &gFXAAProgram;
- shader->bind();
+ F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f;
+ current_distance = start_distance + (target_distance - start_distance) * t;
+ }
+ else
+ { // small or no change, just snap to target distance
+ current_distance = target_distance;
+ }
- channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage());
- if (channel > -1)
- {
- mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR);
- }
+ // convert to mm
+ F32 subject_distance = current_distance * 1000.f;
+ F32 fnumber = CameraFNumber;
+ F32 default_focal_length = CameraFocalLength;
- gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
- gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
- gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
- gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
- glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
-
- F32 scale_x = (F32) width / mFXAABuffer.getWidth();
- F32 scale_y = (F32) height / mFXAABuffer.getHeight();
- shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y);
- shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y,
- 0.5f / width * scale_x, 0.5f / height * scale_y);
- shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y,
- 2.f / width * scale_x, 2.f / height * scale_y);
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.vertex2f(-1, -1);
- gGL.vertex2f(-1, 3);
- gGL.vertex2f(3, -1);
- gGL.end();
-
- gGL.flush();
- shader->unbind();
- }
- }
- else // not deferred
- {
- U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
- LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0);
- buff->allocateBuffer(3, 0, TRUE);
+ F32 fov = LLViewerCamera::getInstance()->getView();
- LLStrider<LLVector3> v;
- LLStrider<LLVector2> uv1;
- LLStrider<LLVector2> uv2;
+ const F32 default_fov = CameraFieldOfView * F_PI / 180.f;
- buff->getVertexStrider(v);
- buff->getTexCoord0Strider(uv1);
- buff->getTexCoord1Strider(uv2);
+ // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight();
- uv1[0] = LLVector2(0, 0);
- uv1[1] = LLVector2(0, 2);
- uv1[2] = LLVector2(2, 0);
+ F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f);
- uv2[0] = LLVector2(0, 0);
- uv2[1] = LLVector2(0, tc2.mV[1] * 2.f);
- uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0);
+ F32 focal_length = dv / (2 * tanf(fov / 2.f));
- v[0] = LLVector3(-1, -1, 0);
- v[1] = LLVector3(-1, 3, 0);
- v[2] = LLVector3(3, -1, 0);
+ // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
- buff->flush();
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
- LLGLDisable blend(GL_BLEND);
+ F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length));
+ blur_constant /= 1000.f; // convert to meters for shader
+ F32 magnification = focal_length / (subject_distance - focal_length);
- gGlowCombineProgram.bind();
+ { // build diffuse+bloom+CoF
+ mRT->deferredLight.bindTarget();
- gGL.getTexUnit(0)->bind(&mGlow[1]);
- gGL.getTexUnit(1)->bind(&mScreen);
+ gDeferredCoFProgram.bind();
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredCoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
- buff->setBuffer(mask);
- buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+ gDeferredCoFProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle));
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredCoFProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- gGlowCombineProgram.unbind();
- }
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ gDeferredCoFProgram.unbind();
+ mRT->deferredLight.flush();
+ }
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale);
+ U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale);
- if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
- {
- gSplatTextureRectProgram.bind();
+ { // perform DoF sampling at half-res (preserve alpha channel)
+ src->bindTarget();
+ glViewport(0, 0, dof_width, dof_height);
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, false);
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2,
- (F32) gViewerWindow->getWorldViewHeightRaw() * 2);
+ gDeferredPostProgram.bind();
+ gDeferredPostProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, &mRT->deferredLight, LLTexUnit::TFO_POINT);
- LLGLEnable blend(GL_BLEND);
- gGL.color4f(1, 1, 1, 0.75f);
+ gDeferredPostProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredPostProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
- gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- gGL.begin(LLRender::TRIANGLES);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
+ gDeferredPostProgram.unbind();
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
+ src->flush();
+ gGL.setColorMask(true, true);
+ }
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
+ { // combine result based on alpha
+
+ dst->bindTarget();
+ if (RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete())
+ {
+ glViewport(0, 0, dst->getWidth(), dst->getHeight());
+ }
+ else
+ {
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+ }
- gGL.end();
- gGL.flush();
+ gDeferredDoFCombineProgram.bind();
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, src, LLTexUnit::TFO_POINT);
+ gDeferredDoFCombineProgram.bindTexture(LLShaderMgr::DEFERRED_LIGHT, &mRT->deferredLight, LLTexUnit::TFO_POINT);
- gSplatTextureRectProgram.unbind();
- }
+ gDeferredDoFCombineProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, dst->getWidth(), dst->getHeight());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)src->getWidth());
+ gDeferredDoFCombineProgram.uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)src->getHeight());
- if (LLRenderTarget::sUseFBO)
- { // copy depth buffer from mScreen to framebuffer
- LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), 0, 0,
- mScreen.getWidth(), mScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gDeferredDoFCombineProgram.unbind();
+
+ dst->flush();
+ }
+ }
+ else
+ {
+ copyRenderTarget(src, dst);
+ }
+ }
+}
+
+void LLPipeline::renderFinalize()
+{
+ llassert(!gCubeSnapshot);
+ LLVertexBuffer::unbind();
+ LLGLState::checkStates();
+
+ assertInitialized();
+
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
+ LL_PROFILE_GPU_ZONE("renderFinalize");
+
+ gGL.color4f(1, 1, 1, 1);
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable cull(GL_CULL_FACE);
+
+ enableLightsFullbright();
+
+ gGL.setColorMask(true, true);
+ glClearColor(0, 0, 0, 0);
+
+
+ copyScreenSpaceReflections(&mRT->screen, &mSceneMap);
+
+ generateLuminance(&mRT->screen, &mLuminanceMap);
+
+ generateExposure(&mLuminanceMap, &mExposureMap);
+
+ gammaCorrect(&mRT->screen, &mPostMap);
+
+ LLVertexBuffer::unbind();
+
+ generateGlow(&mPostMap);
+
+ combineGlow(&mPostMap, &mRT->screen);
+
+ gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
+ gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom;
+ gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth();
+ gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight();
+ glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
+
+ renderDoF(&mRT->screen, &mPostMap);
+
+ applyFXAA(&mPostMap, &mRT->screen);
+ LLRenderTarget* finalBuffer = &mRT->screen;
+ if (RenderBufferVisualization > -1)
+ {
+ finalBuffer = &mPostMap;
+ switch (RenderBufferVisualization)
+ {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ visualizeBuffers(&mRT->deferredScreen, finalBuffer, RenderBufferVisualization);
+ break;
+ case 4:
+ visualizeBuffers(&mLuminanceMap, finalBuffer, 0);
+ default:
+ break;
+ }
+ }
+
+ // Present the screen target.
+
+ gDeferredPostNoDoFProgram.bind();
+
+ // Whatever is last in the above post processing chain should _always_ be rendered directly here. If not, expect problems.
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, finalBuffer);
+ gDeferredPostNoDoFProgram.bindTexture(LLShaderMgr::DEFERRED_DEPTH, &mRT->deferredScreen, true);
+
+ {
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredPostNoDoFProgram.unbind();
+
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+ {
+ renderPhysicsDisplay();
}
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ /*if (LLRenderTarget::sUseFBO && !gCubeSnapshot)
+ { // copy depth buffer from mRT->screen to framebuffer
+ LLRenderTarget::copyContentsToFramebuffer(mRT->screen, 0, 0, mRT->screen.getWidth(), mRT->screen.getHeight(), 0, 0,
+ mRT->screen.getWidth(), mRT->screen.getHeight(),
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ }*/
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
+
+ // flush calls made to "addTrianglesDrawn" so far to stats machinery
+ recordTrianglesDrawn();
+}
+
+void LLPipeline::bindLightFunc(LLGLSLShader& shader)
+{
+ S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_BRDF_LUT, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ mPbrBrdfLut.bindTexture(0, channel);
+ }
+}
+
+void LLPipeline::bindShadowMaps(LLGLSLShader& shader)
+{
+ for (U32 i = 0; i < 4; i++)
+ {
+ LLRenderTarget* shadow_target = getSunShadowTarget(i);
+ if (shadow_target)
+ {
+ S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(getSunShadowTarget(i), TRUE);
+ }
+ }
+ }
+
+ for (U32 i = 4; i < 6; i++)
+ {
+ S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0 + i);
+ if (channel > -1)
+ {
+ LLRenderTarget* shadow_target = getSpotShadowTarget(i - 4);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
+ }
+ }
+ }
+}
+
+void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader)
+{
+ if (shader.mCanBindFast)
+ { // was previously fully bound, use fast path
+ shader.bind();
+ bindLightFunc(shader);
+ bindShadowMaps(shader);
+ bindReflectionProbes(shader);
+ }
+ else
+ { //wasn't previously bound, use slow path
+ bindDeferredShader(shader);
+ shader.mCanBindFast = true;
+ }
}
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
shader.bind();
S32 channel = 0;
channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); // frag_data[0]
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); // frag_data[1]
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
if (channel > -1)
{
- deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT);
+ deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); // frag_data[2]
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
- if (channel > -1)
- {
- gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
- stop_glerror();
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ deferred_target->bindTexture(3, channel, LLTexUnit::TFO_POINT); // frag_data[3]
+ gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
}
-
- glh::matrix4f projection = get_current_projection();
- glh::matrix4f inv_proj = projection.inverse();
-
- if (shader.getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX) != -1)
+
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(deferred_target, TRUE);
+ stop_glerror();
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::EXPOSURE_MAP);
+ if (channel > -1)
{
- shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ gGL.getTexUnit(channel)->bind(&mExposureMap);
}
if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
@@ -8129,11 +7527,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
- if (channel > -1)
- {
- gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- }
+ bindLightFunc(shader);
stop_glerror();
@@ -8141,60 +7535,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage());
if (channel > -1)
{
- light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
-
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM);
- if (channel > -1)
- {
- mGlow[1].bindTexture(0, channel);
+ if (light_target->isComplete())
+ {
+ light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
+ }
+ else
+ {
+ gGL.getTexUnit(channel)->bindFast(LLViewerFetchedTexture::sWhiteImagep);
+ }
}
stop_glerror();
- for (U32 i = 0; i < 4; i++)
- {
- LLRenderTarget* shadow_target = getShadowTarget(i);
- if (shadow_target)
- {
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
- stop_glerror();
- if (channel > -1)
- {
- stop_glerror();
- gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
- stop_glerror();
- }
- }
- }
-
- for (U32 i = 4; i < 6; i++)
- {
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i);
- stop_glerror();
- if (channel > -1)
- {
- stop_glerror();
- LLRenderTarget* shadow_target = getShadowTarget(i);
- if (shadow_target)
- {
- gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
- stop_glerror();
- }
- }
- }
+ bindShadowMaps(shader);
stop_glerror();
@@ -8213,23 +7566,29 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
stop_glerror();
- channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- if (channel > -1)
- {
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if (cube_map)
- {
- cube_map->enable(channel);
- cube_map->bind();
- F32* m = gGLModelView;
-
- F32 mat[] = { m[0], m[1], m[2],
- m[4], m[5], m[6],
- m[8], m[9], m[10] };
-
- shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
- }
- }
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ if (channel > -1)
+ {
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+ if (cube_map)
+ {
+ cube_map->enable(channel);
+ cube_map->bind();
+ }
+
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
+ }
+ }
+
+ bindReflectionProbes(shader);
if (gAtmosphere)
{
@@ -8259,7 +7618,14 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
}
}
- shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ /*if (gCubeSnapshot)
+ { // we only really care about the first two values, but the shader needs increasing separation between clip planes
+ shader.uniform4f(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1.f, 64.f, 128.f, 256.f);
+ }
+ else*/
+ {
+ shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
+ }
shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize);
@@ -8294,24 +7660,39 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_
shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
shader.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.mV);
- shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight());
- shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mRT->shadow[0].getWidth(), mRT->shadow[0].getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mSpotShadow[0].getWidth(), mSpotShadow[0].getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
+ shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLDeltaModelView);
+ shader.uniformMatrix4fv(LLShaderMgr::INVERSE_MODELVIEW_DELTA_MATRIX, 1, GL_FALSE, gGLInverseDeltaModelView);
+
+ shader.uniform1i(LLShaderMgr::CUBE_SNAPSHOT, gCubeSnapshot ? 1 : 0);
+
if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
- shader.uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV);
- shader.uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
+ // auto adjust legacy sun color if needed
+ static LLCachedControl<bool> should_auto_adjust(gSavedSettings, "RenderSkyAutoAdjustLegacy", true);
+ static LLCachedControl<F32> auto_adjust_sun_color_scale(gSavedSettings, "RenderSkyAutoAdjustSunColorScale", 1.f);
+ LLSettingsSky::ptr_t psky = LLEnvironment::instance().getCurrentSky();
+ LLColor3 sun_diffuse(mSunDiffuse.mV);
+ if (should_auto_adjust && psky->canAutoAdjust())
+ {
+ sun_diffuse *= auto_adjust_sun_color_scale;
+ }
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsSky::ptr_t sky = environment.getCurrentSky();
+ shader.uniform3fv(LLShaderMgr::SUNLIGHT_COLOR, 1, sun_diffuse.mV);
+ shader.uniform3fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV);
+
+ shader.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mReflectionMapManager.mMaxProbeLOD);
}
+
LLColor3 pow3f(LLColor3 v, F32 f)
{
v.mV[0] = powf(v.mV[0], f);
@@ -8328,48 +7709,36 @@ LLVector4 pow4fsrgb(LLVector4 v, F32 f)
return v;
}
-void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
+void LLPipeline::renderDeferredLighting()
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("renderDeferredLighting");
if (!sCull)
{
return;
}
- LLRenderTarget *deferred_target = &mDeferredScreen;
- LLRenderTarget *deferred_depth_target = &mDeferredDepth;
- LLRenderTarget *deferred_light_target = &mDeferredLight;
+ llassert(!sRenderingHUDs);
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
- LLViewerCamera *camera = LLViewerCamera::getInstance();
- {
- LLGLDepthTest depth(GL_TRUE);
- deferred_depth_target->copyContents(*deferred_target,
- 0,
- 0,
- deferred_target->getWidth(),
- deferred_target->getHeight(),
- 0,
- 0,
- deferred_depth_target->getWidth(),
- deferred_depth_target->getHeight(),
- GL_DEPTH_BUFFER_BIT,
- GL_NEAREST);
- }
+ F32 light_scale = 1.f;
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ if (gCubeSnapshot)
+ { //darken local lights when probe ambiance is above 1
+ light_scale = mReflectionMapManager.mLightScale;
+ }
+ LLRenderTarget *screen_target = &mRT->screen;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("deferred");
+ LLViewerCamera *camera = LLViewerCamera::getInstance();
+
if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
{
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
}
- // ati doesn't seem to love actually using the stencil buffer on FBO's
- LLGLDisable stencil(GL_STENCIL_TEST);
- // glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
- // glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
-
gGL.setColorMask(true, true);
// draw a cube around every light
@@ -8380,14 +7749,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
glh::matrix4f mat = copy_matrix(gGLModelView);
- LLStrider<LLVector3> vert;
- mDeferredVB->getVertexStrider(vert);
-
- vert[0].set(-1, 1, 0);
- vert[1].set(-1, -3, 0);
- vert[2].set(3, 1, 0);
-
- setupHWLights(NULL); // to set mSun/MoonDir;
+ setupHWLights(); // to set mSun/MoonDir;
glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
@@ -8397,19 +7759,14 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
mat.mult_matrix_vec(tc_moon);
mTransformedMoonDir.set(tc_moon.v);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
if (RenderDeferredSSAO || RenderShadowDetail > 0)
{
+ LL_PROFILE_GPU_ZONE("sun program");
deferred_light_target->bindTarget();
{ // paint shadow/SSAO light map (direct lighting lightmap)
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow");
bindDeferredShader(gDeferredSunProgram, deferred_light_target);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mScreenTriangleVB->setBuffer();
glClearColor(1, 1, 1, 1);
deferred_light_target->clear(GL_COLOR_BUFFER_BIT);
glClearColor(0, 0, 0, 0);
@@ -8441,9 +7798,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LLGLDisable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
unbindDeferredShader(gDeferredSunProgram);
@@ -8452,8 +7807,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
}
if (RenderDeferredSSAO)
- { // soften direct lighting lightmap
+ {
+ // soften direct lighting lightmap
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - soften shadow");
+ LL_PROFILE_GPU_ZONE("soften shadow");
// blur lightmap
screen_target->bindTarget();
glClearColor(1, 1, 1, 1);
@@ -8461,10 +7818,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
glClearColor(0, 0, 0, 0);
bindDeferredShader(gDeferredBlurLightProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- LLVector3 go = RenderShadowGaussian;
+
+ LLVector3 go = RenderShadowGaussian;
const U32 kern_length = 4;
- F32 blur_size = RenderShadowBlurSize;
+ F32 blur_size = RenderShadowBlurSize;
F32 dist_factor = RenderShadowBlurDistFactor;
// sample symmetrically with the middle sample falling exactly on 0.0
@@ -8488,9 +7845,8 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LLGLDisable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
screen_target->flush();
@@ -8498,7 +7854,6 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
bindDeferredShader(gDeferredBlurLightProgram, screen_target);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
deferred_light_target->bindTarget();
gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
@@ -8506,22 +7861,13 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LLGLDisable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
deferred_light_target->flush();
unbindDeferredShader(gDeferredBlurLightProgram);
}
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
-
screen_target->bindTarget();
// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
glClearColor(0, 0, 0, 0);
@@ -8532,64 +7878,50 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLGLSLShader &soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - atmospherics");
+ LL_PROFILE_GPU_ZONE("atmospherics");
bindDeferredShader(soften_shader);
+ static LLCachedControl<F32> ssao_scale(gSavedSettings, "RenderSSAOIrradianceScale", 0.5f);
+ static LLCachedControl<F32> ssao_max(gSavedSettings, "RenderSSAOIrradianceMax", 0.25f);
+ static LLStaticHashedString ssao_scale_str("ssao_irradiance_scale");
+ static LLStaticHashedString ssao_max_str("ssao_irradiance_max");
+
+ soften_shader.uniform1f(ssao_scale_str, ssao_scale);
+ soften_shader.uniform1f(ssao_max_str, ssao_max);
+
LLEnvironment &environment = LLEnvironment::instance();
soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+ soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV);
+
+ soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
- LLGLDisable test(GL_ALPHA_TEST);
// full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
- { // render non-deferred geometry (fullbright, alpha, etc)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
-
- gPipeline.pushRenderTypeMask();
-
- gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
-
- renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
- gPipeline.popRenderTypeMask();
- }
-
- bool render_local = RenderLocalLights;
+ static LLCachedControl<S32> local_light_count(gSavedSettings, "RenderLocalLightCount", 256);
- if (render_local)
+ if (local_light_count > 0)
{
gGL.setSceneBlendType(LLRender::BT_ADD);
std::list<LLVector4> fullscreen_lights;
LLDrawable::drawable_list_t spot_lights;
LLDrawable::drawable_list_t fullscreen_spot_lights;
- for (U32 i = 0; i < 2; i++)
+ if (!gCubeSnapshot)
{
- mTargetShadowSpotLight[i] = NULL;
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
}
std::list<LLVector4> light_colors;
@@ -8598,21 +7930,29 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - local lights");
+ LL_PROFILE_GPU_ZONE("local lights");
bindDeferredShader(gDeferredLightProgram);
if (mCubeVB.isNull())
{
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX);
}
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer();
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
// mNearbyLights already includes distance calculation and excludes muted avatars.
// It is calculated from mLights
// mNearbyLights also provides fade value to gracefully fade-out out of range lights
+ S32 count = 0;
for (light_set_t::iterator iter = mNearbyLights.begin(); iter != mNearbyLights.end(); ++iter)
{
+ count++;
+ if (count > local_light_count)
+ { //stop collecting lights once we hit the limit
+ break;
+ }
+
LLDrawable * drawablep = iter->drawable;
LLVOVolume * volume = drawablep->getVOVolume();
if (!volume)
@@ -8634,7 +7974,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
F32 s = volume->getLightRadius() * 1.5f;
// send light color to shader in linear space
- LLColor3 col = volume->getLightLinearColor();
+ LLColor3 col = volume->getLightLinearColor() * light_scale;
if (col.magVecSquared() < 0.001f)
{
@@ -8659,24 +7999,20 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
camera->getOrigin().mV[1] > c[1] + s + 0.2f || camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
camera->getOrigin().mV[2] > c[2] + s + 0.2f || camera->getOrigin().mV[2] < c[2] - s - 0.2f)
{ // draw box if camera is outside box
- if (render_local)
+ if (volume->isLightSpotlight())
{
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- spot_lights.push_back(drawablep);
- continue;
- }
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ continue;
+ }
- gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
- gGL.syncMatrices();
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF));
+ gGL.syncMatrices();
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- stop_glerror();
- }
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
}
else
{
@@ -8704,10 +8040,11 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
if (!spot_lights.empty())
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - projectors");
+ LL_PROFILE_GPU_ZONE("projectors");
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bindDeferredShader(gDeferredSpotLightProgram);
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mCubeVB->setBuffer();
gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -8727,7 +8064,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
setupSpotLight(gDeferredSpotLightProgram, drawablep);
// send light color to shader in linear space
- LLColor3 col = volume->getLightLinearColor();
+ LLColor3 col = volume->getLightLinearColor() * light_scale;
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
@@ -8741,22 +8078,10 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
unbindDeferredShader(gDeferredSpotLightProgram);
}
- // reset mDeferredVB to fullscreen triangle
- mDeferredVB->getVertexStrider(vert);
- vert[0].set(-1, 1, 0);
- vert[1].set(-1, -3, 0);
- vert[2].set(3, 1, 0);
-
{
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights");
LLGLDepthTest depth(GL_FALSE);
-
- // full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
+ LL_PROFILE_GPU_ZONE("fullscreen lights");
U32 count = 0;
@@ -8785,8 +8110,8 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
far_z = 0.f;
count = 0;
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mScreenTriangleVB->setBuffer();
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
@@ -8795,7 +8120,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mScreenTriangleVB->setBuffer();
for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
{
@@ -8814,94 +8139,37 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
// send light color to shader in linear space
- LLColor3 col = volume->getLightLinearColor();
+ LLColor3 col = volume->getLightLinearColor() * light_scale;
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final);
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
}
gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
unbindDeferredShader(gDeferredMultiSpotLightProgram);
-
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
}
}
- gGL.setColorMask(true, true);
- }
-
- screen_target->flush();
-
- // gamma correct lighting
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- {
- LLGLDepthTest depth(GL_FALSE, GL_FALSE);
-
- LLVector2 tc1(0, 0);
- LLVector2 tc2((F32) screen_target->getWidth() * 2, (F32) screen_target->getHeight() * 2);
-
- screen_target->bindTarget();
- // Apply gamma correction to the frame here.
- gDeferredPostGammaCorrectProgram.bind();
- // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- S32 channel = 0;
- channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
- if (channel > -1)
- {
- screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
-
- F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
-
- gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f));
-
- gGL.begin(LLRender::TRIANGLE_STRIP);
- gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
- gGL.vertex2f(-1, -1);
-
- gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
- gGL.vertex2f(-1, 3);
-
- gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
- gGL.vertex2f(3, -1);
-
- gGL.end();
- gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- screen_target->flush();
+ gGL.setColorMask(true, true);
}
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- screen_target->bindTarget();
-
{ // render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
+ //LLGLDisable stencil(GL_STENCIL_TEST);
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_VOLUME,
LLPipeline::RENDER_TYPE_GLOW,
LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_GLTF_PBR,
LLPipeline::RENDER_TYPE_PASS_SIMPLE,
LLPipeline::RENDER_TYPE_PASS_ALPHA,
LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
@@ -8911,6 +8179,7 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GLTF_GLOW,
LLPipeline::RENDER_TYPE_PASS_GRASS,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
@@ -8919,31 +8188,26 @@ void LLPipeline::renderDeferredLighting(LLRenderTarget *screen_target)
LLPipeline::RENDER_TYPE_CONTROL_AV,
LLPipeline::RENDER_TYPE_ALPHA_MASK,
LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_WATER,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
popRenderTypeMask();
}
- {
- // render highlights, etc.
- renderHighlights();
- mHighlightFaces.clear();
-
- renderDebug();
-
- LLVertexBuffer::unbind();
+ screen_target->flush();
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ if (!gCubeSnapshot)
+ {
+ // this is the end of the 3D scene render, grab a copy of the modelview and projection
+ // matrix for use in off-by-one-frame effects in the next frame
+ for (U32 i = 0; i < 16; i++)
{
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- gObjectList.resetObjectBeacons();
- gSky.addSunMoonBeacons();
+ gGLLastModelView[i] = gGLModelView[i];
+ gGLLastProjection[i] = gGLProjection[i];
}
}
-
- screen_target->flush();
+ gGL.setColorMask(true, true);
}
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
@@ -9036,9 +8300,13 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f);
}
+ // make sure we're not already targeting the same spot light with both shadow maps
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
+
+ if (!gCubeSnapshot)
{
LLDrawable* potential = drawablep;
- //determine if this is a good light for casting shadows
+ //determine if this light is higher priority than one of the existing spot shadows
F32 m_pri = volume->getSpotLightPriority();
for (U32 i = 0; i < 2; i++)
@@ -9047,7 +8315,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
if (mTargetShadowSpotLight[i].notNull())
{
- pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
+ pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority();
}
if (m_pri > pri)
@@ -9060,6 +8328,9 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
}
}
+ // make sure we didn't end up targeting the same spot light with both shadow maps
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
+
LLViewerTexture* img = volume->getLightTexture();
if (img == NULL)
@@ -9087,15 +8358,17 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
- LLRenderTarget* deferred_target = &mDeferredScreen;
- LLRenderTarget* deferred_depth_target = &mDeferredDepth;
- LLRenderTarget* deferred_light_target = &mDeferredLight;
+ LLRenderTarget* deferred_target = &mRT->deferredScreen;
+ LLRenderTarget* deferred_light_target = &mRT->deferredLight;
stop_glerror();
shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_EMISSIVE, deferred_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_BRDF_LUT);
+ //shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
+ shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_target->getUsage());
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -9104,7 +8377,7 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
@@ -9112,366 +8385,122 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1)
{
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
}
}
shader.disableTexture(LLShaderMgr::DEFERRED_NOISE);
shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC);
- S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- if (channel > -1)
- {
- LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
- if (cube_map)
- {
- cube_map->disable();
- }
- }
+ if (!LLPipeline::sReflectionProbesEnabled)
+ {
+ S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ if (channel > -1)
+ {
+ LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL;
+ if (cube_map)
+ {
+ cube_map->disable();
+ }
+ }
+ }
+
+ unbindReflectionProbes(shader);
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(0)->activate();
shader.unbind();
}
-inline float sgn(float a)
+void LLPipeline::setEnvMat(LLGLSLShader& shader)
{
- if (a > 0.0F) return (1.0F);
- if (a < 0.0F) return (-1.0F);
- return (0.0F);
+ F32* m = gGLModelView;
+
+ F32 mat[] = { m[0], m[1], m[2],
+ m[4], m[5], m[6],
+ m[8], m[9], m[10] };
+
+ shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat);
}
-void LLPipeline::generateWaterReflection(LLCamera& camera_in)
+void LLPipeline::bindReflectionProbes(LLGLSLShader& shader)
{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-
- if (!assertInitialized())
+ if (!sReflectionProbesEnabled)
{
return;
}
- if (LLPipeline::sWaterReflections && LLDrawPoolWater::sNeedsReflectionUpdate)
+ S32 channel = shader.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ bool bound = false;
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
{
- //disable occlusion culling for reflection/refraction passes (save setting to restore later)
- S32 occlude = LLPipeline::sUseOcclusion;
- LLPipeline::sUseOcclusion = 0;
-
- bool skip_avatar_update = false;
- if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
- {
- skip_avatar_update = true;
- }
-
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
-
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
-
- LLPipeline::sReflectionRender = true;
-
- gPipeline.pushRenderTypeMask();
-
- glh::matrix4f saved_modelview = get_current_modelview();
- glh::matrix4f saved_projection = get_current_projection();
- glh::matrix4f mat;
-
- S32 reflection_detail = RenderReflectionDetail;
-
- F32 water_height = gAgent.getRegion()->getWaterHeight();
- F32 camera_height = camera_in.getOrigin().mV[VZ];
- F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height);
-
- LLVector3 reflection_offset = LLVector3(0, 0, distance_to_water * 2.0f);
- LLVector3 camera_look_at = camera_in.getAtAxis();
- LLVector3 reflection_look_at = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]);
- LLVector3 reflect_origin = camera_in.getOrigin() - reflection_offset;
- LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f);
-
- camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
-
- //plane params
- LLPlane plane;
- LLVector3 pnorm;
-
- if (camera_is_underwater)
- {
- //camera is below water, cull above water
- pnorm.setVec(0, 0, 1);
- }
- else
- {
- //camera is above water, cull below water
- pnorm = LLVector3(0, 0, -1);
- }
-
- plane.setVec(LLVector3(0, 0, water_height), pnorm);
-
- if (!camera_is_underwater)
- {
- //generate planar reflection map
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
-
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- mat.set_scale(glh::vec3f(1, 1, -1));
- mat.set_translate(glh::vec3f(0,0,water_height*2.f));
- mat = saved_modelview * mat;
-
-
- mReflectionModelView = mat;
-
- set_current_modelview(mat);
- gGL.loadMatrix(mat.m);
-
- LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
-
- glh::vec3f origin(0, 0, 0);
- glh::matrix4f inv_mat = mat.inverse();
- inv_mat.mult_matrix_vec(origin);
-
- camera.setOrigin(origin.v);
-
- glCullFace(GL_FRONT);
-
- if (LLDrawPoolWater::sNeedsReflectionUpdate)
- {
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- glClearColor(0,0,0,0);
- mWaterRef.bindTarget();
-
- gGL.setColorMask(true, true);
- mWaterRef.clear();
- gGL.setColorMask(true, false);
- mWaterRef.getViewport(gGLViewport);
-
- //initial sky pass (no user clip plane)
- //mask out everything but the sky
- gPipeline.pushRenderTypeMask();
- {
- if (reflection_detail >= WATER_REFLECT_MINIMAL)
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
- }
- else
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
- }
-
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- gPipeline.pushRenderTypeMask();
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
-
- if (reflection_detail > WATER_REFLECT_MINIMAL)
- { //mask out selected geometry based on reflection detail
- if (reflection_detail < WATER_REFLECT_EVERYTHING)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_AVATARS)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_CONTROL_AV,
- END_RENDER_TYPES);
- if (reflection_detail < WATER_REFLECT_STATIC_OBJECTS)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
- }
- }
- }
-
- LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
- LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, mReflectedObjects, &plane);
- stateSort(camera, mReflectedObjects);
- renderGeom(camera);
- }
- }
- gPipeline.popRenderTypeMask();
- }
-
- mWaterRef.flush();
- }
-
- glCullFace(GL_BACK);
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- set_current_modelview(saved_modelview);
- }
-
- camera.setOrigin(camera_in.getOrigin());
- //render distortion map
- static bool last_update = true;
- if (last_update)
- {
- gPipeline.pushRenderTypeMask();
-
- camera.setFar(camera_in.getFar());
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- END_RENDER_TYPES);
-
- // intentionally inverted so that distortion map contents (objects under the water when we're above it)
- // will properly include water fog effects
- LLPipeline::sUnderWaterRender = !camera_is_underwater;
-
- if (LLPipeline::sUnderWaterRender)
- {
- clearRenderTypeMask(
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- END_RENDER_TYPES);
- }
- LLViewerCamera::updateFrustumPlanes(camera);
-
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- LLPipeline::sDistortionRender = true;
-
- LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
- glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
-
- // HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts
- // during distortion render (doesn't break main render because the camera is the same perspective
- // as world camera and occlusion culling is disabled for this pass)
- //LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- mWaterDis.bindTarget();
- mWaterDis.getViewport(gGLViewport);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- F32 water_dist = water_height;
-
- //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself,
- // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map
- LLPlane plane;
-
- if (camera_is_underwater)
- {
- //nudge clip plane below water to avoid visible holes in objects intersecting water surface
- water_dist /= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is below water, clip plane points up
- pnorm.setVec(0, 0, -1);
- }
- else
- {
- //nudge clip plane above water to avoid visible holes in objects intersecting water surface
- water_dist *= LLPipeline::sDistortionWaterClipPlaneMargin;
- //camera is above water, clip plane points down
- pnorm = LLVector3(0, 0, 1);
- }
-
- plane.setVec(LLVector3(0, 0, water_dist), pnorm);
-
- LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
-
- gGL.setColorMask(true, true);
- mWaterDis.clear();
- gGL.setColorMask(true, false);
-
- if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
- {
- updateCull(camera, mRefractedObjects, &plane);
- stateSort(camera, mRefractedObjects);
- renderGeom(camera);
- }
-
- gUIProgram.bind();
+ mReflectionMapManager.mTexture->bind(channel);
+ bound = true;
+ }
- LLWorld::getInstance()->renderPropertyLines();
+ channel = shader.enableTexture(LLShaderMgr::IRRADIANCE_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY);
+ if (channel > -1 && mReflectionMapManager.mIrradianceMaps.notNull())
+ {
+ mReflectionMapManager.mIrradianceMaps->bind(channel);
+ bound = true;
+ }
- gUIProgram.unbind();
+ if (bound)
+ {
+ mReflectionMapManager.setUniforms();
- mWaterDis.flush();
- }
+ setEnvMat(shader);
+ }
- LLPipeline::sDistortionRender = false;
+ // reflection probe shaders generally sample the scene map as well for SSR
+ channel = shader.enableTexture(LLShaderMgr::SCENE_MAP);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&mSceneMap);
+ }
- gPipeline.popRenderTypeMask();
- }
- last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
+
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ITR_COUNT, RenderScreenSpaceReflectionIterations);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_DIST_BIAS, RenderScreenSpaceReflectionDistanceBias);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_RAY_STEP, RenderScreenSpaceReflectionRayStep);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_GLOSSY_SAMPLES, RenderScreenSpaceReflectionGlossySamples);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_REJECT_BIAS, RenderScreenSpaceReflectionDepthRejectBias);
+ mPoissonOffset++;
- gPipeline.popRenderTypeMask();
+ if (mPoissonOffset > 128 - RenderScreenSpaceReflectionGlossySamples)
+ mPoissonOffset = 0;
- LLPipeline::sUnderWaterRender = false;
- LLPipeline::sReflectionRender = false;
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_NOISE_SINE, mPoissonOffset);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SSR_ADAPTIVE_STEP_MULT, RenderScreenSpaceReflectionAdaptiveStepMultiplier);
- LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
- LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
+ channel = shader.enableTexture(LLShaderMgr::SCENE_DEPTH);
+ if (channel > -1)
+ {
+ gGL.getTexUnit(channel)->bind(&mSceneMap, true);
+ }
- if (!LLRenderTarget::sUseFBO)
- {
- glClear(GL_DEPTH_BUFFER_BIT);
- }
- glClearColor(0.f, 0.f, 0.f, 0.f);
- gViewerWindow->setup3DViewport();
- LLGLState::checkStates();
+}
- if (!skip_avatar_update)
+void LLPipeline::unbindReflectionProbes(LLGLSLShader& shader)
+{
+ S32 channel = shader.disableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP);
+ if (channel > -1 && mReflectionMapManager.mTexture.notNull())
+ {
+ mReflectionMapManager.mTexture->unbind();
+ if (channel == 0)
{
- gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+ gGL.getTexUnit(channel)->enable(LLTexUnit::TT_TEXTURE);
}
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- // restore occlusion culling
- LLPipeline::sUseOcclusion = occlude;
}
- else
- {
- // Initial sky pass is still needed even if water reflection is not rendering
- bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
- if (!camera_is_underwater)
- {
- gPipeline.pushRenderTypeMask();
- {
- gPipeline.andRenderTypeMask(
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+}
- LLCamera camera = camera_in;
- camera.setFar(camera_in.getFar() * 0.75f);
- updateCull(camera, mSky);
- stateSort(camera, mSky);
- renderGeom(camera, TRUE);
- }
- gPipeline.popRenderTypeMask();
- }
- }
+inline float sgn(float a)
+{
+ if (a > 0.0F) return (1.0F);
+ if (a < 0.0F) return (-1.0F);
+ return (0.0F);
}
glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -9551,24 +8580,25 @@ static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass");
static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked");
-void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width)
+void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult& result, bool depth_clamp)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
-
- //disable occlusion culling for shadow passes (save setting to restore later)
- S32 occlude = LLPipeline::sUseOcclusion;
- if (!use_occlusion)
- {
- LLPipeline::sUseOcclusion = 0;
- }
+ LL_PROFILE_GPU_ZONE("renderShadow");
+
LLPipeline::sShadowRender = true;
+ // disable occlusion culling during shadow render
+ U32 saved_occlusion = sUseOcclusion;
+ sUseOcclusion = 0;
+
+ // List of render pass types that use the prim volume as the shadow,
+ // ignoring textures.
static const U32 types[] = {
LLRenderPass::PASS_SIMPLE,
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_FULLBRIGHT_SHINY,
LLRenderPass::PASS_MATERIAL,
LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
LLRenderPass::PASS_SPECMAP,
@@ -9576,28 +8606,20 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_NORMMAP,
LLRenderPass::PASS_NORMMAP_EMISSIVE,
LLRenderPass::PASS_NORMSPEC,
- LLRenderPass::PASS_NORMSPEC_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE
};
LLGLEnable cull(GL_CULL_FACE);
//enable depth clamping if available
- LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+ LLGLEnable clamp_depth(depth_clamp ? GL_DEPTH_CLAMP : 0);
- if (use_shader)
- {
- gDeferredShadowCubeProgram.bind();
- }
+ LLGLDepthTest depth_test(GL_TRUE, GL_TRUE, GL_LESS);
- LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID - 1];
-
- occlusion_target.bindTarget();
updateCull(shadow_cam, result);
- occlusion_target.flush();
stateSort(shadow_cam, result);
-
//generate shadow map
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -9613,22 +8635,20 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
stop_glerror();
- LLEnvironment& environment = LLEnvironment::instance();
+ struct CompareVertexBuffer
+ {
+ bool operator()(const LLDrawInfo* const& lhs, const LLDrawInfo* const& rhs)
+ {
+ return lhs->mVertexBuffer > rhs->mVertexBuffer;
+ }
+ };
- LLVertexBuffer::unbind();
+ LLVertexBuffer::unbind();
for (int j = 0; j < 2; ++j) // 0 -- static, 1 -- rigged
{
bool rigged = j == 1;
- if (!use_shader)
- { //occlusion program is general purpose depth-only no-textures
- gOcclusionProgram.bind(rigged);
- }
- else
- {
- gDeferredShadowProgram.bind(rigged);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- }
+ gDeferredShadowProgram.bind(rigged);
gGL.diffuseColor4f(1, 1, 1, 1);
@@ -9641,107 +8661,116 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow simple"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
-
+ LL_PROFILE_GPU_ZONE("shadow simple");
gGL.getTexUnit(0)->disable();
- for (U32 i = 0; i < sizeof(types) / sizeof(U32); ++i)
- {
- renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged);
- }
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!use_shader)
+
+ for (U32 type : types)
{
- gOcclusionProgram.unbind();
+ renderObjects(type, false, false, rigged);
}
+ renderGLTFObjects(LLRenderPass::PASS_GLTF_PBR, false, rigged);
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
}
- if (use_shader)
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
-
- gDeferredShadowProgram.unbind();
- renderGeomShadow(shadow_cam);
- gDeferredShadowProgram.bind();
- gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
+ if (LLPipeline::sUseOcclusion > 1)
+ { // do occlusion culling against non-masked only to take advantage of hierarchical Z
+ doOcclusion(shadow_cam);
}
- else
- {
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM);
+
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow geom");
renderGeomShadow(shadow_cam);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha");
+ LL_PROFILE_GPU_ZONE("shadow alpha");
+ const S32 sun_up = LLEnvironment::instance().getIsSunUp() ? 1 : 0;
+ U32 target_width = LLRenderTarget::sCurResX;
for (int i = 0; i < 2; ++i)
{
bool rigged = i == 1;
- gDeferredShadowAlphaMaskProgram.bind(rigged);
- LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
-
- U32 mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0 |
- LLVertexBuffer::MAP_COLOR |
- LLVertexBuffer::MAP_TEXTURE_INDEX;
-
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED);
- renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked");
+ LL_PROFILE_GPU_ZONE("shadow alpha masked");
+ gDeferredShadowAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, true, true, rigged);
}
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND);
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
- renderAlphaObjects(mask, TRUE, TRUE, rigged);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend");
+ LL_PROFILE_GPU_ZONE("shadow alpha blend");
+ renderAlphaObjects(rigged);
}
-
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked");
+ LL_PROFILE_GPU_ZONE("shadow alpha masked");
gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
- LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0);
- renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged);
+ renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true, rigged);
}
-
{
- LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); //LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS);
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass");
+ LL_PROFILE_GPU_ZONE("shadow alpha grass");
gDeferredTreeShadowProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(ALPHA_BLEND_CUTOFF);
+
if (i == 0)
{
- LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f);
- renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
+ renderObjects(LLRenderPass::PASS_GRASS, true);
}
- U32 no_idx_mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, no_idx_mask, true, false, rigged);
- renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged);
- renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged);
- renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged);
+ {
+ LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha material");
+ LL_PROFILE_GPU_ZONE("shadow alpha material");
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, true, false, rigged);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, true, false, rigged);
+ }
}
}
- }
- //glCullFace(GL_BACK);
-
- gDeferredShadowCubeProgram.bind();
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
+ for (int i = 0; i < 2; ++i)
+ {
+ bool rigged = i == 1;
+ gDeferredShadowGLTFAlphaMaskProgram.bind(rigged);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up);
+ LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
+
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
- LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID - 1];
+ U32 type = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK;
- doOcclusion(shadow_cam, occlusion_source, occlusion_target);
+ if (rigged)
+ {
+ mAlphaMaskPool->pushRiggedGLTFBatches(type + 1);
+ }
+ else
+ {
+ mAlphaMaskPool->pushGLTFBatches(type);
+ }
- if (use_shader)
- {
- gDeferredShadowProgram.unbind();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ }
}
+ gDeferredShadowCubeProgram.bind();
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+
gGL.setColorMask(true, true);
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -9750,7 +8779,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGL.popMatrix();
gGLLastMatrix = NULL;
- LLPipeline::sUseOcclusion = occlude;
+ // reset occlusion culling flag
+ sUseOcclusion = saved_occlusion;
LLPipeline::sShadowRender = false;
}
@@ -9949,69 +8979,40 @@ void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade)
}
}
-void LLPipeline::generateHighlight(LLCamera& camera)
-{
- //render highlighted object as white into offscreen render target
- if (mHighlightObject.notNull())
- {
- mHighlightSet.insert(HighlightItem(mHighlightObject));
- }
-
- if (!mHighlightSet.empty())
- {
- F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;
-
- LLGLDisable test(GL_ALPHA_TEST);
- LLGLDepthTest depth(GL_FALSE);
- mHighlight.bindTarget();
- disableLights();
- gGL.setColorMask(true, true);
- mHighlight.clear();
-
- gHighlightProgram.bind();
-
- gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep);
- for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); )
- {
- std::set<HighlightItem>::iterator cur_iter = iter++;
-
- if (cur_iter->mItem.isNull())
- {
- mHighlightSet.erase(cur_iter);
- continue;
- }
-
- if (cur_iter->mItem == mHighlightObject)
- {
- cur_iter->incrFade(transition);
- }
- else
- {
- cur_iter->incrFade(-transition);
- if (cur_iter->mFade <= 0.f)
- {
- mHighlightSet.erase(cur_iter);
- continue;
- }
- }
-
- renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade);
- }
- mHighlight.flush();
- gGL.setColorMask(true, false);
- gViewerWindow->setup3DViewport();
- }
+LLRenderTarget* LLPipeline::getSunShadowTarget(U32 i)
+{
+ llassert(i < 4);
+ return &mRT->shadow[i];
}
-LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
+LLRenderTarget* LLPipeline::getSpotShadowTarget(U32 i)
{
- return &mShadow[i];
+ llassert(i < 2);
+ return &mSpotShadow[i];
}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render");
+// helper class for disabling occlusion culling for the current stack frame
+class LLDisableOcclusionCulling
+{
+public:
+ S32 mUseOcclusion;
+
+ LLDisableOcclusionCulling()
+ {
+ mUseOcclusion = LLPipeline::sUseOcclusion;
+ LLPipeline::sUseOcclusion = 0;
+ }
+
+ ~LLDisableOcclusionCulling()
+ {
+ LLPipeline::sUseOcclusion = mUseOcclusion;
+ }
+};
+
void LLPipeline::generateSunShadow(LLCamera& camera)
{
if (!sRenderDeferred || RenderShadowDetail <= 0)
@@ -10020,11 +9021,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
+ LL_PROFILE_GPU_ZONE("generateSunShadow");
+
+ LLDisableOcclusionCulling no_occlusion;
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
{
-
skip_avatar_update = true;
}
@@ -10044,7 +9047,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
pushRenderTypeMask();
andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_ALPHA_PRE_WATER,
+ LLPipeline::RENDER_TYPE_ALPHA_POST_WATER,
LLPipeline::RENDER_TYPE_GRASS,
+ LLPipeline::RENDER_TYPE_GLTF_PBR,
LLPipeline::RENDER_TYPE_FULLBRIGHT,
LLPipeline::RENDER_TYPE_BUMP,
LLPipeline::RENDER_TYPE_VOLUME,
@@ -10102,6 +9108,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED,
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_GLTF_PBR,
+ LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_RIGGED,
+ LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -10118,27 +9128,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
glh::matrix4f view[6];
glh::matrix4f proj[6];
- //clip contains parallel split distances for 3 splits
- LLVector3 clip = RenderShadowClipPlanes;
-
LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
- //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold");
-
- //far clip on last split is minimum of camera view distance and 128
- mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]);
-
- clip = RenderShadowOrthoClipPlanes;
- mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
-
- //currently used for amount to extrude frusta corners for constructing shadow frusta
- //LLVector3 n = RenderShadowNearDist;
- //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
-
//put together a universal "near clip" plane for shadow frusta
LLPlane shadow_near_clip;
{
- LLVector3 p = gAgent.getPositionAgent();
+ LLVector3 p = camera.getOrigin(); // gAgent.getPositionAgent();
p += caster_dir * RenderFarClip*2.f;
shadow_near_clip.setVec(p, caster_dir);
}
@@ -10159,9 +9154,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
up = camera.getUpAxis();
}
- /*LLVector3 left = up%at;
- up = at%left;*/
-
up.normVec();
at.normVec();
@@ -10180,7 +9172,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (fp.empty())
{
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowCamera[0] = main_camera;
mShadowExtents[0][0] = min;
@@ -10244,30 +9236,38 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding
}
+ if (gCubeSnapshot)
+ { // stretch clip planes for reflection probe renders to reduce number of shadow passes
+ mSunClipPlanes.mV[1] = mSunClipPlanes.mV[2];
+ mSunClipPlanes.mV[2] = mSunClipPlanes.mV[3];
+ mSunClipPlanes.mV[3] *= 1.5f;
+ }
+
+
// convenience array of 4 near clip plane distances
F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] };
-
if (mSunDiffuse == LLColor4::black)
- { //sun diffuse is totally black, shadows don't matter
+ { //sun diffuse is totally black shadows don't matter
skipRenderingShadows();
}
else
{
- for (S32 j = 0; j < 4; j++)
+ for (S32 j = 0; j < (gCubeSnapshot ? 2 : 4); j++)
{
- if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowFrustPoints[j].clear();
}
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SUN_SHADOW0+j);
//restore render matrices
set_current_modelview(saved_view);
set_current_projection(saved_proj);
LLVector3 eye = camera.getOrigin();
+ llassert(eye.isFinite());
//camera used for shadow cull/render
LLCamera shadow_cam;
@@ -10298,7 +9298,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
shadow_cam.calcAgentFrustumPlanes(frust);
shadow_cam.mFrustumCornerDist = 0.f;
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowCamera[j] = shadow_cam;
}
@@ -10309,19 +9309,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
|| j > RenderShadowSplits)
{
//no possible shadow receivers
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowExtents[j][0] = LLVector3();
mShadowExtents[j][1] = LLVector3();
mShadowCamera[j+4] = shadow_cam;
}
- mShadow[j].bindTarget();
+ mRT->shadow[j].bindTarget();
{
LLGLDepthTest depth(GL_TRUE);
- mShadow[j].clear();
+ mRT->shadow[j].clear();
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
mShadowError.mV[j] = 0.f;
mShadowFOV.mV[j] = 0.f;
@@ -10329,7 +9329,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
continue;
}
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowExtents[j][0] = min;
mShadowExtents[j][1] = max;
@@ -10548,6 +9548,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
{
//get perspective projection
view[j] = view[j].inverse();
+ //llassert(origin.isFinite());
glh::vec3f origin_agent(origin.mV);
@@ -10555,8 +9556,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
view[j].mult_matrix_vec(origin_agent);
eye = LLVector3(origin_agent.v);
-
- if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ //llassert(eye.isFinite());
+ if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowFrustOrigin[j] = eye;
}
@@ -10608,168 +9609,175 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
stop_glerror();
- mShadow[j].bindTarget();
- mShadow[j].getViewport(gGLViewport);
- mShadow[j].clear();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].getViewport(gGLViewport);
+ mRT->shadow[j].clear();
- U32 target_width = mShadow[j].getWidth();
-
{
static LLCullResult result[4];
- renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width);
+ renderShadow(view[j], proj[j], shadow_cam, result[j], true);
}
- mShadow[j].flush();
+ mRT->shadow[j].flush();
- if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
+ if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot)
{
mShadowCamera[j+4] = shadow_cam;
}
}
}
-
//hack to disable projector shadows
bool gen_shadow = RenderShadowDetail > 1;
if (gen_shadow)
{
- LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
- F32 fade_amt = gFrameIntervalSeconds.value()
- * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
-
- if (mShadowSpotLight[i].notNull() &&
- (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
- mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
- { //keep this spotlight
- mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
- }
- else
- { //fade out this light
- mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-
- if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
- { //faded out, grab one of the pending spots (whichever one isn't already taken)
- if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[0];
- }
- else
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[1];
- }
- }
- }
- }
+ // should never happen
+ llassert(mTargetShadowSpotLight[0] != mTargetShadowSpotLight[1] || mTargetShadowSpotLight[0].isNull());
- for (S32 i = 0; i < 2; i++)
- {
- set_current_modelview(saved_view);
- set_current_projection(saved_proj);
+ //update shadow targets
+ for (U32 i = 0; i < 2; i++)
+ { //for each current shadow
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
+
+ if (mShadowSpotLight[i].notNull() &&
+ (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+ mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+ { //keep this spotlight
+ mSpotLightFade[i] = llmin(mSpotLightFade[i] + fade_amt, 1.f);
+ }
+ else
+ { //fade out this light
+ mSpotLightFade[i] = llmax(mSpotLightFade[i] - fade_amt, 0.f);
- if (mShadowSpotLight[i].isNull())
- {
- continue;
- }
+ if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+ { //faded out, grab one of the pending spots (whichever one isn't already taken)
+ if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i + 1) % 2])
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+ }
+ else
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ }
+ }
+ }
+ }
+ }
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ // this should never happen
+ llassert(mShadowSpotLight[0] != mShadowSpotLight[1] || mShadowSpotLight[0].isNull());
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ for (S32 i = 0; i < 2; i++)
+ {
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
- LLDrawable* drawable = mShadowSpotLight[i];
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ LLDrawable* drawable = mShadowSpotLight[i];
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- LLVector3 origin = np - at_axis*dist;
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0, 0, -scale.mV[2] * 0.5f);
+ at_axis *= quat;
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLVector3 np = center + at_axis;
+ at_axis.normVec();
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1] * 0.5f) / tanf(fov * 0.5f);
- view[i+4] = view[i+4].inverse();
+ LLVector3 origin = np - at_axis * dist;
- //get perspective matrix
- F32 near_clip = dist+0.01f;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = dist+volume->getLightRadius()*1.5f;
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ view[i + 4] = glh::matrix4f((F32*)mat.mMatrix);
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ view[i + 4] = view[i + 4].inverse();
- set_current_modelview(view[i+4]);
- set_current_projection(proj[i+4]);
+ //get perspective matrix
+ F32 near_clip = dist + 0.01f;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = dist + volume->getLightRadius() * 1.5f;
- mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-
- for (U32 j = 0; j < 16; j++)
- {
- gGLLastModelView[j] = mShadowModelview[i+4].m[j];
- gGLLastProjection[j] = mShadowProjection[i+4].m[j];
- }
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width / height;
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ proj[i + 4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ set_current_modelview(view[i + 4]);
+ set_current_projection(proj[i + 4]);
- stop_glerror();
+ mSunShadowMatrix[i + 4] = trans * proj[i + 4] * view[i + 4] * inv_view;
- mShadow[i+4].bindTarget();
- mShadow[i+4].getViewport(gGLViewport);
- mShadow[i+4].clear();
+ for (U32 j = 0; j < 16; j++)
+ {
+ gGLLastModelView[j] = mShadowModelview[i + 4].m[j];
+ gGLLastProjection[j] = mShadowProjection[i + 4].m[j];
+ }
- U32 target_width = mShadow[i+4].getWidth();
+ mShadowModelview[i + 4] = view[i + 4];
+ mShadowProjection[i + 4] = proj[i + 4];
+
+ if (!gCubeSnapshot) //skip updating spot shadow maps during cubemap updates
+ {
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- static LLCullResult result[2];
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ //
+
+ mSpotShadow[i].bindTarget();
+ mSpotShadow[i].getViewport(gGLViewport);
+ mSpotShadow[i].clear();
- RenderSpotLight = drawable;
+ static LLCullResult result[2];
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SPOT_SHADOW0 + i);
- RenderSpotLight = nullptr;
+ RenderSpotLight = drawable;
- mShadow[i+4].flush();
- }
+ renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], false);
+
+ RenderSpotLight = nullptr;
+
+ mSpotShadow[i].flush();
+ }
+ }
}
else
{ //no spotlight shadows
@@ -10791,7 +9799,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
gGL.loadMatrix(proj[1].m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
- gGL.setColorMask(true, false);
+ gGL.setColorMask(true, true);
for (U32 i = 0; i < 16; i++)
{
@@ -10807,7 +9815,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
}
-void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture)
+void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, bool texture)
{
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
@@ -10817,12 +9825,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool textu
gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
group->mDrawMap.find(type) != group->mDrawMap.end())
{
- pass->renderGroup(group,type,mask,texture);
+ pass->renderGroup(group,type,texture);
}
}
}
-void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture)
+void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture)
{
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
@@ -10832,18 +9840,86 @@ void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool
gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
group->mDrawMap.find(type) != group->mDrawMap.end())
{
- pass->renderRiggedGroup(group, type, mask, texture);
+ pass->renderRiggedGroup(group, type, texture);
}
}
}
-static LLTrace::BlockTimerStatHandle FTM_GENERATE_IMPOSTOR("Generate Impostor");
+void LLPipeline::profileAvatar(LLVOAvatar* avatar, bool profile_attachments)
+{
+ if (gGLManager.mGLVersion < 3.25f)
+ { // profiling requires GL 3.3 or later
+ return;
+ }
+
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+
+ // don't continue to profile an avatar that is known to be too slow
+ llassert(!avatar->isTooSlow());
+
+ LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr;
-void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
+ mRT->deferredScreen.bindTarget();
+ mRT->deferredScreen.clear();
+
+ if (!profile_attachments)
+ {
+ // profile entire avatar all at once and readback asynchronously
+ avatar->placeProfileQuery();
+
+ LLTimer cpu_timer;
+
+ generateImpostor(avatar, false, true);
+
+ avatar->mCPURenderTime = (F32)cpu_timer.getElapsedTimeF32() * 1000.f;
+
+ avatar->readProfileQuery(5); // allow up to 5 frames of latency
+ }
+ else
+ {
+ // profile attachments one at a time
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
+ {
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
+ {
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ // use gDebugProgram to do the GPU queries
+ gDebugProgram.clearStats();
+ gDebugProgram.placeProfileQuery(true);
+
+ generateImpostor(avatar, false, true, attached_object);
+ gDebugProgram.readProfileQuery(true, true);
+
+ attached_object->mGPURenderTime = gDebugProgram.mTimeElapsed / 1000000.f;
+ }
+ }
+ }
+ }
+
+ mRT->deferredScreen.flush();
+
+ if (cur_shader)
+ {
+ cur_shader->bind();
+ }
+}
+
+void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar, bool for_profile, LLViewerObject* specific_attachment)
{
- LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
+ LL_PROFILE_GPU_ZONE("generateImpostor");
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
static LLCullResult result;
result.clear();
@@ -10859,11 +9935,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
assertInitialized();
// previews can't be muted or impostered
- bool visually_muted = !preview_avatar && avatar->isVisuallyMuted();
+ bool visually_muted = !for_profile && !preview_avatar && avatar->isVisuallyMuted();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( visually_muted ? "" : "not ") << "visually muted"
<< LL_ENDL;
- bool too_complex = !preview_avatar && avatar->isTooComplex();
+ bool too_complex = !for_profile && !preview_avatar && avatar->isTooComplex();
LL_DEBUGS_ONCE("AvatarRenderPipeline") << "Avatar " << avatar->getID()
<< " is " << ( too_complex ? "" : "not ") << "too complex"
<< LL_ENDL;
@@ -10883,13 +9959,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
clearRenderTypeMask(
RENDER_TYPE_SKY,
RENDER_TYPE_WL_SKY,
- RENDER_TYPE_GROUND,
RENDER_TYPE_TERRAIN,
RENDER_TYPE_GRASS,
RENDER_TYPE_CONTROL_AV, // Animesh
RENDER_TYPE_TREE,
RENDER_TYPE_VOIDWATER,
RENDER_TYPE_WATER,
+ RENDER_TYPE_ALPHA_PRE_WATER,
RENDER_TYPE_PASS_GRASS,
RENDER_TYPE_HUD,
RENDER_TYPE_PARTICLES,
@@ -10899,6 +9975,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
);
}
+ if (specific_attachment && specific_attachment->isHUDAttachment())
+ { //enable HUD rendering
+ setRenderTypeMask(RENDER_TYPE_HUD, END_RENDER_TYPES);
+ }
+
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
@@ -10955,20 +10036,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
}
else
{
- LLVOAvatar::attachment_map_t::iterator iter;
- for (iter = avatar->mAttachmentPoints.begin();
- iter != avatar->mAttachmentPoints.end();
- ++iter)
+ if (specific_attachment)
{
- LLViewerJointAttachment *attachment = iter->second;
- for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
- attachment_iter != attachment->mAttachedObjects.end();
- ++attachment_iter)
+ markVisible(specific_attachment->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
+ else
+ {
+ LLVOAvatar::attachment_map_t::iterator iter;
+ LLVOAvatar::attachment_map_t::iterator begin = avatar->mAttachmentPoints.begin();
+ LLVOAvatar::attachment_map_t::iterator end = avatar->mAttachmentPoints.end();
+
+ for (iter = begin;
+ iter != end;
+ ++iter)
{
- LLViewerObject* attached_object = attachment_iter->get();
- if (attached_object)
+ LLViewerJointAttachment* attachment = iter->second;
+ for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+ attachment_iter != attachment->mAttachedObjects.end();
+ ++attachment_iter)
{
- markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ LLViewerObject* attached_object = attachment_iter->get();
+ if (attached_object)
+ {
+ markVisible(attached_object->mDrawable->getSpatialBridge(), *viewer_camera);
+ }
}
}
}
@@ -11038,25 +10129,28 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
resY = llmin(nhpo2((U32) (fov*pa)), (U32) 512);
resX = llmin(nhpo2((U32) (atanf(tdim.mV[0]/distance)*2.f*RAD_TO_DEG*pa)), (U32) 512);
- if (!avatar->mImpostor.isComplete())
- {
- avatar->mImpostor.allocate(resX, resY, GL_RGBA, TRUE, FALSE);
+ if (!for_profile)
+ {
+ if (!avatar->mImpostor.isComplete())
+ {
+ avatar->mImpostor.allocate(resX, resY, GL_RGBA, true);
- if (LLPipeline::sRenderDeferred)
- {
- addDeferredAttachments(avatar->mImpostor, true);
- }
-
- gGL.getTexUnit(0)->bind(&avatar->mImpostor);
- gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- }
- else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
- {
- avatar->mImpostor.resize(resX,resY);
- }
+ if (LLPipeline::sRenderDeferred)
+ {
+ addDeferredAttachments(avatar->mImpostor, true);
+ }
- avatar->mImpostor.bindTarget();
+ gGL.getTexUnit(0)->bind(&avatar->mImpostor);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ }
+ else if (resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
+ {
+ avatar->mImpostor.resize(resX, resY);
+ }
+
+ avatar->mImpostor.bindTarget();
+ }
}
F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
@@ -11066,20 +10160,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLDrawPoolAvatar::sMinimumAlpha = 0.f;
}
- if (preview_avatar)
+ if (preview_avatar || for_profile)
{
- // previews don't care about imposters
- if (LLPipeline::sRenderDeferred)
- {
- renderGeomDeferred(camera);
- renderGeomPostDeferred(camera);
- }
- else
- {
- renderGeom(camera);
- }
+ // previews and profiles don't care about imposters
+ renderGeomDeferred(camera);
+ renderGeomPostDeferred(camera);
}
- else if (LLPipeline::sRenderDeferred)
+ else
{
avatar->mImpostor.clear();
renderGeomDeferred(camera);
@@ -11101,37 +10188,15 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
sImpostorRenderAlphaDepthPass = false;
}
- else
- {
- LLGLEnable scissor(GL_SCISSOR_TEST);
- glScissor(0, 0, resX, resY);
- avatar->mImpostor.clear();
- renderGeom(camera);
-
- // Shameless hack time: render it all again,
- // this time writing the depth
- // values we need to generate the alpha mask below
- // while preserving the alpha-sorted color rendering
- // from the previous pass
- //
- sImpostorRenderAlphaDepthPass = true;
-
- // depth-only here...
- //
- gGL.setColorMask(false,false);
- renderGeom(camera);
-
- sImpostorRenderAlphaDepthPass = false;
- }
LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+ if (!for_profile)
{ //create alpha mask based on depth buffer (grey out if muted)
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
- LL_PROFILER_GPU_ZONEC( "gl.DrawBuffersARB", 0x8000FF );
- glDrawBuffersARB(1, &buff);
+ glDrawBuffers(1, &buff);
}
LLGLDisable blend(GL_BLEND);
@@ -11188,7 +10253,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
gGL.popMatrix();
}
- if (!preview_avatar)
+ if (!preview_avatar && !for_profile)
{
avatar->mImpostor.flush();
avatar->setImpostorDim(tdim);
@@ -11205,7 +10270,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- if (!preview_avatar)
+ if (!preview_avatar && !for_profile)
{
avatar->mNeedsImpostorUpdate = FALSE;
avatar->cacheImpostorValues();
@@ -11214,7 +10279,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar)
LLVertexBuffer::unbind();
LLGLState::checkStates();
- LLGLState::checkTextureChannels();
}
bool LLPipeline::hasRenderBatches(const U32 type) const
@@ -11484,7 +10548,7 @@ void LLPipeline::hideObject( const LLUUID& id )
void LLPipeline::hideDrawable( LLDrawable *pDrawable )
{
pDrawable->setState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
//hide the children
LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -11495,14 +10559,14 @@ void LLPipeline::hideDrawable( LLDrawable *pDrawable )
if ( drawable )
{
drawable->setState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL);
}
}
}
void LLPipeline::unhideDrawable( LLDrawable *pDrawable )
{
pDrawable->clearState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( pDrawable, LLDrawable::REBUILD_ALL, TRUE );
+ markRebuild( pDrawable, LLDrawable::REBUILD_ALL);
//restore children
LLViewerObject::const_child_list_t& child_list = pDrawable->getVObj()->getChildren();
for ( LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
@@ -11513,7 +10577,7 @@ void LLPipeline::unhideDrawable( LLDrawable *pDrawable )
if ( drawable )
{
drawable->clearState( LLDrawable::FORCE_INVISIBLE );
- markRebuild( drawable, LLDrawable::REBUILD_ALL, TRUE );
+ markRebuild( drawable, LLDrawable::REBUILD_ALL);
}
}
}
@@ -11537,9 +10601,9 @@ void LLPipeline::skipRenderingShadows()
for (S32 j = 0; j < 4; j++)
{
- mShadow[j].bindTarget();
- mShadow[j].clear();
- mShadow[j].flush();
+ mRT->shadow[j].bindTarget();
+ mRT->shadow[j].clear();
+ mRT->shadow[j].flush();
}
}
@@ -11555,3 +10619,42 @@ void LLPipeline::handleShadowDetailChanged()
}
}
+class LLOctreeDirty : public OctreeTraveler
+{
+public:
+ virtual void visit(const OctreeNode* state)
+ {
+ LLSpatialGroup* group = (LLSpatialGroup*)state->getListener(0);
+
+ if (group->getSpatialPartition()->mRenderByGroup)
+ {
+ group->setState(LLSpatialGroup::GEOM_DIRTY);
+ gPipeline.markRebuild(group);
+ }
+
+ for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i)
+ {
+ LLSpatialBridge* bridge = *i;
+ traverse(bridge->mOctree);
+ }
+ }
+};
+
+
+void LLPipeline::rebuildDrawInfo()
+{
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLOctreeDirty dirty;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_VOLUME);
+ dirty.traverse(part->mOctree);
+
+ part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
+ dirty.traverse(part->mOctree);
+ }
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 6580c6216c..6e4c9c7a97 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -38,6 +38,7 @@
#include "llgl.h"
#include "lldrawable.h"
#include "llrendertarget.h"
+#include "llreflectionmapmanager.h"
#include <stack>
@@ -50,6 +51,7 @@ class LLVOAvatar;
class LLVOPartGroup;
class LLGLSLShader;
class LLDrawPoolAlpha;
+class LLSettingsSky;
typedef enum e_avatar_skinning_method
{
@@ -95,9 +97,7 @@ public:
void destroyGL();
void restoreGL();
- void resetVertexBuffers();
- void doResetVertexBuffers(bool forced = false);
- void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
+ void requestResizeScreenTexture(); // set flag only, no work, safer for callbacks...
void requestResizeShadowTexture(); // set flag only, no work, safer for callbacks...
void resizeScreenTexture();
@@ -131,12 +131,34 @@ public:
bool allocateScreenBuffer(U32 resX, U32 resY, U32 samples);
bool allocateShadowBuffer(U32 resX, U32 resY);
- void allocatePhysicsBuffer();
-
+ // rebuild all LLVOVolume render batches
+ void rebuildDrawInfo();
+
+ // Clear LLFace mVertexBuffer pointers
void resetVertexBuffers(LLDrawable* drawable);
- void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);
+
+ // perform a profile of the given avatar
+ // if profile_attachments is true, run a profile for each attachment
+ void profileAvatar(LLVOAvatar* avatar, bool profile_attachments = false);
+
+ // generate an impostor for the given avatar
+ // preview_avatar - if true, a preview window render is being performed
+ // for_profile - if true, a profile is being performed, do not update actual impostor
+ // specific_attachment - specific attachment to profile, or nullptr to profile entire avatar
+ void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false, bool for_profile = false, LLViewerObject* specific_attachment = nullptr);
+
void bindScreenToTexture();
void renderFinalize();
+ void copyScreenSpaceReflections(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateLuminance(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateExposure(LLRenderTarget* src, LLRenderTarget* dst);
+ void gammaCorrect(LLRenderTarget* src, LLRenderTarget* dst);
+ void generateGlow(LLRenderTarget* src);
+ void applyFXAA(LLRenderTarget* src, LLRenderTarget* dst);
+ void renderDoF(LLRenderTarget* src, LLRenderTarget* dst);
+ void copyRenderTarget(LLRenderTarget* src, LLRenderTarget* dst);
+ void combineGlow(LLRenderTarget* src, LLRenderTarget* dst);
+ void visualizeBuffers(LLRenderTarget* src, LLRenderTarget* dst, U32 bufferIndex);
void init();
void cleanup();
@@ -167,19 +189,14 @@ public:
void markVisible(LLDrawable *drawablep, LLCamera& camera);
void markOccluder(LLSpatialGroup* group);
- //downsample source to dest, taking the maximum depth value per pixel in source and writing to dest
- // if source's depth buffer cannot be bound for reading, a scratch space depth buffer must be provided
- void downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
-
- void doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space = NULL);
void doOcclusion(LLCamera& camera);
void markNotCulled(LLSpatialGroup* group, LLCamera &camera);
void markMoved(LLDrawable *drawablep, bool damped_motion = false);
void markShift(LLDrawable *drawablep);
void markTextured(LLDrawable *drawablep);
void markGLRebuild(LLGLUpdate* glu);
- void markRebuild(LLSpatialGroup* group, bool priority = false);
- void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, bool priority = false);
+ void markRebuild(LLSpatialGroup* group);
+ void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL);
void markPartitionMove(LLDrawable* drawablep);
void markMeshDirty(LLSpatialGroup* group);
@@ -187,6 +204,8 @@ public:
LLViewerObject* lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
bool pick_transparent,
bool pick_rigged,
+ bool pick_unselectable,
+ bool pick_reflection_probe,
S32* face_hit, // return the face hit
LLVector4a* intersection = NULL, // return the intersection point
LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point
@@ -216,18 +235,12 @@ public:
U32 addObject(LLViewerObject *obj);
void enableShadows(const bool enable_shadows);
- void releaseShadowTargets();
- void releaseShadowTarget(U32 index);
-
-// void setLocalLighting(const bool local_lighting);
-// bool isLocalLightingEnabled() const;
- S32 setLightingDetail(S32 level);
- S32 getLightingDetail() const { return mLightingDetail; }
- S32 getMaxLightingDetail() const;
-
+ void releaseSpotShadowTargets();
+ void releaseSunShadowTargets();
+ void releaseSunShadowTarget(U32 index);
+
bool shadersLoaded();
bool canUseWindLightShaders() const;
- bool canUseWindLightShadersOnObjects() const;
bool canUseAntiAliasing() const;
// phases
@@ -240,7 +253,9 @@ public:
bool visibleObjectsInFrustum(LLCamera& camera);
bool getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
bool getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
- void updateCull(LLCamera& camera, LLCullResult& result, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
+
+ // Populate given LLCullResult with results of a frustum cull of the entire scene against the given LLCamera
+ void updateCull(LLCamera& camera, LLCullResult& result);
void createObjects(F32 max_dtime);
void createObject(LLViewerObject* vobj);
void processPartitionQ();
@@ -261,19 +276,17 @@ public:
void stateSort(LLDrawable* drawablep, LLCamera& camera);
void postSort(LLCamera& camera);
- //update stats for textures in given DrawInfo
- void touchTextures(LLDrawInfo* info);
- void touchTexture(LLViewerTexture* tex, F32 vsize);
-
void forAllVisibleDrawables(void (*func)(LLDrawable*));
- void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
- void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
- void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
- void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderGLTFObjects(U32 type, bool texture = true, bool rigged = false);
+
+ void renderAlphaObjects(bool rigged = false);
+ void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
+ void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false);
- void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);
- void renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture);
+ void renderGroups(LLRenderPass* pass, U32 type, bool texture);
+ void renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture);
void grabReferences(LLCullResult& result);
void clearReferences();
@@ -283,29 +296,37 @@ public:
void checkReferences(LLDrawable* drawable);
void checkReferences(LLDrawInfo* draw_info);
void checkReferences(LLSpatialGroup* group);
-
-
- void renderGeom(LLCamera& camera, bool forceVBOUpdate = false);
- void renderGeomDeferred(LLCamera& camera);
- void renderGeomPostDeferred(LLCamera& camera, bool do_occlusion=true);
+
+ void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false);
+ void renderGeomPostDeferred(LLCamera& camera);
void renderGeomShadow(LLCamera& camera);
+ void bindLightFunc(LLGLSLShader& shader);
+
+ // bind shadow maps
+ // if setup is true, wil lset texture compare mode function and filtering options
+ void bindShadowMaps(LLGLSLShader& shader);
+ void bindDeferredShaderFast(LLGLSLShader& shader);
void bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target = nullptr);
void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep);
void unbindDeferredShader(LLGLSLShader& shader);
- void renderDeferredLighting(LLRenderTarget* light_target);
+
+ // set env_mat parameter in given shader
+ void setEnvMat(LLGLSLShader& shader);
+
+ void bindReflectionProbes(LLGLSLShader& shader);
+ void unbindReflectionProbes(LLGLSLShader& shader);
+
+ void renderDeferredLighting();
void postDeferredGammaCorrect(LLRenderTarget* screen_target);
- void generateWaterReflection(LLCamera& camera);
void generateSunShadow(LLCamera& camera);
- LLRenderTarget* getShadowTarget(U32 i);
+ LLRenderTarget* getSunShadowTarget(U32 i);
+ LLRenderTarget* getSpotShadowTarget(U32 i);
- void generateHighlight(LLCamera& camera);
void renderHighlight(const LLViewerObject* obj, F32 fade);
- void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; }
-
-
- void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool use_shader, bool use_occlusion, U32 target_width);
+
+ void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, LLCullResult& result, bool depth_clamp);
void renderHighlights();
void renderDebug();
void renderPhysicsDisplay();
@@ -318,10 +339,9 @@ public:
S32 getLightCount() const { return mLights.size(); }
void calcNearbyLights(LLCamera& camera);
- void setupHWLights(LLDrawPool* pool);
+ void setupHWLights();
void setupAvatarLights(bool for_edit = false);
void enableLights(U32 mask);
- void enableLightsStatic();
void enableLightsDynamic();
void enableLightsAvatar();
void enableLightsPreview();
@@ -341,8 +361,8 @@ public:
LLCullResult::sg_iterator beginRiggedAlphaGroups();
LLCullResult::sg_iterator endRiggedAlphaGroups();
-
- void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
+ void addTrianglesDrawn(S32 index_count);
+ void recordTrianglesDrawn();
bool hasRenderDebugFeatureMask(const U32 mask) const { return bool(mRenderDebugFeatureMask & mask); }
bool hasRenderDebugMask(const U64 mask) const { return bool(mRenderDebugMask & mask); }
@@ -354,6 +374,8 @@ public:
bool hasRenderType(const U32 type) const;
bool hasAnyRenderType(const U32 type, ...) const;
+ static bool isWaterClip();
+
void setRenderTypeMask(U32 type, ...);
// This is equivalent to 'setRenderTypeMask'
//void orRenderTypeMask(U32 type, ...);
@@ -414,8 +436,6 @@ public:
static void setRenderHighlightTextureChannel(LLRender::eTexIndex channel); // sets which UV setup to display in highlight overlay
static void updateRenderTransparentWater();
- static void updateRenderBump();
- static void updateRenderDeferred();
static void refreshCachedSettings();
void addDebugBlip(const LLVector3& position, const LLColor4& color);
@@ -427,11 +447,13 @@ public:
void restoreHiddenObject( const LLUUID& id );
void handleShadowDetailChanged();
+ LLReflectionMapManager mReflectionMapManager;
+
private:
void unloadShaders();
void addToQuickLookup( LLDrawPool* new_poolp );
void removeFromQuickLookup( LLDrawPool* poolp );
- bool updateDrawableGeom(LLDrawable* drawable, bool priority);
+ bool updateDrawableGeom(LLDrawable* drawable);
void assertInitializedDoError();
bool assertInitialized() { const bool is_init = isInit(); if (!is_init) assertInitializedDoError(); return is_init; };
void connectRefreshCachedSettingsSafe(const std::string name);
@@ -446,7 +468,6 @@ public:
// Following are pool types (some are also object types)
RENDER_TYPE_SKY = LLDrawPool::POOL_SKY,
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_GRASS = LLDrawPool::POOL_GRASS,
@@ -458,10 +479,13 @@ public:
RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR,
RENDER_TYPE_CONTROL_AV = LLDrawPool::POOL_CONTROL_AV, // Animesh
RENDER_TYPE_TREE = LLDrawPool::POOL_TREE,
- RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE,
RENDER_TYPE_VOIDWATER = LLDrawPool::POOL_VOIDWATER,
RENDER_TYPE_WATER = LLDrawPool::POOL_WATER,
+ RENDER_TYPE_GLTF_PBR = LLDrawPool::POOL_GLTF_PBR,
+ RENDER_TYPE_GLTF_PBR_ALPHA_MASK = LLDrawPool::POOL_GLTF_PBR_ALPHA_MASK,
RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA,
+ RENDER_TYPE_ALPHA_PRE_WATER = LLDrawPool::POOL_ALPHA_PRE_WATER,
+ RENDER_TYPE_ALPHA_POST_WATER = LLDrawPool::POOL_ALPHA_POST_WATER,
RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW,
RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE,
RENDER_TYPE_PASS_SIMPLE_RIGGED = LLRenderPass::PASS_SIMPLE_RIGGED,
@@ -482,6 +506,8 @@ public:
RENDER_TYPE_PASS_POST_BUMP_RIGGED = LLRenderPass::PASS_POST_BUMP_RIGGED,
RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
RENDER_TYPE_PASS_GLOW_RIGGED = LLRenderPass::PASS_GLOW_RIGGED,
+ RENDER_TYPE_PASS_GLTF_GLOW = LLRenderPass::PASS_GLTF_GLOW,
+ RENDER_TYPE_PASS_GLTF_GLOW_RIGGED = LLRenderPass::PASS_GLTF_GLOW_RIGGED,
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
RENDER_TYPE_PASS_ALPHA_MASK_RIGGED = LLRenderPass::PASS_ALPHA_MASK_RIGGED,
@@ -519,6 +545,10 @@ public:
RENDER_TYPE_PASS_NORMSPEC_MASK_RIGGED = LLRenderPass::PASS_NORMSPEC_MASK_RIGGED,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE = LLRenderPass::PASS_NORMSPEC_EMISSIVE,
RENDER_TYPE_PASS_NORMSPEC_EMISSIVE_RIGGED = LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED,
+ RENDER_TYPE_PASS_GLTF_PBR = LLRenderPass::PASS_GLTF_PBR,
+ RENDER_TYPE_PASS_GLTF_PBR_RIGGED = LLRenderPass::PASS_GLTF_PBR_RIGGED,
+ RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK,
+ RENDER_TYPE_PASS_GLTF_PBR_ALPHA_MASK_RIGGED = LLRenderPass::PASS_GLTF_PBR_ALPHA_MASK_RIGGED,
// Following are object types (only used in drawable mRenderType)
RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES,
RENDER_TYPE_VOLUME,
@@ -566,17 +596,17 @@ public:
RENDER_DEBUG_SCULPTED = 0x00080000,
RENDER_DEBUG_AVATAR_VOLUME = 0x00100000,
RENDER_DEBUG_AVATAR_JOINTS = 0x00200000,
- RENDER_DEBUG_BUILD_QUEUE = 0x00400000,
RENDER_DEBUG_AGENT_TARGET = 0x00800000,
RENDER_DEBUG_UPDATE_TYPE = 0x01000000,
RENDER_DEBUG_PHYSICS_SHAPES = 0x02000000,
RENDER_DEBUG_NORMALS = 0x04000000,
RENDER_DEBUG_LOD_INFO = 0x08000000,
- RENDER_DEBUG_RENDER_COMPLEXITY = 0x10000000,
RENDER_DEBUG_ATTACHMENT_BYTES = 0x20000000, // not used
RENDER_DEBUG_TEXEL_DENSITY = 0x40000000,
RENDER_DEBUG_TRIANGLE_COUNT = 0x80000000,
- RENDER_DEBUG_IMPOSTORS = 0x100000000
+ RENDER_DEBUG_IMPOSTORS = 0x100000000,
+ RENDER_DEBUG_REFLECTION_PROBES = 0x200000000,
+ RENDER_DEBUG_PROBE_UPDATES = 0x400000000
};
public:
@@ -599,22 +629,20 @@ public:
S32 mNumVisibleFaces;
+ S32 mPoissonOffset;
+
static S32 sCompiles;
static bool sShowHUDAttachments;
static bool sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.
static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write
- static bool sDelayVBUpdate;
static bool sAutoMaskAlphaDeferred;
static bool sAutoMaskAlphaNonDeferred;
static bool sRenderTransparentWater;
- static bool sRenderBump;
static bool sBakeSunlight;
static bool sNoAlpha;
- static bool sUseTriStrips;
static bool sUseFarClip;
static bool sShadowRender;
- static bool sWaterReflections;
static bool sDynamicLOD;
static bool sPickAvatar;
static bool sReflectionRender;
@@ -624,50 +652,82 @@ public:
static bool sUnderWaterRender;
static bool sRenderGlow;
static bool sTextureBindTest;
- static bool sRenderFrameTest;
static bool sRenderAttachedLights;
static bool sRenderAttachedParticles;
static bool sRenderDeferred;
+ static bool sReflectionProbesEnabled;
static S32 sVisibleLightCount;
static bool sRenderingHUDs;
static F32 sDistortionWaterClipPlaneMargin;
static LLTrace::EventStatHandle<S64> sStatBatchSize;
- //screen texture
- U32 mScreenWidth;
- U32 mScreenHeight;
-
- LLRenderTarget mScreen;
- LLRenderTarget mUIScreen;
- LLRenderTarget mDeferredScreen;
- LLRenderTarget mFXAABuffer;
- LLRenderTarget mEdgeMap;
- LLRenderTarget mDeferredDepth;
- LLRenderTarget mOcclusionDepth;
- LLRenderTarget mDeferredLight;
- LLRenderTarget mHighlight;
- LLRenderTarget mPhysicsDisplay;
+ class RenderTargetPack
+ {
+ public:
+ U32 width = 0;
+ U32 height = 0;
+
+ //screen texture
+ LLRenderTarget screen;
+ LLRenderTarget uiScreen;
+ LLRenderTarget deferredScreen;
+ LLRenderTarget fxaaBuffer;
+ LLRenderTarget edgeMap;
+ LLRenderTarget deferredLight;
+
+ //sun shadow map
+ LLRenderTarget shadow[4];
+ };
+
+ // main full resoltuion render target
+ RenderTargetPack mMainRT;
+
+ // auxillary 512x512 render target pack
+ RenderTargetPack mAuxillaryRT;
+
+ // currently used render target pack
+ RenderTargetPack* mRT;
+
+ LLRenderTarget mSpotShadow[2];
+
+ LLRenderTarget mPbrBrdfLut;
+
+ // copy of the color/depth buffer just before gamma correction
+ // for use by SSR
+ LLRenderTarget mSceneMap;
+
+ // exposure map for getting average color in scene
+ LLRenderTarget mLuminanceMap;
+ LLRenderTarget mExposureMap;
+ LLRenderTarget mLastExposure;
+
+ // tonemapped and gamma corrected render ready for post
+ LLRenderTarget mPostMap;
LLCullResult mSky;
LLCullResult mReflectedObjects;
LLCullResult mRefractedObjects;
- //utility buffer for rendering post effects, gets abused by renderDeferredLighting
+ //utility buffers for rendering post effects
LLPointer<LLVertexBuffer> mDeferredVB;
+ // a single triangle that covers the whole screen
+ LLPointer<LLVertexBuffer> mScreenTriangleVB;
+
//utility buffer for rendering cubes, 8 vertices are corners of a cube [-1, 1]
LLPointer<LLVertexBuffer> mCubeVB;
- //sun shadow map
- LLRenderTarget mShadow[6];
- LLRenderTarget mShadowOcclusion[6];
+ //list of currently bound reflection maps
+ std::vector<LLReflectionMap*> mReflectionMaps;
+
std::vector<LLVector3> mShadowFrustPoints[4];
LLVector4 mShadowError;
LLVector4 mShadowFOV;
LLVector3 mShadowFrustOrigin[4];
LLCamera mShadowCamera[8];
LLVector3 mShadowExtents[4][2];
+ // TODO : separate Sun Shadow and Spot Shadow matrices
glh::matrix4f mSunShadowMatrix[6];
glh::matrix4f mShadowModelview[6];
glh::matrix4f mShadowProjection[6];
@@ -681,9 +741,6 @@ public:
LLVector4 mSunOrthoClipPlanes;
LLVector2 mScreenScale;
- //water reflection texture
- LLRenderTarget mWaterRef;
-
//water distortion texture (refraction)
LLRenderTarget mWaterDis;
@@ -754,7 +811,7 @@ protected:
};
typedef std::set< Light, Light::compare > light_set_t;
- LLDrawable::drawable_set_t mLights;
+ LLDrawable::ordered_drawable_set_t mLights;
light_set_t mNearbyLights; // lights near camera
LLColor4 mHWLightColors[8];
@@ -763,9 +820,7 @@ protected:
// Different queues of drawables being processed.
//
LLDrawable::drawable_list_t mBuildQ1; // priority
- LLDrawable::drawable_list_t mBuildQ2; // non-priority
LLSpatialGroup::sg_vector_t mGroupQ1; //priority
- LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority
LLSpatialGroup::sg_vector_t mGroupSaveQ1; // a place to save mGroupQ1 until it is safe to unref
@@ -774,7 +829,6 @@ protected:
LLDrawable::drawable_list_t mPartitionQ; //drawables that need to update their spatial partition radius
- bool mGroupQ2Locked;
bool mGroupQ1Locked;
bool mResetVertexBuffers; //if true, clear vertex buffers on next update
@@ -810,9 +864,6 @@ protected:
}
};
- std::set<HighlightItem> mHighlightSet;
- LLPointer<LLDrawable> mHighlightObject;
-
//////////////////////////////////////////////////
//
// Draw pools are responsible for storing all rendered data,
@@ -846,21 +897,23 @@ protected:
// For quick-lookups into mPools (mapped by texture pointer)
std::map<uintptr_t, LLDrawPool*> mTerrainPools;
std::map<uintptr_t, LLDrawPool*> mTreePools;
- LLDrawPoolAlpha* mAlphaPool;
- LLDrawPool* mSkyPool;
- LLDrawPool* mTerrainPool;
- LLDrawPool* mWaterPool;
- LLDrawPool* mGroundPool;
- LLRenderPass* mSimplePool;
- LLRenderPass* mGrassPool;
- LLRenderPass* mAlphaMaskPool;
- LLRenderPass* mFullbrightAlphaMaskPool;
- LLRenderPass* mFullbrightPool;
- LLDrawPool* mInvisiblePool;
- LLDrawPool* mGlowPool;
- LLDrawPool* mBumpPool;
- LLDrawPool* mMaterialsPool;
- LLDrawPool* mWLSkyPool;
+ LLDrawPoolAlpha* mAlphaPoolPreWater = nullptr;
+ LLDrawPoolAlpha* mAlphaPoolPostWater = nullptr;
+ LLDrawPool* mSkyPool = nullptr;
+ LLDrawPool* mTerrainPool = nullptr;
+ LLDrawPool* mWaterPool = nullptr;
+ LLRenderPass* mSimplePool = nullptr;
+ LLRenderPass* mGrassPool = nullptr;
+ LLRenderPass* mAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightAlphaMaskPool = nullptr;
+ LLRenderPass* mFullbrightPool = nullptr;
+ LLDrawPool* mGlowPool = nullptr;
+ LLDrawPool* mBumpPool = nullptr;
+ LLDrawPool* mMaterialsPool = nullptr;
+ LLDrawPool* mWLSkyPool = nullptr;
+ LLDrawPool* mPBROpaquePool = nullptr;
+ LLDrawPool* mPBRAlphaMaskPool = nullptr;
+
// Note: no need to keep an quick-lookup to avatar pools, since there's only one per avatar
public:
@@ -886,7 +939,6 @@ protected:
U32 mLightMask;
U32 mLightMovingMask;
- S32 mLightingDetail;
static bool sRenderPhysicalBeacons;
static bool sRenderMOAPBeacons;
@@ -916,7 +968,6 @@ public:
static S32 RenderShadowSplits;
static bool RenderDeferredSSAO;
static F32 RenderShadowResolutionScale;
- static bool RenderLocalLights;
static bool RenderDelayCreation;
static bool RenderAnimateRes;
static bool FreezeTime;
@@ -944,6 +995,7 @@ public:
static S32 RenderGlowIterations;
static F32 RenderGlowWidth;
static F32 RenderGlowStrength;
+ static bool RenderGlowNoise;
static bool RenderDepthOfField;
static bool RenderDepthOfFieldInEditMode;
static F32 CameraFocusTransitionTime;
@@ -968,11 +1020,7 @@ public:
static LLVector3 RenderShadowGaussian;
static F32 RenderShadowBlurDistFactor;
static bool RenderDeferredAtmospheric;
- static S32 RenderReflectionDetail;
static F32 RenderHighlightFadeTime;
- static LLVector3 RenderShadowClipPlanes;
- static LLVector3 RenderShadowOrthoClipPlanes;
- static LLVector3 RenderShadowNearDist;
static F32 RenderFarClip;
static LLVector3 RenderShadowSplitExponent;
static F32 RenderShadowErrorCutoff;
@@ -981,6 +1029,14 @@ public:
static F32 CameraMaxCoF;
static F32 CameraDoFResScale;
static F32 RenderAutoHideSurfaceAreaLimit;
+ static bool RenderScreenSpaceReflections;
+ static S32 RenderScreenSpaceReflectionIterations;
+ static F32 RenderScreenSpaceReflectionRayStep;
+ static F32 RenderScreenSpaceReflectionDistanceBias;
+ static F32 RenderScreenSpaceReflectionDepthRejectBias;
+ static F32 RenderScreenSpaceReflectionAdaptiveStepMultiplier;
+ static S32 RenderScreenSpaceReflectionGlossySamples;
+ static S32 RenderBufferVisualization;
};
void render_bbox(const LLVector3 &min, const LLVector3 &max);
diff --git a/indra/newview/skins/default/textures/default_irradiance.png b/indra/newview/skins/default/textures/default_irradiance.png
new file mode 100644
index 0000000000..899e0ddf2a
--- /dev/null
+++ b/indra/newview/skins/default/textures/default_irradiance.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/icons/Inv_Material.png b/indra/newview/skins/default/textures/icons/Inv_Material.png
new file mode 100644
index 0000000000..f5918ceaed
--- /dev/null
+++ b/indra/newview/skins/default/textures/icons/Inv_Material.png
Binary files differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index aa99fe38cd..2126db32df 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -315,6 +315,7 @@ with the same filename but different name
<texture name="Inv_LostClosed" file_name="icons/Inv_LostClosed.png" preload="false" />
<texture name="Inv_LostOpen" file_name="icons/Inv_LostOpen.png" preload="false" />
<texture name="Inv_Landmark" file_name="icons/Inv_Landmark.png" preload="false" />
+ <texture name="Inv_Material" file_name="icons/Inv_Material.png" preload="false" />
<texture name="Inv_Mesh" file_name="icons/Inv_Mesh.png" preload="false" />
<texture name="Inv_Notecard" file_name="icons/Inv_Notecard.png" preload="false" />
<texture name="Inv_Object" file_name="icons/Inv_Object.png" preload="false" />
diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
index bf97d32a5c..91a1dffcb5 100644
--- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
+++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
@@ -10,6 +10,9 @@
min_height="275"
single_instance="true"
can_resize="false">
+ <string name="hdr_string">HDR Scale:</string>
+ <string name="brightness_string">Brightness:</string>
+ <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
<layout_stack name="outer_stack"
width="845"
height="275"
@@ -245,13 +248,33 @@
top_pad="5"
width="185"
can_edit_text="true"/>
+ <text follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_pad="15"
+ width="180">Reflection Probe Ambiance:</text>
+ <slider decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="10"
+ name="probe_ambiance"
+ tool_tip="Intensity of environment based indirect lighting. At zero HDR scale becomes Brightness"
+ top_pad="5"
+ width="185"
+ can_edit_text="true"/>
<text follows="left|top"
name="scene_gamma_label"
height="10"
layout="topleft"
left_delta="-5"
top_pad="15"
- width="80">Scene Gamma:</text>
+ width="80">Brightness:</text>
<slider decimal_digits="2"
follows="left|top"
height="16"
diff --git a/indra/newview/skins/default/xui/en/floater_build_options.xml b/indra/newview/skins/default/xui/en/floater_build_options.xml
index 38428b36fc..7278e55d57 100644
--- a/indra/newview/skins/default/xui/en/floater_build_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_build_options.xml
@@ -46,14 +46,14 @@
name="GridSubUnit"
top_pad="0"
width="200" />
- <check_box
+ <!-- <check_box
control_name="GridCrossSections"
height="16"
label="View cross-sections"
layout="topleft"
name="GridCrossSection"
top_pad="5"
- width="200" />
+ width="200" />-->
<text
type="string"
length="1"
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 431c33a339..7aa31bed71 100644
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -170,6 +170,20 @@
name="icon_setting"
tool_tip="Environment settings"
left_pad="2" />
+ <check_box
+ control_name="BulkChangeIncludeMaterials"
+ height="16"
+ name="check_materials"
+ top_pad="5"
+ left="245"
+ width="16" />
+ <icon
+ height="16"
+ image_name="Inv_Material"
+ mouse_opaque="true"
+ name="icon_materials"
+ tool_tip="Materials"
+ left_pad="2" />
<button
height="23"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
new file mode 100644
index 0000000000..63eaffde18
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_combobox_ok_cancel.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<floater
+ legacy_header_height="18"
+ height="130"
+ min_height="130"
+ width="270"
+ min_width="270"
+ layout="topleft"
+ name="floater_combo"
+ title="floater_combo"
+ help_topic="floater_combo"
+ can_resize="false"
+ can_minimize="false">
+ <text
+ follows="top|left|right"
+ height="10"
+ layout="topleft"
+ left="20"
+ name="combo_text"
+ top="30"
+ width="200">
+ Select an option:
+ </text>
+ <combo_box
+ follows="top|left"
+ layout="topleft"
+ left="20"
+ name="combo_options"
+ top_delta="20"
+ width="230"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="OK"
+ layout="topleft"
+ top_delta="40"
+ left="20"
+ name="combo_ok"
+ width="90"/>
+ <button
+ follows="top|left"
+ height="23"
+ label="Cancel"
+ layout="topleft"
+ left_pad="50"
+ name="combo_cancel"
+ width="90"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
index d783d1e23c..e91efb89b2 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_view_finder.xml
@@ -2,7 +2,7 @@
<floater
legacy_header_height="18"
can_minimize="false"
- height="466"
+ height="486"
layout="topleft"
name="Inventory Finder"
help_topic="inventory_finder"
@@ -95,12 +95,29 @@
width="126" />
<icon
height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left="8"
+ mouse_opaque="true"
+ name="icon_material"
+ top="122"
+ width="16" />
+ <check_box
+ height="16"
+ label="Materials"
+ layout="topleft"
+ left_pad="2"
+ name="check_material"
+ top_delta="0"
+ width="126" />
+ <icon
+ height="16"
image_name="Inv_Notecard"
layout="topleft"
left="8"
mouse_opaque="true"
name="icon_notecard"
- top="122"
+ top="142"
width="16" />
<check_box
height="16"
@@ -117,7 +134,7 @@
left="8"
mouse_opaque="true"
name="icon_object"
- top="142"
+ top="162"
width="16" />
<check_box
height="16"
@@ -134,7 +151,7 @@
left="8"
mouse_opaque="true"
name="icon_script"
- top="162"
+ top="182"
width="16" />
<check_box
height="16"
@@ -151,7 +168,7 @@
left="8"
mouse_opaque="true"
name="icon_sound"
- top="182"
+ top="202"
width="16" />
<check_box
height="16"
@@ -168,7 +185,7 @@
left="8"
mouse_opaque="true"
name="icon_texture"
- top="202"
+ top="222"
width="16" />
<check_box
height="16"
@@ -185,7 +202,7 @@
left="8"
mouse_opaque="true"
name="icon_snapshot"
- top="222"
+ top="242"
width="16" />
<check_box
height="16"
@@ -202,7 +219,7 @@
left="8"
mouse_opaque="true"
name="icon_settings"
- top="242"
+ top="262"
width="16" />
<check_box
height="16"
@@ -220,7 +237,7 @@
layout="topleft"
left="8"
name="All"
- top="262"
+ top="282"
width="100" />
<button
height="20"
@@ -274,7 +291,7 @@
width="260"/>
<check_box
height="16"
- top="352"
+ top="372"
label="Since Logoff"
layout="topleft"
left_delta="0"
@@ -290,7 +307,7 @@
layout="topleft"
left_delta="0"
name="- OR -"
- top="370"
+ top="390"
width="144">
- OR -
</text>
@@ -298,7 +315,7 @@
height="16"
layout="topleft"
name="date_search_direction"
- top="388"
+ top="408"
left="8"
width="270">
<radio_item
@@ -368,6 +385,6 @@
layout="topleft"
name="Close"
right="-6"
- top="434"
+ top="454"
width="76" />
</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_live_material_editor.xml b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml
new file mode 100644
index 0000000000..5b7dab6a52
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_live_material_editor.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ height="790"
+ width="256"
+ min_height="500"
+ min_width="256"
+ layout="topleft"
+ name="material editor"
+ help_topic="material_editor"
+ single_instance="true"
+ title="Editing Material">
+ <scroll_container
+ name="materials_scroll"
+ top="18"
+ left="4"
+ height="768"
+ width="250"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ tab_stop="true"
+ border="false"
+ reserve_scroll_corner="false">
+ <panel
+ name="panel_material"
+ filename="panel_gltf_material.xml"
+ layout="topleft"
+ follows="left|top|right"
+ border="false"
+ top="0"
+ left="0"
+ height="768"
+ width="236" />
+ </scroll_container>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml
new file mode 100644
index 0000000000..a6a401f43e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ height="891"
+ width="256"
+ min_height="500"
+ min_width="256"
+ layout="topleft"
+ name="material editor"
+ help_topic="material_editor"
+ title="[MATERIAL_NAME]">
+ <string name="no_upload_fee_string">no upload fee</string>
+ <string name="upload_fee_string">L$[FEE] upload fee</string>
+ <string name="material_selection_title">Material selection</string>
+ <string name="material_selection_text">Select material:</string>
+ <string name="material_batch_import_text">--- Bulk Upload All ---</string>
+ <string name="material_override_title">Editing Material</string>
+
+ <scroll_container
+ name="materials_scroll"
+ top="18"
+ left="4"
+ height="768"
+ width="250"
+ follows="all"
+ layout="topleft"
+ color="DkGray2"
+ opaque="true"
+ tab_stop="true"
+ reserve_scroll_corner="false">
+ <panel
+ name="panel_material"
+ filename="panel_gltf_material.xml"
+ layout="topleft"
+ follows="left|top|right"
+ border="false"
+ top="0"
+ left="0"
+ height="768"
+ width="236" />
+ </scroll_container>
+
+ <panel
+ follows="right|bottom"
+ width="246"
+ height="97"
+ layout="bottomright"
+ top_pad="0"
+ left="5"
+ name="button_panel"
+ >
+ <text
+ type="string"
+ name="unsaved_changes"
+ font.style="BOLD"
+ text_color="DrYellow"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="200"
+ layout="topleft"
+ left="10"
+ top="0"
+ >
+ Unsaved changes
+ </text>
+ <button
+ follows="left|top"
+ height="25"
+ label="Save"
+ enabled="false"
+ layout="topleft"
+ name="save"
+ top_pad="7"
+ left="0"
+ width="120" />
+ <button
+ follows="left|top"
+ height="25"
+ label="Save As..."
+ enabled="false"
+ layout="topleft"
+ name="save_as"
+ top_delta="0"
+ left_pad="6"
+ width="120" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="220"
+ layout="topleft"
+ left="10"
+ top_pad="5"
+ name="total_upload_fee"
+ >
+ Total upload fee: L$ [FEE]
+ </text>
+
+ <view_border
+ bevel_style="none"
+ height="0"
+ layout="topleft"
+ left="0"
+ name="button_border"
+ top_pad="7"
+ width="246"/>
+
+ <button
+ follows="left|top"
+ height="25"
+ label="Cancel"
+ layout="topleft"
+ name="cancel"
+ top_pad="7"
+ left="61"
+ width="121" />
+ </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_my_environments.xml b/indra/newview/skins/default/xui/en/floater_my_environments.xml
index 4ff25de5e2..8c9c450d7c 100644
--- a/indra/newview/skins/default/xui/en/floater_my_environments.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_environments.xml
@@ -120,7 +120,7 @@
follows="all"
layout="topleft"
name="pnl_settings"
- filter_asset_type="settings"/>
+ filter_asset_types="settings"/>
</panel>
</layout_panel>
<layout_panel
diff --git a/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml
index 5f0eeab71c..c8726d36b4 100644
--- a/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml
+++ b/indra/newview/skins/default/xui/en/floater_new_feature_notification.xml
@@ -20,6 +20,15 @@ New inventory features
You can now add preview images to inventory items and view a folder in its own window.
Learn more in this [https://community.secondlife.com/blogs/entry/13637-new-features-inventory-item-preview-and-single-folder-view/ blogpost]
</floater.string>
+ <floater.string name="title_txt_gltf">
+New GLTF PBR materials support
+ </floater.string>
+ <floater.string name="description_txt_gltf">
+You can now use expanded material support with the ability to import and edit GLTF Physically Based Rendering (PBR) Materials.
+In order to support the addition of the GLTF format, some areas in the viewer may appear darker than usual.
+
+Learn more about [https://wiki.secondlife.com/wiki/PBR_Materials Physically Based Rendering (PBR)]
+ </floater.string>
<text
type="string"
length="1"
@@ -37,7 +46,7 @@ New feature
<text
type="string"
length="1"
- follows="top|left|right"
+ follows="top|left|right|bottom"
text_color="White"
layout="topleft"
left="10"
diff --git a/indra/newview/skins/default/xui/en/floater_perms_default.xml b/indra/newview/skins/default/xui/en/floater_perms_default.xml
index 49dc719a24..9ca61671e1 100644
--- a/indra/newview/skins/default/xui/en/floater_perms_default.xml
+++ b/indra/newview/skins/default/xui/en/floater_perms_default.xml
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<floater
legacy_header_height="18"
- height="250"
+ height="266"
layout="topleft"
name="perms default"
help_topic="perms_default"
@@ -10,7 +10,7 @@
width="700">
<panel
follows="left|top|right|bottom"
- height="200"
+ height="216"
label="Default Permissions"
layout="topleft"
left="10"
@@ -549,6 +549,70 @@
left_pad="0"
top_delta="0"
width="100" />
+ <text
+ name="label_14"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="0"
+ tool_tip="Set default permissions for when GLTF Materials are created"
+ width="100">
+ Materials
+ </text>
+ <icon
+ follows="left|top"
+ height="16"
+ image_name="Inv_Material"
+ layout="topleft"
+ left_pad="2"
+ width="18"/>
+ <check_box
+ control_name="MaterialsNextOwnerCopy"
+ height="16"
+ layout="topleft"
+ name="env_material_c"
+ left_pad="45"
+ top_delta="0"
+ width="100">
+ <check_box.commit_callback
+ function="PermsDefault.Copy"
+ parameter="Materials" />
+ </check_box>
+ <check_box
+ control_name="MaterialsNextOwnerModify"
+ height="16"
+ layout="topleft"
+ name="env_materials_m"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ enabled_control="MaterialsNextOwnerCopy"
+ control_name="MaterialsNextOwnerTransfer"
+ height="16"
+ layout="topleft"
+ name="env_materials_t"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
+ <check_box
+ control_name="MaterialsShareWithGroup"
+ height="16"
+ layout="topleft"
+ name="env_materials_s"
+ left_pad="0"
+ top_delta="0"
+ width="120" />
+ <check_box
+ control_name="MaterialsEveryoneCopy"
+ height="16"
+ layout="topleft"
+ name="env_materials_e"
+ left_pad="0"
+ top_delta="0"
+ width="100" />
</panel>
<button
height="20"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 11c2d11987..bc237322af 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -273,68 +273,6 @@
Hardware
</text>
- <slider
- control_name="TextureMemory"
- decimal_digits="0"
- follows="left|top"
- height="16"
- increment="16"
- initial_value="32"
- label="Texture Memory (MB):"
- label_width="185"
- layout="topleft"
- left="30"
- max_val="4096"
- name="GraphicsCardTextureMemory"
- tool_tip="Amount of memory to allocate for textures. Defaults to video card memory. Reducing this may improve performance but may also make textures blurry."
- top_delta="16"
- width="335" />
-
- <slider
- control_name="RenderFogRatio"
- follows="left|top"
- height="16"
- initial_value="4"
- decimal_digits="1"
- label="Fog Distance Ratio:"
- label_width="185"
- layout="topleft"
- left="30"
- name="fog"
- min_val="0.5"
- max_val="10"
- increment="0.1"
- top_delta="16"
- width="332" />
-
- <slider
- control_name="RenderGamma"
- follows="left|top"
- height="16"
- initial_value="1"
- decimal_digits="2"
- label="Gamma:"
- label_width="185"
- layout="topleft"
- left="30"
- name="gamma"
- min_val="0"
- max_val="2"
- increment="0.01"
- top_delta="16"
- width="332" />
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- left="30"
- name="(brightness, lower is brighter)"
- top_delta="16"
- width="260">
- (0 = default brightness, lower = brighter)
- </text>
<check_box
control_name="RenderAnisotropic"
@@ -602,141 +540,6 @@
function="Pref.RenderOptionUpdate" />
</check_box>
- <check_box
- control_name="RenderObjectBump"
- height="16"
- initial_value="true"
- label="Bump mapping and shiny"
- layout="topleft"
- left="420"
- name="BumpShiny"
- top_delta="16"
- width="300">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
- control_name="RenderLocalLights"
- height="16"
- initial_value="true"
- label="Local Lights"
- layout="topleft"
- left="420"
- name="LocalLights"
- top_delta="16"
- width="300" />
-
- <slider
- control_name="RenderTerrainDetail"
- follows="left|top"
- height="16"
- label="Terrain Detail:"
- label_width="165"
- layout="topleft"
- left="440"
- show_text="false"
- initial_value="0"
- increment="1"
- min_val="0"
- max_val="1"
- name="TerrainDetail"
- top_delta="16"
- width="280" >
- <slider.commit_callback
- function="Pref.UpdateSliderText"
- parameter="TerrainDetail" />
- </slider>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- top_delta="0"
- left_delta="284"
- name="TerrainDetailText"
- text_readonly_color="LabelDisabledColor"
- width="65">
- Low
- </text>
-
- <check_box
- control_name="RenderAvatarCloth"
- height="16"
- initial_value="true"
- label="Avatar cloth"
- layout="topleft"
- left="440"
- name="AvatarCloth"
- top_delta="16"
- width="280" />
-
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- name="ReflectionsText"
- text_readonly_color="LabelDisabledColor"
- top_delta="16"
- left="440"
- width="128">
- Water Reflections:
- </text>
- <combo_box
- control_name="RenderReflectionDetail"
- height="18"
- layout="topleft"
- left_delta="170"
- top_delta="0"
- name="Reflections"
- width="150">
- <combo_box.item
- label="None; opaque"
- name="0"
- value="-2"/>
- <combo_box.item
- label="None; transparent"
- name="0"
- value="-1"/>
- <combo_box.item
- label="Minimal"
- name="0"
- value="0"/>
- <combo_box.item
- label="Terrain and trees"
- name="1"
- value="1"/>
- <combo_box.item
- label="All static objects"
- name="2"
- value="2"/>
- <combo_box.item
- label="All avatars and objects"
- name="3"
- value="3"/>
- <combo_box.item
- label="Everything"
- name="4"
- value="4"/>
- </combo_box>
-
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="440"
- name="WindLightUseAtmosShaders"
- top_delta="16"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
<slider
control_name="WLSkyDetail"
decimal_digits="0"
@@ -747,7 +550,7 @@
label="Sky:"
label_width="145"
layout="topleft"
- left="460"
+ left="420"
min_val="16"
max_val="128"
name="SkyMeshDetail"
@@ -773,26 +576,12 @@
</text>
<check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="460"
- name="UseLightShaders"
- top_delta="16"
- width="260">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
control_name="RenderDeferredSSAO"
height="16"
initial_value="true"
- label="Ambient Occlusion"
+ label="Screen Space Ambient Occlusion"
layout="topleft"
- left="480"
+ left="420"
name="UseSSAO"
top_delta="16"
width="240">
@@ -806,7 +595,7 @@
initial_value="true"
label="Depth of Field"
layout="topleft"
- left="480"
+ left="420"
name="UseDoF"
top_delta="16"
width="240">
@@ -814,29 +603,13 @@
function="Pref.RenderOptionUpdate" />
</check_box>
- <!--
- <check_box
- control_name="RenderUseAdvancedAtmospherics"
- height="16"
- initial_value="true"
- label="Advanced Atmospherics"
- layout="topleft"
- left="480"
- name="UseAdvancedAtmo"
- top_delta="16"
- width="240">
- <check_box.commit_callback
- function="Pref.AdvancedAtmosphericsEnable" />
- </check_box>
- -->
-
<text
type="string"
length="1"
follows="left|top"
height="16"
layout="topleft"
- left="480"
+ left="420"
name="RenderShadowDetailText"
text_readonly_color="LabelDisabledColor"
top_delta="16"
@@ -864,15 +637,124 @@
name="2"
value="2"/>
</combo_box>
+
+ <check_box
+ control_name="RenderScreenSpaceReflections"
+ height="16"
+ initial_value="true"
+ label="Screen Space Reflections"
+ layout="topleft"
+ left="420"
+ name="ScreenSpaceReflections"
+ top_delta="16"
+ width="240">
+ <check_box.commit_callback
+ function="Pref.RenderOptionUpdate" />
+ </check_box>
-<!-- End of Advanced Settings block -->
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="ReflectionDetailText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="16"
+ width="128">
+ Reflection Detail:
+ </text>
+
+ <combo_box
+ control_name="RenderReflectionProbeDetail"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="ReflectionDetail"
+ width="150">
+ <combo_box.item
+ label="Static Only"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Static+Dynamic"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Realtime"
+ name="2"
+ value="2"/>
+ </combo_box>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="16"
+ layout="topleft"
+ left="420"
+ name="ReflectionProbeText"
+ text_readonly_color="LabelDisabledColor"
+ top_delta="16"
+ width="128">
+ Reflection Coverage:
+ </text>
+
+ <combo_box
+ control_name="RenderReflectionProbeLevel"
+ height="18"
+ layout="topleft"
+ left_delta="130"
+ top_delta="0"
+ name="ReflectionLevel"
+ width="150">
+ <combo_box.item
+ label="None"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Manual only"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Manual + terrain"
+ name="2"
+ value="2"/>
+ <combo_box.item
+ label="Full scene"
+ name="3"
+ value="3"/>
+ </combo_box>
+
+ <slider
+ control_name="RenderExposure"
+ decimal_digits="1"
+ follows="left|top"
+ height="16"
+ increment="0.1"
+ initial_value="160"
+ label="Exposure:"
+ label_width="145"
+ layout="topleft"
+ left="420"
+ min_val="0.5"
+ max_val="1.5"
+ name="RenderExposure"
+ show_text="true"
+ top_delta="20"
+ width="260">
+ </slider>
+
+ <!-- End of Advanced Settings block -->
<view_border
bevel_style="in"
height="0"
layout="topleft"
left="13"
name="horiz_border"
- top_pad="21"
+ top="338"
top_delta="5"
width="774"/>
<button
@@ -882,7 +764,7 @@
layout="topleft"
left="20"
name="Defaults"
- top_delta="10"
+ top_delta="20"
width="210">
<button.commit_callback
function="Pref.HardwareDefaults" />
diff --git a/indra/newview/skins/default/xui/en/floater_settings_picker.xml b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
index 3a26c3b547..8931269fe7 100644
--- a/indra/newview/skins/default/xui/en/floater_settings_picker.xml
+++ b/indra/newview/skins/default/xui/en/floater_settings_picker.xml
@@ -89,7 +89,7 @@
top="1"
right="-4"
bottom="-1"
- filter_asset_type="settings" />
+ filter_asset_types="settings" />
</panel>
</layout_panel>
<layout_panel name="pnl_combo"
diff --git a/indra/newview/skins/default/xui/en/floater_stats.xml b/indra/newview/skins/default/xui/en/floater_stats.xml
index b9ca0108b6..9ee161e611 100644
--- a/indra/newview/skins/default/xui/en/floater_stats.xml
+++ b/indra/newview/skins/default/xui/en/floater_stats.xml
@@ -133,6 +133,12 @@
label="Bound Mem"
stat="glboundmemstat"/>
</stat_view>
+ <stat_view name="material"
+ label="Material">
+ <stat_bar name="nummaterials"
+ label="Count"
+ stat="nummaterials"/>
+ </stat_view>
<stat_view name="memory"
label="Memory Usage">
<stat_bar name="LLTrace"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
index 8081af6673..2d3321bb2f 100644
--- a/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
+++ b/indra/newview/skins/default/xui/en/floater_texture_ctrl.xml
@@ -19,7 +19,15 @@
</floater.string>
<floater.string
name="pick title">
- Pick:
+Pick:
+ </floater.string>
+ <floater.string
+ name="pick_material">
+PICK: MATERIAL
+ </floater.string>
+ <floater.string
+ name="pick_texture">
+PICK: TEXTURE
</floater.string>
<view
@@ -154,6 +162,7 @@
word_wrap="true"
visible="false"
width="87" />
+
<filter_editor
follows="left|top|right"
height="23"
@@ -169,22 +178,13 @@
bg_alpha_color="DkGray2"
border="false"
follows="all"
- height="233"
+ height="242"
layout="topleft"
left_delta="0"
name="inventory panel"
top_pad="4"
width="231"
- filter_asset_type="texture"/>
- <check_box
- height="14"
- initial_value="false"
- label="Show folders"
- layout="topleft"
- name="show_folders_check"
- top_pad="0"
- left_delta="-3"
- width="200" />
+ filter_asset_types="texture|material"/>
<!-- middle: local mode -->
<button
@@ -234,8 +234,8 @@
multi_select="true"
search_column="1"
visible="false">
+ <column name="icon" label="" width="20" />
<column name="unit_name" label="Name" dynamicwidth="true" />
- <column name="unit_id_HIDDEN" label="ID" width="0" />
</scroll_list>
<!-- middle: bake mode -->
@@ -299,19 +299,6 @@
name="BAKED_AUX3"
value="10" />
</combo_box>
- <check_box
- follows="left|top"
- height="20"
- initial_value="false"
- label="Hide Base Mesh Region"
-
-layout="topleft"
- name="hide_base_mesh_region"
- left_delta="0"
- top_pad="10"
- top_delta="0"
- width="120"
- visible="false"/>
<!-- bottom static -->
<button
follows="bottom"
diff --git a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml b/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
deleted file mode 100644
index 9278a1a598..0000000000
--- a/indra/newview/skins/default/xui/en/floater_texture_fetch_debugger.xml
+++ /dev/null
@@ -1,440 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- legacy_header_height="18"
- can_minimize="false"
- height="600"
- layout="topleft"
- name="TexFetchDebugger"
- help_topic="texfetchdebugger"
- title="Texture Fetching Debugger"
- width="540">
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left="10"
- name="total_num_fetched_label"
- top="30"
- width="400">
- 1, Total number of fetched textures: [NUM]
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_num_fetching_requests_label"
- top_delta="25"
- width="400">
- 2, Total number of fetching requests: [NUM]
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_num_cache_hits_label"
- top_delta="25"
- width="400">
- 3, Total number of cache hits: [NUM]
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_num_visible_tex_label"
- top_delta="25"
- width="400">
- 4, Total number of visible textures: [NUM]
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_num_visible_tex_fetch_req_label"
- top_delta="25"
- width="450">
- 5, Total number of visible texture fetching requests: [NUM]
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_fetched_data_label"
- top_delta="25"
- width="530">
- 6, Total number of fetched data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_fetched_vis_data_label"
- top_delta="25"
- width="480">
- 7, Total number of visible data: [SIZE1]KB, Decoded Data: [SIZE2]KB
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_fetched_rendered_data_label"
- top_delta="25"
- width="530">
- 8, Total number of rendered data: [SIZE1]KB, Decoded Data: [SIZE2]KB, [PIXEL]MPixels
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_cache_read_label"
- top_delta="25"
- width="400">
- 9, Total time on cache readings: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_cache_write_label"
- top_delta="25"
- width="400">
- 10, Total time on cache writings: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_decode_label"
- top_delta="25"
- width="400">
- 11, Total time on decodings: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_gl_label"
- top_delta="25"
- width="400">
- 12, Total time on gl texture creation: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_http_label"
- top_delta="25"
- width="400">
- 13, Total time on HTTP fetching: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_fetch_label"
- top_delta="25"
- width="400">
- 14, Total time on entire fetching: [TIME] seconds
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_refetch_vis_cache_label"
- top_delta="25"
- width="540">
- 15, Refetching visibles from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_refetch_all_cache_label"
- top_delta="25"
- width="540">
- 16, Refetching all textures from cache, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_refetch_vis_http_label"
- top_delta="25"
- width="540">
- 17, Refetching visibles from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
- </text>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="total_time_refetch_all_http_label"
- top_delta="25"
- width="540">
- 18, Refetching all textures from HTTP, Time: [TIME] seconds, Fetched: [SIZE]KB, [PIXEL]MPixels
- </text>
- <spinner
- decimal_digits="2"
- follows="left|top"
- height="20"
- increment="0.01"
- initial_value="1.0"
- label="19, Ratio of Texel/Pixel:"
- label_width="130"
- layout="topleft"
- left_delta="0"
- max_val="10.0"
- min_val="0.01"
- name="texel_pixel_ratio"
- top_delta="30"
- width="200">
- <spinner.commit_callback
- function="TexFetchDebugger.ChangeTexelPixelRatio" />
- </spinner>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="25"
- layout="topleft"
- left_delta="0"
- name="texture_source_label"
- top_delta="30"
- width="110">
- 20, Texture Source:
- </text>
- <radio_group
- control_name="TextureFetchSource"
- follows="top|left"
- draw_border="false"
- height="25"
- layout="topleft"
- left_pad="0"
- name="texture_source"
- top_delta="0"
- width="264">
- <radio_item
- height="16"
- label="Cache + HTTP"
- layout="topleft"
- left="3"
- name="0"
- top="0"
- width="100" />
- <radio_item
- height="16"
- label="HTTP Only"
- layout="topleft"
- left_delta="100"
- name="1"
- top_delta="0"
- width="200" />
- </radio_group>
- <button
- follows="left|top"
- height="20"
- label="Start"
- layout="topleft"
- left="10"
- name="start_btn"
- top_delta="20"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.Start" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Reset"
- layout="topleft"
- left_pad="7"
- name="clear_btn"
- top_delta="0"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.Clear" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Close"
- layout="topleft"
- left_pad="7"
- name="close_btn"
- top_delta="0"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.Close" />
- </button>
- <button
- follows="left|top"
- height="22"
- label="Reset Fetching Time"
- layout="topleft"
- left_pad="175"
- name="reset_time_btn"
- top_delta="0"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.ResetFetchTime" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Cache Read"
- layout="topleft"
- left="10"
- name="cacheread_btn"
- top_delta="20"
- width="80">
- <button.commit_callback
- function="TexFetchDebugger.CacheRead" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Cache Write"
- layout="topleft"
- left_pad="7"
- name="cachewrite_btn"
- top_delta="0"
- width="80">
- <button.commit_callback
- function="TexFetchDebugger.CacheWrite" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="HTTP"
- layout="topleft"
- left_pad="7"
- name="http_btn"
- top_delta="0"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.HTTPLoad" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Decode"
- layout="topleft"
- left_pad="7"
- name="decode_btn"
- top_delta="0"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.Decode" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="GL Texture"
- layout="topleft"
- left_pad="7"
- name="gl_btn"
- top_delta="0"
- width="70">
- <button.commit_callback
- function="TexFetchDebugger.GLTexture" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Refetch Vis Cache"
- layout="topleft"
- left="10"
- name="refetchviscache_btn"
- top_delta="20"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.RefetchVisCache" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Refetch All Cache"
- layout="topleft"
- left_pad="7"
- name="refetchallcache_btn"
- top_delta="0"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.RefetchAllCache" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Refetch Vis HTTP"
- layout="topleft"
- left_pad="7"
- name="refetchvishttp_btn"
- top_delta="0"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.RefetchVisHTTP" />
- </button>
- <button
- follows="left|top"
- height="20"
- label="Refetch All HTTP"
- layout="topleft"
- left_pad="7"
- name="refetchallhttp_btn"
- top_delta="0"
- width="120">
- <button.commit_callback
- function="TexFetchDebugger.RefetchAllHTTP" />
- </button>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 684470e0fc..9966fe0b56 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -2,7 +2,7 @@
<floater
positioning="cascading"
legacy_header_height="18"
- height="609"
+ height="651"
layout="topleft"
bg_opaque_image="Window_NoTitle_Foreground"
bg_alpha_image="Window_NoTitle_Background"
@@ -820,7 +820,7 @@
width="282"/>
<tab_container
follows="left|top"
- height="426"
+ height="476"
halign="center"
left="0"
name="Object Info Tabs"
@@ -2534,7 +2534,70 @@ even though the user gets a free copy.
mouse_opaque="true"
name="Light Ambiance"
width="120" />
- <text
+ <check_box
+ height="16"
+ label="Reflection Probe"
+ layout="topleft"
+ left="10"
+ name="Reflection Probe"
+ tool_tip="Adjusts how objects within this volume receive reflections when PBR is enabled"
+ top_pad="10"
+ width="60" />
+ <combo_box
+ height="19"
+ top_delta="0"
+ left="144"
+ follows="left|top"
+ name="Probe Volume Type"
+ tool_tip="Choose the probe influence volume"
+ width="108">
+ <combo_box.item
+ label="Sphere"
+ name="Sphere"
+ value="Sphere" />
+ <combo_box.item
+ label="Box"
+ name="Box"
+ value="Box"/>
+ </combo_box>
+ <check_box
+ height="16"
+ label="Dynamic"
+ layout="topleft"
+ left="10"
+ name="Probe Dynamic"
+ tool_tip="When enabled, Avatars will appear in reflections within this probe's influence volume."
+ bottom_delta="19"
+ width="60" />
+ <spinner bottom_delta="19"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Ambiance"
+ label_width="55"
+ left="10"
+ max_val="100"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Ambiance"
+ width="120" />
+ <spinner bottom_delta="0"
+ decimal_digits="3"
+ follows="left|top"
+ height="16"
+ increment="0.05"
+ initial_value="0"
+ label="Near Clip"
+ label_width="55"
+ left="144"
+ max_val="1024"
+ min_val="0"
+ mouse_opaque="true"
+ name="Probe Near Clip"
+ width="120" />
+ <text
type="string"
length="1"
follows="left|top"
@@ -2689,7 +2752,7 @@ even though the user gets a free copy.
border_visible="true"
bevel_style="in"
follows="left|top|right"
- height="335"
+ height="387"
layout="topleft"
left="10"
name="contents_inventory"
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 3b91b9df7a..8e041f8de3 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -13,6 +13,14 @@
function="EnableEdit" />
</menu_item_call>
<menu_item_call
+ label="Edit PBR material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_visible
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
enabled="false"
label="Detach item"
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 7016c8e558..0295ef8ccd 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -144,14 +144,6 @@
parameter="rename" />
</menu_item_call>
<menu_item_call
- label="New Folder"
- layout="topleft"
- name="New Folder">
- <menu_item_call.on_click
- function="Inventory.DoCreate"
- parameter="category" />
- </menu_item_call>
- <menu_item_call
label="New Outfit"
layout="topleft"
name="New Outfit">
@@ -707,6 +699,234 @@
<menu_item_separator
layout="topleft"
name="Subfolder Separator" />
+ <menu
+ label="Create new"
+ layout="topleft"
+ name="create_new">
+ <menu_item_call
+ label="New Folder"
+ layout="topleft"
+ name="New Folder">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="category" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Script"
+ layout="topleft"
+ name="New Script">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="lsl" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Notecard"
+ layout="topleft"
+ name="New Note">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="notecard" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gesture"
+ layout="topleft"
+ name="New Gesture">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gesture" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ <menu_item_call.on_enable
+ function="Inventory.MaterialsEnabled" />
+ </menu_item_call>
+ <menu
+ label="New Clothes"
+ layout="topleft"
+ name="New Clothes">
+ <menu_item_call
+ label="New Shirt"
+ layout="topleft"
+ name="New Shirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Pants"
+ layout="topleft"
+ name="New Pants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="pants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Shoes"
+ layout="topleft"
+ name="New Shoes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shoes" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Socks"
+ layout="topleft"
+ name="New Socks">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="socks" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Jacket"
+ layout="topleft"
+ name="New Jacket">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="jacket" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skirt"
+ layout="topleft"
+ name="New Skirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Gloves"
+ layout="topleft"
+ name="New Gloves">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="gloves" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Undershirt"
+ layout="topleft"
+ name="New Undershirt">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="undershirt" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Underpants"
+ layout="topleft"
+ name="New Underpants">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="underpants" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Alpha Mask"
+ layout="topleft"
+ name="New Alpha Mask">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="alpha" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Tattoo"
+ layout="topleft"
+ name="New Tattoo">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="tattoo" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Universal"
+ layout="topleft"
+ name="New Universal">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="universal" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Physics"
+ layout="topleft"
+ name="New Physics">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="physics" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Body Parts"
+ layout="topleft"
+ name="New Body Parts">
+ <menu_item_call
+ label="New Shape"
+ layout="topleft"
+ name="New Shape">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="shape" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Skin"
+ layout="topleft"
+ name="New Skin">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="skin" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Hair"
+ layout="topleft"
+ name="New Hair">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="hair" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Eyes"
+ layout="topleft"
+ name="New Eyes">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="eyes" />
+ </menu_item_call>
+ </menu>
+ <menu
+ label="New Settings"
+ layout="topleft"
+ name="New Settings">
+ <menu_item_call
+ label="New Sky"
+ layout="topleft"
+ name="New Sky">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="sky"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Water"
+ layout="topleft"
+ name="New Water">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="water"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ <menu_item_call
+ label="New Day Cycle"
+ layout="topleft"
+ name="New Day Cycle">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="daycycle"/>
+ <menu_item_call.on_enable
+ function="Inventory.EnvironmentEnabled" />
+ </menu_item_call>
+ </menu>
+ </menu>
<menu_item_call
label="Create folder from selected"
layout="topleft"
@@ -759,6 +979,14 @@
function="Inventory.FileUploadLocation"
parameter="model" />
</menu_item_call>
+ <menu_item_call
+ label="PBR material uploads"
+ layout="topleft"
+ name="PBR uploads">
+ <menu_item_call.on_click
+ function="Inventory.FileUploadLocation"
+ parameter="pbr_material" />
+ </menu_item_call>
</menu>
<menu_item_separator
layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_add.xml b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
index 12ba121d3c..284dd8d9fc 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_add.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_add.xml
@@ -47,13 +47,23 @@
label="Model..."
layout="topleft"
name="Upload Model">
- <menu_item_call.on_click
- function="File.UploadModel"
- parameter="" />
- <menu_item_call.on_enable
- function="File.EnableUploadModel" />
- <menu_item_call.on_visible
- function="File.VisibleUploadModel"/>
+ <menu_item_call.on_click
+ function="File.UploadModel"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadModel" />
+ <menu_item_call.on_visible
+ function="File.VisibleUploadModel"/>
+ </menu_item_call>
+ <menu_item_call
+ label="Material..."
+ layout="topleft"
+ name="Upload Material">
+ <menu_item_call.on_click
+ function="File.UploadMaterial"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadMaterial" />
</menu_item_call>
<menu_item_call
label="Bulk..."
@@ -97,6 +107,16 @@
function="Inventory.DoCreate"
parameter="gesture" />
</menu_item_call>
+ <menu_item_call
+ label="New Material"
+ layout="topleft"
+ name="New Material">
+ <menu_item_call.on_click
+ function="Inventory.DoCreate"
+ parameter="material" />
+ <menu_item_call.on_enable
+ function="Inventory.MaterialsEnabled" />
+ </menu_item_call>
<menu
height="175"
label="New Clothes"
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index ce34508303..5507c9f3a1 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -22,6 +22,14 @@
function="EnableEdit"/>
</menu_item_call>
<menu_item_call
+ label="Edit PBR material"
+ name="EditGLTFMaterial">
+ <menu_item_call.on_click
+ function="Object.EditGLTFMaterial" />
+ <menu_item_call.on_visible
+ function="Object.EnableEditGLTFMaterial"/>
+ </menu_item_call>
+ <menu_item_call
label="Build"
name="Build">
<menu_item_call.on_click
@@ -38,26 +46,25 @@
<menu_item_call.on_enable
function="Object.EnableOpen" />
</menu_item_call>
+ <menu_item_separator layout="topleft" />
<menu_item_call
- enabled="false"
- label="Sit Here"
+ label="Sit here"
name="Object Sit">
<menu_item_call.on_click
function="Object.SitOrStand" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="Object.EnableSit" />
</menu_item_call>
<menu_item_call
- enabled="false"
- label="Stand Up"
+ label="Stand up"
name="Object Stand Up">
<menu_item_call.on_click
function="Object.SitOrStand" />
- <menu_item_call.on_enable
+ <menu_item_call.on_visible
function="Object.EnableStandUp" />
</menu_item_call>
<menu_item_call
- label="Object Profile"
+ label="Object profile"
name="Object Inspect">
<menu_item_call.on_click
function="Object.Inspect" />
@@ -65,13 +72,13 @@
function="Object.EnableInspect" />
</menu_item_call>
<menu_item_call
- label="Zoom In"
+ label="Zoom in"
name="Zoom In">
<menu_item_call.on_click
function="Object.ZoomIn" />
</menu_item_call>
<menu_item_call
- label="Show in linksets"
+ label="Show in Region Objects"
name="show_in_linksets">
<menu_item_call.on_click
function="Pathfinding.Linksets.Select" />
@@ -92,7 +99,7 @@
</menu_item_call>
<menu_item_separator layout="topleft" />
<context_menu
- label="Put On"
+ label="Put on"
name="Put On" >
<menu_item_call
enabled="false"
@@ -169,7 +176,7 @@
</menu_item_call>
<menu_item_call
enabled="false"
- label="Take Copy"
+ label="Take copy"
name="Take Copy">
<menu_item_call.on_click
function="Tools.TakeCopy" />
@@ -207,7 +214,7 @@
layout="topleft" />
<menu_item_call
enabled="false"
- label="Block Particle Owner"
+ label="Block particle owner"
name="Mute Particle">
<menu_item_call.on_click
function="Particle.Mute" />
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 810d3fddd5..0bfdead6e7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -933,17 +933,27 @@
function="World.EnableEnvSettings"
parameter="sunrise" />
</menu_item_check>
- <menu_item_check
- label="Midday"
- name="Noon"
- shortcut="control|shift|Y">
- <menu_item_check.on_click
- function="World.EnvSettings"
- parameter="noon" />
- <menu_item_check.on_check
- function="World.EnableEnvSettings"
- parameter="noon" />
- </menu_item_check>
+ <menu_item_check
+ label="Midday"
+ name="Noon"
+ shortcut="control|shift|Y">
+ <menu_item_check.on_click
+ function="World.EnvSettings"
+ parameter="noon" />
+ <menu_item_check.on_check
+ function="World.EnableEnvSettings"
+ parameter="noon" />
+ </menu_item_check>
+ <menu_item_check
+ label="Midday (Legacy)"
+ name="legacy noon">
+ <menu_item_check.on_click
+ function="World.EnvSettings"
+ parameter="legacy noon" />
+ <menu_item_check.on_check
+ function="World.EnableEnvSettings"
+ parameter="legacy noon" />
+ </menu_item_check>
<menu_item_check
label="Sunset"
name="Sunset"
@@ -1449,6 +1459,24 @@ function="World.EnvPreset"
function="Tools.SelectOnlyMovableObjects"
parameter="movable" />
</menu_item_check>
+ <menu_item_check
+ label="Select Invisible Objects"
+ name="Select Invisible Objects">
+ <menu_item_check.on_check
+ control="SelectInvisibleObjects" />
+ <menu_item_check.on_click
+ function="Tools.SelectInvisibleObjects"
+ parameter="invisible" />
+ </menu_item_check>
+ <menu_item_check
+ label="Select Reflection Probes"
+ name="Select Reflection Probes">
+ <menu_item_check.on_check
+ control="SelectReflectionProbes" />
+ <menu_item_check.on_click
+ function="Tools.SelectReflectionProbes"
+ parameter="reflection_probes" />
+ </menu_item_check>
<menu_item_check
label="Select By Surrounding"
name="Select By Surrounding">
@@ -1487,6 +1515,15 @@ function="World.EnvPreset"
function="Tools.ShowSelectionLightRadius" />
</menu_item_check>
<menu_item_check
+ label="Show Reflection Probe Volumes"
+ name="Show Reflection Probe Volumes">
+ <menu_item_check.on_check
+ control="RenderReflectionProbeVolumes" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderReflectionProbeVolumes" />
+ </menu_item_check>
+ <menu_item_check
label="Show Selection Beam"
name="Show Selection Beam">
<menu_item_check.on_check
@@ -1495,7 +1532,28 @@ function="World.EnvPreset"
function="ToggleControl"
parameter="ShowSelectionBeam" />
</menu_item_check>
-
+ <menu_item_check
+ label="Highlight Transparent"
+ name="Highlight Transparent"
+ shortcut="control|alt|T"
+ use_mac_ctrl="true">
+ <menu_item_check.on_check
+ function="View.CheckHighlightTransparent" />
+ <menu_item_check.on_click
+ function="View.HighlightTransparent" />
+ </menu_item_check>
+ <menu_item_separator/>
+
+ <menu_item_check
+ label="No Post"
+ name="No Post">
+ <menu_item_check.on_check
+ control="RenderDisablePostProcessing" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderDisablePostProcessing" />
+ </menu_item_check>
+
<menu_item_separator/>
<menu_item_check
@@ -1606,6 +1664,16 @@ function="World.EnvPreset"
<menu_item_call.on_visible
function="File.VisibleUploadModel"/>
</menu_item_call>
+ <menu_item_call
+ label="Material..."
+ layout="topleft"
+ name="Upload Material">
+ <menu_item_call.on_click
+ function="File.UploadMaterial"
+ parameter="" />
+ <menu_item_call.on_enable
+ function="File.EnableUploadMaterial" />
+ </menu_item_call>
<menu_item_call
label="Bulk..."
layout="topleft"
@@ -1618,7 +1686,8 @@ function="World.EnvPreset"
parameter="" />
</menu_item_call>
</menu>
- <menu_item_separator/>
+
+ <menu_item_separator/>
<menu_item_call
enabled="false"
label="Undo"
@@ -1894,16 +1963,6 @@ function="World.EnvPreset"
parameter="HideSelectedObjects" />
</menu_item_check>
<menu_item_check
- label="Highlight Transparent"
- name="Highlight Transparent"
- shortcut="control|alt|T"
- use_mac_ctrl="true">
- <menu_item_check.on_check
- function="View.CheckHighlightTransparent" />
- <menu_item_check.on_click
- function="View.HighlightTransparent" />
- </menu_item_check>
- <menu_item_check
label="Show Mouselook Crosshairs"
name="ShowCrosshairs">
<menu_item_check.on_check
@@ -2049,17 +2108,6 @@ function="World.EnvPreset"
parameter="water" />
</menu_item_check>
<menu_item_check
- label="Ground"
- name="Rendering Type Ground"
- shortcut="control|alt|shift|8">
- <menu_item_check.on_check
- function="Advanced.CheckRenderType"
- parameter="ground" />
- <menu_item_check.on_click
- function="Advanced.ToggleRenderType"
- parameter="ground" />
- </menu_item_check>
- <menu_item_check
label="Volume"
name="Rendering Type Volume"
shortcut="control|alt|shift|9">
@@ -2470,20 +2518,6 @@ function="World.EnvPreset"
function="Advanced.ToggleConsole"
parameter="scene monitor" />
</menu_item_check>
- <menu_item_call
- enabled="false"
- visible="false"
- label="Texture Fetch Debug Console"
- name="Texture Fetch Debug Console">
- <menu_item_call.on_click
- function="Floater.Show"
- parameter="tex_fetch_debugger" />
- <on_enable
- function="Develop.SetTexFetchDebugger" />
- <on_visible
- function="Develop.SetTexFetchDebugger" />
- </menu_item_call>
-
<menu_item_separator/>
<menu_item_call
@@ -2762,15 +2796,6 @@ function="World.EnvPreset"
function="Advanced.TogglePeriodicSlowFrame"
parameter="points" />
</menu_item_check>
- <menu_item_check
- label="Frame Test"
- name="Frame Test">
- <menu_item_check.on_check
- function="Advanced.CheckFrameTest"
- parameter="Frame Test" />
- <menu_item_check.on_click
- function="Advanced.ToggleFrameTest" />
- </menu_item_check>
<menu_item_call
label="Frame Profile"
name="Frame Profile">
@@ -2930,24 +2955,34 @@ function="World.EnvPreset"
parameter="triangle count" />
</menu_item_check>
<menu_item_check
- label="Build Queue"
- name="Build Queue">
+ label="Lights"
+ name="Lights">
<menu_item_check.on_check
function="Advanced.CheckInfoDisplay"
- parameter="build queue" />
+ parameter="lights" />
<menu_item_check.on_click
function="Advanced.ToggleInfoDisplay"
- parameter="build queue" />
+ parameter="lights" />
</menu_item_check>
<menu_item_check
- label="Lights"
- name="Lights">
+ label="Reflection Probes"
+ name="Reflection Probes">
<menu_item_check.on_check
function="Advanced.CheckInfoDisplay"
- parameter="lights" />
+ parameter="reflection probes" />
<menu_item_check.on_click
function="Advanced.ToggleInfoDisplay"
- parameter="lights" />
+ parameter="reflection probes" />
+ </menu_item_check>
+ <menu_item_check
+ label="Probe Updates"
+ name="Probe Updates">
+ <menu_item_check.on_check
+ function="Advanced.CheckInfoDisplay"
+ parameter="probe updates" />
+ <menu_item_check.on_click
+ function="Advanced.ToggleInfoDisplay"
+ parameter="probe updates" />
</menu_item_check>
<menu_item_check
label="Particles"
@@ -3115,24 +3150,10 @@ function="World.EnvPreset"
<menu_item_check.on_click
function="ToggleControl"
parameter="UseOcclusion" />
- <menu_item_check.on_enable
- function="Advanced.EnableObjectObjectOcclusion" />
</menu_item_check>
<menu_item_separator />
<menu_item_check
- label="Advanced Lighting Model"
- name="Advanced Lighting Model">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderDeferred" />
- <menu_item_check.on_enable
- function="Advanced.EnableRenderDeferred" />
- </menu_item_check>
- <menu_item_check
label=" Shadows from Sun/Moon/Projectors"
name="Shadows from Sun/Moon/Projectors">
<menu_item_check.on_check
@@ -3219,36 +3240,6 @@ function="World.EnvPreset"
parameter="TextureDisable" />
</menu_item_check>
<menu_item_check
- label="Disable Ambient"
- name="Disable Ambient">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="AmbientDisable" />
- <menu_item_check.on_click
- function="ToggleShaderControl"
- parameter="AmbientDisable" />
- </menu_item_check>
- <menu_item_check
- label="Disable Sunlight"
- name="Disable Sunlight">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="SunlightDisable" />
- <menu_item_check.on_click
- function="ToggleShaderControl"
- parameter="SunlightDisable" />
- </menu_item_check>
- <menu_item_check
- label="Disable Local Lights"
- name="Disable Local Lights">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="LocalLightDisable" />
- <menu_item_check.on_click
- function="ToggleShaderControl"
- parameter="LocalLightDisable" />
- </menu_item_check>
- <menu_item_check
label="Full Res Textures"
name="Rull Res Textures">
<menu_item_check.on_check
@@ -3278,18 +3269,25 @@ function="World.EnvPreset"
function="Advanced.HandleAttachedLightParticles"
parameter="RenderAttachedParticles" />
</menu_item_check>
- <menu_item_check
- label="Hover Glow Objects"
- name="Hover Glow Objects">
- <menu_item_check.on_check
- function="CheckControl"
- parameter="RenderHoverGlowEnable" />
- <menu_item_check.on_click
- function="ToggleControl"
- parameter="RenderHoverGlowEnable" />
- </menu_item_check>
<menu_item_separator />
-
+ <menu_item_check
+ label="Enable Shader Cache"
+ name="Enable Shader Cache">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderShaderCacheEnabled" />
+ <menu_item_check.on_click
+ function="ToggleShaderControl"
+ parameter="RenderShaderCacheEnabled" />
+ </menu_item_check>
+ <menu_item_call
+ enabled="true"
+ label="Clear Shader Cache"
+ name="Shader Cache Clear">
+ <menu_item_call.on_click
+ function="Advanced.ClearShaderCache" />
+ </menu_item_call>
+ <menu_item_separator />
<menu_item_call
enabled="true"
label="Clear Cache Immediately"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 204fead7e0..d1838fc7ef 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5962,6 +5962,22 @@ You have updated the location of this pick but the other details will retain the
<notification
icon="alertmodal.tga"
+ name="ApplyInventoryToObject"
+ type="alertmodal">
+You are applying &apos;no copy&apos; inventory item.
+This item will be moved to object's inventory, not copied.
+
+Move the inventory item?
+ <tag>confirm</tag>
+ <usetemplate
+ ignoretext="Warn me before I apply &apos;no-copy&apos; items to an object"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="MoveInventoryFromObject"
type="alertmodal">
You have selected &apos;no copy&apos; inventory items.
@@ -6932,6 +6948,22 @@ You don&apos;t have permission to view this notecard.
<notification
icon="notifytip.tga"
+ name="MaterialMissing"
+ type="notifytip">
+ Material is missing from database.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="MaterialNoPermissions"
+ type="notifytip">
+ You don&apos;t have permission to view this material.
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
name="RezItemNoPermissions"
type="notifytip">
Insufficient permissions to rez object.
@@ -6962,6 +6994,26 @@ Please try again.
</notification>
<notification
+ icon="alertmodal.tga"
+ name="UnableToLoadMaterial"
+ type="alertmodal">
+Unable to load material.
+Please try again.
+ <tag>fail</tag>
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="MissingMaterialCaps"
+ type="notifytip">
+ <tag>fail</tag>
+ Not connected to a materials capable region.
+ </notification>
+
+ <notification
icon="notifytip.tga"
name="ScriptMissing"
type="notifytip">
@@ -9193,7 +9245,64 @@ Unable to upload texture.
[REASON]
<tag>fail</tag>
</notification>
-
+
+ <notification
+ icon="alertmodal.tga"
+ name="CannotUploadMaterial"
+ type="alertmodal">
+There was a problem uploading the file
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ label="Save Material"
+ name="SaveMaterialAs"
+ type="alertmodal">
+ <unique/>
+ Name this material:
+ <tag>confirm</tag>
+ <form name="form">
+ <input name="message" type="text">
+ [DESC]
+ </input>
+ <button
+ default="true"
+ index="0"
+ name="OK"
+ text="OK"/>
+ <button
+ index="1"
+ name="Cancel"
+ text="Cancel"/>
+ </form>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="InvalidMaterialName"
+ type="alertmodal">
+Please enter a non-empty name
+ <tag>fail</tag>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="UsavedMaterialChanges"
+ type="alertmodal">
+ You have unsaved changes.
+ <form name="form">
+ <button
+ index="0"
+ name="discard"
+ text="Discard changes"/>
+ <button
+ index="1"
+ name="keep"
+ text="Keep editing"/>
+ </form>
+ </notification>
+
<notification
icon="alertmodal.tga"
name="LivePreviewUnavailable"
@@ -9208,6 +9317,18 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran
<notification
icon="alertmodal.tga"
+ name="LivePreviewUnavailablePBR"
+ type="alert">
+
+We cannot display a preview of this material because it is no-copy, no-transfer, and/or no-modify.
+ <usetemplate
+ ignoretext="Warn me that Live Preview mode is not available for no-copy, no-transfer, and/or no-modify materials"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="FacePasteFailed"
type="alertmodal">
Paste failed. [REASON]
@@ -9218,6 +9339,26 @@ Paste failed. [REASON]
<notification
icon="alertmodal.tga"
+ name="FailedToApplyTextureNoCopyToMultiple"
+ type="alertmodal">
+Failed to apply texture. You can not apply a no-copy texture to multiple objects.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
+ name="FailedToApplyGLTFNoCopyToMultiple"
+ type="alertmodal">
+Failed to apply GLTF material. You can not apply a no-copy material to multiple objects.
+ <usetemplate
+ name="okbutton"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="FacePasteTexturePermissions"
type="alertmodal">
You applied a texture with limited permissions, object will inherit permissions from texture.
@@ -9890,6 +10031,15 @@ Attempt cancelled.
<notification
icon="alertmodal.tga"
+ name="LocalGLTFVerifyFail"
+ persist="true"
+ type="notify">
+Attempted to add an invalid or unreadable GLTF material [FNAME] which could not be opened or decoded.
+Attempt cancelled.
+ </notification>
+
+ <notification
+ icon="alertmodal.tga"
name="PathfindingReturnMultipleItems"
type="alertmodal">
You are returning [NUM_ITEMS] items. Are you sure you want to continue?
@@ -12099,4 +12249,28 @@ Would you like to save them first?
yestext="Yes"/>
</notification>
+ <notification
+ icon="notifytip.tga"
+ name="ReflectionProbeApplied"
+ persist="true"
+ type="alertmodal">
+ WARNING: You have made your object a Reflection Probe. This will implicitly change the object to mimic its influence volume and will make irreversible changes to the object. Do you want to continue?
+ <usetemplate
+ ignoretext="Reflection Probe tips"
+ name="okcancelignore"
+ notext="Cancel"
+ yestext="OK"/>
+ </notification>
+
+ <notification
+ icon="notifytip.tga"
+ name="AutoAdjustHDRSky"
+ type="alertmodal">
+ You are editing a non-HDR sky that has been automatically converted to HDR. To remove HDR and tone mapping, set Reflection Probe Ambiance to zero.
+ <usetemplate
+ ignoretext="HDR Sky adjustment warning"
+ name="okignore"
+ yestext="OK"/>
+ </notification>
+
</notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_gltf_material.xml b/indra/newview/skins/default/xui/en/panel_gltf_material.xml
new file mode 100644
index 0000000000..45df40bc05
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_gltf_material.xml
@@ -0,0 +1,392 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ layout="topleft"
+ follows="left|top|right"
+ border="false"
+ name="panel_gltf_material"
+ top="0"
+ left="0"
+ height="768"
+ width="247">
+ <check_box
+ follows="left|top"
+ layout="topleft"
+ label="Double Sided"
+ left="10"
+ top="0"
+ name="double sided"
+ height="25"
+ width="120" />
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="196"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="base_color_texture_pnl"
+ top_pad="5"
+ >
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="128"
+ name="base_color_lbl">
+ Base Color:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="base_color_texture"
+ tool_tip="Base Color map. Alpha channel is optional and used for transparency."
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="base_color_upload_fee">
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ name="base_color_tint_lbl">
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="base color"
+ width="40" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ name="base_color_transparency_lbl">
+ Alpha
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="transparency"
+ width="64"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ text_readonly_color="LabelDisabledColor"
+ top_pad="5"
+ width="90"
+ name="alpha_mode_lbl">
+ Alpha mode
+ </text>
+ <combo_box
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ name="alpha mode"
+ top_pad="4"
+ width="89">
+ <combo_box.item
+ label="Opaque"
+ name="None"
+ value="OPAQUE" />
+ <combo_box.item
+ label="Blend"
+ name="Alpha blending"
+ value="BLEND" />
+ <combo_box.item
+ label="Mask"
+ name="Alpha masking"
+ value="MASK" />
+ </combo_box>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ name="alpha_cutoff_lbl">
+ Alpha Cutoff
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="1"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="alpha cutoff"
+ width="64"/>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="metallic_texture_pnl"
+ top_pad="5">
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ name="metallic_roughness_lbl">
+ Metallic-Roughness:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ width="128"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="metallic_roughness_texture"
+ tool_tip="GLTF metallic-roughness map with optional occlusion. Red channel is occlusion, green channel is roughness, blue channel is metalness."
+ top_pad="8"/>
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="metallic_upload_fee">
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ name="metallic_factor_lbl">
+ Metallic Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="metalness factor"
+ width="64"/>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ width="96"
+ name="roughness_factor_lbl">
+ Roughness Factor
+ </text>
+ <spinner
+ decimal_digits="3"
+ follows="left|top"
+ height="19"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ min_val="0"
+ max_val="1"
+ name="roughness factor"
+ width="64"/>
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ name="emissive_texture_pnl"
+ top_pad="5">
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64"
+ name="emissive_lbl">
+ Emissive:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="emissive_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="emissive_upload_fee">
+ No upload fee
+ </text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_pad="5"
+ top="8"
+ name="emissive_tint_lbl">
+ Tint
+ </text>
+ <color_swatch
+ can_apply_immediately="true"
+ follows="left|top"
+ height="40"
+ label_height="0"
+ layout="topleft"
+ left_delta="0"
+ top_pad="5"
+ name="emissive color"
+ width="40" />
+ </panel>
+ <panel
+ border="true"
+ follows="left|top"
+ width="246"
+ height="175"
+ layout="topleft"
+ left="1"
+ mouse_opaque="false"
+ top_pad="5"
+ name="normal_texture_pnl">
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="10"
+ top="5"
+ width="64"
+ name="normal_lbl">
+ Normal:
+ </text>
+ <texture_picker
+ can_apply_immediately="true"
+ default_image_name="Default"
+ fallback_image="materials_ui_x_24.png"
+ allow_no_texture="true"
+ follows="left|top"
+ top_pad="8"
+ height="151"
+ layout="topleft"
+ left="10"
+ name="normal_texture"
+ width="128" />
+ <text
+ type="string"
+ font.style="BOLD"
+ length="1"
+ follows="left|top"
+ height="10"
+ width="128"
+ layout="topleft"
+ left="10"
+ top_pad="-17"
+ name="normal_upload_fee">
+ No upload fee
+ </text>
+ </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
index b52c19d5e3..83db17b679 100644
--- a/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
+++ b/indra/newview/skins/default/xui/en/panel_performance_preferences.xml
@@ -273,7 +273,7 @@
left="20"
name="environment_lbl"
width="100">
- Environment
+ Shadows
</text>
<text
follows="left|top"
@@ -285,29 +285,8 @@
left="160"
name="enhancements_desc"
width="350">
- Each enhancement improves realism but can reduce speed.
+ Shadows significantly improve visual quality but can reduce speed.
</text>
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- name="atmospheric_shaders"
- top_pad="5"
- left="157"
- width="280">
- </check_box>
- <check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting"
- layout="topleft"
- name="advanced_lighting_model"
- top_delta="24"
- width="280">
- </check_box>
<text
type="string"
length="1"
@@ -319,7 +298,7 @@
text_readonly_color="LabelDisabledColor"
top_pad="10"
width="128">
- Shadows:
+ Shadow Detail:
</text>
<combo_box
control_name="RenderShadowDetail"
@@ -372,7 +351,7 @@
left="160"
name="water_desc"
width="380">
- Reducing or turning off water effects can greatly improve frame rate.
+ Reducing or turning off transparent water may improve frame rate.
</text>
<check_box
control_name="RenderTransparentWater"
@@ -385,56 +364,6 @@
left="157"
width="280">
</check_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="16"
- layout="topleft"
- name="ReflectionsText"
- text_readonly_color="LabelDisabledColor"
- top_pad="16"
- left="160"
- width="128">
- Water Reflections:
- </text>
- <combo_box
- control_name="RenderReflectionDetail"
- height="18"
- layout="topleft"
- left_delta="150"
- top_delta="0"
- name="Reflections"
- width="150">
- <combo_box.item
- label="None; opaque"
- name="0"
- value="-2"/>
- <combo_box.item
- label="None; transparent"
- name="0"
- value="-1"/>
- <combo_box.item
- label="Minimal"
- name="0"
- value="0"/>
- <combo_box.item
- label="Terrain and trees"
- name="1"
- value="1"/>
- <combo_box.item
- label="All static objects"
- name="2"
- value="2"/>
- <combo_box.item
- label="All avatars and objects"
- name="3"
- value="3"/>
- <combo_box.item
- label="Everything"
- name="4"
- value="4"/>
- </combo_box>
<view_border
bevel_style="in"
height="0"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index ad02df3087..fe74cea2f1 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -231,34 +231,6 @@
m
</text>
- <check_box
- control_name="WindLightUseAtmosShaders"
- height="16"
- initial_value="true"
- label="Atmospheric shaders"
- layout="topleft"
- left="30"
- name="WindLightUseAtmosShaders"
- top_delta="24"
- width="280">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
- <check_box
- control_name="RenderDeferred"
- height="16"
- initial_value="true"
- label="Advanced Lighting Model"
- layout="topleft"
- left="30"
- name="UseLightShaders"
- top_delta="24"
- width="256">
- <check_box.commit_callback
- function="Pref.RenderOptionUpdate" />
- </check_box>
-
<button
height="23"
label="Automatic adjustments settings"
@@ -343,6 +315,25 @@ width="120">
function="Pref.RenderExceptions"/>
</button>
+ <slider
+ control_name="RenderExposure"
+ decimal_digits="1"
+ follows="left|top"
+ height="16"
+ increment="0.1"
+ initial_value="160"
+ label="Brightness (exposure)"
+ label_width="145"
+ layout="topleft"
+ left="30"
+ min_val="0.5"
+ max_val="1.5"
+ name="RenderExposure"
+ show_text="true"
+ top_pad="14"
+ width="260">
+ </slider>
+
<!-- End of Basic Settings block -->
<button
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 67eff2b762..08ff3d4d53 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -126,6 +126,31 @@
type="string"
length="1"
follows="left|top"
+ height="12"
+ layout="topleft"
+ left="37"
+ name="title_pbr"
+ top_pad="7"
+ width="100">
+ PBR Materials
+ </text>
+ <text
+ type="string"
+ use_ellipses="true"
+ follows="left|top"
+ height="27"
+ layout="topleft"
+ font.style="BOLD"
+ left="37"
+ name="upload_pbr"
+ top_pad="5"
+ width="370"
+ word_wrap="true"/>
+
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
height="30"
layout="topleft"
font.style="ITALIC"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
index fa2d4dfe73..da82c95c83 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml
@@ -7,6 +7,9 @@
left="0"
name="panel_settings_sky_atmos"
top="0">
+ <string name="hdr_string">HDR Scale:</string>
+ <string name="brightness_string">Brightness:</string>
+ <string name="hdr_tooltip">Intensity of lightning effects such as realistically bright skies and dynamic exposure. 1.0 is the default, 0 is off, values between 0 and 1 are mixing Ambient with HDR.</string>
<layout_stack
name="main_ls"
follows="all"
@@ -228,29 +231,6 @@
name="ice_level"
width="207"
can_edit_text="true"/>
- <text
- name="scene_gamma_label"
- follows="left|top"
- height="10"
- layout="topleft"
- left_delta="-5"
- top_delta="25"
- width="80">
- Scene Gamma:
- </text>
- <slider
- decimal_digits="2"
- follows="left|top"
- height="16"
- increment="0.01"
- initial_value="0"
- layout="topleft"
- left_delta="5"
- max_val="20"
- name="scene_gamma"
- top_delta="20"
- width="207"
- can_edit_text="true"/>
</layout_panel>
<layout_panel
name="right_lp"
@@ -332,6 +312,54 @@
top_delta="20"
width="219"
can_edit_text="true"/>
+ <text
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ tooltip="Irradiance control. When not zero, enables HDR lighting model."
+ width="200">
+ Reflection Probe Ambiance (HDR):
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ min_val="0"
+ max_val="10"
+ name="probe_ambiance"
+ tool_tip="Intensity of environment based indirect lighting. At zero HDR scale becomes Brightness"
+ top_delta="20"
+ width="219"
+ can_edit_text="true"/>
+ <text
+ name="scene_gamma_label"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left_delta="-5"
+ top_delta="25"
+ width="80">
+ Brightness:
+ </text>
+ <slider
+ decimal_digits="2"
+ follows="left|top"
+ height="16"
+ increment="0.01"
+ initial_value="0"
+ layout="topleft"
+ left_delta="5"
+ max_val="20"
+ name="scene_gamma"
+ top_delta="20"
+ width="207"
+ can_edit_text="true"/>
</layout_panel>
</layout_stack>
</layout_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_settings_water.xml b/indra/newview/skins/default/xui/en/panel_settings_water.xml
index 1aa42af3a8..f19629df26 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_water.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_water.xml
@@ -72,8 +72,8 @@
initial_value="0"
layout="top"
left_delta="15"
- min_val="-10"
- max_val="10"
+ min_val="0.001"
+ max_val="100"
name="water_fog_density"
top_delta="5"
width="150"
diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
index c7052bb737..fe01996623 100644
--- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml
+++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml
@@ -2,7 +2,7 @@
<panel
border="false"
follows="all"
- height="420"
+ height="500"
label="Texture"
layout="topleft"
left="0"
@@ -132,28 +132,43 @@
name="object_horizontal"
top_pad="4"
width="278" />
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ left="12"
+ top_pad="12"
+ name="label_matmedia"
+ width="90">
+ Material
+ </text>
<combo_box
height="23"
layout="topleft"
left="10"
name="combobox matmedia"
- top_pad="17"
+ top_pad="5"
width="90">
<combo_box.item
- label="Materials"
+ label="Textures"
name="Materials"
value="Materials" />
<combo_box.item
+ label="PBR Metallic Roughness"
+ name="PBR"
+ value="PBR" />
+ <combo_box.item
label="Media"
name="Media"
value="Media" />
</combo_box>
<radio_group
- control_name="ComboMaterialType"
- height="50"
+ height="84"
layout="topleft"
left_pad="5"
- top_delta="-10"
+ top_delta="-20"
width="150"
visible = "false"
name="radio_material_type">
@@ -179,6 +194,50 @@
top_pad="1"
value="2"/>
</radio_group>
+ <radio_group
+ height="84"
+ layout="topleft"
+ left_delta="0"
+ top_delta="0"
+ width="150"
+ visible = "false"
+ name="radio_pbr_type">
+ <radio_item
+ label="Complete material"
+ name="Complete material"
+ top="0"
+ layout="topleft"
+ height="16"
+ value="0"/>
+ <radio_item
+ label="Base color"
+ name="Base color"
+ layout="topleft"
+ top_pad="1"
+ height="16"
+ value="1"/>
+ <radio_item
+ label="Metallic/roughness"
+ name="Metallic/roughness"
+ height="16"
+ layout="topleft"
+ top_pad="1"
+ value="2"/>
+ <radio_item
+ label="Emissive"
+ name="Emissive"
+ layout="topleft"
+ top_pad="1"
+ height="16"
+ value="3"/>
+ <radio_item
+ label="Normal"
+ layout="topleft"
+ top_pad="1"
+ height="16"
+ name="Normal"
+ value="4"/>
+ </radio_group>
<menu_button
menu_filename="menu_copy_paste_texture.xml"
follows="top|left"
@@ -195,7 +254,7 @@
<check_box
control_name="SyncMaterialSettings"
follows="top|left"
- height="20"
+ height="47"
initial_value="false"
label="Lock repeat"
layout="topleft"
@@ -206,6 +265,59 @@
width="160" />
<texture_picker
can_apply_immediately="true"
+ allow_no_texture="true"
+ follows="left|top"
+ height="80"
+ label="Material"
+ layout="topleft"
+ left="10"
+ name="pbr_control"
+ tool_tip="Click to choose a pbr material"
+ top_pad="5"
+ width="64" />
+ <button
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_pad="10"
+ top_delta="0"
+ name="pbr_from_inventory"
+ label="Choose from inventory"
+ width="140"/>
+ <text
+ visible="false"
+ type="string"
+ length="1"
+ follows="left|top"
+ height="10"
+ layout="topleft"
+ top_pad="4"
+ left_delta="0"
+ name="material_permissions_loading_label"
+ text_readonly_color="LabelDisabledColor"
+ width="160">
+ Loading contents...
+ </text>
+ <button
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ top_delta="0"
+ name="edit_selected_pbr"
+ label="Edit Selected"
+ width="140"/>
+ <button
+ follows="left|top"
+ height="23"
+ layout="topleft"
+ left_delta="0"
+ top_pad="4"
+ name="save_selected_pbr"
+ label="Save to inventory"
+ width="140"/>
+ <texture_picker
+ can_apply_immediately="true"
default_image_name="Default"
fallback_image="materials_ui_x_24.png"
follows="left|top"
@@ -215,7 +327,7 @@
left="10"
name="texture control"
tool_tip="Click to choose a picture"
- top_pad="5"
+ top_delta="-54"
width="64" />
<text
type="string"
@@ -814,13 +926,13 @@
left="7"
name="checkbox planar align"
tool_tip="Align textures on all selected faces with the last selected face. Requires Planar texture mapping."
- top_delta="16"
+ top_delta="20"
width="260" />
<button
- follows="left|top"
- layout="topleft"
+ follows="left|top"
+ layout="topleft"
left="9"
- top="204"
+ top="231"
height="20"
label="Align"
label_selected="Align current texture layers"
@@ -839,4 +951,67 @@
height="4"
start_url="about:blank"
decouple_texture_size="true" />
- </panel>
+ <!-- BEGIN PBR Material texture transform parameters -->
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="1"
+ label="Scale u"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="gltfTextureScaleU"
+ top_delta="34"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="1"
+ label="Scale v"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-100"
+ max_val="100"
+ name="gltfTextureScaleV"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Rotation"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-360"
+ max_val="360"
+ name="gltfTextureRotation"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Offset u"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-999"
+ max_val="999"
+ name="gltfTextureOffsetU"
+ width="265" />
+ <spinner
+ follows="left|top"
+ height="19"
+ initial_value="0"
+ label="Offset v"
+ label_width="205"
+ layout="topleft"
+ left="10"
+ min_val="-999"
+ max_val="999"
+ name="gltfTextureOffsetV"
+ width="265" />
+ <!-- END PBR Material texture transform parameters -->
+</panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 844af62905..5d33853adc 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -319,6 +319,11 @@ Only items with unrestricted
'next owner' permissions
can be attached to notecards.
</string>
+ <string name="TooltipTextureRestrictedDrop">
+Only textures with unrestricted
+copy and transfer permissions
+are allowed.
+ </string>
<!-- searching - generic -->
<string name="Searching">Searching...</string>
@@ -403,6 +408,7 @@ http://secondlife.com/support for help fixing this problem.
<string name="symbolic link">link</string>
<string name="symbolic folder link">folder link</string>
<string name="settings blob">settings</string>
+ <string name="render material">material</string>
<string name="mesh">mesh</string>
<!-- llvoavatar. Displayed in the avatar chat bubble -->
@@ -2433,6 +2439,7 @@ If you continue to receive this message, please contact Second Life support for
<string name="Clothing" value=" Clothing," />
<string name="Gestures" value=" Gestures," />
<string name="Landmarks" value=" Landmarks," />
+ <string name="Materials" value=" Materials," />
<string name="Notecards" value=" Notecards," />
<string name="Objects" value=" Objects," />
<string name="Scripts" value=" Scripts," />
@@ -2478,6 +2485,9 @@ If you continue to receive this message, please contact Second Life support for
<string name="InvFolder Meshes">Meshes</string>
<string name="InvFolder Received Items">Received Items</string>
<string name="InvFolder Merchant Outbox">Merchant Outbox</string>
+ <string name="InvFolder Settings">Settings</string>
+ <string name="InvFolder Material">Materials</string>
+ <string name="InvFolder Materials">Materials</string>
<!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
<string name="InvFolder Friends">Friends</string>
@@ -3002,16 +3012,6 @@ Running in window.
<string name="MBDevContextErr">Can't make GL device context</string>
<string name="MBPixelFmtErr">Can't find suitable pixel format</string>
<string name="MBPixelFmtDescErr">Can't get pixel format description</string>
- <string name="MBTrueColorWindow">
- [APP_NAME] requires True Color (32-bit) to run.
-Please go to your computer's display settings and set the color mode to 32-bit.
- </string>
- <string name="MBAlpha">
- [APP_NAME] is unable to run because it can't get an 8 bit alpha channel. Usually this is due to video card driver issues.
-Please make sure you have the latest video card drivers installed.
-Also be sure your monitor is set to True Color (32-bit) in Control Panels &gt; Display &gt; Settings.
-If you continue to receive this message, contact the [SUPPORT_SITE].
- </string>
<string name="MBPixelFmtSetErr">Can't set pixel format</string>
<string name="MBGLContextErr">Can't create GL rendering context</string>
<string name="MBGLContextActErr">Can't activate GL rendering context</string>
@@ -3858,6 +3858,7 @@ Abuse Report</string>
<string name="New Physics">New Physics</string>
<string name="Invalid Wearable">Invalid Wearable</string>
<string name="New Gesture">New Gesture</string>
+ <string name="New Material">New Material</string>
<string name="New Script">New Script</string>
<string name="New Note">New Note</string>
<string name="New Folder">New Folder</string>
@@ -4280,6 +4281,9 @@ name="Command_360_Capture_Tooltip">Capture a 360 equirectangular image</string>
<string name="ExperiencePermissionShort16">Sit</string>
<string name="ExperiencePermissionShort17">Environment</string>
+ <!-- PBR Materials -->
+ <string name="Material Texture Name Header">Textures present this material: </string>
+
<!-- Conversation log messages -->
<string name="logging_calls_disabled_log_empty">
Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
diff --git a/indra/newview/tests/lldir_stub.cpp b/indra/newview/tests/lldir_stub.cpp
index 2bc6772d86..911e9334dd 100644
--- a/indra/newview/tests/lldir_stub.cpp
+++ b/indra/newview/tests/lldir_stub.cpp
@@ -30,25 +30,29 @@ LLDir::LLDir() {}
LLDir::~LLDir() {}
BOOL LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask) { return true; }
void LLDir::setChatLogsDir(const std::string &path) {}
-void LLDir::setPerAccountChatLogsDir(const std::string &first, const std::string &last) {}
-void LLDir::setLindenUserDir(const std::string &first, const std::string &last) {}
+void LLDir::setPerAccountChatLogsDir(const std::string &) {}
+void LLDir::updatePerAccountChatLogsDir() {}
+void LLDir::setLindenUserDir(const std::string &) {}
void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language) {}
bool LLDir::setCacheDir(const std::string &path) { return true; }
-void LLDir::dumpCurrentDirectories() {}
+void LLDir::dumpCurrentDirectories(LLError::ELevel) {}
+std::string LLDir::getSkinFolder() const { return ""; }
+std::string LLDir::getLanguage() const { return ""; }
+
class LLDir_stub : public LLDir
{
public:
- LLDir_stub() {}
- ~LLDir_stub() {}
+ LLDir_stub() = default;
+ ~LLDir_stub() = default;
+
+ void initAppDirs(const std::string &app_name, const std::string &) override {}
- /*virtual*/ void initAppDirs(const std::string &app_name) {}
+ std::string getCurPath() override { return "CUR_PATH_FROM_LLDIR"; }
+ bool fileExists(const std::string &filename) const override { return false; }
- /*virtual*/ std::string getCurPath() { return "CUR_PATH_FROM_LLDIR"; }
- /*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask) { return 42; }
- /*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) { fname = fname + "_NEXT"; return false; }
- /*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) { fname = "RANDOM_FILE"; }
- /*virtual*/ bool fileExists(const std::string &filename) const { return false; }
+ std::string getLLPluginLauncher() override { return ""; }
+ std::string getLLPluginFilename(std::string base_name) override { return ""; }
};
LLDir_stub gDirUtil;
@@ -60,3 +64,7 @@ std::string LLDir::getExpandedFilename(ELLPath loc, const std::string& subdir, c
return subdir + " --- " + filename + " --- expanded!";
}
+std::string LLDir::getExpandedFilename(ELLPath location, const std::string &filename) const
+{
+ return filename + " --- expanded!";
+}
diff --git a/indra/newview/tests/llviewercontrollistener_test.cpp b/indra/newview/tests/llviewercontrollistener_test.cpp
new file mode 100644
index 0000000000..8aed2a8043
--- /dev/null
+++ b/indra/newview/tests/llviewercontrollistener_test.cpp
@@ -0,0 +1,173 @@
+/**
+ * @file llviewercontrollistener_test.cpp
+ * @author Nat Goodspeed
+ * @date 2022-06-09
+ * @brief Test for llviewercontrollistener.
+ *
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Copyright (c) 2022, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "../llviewerprecompiledheaders.h"
+// associated header
+#include "../llviewercontrollistener.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "../test/lltut.h"
+#include "../test/catch_and_store_what_in.h" // catch_what()
+#include "commoncontrol.h"
+#include "llcontrol.h" // LLControlGroup
+
+/*****************************************************************************
+* TUT
+*****************************************************************************/
+namespace tut
+{
+ void ensure_contains(const std::string& msg, const std::string& substr)
+ {
+ ensure_contains("Exception does not contain " + substr, msg, substr);
+ }
+
+ struct llviewercontrollistener_data
+ {
+ LLControlGroup Global{"FakeGlobal"};
+
+ llviewercontrollistener_data()
+ {
+ Global.declareString("strvar", "woof", "string variable");
+ // together we will stroll the boolvar, ma cherie
+ Global.declareBOOL("boolvar", TRUE, "bool variable");
+ }
+ };
+ typedef test_group<llviewercontrollistener_data> llviewercontrollistener_group;
+ typedef llviewercontrollistener_group::object object;
+ llviewercontrollistener_group llviewercontrollistenergrp("llviewercontrollistener");
+
+ template<> template<>
+ void object::test<1>()
+ {
+ set_test_name("CommonControl no listener");
+ // Not implemented: the linker drags in LLViewerControlListener when
+ // we bring in LLViewerControl.
+ }
+
+ template<> template<>
+ void object::test<2>()
+ {
+ set_test_name("CommonControl bad group");
+ std::string threw{ catch_what<LL::CommonControl::ParamError>(
+ [](){ LL::CommonControl::get("Nonexistent", "Variable"); }) };
+ ensure_contains(threw, "group");
+ ensure_contains(threw, "Nonexistent");
+ }
+
+ template<> template<>
+ void object::test<3>()
+ {
+ set_test_name("CommonControl bad variable");
+ std::string threw{ catch_what<LL::CommonControl::ParamError>(
+ [](){ LL::CommonControl::get("FakeGlobal", "Nonexistent"); }) };
+ ensure_contains(threw, "key");
+ ensure_contains(threw, "Nonexistent");
+ }
+
+ template<> template<>
+ void object::test<4>()
+ {
+ set_test_name("CommonControl toggle string");
+ std::string threw{ catch_what<LL::CommonControl::ParamError>(
+ [](){ LL::CommonControl::toggle("FakeGlobal", "strvar"); }) };
+ ensure_contains(threw, "non-boolean");
+ ensure_contains(threw, "strvar");
+ }
+
+ template<> template<>
+ void object::test<5>()
+ {
+ set_test_name("CommonControl list bad group");
+ std::string threw{ catch_what<LL::CommonControl::ParamError>(
+ [](){ LL::CommonControl::get_vars("Nonexistent"); }) };
+ ensure_contains(threw, "group");
+ ensure_contains(threw, "Nonexistent");
+ }
+
+ template<> template<>
+ void object::test<6>()
+ {
+ set_test_name("CommonControl get");
+ auto strvar{ LL::CommonControl::get("FakeGlobal", "strvar") };
+ ensure_equals(strvar, "woof");
+ auto boolvar{ LL::CommonControl::get("FakeGlobal", "boolvar") };
+ ensure(boolvar);
+ }
+
+ template<> template<>
+ void object::test<7>()
+ {
+ set_test_name("CommonControl set, set_default, toggle");
+
+ std::string newstr{ LL::CommonControl::set("FakeGlobal", "strvar", "mouse").asString() };
+ ensure_equals(newstr, "mouse");
+ ensure_equals(LL::CommonControl::get("FakeGlobal", "strvar").asString(), "mouse");
+ ensure_equals(LL::CommonControl::set_default("FakeGlobal", "strvar").asString(), "woof");
+
+ bool newbool{ LL::CommonControl::set("FakeGlobal", "boolvar", false) };
+ ensure(! newbool);
+ ensure(! LL::CommonControl::get("FakeGlobal", "boolvar").asBoolean());
+ ensure(LL::CommonControl::set_default("FakeGlobal", "boolvar").asBoolean());
+ ensure(! LL::CommonControl::toggle("FakeGlobal", "boolvar").asBoolean());
+ }
+
+ template<> template<>
+ void object::test<8>()
+ {
+ set_test_name("CommonControl get_def");
+ LLSD def{ LL::CommonControl::get_def("FakeGlobal", "strvar") };
+ ensure_equals(
+ def,
+ llsd::map("name", "strvar",
+ "type", "String",
+ "value", "woof",
+ "comment", "string variable"));
+ }
+
+ template<> template<>
+ void object::test<9>()
+ {
+ set_test_name("CommonControl get_groups");
+ std::vector<std::string> groups{ LL::CommonControl::get_groups() };
+ ensure_equals(groups.size(), 1);
+ ensure_equals(groups[0], "FakeGlobal");
+ }
+
+ template<> template<>
+ void object::test<10>()
+ {
+ set_test_name("CommonControl get_vars");
+ LLSD vars{ LL::CommonControl::get_vars("FakeGlobal") };
+ // convert from array (unpredictable order) to map
+ LLSD varsmap{ LLSD::emptyMap() };
+ for (auto& var : llsd::inArray(vars))
+ {
+ varsmap[var["name"].asString()] = var;
+ }
+ // comparing maps is order-insensitive
+ ensure_equals(
+ varsmap,
+ llsd::map(
+ "strvar",
+ llsd::map("name", "strvar",
+ "type", "String",
+ "value", "woof",
+ "comment", "string variable"),
+ "boolvar",
+ llsd::map("name", "boolvar",
+ "type", "Boolean",
+ "value", TRUE,
+ "comment", "bool variable")));
+ }
+} // namespace tut
diff --git a/indra/newview/tests/llvieweroctree_stub.cpp b/indra/newview/tests/llvieweroctree_stub.cpp
new file mode 100644
index 0000000000..ab180c49a3
--- /dev/null
+++ b/indra/newview/tests/llvieweroctree_stub.cpp
@@ -0,0 +1,86 @@
+/**
+ * @file llvieweroctree_stub.cpp
+ * @brief stub implementations to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+S32 AABBSphereIntersect(const LLVector4a& min, const LLVector4a& max, const LLVector3 &origin, const F32 &rad) { return 0; }
+
+void LLViewerOctreeCull::traverse(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
+void LLViewerOctreeCull::visit(const LLOctreeNode<LLViewerOctreeEntry, LLPointer<LLViewerOctreeEntry> >* node) { }
+void LLViewerOctreeCull::preprocess(LLViewerOctreeGroup* group) {}
+bool LLViewerOctreeCull::earlyFail(LLViewerOctreeGroup* group) { return false; }
+bool LLViewerOctreeCull::checkProjectionArea(const LLVector4a& center, const LLVector4a& size, const LLVector3& shift, F32 pixel_threshold, F32 near_radius) { return false; }
+bool LLViewerOctreeCull::checkObjects(const OctreeNode* branch, const LLViewerOctreeGroup* group) { return false; }
+void LLViewerOctreeCull::processGroup(LLViewerOctreeGroup* group) {}
+
+
+bool LLViewerOctreeGroup::boundObjects(BOOL empty, LLVector4a& minOut, LLVector4a& maxOut) { return false; }
+void LLViewerOctreeGroup::unbound() {}
+void LLViewerOctreeGroup::rebound() {}
+void LLViewerOctreeGroup::handleInsertion(const TreeNode* node, LLViewerOctreeEntry* obj) {}
+void LLViewerOctreeGroup::handleRemoval(const TreeNode* node, LLViewerOctreeEntry* obj) {}
+void LLViewerOctreeGroup::handleDestruction(const TreeNode* node) {}
+void LLViewerOctreeGroup::handleStateChange(const TreeNode* node) {}
+void LLViewerOctreeGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* child) {}
+void LLViewerOctreeGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNode* child) {}
+
+LLOcclusionCullingGroup::LLOcclusionCullingGroup(OctreeNode* node, LLViewerOctreePartition* part) :
+ LLViewerOctreeGroup(node),
+ mSpatialPartition(part)
+{
+}
+LLOcclusionCullingGroup::~LLOcclusionCullingGroup() = default;
+void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift) {}
+void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode) {}
+void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode) {}
+void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode *parent, OctreeNode *child) {}
+BOOL LLOcclusionCullingGroup::isRecentlyVisible() const { return FALSE; }
+BOOL LLOcclusionCullingGroup::isAnyRecentlyVisible() const { return FALSE; }
+
+
+LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node) : mOctreeNode(node) {}
+LLViewerOctreeGroup::~LLViewerOctreeGroup() = default;
+
+LLViewerOctreeEntryData::LLViewerOctreeEntryData(LLViewerOctreeEntry::eEntryDataType_t) {}
+LLViewerOctreeEntryData::~LLViewerOctreeEntryData() = default;
+bool LLViewerOctreeEntryData::isVisible() const { return false; }
+bool LLViewerOctreeEntryData::isRecentlyVisible() const { return false; }
+void LLViewerOctreeEntryData::setVisible() const {}
+void LLViewerOctreeEntryData::resetVisible() const {}
+const LLVector4a& LLViewerOctreeEntryData::getPositionGroup() const { return LLVector4a::getZero(); }
+const LLVector4a* LLViewerOctreeEntryData::getSpatialExtents() const { return nullptr; }
+LLViewerOctreeGroup* LLViewerOctreeEntryData::getGroup() const { return nullptr; }
+void LLViewerOctreeEntryData::setSpatialExtents(const LLVector4a& min, const LLVector4a& max) {}
+void LLViewerOctreeEntryData::setPositionGroup(const LLVector4a& pos) {}
+void LLViewerOctreeEntryData::setGroup(LLViewerOctreeGroup* group) {}
+void LLViewerOctreeEntryData::setOctreeEntry(LLViewerOctreeEntry* entry) {}
+U32 LLViewerOctreeEntryData::sCurVisible{};
+
+LLViewerOctreePartition::LLViewerOctreePartition() = default;
+LLViewerOctreePartition::~LLViewerOctreePartition() = default;
+void LLViewerOctreePartition::cleanup() {}
+
+BOOL LLViewerOctreeGroup::isRecentlyVisible() const { return FALSE; }
+
+
diff --git a/indra/newview/tests/llvocache_test.cpp b/indra/newview/tests/llvocache_test.cpp
new file mode 100644
index 0000000000..c27730eb58
--- /dev/null
+++ b/indra/newview/tests/llvocache_test.cpp
@@ -0,0 +1,147 @@
+/**
+ * @file llvocache_.cpp
+ * @author Brad
+ * @date 2023-03-01
+ * @brief Test Viewer Object Cache functionality
+ *
+ * $LicenseInfo:firstyear=2023&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2014, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+#include "../llviewerprecompiledheaders.h"
+#include "../test/lltut.h"
+
+#include "../llvocache.h"
+
+#include "lldir.h"
+#include "../llhudobject.h"
+#include "llregionhandle.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#include "../llviewerobjectlist.h"
+#include "../llviewerregion.h"
+
+#include "lldir_stub.cpp"
+#include "llvieweroctree_stub.cpp"
+
+namespace
+{
+
+}
+
+
+//----------------------------------------------------------------------------
+// Mock objects for the dependencies of the code we're testing
+S32 LLVOCachePartition::cull(LLCamera &camera, bool do_occlusion) { return 0; }
+
+LLViewerObjectList::LLViewerObjectList() = default;
+LLViewerObjectList::~LLViewerObjectList() = default;
+LLDebugBeacon::~LLDebugBeacon() = default;
+LLViewerObjectList gObjectList{};
+LLViewerCamera::eCameraID LLViewerCamera::sCurCameraID{};
+void LLViewerObject::unpackUUID(LLDataPackerBinaryBuffer *dp, LLUUID &value, std::string name) {}
+
+bool LLViewerRegion::addVisibleGroup(LLViewerOctreeGroup*) { return false; }
+U32 LLViewerRegion::getNumOfVisibleGroups() const { return 0; }
+LLVector3 LLViewerRegion::getOriginAgent() const { return LLVector3::zero; }
+S32 LLViewerRegion::sLastCameraUpdated{};
+
+// -------------------------------------------------------------------------------------------
+// TUT
+// -------------------------------------------------------------------------------------------
+namespace tut
+{
+ // Test wrapper declaration
+ struct vocacheTest
+ {
+ vocacheTest() = default;
+ ~vocacheTest() = default;
+
+ static const std::string override_llsd_text[];
+ };
+
+ const std::string vocacheTest::override_llsd_text[]{
+ // sample override contents captured from traffic
+ R"(<? llsd/notation ?>
+ {'gltf_json':['{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n','{"asset":{"version":"2.0"},"images":[{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"},{"uri":"00000000-0000-0000-0000-000000000000"}],"materials":[{"emissiveTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":3},"normalTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":1},"occlusionTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":4},"pbrMetallicRoughness":{"baseColorTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":0},"metallicRoughnessTexture":{"extensions":{"KHR_texture_transform":{"offset":[0.0,0.0],"rotation":0.0,"scale":[2.0,2.0]}},"index":2}}}],"textures":[{"source":0},{"source":1},{"source":2},{"source":3},{"source":4}]}\n'],'object_id':u8b357110-4845-1d40-1cf0-cc4a2c22a4f1,'sides':[i0,i1,i2,i3,i4,i5,i6]})"
+ };
+
+ // Tut templating thingamagic: test group, object and test instance
+ struct vocacheTestFactory : public test_group<vocacheTest>
+ {
+ vocacheTestFactory()
+ : test_group<vocacheTest>("LLVOCache")
+ {
+ ll_init_apr();
+
+ const bool READ_ONLY = false;
+ const U32 INDRA_OBJECT_CACHE_VERSION = 15; // see LLAppViewer::getObjectCacheVersion()
+ const U32 CACHE_NUMBER_OF_REGIONS = 128; // see setting CacheNumberOfRegionsForObjects
+
+ LLVOCache &instance = LLVOCache::initParamSingleton(READ_ONLY);
+ instance.initCache(LL_PATH_CACHE, CACHE_NUMBER_OF_REGIONS, INDRA_OBJECT_CACHE_VERSION);
+ }
+
+ ~vocacheTestFactory()
+ {
+ LLVOCache::deleteSingleton();
+ ll_cleanup_apr();
+ }
+
+ };
+
+ typedef vocacheTestFactory::object vocacheTestObject;
+ tut::vocacheTestFactory tut_test;
+
+ // ---------------------------------------------------------------------------------------
+ // Test functions
+ // ---------------------------------------------------------------------------------------
+
+ template<> template<>
+ void vocacheTestObject::test<1>()
+ {
+ LLGLTFOverrideCacheEntry entry{};
+ LLSD entry_llsd;
+
+ std::istringstream in_llsd(override_llsd_text[0]);
+ bool success = LLSDSerialize::deserialize(entry_llsd, in_llsd, override_llsd_text[0].length());
+
+ ensure("llsd deserialize succeeds", success);
+
+ entry.fromLLSD(entry_llsd);
+ ensure_equals("entry object_id match", entry.mObjectId, LLUUID("8b357110-4845-1d40-1cf0-cc4a2c22a4f1"));
+ ensure_equals("sides count", entry.mSides.size(), 7);
+
+ //std::cout << other << std::endl;
+ ensure_equals("toLLSD() match", entry.toLLSD(), entry_llsd);
+ }
+
+ template<> template<>
+ void vocacheTestObject::test<2>()
+ {
+ LLVOCacheEntry::vocache_gltf_overrides_map_t extras;
+
+ U64 region_handle = to_region_handle(140, 81);
+ LLUUID region_id = LLUUID::generateNewID();
+
+ LLVOCache::instance().readGenericExtrasFromCache(region_handle, region_id, extras);
+ }
+}