summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp1970
1 files changed, 928 insertions, 1042 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e7f50f6b59..828910c9c0 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -88,6 +88,7 @@
#include "llvocache.h"
#include "llvoground.h"
#include "llvosky.h"
+#include "llvowlsky.h"
#include "llvotree.h"
#include "llvovolume.h"
#include "llvosurfacepatch.h"
@@ -100,8 +101,6 @@
#include "llviewerstats.h"
#include "llviewerjoystick.h"
#include "llviewerdisplay.h"
-#include "llwlparammanager.h"
-#include "llwaterparammanager.h"
#include "llspatialpartition.h"
#include "llmutelist.h"
#include "lltoolpie.h"
@@ -116,6 +115,8 @@
#include "llprogressview.h"
#include "llcleanup.h"
+#include "llenvironment.h"
+
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
//#define DEBUG_INDICES
@@ -298,62 +299,6 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
-glh::matrix4f glh_copy_matrix(F32* src)
-{
- glh::matrix4f ret;
- ret.set_value(src);
- return ret;
-}
-
-glh::matrix4f glh_get_current_modelview()
-{
- return glh_copy_matrix(gGLModelView);
-}
-
-glh::matrix4f glh_get_current_projection()
-{
- return glh_copy_matrix(gGLProjection);
-}
-
-glh::matrix4f glh_get_last_modelview()
-{
- return glh_copy_matrix(gGLLastModelView);
-}
-
-glh::matrix4f glh_get_last_projection()
-{
- return glh_copy_matrix(gGLLastProjection);
-}
-
-void glh_copy_matrix(const glh::matrix4f& src, F32* dst)
-{
- for (U32 i = 0; i < 16; i++)
- {
- dst[i] = src.m[i];
- }
-}
-
-void glh_set_current_modelview(const glh::matrix4f& mat)
-{
- glh_copy_matrix(mat, gGLModelView);
-}
-
-void glh_set_current_projection(glh::matrix4f& mat)
-{
- glh_copy_matrix(mat, gGLProjection);
-}
-
-glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar)
-{
- glh::matrix4f ret(
- 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left),
- 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom),
- 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear),
- 0.f, 0.f, 0.f, 1.f);
-
- return ret;
-}
-
void display_update_camera();
//----------------------------------------
@@ -381,6 +326,7 @@ bool LLPipeline::sRenderBump = true;
bool LLPipeline::sBakeSunlight = false;
bool LLPipeline::sNoAlpha = false;
bool LLPipeline::sUseTriStrips = true;
+bool LLPipeline::sUseAdvancedAtmospherics = false;
bool LLPipeline::sUseFarClip = true;
bool LLPipeline::sShadowRender = false;
bool LLPipeline::sWaterReflections = false;
@@ -479,7 +425,7 @@ void LLPipeline::init()
gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
- sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+ sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw");
@@ -906,6 +852,9 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
return ret;
}
+ // must be even to avoid a stripe in the horizontal shadow blur
+inline U32 BlurHappySize(U32 x, U32 scale) { return (((x*scale)+1)&~1); }
+
bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
{
refreshCachedSettings();
@@ -932,17 +881,24 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
if (LLPipeline::sRenderDeferred)
{
+ U32 water_buffer_res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
S32 shadow_detail = RenderShadowDetail;
bool ssao = RenderDeferredSSAO;
- const U32 occlusion_divisor = 3;
+ const U32 occlusion_divisor = 4;
//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 (!mWaterDeferredScreen.allocate(water_buffer_res, water_buffer_res, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mWaterDeferredDepth.allocate(water_buffer_res, water_buffer_res, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mWaterOcclusionDepth.allocate(water_buffer_res >> 1, water_buffer_res >> 1, 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;
-
+ if (!addDeferredAttachments(mWaterDeferredScreen)) return false;
+
GLuint screenFormat = GL_RGBA16;
if (gGLManager.mIsATI)
{
@@ -967,50 +923,89 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
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;
+ if (!mWaterDeferredLight.allocate(water_buffer_res, water_buffer_res, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
else
{
mDeferredLight.release();
+ mWaterDeferredLight.release();
}
F32 scale = 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
- U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur
for (U32 i = 0; i < 4; i++)
- {
- if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
- if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ {
+ if (shadow_detail > 3)
+ {
+ //allocate VSM sun shadow map(s)
+ if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, GL_RGBA16F_ARB, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ {
+ return false;
+ }
+ }
+ else if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ {
+ return false;
+ }
+
+ if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE))
+ {
+ return false;
+ }
}
}
else
{
for (U32 i = 0; i < 4; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
}
+ // for EEP atmospherics
+ bool allocated_sh0 = mSkySH.allocate(64, 64, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_TEXTURE);
+ if (!allocated_sh0)
+ {
+ return false;
+ }
+ else
+ {
+ mSkySH.addColorAttachment(GL_RGBA16F_ARB);
+ mSkySH.addColorAttachment(GL_RGBA16F_ARB);
+ }
+
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_width = width;
+ U32 spot_shadow_map_height = height;
for (U32 i = 4; i < 6; i++)
{
- if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
- if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
+ if ((shadow_detail > 3) && !mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, GL_RGBA16F_ARB, FALSE, FALSE))
+ {
+ return false;
+ }
+ else 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;
+ }
}
}
else
{
for (U32 i = 4; i < 6; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
}
@@ -1023,16 +1018,17 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
else
{
mDeferredLight.release();
-
- for (U32 i = 0; i < 6; i++)
- {
- mShadow[i].release();
- mShadowOcclusion[i].release();
- }
+ mWaterDeferredLight.release();
+
+ releaseShadowTargets();
+
mFXAABuffer.release();
mScreen.release();
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
mDeferredDepth.release();
+ mWaterDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mWaterDeferredScreen first
+ mWaterDeferredDepth.release();
+ mWaterOcclusionDepth.release();
mOcclusionDepth.release();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
@@ -1096,6 +1092,7 @@ void LLPipeline::refreshCachedSettings()
RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP");
WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders");
RenderDeferred = gSavedSettings.getBOOL("RenderDeferred");
+ sUseAdvancedAtmospherics = WindLightUseAtmosShaders && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics");
RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash");
RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples");
RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor");
@@ -1221,17 +1218,30 @@ void LLPipeline::releaseScreenBuffers()
mPhysicsDisplay.release();
mDeferredScreen.release();
mDeferredDepth.release();
+ mWaterDeferredScreen.release();
+ mWaterDeferredDepth.release();
mDeferredLight.release();
+ mWaterDeferredLight.release();
+ mWaterOcclusionDepth.release();
mOcclusionDepth.release();
-
- for (U32 i = 0; i < 6; i++)
+ releaseShadowTargets();
+}
+
+
+void LLPipeline::releaseShadowTarget(U32 index)
+{
+ mShadow[index].release();
+ mShadowOcclusion[index].release();
+}
+
+void LLPipeline::releaseShadowTargets()
+{
+ for (U32 i = 0; i < 6; i++)
{
- mShadow[i].release();
- mShadowOcclusion[i].release();
+ releaseShadowTarget(i);
}
}
-
void LLPipeline::createGLBuffers()
{
stop_glerror();
@@ -1239,19 +1249,13 @@ void LLPipeline::createGLBuffers()
updateRenderDeferred();
- bool materials_in_water = false;
-
-#if MATERIALS_IN_REFLECTIONS
- materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
-#endif
-
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
-
+
// Set up SRGB targets if we're doing deferred-path reflection rendering
//
- if (LLPipeline::sRenderDeferred && materials_in_water)
+ if (LLPipeline::sRenderDeferred)
{
mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
//always use FBO for mWaterDis so it can be used for avatar texture bakes
@@ -1259,10 +1263,10 @@ void LLPipeline::createGLBuffers()
}
else
{
- mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
- //always use FBO for mWaterDis so it can be used for avatar texture bakes
- mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
- }
+ mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
+ //always use FBO for mWaterDis so it can be used for avatar texture bakes
+ mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
+ }
}
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
@@ -1434,15 +1438,15 @@ bool LLPipeline::canUseVertexShaders()
bool LLPipeline::canUseWindLightShaders() const
{
- return (!LLPipeline::sDisableShaders &&
- gWLSkyProgram.mProgramObject != 0 &&
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1);
+ bool usingWindlight = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1;
+ bool haveShaders = ((gWLSkyProgram.mProgramObject != 0) || (gDeferredWLSkyProgram.mProgramObject != 0));
+ return (!LLPipeline::sDisableShaders && haveShaders && usingWindlight);
}
bool LLPipeline::canUseWindLightShadersOnObjects() const
{
return (canUseWindLightShaders()
- && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
+ && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0);
}
bool LLPipeline::canUseAntiAliasing() const
@@ -1471,7 +1475,7 @@ void LLPipeline::enableShadows(const bool enable_shadows)
S32 LLPipeline::getMaxLightingDetail() const
{
- /*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
+ /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS)
{
return 3;
}
@@ -2190,7 +2194,7 @@ void check_references(LLSpatialGroup* group, LLFace* face)
void LLPipeline::checkReferences(LLFace* face)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2222,7 +2226,7 @@ void LLPipeline::checkReferences(LLFace* face)
void LLPipeline::checkReferences(LLDrawable* drawable)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2273,7 +2277,7 @@ void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
void LLPipeline::checkReferences(LLDrawInfo* draw_info)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2299,7 +2303,7 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info)
void LLPipeline::checkReferences(LLSpatialGroup* group)
{
-#if 0
+#if CHECK_PIPELINE_REFERENCES
if (sCull)
{
for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
@@ -2417,7 +2421,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderDeferred && LLPipeline::sReflectionRender)
+ {
+ mWaterOcclusionDepth.bindTarget();
+ }
+ else if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.bindTarget();
}
@@ -2444,38 +2452,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
- //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling)
- LLViewerRegion* region = gAgent.getRegion();
- LLPlane plane;
-
- if (planep)
- {
- plane = *planep;
- }
- else
- {
- if (region)
- {
- LLVector3 pnorm;
- F32 height = region->getWaterHeight();
- if (water_clip < 0)
- { //camera is above water, clip plane points up
- pnorm.setVec(0,0,1);
- plane.setVec(pnorm, -height);
- }
- else if (water_clip > 0)
- { //camera is below water, clip plane points down
- pnorm = LLVector3(0,0,-1);
- plane.setVec(pnorm, height);
- }
- }
- }
-
- glh::matrix4f modelview = glh_get_last_modelview();
- glh::matrix4f proj = glh_get_last_projection();
- LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender);
-
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
bool bound_shader = false;
@@ -2495,21 +2471,18 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
}
+ camera.disableUserClipPlane();
+
+ bool use_far_clip = LLPipeline::sUseFarClip;
+
+ LLPipeline::sUseFarClip = false;
+
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
LLViewerRegion* region = *iter;
- if (water_clip != 0)
- {
- LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight());
- camera.setUserClipPlane(plane);
- }
- else
- {
- camera.disableUserClipPlane();
- }
-
- for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
{
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
@@ -2530,6 +2503,8 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
}
}
+ LLPipeline::sUseFarClip = use_far_clip;
+
if (bound_shader)
{
gOcclusionCubeProgram.unbind();
@@ -2557,7 +2532,22 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
sCull->pushDrawable(gSky.mVOGroundp->mDrawable);
}
+ if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) &&
+ gPipeline.canUseWindLightShaders() &&
+ gSky.mVOWLSkyp.notNull() &&
+ gSky.mVOWLSkyp->mDrawable.notNull())
+ {
+ gSky.mVOWLSkyp->mDrawable->setVisible(camera);
+ sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable);
+ }
+ bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER));
+
+ if (render_water)
+ {
+ LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water);
+ }
+
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -2570,7 +2560,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- if (LLPipeline::sRenderDeferred)
+ if (LLPipeline::sRenderDeferred && LLPipeline::sReflectionRender)
+ {
+ mWaterOcclusionDepth.flush();
+ }
+ else if (LLPipeline::sRenderDeferred)
{
mOcclusionDepth.flush();
}
@@ -2646,6 +2640,65 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleMinMaxDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? GL_DEPTH_BUFFER_BIT : GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_COLOR_BUFFER_BIT); // dest should be an RG16F target
+
+ 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 = &gDownsampleMinMaxDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleMinMaxDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f / source.getWidth(), 1.f / source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
{
LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
@@ -2656,7 +2709,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
{
scratch_space->copyContents(source,
0, 0, source.getWidth(), source.getHeight(),
- 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), source.hasStencil() ? (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT) : GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
dest.bindTarget();
@@ -4219,7 +4272,7 @@ void LLPipeline::renderHighlights()
//gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4266,7 +4319,7 @@ void LLPipeline::renderHighlights()
// have touch-handlers.
mHighlightFaces.clear();
- if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
+ if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)
{
gHighlightProgram.unbind();
}
@@ -4275,7 +4328,7 @@ void LLPipeline::renderHighlights()
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
{
color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightNormalProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4296,7 +4349,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightNormalProgram.unbind();
}
@@ -4305,7 +4358,7 @@ void LLPipeline::renderHighlights()
if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
{
color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightSpecularProgram.bind();
gGL.diffuseColor4f(1,1,1,0.5f);
@@ -4326,7 +4379,7 @@ void LLPipeline::renderHighlights()
facep->renderSelected(mFaceSelectImagep, color);
}
- if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
{
gHighlightSpecularProgram.unbind();
}
@@ -4553,6 +4606,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate)
// Render debugging beacons.
gObjectList.renderObjectBeacons();
gObjectList.resetObjectBeacons();
+ gSky.addSunMoonBeacons();
}
else
{
@@ -4613,63 +4667,46 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
LLGLState::checkTextureChannels();
LLGLState::checkClientArrays();
- U32 cur_type = 0;
-
gGL.setColorMask(true, true);
-
- pool_set_t::iterator iter1 = mPools.begin();
- while ( iter1 != mPools.end() )
+ pool_set_t::iterator iter = mPools.begin();
+ while ( iter != mPools.end() )
{
- LLDrawPool *poolp = *iter1;
-
- cur_type = poolp->getType();
-
- pool_set_t::iterator iter2 = iter1;
- if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
- {
- LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
-
- gGLLastMatrix = NULL;
- gGL.loadMatrix(gGLModelView);
-
- for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ )
- {
- LLVertexBuffer::unbind();
- poolp->beginDeferredPass(i);
- for (iter2 = iter1; iter2 != mPools.end(); iter2++)
- {
- LLDrawPool *p = *iter2;
- if (p->getType() != cur_type)
- {
- break;
- }
-
- if ( !p->getSkipRenderFlag() ) { p->renderDeferred(i); }
- }
- poolp->endDeferredPass(i);
- LLVertexBuffer::unbind();
+ LLDrawPool* poolp = *iter;
+ llassert(poolp != nullptr);
+ if (poolp)
+ {
+ U32 pool_type = poolp->getType();
+ S32 deferred_passes = poolp->getNumDeferredPasses();
+ if (hasRenderType(pool_type) && (deferred_passes > 0))
+ {
+ LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
+
+ gGLLastMatrix = NULL;
+ gGL.loadMatrix(gGLModelView);
+
+ for( S32 i = 0; i < deferred_passes; i++ )
+ {
+ LLVertexBuffer::unbind();
+ stop_glerror();
+
+ poolp->beginDeferredPass(i);
+ poolp->renderDeferred(i);
+ poolp->endDeferredPass(i);
+
+ // per-pass validation that our conception of current GL state is correct
+ if (gDebugGL || gDebugPipeline)
+ {
+ LLGLState::checkStates();
+ }
+ }
+
+ LLVertexBuffer::unbind();
+ stop_glerror();
+ }
+ }
- if (gDebugGL || gDebugPipeline)
- {
- LLGLState::checkStates();
- }
- }
- }
- 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();
+ iter++;
}
gGLLastMatrix = NULL;
@@ -4707,7 +4744,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
- doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
+
+ doOcclusion(camera, mScreen, sReflectionRender ? mWaterOcclusionDepth : mOcclusionDepth, sReflectionRender ? &mWaterDeferredDepth : &mDeferredDepth);
gGL.setColorMask(true, false);
}
@@ -5344,6 +5382,55 @@ void LLPipeline::renderDebug()
visible_selected_groups.clear();
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SH) && gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics") && LLPipeline::sRenderDeferred)
+ {
+ bindDeferredShader(gDeferredShVisProgram);
+
+ S32 l1r_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, gPipeline.mSkySH.getUsage());
+ if (l1r_channel > -1)
+ {
+ gPipeline.mSkySH.bindTexture(0,l1r_channel);
+ gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1b_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, gPipeline.mSkySH.getUsage());
+ if (l1b_channel > -1)
+ {
+ gPipeline.mSkySH.bindTexture(1,l1b_channel);
+ gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1g_channel = gDeferredShVisProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, gPipeline.mSkySH.getUsage());
+ if (l1g_channel > -1)
+ {
+ gPipeline.mSkySH.bindTexture(2,l1g_channel);
+ gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS);
+
+ LLVector3 pos = LLViewerCamera::instance().getOrigin();
+ pos += LLViewerCamera::instance().getAtAxis() * 10.0f;
+
+ gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA);
+
+ gGL.begin(LLRender::TRIANGLES);
+ gGL.texCoord2f(0.0f, 0.0f);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(0.0f, 1.0f);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(1.0f, 0.0f);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+ gGL.flush();
+
+ unbindDeferredShader(gDeferredShVisProgram);
+ }
+
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
@@ -5983,6 +6070,13 @@ void LLPipeline::setupAvatarLights(bool for_edit)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
if (for_edit)
{
LLColor4 diffuse(1.f, 1.f, 1.f, 0.f);
@@ -6017,12 +6111,14 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
{
- LLVector3 opposite_pos = -1.f * mSunDir;
- LLVector3 orthog_light_pos = mSunDir % LLVector3::z_axis;
+ LLVector3 light_dir = sun_is_primary ? LLVector3(mSunDir) : LLVector3(mMoonDir);
+ LLVector3 opposite_pos = -light_dir;
+ LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis;
LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f);
backlight_pos.normalize();
-
- LLColor4 light_diffuse = mSunDiffuse;
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+
LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f);
F32 max_component = 0.001f;
for (S32 i = 0; i < 3; i++)
@@ -6033,7 +6129,7 @@ void LLPipeline::setupAvatarLights(bool for_edit)
}
}
F32 backlight_mag;
- if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
+ if (LLEnvironment::instance().getIsSunUp())
{
backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT;
}
@@ -6242,26 +6338,30 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
{
assertInitialized();
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
// Ambient
if (!LLGLSLShader::sNoFixedFunction)
{
gGL.syncMatrices();
- LLColor4 ambient = gSky.getTotalAmbientColor();
+ LLColor4 ambient = psky->getTotalAmbient();
gGL.setAmbientLightColor(ambient);
}
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+
// Light 0 = Sun or Moon (All objects)
{
- if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS)
- {
- mSunDir.setVec(gSky.getSunDirection());
- mSunDiffuse.setVec(gSky.getSunDiffuseColor());
- }
- else
- {
- mSunDir.setVec(gSky.getMoonDirection());
- mSunDiffuse.setVec(gSky.getMoonDiffuseColor());
- }
+ LLVector4 sun_dir(environment.getSunDirection(), 0.0f);
+ LLVector4 moon_dir(environment.getMoonDirection(), 0.0f);
+
+ mSunDir.setVec(sun_dir);
+ mMoonDir.setVec(moon_dir);
+ mSunDiffuse.setVec(psky->getSunDiffuse());
+ mMoonDiffuse.setVec(psky->getMoonDiffuse());
F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]);
if (max_color > 1.f)
@@ -6270,20 +6370,21 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
}
mSunDiffuse.clamp();
- LLVector4 light_pos(mSunDir, 0.0f);
- LLColor4 light_diffuse = mSunDiffuse;
-
- if (LLPipeline::sRenderDeferred)
+ max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]);
+ if (max_color > 1.f)
{
- /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
- light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
- light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ mMoonDiffuse *= 1.f/max_color;
}
+ mMoonDiffuse.clamp();
+
+ LLColor4 light_diffuse = sun_is_primary ? mSunDiffuse : mMoonDiffuse;
+ LLVector4 light_dir = sun_is_primary ? mSunDir : mMoonDir;
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
- light->setPosition(light_pos);
+ light->setPosition(light_dir);
+
light->setDiffuse(light_diffuse);
light->setAmbient(LLColor4::black);
light->setSpecular(LLColor4::black);
@@ -6502,7 +6603,7 @@ void LLPipeline::enableLights(U32 mask)
mLightMask = mask;
stop_glerror();
- LLColor4 ambient = gSky.getTotalAmbientColor();
+ LLColor4 ambient = LLEnvironment::instance().getCurrentSky()->getTotalAmbient();
gGL.setAmbientLightColor(ambient);
}
}
@@ -7516,6 +7617,8 @@ static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
{
+ LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight;
+
if (!(gPipeline.canUseVertexShaders() &&
sRenderGlow))
{
@@ -7807,7 +7910,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
F32 magnification = focal_length/(subject_distance-focal_length);
{ //build diffuse+bloom+CoF
- mDeferredLight.bindTarget();
+ deferred_light_target->bindTarget();
shader = &gDeferredCoFProgram;
bindDeferredShader(*shader);
@@ -7838,7 +7941,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
gGL.end();
unbindDeferredShader(*shader);
- mDeferredLight.flush();
+ deferred_light_target->flush();
}
U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale);
@@ -7851,10 +7954,10 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
shader = &gDeferredPostProgram;
bindDeferredShader(*shader);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ deferred_light_target->bindTexture(0, channel);
}
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
@@ -7880,8 +7983,8 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
{ //combine result based on alpha
if (multisample)
{
- mDeferredLight.bindTarget();
- glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ deferred_light_target->bindTarget();
+ glViewport(0, 0, deferred_light_target->getWidth(), deferred_light_target->getHeight());
}
else
{
@@ -7930,7 +8033,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
if (multisample)
{
- mDeferredLight.flush();
+ deferred_light_target->flush();
}
}
}
@@ -7938,7 +8041,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
{
if (multisample)
{
- mDeferredLight.bindTarget();
+ deferred_light_target->bindTarget();
}
LLGLSLShader* shader = &gDeferredPostNoDoFProgram;
@@ -7973,7 +8076,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
if (multisample)
{
- mDeferredLight.flush();
+ deferred_light_target->flush();
}
}
@@ -7991,10 +8094,10 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
shader->bind();
shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height);
- S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());
if (channel > -1)
{
- mDeferredLight.bindTexture(0, channel);
+ deferred_light_target->bindTexture(0, channel);
}
gGL.begin(LLRender::TRIANGLE_STRIP);
@@ -8005,7 +8108,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
gGL.flush();
- shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage());
+ shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_light_target->getUsage());
shader->unbind();
mFXAABuffer.flush();
@@ -8169,63 +8272,69 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
-void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map)
+void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target)
{
LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED);
- if (noise_map == 0xFFFFFFFF)
- {
- noise_map = mNoiseMap;
- }
+ LLRenderTarget* deferred_target = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen;
+ LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth : &mDeferredDepth;
+ LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight;
shader.bind();
S32 channel = 0;
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(0,channel);
+ deferred_target->bindTexture(0,channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(1, channel);
+ deferred_target->bindTexture(1, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage());
if (channel > -1)
{
- mDeferredScreen.bindTexture(2, channel);
+ deferred_target->bindTexture(2, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage());
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage());
if (channel > -1)
{
- gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE);
+ gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE);
stop_glerror();
-
- //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
- //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA);
+ }
- stop_glerror();
+ glh::matrix4f projection = get_current_projection();
+ glh::matrix4f inv_proj = projection.inverse();
- glh::matrix4f projection = glh_get_current_projection();
- glh::matrix4f inv_proj = projection.inverse();
-
- shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
- shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
- (F32) gGLViewport[1],
- (F32) gGLViewport[2],
- (F32) gGLViewport[3]);
- }
+ if (shader.getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX) != -1)
+ {
+ shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m);
+ }
+
+ if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1)
+ {
+ shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0],
+ (F32) gGLViewport[1],
+ (F32) gGLViewport[2],
+ (F32) gGLViewport[3]);
+ }
+
+ if (sReflectionRender && shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX))
+ {
+ shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m);
+ }
channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE);
if (channel > -1)
{
- gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map);
+ gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -8237,17 +8346,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
stop_glerror();
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
+ light_target = light_target ? light_target : deferred_light_target;
+ channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage());
if (channel > -1)
{
- if (light_index > 0)
- {
- mScreen.bindTexture(0, channel);
- }
- else
- {
- mDeferredLight.bindTexture(0, channel);
- }
+ light_target->bindTexture(0, channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
@@ -8261,20 +8364,24 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
for (U32 i = 0; i < 4; i++)
{
- channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE);
- stop_glerror();
- if (channel > -1)
- {
- stop_glerror();
- gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
+ 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_BILINEAR);
+ 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();
- }
+ 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++)
@@ -8284,23 +8391,25 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
if (channel > -1)
{
stop_glerror();
- gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
- gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
- stop_glerror();
+ LLRenderTarget* shadow_target = getShadowTarget(i);
+ if (shadow_target)
+ {
+ gGL.getTexUnit(channel)->bind(shadow_target, TRUE);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ 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();
+ 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();
+ }
}
}
- stop_glerror();
-
F32 mat[16*6];
for (U32 i = 0; i < 16; i++)
{
- mat[i] = mSunShadowMatrix[0].m[i];
+ mat[i] = mSunShadowMatrix[0].m[i];
mat[i+16] = mSunShadowMatrix[1].m[i];
mat[i+32] = mSunShadowMatrix[2].m[i];
mat[i+48] = mSunShadowMatrix[3].m[i];
@@ -8330,6 +8439,34 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
}
}
+ if (gAtmosphere)
+ {
+ // bind precomputed textures necessary for calculating sun and sky luminance
+ channel = shader.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering());
+ }
+
+ channel = shader.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ shader.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance());
+ }
+ }
+
shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV);
shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash);
shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise);
@@ -8354,15 +8491,17 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
//F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f;
+ F32 shadow_bias = RenderShadowBias + shadow_bias_error;
- shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
+ shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->getHeight());
shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f);
shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset); //*shadow_offset_error);
- shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias+shadow_bias_error);
+ shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, shadow_bias);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset);
shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias);
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.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff);
@@ -8371,7 +8510,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
- glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f norm_mat = get_current_modelview().inverse().transpose();
shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
}
@@ -8404,21 +8543,24 @@ static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");
static LLTrace::BlockTimerStatHandle FTM_POST("Post");
-void LLPipeline::renderDeferredLighting()
+void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target)
{
if (!sCull)
{
return;
}
+ LLRenderTarget* deferred_target = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen;
+ LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth : &mDeferredDepth;
+ LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight;
+
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
-
LLViewerCamera* camera = LLViewerCamera::getInstance();
{
LLGLDepthTest depth(GL_TRUE);
- mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 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);
}
LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
@@ -8441,7 +8583,7 @@ void LLPipeline::renderDeferredLighting()
LLGLEnable cull(GL_CULL_FACE);
LLGLEnable blend(GL_BLEND);
- glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+ glh::matrix4f mat = copy_matrix(gGLModelView);
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
@@ -8449,13 +8591,32 @@ void LLPipeline::renderDeferredLighting()
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
+
+ const LLEnvironment& environment = LLEnvironment::instance();
+
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
{
- setupHWLights(NULL); //to set mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
+ setupHWLights(NULL); //to set mSun/MoonDir;
+ glh::vec4f tc(mSunDir.mV);
mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
+
+ glh::vec4f tc_moon(mMoonDir.mV);
+ mTransformedMoonDir.set(tc_moon.v);
+ mTransformedMoonDir.normalize();
+
+ bool sun_is_primary = sun_up || !moon_up;
+ if (sun_is_primary)
+ {
+ mTransformedSunDir.set(tc.v);
+ mTransformedSunDir.normalize();
+ }
+ else
+ {
+ mTransformedSunDir.set(tc_moon.v);
+ mTransformedSunDir.normalize();
+ }
}
gGL.pushMatrix();
@@ -8466,16 +8627,16 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredSSAO || RenderShadowDetail > 0)
{
- mDeferredLight.bindTarget();
+ deferred_light_target->bindTarget();
{ //paint shadow/SSAO light map (direct lighting lightmap)
LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
- bindDeferredShader(gDeferredSunProgram, 0);
+ bindDeferredShader(gDeferredSunProgram, deferred_light_target);
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
glClearColor(1,1,1,1);
- mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
+ deferred_light_target->clear(GL_COLOR_BUFFER_BIT);
glClearColor(0,0,0,0);
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+ glh::matrix4f inv_trans = get_current_modelview().inverse().transpose();
const U32 slice = 32;
F32 offset[slice*3];
@@ -8495,7 +8656,7 @@ void LLPipeline::renderDeferredLighting()
}
gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
- gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight());
{
LLGLDisable blend(GL_BLEND);
@@ -8507,16 +8668,16 @@ void LLPipeline::renderDeferredLighting()
unbindDeferredShader(gDeferredSunProgram);
}
- mDeferredLight.flush();
+ deferred_light_target->flush();
}
if (RenderDeferredSSAO)
{ //soften direct lighting lightmap
LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
//blur lightmap
- mScreen.bindTarget();
+ screen_target->bindTarget();
glClearColor(1,1,1,1);
- mScreen.clear(GL_COLOR_BUFFER_BIT);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
glClearColor(0,0,0,0);
bindDeferredShader(gDeferredBlurLightProgram);
@@ -8552,12 +8713,13 @@ void LLPipeline::renderDeferredLighting()
stop_glerror();
}
- mScreen.flush();
+ screen_target->flush();
unbindDeferredShader(gDeferredBlurLightProgram);
- bindDeferredShader(gDeferredBlurLightProgram, 1);
+ bindDeferredShader(gDeferredBlurLightProgram, screen_target);
+
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- mDeferredLight.bindTarget();
+ deferred_light_target->bindTarget();
gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
@@ -8568,7 +8730,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
stop_glerror();
}
- mDeferredLight.flush();
+ deferred_light_target->flush();
unbindDeferredShader(gDeferredBlurLightProgram);
}
@@ -8580,19 +8742,42 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
stop_glerror();
- mScreen.bindTarget();
+ screen_target->bindTarget();
// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
glClearColor(0,0,0,0);
- mScreen.clear(GL_COLOR_BUFFER_BIT);
+ screen_target->clear(GL_COLOR_BUFFER_BIT);
if (RenderDeferredAtmospheric)
- { //apply sunlight contribution
+ { //apply sunlight contribution
+ LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram;
+
LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
- bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
+ bindDeferredShader(soften_shader);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
+
+ S32 l1r_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH.getUsage());
+ if (l1r_channel > -1)
+ {
+ mSkySH.bindTexture(0,l1r_channel);
+ gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1b_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH.getUsage());
+ if (l1b_channel > -1)
+ {
+ mSkySH.bindTexture(1,l1b_channel);
+ gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1g_channel = soften_shader.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH.getUsage());
+ if (l1g_channel > -1)
+ {
+ mSkySH.bindTexture(2,l1g_channel);
+ gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
//full screen blit
gGL.pushMatrix();
@@ -8842,17 +9027,17 @@ void LLPipeline::renderDeferredLighting()
count++;
if (count == max_count || fullscreen_lights.empty())
{
- U32 idx = count-1;
- bindDeferredShader(gDeferredMultiLightProgram[idx]);
- gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- 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);
- unbindDeferredShader(gDeferredMultiLightProgram[idx]);
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ 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);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
@@ -8905,7 +9090,7 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true);
}
- mScreen.flush();
+ screen_target->flush();
//gamma correct lighting
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -8919,22 +9104,22 @@ void LLPipeline::renderDeferredLighting()
LLGLDepthTest depth(GL_FALSE, GL_FALSE);
LLVector2 tc1(0,0);
- LLVector2 tc2((F32) mScreen.getWidth()*2,
- (F32) mScreen.getHeight()*2);
+ LLVector2 tc2((F32) screen_target->getWidth()*2,
+ (F32) screen_target->getHeight()*2);
- mScreen.bindTarget();
+ 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, mScreen.getUsage());
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage());
if (channel > -1)
{
- mScreen.bindTexture(0,channel);
+ screen_target->bindTexture(0,channel);
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
}
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight());
F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
@@ -8952,9 +9137,9 @@ void LLPipeline::renderDeferredLighting()
gGL.end();
- gGL.getTexUnit(channel)->unbind(mScreen.getUsage());
+ gGL.getTexUnit(channel)->unbind(screen_target->getUsage());
gDeferredPostGammaCorrectProgram.unbind();
- mScreen.flush();
+ screen_target->flush();
}
gGL.matrixMode(LLRender::MM_PROJECTION);
@@ -8962,7 +9147,7 @@ void LLPipeline::renderDeferredLighting()
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
- mScreen.bindTarget();
+ screen_target->bindTarget();
{ //render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
@@ -9013,541 +9198,10 @@ void LLPipeline::renderDeferredLighting()
}
}
- mScreen.flush();
+ screen_target->flush();
}
-void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
-{
- if (!sCull)
- {
- return;
- }
-
- {
- LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
-
- LLViewerCamera* camera = LLViewerCamera::getInstance();
-
- {
- LLGLDepthTest depth(GL_TRUE);
- mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
- }
-
- LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
-
- 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
- LLVertexBuffer::unbind();
-
- LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable blend(GL_BLEND);
-
- glh::matrix4f mat = glh_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 mSunDir;
- LLVector4 dir(mSunDir, 0.f);
- glh::vec4f tc(dir.mV);
- mat.mult_matrix_vec(tc);
- mTransformedSunDir.set(tc.v);
- }
-
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- if (RenderDeferredSSAO || RenderShadowDetail > 0)
- {
- mDeferredLight.bindTarget();
- { //paint shadow/SSAO light map (direct lighting lightmap)
- LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
- bindDeferredShader(gDeferredSunProgram);
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
- glClearColor(1,1,1,1);
- mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
-
- glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
-
- const U32 slice = 32;
- F32 offset[slice*3];
- for (U32 i = 0; i < 4; i++)
- {
- for (U32 j = 0; j < 8; j++)
- {
- glh::vec3f v;
- v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
- v.normalize();
- inv_trans.mult_matrix_vec(v);
- v.normalize();
- offset[(i*8+j)*3+0] = v.v[0];
- offset[(i*8+j)*3+1] = v.v[2];
- offset[(i*8+j)*3+2] = v.v[1];
- }
- }
-
- gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
- gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
-
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
- stop_glerror();
- }
-
- unbindDeferredShader(gDeferredSunProgram);
- }
- mDeferredLight.flush();
- }
-
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- stop_glerror();
- gGL.popMatrix();
- stop_glerror();
-
- target->bindTarget();
-
- //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
- glClearColor(0,0,0,0);
- target->clear(GL_COLOR_BUFFER_BIT);
-
- if (RenderDeferredAtmospheric)
- { //apply sunlight contribution
- LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
- {
- 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();
- }
-
- unbindDeferredShader(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;
-
- if (render_local)
- {
- 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++)
- {
- mTargetShadowSpotLight[i] = NULL;
- }
-
- std::list<LLVector4> light_colors;
-
- LLVertexBuffer::unbind();
-
- {
- bindDeferredShader(gDeferredLightProgram);
-
- if (mCubeVB.isNull())
- {
- mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
- }
-
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
- {
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
- if (!volume)
- {
- continue;
- }
-
- if (volume->isAttachment())
- {
- if (!sRenderAttachedLights)
- {
- continue;
- }
- }
-
-
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
-
- LLColor3 col = volume->getLightColor();
-
- if (col.magVecSquared() < 0.001f)
- {
- continue;
- }
-
- if (s <= 0.001f)
- {
- continue;
- }
-
- LLVector4a sa;
- sa.splat(s);
- if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
- {
- continue;
- }
-
- sVisibleLightCount++;
-
- if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
- camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
- 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())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- spot_lights.push_back(drawablep);
- continue;
- }
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
- 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()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- stop_glerror();
- }
- }
- else
- {
- if (volume->isLightSpotlight())
- {
- drawablep->getVOVolume()->updateSpotLightPriority();
- fullscreen_spot_lights.push_back(drawablep);
- continue;
- }
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
- light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
- }
- }
- unbindDeferredShader(gDeferredLightProgram);
- }
-
- if (!spot_lights.empty())
- {
- LLGLDepthTest depth(GL_TRUE, GL_FALSE);
- bindDeferredShader(gDeferredSpotLightProgram);
-
- mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-
- for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
-
- LLVector4a center;
- center.load3(drawablep->getPositionAgent().mV);
- const F32* c = center.getF32ptr();
- F32 s = volume->getLightRadius()*1.5f;
-
- sVisibleLightCount++;
-
- setupSpotLight(gDeferredSpotLightProgram, drawablep);
-
- LLColor3 col = volume->getLightColor();
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- gGL.syncMatrices();
-
- mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
- }
- gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
- 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);
-
- {
- LLGLDepthTest depth(GL_FALSE);
-
- //full screen blit
- gGL.pushMatrix();
- gGL.loadIdentity();
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.pushMatrix();
- gGL.loadIdentity();
-
- U32 count = 0;
-
- const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
- LLVector4 light[max_count];
- LLVector4 col[max_count];
-
- F32 far_z = 0.f;
-
- while (!fullscreen_lights.empty())
- {
- LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
- light[count] = fullscreen_lights.front();
- fullscreen_lights.pop_front();
- col[count] = light_colors.front();
- light_colors.pop_front();
-
- /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
- col[count].mV[1] = powf(col[count].mV[1], 2.2f);
- col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
-
- far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
- //col[count] = pow4fsrgb(col[count], 2.2f);
- count++;
- if (count == max_count || fullscreen_lights.empty())
- {
- U32 idx = count-1;
- bindDeferredShader(gDeferredMultiLightProgram[idx]);
- gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- 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);
- }
- }
-
- unbindDeferredShader(gDeferredMultiLightProgram[0]);
-
- bindDeferredShader(gDeferredMultiSpotLightProgram);
-
- gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
- for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
- {
- LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
- LLDrawable* drawablep = *iter;
-
- LLVOVolume* volume = drawablep->getVOVolume();
-
- LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
- F32 s = volume->getLightRadius()*1.5f;
-
- sVisibleLightCount++;
-
- glh::vec3f tc(c);
- mat.mult_matrix_vec(tc);
-
- setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
-
- LLColor3 col = volume->getLightColor();
-
- /*col.mV[0] = powf(col.mV[0], 2.2f);
- col.mV[1] = powf(col.mV[1], 2.2f);
- col.mV[2] = powf(col.mV[2], 2.2f);*/
-
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
- gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
- mDeferredVB->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);
- }
-
- /*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) target->getWidth()*2,
- (F32) target->getHeight()*2);
-
- 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, target->getUsage());
- if (channel > -1)
- {
- target->bindTexture(0,channel);
- gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
- }
-
- gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), 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(target->getUsage());
- gDeferredPostGammaCorrectProgram.unbind();
- target->flush();
- }
-
- gGL.matrixMode(LLRender::MM_PROJECTION);
- gGL.popMatrix();
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.popMatrix();
-
- target->bindTarget();*/
-
- { //render non-deferred geometry (alpha, fullbright, glow)
- LLGLDisable blend(GL_BLEND);
- LLGLDisable stencil(GL_STENCIL_TEST);
-
- pushRenderTypeMask();
- andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
- LLPipeline::RENDER_TYPE_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_GLOW,
- LLPipeline::RENDER_TYPE_BUMP,
- LLPipeline::RENDER_TYPE_PASS_SIMPLE,
- LLPipeline::RENDER_TYPE_PASS_ALPHA,
- LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_BUMP,
- LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
- LLPipeline::RENDER_TYPE_PASS_GLOW,
- LLPipeline::RENDER_TYPE_PASS_GRASS,
- LLPipeline::RENDER_TYPE_PASS_SHINY,
- LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
- LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
- LLPipeline::RENDER_TYPE_AVATAR,
- LLPipeline::RENDER_TYPE_ALPHA_MASK,
- LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
- END_RENDER_TYPES);
-
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
- popRenderTypeMask();
- }
-
- //target->flush();
-}
-
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -9577,7 +9231,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
LLMatrix4 light_mat(quat, LLVector4(origin,1.f));
glh::matrix4f light_to_agent((F32*) light_mat.mMatrix);
- glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent;
+ glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent;
glh::matrix4f screen_to_light = light_to_screen.inverse();
@@ -9689,12 +9343,16 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
void LLPipeline::unbindDeferredShader(LLGLSLShader &shader)
{
+ LLRenderTarget* deferred_target = LLPipeline::sReflectionRender ? &mWaterDeferredScreen : &mDeferredScreen;
+ LLRenderTarget* deferred_depth_target = LLPipeline::sReflectionRender ? &mWaterDeferredDepth : &mDeferredDepth;
+ LLRenderTarget* deferred_light_target = LLPipeline::sReflectionRender ? &mWaterDeferredLight : &mDeferredLight;
+
stop_glerror();
- shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage());
- shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage());
+ 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_LIGHT, deferred_light_target->getUsage());
shader.disableTexture(LLShaderMgr::DIFFUSE_MAP);
shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM);
@@ -9760,52 +9418,52 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLCamera camera = camera_in;
camera.setFar(camera.getFar()*0.87654321f);
- LLPipeline::sReflectionRender = true;
-
+
+ LLPipeline::sReflectionRender = true;
+
gPipeline.pushRenderTypeMask();
- glh::matrix4f projection = glh_get_current_projection();
+ glh::matrix4f projection = get_current_projection();
glh::matrix4f mat;
stop_glerror();
LLPlane plane;
- F32 height = gAgent.getRegion()->getWaterHeight();
- F32 to_clip = fabsf(camera.getOrigin().mV[2]-height);
- F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by
+ F32 water_height = gAgent.getRegion()->getWaterHeight();
+ F32 camera_height = camera_in.getOrigin().mV[2];
+ 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
LLVector3 pnorm;
- F32 pd;
-
S32 water_clip = 0;
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //camera is above water, clip plane points up
pnorm.setVec(0,0,1);
- pd = -height;
- plane.setVec(pnorm, pd);
- water_clip = -1;
+ plane.setVec(pnorm, -water_height);
+ water_clip = 1;
}
else
{ //camera is below water, clip plane points down
pnorm = LLVector3(0,0,-1);
- pd = height;
- plane.setVec(pnorm, pd);
- water_clip = 1;
+ plane.setVec(pnorm, water_height);
+ water_clip = -1;
}
- bool materials_in_water = false;
-
-#if MATERIALS_IN_REFLECTIONS
- materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
-#endif
-
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
-
//disable occlusion culling for reflection map for now
S32 occlusion = LLPipeline::sUseOcclusion;
+
LLPipeline::sUseOcclusion = 0;
+
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
@@ -9820,31 +9478,30 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.pushMatrix();
- mat.set_scale(glh::vec3f(1,1,-1));
- mat.set_translate(glh::vec3f(0,0,height*2.f));
+ glh::matrix4f current = get_current_modelview();
- glh::matrix4f current = glh_get_current_modelview();
+ glh::matrix4f mat;
+ camera.getOpenGLTransform(mat.m);
- mat = current * mat;
+ glh::matrix4f scal;
+ scal.set_scale(glh::vec3f(1, 1, -1));
+ mat = scal * mat;
- glh_set_current_modelview(mat);
- gGL.loadMatrix(mat.m);
+ // convert from CFR to OGL coord sys...
+ mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
- LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
+ mReflectionModelView = mat;
- glh::matrix4f inv_mat = mat.inverse();
-
- glh::vec3f origin(0,0,0);
- inv_mat.mult_matrix_vec(origin);
+ set_current_modelview(mat);
+ gGL.loadMatrix(mat.m);
- camera.setOrigin(origin.v);
+ LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
glCullFace(GL_FRONT);
- static LLCullResult ref_result;
-
if (LLDrawPoolWater::sNeedsReflectionUpdate)
{
//initial sky pass (no user clip plane)
@@ -9855,31 +9512,32 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::RENDER_TYPE_CLOUDS,
LLPipeline::END_RENDER_TYPES);
- static LLCullResult result;
- updateCull(camera, result);
- stateSort(camera, result);
-
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- mWaterRef.flush();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
- gPipeline.grabReferences(result);
- gPipeline.mDeferredScreen.bindTarget();
- gGL.setColorMask(true, true);
- glClearColor(0,0,0,0);
- gPipeline.mDeferredScreen.clear();
+ static LLCullResult sky_and_clouds;
+ updateCull(camera, sky_and_clouds);
+ stateSort(camera, sky_and_clouds);
+ gPipeline.grabReferences(sky_and_clouds);
- renderGeomDeferred(camera);
+ if (LLPipeline::sRenderDeferred)
+ {
+ gPipeline.mWaterDeferredDepth.bindTarget();
+ gPipeline.mWaterDeferredDepth.clear();
+ gPipeline.mWaterDeferredScreen.bindTarget();
+ gPipeline.mWaterDeferredScreen.clear();
+ renderGeomDeferred(camera);
}
else
{
- renderGeom(camera, TRUE);
+ renderGeom(camera, TRUE);
}
gPipeline.popRenderTypeMask();
}
gGL.setColorMask(true, false);
+
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
@@ -9905,42 +9563,44 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
}
- LLGLUserClipPlane clip_plane(plane, mat, projection);
- LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, ref_result, -water_clip, &plane);
- stateSort(camera, ref_result);
+
}
if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
- if (RenderReflectionDetail > 0)
+ if (detail > 0)
{
- gPipeline.grabReferences(ref_result);
- LLGLUserClipPlane clip_plane(plane, mat, projection);
+ static LLCullResult reflected_objects;
+ LLGLDisable cull(GL_CULL_FACE);
+ updateCull(camera, reflected_objects);
+ stateSort(camera, reflected_objects);
- if (LLPipeline::sRenderDeferred && materials_in_water)
+ gPipeline.grabReferences(reflected_objects);
+
+ LLGLUserClipPlane clip_plane(plane, mat, projection);
+ if (LLPipeline::sRenderDeferred)
{
renderGeomDeferred(camera);
+ gPipeline.mWaterDeferredScreen.flush();
+ gPipeline.mWaterDeferredDepth.flush();
+ mWaterRef.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(),
+ 0, 0, gPipeline.mWaterRef.getWidth(), gPipeline.mWaterRef.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
else
{
- renderGeom(camera);
- }
+ renderGeom(camera);
+ }
+ }
}
- }
-
- if (LLPipeline::sRenderDeferred && materials_in_water)
- {
- gPipeline.mDeferredScreen.flush();
- renderDeferredLightingToRT(&mWaterRef);
- }
gPipeline.popRenderTypeMask();
}
+
glCullFace(GL_BACK);
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.popMatrix();
mWaterRef.flush();
- glh_set_current_modelview(current);
+ set_current_modelview(current);
LLPipeline::sUseOcclusion = occlusion;
}
@@ -9970,7 +9630,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- LLColor4& col = LLDrawPoolWater::sWaterFogColor;
+ LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
@@ -9980,8 +9640,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
{
//clip out geometry on the same side of water as the camera
- mat = glh_get_current_modelview();
- LLPlane plane(-pnorm, -(pd+pad));
+ mat = get_current_modelview();
+ LLPlane plane(-pnorm, -distance_to_water);
LLGLUserClipPlane clip_plane(plane, mat, projection);
static LLCullResult result;
@@ -9995,13 +9655,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, false);
- if (LLPipeline::sRenderDeferred && materials_in_water)
+ if (LLPipeline::sRenderDeferred)
{
mWaterDis.flush();
- gPipeline.mDeferredScreen.bindTarget();
+ gPipeline.mWaterDeferredScreen.bindTarget();
gGL.setColorMask(true, true);
glClearColor(0,0,0,0);
- gPipeline.mDeferredScreen.clear();
+ gPipeline.mWaterDeferredScreen.clear();
gPipeline.grabReferences(result);
renderGeomDeferred(camera);
}
@@ -10022,19 +9682,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
}
- if (LLPipeline::sRenderDeferred && materials_in_water)
+ if (LLPipeline::sRenderDeferred)
{
- gPipeline.mDeferredScreen.flush();
- renderDeferredLightingToRT(&mWaterDis);
+ gPipeline.mWaterDeferredScreen.flush();
+ gPipeline.mWaterDeferredDepth.flush();
+ mWaterDis.copyContents(gPipeline.mWaterDeferredScreen, 0, 0, gPipeline.mWaterDeferredScreen.getWidth(), gPipeline.mWaterDeferredScreen.getHeight(),
+ 0, 0, gPipeline.mWaterDeferredDepth.getWidth(), gPipeline.mWaterDeferredDepth.getHeight(), GL_COLOR_BUFFER_BIT, GL_NEAREST);
}
}
- mWaterDis.flush();
- LLPipeline::sUnderWaterRender = false;
-
+ mWaterDis.flush();
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
+ LLPipeline::sUnderWaterRender = false;
LLPipeline::sReflectionRender = false;
if (!LLRenderTarget::sUseFBO)
@@ -10046,8 +9707,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
- LLPlane npnorm(-pnorm, -pd);
- LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
LLGLState::checkStates();
@@ -10205,8 +9864,15 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
gGL.diffuseColor4f(1,1,1,1);
- gGL.setColorMask(false, false);
-
+
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+
+ // if not using VSM, disable color writes
+ if (shadow_detail <= 2)
+ {
+ gGL.setColorMask(false, false);
+ }
+
LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
gGL.getTexUnit(0)->disable();
@@ -10425,23 +10091,25 @@ bool LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
for (U32 j = 0; j < 3; ++j)
{
- if (p[j] < ext[0].mV[j] ||
- p[j] > ext[1].mV[j])
+ if (p[j] < ext[0].mV[j] || p[j] > ext[1].mV[j])
{
found = false;
break;
}
}
-
- for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
+
+ if (found) // don't bother testing user clip planes if we're already rejected...
{
- const LLPlane& cp = camera.getAgentPlane(j);
- F32 dist = cp.dist(pp[i]);
- if (dist > 0.05f) //point is above some plane, not contained
- {
- found = false;
- break;
- }
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
+ {
+ const LLPlane& cp = camera.getAgentPlane(j);
+ F32 dist = cp.dist(pp[i]);
+ if (dist > 0.05f) //point is above some plane, not contained
+ {
+ found = false;
+ break;
+ }
+ }
}
if (found)
@@ -10535,6 +10203,187 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
}
+LLRenderTarget* LLPipeline::getShadowTarget(U32 i)
+{
+ return &mShadow[i];
+}
+
+static LLTrace::BlockTimerStatHandle FTM_GEN_SKY_INDIRECT("Gen Sky Indirect");
+
+void LLPipeline::generateSkyIndirect()
+{
+ if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderUseAdvancedAtmospherics"))
+ {
+ return;
+ }
+
+ LL_RECORD_BLOCK_TIME(FTM_GEN_SKY_INDIRECT);
+
+ gGL.setColorMask(true, true);
+
+ LLVertexBuffer::unbind();
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ mSkySH.bindTarget();
+
+ bindDeferredShader(gDeferredGenSkyShProgram, &mSkySH);
+
+ gDeferredGenSkyShProgram.bind();
+
+ llassert(gAtmosphere);
+
+ int channel = -1;
+
+ if (gAtmosphere)
+ {
+ // bind precomputed textures necessary for calculating sun and sky luminance
+ channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance());
+ }
+
+ channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering());
+ }
+
+ channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D);
+ if (channel > -1)
+ {
+ gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering());
+ }
+
+ channel = gDeferredGenSkyShProgram.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE);
+ if (channel > -1)
+ {
+ gDeferredGenSkyShProgram.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance());
+ }
+ }
+
+ gDeferredGenSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mSkySH.getWidth(), mSkySH.getHeight());
+
+ LLStrider<LLVector3> vertices;
+ LLStrider<LLVector2> texCoords;
+ LLStrider<U16> indices;
+
+ if (!mDeferredVB->allocateBuffer(4, 6, TRUE))
+ {
+ LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL;
+ }
+
+ BOOL success = mDeferredVB->getVertexStrider(vertices)
+ && mDeferredVB->getTexCoord0Strider(texCoords)
+ && mDeferredVB->getIndexStrider(indices);
+
+ if(!success)
+ {
+ LL_ERRS() << "Failed updating WindLight fullscreen sky geometry." << LL_ENDL;
+ }
+
+ *vertices++ = LLVector3(-1.0f, -1.0f, 0.0f);
+ *vertices++ = LLVector3( 1.0f, -1.0f, 0.0f);
+ *vertices++ = LLVector3(-1.0f, 1.0f, 0.0f);
+ *vertices++ = LLVector3( 1.0f, 1.0f, 0.0f);
+
+ *texCoords++ = LLVector2(0.0f, 0.0f);
+ *texCoords++ = LLVector2(1.0f, 0.0f);
+ *texCoords++ = LLVector2(0.0f, 1.0f);
+ *texCoords++ = LLVector2(1.0f, 1.0f);
+
+ *indices++ = 0;
+ *indices++ = 1;
+ *indices++ = 2;
+ *indices++ = 1;
+ *indices++ = 3;
+ *indices++ = 2;
+
+ mDeferredVB->flush();
+
+ glClearColor(0,0,0,0);
+ mSkySH.clear(GL_COLOR_BUFFER_BIT);
+
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE, GL_ALWAYS);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0);
+ stop_glerror();
+
+ gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::TRANSMITTANCE_TEX);
+ gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SCATTER_TEX);
+ gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX);
+ gDeferredGenSkyShProgram.disableTexture(LLShaderMgr::ILLUMINANCE_TEX);
+ gDeferredGenSkyShProgram.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV);
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+ gGL.getTexUnit(0)->activate();
+ gDeferredGenSkyShProgram.unbind();
+
+ mSkySH.flush();
+
+#if GATHER_SKY_SH
+ gDeferredGatherSkyShProgram.bind();
+
+ S32 res = mSkySH[0].getWidth();
+ S32 ping = 0;
+
+ while (res > 1)
+ {
+ S32 pong = 1 - ping;
+ S32 l1r_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1R, mSkySH[ping].getUsage());
+ if (l1r_channel > -1)
+ {
+ mSkySH[ping].bindTexture(0,l1r_channel);
+ gGL.getTexUnit(l1r_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1b_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1G, mSkySH[ping].getUsage());
+ if (l1b_channel > -1)
+ {
+ mSkySH[ping].bindTexture(1,l1b_channel);
+ gGL.getTexUnit(l1b_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ S32 l1g_channel = gDeferredGatherSkyShProgram.enableTexture(LLShaderMgr::SH_INPUT_L1B, mSkySH[ping].getUsage());
+ if (l1g_channel > -1)
+ {
+ mSkySH[ping].bindTexture(2,l1g_channel);
+ gGL.getTexUnit(l1g_channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredGatherSkyShProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, res >> 1, res >> 1);
+
+ glViewport(0, 0, res >> 1, res >> 1);
+
+ mSkySH[pong].bindTarget();
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0);
+ mDeferredVB->drawRange(LLRender::TRIANGLES, 0, mDeferredVB->getNumVerts() - 1, mDeferredVB->getNumIndices(), 0);
+ stop_glerror();
+
+ mSkySH[pong].flush();
+
+ gGL.getTexUnit(l1r_channel)->unbind(mSkySH[ping].getUsage());
+ gGL.getTexUnit(l1b_channel)->unbind(mSkySH[ping].getUsage());
+ gGL.getTexUnit(l1g_channel)->unbind(mSkySH[ping].getUsage());
+
+ ping ^= 1;
+ res >>= 1;
+ }
+#endif
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+}
static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
@@ -10550,7 +10399,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
bool skip_avatar_update = false;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
{
-
skip_avatar_update = true;
}
@@ -10606,13 +10454,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
- gGL.setColorMask(false, false);
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+
+ // if not using VSM, disable color writes
+ if (shadow_detail <= 2)
+ {
+ gGL.setColorMask(false, false);
+ }
//get sun view matrix
//store current projection/modelview matrix
- glh::matrix4f saved_proj = glh_get_current_projection();
- glh::matrix4f saved_view = glh_get_current_modelview();
+ glh::matrix4f saved_proj = get_current_projection();
+ glh::matrix4f saved_view = get_current_modelview();
glh::matrix4f inv_view = saved_view.inverse();
glh::matrix4f view[6];
@@ -10633,15 +10487,20 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//LLVector3 n = RenderShadowNearDist;
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
+ LLEnvironment& environment = LLEnvironment::instance();
+ LLSettingsSky::ptr_t psky = environment.getCurrentSky();
+
+ LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir);
+
//put together a universal "near clip" plane for shadow frusta
LLPlane shadow_near_clip;
- {
+ {
LLVector3 p = gAgent.getPositionAgent();
- p += mSunDir * RenderFarClip*2.f;
- shadow_near_clip.setVec(p, mSunDir);
+ p += caster_dir * RenderFarClip*2.f;
+ shadow_near_clip.setVec(p, caster_dir);
}
- LLVector3 lightDir = -mSunDir;
+ LLVector3 lightDir = -caster_dir;
lightDir.normVec();
glh::vec3f light_dir(lightDir.mV);
@@ -10744,17 +10603,27 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
// 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)
+ bool sun_up = environment.getIsSunUp();
+ bool moon_up = environment.getIsMoonUp();
+ bool sun_is_primary = sun_up || !moon_up;
+ bool ignore_shadows = (sun_is_primary && (mSunDiffuse == LLColor4::black))
+ || (moon_up && (mMoonDiffuse == LLColor4::black))
+ || !(sun_up || moon_up);
+
+ if (ignore_shadows)
{ //sun diffuse is totally black, shadows don't matter
LLGLDepthTest depth(GL_TRUE);
for (S32 j = 0; j < 4; j++)
{
- mShadow[j].bindTarget();
- mShadow[j].clear();
- mShadow[j].flush();
+ LLRenderTarget* shadow_target = getShadowTarget(j);
+ if (shadow_target)
+ {
+ shadow_target->bindTarget();
+ shadow_target->clear();
+ shadow_target->flush();
+ }
}
}
else
@@ -10769,8 +10638,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
//restore render matrices
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
LLVector3 eye = camera.getOrigin();
@@ -10820,12 +10689,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowCamera[j+4] = shadow_cam;
}
- mShadow[j].bindTarget();
- {
- LLGLDepthTest depth(GL_TRUE);
- mShadow[j].clear();
- }
- mShadow[j].flush();
+ LLRenderTarget* shadow_target = getShadowTarget(j);
+ if (shadow_target)
+ {
+ shadow_target->bindTarget();
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ shadow_target->clear();
+ }
+ shadow_target->flush();
+ }
mShadowError.mV[j] = 0.f;
mShadowFOV.mV[j] = 0.f;
@@ -11083,8 +10956,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
shadow_cam.setOrigin(0,0,0);
- glh_set_current_modelview(view[j]);
- glh_set_current_projection(proj[j]);
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
@@ -11097,8 +10970,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
0.f, 0.f, 0.5f, 0.5f,
0.f, 0.f, 0.f, 1.f);
- glh_set_current_modelview(view[j]);
- glh_set_current_projection(proj[j]);
+ set_current_modelview(view[j]);
+ set_current_projection(proj[j]);
for (U32 i = 0; i < 16; i++)
{
@@ -11114,20 +10987,24 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
stop_glerror();
- mShadow[j].bindTarget();
- mShadow[j].getViewport(gGLViewport);
- mShadow[j].clear();
-
- U32 target_width = mShadow[j].getWidth();
+ LLRenderTarget* shadow_target = getShadowTarget(j);
- {
- static LLCullResult result[4];
+ if (shadow_target)
+ {
+ shadow_target->bindTarget();
+ shadow_target->getViewport(gGLViewport);
+ shadow_target->clear();
- renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
- }
+ U32 target_width = shadow_target->getWidth();
+
+ {
+ static LLCullResult result[4];
+ renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
+ }
+
+ shadow_target->flush();
+ }
- mShadow[j].flush();
-
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
@@ -11177,8 +11054,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
for (S32 i = 0; i < 2; i++)
{
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
if (mShadowSpotLight[i].isNull())
{
@@ -11238,8 +11115,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
0.f, 0.f, 0.5f, 0.5f,
0.f, 0.f, 0.f, 1.f);
- glh_set_current_modelview(view[i+4]);
- glh_set_current_projection(proj[i+4]);
+ set_current_modelview(view[i+4]);
+ set_current_projection(proj[i+4]);
mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
@@ -11260,19 +11137,23 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
stop_glerror();
- mShadow[i+4].bindTarget();
- mShadow[i+4].getViewport(gGLViewport);
- mShadow[i+4].clear();
-
- U32 target_width = mShadow[i+4].getWidth();
+ LLRenderTarget* shadow_target = getShadowTarget(i + 4);
- static LLCullResult result[2];
+ if (shadow_target)
+ {
+ shadow_target->bindTarget();
+ shadow_target->getViewport(gGLViewport);
+ shadow_target->clear();
+
+ U32 target_width = shadow_target->getWidth();
- LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
+ static LLCullResult result[2];
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
+ renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
- mShadow[i+4].flush();
+ shadow_target->flush();
+ }
}
}
else
@@ -11283,13 +11164,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (!CameraOffset)
{
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
+ set_current_modelview(saved_view);
+ set_current_projection(saved_proj);
}
else
{
- glh_set_current_modelview(view[1]);
- glh_set_current_projection(proj[1]);
+ set_current_modelview(view[1]);
+ set_current_projection(proj[1]);
gGL.loadMatrix(view[1].m);
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.loadMatrix(proj[1].m);
@@ -11467,7 +11348,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG;
F32 aspect = tdim.mV[0]/tdim.mV[1];
glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f);
- glh_set_current_projection(persp);
+ set_current_projection(persp);
gGL.loadMatrix(persp.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
@@ -11478,7 +11359,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat;
gGL.loadMatrix(mat.m);
- glh_set_current_modelview(mat);
+ set_current_modelview(mat);
glClearColor(0.0f,0.0f,0.0f,0.0f);
gGL.setColorMask(true, true);
@@ -11973,3 +11854,8 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
+bool LLPipeline::useAdvancedAtmospherics() const
+{
+ return sUseAdvancedAtmospherics;
+}
+