summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEuclid Linden <euclid@lindenlab.com>2021-11-22 23:10:33 +0000
committerEuclid Linden <euclid@lindenlab.com>2021-11-22 23:10:33 +0000
commitc2f96c78266e1a8191a4b1b2c9a832f1b7f128ea (patch)
treed79b73f0e5c95d85eef3bad71ced9ce022ade907
parent40f2e70875db857c70b08369410046da6d873967 (diff)
parent8425c6429299590653d6a40cd127d9fbed4c76d7 (diff)
Merged in euclid-13565-2 (pull request #782)
Condition reflection pass on non-void water occlusion queries directly, when occlusion is enabled Approved-by: Dave Parks Approved-by: Michael Pohoreski
-rw-r--r--indra/llrender/llgl.cpp3
-rw-r--r--indra/newview/lldrawpoolwater.cpp472
-rw-r--r--indra/newview/lldrawpoolwater.h3
-rw-r--r--indra/newview/llvieweroctree.cpp293
-rw-r--r--indra/newview/llworld.cpp1
5 files changed, 347 insertions, 425 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c7f85aec21..b49b14615f 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1095,8 +1095,7 @@ void LLGLManager::initExtensions()
mHasSync = ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts);
mHasMapBufferRange = ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts);
mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts);
- //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
- mHasDepthClamp = FALSE;
+ mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
#ifdef GL_ARB_framebuffer_object
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 2f3c52ecd2..e2d3f67e46 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;
@@ -146,7 +144,7 @@ void LLDrawPoolWater::renderDeferred(S32 pass)
}
deferred_render = TRUE;
- shade();
+ renderWater();
deferred_render = FALSE;
}
@@ -182,7 +180,7 @@ void LLDrawPoolWater::render(S32 pass)
if ((mShaderLevel > 0) && !sSkipScreenCopy)
{
- shade();
+ renderWater();
return;
}
@@ -485,332 +483,246 @@ 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()
{
LL_PROFILE_ZONE_SCOPED;
- 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();
- }
+ 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)))
- {
- gGL.getTexUnit(bumpTex)->bind(tex_a);
- blend_factor = 0; // only one tex provided, no blending
- }
- else if (tex_b && !tex_a)
+ if (sun_up)
{
- gGL.getTexUnit(bumpTex)->bind(tex_b);
- 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_a);
- gGL.getTexUnit(bumpTex2)->bind(tex_b);
+ light_diffuse += psky->getMoonlightColor();
}
-
- // 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)
- {
- //F32 fog_density_slider_value = param_mgr->mDensitySliderValue;
- //sWaterFogColor.mV[3] = fog_density_slider_value;
- fog_color.mV[VW] = log(fog_density) / log(2);
- }
-
- shader->uniform4fv(LLShaderMgr::WATER_FOGCOLOR, 1, fog_color.mV);
-
- //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())
+ // 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...
{
- 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());
+ light_diffuse *= (1.5f + (6.f * ground_proj_sq));
}
- else
+
+ // set up normal maps filtering
+ for (auto norm_map : mWaterNormp)
{
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR1, 1, pwater->getWave1Dir().mV);
- shader->uniform2fv(LLShaderMgr::WATER_WAVE_DIR2, 1, pwater->getWave2Dir().mV);
+ if (norm_map) norm_map->setFilteringOption(has_normal_mips ? LLTexUnit::TFO_ANISOTROPIC : LLTexUnit::TFO_POINT);
}
- 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());
+ LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
+ F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
+ bool edge = false;
+ LLGLSLShader *shader = nullptr;
+ do // twice through, once with normal shader bound & once with edge shader bound
+ {
+ // 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();
- F32 sunAngle = llmax(0.f, light_dir.mV[1]);
- F32 scaledAngle = 1.f - sunAngle;
+ // 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();
+ }
- 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);
+ // bind normal map
+ S32 bumpTex = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP);
+ S32 bumpTex2 = shader->enableTexture(LLViewerShaderMgr::BUMP_MAP2);
- 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);
+ LLViewerTexture *tex_a = mWaterNormp[0];
+ LLViewerTexture *tex_b = mWaterNormp[1];
- if (LLViewerCamera::getInstance()->cameraUnderWater())
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleBelow());
- }
- else
- {
- shader->uniform1f(LLShaderMgr::WATER_REFSCALE, pwater->getScaleAbove());
- }
+ F32 blend_factor = pwater->getBlendFactor();
- {
- 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()
-{
- LL_PROFILE_ZONE_SCOPED;
- 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 (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);
+ // If not occlusion culling, record non-void water being drawn
+ // (If occlusion is enabled, these are set within LLOcclusionCullingGroup::checkOcclusion() )
+ if (!edge && !LLPipeline::sUseOcclusion)
+ {
+ 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);
+
+ edge = !edge;
+ } while (!edge);
+ gGL.getTexUnit(0)->activate();
+ gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+ if (!deferred_render)
+ {
+ gGL.setColorMask(true, false);
+ }
}
LLViewerTexture *LLDrawPoolWater::getDebugTexture()
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index a5d163e0d7..6f2fc3271d 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -78,8 +78,7 @@ public:
/*virtual*/ LLColor3 getDebugColor() const; // For AGP debug display
void renderReflection(LLFace* face);
- void shade();
- void shade2(bool edge, LLGLSLShader* shader, const LLColor3& light_diffuse, const LLVector3& light_dir, F32 light_exp);
+ void renderWater();
void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId);
void setOpaqueTexture(const LLUUID& opaqueTextureId);
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 868cf75d11..b7d0e06116 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -32,6 +32,7 @@
#include "llappviewer.h"
#include "llglslshader.h"
#include "llviewershadermgr.h"
+#include "lldrawpoolwater.h"
//-----------------------------------------------------------------------------------
//static variables definitions
@@ -931,47 +932,53 @@ void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames()
}
}
-void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode)
-{
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialSetOcclusionStateDiff setter(state);
- setter.traverse(mOctreeNode);
- }
- else if (mode == STATE_MODE_BRANCH)
- {
- LLSpatialSetOcclusionState setter(state);
- setter.traverse(mOctreeNode);
- }
- else
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mOcclusionState[i] |= state;
-
- if ((state & DISCARD_QUERY) && mOcclusionQuery[i])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
- mOcclusionQuery[i] = 0;
- }
- }
- }
- }
- else
- {
- if (state & OCCLUDED)
- {
- add(sNumObjectsOccluded, 1);
- }
- mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
- if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
- }
+void LLOcclusionCullingGroup::setOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */ )
+{
+ switch (mode)
+ {
+ case STATE_MODE_SINGLE:
+ if (state & OCCLUDED)
+ {
+ add(sNumObjectsOccluded, 1);
+ }
+ mOcclusionState[LLViewerCamera::sCurCameraID] |= state;
+ if ((state & DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
+ }
+ break;
+
+ case STATE_MODE_DIFF:
+ {
+ LLSpatialSetOcclusionStateDiff setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_BRANCH:
+ {
+ LLSpatialSetOcclusionState setter(state);
+ setter.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_ALL_CAMERAS:
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mOcclusionState[i] |= state;
+
+ if ((state & DISCARD_QUERY) && mOcclusionQuery[i])
+ {
+ releaseOcclusionQueryObjectName(mOcclusionQuery[i]);
+ mOcclusionQuery[i] = 0;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
}
class LLSpatialClearOcclusionState : public OctreeTraveler
@@ -1006,36 +1013,42 @@ public:
}
};
-void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode)
-{
- if (mode > STATE_MODE_SINGLE)
- {
- if (mode == STATE_MODE_DIFF)
- {
- LLSpatialClearOcclusionStateDiff clearer(state);
- clearer.traverse(mOctreeNode);
- }
- else if (mode == STATE_MODE_BRANCH)
- {
- LLSpatialClearOcclusionState clearer(state);
- clearer.traverse(mOctreeNode);
- }
- else
- {
- for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
- {
- mOcclusionState[i] &= ~state;
- }
- }
- }
- else
- {
- if (state & OCCLUDED)
- {
- add(sNumObjectsUnoccluded, 1);
- }
- mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
- }
+void LLOcclusionCullingGroup::clearOcclusionState(U32 state, S32 mode /* = STATE_MODE_SINGLE */)
+{
+ switch (mode)
+ {
+ case STATE_MODE_SINGLE:
+ if (state & OCCLUDED)
+ {
+ add(sNumObjectsUnoccluded, 1);
+ }
+ mOcclusionState[LLViewerCamera::sCurCameraID] &= ~state;
+ break;
+
+ case STATE_MODE_DIFF:
+ {
+ LLSpatialClearOcclusionStateDiff clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_BRANCH:
+ {
+ LLSpatialClearOcclusionState clearer(state);
+ clearer.traverse(mOctreeNode);
+ }
+ break;
+
+ case STATE_MODE_ALL_CAMERAS:
+ for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; i++)
+ {
+ mOcclusionState[i] &= ~state;
+ }
+ break;
+
+ default:
+ break;
+ }
}
BOOL LLOcclusionCullingGroup::earlyFail(LLCamera* camera, const LLVector4a* bounds)
@@ -1089,75 +1102,73 @@ U32 LLOcclusionCullingGroup::getLastOcclusionIssuedTime()
void LLOcclusionCullingGroup::checkOcclusion()
{
- if (LLPipeline::sUseOcclusion > 1)
- {
- LL_PROFILE_ZONE_SCOPED;
- LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent();
- if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
- { //if the parent has been marked as occluded, the child is implicitly occluded
- clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
- }
- else if (isOcclusionState(QUERY_PENDING))
- { //otherwise, if a query is pending, read it back
+ if (LLPipeline::sUseOcclusion < 2) return; // 0 - NoOcclusion, 1 = ReadOnly, 2 = ModifyOcclusionState TODO: DJH 11-2021 ENUM this
- GLuint available = 0;
- if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- LL_PROFILE_ZONE_NAMED("co - query available")
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
- }
- else
- {
- available = 1;
- }
-
- if (available)
- { //result is available, read it back, otherwise wait until next frame
- GLuint res = 1;
- if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
- {
- LL_PROFILE_ZONE_NAMED("co - query result")
- glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &res);
+ LL_PROFILE_ZONE_SCOPED;
+ LLOcclusionCullingGroup* parent = (LLOcclusionCullingGroup*)getParent();
+ if (parent && parent->isOcclusionState(LLOcclusionCullingGroup::OCCLUDED))
+ { //if the parent has been marked as occluded, the child is implicitly occluded
+ clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
+ return;
+ }
+
+ if (mOcclusionQuery[LLViewerCamera::sCurCameraID] && isOcclusionState(QUERY_PENDING))
+ {
+ if (isOcclusionState(DISCARD_QUERY))
+ { // delete the query to avoid holding onto hundreds of pending queries
+ releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
+ // mark non-occluded
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
+ }
+ else
+ {
+ GLuint available;
+ {
+ LL_PROFILE_ZONE_NAMED("co - query available");
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
+ }
+
+ if (available)
+ {
+ GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint)
+ {
+ LL_PROFILE_ZONE_NAMED("co - query result");
+ glGetQueryObjectuivARB(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result);
+ }
#if LL_TRACK_PENDING_OCCLUSION_QUERIES
- sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
+ sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
#endif
- }
- else if (mOcclusionQuery[LLViewerCamera::sCurCameraID])
- { //delete the query to avoid holding onto hundreds of pending queries
- releaseOcclusionQueryObjectName(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
- mOcclusionQuery[LLViewerCamera::sCurCameraID] = 0;
- }
-
- if (isOcclusionState(DISCARD_QUERY))
- {
- res = 2;
- }
-
- if (res > 0)
- {
- assert_states_valid(this);
- clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
- assert_states_valid(this);
- }
- else
- {
- assert_states_valid(this);
-
- setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
-
- assert_states_valid(this);
- }
-
- clearOcclusionState(QUERY_PENDING | DISCARD_QUERY);
- }
- }
- 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);
- assert_states_valid(this);
- }
- }
+ 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;
+ }
+ }
+
+ if (query_result > 0)
+ {
+ clearOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ }
+ else
+ {
+ setOcclusionState(LLOcclusionCullingGroup::OCCLUDED, LLOcclusionCullingGroup::STATE_MODE_DIFF);
+ }
+ clearOcclusionState(QUERY_PENDING);
+ }
+ }
+ }
+ 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);
+ assert_states_valid(this);
+ }
}
void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* shift)
@@ -1175,7 +1186,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
}
F32 OCCLUSION_FUDGE_Z = SG_OCCLUSION_FUDGE; //<-- #Solution #2
- if (LLDrawPool::POOL_WATER == mSpatialPartition->mDrawableType)
+ if (LLPipeline::RENDER_TYPE_VOIDWATER == mSpatialPartition->mDrawableType)
{
OCCLUSION_FUDGE_Z = 1.;
}
@@ -1205,8 +1216,8 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
// 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 == LLDrawPool::POOL_WATER ||
- mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
+ (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER ||
+ mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER);
LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0);
@@ -1237,7 +1248,7 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh
bounds[1][1]+SG_OCCLUSION_FUDGE,
bounds[1][2]+OCCLUSION_FUDGE_Z);
- if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
+ if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER)
{
LL_PROFILE_ZONE_NAMED("doOcclusion - draw water");
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index d5cce6a52a..d7f16713d2 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -885,6 +885,7 @@ void LLWorld::waterHeightRegionInfo(std::string const& sim_name, F32 water_heigh
void LLWorld::precullWaterObjects(LLCamera& camera, LLCullResult* cull, bool include_void_water)
{
+ LL_PROFILE_ZONE_SCOPED;
if (!gAgent.getRegion())
{
return;