VWR-21927 Fix for water reflections causing LoD updates.
SH-735 Potential fix for ATI X1950 wasting time in occlusion culling.meow-7.2.2
parent
1e647e2cd2
commit
808cd0fcbf
|
|
@ -222,7 +222,17 @@ static U8 sOcclusionIndices[] =
|
|||
b000, b110, b100, b101, b001, b011, b010, b110,
|
||||
};
|
||||
|
||||
U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
|
||||
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
|
||||
{
|
||||
LLVector4a origin;
|
||||
origin.load3(camera->getOrigin().mV);
|
||||
|
||||
S32 cypher = center.greaterThan(origin).getGatheredBits() & 0x7;
|
||||
|
||||
return cypher*8;
|
||||
}
|
||||
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
|
||||
{
|
||||
LLVector4a origin;
|
||||
origin.load3(camera->getOrigin().mV);
|
||||
|
|
@ -231,12 +241,21 @@ U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center)
|
|||
|
||||
return sOcclusionIndices+cypher*8;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LLSpatialGroup::buildOcclusion()
|
||||
{
|
||||
if (!mOcclusionVerts)
|
||||
if (mOcclusionVerts.isNull())
|
||||
{
|
||||
mOcclusionVerts = new LLVector4a[8];
|
||||
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_DYNAMIC_DRAW_ARB);
|
||||
mOcclusionVerts->allocateBuffer(8, 64, true);
|
||||
|
||||
LLStrider<U16> idx;
|
||||
mOcclusionVerts->getIndexStrider(idx);
|
||||
for (U32 i = 0; i < 64; i++)
|
||||
{
|
||||
*idx++ = sOcclusionIndices[i];
|
||||
}
|
||||
}
|
||||
|
||||
LLVector4a fudge;
|
||||
|
|
@ -251,7 +270,12 @@ void LLSpatialGroup::buildOcclusion()
|
|||
|
||||
r.setMin(r, r2);
|
||||
|
||||
LLVector4a* v = mOcclusionVerts;
|
||||
LLStrider<LLVector3> pos;
|
||||
|
||||
mOcclusionVerts->getVertexStrider(pos);
|
||||
|
||||
LLVector4a* v = (LLVector4a*) pos.get();
|
||||
|
||||
const LLVector4a& c = mBounds[0];
|
||||
const LLVector4a& s = r;
|
||||
|
||||
|
|
@ -275,10 +299,13 @@ void LLSpatialGroup::buildOcclusion()
|
|||
|
||||
for (S32 i = 0; i < 8; ++i)
|
||||
{
|
||||
v[i] = s;
|
||||
v[i].mul(octant[i]);
|
||||
v[i].add(c);
|
||||
LLVector4a p;
|
||||
p.setMul(s, octant[i]);
|
||||
p.add(c);
|
||||
v[i] = p;
|
||||
}
|
||||
|
||||
mOcclusionVerts->setBuffer(0);
|
||||
|
||||
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
|
||||
}
|
||||
|
|
@ -339,7 +366,6 @@ LLSpatialGroup::~LLSpatialGroup()
|
|||
sQueryPool.release(mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
}
|
||||
|
||||
delete [] mOcclusionVerts;
|
||||
mOcclusionVerts = NULL;
|
||||
|
||||
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
|
||||
|
|
@ -881,12 +907,9 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
|
|||
gPipeline.markRebuild(this, TRUE);
|
||||
}
|
||||
|
||||
if (mOcclusionVerts)
|
||||
if (mOcclusionVerts.notNull())
|
||||
{
|
||||
for (U32 i = 0; i < 8; i++)
|
||||
{
|
||||
mOcclusionVerts[i].add(offset);
|
||||
}
|
||||
setState(OCCLUSION_DIRTY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1423,7 +1446,6 @@ void LLSpatialGroup::destroyGL()
|
|||
}
|
||||
}
|
||||
|
||||
delete [] mOcclusionVerts;
|
||||
mOcclusionVerts = NULL;
|
||||
|
||||
for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
|
||||
|
|
@ -1573,57 +1595,58 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
|
|||
else
|
||||
{
|
||||
if (!isOcclusionState(QUERY_PENDING) || isOcclusionState(DISCARD_QUERY))
|
||||
{ //no query pending, or previous query to be discarded
|
||||
LLFastTimer t(FTM_RENDER_OCCLUSION);
|
||||
{
|
||||
{ //no query pending, or previous query to be discarded
|
||||
LLFastTimer t(FTM_RENDER_OCCLUSION);
|
||||
|
||||
if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
|
||||
{
|
||||
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
|
||||
if (!mOcclusionQuery[LLViewerCamera::sCurCameraID])
|
||||
{
|
||||
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
|
||||
}
|
||||
|
||||
if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
|
||||
{
|
||||
buildOcclusion();
|
||||
}
|
||||
|
||||
// Depth clamp all water to avoid it being culled as a result of being
|
||||
// behind the far clip plane, and in the case of edge water to avoid
|
||||
// it being culled while still visible.
|
||||
bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
|
||||
(mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
|
||||
mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
|
||||
if (use_depth_clamp)
|
||||
{
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
|
||||
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
|
||||
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
|
||||
if (camera->getOrigin().isExactlyZero())
|
||||
{ //origin is invalid, draw entire box
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
|
||||
}
|
||||
|
||||
glEndQueryARB(mode);
|
||||
|
||||
if (use_depth_clamp)
|
||||
{
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY))
|
||||
{
|
||||
buildOcclusion();
|
||||
}
|
||||
|
||||
// Depth clamp all water to avoid it being culled as a result of being
|
||||
// behind the far clip plane, and in the case of edge water to avoid
|
||||
// it being culled while still visible.
|
||||
bool const use_depth_clamp = gGLManager.mHasDepthClamp &&
|
||||
(mSpatialPartition->mDrawableType == LLDrawPool::POOL_WATER ||
|
||||
mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER);
|
||||
if (use_depth_clamp)
|
||||
{
|
||||
glEnable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
|
||||
U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB;
|
||||
|
||||
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
|
||||
|
||||
glVertexPointer(3, GL_FLOAT, 16, mOcclusionVerts);
|
||||
if (camera->getOrigin().isExactlyZero())
|
||||
{ //origin is invalid, draw entire box
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, sOcclusionIndices+b111*8);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices(camera, mBounds[0]));
|
||||
}
|
||||
glEndQueryARB(mode);
|
||||
|
||||
if (use_depth_clamp)
|
||||
{
|
||||
glDisable(GL_DEPTH_CLAMP);
|
||||
}
|
||||
setOcclusionState(LLSpatialGroup::QUERY_PENDING);
|
||||
clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
|
||||
}
|
||||
|
||||
setOcclusionState(LLSpatialGroup::QUERY_PENDING);
|
||||
clearOcclusionState(LLSpatialGroup::DISCARD_QUERY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2617,17 +2640,17 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
|
|||
gGL.color4f(0.f, 0.75f, 0.f, 0.5f);
|
||||
pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX);
|
||||
}
|
||||
else if (camera && group->mOcclusionVerts)
|
||||
else if (camera && group->mOcclusionVerts.notNull())
|
||||
{
|
||||
LLVertexBuffer::unbind();
|
||||
glVertexPointer(3, GL_FLOAT, 16, group->mOcclusionVerts);
|
||||
|
||||
group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
|
||||
|
||||
glColor4f(1.0f, 0.f, 0.f, 0.5f);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));
|
||||
group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
|
||||
glColor4f(1.0f, 1.f, 1.f, 1.0f);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, GL_UNSIGNED_BYTE, get_box_fan_indices(camera, group->mBounds[0]));
|
||||
group->mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, group->mBounds[0]));
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVe
|
|||
void pushVerts(LLFace* face, U32 mask);
|
||||
|
||||
// get index buffer for binary encoded axis vertex buffer given a box at center being viewed by given camera
|
||||
U8* get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
|
||||
U32 get_box_fan_indices(LLCamera* camera, const LLVector4a& center);
|
||||
U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center);
|
||||
|
||||
class LLDrawInfo : public LLRefCount
|
||||
{
|
||||
|
|
@ -393,7 +394,7 @@ public:
|
|||
LLSpatialPartition* mSpatialPartition;
|
||||
|
||||
LLPointer<LLVertexBuffer> mVertexBuffer;
|
||||
LLVector4a* mOcclusionVerts;
|
||||
LLPointer<LLVertexBuffer> mOcclusionVerts;
|
||||
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
|
||||
|
||||
U32 mBufferUsage;
|
||||
|
|
|
|||
|
|
@ -7084,6 +7084,8 @@ void LLPipeline::renderDeferredLighting()
|
|||
|
||||
std::list<LLVector4> light_colors;
|
||||
|
||||
LLVertexBuffer::unbind();
|
||||
|
||||
F32 v[24];
|
||||
glVertexPointer(3, GL_FLOAT, 0, v);
|
||||
|
||||
|
|
@ -7173,7 +7175,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
|
||||
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
|
@ -7239,7 +7241,7 @@ void LLPipeline::renderDeferredLighting()
|
|||
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
|
||||
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
|
||||
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
|
||||
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
|
||||
}
|
||||
gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
|
||||
unbindDeferredShader(gDeferredSpotLightProgram);
|
||||
|
|
@ -7650,11 +7652,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
LLCamera camera = camera_in;
|
||||
camera.setFar(camera.getFar()*0.87654321f);
|
||||
LLPipeline::sReflectionRender = TRUE;
|
||||
S32 occlusion = LLPipeline::sUseOcclusion;
|
||||
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
|
||||
LLPipeline::sUseOcclusion = llmin(occlusion, 1);
|
||||
|
||||
gPipeline.pushRenderTypeMask();
|
||||
|
||||
|
|
@ -7693,19 +7690,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
glClearColor(0,0,0,0);
|
||||
mWaterRef.bindTarget();
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
|
||||
gGL.setColorMask(true, true);
|
||||
mWaterRef.clear();
|
||||
gGL.setColorMask(true, false);
|
||||
|
||||
mWaterRef.getViewport(gGLViewport);
|
||||
|
||||
|
||||
stop_glerror();
|
||||
|
||||
glPushMatrix();
|
||||
|
||||
mat.set_scale(glh::vec3f(1,1,-1));
|
||||
mat.set_translate(glh::vec3f(0,0,height*2.f));
|
||||
|
||||
|
||||
glh::matrix4f current = glh_get_current_modelview();
|
||||
|
||||
mat = current * mat;
|
||||
|
|
@ -7725,22 +7723,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
glCullFace(GL_FRONT);
|
||||
|
||||
static LLCullResult ref_result;
|
||||
|
||||
|
||||
if (LLDrawPoolWater::sNeedsDistortionUpdate)
|
||||
{
|
||||
//initial sky pass (no user clip plane)
|
||||
{ //mask out everything but the sky
|
||||
gPipeline.pushRenderTypeMask();
|
||||
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
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);
|
||||
LLPipeline::RENDER_TYPE_CLOUDS,
|
||||
LLPipeline::RENDER_TYPE_WL_SKY,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
renderGeom(camera, TRUE);
|
||||
gPipeline.popRenderTypeMask();
|
||||
|
|
@ -7749,23 +7749,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
gPipeline.pushRenderTypeMask();
|
||||
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
|
||||
LLPipeline::RENDER_TYPE_VOIDWATER,
|
||||
LLPipeline::RENDER_TYPE_GROUND,
|
||||
LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_CLOUDS,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
LLPipeline::RENDER_TYPE_VOIDWATER,
|
||||
LLPipeline::RENDER_TYPE_GROUND,
|
||||
LLPipeline::RENDER_TYPE_SKY,
|
||||
LLPipeline::RENDER_TYPE_CLOUDS,
|
||||
LLPipeline::END_RENDER_TYPES);
|
||||
|
||||
S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
|
||||
S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
|
||||
if (detail > 0)
|
||||
{ //mask out selected geometry based on reflection detail
|
||||
if (detail < 4)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
|
||||
if (detail < 3)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
|
||||
if (detail < 2)
|
||||
if (detail < 3)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
|
||||
if (detail < 2)
|
||||
{
|
||||
clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
|
||||
}
|
||||
}
|
||||
|
|
@ -7776,16 +7776,16 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
updateCull(camera, ref_result, 1);
|
||||
stateSort(camera, ref_result);
|
||||
}
|
||||
|
||||
if (LLDrawPoolWater::sNeedsDistortionUpdate)
|
||||
{
|
||||
if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
|
||||
|
||||
if (LLDrawPoolWater::sNeedsDistortionUpdate)
|
||||
{
|
||||
gPipeline.grabReferences(ref_result);
|
||||
LLGLUserClipPlane clip_plane(plane, mat, projection);
|
||||
renderGeom(camera);
|
||||
}
|
||||
}
|
||||
if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
|
||||
{
|
||||
gPipeline.grabReferences(ref_result);
|
||||
LLGLUserClipPlane clip_plane(plane, mat, projection);
|
||||
renderGeom(camera);
|
||||
}
|
||||
}
|
||||
|
||||
gPipeline.popRenderTypeMask();
|
||||
}
|
||||
|
|
@ -7823,6 +7823,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
|
||||
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
|
||||
mWaterDis.bindTarget();
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
|
||||
mWaterDis.getViewport(gGLViewport);
|
||||
|
||||
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
|
||||
|
|
@ -7860,7 +7861,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
|
||||
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
|
||||
LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
|
||||
LLPipeline::sUseOcclusion = occlusion;
|
||||
|
||||
LLGLState::checkStates();
|
||||
LLGLState::checkTextureChannels();
|
||||
|
|
@ -7870,6 +7870,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
|
|||
{
|
||||
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
|
||||
}
|
||||
|
||||
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue