Occlusion now using LLVertexbuffer class.

This commit is contained in:
Shyotl
2011-08-05 02:55:13 -05:00
parent b75a28ec15
commit 9cc398e939
3 changed files with 98 additions and 169 deletions

View File

@@ -115,23 +115,6 @@ void sg_assert(BOOL expr)
#endif
}
#if LL_DEBUG
void validate_drawable(LLDrawable* drawablep)
{
F64 rad = drawablep->getBinRadius();
const LLVector3* ext = drawablep->getSpatialExtents();
if (rad < 0 || rad > 4096 ||
(ext[1]-ext[0]).magVec() > 4096)
{
llwarns << "Invalid drawable found in octree." << llendl;
}
}
#else
#define validate_drawable(x)
#endif
S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad)
{
return AABBSphereIntersectR2(min, max, origin, rad*rad);
@@ -277,38 +260,70 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center)
void LLSpatialGroup::buildOcclusion()
{
if (!mOcclusionVerts)
if (mOcclusionVerts.isNull())
{
mOcclusionVerts = new F32[8*3];
}
LLVector3 bounds[2];
bounds[0].set(mBounds[0].getF32ptr());
bounds[1].set(mBounds[1].getF32ptr());
LLVector3 r = bounds[1] + LLVector3(SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE, SG_OCCLUSION_FUDGE);
for (U32 k = 0; k < 3; k++)
{
r.mV[k] = llmin(bounds[1].mV[k]+0.25f, r.mV[k]);
}
F32* v = mOcclusionVerts;
F32* c = bounds[0].mV;
F32* s = r.mV;
mOcclusionVerts = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX,
LLVertexBuffer::sUseStreamDraw ? mBufferUsage : 0); //if GL has a hard time with VBOs, don't use them for occlusion culling.
mOcclusionVerts->allocateBuffer(8, 64, true);
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
//meaning negative facing
v[0] = c[0]-s[0]; v[1] = c[1]-s[1]; v[2] = c[2]-s[2]; // 0 - 0000
v[3] = c[0]-s[0]; v[4] = c[1]-s[1]; v[5] = c[2]+s[2]; // 1 - 0001
v[6] = c[0]-s[0]; v[7] = c[1]+s[1]; v[8] = c[2]-s[2]; // 2 - 0010
v[9] = c[0]-s[0]; v[10] = c[1]+s[1]; v[11] = c[2]+s[2]; // 3 - 0011
v[12] = c[0]+s[0]; v[13] = c[1]-s[1]; v[14] = c[2]-s[2]; // 4 - 0100
v[15] = c[0]+s[0]; v[16] = c[1]-s[1]; v[17] = c[2]+s[2]; // 5 - 0101
v[18] = c[0]+s[0]; v[19] = c[1]+s[1]; v[20] = c[2]-s[2]; // 6 - 0110
v[21] = c[0]+s[0]; v[22] = c[1]+s[1]; v[23] = c[2]+s[2]; // 7 - 0111
LLStrider<U16> idx;
mOcclusionVerts->getIndexStrider(idx);
for (U32 i = 0; i < 64; i++)
{
*idx++ = sOcclusionIndices[i];
}
}
LLVector4a fudge;
fudge.splat(SG_OCCLUSION_FUDGE);
LLVector4a r;
r.setAdd(mBounds[1], fudge);
LLStrider<LLVector3> pos;
{
//LLFastTimer t(LLFastTimer::FTM_BUILD_OCCLUSION);
mOcclusionVerts->getVertexStrider(pos);
}
{
LLVector4a* v = (LLVector4a*) pos.get();
const LLVector4a& c = mBounds[0];
const LLVector4a& s = r;
static const LLVector4a octant[] =
{
LLVector4a(-1.f, -1.f, -1.f),
LLVector4a(-1.f, -1.f, 1.f),
LLVector4a(-1.f, 1.f, -1.f),
LLVector4a(-1.f, 1.f, 1.f),
LLVector4a(1.f, -1.f, -1.f),
LLVector4a(1.f, -1.f, 1.f),
LLVector4a(1.f, 1.f, -1.f),
LLVector4a(1.f, 1.f, 1.f),
};
//vertex positions are encoded so the 3 bits of their vertex index
//correspond to their axis facing, with bit position 3,2,1 matching
//axis facing x,y,z, bit set meaning positive facing, bit clear
//meaning negative facing
for (S32 i = 0; i < 8; ++i)
{
LLVector4a p;
p.setMul(s, octant[i]);
p.add(c);
v[i] = p;
}
}
{
mOcclusionVerts->setBuffer(0);
}
clearState(LLSpatialGroup::OCCLUSION_DIRTY);
}
@@ -374,7 +389,6 @@ LLSpatialGroup::~LLSpatialGroup()
}
}
delete [] mOcclusionVerts;
mOcclusionVerts = NULL;
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -469,52 +483,6 @@ void LLSpatialGroup::checkStates()
#endif
}
void validate_draw_info(LLDrawInfo& params)
{
#if LL_OCTREE_PARANOIA_CHECK
if (!params.mVertexBuffer)
{
llerrs << "Draw batch has no vertex buffer." << llendl;
}
//bad range
if (params.mStart >= params.mEnd)
{
llerrs << "Draw batch has invalid range." << llendl;
}
if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts())
{
llerrs << "Draw batch has buffer overrun error." << llendl;
}
if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices())
{
llerrs << "Draw batch has index buffer ovverrun error." << llendl;
}
//bad indices
U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer();
if (indicesp)
{
for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++)
{
if (indicesp[i] < (U16)params.mStart)
{
llerrs << "Draw batch has vertex buffer index out of range error (index too low). "
<< "indicesp["<<i<<"]="<<indicesp[i]<< llendl;
}
if (indicesp[i] > (U16)params.mEnd)
{
llerrs << "Draw batch has vertex buffer index out of range error (index too high)."
<< "indicesp["<<i<<"]="<<indicesp[i]<< llendl;
}
}
} //Complains -SG
#endif
}
void LLSpatialGroup::validateDrawMap()
{
#if LL_OCTREE_PARANOIA_CHECK
@@ -524,8 +492,8 @@ void LLSpatialGroup::validateDrawMap()
for (drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
{
LLDrawInfo& params = **j;
validate_draw_info(params);
params.validate();
}
}
#endif
@@ -536,7 +504,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
drawablep->updateSpatialExtents();
validate_drawable(drawablep);
OctreeNode* parent = mOctreeNode->getOctParent();
@@ -548,7 +515,6 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate)
unbound();
setState(OBJECT_DIRTY);
//setState(GEOM_DIRTY);
validate_drawable(drawablep);
return TRUE;
}
@@ -566,7 +532,6 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc
else
{
drawablep->setSpatialGroup(this);
validate_drawable(drawablep);
setState(OBJECT_DIRTY | GEOM_DIRTY);
setOcclusionState(LLSpatialGroup::DISCARD_QUERY, LLSpatialGroup::STATE_MODE_ALL_CAMERAS);
gPipeline.markRebuild(this, TRUE);
@@ -839,7 +804,7 @@ void LLSpatialGroup::shift(const LLVector4a &offset)
gPipeline.markRebuild(this, TRUE);
}
if (mOcclusionVerts)
if (mOcclusionVerts.notNull())
{
setState(OCCLUSION_DIRTY);
}
@@ -874,24 +839,16 @@ void LLSpatialGroup::setState(eSpatialState state)
// if (LLSpatialPartition::sFreezeState)
// return;
mState |= state;
if (state > LLSpatialGroup::STATE_MASK)
{
llerrs << "WTF?" << llendl;
}
llassert(state <= LLSpatialGroup::STATE_MASK);
}
void LLSpatialGroup::setState(eSpatialState state, S32 mode)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
// if (LLSpatialPartition::sFreezeState)
// return;
if (state > LLSpatialGroup::STATE_MASK)
{
llerrs << "WTF?" << llendl;
}
llassert(state <= LLSpatialGroup::STATE_MASK);
if (mode > STATE_MODE_SINGLE)
{
if (mode == STATE_MODE_DIFF)
@@ -937,25 +894,14 @@ public:
void LLSpatialGroup::clearState(eSpatialState state)
{
// if (LLSpatialPartition::sFreezeState)
// return;
if (state > LLSpatialGroup::STATE_MASK)
{
llerrs << "WTF?" << llendl;
}
llassert(state <= LLSpatialGroup::STATE_MASK);
mState &= ~state;
}
void LLSpatialGroup::clearState(eSpatialState state, S32 mode)
{
// if (LLSpatialPartition::sFreezeState)
// return;
if (state > LLSpatialGroup::STATE_MASK)
{
llerrs << "WTF?" << llendl;
}
llassert(state <= LLSpatialGroup::STATE_MASK);
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
@@ -980,10 +926,7 @@ void LLSpatialGroup::clearState(eSpatialState state, S32 mode)
BOOL LLSpatialGroup::isState(eSpatialState state) const
{
if (state > LLSpatialGroup::STATE_MASK)
{
llerrs << "LLSpatialGroup::isState passed invalid state '" << state << "'" << llendl;
}
llassert(state <= LLSpatialGroup::STATE_MASK);
return mState & state ? TRUE : FALSE;
}
@@ -1121,7 +1064,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) :
mOctreeNode(node),
mSpatialPartition(part),
mVertexBuffer(NULL),
mBufferUsage(GL_STATIC_DRAW_ARB),
mBufferUsage(part->mBufferUsage),
mDistance(0.f),
mDepth(0.f),
mLastUpdateDistance(-1.f),
@@ -1399,7 +1342,6 @@ void LLSpatialGroup::destroyGL()
}
}
delete [] mOcclusionVerts;
mOcclusionVerts = NULL;
for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i)
@@ -1573,7 +1515,7 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
mOcclusionQuery[LLViewerCamera::sCurCameraID] = sQueryPool.allocate();
}
if (!mOcclusionVerts || isState(LLSpatialGroup::OCCLUSION_DIRTY))
if (mOcclusionVerts.isNull() || isState(LLSpatialGroup::OCCLUSION_DIRTY))
{
buildOcclusion();
}
@@ -1600,37 +1542,32 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera)
{
//LLFastTimer t(FTM_PUSH_OCCLUSION_VERTS);
glBeginQueryARB(mode, mOcclusionQuery[LLViewerCamera::sCurCameraID]);
glVertexPointer(3, GL_FLOAT, 0, mOcclusionVerts);
mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX);
if (!use_depth_clamp && mSpatialPartition->mDrawableType == LLDrawPool::POOL_VOIDWATER)
{
LLGLSquashToFarClip squash(glh_get_current_projection(), 1);
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);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0]));
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
else
{
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);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, 0);
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, b111*8);
}
else
{
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, mBounds[0]));
mOcclusionVerts->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, mBounds[0]));
}
}
@@ -1689,7 +1626,6 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
drawablep->updateSpatialExtents();
validate_drawable(drawablep);
//keep drawable from being garbage collected
LLPointer<LLDrawable> ptr = drawablep;
@@ -1988,11 +1924,8 @@ public:
virtual void processGroup(LLSpatialGroup* group)
{
if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty())
{
llerrs << "WTF?" << llendl;
}
llassert(!group->isState(LLSpatialGroup::DIRTY) && !group->getData().empty())
if (mRes < 2)
{
if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) > 0)
@@ -2356,6 +2289,8 @@ void pushVerts(LLSpatialGroup* group, U32 mask)
void pushVerts(LLFace* face, U32 mask)
{
llassert(face->verify());
LLVertexBuffer* buffer = face->getVertexBuffer();
if (buffer)
@@ -3159,7 +3094,6 @@ public:
{
renderAgentTarget(avatar);
}
}
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
@@ -3550,18 +3484,9 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mFace(NULL),
mDistance(0.f)
{
mDebugColor = (rand() << 16) + rand();
if (mStart >= mVertexBuffer->getRequestedVerts() ||
mEnd >= mVertexBuffer->getRequestedVerts())
{
llerrs << "Invalid draw info vertex range." << llendl;
}
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() ||
mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices())
{
llerrs << "Invalid draw info index range." << llendl;
}
mDebugColor = (rand() << 16) + rand();
}
LLDrawInfo::~LLDrawInfo()
@@ -3582,6 +3507,11 @@ LLDrawInfo::~LLDrawInfo()
}
}
void LLDrawInfo::validate()
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
}
LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage)
{
return new LLVertexBuffer(type_mask, usage);

View File

@@ -88,6 +88,7 @@ public:
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
void validate();
LLVector4a mExtents[2];
@@ -361,9 +362,9 @@ public:
F32 mBuilt;
OctreeNode* mOctreeNode;
LLSpatialPartition* mSpatialPartition;
LLPointer<LLVertexBuffer> mVertexBuffer;
F32* mOcclusionVerts;
LLPointer<LLVertexBuffer> mOcclusionVerts;
GLuint mOcclusionQuery[LLViewerCamera::NUM_CAMERAS];
U32 mBufferUsage;
@@ -694,8 +695,6 @@ public:
virtual void shift(const LLVector4a &offset);
};
void validate_draw_info(LLDrawInfo& params);
extern const F32 SG_BOX_SIDE;
extern const F32 SG_BOX_OFFSET;
extern const F32 SG_BOX_RAD;

View File

@@ -2942,7 +2942,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
validate_draw_info(*draw_vec[idx]);
draw_vec[idx]->validate();
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
}
@@ -2966,7 +2966,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
}
draw_info->mExtents[0] = facep->mExtents[0];
draw_info->mExtents[1] = facep->mExtents[1];
validate_draw_info(*draw_info);
draw_info->validate();
}
}