summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolwater.cpp
diff options
context:
space:
mode:
authorAnsariel <ansariel.hiller@phoenixviewer.com>2024-05-22 21:25:21 +0200
committerAndrey Lihatskiy <alihatskiy@productengine.com>2024-05-22 22:40:26 +0300
commite2e37cced861b98de8c1a7c9c0d3a50d2d90e433 (patch)
tree1bb897489ce524986f6196201c10ac0d8861aa5f /indra/newview/lldrawpoolwater.cpp
parent069ea06848f766466f1a281144c82a0f2bd79f3a (diff)
Fix line endlings
Diffstat (limited to 'indra/newview/lldrawpoolwater.cpp')
-rw-r--r--indra/newview/lldrawpoolwater.cpp722
1 files changed, 361 insertions, 361 deletions
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 7d86055543..793d84652b 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -1,361 +1,361 @@
-/**
- * @file lldrawpoolwater.cpp
- * @brief LLDrawPoolWater 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 "llfeaturemanager.h"
-#include "lldrawpoolwater.h"
-
-#include "llviewercontrol.h"
-#include "lldir.h"
-#include "llerror.h"
-#include "m3math.h"
-#include "llrender.h"
-
-#include "llagent.h" // for gAgent for getRegion for getWaterHeight
-#include "llcubemap.h"
-#include "lldrawable.h"
-#include "llface.h"
-#include "llsky.h"
-#include "llviewertexturelist.h"
-#include "llviewerregion.h"
-#include "llvowater.h"
-#include "llworld.h"
-#include "pipeline.h"
-#include "llviewershadermgr.h"
-#include "llenvironment.h"
-#include "llsettingssky.h"
-#include "llsettingswater.h"
-
-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)
-{
-}
-
-LLDrawPoolWater::~LLDrawPoolWater()
-{
-}
-
-void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId)
-{
- LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId());
- mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()));
- mWaterImagep[0]->addTextureStats(1024.f*1024.f);
- mWaterImagep[1]->addTextureStats(1024.f*1024.f);
-}
-
-void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId)
-{
- LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId);
- mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
-}
-
-void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId)
-{
- LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
- mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId());
- mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()));
- mWaterNormp[0]->addTextureStats(1024.f*1024.f);
- mWaterNormp[1]->addTextureStats(1024.f*1024.f);
-}
-
-void LLDrawPoolWater::prerender()
-{
- mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
-}
-
-S32 LLDrawPoolWater::getNumPostDeferredPasses()
-{
- if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
- {
- return 1;
- }
-
- return 0;
-}
-
-void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
-{
- LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
- gGL.setColorMask(true, true);
-
- if (LLPipeline::sRenderTransparentWater)
- {
- // copy framebuffer contents so far to a texture to be used for
- // reflections and refractions
- LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
-
- LLRenderTarget& src = gPipeline.mRT->screen;
- LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
- LLRenderTarget& dst = gPipeline.mWaterDis;
-
- dst.bindTarget();
- 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);
-
- gPipeline.mScreenTriangleVB->setBuffer();
- gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
-
- dst.flush();
- }
-}
-
-void LLDrawPoolWater::renderPostDeferred(S32 pass)
-{
- LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
- 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();
- 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)
- {
- light_diffuse += psky->getSunlightColor();
- }
- // moonlight is several orders of magnitude less bright than sunlight,
- // so only use this color when the moon alone is showing
- else if (moon_up)
- {
- light_diffuse += psky->getMoonlightColor();
- }
-
- // Apply magic numbers translating light direction into intensities
- light_dir.normalize();
- 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++)
- {
- // select shader
- if (underwater)
- {
- shader = &gUnderWaterProgram;
- }
- else
- {
- if (edge)
- {
- shader = &gWaterEdgeProgram;
- }
- else
- {
- shader = &gWaterProgram;
- }
- }
-
- gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
-
- //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];
-
- F32 blend_factor = pwater->getBlendFactor();
-
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
-
- if (tex_a && (!tex_b || (tex_a == tex_b)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- 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
- }
- else if (tex_b != tex_a)
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
- }
-
- // bind reflection texture from RenderTarget
- S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
-
- F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
-
- S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
-
- shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
- shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
-
- F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
-
- if (screentex > -1)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
-
- if (mShaderLevel == 1)
- {
- fog_color.mV[VW] = log(fog_density) / log(2);
- }
-
- 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);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
-
- 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);
-
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
-
- shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
-
- shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
- shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
- 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 scaledAngle = 1.f - sunAngle;
-
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
- shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
- shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
- shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
-
- // 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())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
-
- LLGLDisable cullface(GL_CULL_FACE);
-
- LLVOWater* water = nullptr;
- for (LLFace* const& face : mDrawFace)
- {
- if (!face) continue;
- water = static_cast<LLVOWater*>(face->getViewerObject());
- if (!water) continue;
-
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- if ((bool)edge == (bool)water->getIsEdgePatch())
- {
- face->renderIndexed();
-
- // Note non-void water being drawn, updates required
- if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
- {
- sNeedsReflectionUpdate = true;
- sNeedsDistortionUpdate = true;
- }
- }
- }
-
- shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
- shader->disableTexture(LLShaderMgr::BUMP_MAP);
- shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->disableTexture(LLShaderMgr::WATER_REFTEX);
-
- // clean up
- 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);
-
- gGL.setColorMask(true, false);
-}
-
-LLViewerTexture *LLDrawPoolWater::getDebugTexture()
-{
- return LLViewerTextureManager::getFetchedTexture(IMG_SMOKE);
-}
-
-LLColor3 LLDrawPoolWater::getDebugColor() const
-{
- return LLColor3(0.f, 1.f, 1.f);
-}
+/**
+ * @file lldrawpoolwater.cpp
+ * @brief LLDrawPoolWater 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 "llfeaturemanager.h"
+#include "lldrawpoolwater.h"
+
+#include "llviewercontrol.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "m3math.h"
+#include "llrender.h"
+
+#include "llagent.h" // for gAgent for getRegion for getWaterHeight
+#include "llcubemap.h"
+#include "lldrawable.h"
+#include "llface.h"
+#include "llsky.h"
+#include "llviewertexturelist.h"
+#include "llviewerregion.h"
+#include "llvowater.h"
+#include "llworld.h"
+#include "pipeline.h"
+#include "llviewershadermgr.h"
+#include "llenvironment.h"
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+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)
+{
+}
+
+LLDrawPoolWater::~LLDrawPoolWater()
+{
+}
+
+void LLDrawPoolWater::setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterImagep[0] = LLViewerTextureManager::getFetchedTexture(!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId());
+ mWaterImagep[1] = LLViewerTextureManager::getFetchedTexture(!nextTransparentTextureId.isNull() ? nextTransparentTextureId : (!transparentTextureId.isNull() ? transparentTextureId : pwater->GetDefaultTransparentTextureAssetId()));
+ mWaterImagep[0]->addTextureStats(1024.f*1024.f);
+ mWaterImagep[1]->addTextureStats(1024.f*1024.f);
+}
+
+void LLDrawPoolWater::setOpaqueTexture(const LLUUID& opaqueTextureId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(opaqueTextureId);
+ mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
+}
+
+void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId)
+{
+ LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
+ mWaterNormp[0] = LLViewerTextureManager::getFetchedTexture(!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId());
+ mWaterNormp[1] = LLViewerTextureManager::getFetchedTexture(!nextNormalMapId.isNull() ? nextNormalMapId : (!normalMapId.isNull() ? normalMapId : pwater->GetDefaultWaterNormalAssetId()));
+ mWaterNormp[0]->addTextureStats(1024.f*1024.f);
+ mWaterNormp[1]->addTextureStats(1024.f*1024.f);
+}
+
+void LLDrawPoolWater::prerender()
+{
+ mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0;
+}
+
+S32 LLDrawPoolWater::getNumPostDeferredPasses()
+{
+ if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f)
+ {
+ return 1;
+ }
+
+ return 0;
+}
+
+void LLDrawPoolWater::beginPostDeferredPass(S32 pass)
+{
+ LL_PROFILE_GPU_ZONE("water beginPostDeferredPass")
+ gGL.setColorMask(true, true);
+
+ if (LLPipeline::sRenderTransparentWater)
+ {
+ // copy framebuffer contents so far to a texture to be used for
+ // reflections and refractions
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+
+ LLRenderTarget& src = gPipeline.mRT->screen;
+ LLRenderTarget& depth_src = gPipeline.mRT->deferredScreen;
+ LLRenderTarget& dst = gPipeline.mWaterDis;
+
+ dst.bindTarget();
+ 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);
+
+ gPipeline.mScreenTriangleVB->setBuffer();
+ gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ dst.flush();
+ }
+}
+
+void LLDrawPoolWater::renderPostDeferred(S32 pass)
+{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ 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();
+ 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)
+ {
+ light_diffuse += psky->getSunlightColor();
+ }
+ // moonlight is several orders of magnitude less bright than sunlight,
+ // so only use this color when the moon alone is showing
+ else if (moon_up)
+ {
+ light_diffuse += psky->getMoonlightColor();
+ }
+
+ // Apply magic numbers translating light direction into intensities
+ light_dir.normalize();
+ 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++)
+ {
+ // select shader
+ if (underwater)
+ {
+ shader = &gUnderWaterProgram;
+ }
+ else
+ {
+ if (edge)
+ {
+ shader = &gWaterEdgeProgram;
+ }
+ else
+ {
+ shader = &gWaterProgram;
+ }
+ }
+
+ gPipeline.bindDeferredShader(*shader, nullptr, &gPipeline.mWaterDis);
+
+ //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];
+
+ F32 blend_factor = pwater->getBlendFactor();
+
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ 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
+ }
+ else if (tex_b != tex_a)
+ {
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ }
+
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+
+ F32 screenRes[] = { 1.f / gGLViewport[2], 1.f / gGLViewport[3] };
+
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
+
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
+
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
+
+ if (screentex > -1)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
+
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
+
+ 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);
+ shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+
+ 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);
+
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+
+ shader->uniform3fv(LLShaderMgr::WATER_LIGHT_DIR, 1, light_dir.mV);
+
+ shader->uniform3fv(LLShaderMgr::WATER_NORM_SCALE, 1, pwater->getNormalScale().mV);
+ shader->uniform1f(LLShaderMgr::WATER_FRESNEL_SCALE, pwater->getFresnelScale());
+ 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 scaledAngle = 1.f - sunAngle;
+
+ shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, sun_up ? 1 : 0);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE, sunAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SCALED_ANGLE, scaledAngle);
+ shader->uniform1f(LLShaderMgr::WATER_SUN_ANGLE2, 0.1f + 0.2f * sunAngle);
+ shader->uniform1i(LLShaderMgr::WATER_EDGE_FACTOR, edge ? 1 : 0);
+
+ // 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())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
+
+ LLGLDisable cullface(GL_CULL_FACE);
+
+ LLVOWater* water = nullptr;
+ for (LLFace* const& face : mDrawFace)
+ {
+ if (!face) continue;
+ water = static_cast<LLVOWater*>(face->getViewerObject());
+ if (!water) continue;
+
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
+
+ if ((bool)edge == (bool)water->getIsEdgePatch())
+ {
+ face->renderIndexed();
+
+ // Note non-void water being drawn, updates required
+ if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
+ {
+ sNeedsReflectionUpdate = true;
+ sNeedsDistortionUpdate = true;
+ }
+ }
+ }
+
+ shader->disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENTEX);
+ shader->disableTexture(LLShaderMgr::BUMP_MAP);
+ shader->disableTexture(LLShaderMgr::DIFFUSE_MAP);
+ shader->disableTexture(LLShaderMgr::WATER_REFTEX);
+
+ // clean up
+ 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);
+
+ gGL.setColorMask(true, false);
+}
+
+LLViewerTexture *LLDrawPoolWater::getDebugTexture()
+{
+ return LLViewerTextureManager::getFetchedTexture(IMG_SMOKE);
+}
+
+LLColor3 LLDrawPoolWater::getDebugColor() const
+{
+ return LLColor3(0.f, 1.f, 1.f);
+}