summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpoolwater.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/lldrawpoolwater.cpp')
-rw-r--r--indra/newview/lldrawpoolwater.cpp518
1 files changed, 216 insertions, 302 deletions
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index aa426cd785..6762b38c39 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -50,8 +50,6 @@
#include "llsettingssky.h"
#include "llsettingswater.h"
-static float sTime;
-
BOOL deferred_render = FALSE;
BOOL LLDrawPoolWater::sSkipScreenCopy = FALSE;
@@ -136,9 +134,17 @@ void LLDrawPoolWater::endPostDeferredPass(S32 pass)
//===============================
void LLDrawPoolWater::renderDeferred(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
+
+ if (!LLPipeline::sRenderTransparentWater)
+ {
+ // Will render opaque water without use of ALM
+ render(pass);
+ return;
+ }
+
deferred_render = TRUE;
- shade();
+ renderWater();
deferred_render = FALSE;
}
@@ -146,7 +152,7 @@ void LLDrawPoolWater::renderDeferred(S32 pass)
void LLDrawPoolWater::render(S32 pass)
{
- LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER);
if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
{
return;
@@ -174,7 +180,7 @@ void LLDrawPoolWater::render(S32 pass)
if ((mShaderLevel > 0) && !sSkipScreenCopy)
{
- shade();
+ renderWater();
return;
}
@@ -233,9 +239,6 @@ void LLDrawPoolWater::render(S32 pass)
glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
- gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
- gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);
-
gGL.getTexUnit(0)->activate();
glClearStencil(1);
@@ -293,8 +296,6 @@ void LLDrawPoolWater::render(S32 pass)
gGL.matrixMode(LLRender::MM_MODELVIEW);
LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
iter != mDrawFace.end(); iter++)
{
@@ -311,8 +312,6 @@ void LLDrawPoolWater::render(S32 pass)
}
}
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-
gSky.mVOSkyp->getCubeMap()->disable();
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -330,30 +329,31 @@ void LLDrawPoolWater::render(S32 pass)
glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
renderReflection(refl_face);
}
-
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
// for low end hardware
void LLDrawPoolWater::renderOpaqueLegacyWater()
{
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ LLVOSky *voskyp = gSky.mVOSkyp;
+
+ if (voskyp == NULL)
+ {
+ return;
+ }
LLGLSLShader* shader = NULL;
- if (LLGLSLShader::sNoFixedFunction)
+ if (LLPipeline::sUnderWaterRender)
{
- if (LLPipeline::sUnderWaterRender)
- {
- shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
- }
- else
- {
- shader = &gObjectSimpleNonIndexedTexGenProgram;
- }
-
- shader->bind();
+ shader = &gObjectSimpleNonIndexedTexGenWaterProgram;
+ }
+ else
+ {
+ shader = &gObjectSimpleNonIndexedTexGenProgram;
}
+ shader->bind();
+
stop_glerror();
// Depth sorting and write to depth buffer
@@ -438,12 +438,12 @@ void LLDrawPoolWater::renderOpaqueLegacyWater()
}
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
void LLDrawPoolWater::renderReflection(LLFace* face)
{
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
LLVOSky *voskyp = gSky.mVOSkyp;
if (!voskyp)
@@ -470,330 +470,244 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
face->renderIndexed();
}
-void LLDrawPoolWater::shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp)
+void LLDrawPoolWater::renderWater()
{
- F32 water_height = LLEnvironment::instance().getWaterHeight();
- F32 camera_height = LLViewerCamera::getInstance()->getOrigin().mV[2];
- F32 eyedepth = camera_height - water_height;
- bool underwater = eyedepth <= 0.0f;
-
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
-
- shader->bind();
-
-// bind textures for water rendering
- 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);
- }
- }
-
- LLColor4 specular(psky->getIsSunUp() ? psky->getSunlightColor() : psky->getMoonlightColor());
- shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
-
- sTime = (F32)LLFrameTimer::getElapsedSeconds() * 0.5f;
-
- S32 reftex = shader->enableTexture(LLShaderMgr::WATER_REFTEX);
-
- if (reftex > -1)
- {
- gGL.getTexUnit(reftex)->activate();
- gGL.getTexUnit(reftex)->bind(&gPipeline.mWaterRef);
- gGL.getTexUnit(0)->activate();
- }
+ LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
+ if (!deferred_render)
+ {
+ gGL.setColorMask(true, true);
+ }
- //bind normal map
- S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
- S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
+ LLGLDisable blend(GL_BLEND);
- LLViewerTexture* tex_a = mWaterNormp[0];
- LLViewerTexture* tex_b = mWaterNormp[1];
+ LLColor3 light_diffuse(0, 0, 0);
+ F32 light_exp = 0.0f;
- F32 blend_factor = LLEnvironment::instance().getCurrentWater()->getBlendFactor();
-
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ 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();
- if (tex_a && (!tex_b || (tex_a == tex_b)))
+ if (sun_up)
{
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
+ light_diffuse += psky->getSunlightColor();
}
- else if (tex_b && !tex_a)
+ // 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)
{
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- blend_factor = 0; // only one tex provided, no blending
+ light_diffuse += psky->getMoonlightColor();
}
- else if (tex_b != tex_a)
+
+ // 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...
{
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
-
- // 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);
- stop_glerror();
-
-// set uniforms for water rendering
- 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)
- {
- shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
- gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
- }
-
- if (mShaderLevel == 1)
+ // set up normal maps filtering
+ for (auto norm_map : mWaterNormp)
{
- //F32 fog_density_slider_value = param_mgr->mDensitySliderValue;
- //sWaterFogColor.mV[3] = fog_density_slider_value;
- fog_color.mV[VW] = log(fog_density) / log(2);
- }
+ if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
+ }
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
+ LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
+ F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
+ LLGLSLShader *shader = nullptr;
- //shader->uniformMatrix4fv("inverse_ref", 1, GL_FALSE, (GLfloat*) gGLObliqueProjectionInverse.mMatrix);
- shader->uniform1f(LLShaderMgr::WATER_WATERHEIGHT, eyedepth);
- shader->uniform1f(LLShaderMgr::WATER_TIME, sTime);
- shader->uniform3fv(LLShaderMgr::WATER_EYEVEC, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
- shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
- if (LLEnvironment::instance().isCloudScrollPaused())
- {
- static const std::array<F32, 2> zerowave{ {0.0f, 0.0f} };
-
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
- }
- else
+ // two passes, first with standard water shader bound, second with edge water shader bound
+ for( int edge = 0 ; edge < 2; edge++ )
{
- 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);
+ // select shader
+ if (underwater && LLPipeline::sWaterReflections)
+ {
+ shader = deferred_render ? &gDeferredUnderWaterProgram : &gUnderWaterProgram;
+ }
+ else
+ {
+ if (edge && !deferred_render)
+ {
+ shader = &gWaterEdgeProgram;
+ }
+ else
+ {
+ shader = deferred_render ? &gDeferredWaterProgram : &gWaterProgram;
+ }
+ }
+ shader->bind();
- 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());
+ // 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();
+ }
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ // bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- shader->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 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);
+ LLViewerTexture *tex_a = mWaterNormp[0];
+ LLViewerTexture *tex_b = mWaterNormp[1];
- LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
- shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
- shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
+ F32 blend_factor = pwater->getBlendFactor();
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
-
- {
- LLGLDisable cullface(GL_CULL_FACE);
+ gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
- if (edge)
+ if (tex_a && (!tex_b || (tex_a == tex_b)))
{
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (face)
- {
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- if (water)
- {
- bool edge_patch = water->getIsEdgePatch();
- if (edge_patch)
- {
- //sNeedsReflectionUpdate = TRUE;
- face->renderIndexed();
- }
- }
- }
- }
+ gGL.getTexUnit(bumpTex)->bind(tex_a);
+ blend_factor = 0; // only one tex provided, no blending
}
- else
+ else if (tex_b && !tex_a)
{
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++)
- {
- LLFace *face = *iter;
- if (face)
- {
- LLVOWater* water = (LLVOWater*) face->getViewerObject();
- gGL.getTexUnit(diffTex)->bind(face->getTexture());
-
- if (water)
- {
- bool edge_patch = water->getIsEdgePatch();
- if (!edge_patch)
- {
- sNeedsReflectionUpdate = TRUE;
- sNeedsDistortionUpdate = TRUE;
- face->renderIndexed();
- }
- }
- }
- }
+ 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);
}
- }
- gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
- gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
+ // bind reflection texture from RenderTarget
+ S32 screentex = shader->enableTexture(LLShaderMgr::WATER_SCREENTEX);
+ F32 screenRes[] = {1.f / gGLViewport[2], 1.f / gGLViewport[3]};
- 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);
- shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+ S32 diffTex = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP);
- shader->unbind();
-}
+ // 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);
+ }
+ }
-void LLDrawPoolWater::shade()
-{
- if (!deferred_render)
- {
- gGL.setColorMask(true, true);
- }
+ shader->uniform2fv(LLShaderMgr::DEFERRED_SCREEN_RES, 1, screenRes);
+ shader->uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
- LLVOSky *voskyp = gSky.mVOSkyp;
+ LLColor4 fog_color(pwater->getWaterFogColor(), 0.0f);
+ F32 fog_density = pwater->getModifiedWaterFogDensity(underwater);
- if(voskyp == NULL)
- {
- return;
- }
+ if (screentex > -1)
+ {
+ shader->uniform1f(LLShaderMgr::WATER_FOGDENSITY, fog_density);
+ gGL.getTexUnit(screentex)->bind(&gPipeline.mWaterDis);
+ }
- LLGLDisable blend(GL_BLEND);
+ if (mShaderLevel == 1)
+ {
+ fog_color.mV[VW] = log(fog_density) / log(2);
+ }
- LLColor3 light_diffuse(0,0,0);
- F32 light_exp = 0.0f;
- LLVector3 light_dir;
+ 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);
- LLEnvironment& environment = LLEnvironment::instance();
- LLSettingsWater::ptr_t pwater = environment.getCurrentWater();
- LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+ shader->uniform4fv(LLShaderMgr::SPECULAR_COLOR, 1, specular.mV);
+ shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
- light_dir = environment.getLightDirection();
- light_dir.normalize();
+ shader->uniform3fv(LLShaderMgr::WATER_SPECULAR, 1, light_diffuse.mV);
+ shader->uniform1f(LLShaderMgr::WATER_SPECULAR_EXP, light_exp);
+ if (LLEnvironment::instance().isCloudScrollPaused())
+ {
+ static const std::array<F32, 2> zerowave {{0.0f, 0.0f}};
- bool sun_up = environment.getIsSunUp();
- bool moon_up = environment.getIsMoonUp();
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, zerowave.data());
+ shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, zerowave.data());
+ }
+ else
+ {
+ 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);
- if (sun_up)
- {
- light_diffuse += voskyp->getSun().getColorCached();
- }
- // 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->getMoonDiffuse();
- }
+ 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());
- light_exp = light_dir * LLVector3(light_dir.mV[0], light_dir.mV[1], 0.f);
+ F32 sunAngle = llmax(0.f, light_dir.mV[1]);
+ F32 scaledAngle = 1.f - sunAngle;
- light_diffuse.normalize();
- light_diffuse *= (light_exp + 0.25f);
+ 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);
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= light_exp;
- light_exp *= 256.f;
- light_exp = light_exp > 32.f ? light_exp : 32.f;
+ LLVector4 rotated_light_direction = LLEnvironment::instance().getRotatedLightNorm();
+ shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, rotated_light_direction.mV);
+ shader->uniform3fv(LLShaderMgr::WL_CAMPOSLOCAL, 1, LLViewerCamera::getInstance()->getOrigin().mV);
- light_diffuse *= 6.f;
+ if (LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
+ }
+ else
+ {
+ shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
+ }
- LLGLSLShader* shader = nullptr;
- LLGLSLShader* edge_shader = nullptr;
+ LLGLDisable cullface(GL_CULL_FACE);
- F32 eyedepth = LLViewerCamera::getInstance()->getOrigin().mV[2] - LLEnvironment::instance().getWaterHeight();
-
- if (eyedepth < 0.f && LLPipeline::sWaterReflections)
- {
- if (deferred_render)
- {
- shader = &gDeferredUnderWaterProgram;
- }
- else
+ LLVOWater *water = nullptr;
+ for (LLFace *const &face : mDrawFace)
{
- shader = &gUnderWaterProgram;
- }
- }
- else if (deferred_render)
- {
- shader = &gDeferredWaterProgram;
- edge_shader = nullptr;
- }
- else
- {
- shader = &gWaterProgram;
- edge_shader = &gWaterEdgeProgram;
- }
+ if (!face) continue;
+ water = static_cast<LLVOWater *>(face->getViewerObject());
+ if (!water) continue;
- if (mWaterNormp[0])
- {
- if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- {
- mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp[0]->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- }
+ gGL.getTexUnit(diffTex)->bind(face->getTexture());
- if (mWaterNormp[1])
- {
- if (gSavedSettings.getBOOL("RenderWaterMipNormal"))
- {
- mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
- }
- else
- {
- mWaterNormp[1]->setFilteringOption(LLTexUnit::TFO_POINT);
- }
- }
+ if ((bool)edge == (bool) water->getIsEdgePatch())
+ {
+ face->renderIndexed();
- shade2(false, shader, light_diffuse, light_dir, light_exp);
- shade2(true, edge_shader ? edge_shader : shader, light_diffuse, light_dir, light_exp);
+ // Note non-void water being drawn, updates required
+ if (!edge) // SL-16461 remove !LLPipeline::sUseOcclusion check
+ {
+ sNeedsReflectionUpdate = TRUE;
+ sNeedsDistortionUpdate = TRUE;
+ }
+ }
+ }
- gGL.getTexUnit(0)->activate();
- gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
- if (!deferred_render)
- {
- gGL.setColorMask(true, false);
- }
+ 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);
+ shader->disableTexture(LLShaderMgr::WATER_SCREENDEPTH);
+
+ // clean up
+ shader->unbind();
+ 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);
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()