summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2011-04-08 01:24:17 -0500
committerDave Parks <davep@lindenlab.com>2011-04-08 01:24:17 -0500
commit897a4668bd385fe73237c163284a6bc63353bf26 (patch)
treeae74dddfd9edd70a9c2635f8b690b1e2d5465418
parentfeccb5b84c7ffcfe98a9afd042c7ca44b8717aaf (diff)
SH-1320 Fix for flickering objects in water distortion/reflection maps.
-rw-r--r--indra/llrender/llgl.cpp22
-rw-r--r--indra/llrender/llgl.h4
-rwxr-xr-xindra/newview/pipeline.cpp63
-rw-r--r--indra/newview/pipeline.h2
4 files changed, 70 insertions, 21 deletions
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index d5f0b81830..b508705759 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1858,12 +1858,17 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
}
}
-LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection)
+LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
{
- mModelview = modelview;
- mProjection = projection;
+ mApply = apply;
- setPlane(p[0], p[1], p[2], p[3]);
+ if (mApply)
+ {
+ mModelview = modelview;
+ mProjection = projection;
+
+ setPlane(p[0], p[1], p[2], p[3]);
+ }
}
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
@@ -1894,9 +1899,12 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
LLGLUserClipPlane::~LLGLUserClipPlane()
{
- glMatrixMode(GL_PROJECTION);
- glPopMatrix();
- glMatrixMode(GL_MODELVIEW);
+ if (mApply)
+ {
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ }
}
LLGLNamePool::LLGLNamePool()
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 0d7ba15b12..43992d51cb 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -301,12 +301,14 @@ class LLGLUserClipPlane
{
public:
- LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection);
+ LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true);
~LLGLUserClipPlane();
void setPlane(F32 a, F32 b, F32 c, F32 d);
private:
+ bool mApply;
+
glh::matrix4f mProjection;
glh::matrix4f mModelview;
};
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index bf65fd123e..d18e1de60c 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -240,6 +240,16 @@ 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, GLdouble* dst)
{
for (U32 i = 0; i < 16; i++)
@@ -1910,7 +1920,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
static LLFastTimer::DeclareTimer FTM_CULL("Object Culling");
-void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip)
+void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep)
{
LLFastTimer t(FTM_CULL);
LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL);
@@ -1930,6 +1940,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
mScreen.bindTarget();
}
+ if (sUseOcclusion > 1)
+ {
+ gGL.setColorMask(false, false);
+ }
+
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadMatrixd(gGLLastProjection);
@@ -1944,10 +1959,37 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
LLGLDisable test(GL_ALPHA_TEST);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
- if (sUseOcclusion > 1)
+
+ //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling)
+ LLViewerRegion* region = gAgent.getRegion();
+ LLPlane plane;
+
+ if (planep)
{
- gGL.setColorMask(false, false);
+ 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);
@@ -7887,18 +7929,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
LLPipeline::END_RENDER_TYPES);
static LLCullResult result;
updateCull(camera, result);
stateSort(camera, result);
- andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
-
- //bad pop here
renderGeom(camera, TRUE);
gPipeline.popRenderTypeMask();
@@ -7931,7 +7968,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLGLUserClipPlane clip_plane(plane, mat, projection);
LLGLDisable cull(GL_CULL_FACE);
- updateCull(camera, ref_result, 1);
+ updateCull(camera, ref_result, -water_clip, &plane);
stateSort(camera, ref_result);
}
@@ -7988,9 +8025,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
//clip out geometry on the same side of water as the camera
mat = glh_get_current_modelview();
- LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection);
+ LLPlane plane(-pnorm, -(pd+pad));
+
+ LLGLUserClipPlane clip_plane(plane, mat, projection);
static LLCullResult result;
- updateCull(camera, result, water_clip);
+ updateCull(camera, result, water_clip, &plane);
stateSort(camera, result);
gGL.setColorMask(true, true);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 074c1742e2..0cf3fde562 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -208,7 +208,7 @@ public:
BOOL visibleObjectsInFrustum(LLCamera& camera);
BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max);
BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir = LLVector3(0,0,0));
- void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
+ void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0, LLPlane* plane = NULL); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane
void createObjects(F32 max_dtime);
void createObject(LLViewerObject* vobj);
void updateGeom(F32 max_dtime);