diff options
author | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:50 -0500 |
commit | 89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch) | |
tree | bcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/llspatialpartition.cpp | |
parent | Second Life viewer sources 1.13.3.2 (diff) | |
download | meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2 meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz |
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/llspatialpartition.cpp')
-rw-r--r-- | linden/indra/newview/llspatialpartition.cpp | 1887 |
1 files changed, 1230 insertions, 657 deletions
diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index fd9eec0..24ac1ca 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp | |||
@@ -29,25 +29,21 @@ | |||
29 | 29 | ||
30 | #include "llspatialpartition.h" | 30 | #include "llspatialpartition.h" |
31 | 31 | ||
32 | #include "llglheaders.h" | 32 | #include "llviewerwindow.h" |
33 | |||
34 | #include "llviewerobjectlist.h" | 33 | #include "llviewerobjectlist.h" |
35 | #include "llvovolume.h" | 34 | #include "llvovolume.h" |
36 | #include "llviewercamera.h" | 35 | #include "llviewercamera.h" |
37 | #include "llface.h" | 36 | #include "llface.h" |
38 | #include "viewer.h" | 37 | #include "viewer.h" |
39 | 38 | #include "llagent.h" | |
39 | #include "llviewerregion.h" | ||
40 | #include "llcamera.h" | 40 | #include "llcamera.h" |
41 | #include "pipeline.h" | 41 | #include "pipeline.h" |
42 | 42 | ||
43 | static BOOL sIgnoreOcclusion = TRUE; | ||
44 | static GLuint sBoxList = 0; | 43 | static GLuint sBoxList = 0; |
45 | 44 | ||
46 | const S32 SG_LOD_SWITCH_STAGGER = 4; | 45 | const F32 SG_OCCLUSION_FUDGE = 1.01f; |
47 | const F32 SG_MAX_OBJ_RAD = 1.f; | 46 | //const S32 SG_LOD_PERIOD = 16; |
48 | const F32 SG_OCCLUSION_FUDGE = 1.1f; | ||
49 | const S32 SG_MOVE_PERIOD = 32; | ||
50 | const S32 SG_LOD_PERIOD = 16; | ||
51 | 47 | ||
52 | #define SG_DISCARD_TOLERANCE 0.25f | 48 | #define SG_DISCARD_TOLERANCE 0.25f |
53 | 49 | ||
@@ -57,11 +53,12 @@ const S32 SG_LOD_PERIOD = 16; | |||
57 | #define assert_octree_valid(x) | 53 | #define assert_octree_valid(x) |
58 | #endif | 54 | #endif |
59 | 55 | ||
56 | static U32 sZombieGroups = 0; | ||
57 | |||
60 | static F32 sLastMaxTexPriority = 1.f; | 58 | static F32 sLastMaxTexPriority = 1.f; |
61 | static F32 sCurMaxTexPriority = 1.f; | 59 | static F32 sCurMaxTexPriority = 1.f; |
62 | 60 | ||
63 | //static counter for frame to switch LOD on | 61 | //static counter for frame to switch LOD on |
64 | S32 LLSpatialGroup::sLODSeed = 0; | ||
65 | 62 | ||
66 | void sg_assert(BOOL expr) | 63 | void sg_assert(BOOL expr) |
67 | { | 64 | { |
@@ -144,30 +141,22 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3 | |||
144 | 141 | ||
145 | LLSpatialGroup::~LLSpatialGroup() | 142 | LLSpatialGroup::~LLSpatialGroup() |
146 | { | 143 | { |
147 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 144 | if (isState(DEAD)) |
148 | if (!safeToDelete()) | ||
149 | { | 145 | { |
150 | #ifdef LL_RELEASE_FOR_DOWNLOAD | 146 | sZombieGroups--; |
151 | llwarns << "Spatial Group deleted while being tracked " << ((void*) mState) << llendl; | ||
152 | #else | ||
153 | llerrs << "Spatial Group deleted while being tracked " << ((void*) mState) << llendl; | ||
154 | #endif | ||
155 | } | 147 | } |
156 | 148 | ||
157 | #if LL_OCTREE_PARANOIA_CHECK | 149 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
158 | for (U32 i = 0; i < mSpatialPartition->mOccludedList.size(); i++) | 150 | clearDrawMap(); |
159 | { | ||
160 | if (mSpatialPartition->mOccludedList[i] == this) | ||
161 | { | ||
162 | llerrs << "Spatial Group deleted while being tracked STATE ERROR " << ((void*) mState) << llendl; | ||
163 | } | ||
164 | } | ||
165 | #endif | ||
166 | } | 151 | } |
167 | 152 | ||
168 | BOOL LLSpatialGroup::safeToDelete() | 153 | void LLSpatialGroup::clearDrawMap() |
169 | { | 154 | { |
170 | return gQuit || !isState(IN_QUEUE | ACTIVE_OCCLUSION | RESHADOW_QUEUE); | 155 | for (LLSpatialGroup::draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) |
156 | { | ||
157 | std::for_each(i->second.begin(), i->second.end(), DeletePointer()); | ||
158 | } | ||
159 | mDrawMap.clear(); | ||
171 | } | 160 | } |
172 | 161 | ||
173 | class LLRelightPainter : public LLSpatialGroup::OctreeTraveler | 162 | class LLRelightPainter : public LLSpatialGroup::OctreeTraveler |
@@ -212,13 +201,13 @@ public: | |||
212 | 201 | ||
213 | BOOL LLSpatialGroup::isVisible() | 202 | BOOL LLSpatialGroup::isVisible() |
214 | { | 203 | { |
215 | if (sIgnoreOcclusion) | 204 | if (LLPipeline::sUseOcclusion) |
216 | { | 205 | { |
217 | return !isState(CULLED); | 206 | return !isState(CULLED | OCCLUDED); |
218 | } | 207 | } |
219 | else | 208 | else |
220 | { | 209 | { |
221 | return !isState(CULLED | OCCLUDED); | 210 | return !isState(CULLED); |
222 | } | 211 | } |
223 | } | 212 | } |
224 | 213 | ||
@@ -254,6 +243,90 @@ void LLSpatialGroup::validate() | |||
254 | #endif | 243 | #endif |
255 | } | 244 | } |
256 | 245 | ||
246 | void validate_draw_info(LLDrawInfo& params) | ||
247 | { | ||
248 | #if LL_DEBUG | ||
249 | /* if (params.mVertexBuffer.isNull()) | ||
250 | { | ||
251 | llerrs << "Draw batch has no vertex buffer." << llendl; | ||
252 | } | ||
253 | |||
254 | //bad range | ||
255 | if (params.mStart >= params.mEnd) | ||
256 | { | ||
257 | llerrs << "Draw batch has invalid range." << llendl; | ||
258 | } | ||
259 | |||
260 | if (params.mEnd >= params.mVertexBuffer->getNumVerts()) | ||
261 | { | ||
262 | llerrs << "Draw batch has buffer overrun error." << llendl; | ||
263 | } | ||
264 | |||
265 | if (params.mOffset + params.mCount > params.mVertexBuffer->getNumIndices()) | ||
266 | { | ||
267 | llerrs << "Draw batch has index buffer ovverrun error." << llendl; | ||
268 | } | ||
269 | |||
270 | //bad indices | ||
271 | U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer(); | ||
272 | if (indicesp) | ||
273 | { | ||
274 | for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) | ||
275 | { | ||
276 | if (indicesp[i] < params.mStart) | ||
277 | { | ||
278 | llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; | ||
279 | } | ||
280 | |||
281 | if (indicesp[i] > params.mEnd) | ||
282 | { | ||
283 | llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; | ||
284 | } | ||
285 | } | ||
286 | }*/ | ||
287 | #endif | ||
288 | } | ||
289 | |||
290 | void LLSpatialGroup::validateDrawMap() | ||
291 | { | ||
292 | /* for (draw_map_t::iterator i = mDrawMap.begin(); i != mDrawMap.end(); ++i) | ||
293 | { | ||
294 | std::vector<LLDrawInfo*>& draw_vec = i->second; | ||
295 | for (std::vector<LLDrawInfo*>::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) | ||
296 | { | ||
297 | LLDrawInfo& params = **j; | ||
298 | |||
299 | validate_draw_info(params); | ||
300 | } | ||
301 | }*/ | ||
302 | } | ||
303 | |||
304 | void LLSpatialGroup::makeStatic() | ||
305 | { | ||
306 | #if !LL_DARWIN | ||
307 | if (isState(GEOM_DIRTY | ALPHA_DIRTY)) | ||
308 | { | ||
309 | return; | ||
310 | } | ||
311 | |||
312 | if (mSpatialPartition->mRenderByGroup && mBufferUsage != GL_STATIC_DRAW_ARB) | ||
313 | { | ||
314 | mBufferUsage = GL_STATIC_DRAW_ARB; | ||
315 | if (mVertexBuffer.notNull()) | ||
316 | { | ||
317 | mVertexBuffer->makeStatic(); | ||
318 | } | ||
319 | |||
320 | for (buffer_map_t::iterator i = mBufferMap.begin(); i != mBufferMap.end(); ++i) | ||
321 | { | ||
322 | i->second->makeStatic(); | ||
323 | } | ||
324 | |||
325 | mBuilt = 1.f; | ||
326 | } | ||
327 | #endif | ||
328 | } | ||
329 | |||
257 | BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) | 330 | BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) |
258 | { | 331 | { |
259 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 332 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
@@ -261,10 +334,16 @@ BOOL LLSpatialGroup::updateInGroup(LLDrawable *drawablep, BOOL immediate) | |||
261 | drawablep->updateSpatialExtents(); | 334 | drawablep->updateSpatialExtents(); |
262 | validate_drawable(drawablep); | 335 | validate_drawable(drawablep); |
263 | 336 | ||
264 | if (mOctreeNode->isInside(drawablep) && mOctreeNode->contains(drawablep)) | 337 | OctreeNode* parent = mOctreeNode->getOctParent(); |
338 | |||
339 | if (mOctreeNode->isInside(drawablep->getPositionGroup()) && | ||
340 | (mOctreeNode->contains(drawablep) || | ||
341 | (drawablep->getBinRadius() > mOctreeNode->getSize().mdV[0] && | ||
342 | parent && parent->getElementCount() >= LL_OCTREE_MAX_CAPACITY))) | ||
265 | { | 343 | { |
266 | unbound(); | 344 | unbound(); |
267 | setState(OBJECT_DIRTY); | 345 | setState(OBJECT_DIRTY); |
346 | setState(GEOM_DIRTY); | ||
268 | validate_drawable(drawablep); | 347 | validate_drawable(drawablep); |
269 | return TRUE; | 348 | return TRUE; |
270 | } | 349 | } |
@@ -284,11 +363,82 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc | |||
284 | { | 363 | { |
285 | drawablep->setSpatialGroup(this, 0); | 364 | drawablep->setSpatialGroup(this, 0); |
286 | validate_drawable(drawablep); | 365 | validate_drawable(drawablep); |
366 | setState(OBJECT_DIRTY | GEOM_DIRTY); | ||
367 | mLastAddTime = gFrameTimeSeconds; | ||
368 | if (drawablep->isSpatialBridge()) | ||
369 | { | ||
370 | mBridgeList.push_back((LLSpatialBridge*) drawablep); | ||
371 | } | ||
372 | setState(IMAGE_DIRTY); | ||
287 | } | 373 | } |
288 | 374 | ||
289 | return TRUE; | 375 | return TRUE; |
290 | } | 376 | } |
291 | 377 | ||
378 | void LLSpatialGroup::rebuildGeom() | ||
379 | { | ||
380 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | ||
381 | if (!isDead()) | ||
382 | { | ||
383 | mSpatialPartition->rebuildGeom(this); | ||
384 | } | ||
385 | } | ||
386 | |||
387 | void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) | ||
388 | { | ||
389 | if (group->changeLOD()) | ||
390 | { | ||
391 | group->mLastUpdateDistance = group->mDistance; | ||
392 | group->mLastUpdateViewAngle = group->mViewAngle; | ||
393 | } | ||
394 | |||
395 | if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) | ||
396 | { | ||
397 | return; | ||
398 | } | ||
399 | |||
400 | LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); | ||
401 | |||
402 | group->clearDrawMap(); | ||
403 | |||
404 | //get geometry count | ||
405 | group->mIndexCount = 0; | ||
406 | group->mVertexCount = 0; | ||
407 | |||
408 | addGeometryCount(group, group->mVertexCount, group->mIndexCount); | ||
409 | |||
410 | if (group->mVertexCount > 0 && group->mIndexCount > 0) | ||
411 | { //create vertex buffer containing volume geometry for this node | ||
412 | group->mBuilt = 1.f; | ||
413 | if (group->mVertexBuffer.isNull() || (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) | ||
414 | { | ||
415 | //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); | ||
416 | group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); | ||
417 | group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true); | ||
418 | stop_glerror(); | ||
419 | } | ||
420 | else | ||
421 | { | ||
422 | //LLFastTimer ftm(LLFastTimer::FTM_REBUILD_NONE_VB); | ||
423 | group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount); | ||
424 | stop_glerror(); | ||
425 | } | ||
426 | |||
427 | { | ||
428 | LLFastTimer ftm((LLFastTimer::EFastTimerType) ((U32) LLFastTimer::FTM_REBUILD_VOLUME_VB + mPartitionType)); | ||
429 | getGeometry(group); | ||
430 | } | ||
431 | } | ||
432 | else | ||
433 | { | ||
434 | group->mVertexBuffer = NULL; | ||
435 | group->mBufferMap.clear(); | ||
436 | } | ||
437 | |||
438 | group->mLastUpdateTime = gFrameTimeSeconds; | ||
439 | group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY); | ||
440 | } | ||
441 | |||
292 | BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) | 442 | BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxOut) |
293 | { | 443 | { |
294 | const OctreeState* node = mOctreeNode->getOctState(); | 444 | const OctreeState* node = mOctreeNode->getOctState(); |
@@ -304,7 +454,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO | |||
304 | 454 | ||
305 | LLVector3& newMin = mObjectExtents[0]; | 455 | LLVector3& newMin = mObjectExtents[0]; |
306 | LLVector3& newMax = mObjectExtents[1]; | 456 | LLVector3& newMax = mObjectExtents[1]; |
307 | 457 | ||
308 | if (isState(OBJECT_DIRTY)) | 458 | if (isState(OBJECT_DIRTY)) |
309 | { //calculate new bounding box | 459 | { //calculate new bounding box |
310 | clearState(OBJECT_DIRTY); | 460 | clearState(OBJECT_DIRTY); |
@@ -390,11 +540,28 @@ void LLSpatialGroup::unbound() | |||
390 | } | 540 | } |
391 | } | 541 | } |
392 | 542 | ||
543 | LLSpatialGroup* LLSpatialGroup::getParent() | ||
544 | { | ||
545 | if (isDead()) | ||
546 | { | ||
547 | return NULL; | ||
548 | } | ||
549 | |||
550 | OctreeNode* parent = mOctreeNode->getOctParent(); | ||
551 | |||
552 | if (parent) | ||
553 | { | ||
554 | return (LLSpatialGroup*) parent->getListener(0); | ||
555 | } | ||
556 | |||
557 | return NULL; | ||
558 | } | ||
559 | |||
393 | BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) | 560 | BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) |
394 | { | 561 | { |
395 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 562 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
396 | unbound(); | 563 | unbound(); |
397 | if (!from_octree) | 564 | if (mOctreeNode && !from_octree) |
398 | { | 565 | { |
399 | if (!mOctreeNode->remove(drawablep)) | 566 | if (!mOctreeNode->remove(drawablep)) |
400 | { | 567 | { |
@@ -404,6 +571,18 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) | |||
404 | else | 571 | else |
405 | { | 572 | { |
406 | drawablep->setSpatialGroup(NULL, -1); | 573 | drawablep->setSpatialGroup(NULL, -1); |
574 | setState(GEOM_DIRTY); | ||
575 | if (drawablep->isSpatialBridge()) | ||
576 | { | ||
577 | for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) | ||
578 | { | ||
579 | if (*i == drawablep) | ||
580 | { | ||
581 | mBridgeList.erase(i); | ||
582 | break; | ||
583 | } | ||
584 | } | ||
585 | } | ||
407 | } | 586 | } |
408 | return TRUE; | 587 | return TRUE; |
409 | } | 588 | } |
@@ -420,6 +599,8 @@ void LLSpatialGroup::shift(const LLVector3 &offset) | |||
420 | mObjectBounds[0] += offset; | 599 | mObjectBounds[0] += offset; |
421 | mObjectExtents[0] += offset; | 600 | mObjectExtents[0] += offset; |
422 | mObjectExtents[1] += offset; | 601 | mObjectExtents[1] += offset; |
602 | |||
603 | setState(GEOM_DIRTY | MATRIX_DIRTY | OCCLUSION_DIRTY); | ||
423 | } | 604 | } |
424 | 605 | ||
425 | class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler | 606 | class LLSpatialSetState : public LLSpatialGroup::OctreeTraveler |
@@ -533,30 +714,160 @@ void LLSpatialGroup::clearState(U32 state, S32 mode) | |||
533 | // Octree Listener Implementation | 714 | // Octree Listener Implementation |
534 | //====================================== | 715 | //====================================== |
535 | 716 | ||
536 | LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) | 717 | LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : |
537 | : mState(0), mOctreeNode(node), mSpatialPartition(part) | 718 | mState(0), |
719 | mBuilt(0.f), | ||
720 | mOctreeNode(node), | ||
721 | mSpatialPartition(part), | ||
722 | mVertexBuffer(NULL), | ||
723 | mBufferUsage(GL_STATIC_DRAW_ARB), | ||
724 | mDistance(0.f), | ||
725 | mDepth(0.f), | ||
726 | mLastUpdateDistance(-1.f), | ||
727 | mLastUpdateTime(gFrameTimeSeconds), | ||
728 | mLastAddTime(gFrameTimeSeconds), | ||
729 | mLastRenderTime(gFrameTimeSeconds), | ||
730 | mViewAngle(0.f), | ||
731 | mLastUpdateViewAngle(-1.f) | ||
538 | { | 732 | { |
539 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 733 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
734 | |||
540 | sg_assert(mOctreeNode->getListenerCount() == 0); | 735 | sg_assert(mOctreeNode->getListenerCount() == 0); |
541 | mOctreeNode->addListener(this); | 736 | mOctreeNode->addListener(this); |
542 | setState(DIRTY); | 737 | setState(SG_INITIAL_STATE_MASK); |
543 | 738 | ||
544 | mBounds[0] = LLVector3(node->getCenter()); | 739 | mBounds[0] = LLVector3(node->getCenter()); |
545 | mBounds[1] = LLVector3(node->getSize()); | 740 | mBounds[1] = LLVector3(node->getSize()); |
546 | 741 | ||
547 | sLODSeed = (sLODSeed+1)%SG_LOD_PERIOD; | 742 | part->mLODSeed = (part->mLODSeed+1)%part->mLODPeriod; |
548 | mLODHash = sLODSeed; | 743 | mLODHash = part->mLODSeed; |
744 | |||
745 | mRadius = 1; | ||
746 | mPixelArea = 1024.f; | ||
747 | } | ||
748 | |||
749 | void LLSpatialGroup::updateDistance(LLCamera &camera) | ||
750 | { | ||
751 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
752 | if (isState(LLSpatialGroup::OBJECT_DIRTY)) | ||
753 | { | ||
754 | llerrs << "Spatial group dirty on distance update." << llendl; | ||
755 | } | ||
756 | #endif | ||
757 | if (!getData().empty()) | ||
758 | { | ||
759 | mRadius = mSpatialPartition->mRenderByGroup ? mObjectBounds[1].magVec() : | ||
760 | (F32) mOctreeNode->getSize().magVec(); | ||
761 | mDistance = mSpatialPartition->calcDistance(this, camera); | ||
762 | mPixelArea = mSpatialPartition->calcPixelArea(this, camera); | ||
763 | } | ||
764 | } | ||
765 | |||
766 | F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) | ||
767 | { | ||
768 | LLVector3 eye = group->mObjectBounds[0] - camera.getOrigin(); | ||
769 | |||
770 | F32 dist = 0.f; | ||
771 | |||
772 | if (group->mDrawMap.find(LLRenderPass::PASS_ALPHA) != group->mDrawMap.end()) | ||
773 | { | ||
774 | LLVector3 v = eye; | ||
775 | dist = eye.normVec(); | ||
776 | |||
777 | if (!group->isState(LLSpatialGroup::ALPHA_DIRTY)) | ||
778 | { | ||
779 | LLVector3 view_angle = LLVector3(eye * LLVector3(1,0,0), | ||
780 | eye * LLVector3(0,1,0), | ||
781 | eye * LLVector3(0,0,1)); | ||
782 | |||
783 | if ((view_angle-group->mLastUpdateViewAngle).magVec() > 0.64f) | ||
784 | { | ||
785 | group->mViewAngle = view_angle; | ||
786 | group->mLastUpdateViewAngle = view_angle; | ||
787 | //for occasional alpha sorting within the group | ||
788 | //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, | ||
789 | //not setting this node to dirty would be a very good thing | ||
790 | group->setState(LLSpatialGroup::ALPHA_DIRTY); | ||
791 | } | ||
792 | } | ||
793 | |||
794 | //calculate depth of node for alpha sorting | ||
795 | |||
796 | LLVector3 at = camera.getAtAxis(); | ||
797 | |||
798 | //front of bounding box | ||
799 | for (U32 i = 0; i < 3; i++) | ||
800 | { | ||
801 | v.mV[i] -= group->mObjectBounds[1].mV[i]*0.25f * at.mV[i]; | ||
802 | } | ||
803 | |||
804 | group->mDepth = v * at; | ||
805 | |||
806 | F32 water_height = gAgent.getRegion()->getWaterHeight(); | ||
807 | //figure out if this node is above or below water | ||
808 | if (group->mObjectBounds[0].mV[2] < water_height) | ||
809 | { | ||
810 | group->setState(LLSpatialGroup::BELOW_WATER); | ||
811 | } | ||
812 | else | ||
813 | { | ||
814 | group->clearState(LLSpatialGroup::BELOW_WATER); | ||
815 | } | ||
816 | } | ||
817 | else | ||
818 | { | ||
819 | dist = eye.magVec(); | ||
820 | } | ||
821 | |||
822 | if (dist < 16.f) | ||
823 | { | ||
824 | dist /= 16.f; | ||
825 | dist *= dist; | ||
826 | dist *= 16.f; | ||
827 | } | ||
828 | |||
829 | return dist; | ||
830 | } | ||
831 | |||
832 | F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) | ||
833 | { | ||
834 | return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); | ||
549 | } | 835 | } |
550 | 836 | ||
551 | BOOL LLSpatialGroup::changeLOD() | 837 | BOOL LLSpatialGroup::changeLOD() |
552 | { | 838 | { |
553 | return LLDrawable::getCurrentFrame()%SG_LOD_PERIOD == mLODHash; | 839 | if (isState(ALPHA_DIRTY)) |
840 | { ///an alpha sort is going to happen, update distance and LOD | ||
841 | return TRUE; | ||
842 | } | ||
843 | |||
844 | if (mSpatialPartition->mSlopRatio > 0.f) | ||
845 | { | ||
846 | F32 ratio = (mDistance - mLastUpdateDistance)/(llmax(mLastUpdateDistance, mRadius)); | ||
847 | |||
848 | if (fabsf(ratio) >= mSpatialPartition->mSlopRatio) | ||
849 | { | ||
850 | return TRUE; | ||
851 | } | ||
852 | |||
853 | if (mDistance > mRadius) | ||
854 | { | ||
855 | return FALSE; | ||
856 | } | ||
857 | } | ||
858 | |||
859 | if (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) | ||
860 | { | ||
861 | return TRUE; | ||
862 | } | ||
863 | |||
864 | return FALSE; | ||
554 | } | 865 | } |
555 | 866 | ||
556 | void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawable) | 867 | void LLSpatialGroup::handleInsertion(const TreeNode* node, LLDrawable* drawablep) |
557 | { | 868 | { |
558 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 869 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
559 | addObject(drawable, FALSE, TRUE); | 870 | addObject(drawablep, FALSE, TRUE); |
560 | unbound(); | 871 | unbound(); |
561 | setState(OBJECT_DIRTY); | 872 | setState(OBJECT_DIRTY); |
562 | } | 873 | } |
@@ -571,29 +882,13 @@ void LLSpatialGroup::handleRemoval(const TreeNode* node, LLDrawable* drawable) | |||
571 | void LLSpatialGroup::handleDestruction(const TreeNode* node) | 882 | void LLSpatialGroup::handleDestruction(const TreeNode* node) |
572 | { | 883 | { |
573 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 884 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
574 | 885 | setState(DEAD); | |
575 | if (mOctreeNode) | 886 | clearDrawMap(); |
576 | { | 887 | mOcclusionVerts = NULL; |
577 | OctreeState* state = mOctreeNode->getOctState(); | 888 | mVertexBuffer = NULL; |
578 | for (OctreeState::element_iter i = state->getData().begin(); i != state->getData().end(); ++i) | 889 | mBufferMap.clear(); |
579 | { | 890 | sZombieGroups++; |
580 | LLDrawable* drawable = *i; | 891 | mOctreeNode = NULL; |
581 | if (!drawable->isDead()) | ||
582 | { | ||
583 | drawable->setSpatialGroup(NULL, -1); | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | if (safeToDelete()) | ||
589 | { | ||
590 | delete this; | ||
591 | } | ||
592 | else | ||
593 | { | ||
594 | setState(DEAD); | ||
595 | mOctreeNode = NULL; | ||
596 | } | ||
597 | } | 892 | } |
598 | 893 | ||
599 | void LLSpatialGroup::handleStateChange(const TreeNode* node) | 894 | void LLSpatialGroup::handleStateChange(const TreeNode* node) |
@@ -611,7 +906,8 @@ void LLSpatialGroup::handleChildAddition(const OctreeNode* parent, OctreeNode* c | |||
611 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 906 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
612 | if (child->getListenerCount() == 0) | 907 | if (child->getListenerCount() == 0) |
613 | { | 908 | { |
614 | (new LLSpatialGroup(child, mSpatialPartition))->setState(mState & SG_STATE_INHERIT_MASK); | 909 | LLSpatialGroup* group = new LLSpatialGroup(child, mSpatialPartition); |
910 | group->setState(mState & SG_STATE_INHERIT_MASK); | ||
615 | } | 911 | } |
616 | else | 912 | else |
617 | { | 913 | { |
@@ -626,6 +922,31 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo | |||
626 | unbound(); | 922 | unbound(); |
627 | } | 923 | } |
628 | 924 | ||
925 | void LLSpatialGroup::destroyGL() | ||
926 | { | ||
927 | setState(LLSpatialGroup::GEOM_DIRTY | | ||
928 | LLSpatialGroup::OCCLUSION_DIRTY | | ||
929 | LLSpatialGroup::IMAGE_DIRTY); | ||
930 | mLastUpdateTime = gFrameTimeSeconds; | ||
931 | mVertexBuffer = NULL; | ||
932 | mBufferMap.clear(); | ||
933 | |||
934 | mOcclusionVerts = NULL; | ||
935 | mReflectionMap = NULL; | ||
936 | clearDrawMap(); | ||
937 | |||
938 | for (LLSpatialGroup::element_iter i = getData().begin(); i != getData().end(); ++i) | ||
939 | { | ||
940 | LLDrawable* drawable = *i; | ||
941 | for (S32 j = 0; j < drawable->getNumFaces(); j++) | ||
942 | { | ||
943 | LLFace* facep = drawable->getFace(j); | ||
944 | facep->mVertexBuffer = NULL; | ||
945 | facep->mLastVertexBuffer = NULL; | ||
946 | } | ||
947 | } | ||
948 | } | ||
949 | |||
629 | BOOL LLSpatialGroup::rebound() | 950 | BOOL LLSpatialGroup::rebound() |
630 | { | 951 | { |
631 | if (!isState(DIRTY)) | 952 | if (!isState(DIRTY)) |
@@ -635,7 +956,7 @@ BOOL LLSpatialGroup::rebound() | |||
635 | 956 | ||
636 | LLVector3 oldBounds[2]; | 957 | LLVector3 oldBounds[2]; |
637 | 958 | ||
638 | if (isState(QUERY_OUT)) | 959 | if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) |
639 | { //a query has been issued, if our bounding box changes significantly | 960 | { //a query has been issued, if our bounding box changes significantly |
640 | //we need to discard the issued query | 961 | //we need to discard the issued query |
641 | oldBounds[0] = mBounds[0]; | 962 | oldBounds[0] = mBounds[0]; |
@@ -700,7 +1021,7 @@ BOOL LLSpatialGroup::rebound() | |||
700 | mBounds[1] = (newMax - newMin)*0.5f; | 1021 | mBounds[1] = (newMax - newMin)*0.5f; |
701 | } | 1022 | } |
702 | 1023 | ||
703 | if (isState(QUERY_OUT)) | 1024 | if (mSpatialPartition->isVolatile() && isState(QUERY_OUT)) |
704 | { | 1025 | { |
705 | for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++) | 1026 | for (U32 i = 0; i < 3 && !isState(DISCARD_QUERY); i++) |
706 | { | 1027 | { |
@@ -713,6 +1034,8 @@ BOOL LLSpatialGroup::rebound() | |||
713 | } | 1034 | } |
714 | } | 1035 | } |
715 | 1036 | ||
1037 | setState(OCCLUSION_DIRTY); | ||
1038 | |||
716 | clearState(DIRTY); | 1039 | clearState(DIRTY); |
717 | 1040 | ||
718 | return TRUE; | 1041 | return TRUE; |
@@ -720,9 +1043,21 @@ BOOL LLSpatialGroup::rebound() | |||
720 | 1043 | ||
721 | //============================================== | 1044 | //============================================== |
722 | 1045 | ||
723 | LLSpatialPartition::LLSpatialPartition() | 1046 | LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL is_volatile, U32 buffer_usage) |
724 | { | 1047 | { |
725 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1048 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1049 | mDrawableType = 0; | ||
1050 | mPartitionType = LLPipeline::PARTITION_NONE; | ||
1051 | mVolatile = is_volatile; | ||
1052 | mLODSeed = 0; | ||
1053 | mLODPeriod = 1; | ||
1054 | mVertexDataMask = data_mask; | ||
1055 | mBufferUsage = buffer_usage; | ||
1056 | mDepthMask = FALSE; | ||
1057 | mSlopRatio = 0.25f; | ||
1058 | mRenderByGroup = TRUE; | ||
1059 | mImageEnabled = FALSE; | ||
1060 | |||
726 | mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0), | 1061 | mOctree = new LLSpatialGroup::OctreeNode(LLVector3d(0,0,0), |
727 | LLVector3d(1,1,1), | 1062 | LLVector3d(1,1,1), |
728 | new LLSpatialGroup::OctreeRoot(), NULL); | 1063 | new LLSpatialGroup::OctreeRoot(), NULL); |
@@ -733,19 +1068,25 @@ LLSpatialPartition::LLSpatialPartition() | |||
733 | LLSpatialPartition::~LLSpatialPartition() | 1068 | LLSpatialPartition::~LLSpatialPartition() |
734 | { | 1069 | { |
735 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1070 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1071 | |||
1072 | for (U32 i = 0; i < mOcclusionQueries.size(); i++) | ||
1073 | { | ||
1074 | glDeleteQueriesARB(1, (GLuint*)(&(mOcclusionQueries[i]))); | ||
1075 | } | ||
1076 | |||
736 | delete mOctree; | 1077 | delete mOctree; |
737 | mOctree = NULL; | 1078 | mOctree = NULL; |
738 | } | 1079 | } |
739 | 1080 | ||
740 | 1081 | ||
741 | LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep) | 1082 | LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible) |
742 | { | 1083 | { |
743 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1084 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
744 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million | 1085 | const F32 MAX_MAG = 1000000.f*1000000.f; // 1 million |
745 | 1086 | ||
746 | if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG) | 1087 | if (drawablep->getPositionGroup().magVecSquared() > MAX_MAG) |
747 | { | 1088 | { |
748 | #ifndef LL_RELEASE_FOR_DOWNLOAD | 1089 | #if 0 //ndef LL_RELEASE_FOR_DOWNLOAD |
749 | llwarns << "LLSpatialPartition::put Object out of range!" << llendl; | 1090 | llwarns << "LLSpatialPartition::put Object out of range!" << llendl; |
750 | llinfos << drawablep->getPositionGroup() << llendl; | 1091 | llinfos << drawablep->getPositionGroup() << llendl; |
751 | 1092 | ||
@@ -770,7 +1111,13 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep) | |||
770 | 1111 | ||
771 | LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep); | 1112 | LLSpatialGroup::OctreeNode* node = mOctree->getNodeAt(drawablep); |
772 | 1113 | ||
773 | return (LLSpatialGroup*) node->getListener(0); | 1114 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); |
1115 | if (was_visible && group->isState(LLSpatialGroup::QUERY_OUT)) | ||
1116 | { | ||
1117 | group->setState(LLSpatialGroup::DISCARD_QUERY); | ||
1118 | } | ||
1119 | |||
1120 | return group; | ||
774 | } | 1121 | } |
775 | 1122 | ||
776 | BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) | 1123 | BOOL LLSpatialPartition::remove(LLDrawable *drawablep, LLSpatialGroup *curp) |
@@ -793,14 +1140,16 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL | |||
793 | { | 1140 | { |
794 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1141 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
795 | LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); | 1142 | LLFastTimer t(LLFastTimer::FTM_UPDATE_MOVE); |
796 | 1143 | ||
1144 | BOOL was_visible = curp ? curp->isVisible() : FALSE; | ||
1145 | |||
797 | if (curp && curp->mSpatialPartition != this) | 1146 | if (curp && curp->mSpatialPartition != this) |
798 | { | 1147 | { |
799 | //keep drawable from being garbage collected | 1148 | //keep drawable from being garbage collected |
800 | LLPointer<LLDrawable> ptr = drawablep; | 1149 | LLPointer<LLDrawable> ptr = drawablep; |
801 | if (curp->mSpatialPartition->remove(drawablep, curp)) | 1150 | if (curp->mSpatialPartition->remove(drawablep, curp)) |
802 | { | 1151 | { |
803 | put(drawablep); | 1152 | put(drawablep, was_visible); |
804 | return; | 1153 | return; |
805 | } | 1154 | } |
806 | else | 1155 | else |
@@ -823,7 +1172,7 @@ void LLSpatialPartition::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL | |||
823 | OCT_ERRS << "Move couldn't find existing spatial group!" << llendl; | 1172 | OCT_ERRS << "Move couldn't find existing spatial group!" << llendl; |
824 | } | 1173 | } |
825 | 1174 | ||
826 | put(drawablep); | 1175 | put(drawablep, was_visible); |
827 | } | 1176 | } |
828 | 1177 | ||
829 | class LLSpatialShift : public LLSpatialGroup::OctreeTraveler | 1178 | class LLSpatialShift : public LLSpatialGroup::OctreeTraveler |
@@ -848,13 +1197,9 @@ void LLSpatialPartition::shift(const LLVector3 &offset) | |||
848 | 1197 | ||
849 | BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera) | 1198 | BOOL LLSpatialPartition::checkOcclusion(LLSpatialGroup* group, LLCamera* camera) |
850 | { | 1199 | { |
851 | if (sIgnoreOcclusion) | 1200 | if (LLPipeline::sUseOcclusion && |
852 | { | 1201 | !group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) && |
853 | return FALSE; | 1202 | (!camera || !earlyFail(camera, group))) |
854 | } | ||
855 | |||
856 | if (!group->isState(LLSpatialGroup::ACTIVE_OCCLUSION | LLSpatialGroup::OCCLUDED) && | ||
857 | !earlyFail(camera, group)) | ||
858 | { | 1203 | { |
859 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); | 1204 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); |
860 | mQueryQueue.push(group); | 1205 | mQueryQueue.push(group); |
@@ -872,8 +1217,8 @@ public: | |||
872 | 1217 | ||
873 | virtual bool earlyFail(const LLSpatialGroup* group) | 1218 | virtual bool earlyFail(const LLSpatialGroup* group) |
874 | { | 1219 | { |
875 | if (mRes && //never occlusion cull the root node | 1220 | if (group->mOctreeNode->getParent() && //never occlusion cull the root node |
876 | !sIgnoreOcclusion && //never occlusion cull selection | 1221 | LLPipeline::sUseOcclusion && //never occlusion cull selection |
877 | group->isState(LLSpatialGroup::OCCLUDED)) | 1222 | group->isState(LLSpatialGroup::OCCLUDED)) |
878 | { | 1223 | { |
879 | return true; | 1224 | return true; |
@@ -950,22 +1295,19 @@ public: | |||
950 | group->mSpatialPartition->checkOcclusion(group, mCamera); | 1295 | group->mSpatialPartition->checkOcclusion(group, mCamera); |
951 | } | 1296 | } |
952 | } | 1297 | } |
1298 | |||
1299 | if (LLPipeline::sDynamicReflections && | ||
1300 | group->mOctreeNode->getSize().mdV[0] == 16.0 && | ||
1301 | group->mDistance < 64.f && | ||
1302 | group->mLastAddTime < gFrameTimeSeconds - 2.f) | ||
1303 | { | ||
1304 | group->mSpatialPartition->markReimage(group); | ||
1305 | } | ||
953 | } | 1306 | } |
954 | 1307 | ||
955 | virtual void processDrawable(LLDrawable* drawable) | 1308 | virtual void processGroup(LLSpatialGroup* group) |
956 | { | 1309 | { |
957 | if (!drawable->isDead()) | 1310 | gPipeline.markNotCulled(group, *mCamera); |
958 | { | ||
959 | const LLVector3* extents = drawable->getSpatialExtents(); | ||
960 | |||
961 | F32 objRad = drawable->getRadius(); | ||
962 | objRad *= objRad; | ||
963 | F32 distSqr = ((extents[0]+extents[1])*0.5f - mCamera->getOrigin()).magVecSquared(); | ||
964 | if (objRad/distSqr > SG_MIN_DIST_RATIO) | ||
965 | { | ||
966 | gPipeline.markNotCulled(drawable, *mCamera); | ||
967 | } | ||
968 | } | ||
969 | } | 1311 | } |
970 | 1312 | ||
971 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 1313 | virtual void visit(const LLSpatialGroup::OctreeState* branch) |
@@ -976,10 +1318,7 @@ public: | |||
976 | 1318 | ||
977 | if (checkObjects(branch, group)) | 1319 | if (checkObjects(branch, group)) |
978 | { | 1320 | { |
979 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | 1321 | processGroup(group); |
980 | { | ||
981 | processDrawable(*i); | ||
982 | } | ||
983 | } | 1322 | } |
984 | } | 1323 | } |
985 | 1324 | ||
@@ -998,34 +1337,32 @@ public: | |||
998 | virtual void lateFail(LLSpatialGroup* group) { } | 1337 | virtual void lateFail(LLSpatialGroup* group) { } |
999 | virtual void preprocess(LLSpatialGroup* group) { } | 1338 | virtual void preprocess(LLSpatialGroup* group) { } |
1000 | 1339 | ||
1001 | virtual void processDrawable(LLDrawable* drawable) | 1340 | virtual void processGroup(LLSpatialGroup* group) |
1002 | { | 1341 | { |
1003 | if (!drawable->isDead()) | 1342 | LLSpatialGroup::OctreeState* branch = group->mOctreeNode->getOctState(); |
1343 | |||
1344 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | ||
1004 | { | 1345 | { |
1005 | if (drawable->isSpatialBridge()) | 1346 | LLDrawable* drawable = *i; |
1006 | { | 1347 | |
1007 | drawable->setVisible(*mCamera, mResults, TRUE); | 1348 | if (!drawable->isDead()) |
1008 | } | ||
1009 | else | ||
1010 | { | 1349 | { |
1011 | mResults->push_back(drawable); | 1350 | if (drawable->isSpatialBridge()) |
1012 | } | 1351 | { |
1013 | } | 1352 | drawable->setVisible(*mCamera, mResults, TRUE); |
1353 | } | ||
1354 | else | ||
1355 | { | ||
1356 | mResults->push_back(drawable); | ||
1357 | } | ||
1358 | } | ||
1359 | } | ||
1014 | } | 1360 | } |
1015 | 1361 | ||
1016 | std::vector<LLDrawable*>* mResults; | 1362 | std::vector<LLDrawable*>* mResults; |
1017 | }; | 1363 | }; |
1018 | 1364 | ||
1019 | 1365 | ||
1020 | void drawBox(const LLVector3& c, const LLVector3& r) | ||
1021 | { | ||
1022 | glPushMatrix(); | ||
1023 | glTranslatef(c.mV[0], c.mV[1], c.mV[2]); | ||
1024 | glScalef(r.mV[0], r.mV[1], r.mV[2]); | ||
1025 | glCallList(sBoxList); | ||
1026 | glPopMatrix(); | ||
1027 | } | ||
1028 | |||
1029 | void genBoxList() | 1366 | void genBoxList() |
1030 | { | 1367 | { |
1031 | if (sBoxList != 0) | 1368 | if (sBoxList != 0) |
@@ -1077,6 +1414,83 @@ void genBoxList() | |||
1077 | glEndList(); | 1414 | glEndList(); |
1078 | } | 1415 | } |
1079 | 1416 | ||
1417 | void drawBox(const LLVector3& c, const LLVector3& r) | ||
1418 | { | ||
1419 | genBoxList(); | ||
1420 | |||
1421 | glPushMatrix(); | ||
1422 | glTranslatef(c.mV[0], c.mV[1], c.mV[2]); | ||
1423 | glScalef(r.mV[0], r.mV[1], r.mV[2]); | ||
1424 | glCallList(sBoxList); | ||
1425 | glPopMatrix(); | ||
1426 | } | ||
1427 | |||
1428 | void drawBoxOutline(const LLVector3& pos, const LLVector3& size) | ||
1429 | { | ||
1430 | LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); | ||
1431 | LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1)); | ||
1432 | LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); | ||
1433 | LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); | ||
1434 | |||
1435 | glBegin(GL_LINE_LOOP); //top | ||
1436 | glVertex3fv((pos+v1).mV); | ||
1437 | glVertex3fv((pos+v2).mV); | ||
1438 | glVertex3fv((pos+v3).mV); | ||
1439 | glVertex3fv((pos+v4).mV); | ||
1440 | glEnd(); | ||
1441 | |||
1442 | glBegin(GL_LINE_LOOP); //bottom | ||
1443 | glVertex3fv((pos-v1).mV); | ||
1444 | glVertex3fv((pos-v2).mV); | ||
1445 | glVertex3fv((pos-v3).mV); | ||
1446 | glVertex3fv((pos-v4).mV); | ||
1447 | glEnd(); | ||
1448 | |||
1449 | |||
1450 | glBegin(GL_LINES); | ||
1451 | |||
1452 | //right | ||
1453 | glVertex3fv((pos+v1).mV); | ||
1454 | glVertex3fv((pos-v3).mV); | ||
1455 | |||
1456 | glVertex3fv((pos+v4).mV); | ||
1457 | glVertex3fv((pos-v2).mV); | ||
1458 | |||
1459 | //left | ||
1460 | glVertex3fv((pos+v2).mV); | ||
1461 | glVertex3fv((pos-v4).mV); | ||
1462 | |||
1463 | glVertex3fv((pos+v3).mV); | ||
1464 | glVertex3fv((pos-v1).mV); | ||
1465 | |||
1466 | glEnd(); | ||
1467 | } | ||
1468 | |||
1469 | class LLOctreeDirty : public LLOctreeTraveler<LLDrawable> | ||
1470 | { | ||
1471 | public: | ||
1472 | virtual void visit(const LLOctreeState<LLDrawable>* state) | ||
1473 | { | ||
1474 | LLSpatialGroup* group = (LLSpatialGroup*) state->getListener(0); | ||
1475 | group->destroyGL(); | ||
1476 | |||
1477 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | ||
1478 | { | ||
1479 | LLDrawable* drawable = *i; | ||
1480 | if (drawable->getVObj() && !group->mSpatialPartition->mRenderByGroup) | ||
1481 | { | ||
1482 | gPipeline.markRebuild(drawable, LLDrawable::REBUILD_ALL, TRUE); | ||
1483 | } | ||
1484 | } | ||
1485 | |||
1486 | for (LLSpatialGroup::bridge_list_t::iterator i = group->mBridgeList.begin(); i != group->mBridgeList.end(); ++i) | ||
1487 | { | ||
1488 | LLSpatialBridge* bridge = *i; | ||
1489 | traverse(bridge->mOctree); | ||
1490 | } | ||
1491 | } | ||
1492 | }; | ||
1493 | |||
1080 | void LLSpatialPartition::restoreGL() | 1494 | void LLSpatialPartition::restoreGL() |
1081 | { | 1495 | { |
1082 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1496 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
@@ -1099,6 +1513,14 @@ void LLSpatialPartition::restoreGL() | |||
1099 | genBoxList(); | 1513 | genBoxList(); |
1100 | } | 1514 | } |
1101 | 1515 | ||
1516 | void LLSpatialPartition::resetVertexBuffers() | ||
1517 | { | ||
1518 | LLOctreeDirty dirty; | ||
1519 | dirty.traverse(mOctree); | ||
1520 | |||
1521 | mOcclusionIndices = NULL; | ||
1522 | } | ||
1523 | |||
1102 | S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) | 1524 | S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* results, BOOL for_select) |
1103 | { | 1525 | { |
1104 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1526 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
@@ -1115,11 +1537,11 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector<LLDrawable *>* result | |||
1115 | } | 1537 | } |
1116 | else | 1538 | else |
1117 | { | 1539 | { |
1540 | LLFastTimer ftm(LLFastTimer::FTM_FRUSTUM_CULL); | ||
1118 | LLOctreeCull culler(&camera); | 1541 | LLOctreeCull culler(&camera); |
1119 | culler.traverse(mOctree); | 1542 | culler.traverse(mOctree); |
1120 | } | 1543 | } |
1121 | 1544 | ||
1122 | sIgnoreOcclusion = !(gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery); | ||
1123 | return 0; | 1545 | return 0; |
1124 | } | 1546 | } |
1125 | 1547 | ||
@@ -1174,9 +1596,10 @@ public: | |||
1174 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) | 1596 | BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) |
1175 | { | 1597 | { |
1176 | LLVector3 c = group->mBounds[0]; | 1598 | LLVector3 c = group->mBounds[0]; |
1177 | LLVector3 r = group->mBounds[1] * (SG_OCCLUSION_FUDGE*2.f) + LLVector3(0.01f,0.01f,0.01f); | 1599 | LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.2f,0.2f,0.2f); |
1178 | 1600 | ||
1179 | if (group->isState(LLSpatialGroup::CULLED) || !camera->AABBInFrustum(c, r)) | 1601 | //if (group->isState(LLSpatialGroup::CULLED)) // || |
1602 | if (!camera->AABBInFrustum(c, r)) | ||
1180 | { | 1603 | { |
1181 | return TRUE; | 1604 | return TRUE; |
1182 | } | 1605 | } |
@@ -1197,6 +1620,100 @@ BOOL earlyFail(LLCamera* camera, LLSpatialGroup* group) | |||
1197 | return TRUE; | 1620 | return TRUE; |
1198 | } | 1621 | } |
1199 | 1622 | ||
1623 | void LLSpatialPartition::markReimage(LLSpatialGroup* group) | ||
1624 | { | ||
1625 | if (mImageEnabled && group->isState(LLSpatialGroup::IMAGE_DIRTY)) | ||
1626 | { | ||
1627 | if (!group->isState(LLSpatialGroup::IN_IMAGE_QUEUE)) | ||
1628 | { | ||
1629 | group->setState(LLSpatialGroup::IN_IMAGE_QUEUE); | ||
1630 | mImageQueue.push(group); | ||
1631 | } | ||
1632 | } | ||
1633 | } | ||
1634 | |||
1635 | void LLSpatialPartition::processImagery(LLCamera* camera) | ||
1636 | { | ||
1637 | if (!mImageEnabled) | ||
1638 | { | ||
1639 | return; | ||
1640 | } | ||
1641 | |||
1642 | U32 process_count = 1; | ||
1643 | |||
1644 | while (process_count > 0 && !mImageQueue.empty()) | ||
1645 | { | ||
1646 | LLPointer<LLSpatialGroup> group = mImageQueue.front(); | ||
1647 | mImageQueue.pop(); | ||
1648 | |||
1649 | group->clearState(LLSpatialGroup::IN_IMAGE_QUEUE); | ||
1650 | |||
1651 | if (group->isDead()) | ||
1652 | { | ||
1653 | continue; | ||
1654 | } | ||
1655 | |||
1656 | if (LLPipeline::sDynamicReflections) | ||
1657 | { | ||
1658 | process_count--; | ||
1659 | LLVector3 origin = group->mBounds[0]; | ||
1660 | |||
1661 | LLCamera cube_cam; | ||
1662 | cube_cam.setOrigin(origin); | ||
1663 | cube_cam.setFar(64.f); | ||
1664 | |||
1665 | LLPointer<LLCubeMap> cube_map = group->mReflectionMap; | ||
1666 | group->mReflectionMap = NULL; | ||
1667 | if (cube_map.isNull()) | ||
1668 | { | ||
1669 | cube_map = new LLCubeMap(); | ||
1670 | cube_map->initGL(); | ||
1671 | } | ||
1672 | |||
1673 | if (gPipeline.mCubeBuffer == NULL) | ||
1674 | { | ||
1675 | gPipeline.mCubeBuffer = new LLCubeMap(); | ||
1676 | gPipeline.mCubeBuffer->initGL(); | ||
1677 | } | ||
1678 | |||
1679 | gPipeline.generateReflectionMap(gPipeline.mCubeBuffer, cube_cam, 128); | ||
1680 | gPipeline.blurReflectionMap(gPipeline.mCubeBuffer, cube_map, 64); | ||
1681 | group->mReflectionMap = cube_map; | ||
1682 | group->setState(LLSpatialGroup::GEOM_DIRTY); | ||
1683 | } | ||
1684 | |||
1685 | group->clearState(LLSpatialGroup::IMAGE_DIRTY); | ||
1686 | } | ||
1687 | } | ||
1688 | |||
1689 | void validate_occlusion_list(std::vector<LLPointer<LLSpatialGroup> >& occluded_list) | ||
1690 | { | ||
1691 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
1692 | for (U32 i = 0; i < occluded_list.size(); i++) | ||
1693 | { | ||
1694 | LLSpatialGroup* group = occluded_list[i]; | ||
1695 | for (U32 j = i+1; j < occluded_list.size(); j++) | ||
1696 | { | ||
1697 | if (occluded_list[i] == occluded_list[j]) | ||
1698 | { | ||
1699 | llerrs << "Duplicate node in occlusion list." << llendl; | ||
1700 | } | ||
1701 | } | ||
1702 | |||
1703 | LLSpatialGroup::OctreeNode* parent = group->mOctreeNode->getOctParent(); | ||
1704 | while (parent) | ||
1705 | { | ||
1706 | LLSpatialGroup* parent_group = (LLSpatialGroup*) parent->getListener(0); | ||
1707 | if (parent_group->isState(LLSpatialGroup::OCCLUDED)) | ||
1708 | { | ||
1709 | llerrs << "Child node of occluded node in occlusion list (redundant query)." << llendl; | ||
1710 | } | ||
1711 | parent = parent->getOctParent(); | ||
1712 | } | ||
1713 | } | ||
1714 | #endif | ||
1715 | } | ||
1716 | |||
1200 | void LLSpatialPartition::processOcclusion(LLCamera* camera) | 1717 | void LLSpatialPartition::processOcclusion(LLCamera* camera) |
1201 | { | 1718 | { |
1202 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 1719 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
@@ -1217,12 +1734,12 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1217 | const U32 MAX_PUSHED = mOcclusionQueue.size(); | 1734 | const U32 MAX_PUSHED = mOcclusionQueue.size(); |
1218 | U32 count = 0; | 1735 | U32 count = 0; |
1219 | U32 pcount = 0; | 1736 | U32 pcount = 0; |
1220 | 1737 | ||
1221 | while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty()) | 1738 | while (pcount < MAX_PUSHED && count < MAX_PULLED && !mOcclusionQueue.empty()) |
1222 | { | 1739 | { |
1223 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION); | 1740 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION); |
1224 | 1741 | ||
1225 | LLSpatialGroup* group = mOcclusionQueue.front(); | 1742 | LLPointer<LLSpatialGroup> group = mOcclusionQueue.front(); |
1226 | if (!group->isState(LLSpatialGroup::IN_QUEUE)) | 1743 | if (!group->isState(LLSpatialGroup::IN_QUEUE)) |
1227 | { | 1744 | { |
1228 | OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl; | 1745 | OCT_ERRS << "Spatial Group State Error. Group in queue not tagged as such." << llendl; |
@@ -1233,10 +1750,6 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1233 | 1750 | ||
1234 | if (group->isDead()) | 1751 | if (group->isDead()) |
1235 | { | 1752 | { |
1236 | if (group->safeToDelete()) | ||
1237 | { | ||
1238 | delete group; | ||
1239 | } | ||
1240 | continue; | 1753 | continue; |
1241 | } | 1754 | } |
1242 | 1755 | ||
@@ -1250,22 +1763,14 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1250 | { | 1763 | { |
1251 | LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0); | 1764 | LLSpatialGroup* child = (LLSpatialGroup*) group->mOctreeNode->getChild(i)->getListener(0); |
1252 | 1765 | ||
1253 | if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED) | 1766 | //if (!child->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED) |
1254 | && !child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION)) | 1767 | if (!child->isState(LLSpatialGroup::IN_QUEUE | LLSpatialGroup::ACTIVE_OCCLUSION)) |
1255 | { | 1768 | { |
1256 | child->setState(LLSpatialGroup::IN_QUEUE); | 1769 | child->setState(LLSpatialGroup::IN_QUEUE); |
1257 | mOcclusionQueue.push(child); | 1770 | mOcclusionQueue.push(child); |
1258 | } | 1771 | } |
1259 | } | 1772 | } |
1260 | 1773 | ||
1261 | /*if (group->isState(LLSpatialGroup::QUERY_PENDING)) | ||
1262 | { //already on the pending group, put it back | ||
1263 | group->setState(LLSpatialGroup::IN_QUEUE); | ||
1264 | mOcclusionQueue.push(group); | ||
1265 | pcount++; | ||
1266 | continue; | ||
1267 | }*/ | ||
1268 | |||
1269 | if (earlyFail(camera, group)) | 1774 | if (earlyFail(camera, group)) |
1270 | { | 1775 | { |
1271 | sg_assert(!group->isState(LLSpatialGroup::OCCLUDED)); | 1776 | sg_assert(!group->isState(LLSpatialGroup::OCCLUDED)); |
@@ -1284,7 +1789,6 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1284 | sg_assert(mOccludedList[i] != group); | 1789 | sg_assert(mOccludedList[i] != group); |
1285 | } | 1790 | } |
1286 | #endif | 1791 | #endif |
1287 | //group->setState(LLSpatialGroup::QUERY_PENDING); | ||
1288 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); | 1792 | group->setState(LLSpatialGroup::ACTIVE_OCCLUSION); |
1289 | mQueryQueue.push(group); | 1793 | mQueryQueue.push(group); |
1290 | count++; | 1794 | count++; |
@@ -1296,7 +1800,7 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1296 | { | 1800 | { |
1297 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); | 1801 | LLFastTimer t(LLFastTimer::FTM_OCCLUSION_READBACK); |
1298 | 1802 | ||
1299 | if (mOccludedList[i]->isDead() || !mOccludedList[i]->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) | 1803 | if (mOccludedList[i]->isDead() || mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) |
1300 | { | 1804 | { |
1301 | continue; | 1805 | continue; |
1302 | } | 1806 | } |
@@ -1347,8 +1851,7 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1347 | LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0); | 1851 | LLSpatialGroup* parent = (LLSpatialGroup*) oct_parent->getListener(0); |
1348 | 1852 | ||
1349 | if (checkOcclusion(parent, camera)) | 1853 | if (checkOcclusion(parent, camera)) |
1350 | { //force a guess on the parent and siblings | 1854 | { //force a guess on the parent and siblings |
1351 | |||
1352 | for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++) | 1855 | for (U32 i = 0; i < parent->mOctreeNode->getChildCount(); i++) |
1353 | { | 1856 | { |
1354 | LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0); | 1857 | LLSpatialGroup* child = (LLSpatialGroup*) parent->mOctreeNode->getChild(i)->getListener(0); |
@@ -1356,13 +1859,17 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1356 | } | 1859 | } |
1357 | } | 1860 | } |
1358 | } | 1861 | } |
1862 | |||
1863 | //take children off the active list | ||
1864 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); | ||
1865 | mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1359 | } | 1866 | } |
1360 | mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); | 1867 | mOccludedList[i]->setState(LLSpatialGroup::OCCLUDED, LLSpatialGroup::STATE_MODE_DIFF); |
1361 | } | 1868 | } |
1362 | else | 1869 | else |
1363 | { | 1870 | { |
1364 | //take children off the active list | 1871 | //take children off the active list |
1365 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_DIFF); | 1872 | mOccludedList[i]->setState(LLSpatialGroup::DEACTIVATE_OCCLUSION, LLSpatialGroup::STATE_MODE_BRANCH); |
1366 | 1873 | ||
1367 | //keep this node on the active list | 1874 | //keep this node on the active list |
1368 | mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | 1875 | mOccludedList[i]->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); |
@@ -1383,15 +1890,13 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1383 | mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded | 1890 | mOccludedList[i]->isState(LLSpatialGroup::DEACTIVATE_OCCLUSION)) //parent is occluded |
1384 | { | 1891 | { |
1385 | LLSpatialGroup* groupp = mOccludedList[i]; | 1892 | LLSpatialGroup* groupp = mOccludedList[i]; |
1386 | mOccludedList.erase(mOccludedList.begin()+i); | 1893 | if (!groupp->isDead()) |
1387 | groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); | ||
1388 | groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1389 | groupp->clearState(LLSpatialGroup::OCCLUDING); | ||
1390 | |||
1391 | if (groupp->isDead() && groupp->safeToDelete()) | ||
1392 | { | 1894 | { |
1393 | delete groupp; | 1895 | groupp->clearState(LLSpatialGroup::ACTIVE_OCCLUSION); |
1896 | groupp->clearState(LLSpatialGroup::DEACTIVATE_OCCLUSION); | ||
1897 | groupp->clearState(LLSpatialGroup::OCCLUDING); | ||
1394 | } | 1898 | } |
1899 | mOccludedList.erase(mOccludedList.begin()+i); | ||
1395 | } | 1900 | } |
1396 | else | 1901 | else |
1397 | { | 1902 | { |
@@ -1399,11 +1904,13 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1399 | } | 1904 | } |
1400 | } | 1905 | } |
1401 | 1906 | ||
1907 | validate_occlusion_list(mOccludedList); | ||
1908 | |||
1402 | //pump some non-culled items onto the occlusion list | 1909 | //pump some non-culled items onto the occlusion list |
1403 | //count = MAX_PULLED; | 1910 | //count = MAX_PULLED; |
1404 | while (!mQueryQueue.empty()) | 1911 | while (!mQueryQueue.empty()) |
1405 | { | 1912 | { |
1406 | LLSpatialGroup* group = mQueryQueue.front(); | 1913 | LLPointer<LLSpatialGroup> group = mQueryQueue.front(); |
1407 | mQueryQueue.pop(); | 1914 | mQueryQueue.pop(); |
1408 | //group->clearState(LLSpatialGroup::QUERY_PENDING); | 1915 | //group->clearState(LLSpatialGroup::QUERY_PENDING); |
1409 | mOccludedList.push_back(group); | 1916 | mOccludedList.push_back(group); |
@@ -1418,12 +1925,161 @@ void LLSpatialPartition::processOcclusion(LLCamera* camera) | |||
1418 | } | 1925 | } |
1419 | } | 1926 | } |
1420 | 1927 | ||
1928 | class LLOcclusionIndexBuffer : public LLVertexBuffer | ||
1929 | { | ||
1930 | public: | ||
1931 | LLOcclusionIndexBuffer(U32 size) | ||
1932 | : LLVertexBuffer(0, GL_STREAM_DRAW_ARB) | ||
1933 | { | ||
1934 | allocateBuffer(0, size, TRUE); | ||
1935 | |||
1936 | LLStrider<U32> idx; | ||
1937 | |||
1938 | getIndexStrider(idx); | ||
1939 | |||
1940 | //12 triangles' indices | ||
1941 | idx[0] = 1; idx[1] = 0; idx[2] = 2; //front | ||
1942 | idx[3] = 3; idx[4] = 2; idx[5] = 0; | ||
1943 | |||
1944 | idx[6] = 4; idx[7] = 5; idx[8] = 1; //top | ||
1945 | idx[9] = 0; idx[10] = 1; idx[11] = 5; | ||
1946 | |||
1947 | idx[12] = 5; idx[13] = 4; idx[14] = 6; //back | ||
1948 | idx[15] = 7; idx[16] = 6; idx[17] = 4; | ||
1949 | |||
1950 | idx[18] = 6; idx[19] = 7; idx[20] = 3; //bottom | ||
1951 | idx[21] = 2; idx[22] = 3; idx[23] = 7; | ||
1952 | |||
1953 | idx[24] = 0; idx[25] = 5; idx[26] = 3; //left | ||
1954 | idx[27] = 6; idx[28] = 3; idx[29] = 5; | ||
1955 | |||
1956 | idx[30] = 4; idx[31] = 1; idx[32] = 7; //right | ||
1957 | idx[33] = 2; idx[34] = 7; idx[35] = 1; | ||
1958 | } | ||
1959 | |||
1960 | //virtual BOOL useVBOs() const { return FALSE; } | ||
1961 | |||
1962 | void setBuffer(U32 data_mask) | ||
1963 | { | ||
1964 | if (useVBOs()) | ||
1965 | { | ||
1966 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); | ||
1967 | sIBOActive = TRUE; | ||
1968 | unmapBuffer(); | ||
1969 | } | ||
1970 | else if (sIBOActive) | ||
1971 | { | ||
1972 | glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); | ||
1973 | sIBOActive = FALSE; | ||
1974 | } | ||
1975 | |||
1976 | sGLRenderIndices = mGLIndices; | ||
1977 | } | ||
1978 | }; | ||
1979 | |||
1980 | class LLOcclusionVertexBuffer : public LLVertexBuffer | ||
1981 | { | ||
1982 | public: | ||
1983 | LLOcclusionVertexBuffer(S32 usage) | ||
1984 | : LLVertexBuffer(MAP_VERTEX, usage) | ||
1985 | { | ||
1986 | allocateBuffer(8, 0, TRUE); | ||
1987 | } | ||
1988 | |||
1989 | //virtual BOOL useVBOs() const { return FALSE; } | ||
1990 | |||
1991 | void setBuffer(U32 data_mask) | ||
1992 | { | ||
1993 | if (useVBOs()) | ||
1994 | { | ||
1995 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); | ||
1996 | sVBOActive = TRUE; | ||
1997 | unmapBuffer(); | ||
1998 | } | ||
1999 | else if (sVBOActive) | ||
2000 | { | ||
2001 | glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); | ||
2002 | sVBOActive = FALSE; | ||
2003 | } | ||
2004 | |||
2005 | if (data_mask) | ||
2006 | { | ||
2007 | glVertexPointer(3,GL_FLOAT, 0, useVBOs() ? 0 : mMappedData); | ||
2008 | } | ||
2009 | |||
2010 | sGLRenderBuffer = mGLBuffer; | ||
2011 | } | ||
2012 | }; | ||
2013 | |||
2014 | void LLSpatialPartition::buildOcclusion() | ||
2015 | { | ||
2016 | if (mOccludedList.empty()) | ||
2017 | { | ||
2018 | return; | ||
2019 | } | ||
2020 | |||
2021 | BOOL reset_all = FALSE; | ||
2022 | if (mOcclusionIndices.isNull()) | ||
2023 | { | ||
2024 | mOcclusionIndices = new LLOcclusionIndexBuffer(36); | ||
2025 | reset_all = TRUE; | ||
2026 | } | ||
2027 | |||
2028 | //fill occlusion vertex buffers | ||
2029 | for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2030 | { | ||
2031 | LLSpatialGroup* group = mOccludedList[i]; | ||
2032 | |||
2033 | if (group->isState(LLSpatialGroup::OCCLUSION_DIRTY) || reset_all) | ||
2034 | { | ||
2035 | LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); | ||
2036 | |||
2037 | if (group->mOcclusionVerts.isNull()) | ||
2038 | { | ||
2039 | group->mOcclusionVerts = new LLOcclusionVertexBuffer(GL_STREAM_DRAW_ARB); | ||
2040 | } | ||
2041 | |||
2042 | group->clearState(LLSpatialGroup::OCCLUSION_DIRTY); | ||
2043 | |||
2044 | LLStrider<LLVector3> vert; | ||
2045 | |||
2046 | group->mOcclusionVerts->getVertexStrider(vert); | ||
2047 | |||
2048 | LLVector3 r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.1f,0.1f,0.1f); | ||
2049 | |||
2050 | for (U32 k = 0; k < 3; k++) | ||
2051 | { | ||
2052 | r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]); | ||
2053 | } | ||
2054 | |||
2055 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,1)); // 0 - left top front | ||
2056 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,1)); // 1 - right top front | ||
2057 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,1)); // 2 - right bottom front | ||
2058 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,1)); // 3 - left bottom front | ||
2059 | |||
2060 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,1,-1)); // 4 - left top back | ||
2061 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,1,-1)); // 5 - right top back | ||
2062 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(-1,-1,-1)); // 6 - right bottom back | ||
2063 | *vert++ = group->mBounds[0] + r.scaledVec(LLVector3(1,-1,-1)); // 7 -left bottom back | ||
2064 | } | ||
2065 | } | ||
2066 | |||
2067 | /* for (U32 i = 0; i < mOccludedList.size(); i++) | ||
2068 | { | ||
2069 | LLSpatialGroup* group = mOccludedList[i]; | ||
2070 | if (!group->mOcclusionVerts.isNull() && group->mOcclusionVerts->isLocked()) | ||
2071 | { | ||
2072 | LLFastTimer ftm(LLFastTimer::FTM_REBUILD_OCCLUSION_VB); | ||
2073 | group->mOcclusionVerts->setBuffer(0); | ||
2074 | } | ||
2075 | }*/ | ||
2076 | } | ||
2077 | |||
1421 | void LLSpatialPartition::doOcclusion(LLCamera* camera) | 2078 | void LLSpatialPartition::doOcclusion(LLCamera* camera) |
1422 | { | 2079 | { |
1423 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); | 2080 | LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); |
1424 | 2081 | ||
1425 | sIgnoreOcclusion = gUseWireframe; | 2082 | LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); |
1426 | LLFastTimer t(LLFastTimer::FTM_RENDER_OCCLUSION); | ||
1427 | 2083 | ||
1428 | #if LL_OCTREE_PARANOIA_CHECK | 2084 | #if LL_OCTREE_PARANOIA_CHECK |
1429 | LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0); | 2085 | LLSpatialGroup* check = (LLSpatialGroup*) mOctree->getListener(0); |
@@ -1432,9 +2088,16 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera) | |||
1432 | 2088 | ||
1433 | stop_glerror(); | 2089 | stop_glerror(); |
1434 | 2090 | ||
2091 | U32 num_verts = mOccludedList.size() * 8; | ||
2092 | |||
2093 | if (num_verts == 0) | ||
2094 | { | ||
2095 | return; | ||
2096 | } | ||
2097 | |||
1435 | //actually perform the occlusion queries | 2098 | //actually perform the occlusion queries |
1436 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | 2099 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); |
1437 | glDisable(GL_TEXTURE_2D); | 2100 | LLGLDisable(GL_TEXTURE_2D); |
1438 | gPipeline.disableLights(); | 2101 | gPipeline.disableLights(); |
1439 | LLGLEnable cull_face(GL_CULL_FACE); | 2102 | LLGLEnable cull_face(GL_CULL_FACE); |
1440 | LLGLDisable blend(GL_BLEND); | 2103 | LLGLDisable blend(GL_BLEND); |
@@ -1443,25 +2106,16 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera) | |||
1443 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); | 2106 | glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); |
1444 | glColor4f(1,1,1,1); | 2107 | glColor4f(1,1,1,1); |
1445 | 2108 | ||
1446 | //sort occlusion queries front to back | 2109 | mOcclusionIndices->setBuffer(0); |
1447 | /*for (U32 i = 0; i < mOccludedList.size(); i++) | ||
1448 | { | ||
1449 | LLSpatialGroup* group = mOccludedList[i]; | ||
1450 | |||
1451 | LLVector3 v = group->mOctreeNode->getCenter()-camera->getOrigin(); | ||
1452 | group->mDistance = v*v; | ||
1453 | } | ||
1454 | |||
1455 | std::sort(mOccludedList.begin(), mOccludedList.end(), dist_greater()); | ||
1456 | 2110 | ||
1457 | glClearStencil(0); | 2111 | U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); |
1458 | glClear(GL_STENCIL_BUFFER_BIT); | ||
1459 | LLGLEnable stencil(GL_STENCIL_TEST); | ||
1460 | glStencilFunc(GL_GREATER, 1, 0xFFFFFFFF); | ||
1461 | glStencilOp(GL_KEEP, GL_SET, GL_KEEP);*/ | ||
1462 | |||
1463 | genBoxList(); | ||
1464 | 2112 | ||
2113 | glDisableClientState(GL_NORMAL_ARRAY); | ||
2114 | glDisableClientState(GL_TEXTURE_COORD_ARRAY); | ||
2115 | glDisableClientState(GL_COLOR_ARRAY); | ||
2116 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
2117 | LLGLState::checkClientArrays(LLVertexBuffer::MAP_VERTEX); | ||
2118 | #endif | ||
1465 | for (U32 i = 0; i < mOccludedList.size(); i++) | 2119 | for (U32 i = 0; i < mOccludedList.size(); i++) |
1466 | { | 2120 | { |
1467 | #if LL_OCTREE_PARANOIA_CHECK | 2121 | #if LL_OCTREE_PARANOIA_CHECK |
@@ -1482,32 +2136,10 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera) | |||
1482 | } | 2136 | } |
1483 | else | 2137 | else |
1484 | { //early rejection criteria passed, send some geometry to the query | 2138 | { //early rejection criteria passed, send some geometry to the query |
1485 | LLVector3 c; | 2139 | group->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); |
1486 | LLVector3 r; | ||
1487 | |||
1488 | sg_assert(!group->isState(LLSpatialGroup::DIRTY)); | ||
1489 | |||
1490 | c = group->mBounds[0]; | ||
1491 | r = group->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.01f,0.01f,0.01f); | ||
1492 | for (U32 k = 0; k < 3; k++) | ||
1493 | { | ||
1494 | r.mV[k] = llmin(group->mBounds[1].mV[k]+0.25f, r.mV[k]); | ||
1495 | } | ||
1496 | |||
1497 | #if LL_OCTREE_PARANOIA_CHECK | ||
1498 | LLVector3 e = camera->getOrigin(); | ||
1499 | LLVector3 min = c - r; | ||
1500 | LLVector3 max = c + r; | ||
1501 | BOOL outside = FALSE; | ||
1502 | for (U32 j = 0; j < 3; j++) | ||
1503 | { | ||
1504 | outside = outside || (e.mV[j] < min.mV[j] || e.mV[j] > max.mV[j]); | ||
1505 | } | ||
1506 | sg_assert(outside); | ||
1507 | #endif | ||
1508 | |||
1509 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]); | 2140 | glBeginQueryARB(GL_SAMPLES_PASSED_ARB, mOcclusionQueries[i]); |
1510 | drawBox(c,r); | 2141 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, |
2142 | GL_UNSIGNED_INT, indicesp); | ||
1511 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); | 2143 | glEndQueryARB(GL_SAMPLES_PASSED_ARB); |
1512 | 2144 | ||
1513 | group->setState(LLSpatialGroup::QUERY_OUT); | 2145 | group->setState(LLSpatialGroup::QUERY_OUT); |
@@ -1516,10 +2148,11 @@ void LLSpatialPartition::doOcclusion(LLCamera* camera) | |||
1516 | } | 2148 | } |
1517 | stop_glerror(); | 2149 | stop_glerror(); |
1518 | 2150 | ||
2151 | gPipeline.mTrianglesDrawn += mOccludedList.size()*12; | ||
2152 | |||
1519 | glFlush(); | 2153 | glFlush(); |
1520 | 2154 | ||
1521 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 2155 | glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); |
1522 | glEnable(GL_TEXTURE_2D); | ||
1523 | } | 2156 | } |
1524 | 2157 | ||
1525 | class LLOctreeGet : public LLSpatialGroup::OctreeTraveler | 2158 | class LLOctreeGet : public LLSpatialGroup::OctreeTraveler |
@@ -1618,6 +2251,8 @@ S32 LLSpatialPartition::getDrawables(const LLVector3& pos, F32 rad, | |||
1618 | 2251 | ||
1619 | S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) | 2252 | S32 LLSpatialPartition::getObjects(const LLVector3& pos, F32 rad, LLDrawable::drawable_set_t &results) |
1620 | { | 2253 | { |
2254 | LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0); | ||
2255 | group->rebound(); | ||
1621 | return getDrawables(pos, rad, results, FALSE); | 2256 | return getDrawables(pos, rad, results, FALSE); |
1622 | } | 2257 | } |
1623 | 2258 | ||
@@ -1626,182 +2261,363 @@ S32 LLSpatialPartition::getLights(const LLVector3& pos, F32 rad, LLDrawable::dra | |||
1626 | return getDrawables(pos, rad, results, TRUE); | 2261 | return getDrawables(pos, rad, results, TRUE); |
1627 | } | 2262 | } |
1628 | 2263 | ||
1629 | class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> | 2264 | void pushVerts(LLDrawInfo* params, U32 mask) |
1630 | { | 2265 | { |
1631 | public: | 2266 | params->mVertexBuffer->setBuffer(mask); |
1632 | LLOctreeRenderNonOccluded() {} | 2267 | U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); |
1633 | 2268 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, | |
1634 | virtual void traverse(const LLSpatialGroup::OctreeNode* node) | 2269 | GL_UNSIGNED_INT, indicesp+params->mOffset); |
2270 | } | ||
2271 | |||
2272 | void pushVerts(LLSpatialGroup* group, U32 mask) | ||
2273 | { | ||
2274 | LLDrawInfo* params = NULL; | ||
2275 | |||
2276 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) | ||
1635 | { | 2277 | { |
1636 | const LLSpatialGroup::OctreeState* state = node->getOctState(); | 2278 | for (std::vector<LLDrawInfo*>::iterator j = i->second.begin(); j != i->second.end(); ++j) |
1637 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | 2279 | { |
2280 | params = *j; | ||
2281 | pushVerts(params, mask); | ||
2282 | } | ||
2283 | } | ||
2284 | } | ||
2285 | |||
2286 | void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) | ||
2287 | { | ||
2288 | LLDrawInfo* params = NULL; | ||
2289 | |||
2290 | LLColor4 colors[] = { | ||
2291 | LLColor4::green, | ||
2292 | LLColor4::green1, | ||
2293 | LLColor4::green2, | ||
2294 | LLColor4::green3, | ||
2295 | LLColor4::green4, | ||
2296 | LLColor4::green5, | ||
2297 | LLColor4::green6 | ||
2298 | }; | ||
1638 | 2299 | ||
1639 | if (!group->isState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED)) | 2300 | static const U32 col_count = sizeof(colors)/sizeof(LLColor4); |
2301 | |||
2302 | U32 col = 0; | ||
2303 | |||
2304 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) | ||
2305 | { | ||
2306 | for (std::vector<LLDrawInfo*>::iterator j = i->second.begin(); j != i->second.end(); ++j) | ||
1640 | { | 2307 | { |
1641 | state->accept(this); | 2308 | params = *j; |
2309 | glColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); | ||
2310 | params->mVertexBuffer->setBuffer(mask); | ||
2311 | U32* indicesp = (U32*) params->mVertexBuffer->getIndicesPointer(); | ||
2312 | glDrawRangeElements(params->mParticle ? GL_POINTS : GL_TRIANGLES, params->mStart, params->mEnd, params->mCount, | ||
2313 | GL_UNSIGNED_INT, indicesp+params->mOffset); | ||
2314 | col = (col+1)%col_count; | ||
2315 | } | ||
2316 | } | ||
2317 | } | ||
1642 | 2318 | ||
1643 | for (U32 i = 0; i < state->getChildCount(); i++) | 2319 | void renderOctree(LLSpatialGroup* group) |
2320 | { | ||
2321 | //render solid object bounding box, color | ||
2322 | //coded by buffer usage and activity | ||
2323 | LLGLDepthTest depth(GL_TRUE, GL_FALSE); | ||
2324 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
2325 | LLVector4 col; | ||
2326 | if (group->mBuilt > 0.f) | ||
2327 | { | ||
2328 | group->mBuilt -= 2.f * gFrameIntervalSeconds; | ||
2329 | if (group->mBufferUsage == GL_STATIC_DRAW_ARB) | ||
2330 | { | ||
2331 | col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); | ||
2332 | } | ||
2333 | else | ||
2334 | { | ||
2335 | col.setVec(0.1f,0.1f,1,0.1f); | ||
2336 | //col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f); | ||
2337 | } | ||
2338 | |||
2339 | if (group->mBufferUsage != GL_STATIC_DRAW_ARB) | ||
2340 | { | ||
2341 | if (group->mBufferUsage == GL_DYNAMIC_DRAW_ARB) | ||
1644 | { | 2342 | { |
1645 | traverse(state->getChild(i)); | 2343 | glColor4f(1,0,0,group->mBuilt); |
1646 | } | 2344 | } |
1647 | 2345 | else | |
1648 | /*if (state->getElementCount() == 0) | ||
1649 | { | 2346 | { |
1650 | return; | 2347 | glColor4f(1,1,0,group->mBuilt); |
1651 | }*/ | 2348 | } |
1652 | 2349 | ||
1653 | //draw tight fit bounding box for spatial group | 2350 | LLGLDepthTest gl_depth(FALSE, FALSE); |
1654 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) | 2351 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); |
2352 | for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) | ||
1655 | { | 2353 | { |
1656 | if (node->getElementCount() == 0) | 2354 | LLDrawable* drawable = *i; |
1657 | { | 2355 | for (S32 j = 0; j < drawable->getNumFaces(); j++) |
1658 | return; | ||
1659 | } | ||
1660 | |||
1661 | if (node->hasLeafState()) | ||
1662 | { | ||
1663 | glColor4f(1,1,1,1); | ||
1664 | } | ||
1665 | else | ||
1666 | { | 2356 | { |
1667 | glColor4f(0,1,1,1); | 2357 | LLFace* face = drawable->getFace(j); |
2358 | if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f && face->mVertexBuffer.notNull()) | ||
2359 | { | ||
2360 | face->mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); | ||
2361 | //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, | ||
2362 | // (face->mExtents[1]-face->mExtents[0])*0.5f); | ||
2363 | glDrawElements(GL_TRIANGLES, face->getIndicesCount(), GL_UNSIGNED_INT, | ||
2364 | ((U32*) face->mVertexBuffer->getIndicesPointer())+face->getIndicesStart()); | ||
2365 | } | ||
1668 | } | 2366 | } |
2367 | } | ||
2368 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
2369 | } | ||
2370 | } | ||
2371 | else | ||
2372 | { | ||
2373 | if (group->mBufferUsage == GL_STATIC_DRAW_ARB && !group->getData().empty() | ||
2374 | && group->mSpatialPartition->mRenderByGroup) | ||
2375 | { | ||
2376 | col.setVec(0.8f, 0.4f, 0.1f, 0.1f); | ||
2377 | } | ||
2378 | else | ||
2379 | { | ||
2380 | col.setVec(0.1f, 0.1f, 1.f, 0.1f); | ||
2381 | } | ||
2382 | } | ||
1669 | 2383 | ||
2384 | glColor4fv(col.mV); | ||
2385 | drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); | ||
2386 | glDepthMask(GL_TRUE); | ||
2387 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
1670 | 2388 | ||
1671 | LLVector3 pos; | 2389 | //draw opaque outline |
1672 | LLVector3 size; | 2390 | glColor4f(col.mV[0], col.mV[1], col.mV[2], 1.f); |
1673 | 2391 | drawBoxOutline(group->mObjectBounds[0], group->mObjectBounds[1]); | |
1674 | pos = group->mObjectBounds[0]; | ||
1675 | size = group->mObjectBounds[1]; | ||
1676 | |||
1677 | LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); | ||
1678 | LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1)); | ||
1679 | LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); | ||
1680 | LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); | ||
1681 | |||
1682 | glBegin(GL_LINE_LOOP); //top | ||
1683 | glVertex3fv((pos+v1).mV); | ||
1684 | glVertex3fv((pos+v2).mV); | ||
1685 | glVertex3fv((pos+v3).mV); | ||
1686 | glVertex3fv((pos+v4).mV); | ||
1687 | glEnd(); | ||
1688 | |||
1689 | glBegin(GL_LINE_LOOP); //bottom | ||
1690 | glVertex3fv((pos-v1).mV); | ||
1691 | glVertex3fv((pos-v2).mV); | ||
1692 | glVertex3fv((pos-v3).mV); | ||
1693 | glVertex3fv((pos-v4).mV); | ||
1694 | glEnd(); | ||
1695 | |||
1696 | |||
1697 | glBegin(GL_LINES); | ||
1698 | |||
1699 | //right | ||
1700 | glVertex3fv((pos+v1).mV); | ||
1701 | glVertex3fv((pos-v3).mV); | ||
1702 | |||
1703 | glVertex3fv((pos+v4).mV); | ||
1704 | glVertex3fv((pos-v2).mV); | ||
1705 | |||
1706 | //left | ||
1707 | glVertex3fv((pos+v2).mV); | ||
1708 | glVertex3fv((pos-v4).mV); | ||
1709 | |||
1710 | glVertex3fv((pos+v3).mV); | ||
1711 | glVertex3fv((pos-v1).mV); | ||
1712 | 2392 | ||
1713 | glEnd(); | 2393 | if (group->mOctreeNode->hasLeafState()) |
2394 | { | ||
2395 | glColor4f(1,1,1,1); | ||
2396 | } | ||
2397 | else | ||
2398 | { | ||
2399 | glColor4f(0,1,1,1); | ||
2400 | } | ||
2401 | |||
2402 | drawBoxOutline(group->mBounds[0],group->mBounds[1]); | ||
2403 | |||
2404 | // LLSpatialGroup::OctreeNode* node = group->mOctreeNode; | ||
2405 | // glColor4f(0,1,0,1); | ||
2406 | // drawBoxOutline(LLVector3(node->getCenter()), LLVector3(node->getSize())); | ||
2407 | } | ||
1714 | 2408 | ||
1715 | LLVector3 nc = LLVector3(node->getCenter()); | 2409 | void renderVisibility(LLSpatialGroup* group) |
1716 | LLVector3 ns = LLVector3(node->getSize()); | 2410 | { |
2411 | LLGLEnable blend(GL_BLEND); | ||
2412 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2413 | LLGLEnable cull(GL_CULL_FACE); | ||
2414 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||
2415 | { | ||
2416 | LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); | ||
2417 | glColor4f(0, 0.5f, 0, 0.5f); | ||
2418 | pushVerts(group, LLVertexBuffer::MAP_VERTEX); | ||
2419 | } | ||
1717 | 2420 | ||
1718 | LLVector3 nv1 = ns.scaledVec(LLVector3( 1, 1,1)); | 2421 | { |
1719 | LLVector3 nv2 = ns.scaledVec(LLVector3(-1, 1,1)); | 2422 | LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); |
1720 | LLVector3 nv3 = ns.scaledVec(LLVector3(-1,-1,1)); | 2423 | pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); |
1721 | LLVector3 nv4 = ns.scaledVec(LLVector3( 1,-1,1)); | ||
1722 | 2424 | ||
1723 | 2425 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | |
1724 | 2426 | ||
1725 | /*if (node->getElementCount() > 0) | 2427 | pushVertsColorCoded(group, LLVertexBuffer::MAP_VERTEX); |
1726 | { | 2428 | } |
1727 | //spokes | 2429 | } |
1728 | glColor4f(1,1,0,1); | ||
1729 | glVertex3fv(pos.mV); | ||
1730 | glColor4f(1,1,0,0); | ||
1731 | glVertex3fv(nc.mV); | ||
1732 | |||
1733 | glColor4f(1,1,0,1); glVertex3fv((pos+v1).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1734 | glColor4f(1,1,0,1); glVertex3fv((pos-v1).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1735 | glColor4f(1,1,0,1); glVertex3fv((pos+v2).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1736 | glColor4f(1,1,0,1); glVertex3fv((pos-v2).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1737 | glColor4f(1,1,0,1); glVertex3fv((pos+v3).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1738 | glColor4f(1,1,0,1); glVertex3fv((pos-v3).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1739 | glColor4f(1,1,0,1); glVertex3fv((pos+v4).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1740 | glColor4f(1,1,0,1); glVertex3fv((pos-v4).mV); glColor4f(1,1,0,0); glVertex3fv(pos.mV); | ||
1741 | }*/ | ||
1742 | 2430 | ||
1743 | 2431 | void renderBoundingBox(LLDrawable* drawable) | |
2432 | { | ||
2433 | if (drawable->isSpatialBridge()) | ||
2434 | { | ||
2435 | glColor4f(1,0.5f,0,1); | ||
2436 | } | ||
2437 | else if (drawable->getVOVolume()) | ||
2438 | { | ||
2439 | if (drawable->isRoot()) | ||
2440 | { | ||
2441 | glColor4f(1,1,0,1); | ||
2442 | } | ||
2443 | else | ||
2444 | { | ||
2445 | glColor4f(0,1,0,1); | ||
2446 | } | ||
2447 | } | ||
2448 | else if (drawable->getVObj()) | ||
2449 | { | ||
2450 | switch (drawable->getVObj()->getPCode()) | ||
2451 | { | ||
2452 | case LLViewerObject::LL_VO_SURFACE_PATCH: | ||
2453 | glColor4f(0,1,1,1); | ||
2454 | break; | ||
2455 | case LLViewerObject::LL_VO_CLOUDS: | ||
2456 | glColor4f(0.5f,0.5f,0.5f,1.0f); | ||
2457 | break; | ||
2458 | case LLViewerObject::LL_VO_PART_GROUP: | ||
2459 | glColor4f(0,0,1,1); | ||
2460 | break; | ||
2461 | case LLViewerObject::LL_VO_WATER: | ||
2462 | glColor4f(0,0.5f,1,1); | ||
2463 | break; | ||
2464 | case LL_PCODE_LEGACY_TREE: | ||
2465 | glColor4f(0,0.5f,0,1); | ||
2466 | default: | ||
2467 | glColor4f(1,0,1,1); | ||
2468 | break; | ||
2469 | } | ||
2470 | } | ||
2471 | else | ||
2472 | { | ||
2473 | glColor4f(1,0,0,1); | ||
2474 | } | ||
1744 | 2475 | ||
1745 | /*glColor4f(0,1,0,1); | 2476 | const LLVector3* ext; |
1746 | glBegin(GL_LINE_LOOP); //top | 2477 | LLVector3 pos, size; |
1747 | glVertex3fv((nc+nv1).mV); | ||
1748 | glVertex3fv((nc+nv2).mV); | ||
1749 | glVertex3fv((nc+nv3).mV); | ||
1750 | glVertex3fv((nc+nv4).mV); | ||
1751 | glEnd(); | ||
1752 | 2478 | ||
1753 | glBegin(GL_LINE_LOOP); //bottom | 2479 | //render face bounding boxes |
1754 | glVertex3fv((nc-nv1).mV); | 2480 | for (S32 i = 0; i < drawable->getNumFaces(); i++) |
1755 | glVertex3fv((nc-nv2).mV); | 2481 | { |
1756 | glVertex3fv((nc-nv3).mV); | 2482 | LLFace* facep = drawable->getFace(i); |
1757 | glVertex3fv((nc-nv4).mV); | ||
1758 | glEnd(); | ||
1759 | 2483 | ||
2484 | ext = facep->mExtents; | ||
1760 | 2485 | ||
1761 | glBegin(GL_LINES); | 2486 | if (ext[0].isExactlyZero() && ext[1].isExactlyZero()) |
2487 | { | ||
2488 | continue; | ||
2489 | } | ||
2490 | pos = (ext[0] + ext[1]) * 0.5f; | ||
2491 | size = (ext[1] - ext[0]) * 0.5f; | ||
2492 | drawBoxOutline(pos,size); | ||
2493 | } | ||
1762 | 2494 | ||
1763 | //right | 2495 | //render drawable bounding box |
1764 | glVertex3fv((nc+nv1).mV); | 2496 | ext = drawable->getSpatialExtents(); |
1765 | glVertex3fv((nc-nv3).mV); | ||
1766 | |||
1767 | glVertex3fv((nc+nv4).mV); | ||
1768 | glVertex3fv((nc-nv2).mV); | ||
1769 | 2497 | ||
1770 | //left | 2498 | pos = (ext[0] + ext[1]) * 0.5f; |
1771 | glVertex3fv((nc+nv2).mV); | 2499 | size = (ext[1] - ext[0]) * 0.5f; |
1772 | glVertex3fv((nc-nv4).mV); | 2500 | |
2501 | drawBoxOutline(pos,size); | ||
2502 | } | ||
1773 | 2503 | ||
1774 | glVertex3fv((nc+nv3).mV); | 2504 | void renderTexturePriority(LLDrawable* drawable) |
1775 | glVertex3fv((nc-nv1).mV); | 2505 | { |
1776 | glEnd();*/ | 2506 | for (int face=0; face<drawable->getNumFaces(); ++face) |
2507 | { | ||
2508 | LLFace *facep = drawable->getFace(face); | ||
2509 | |||
2510 | LLVector4 cold(0,0,0.25f); | ||
2511 | LLVector4 hot(1,0.25f,0.25f); | ||
2512 | |||
2513 | LLVector4 boost_cold(0,0,0,0); | ||
2514 | LLVector4 boost_hot(0,1,0,1); | ||
2515 | |||
2516 | LLGLDisable blend(GL_BLEND); | ||
2517 | |||
2518 | //LLViewerImage* imagep = facep->getTexture(); | ||
2519 | //if (imagep) | ||
2520 | { | ||
2521 | |||
2522 | //F32 vsize = LLVOVolume::getTextureVirtualSize(facep); | ||
2523 | //F32 vsize = imagep->mMaxVirtualSize; | ||
2524 | F32 vsize = facep->getPixelArea(); | ||
1777 | 2525 | ||
1778 | glLineWidth(1); | 2526 | if (vsize > sCurMaxTexPriority) |
1779 | 2527 | { | |
1780 | glDepthMask(GL_FALSE); | 2528 | sCurMaxTexPriority = vsize; |
1781 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
1782 | glColor4f(0.1f,0.1f,1,0.1f); | ||
1783 | drawBox(group->mObjectBounds[0], group->mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); | ||
1784 | glDepthMask(GL_TRUE); | ||
1785 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
1786 | } | 2529 | } |
2530 | |||
2531 | F32 t = vsize/sLastMaxTexPriority; | ||
2532 | |||
2533 | LLVector4 col = lerp(cold, hot, t); | ||
2534 | glColor4fv(col.mV); | ||
1787 | } | 2535 | } |
1788 | /*else | 2536 | //else |
2537 | //{ | ||
2538 | // glColor4f(1,0,1,1); | ||
2539 | //} | ||
2540 | |||
2541 | |||
2542 | |||
2543 | LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; | ||
2544 | LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); | ||
2545 | drawBox(center, size); | ||
2546 | |||
2547 | /*S32 boost = imagep->getBoostLevel(); | ||
2548 | if (boost) | ||
2549 | { | ||
2550 | F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); | ||
2551 | LLVector4 col = lerp(boost_cold, boost_hot, t); | ||
2552 | LLGLEnable blend_on(GL_BLEND); | ||
2553 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
2554 | glColor4fv(col.mV); | ||
2555 | drawBox(center, size); | ||
2556 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2557 | }*/ | ||
2558 | } | ||
2559 | } | ||
2560 | |||
2561 | void renderPoints(LLDrawable* drawablep) | ||
2562 | { | ||
2563 | LLGLDepthTest depth(GL_FALSE, GL_FALSE); | ||
2564 | glBegin(GL_POINTS); | ||
2565 | glColor3f(1,1,1); | ||
2566 | LLVector3 center(drawablep->getPositionGroup()); | ||
2567 | for (S32 i = 0; i < drawablep->getNumFaces(); i++) | ||
2568 | { | ||
2569 | glVertex3fv(drawablep->getFace(i)->mCenterLocal.mV); | ||
2570 | } | ||
2571 | glEnd(); | ||
2572 | } | ||
2573 | |||
2574 | void renderTextureAnim(LLDrawInfo* params) | ||
2575 | { | ||
2576 | if (!params->mTextureMatrix) | ||
2577 | { | ||
2578 | return; | ||
2579 | } | ||
2580 | |||
2581 | LLGLEnable blend(GL_BLEND); | ||
2582 | glColor4f(1,1,0,0.5f); | ||
2583 | pushVerts(params, LLVertexBuffer::MAP_VERTEX); | ||
2584 | } | ||
2585 | |||
2586 | class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable> | ||
2587 | { | ||
2588 | public: | ||
2589 | LLOctreeRenderNonOccluded() {} | ||
2590 | |||
2591 | virtual void traverse(const LLSpatialGroup::OctreeNode* node) | ||
2592 | { | ||
2593 | const LLSpatialGroup::OctreeState* state = node->getOctState(); | ||
2594 | LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0); | ||
2595 | |||
2596 | |||
2597 | if ((!gPipeline.sUseOcclusion || !group->isState(LLSpatialGroup::OCCLUDED)) && | ||
2598 | !group->isState(LLSpatialGroup::CULLED)) | ||
1789 | { | 2599 | { |
1790 | //occlusion paranoia check | 2600 | state->accept(this); |
1791 | const LLSpatialGroup::OctreeNode* parent = node; | 2601 | |
1792 | while (parent != NULL) | 2602 | for (U32 i = 0; i < state->getChildCount(); i++) |
1793 | { | 2603 | { |
1794 | LLSpatialGroup* grp = (LLSpatialGroup*) parent->getListener(0); | 2604 | traverse(state->getChild(i)); |
1795 | if (grp->isState(LLSpatialGroup::ACTIVE_OCCLUSION)) | 2605 | } |
1796 | { | 2606 | |
1797 | return; | 2607 | //draw tight fit bounding boxes for spatial group |
1798 | } | 2608 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) |
1799 | parent = (const LLSpatialGroup::OctreeNode*) parent->getParent(); | 2609 | { |
2610 | renderOctree(group); | ||
1800 | } | 2611 | } |
1801 | 2612 | ||
1802 | glColor4f(1,0,1,1); | 2613 | //render visibility wireframe |
1803 | drawBox(group->mBounds[0], group->mBounds[1]); | 2614 | if (group->mSpatialPartition->mRenderByGroup && |
1804 | }*/ | 2615 | gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && |
2616 | !group->isState(LLSpatialGroup::GEOM_DIRTY)) | ||
2617 | { | ||
2618 | renderVisibility(group); | ||
2619 | } | ||
2620 | } | ||
1805 | } | 2621 | } |
1806 | 2622 | ||
1807 | virtual void visit(const LLSpatialGroup::OctreeState* branch) | 2623 | virtual void visit(const LLSpatialGroup::OctreeState* branch) |
@@ -1816,276 +2632,37 @@ public: | |||
1816 | LLVector3 nodeCenter = group->mBounds[0]; | 2632 | LLVector3 nodeCenter = group->mBounds[0]; |
1817 | LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); | 2633 | LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); |
1818 | 2634 | ||
1819 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) | ||
1820 | { | ||
1821 | glBegin(GL_LINES); | ||
1822 | glColor4f(1,0.5f,0,1); | ||
1823 | glVertex3fv(nodeCenter.mV); | ||
1824 | glColor4f(0,1,1,0); | ||
1825 | glVertex3fv(octCenter.mV); | ||
1826 | glEnd(); | ||
1827 | } | ||
1828 | |||
1829 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) | 2635 | for (LLSpatialGroup::OctreeState::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) |
1830 | { | 2636 | { |
1831 | LLDrawable* drawable = *i; | 2637 | LLDrawable* drawable = *i; |
1832 | 2638 | ||
1833 | if (drawable->isSpatialBridge()) | ||
1834 | { | ||
1835 | LLSpatialBridge* bridge = (LLSpatialBridge*) drawable; | ||
1836 | glPushMatrix(); | ||
1837 | glMultMatrixf((F32*)bridge->mDrawable->getWorldMatrix().mMatrix); | ||
1838 | traverse(bridge->mOctree); | ||
1839 | glPopMatrix(); | ||
1840 | } | ||
1841 | |||
1842 | if (!drawable->isVisible()) | ||
1843 | { | ||
1844 | continue; | ||
1845 | } | ||
1846 | |||
1847 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) | 2639 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) |
1848 | { | 2640 | { |
1849 | if (drawable->isSpatialBridge()) | 2641 | renderBoundingBox(drawable); |
1850 | { | ||
1851 | glColor4f(1,0.5f,0,1); | ||
1852 | } | ||
1853 | else if (drawable->getVOVolume()) | ||
1854 | { | ||
1855 | if (drawable->isRoot()) | ||
1856 | { | ||
1857 | glColor4f(1,1,0,1); | ||
1858 | } | ||
1859 | else | ||
1860 | { | ||
1861 | glColor4f(0,1,0,1); | ||
1862 | } | ||
1863 | } | ||
1864 | else if (drawable->getVObj()) | ||
1865 | { | ||
1866 | switch (drawable->getVObj()->getPCode()) | ||
1867 | { | ||
1868 | case LLViewerObject::LL_VO_SURFACE_PATCH: | ||
1869 | glColor4f(0,1,1,1); | ||
1870 | break; | ||
1871 | case LLViewerObject::LL_VO_CLOUDS: | ||
1872 | glColor4f(0.5f,0.5f,0.5f,1.0f); | ||
1873 | break; | ||
1874 | case LLViewerObject::LL_VO_PART_GROUP: | ||
1875 | glColor4f(0,0,1,1); | ||
1876 | break; | ||
1877 | case LLViewerObject::LL_VO_WATER: | ||
1878 | glColor4f(0,0.5f,1,1); | ||
1879 | break; | ||
1880 | case LL_PCODE_LEGACY_TREE: | ||
1881 | glColor4f(0,0.5f,0,1); | ||
1882 | default: | ||
1883 | glColor4f(1,0,1,1); | ||
1884 | break; | ||
1885 | } | ||
1886 | } | ||
1887 | else | ||
1888 | { | ||
1889 | glColor4f(1,0,0,1); | ||
1890 | } | ||
1891 | |||
1892 | |||
1893 | const LLVector3* ext = drawable->getSpatialExtents(); | ||
1894 | |||
1895 | LLVector3 pos = (ext[0] + ext[1]) * 0.5f; | ||
1896 | LLVector3 size = (ext[1] - ext[0]) * 0.5f; | ||
1897 | |||
1898 | LLVector3 v1 = size.scaledVec(LLVector3( 1, 1,1)); | ||
1899 | LLVector3 v2 = size.scaledVec(LLVector3(-1, 1,1)); | ||
1900 | LLVector3 v3 = size.scaledVec(LLVector3(-1,-1,1)); | ||
1901 | LLVector3 v4 = size.scaledVec(LLVector3( 1,-1,1)); | ||
1902 | |||
1903 | glBegin(GL_LINE_LOOP); //top | ||
1904 | glVertex3fv((pos+v1).mV); | ||
1905 | glVertex3fv((pos+v2).mV); | ||
1906 | glVertex3fv((pos+v3).mV); | ||
1907 | glVertex3fv((pos+v4).mV); | ||
1908 | glEnd(); | ||
1909 | |||
1910 | glBegin(GL_LINE_LOOP); //bottom | ||
1911 | glVertex3fv((pos-v1).mV); | ||
1912 | glVertex3fv((pos-v2).mV); | ||
1913 | glVertex3fv((pos-v3).mV); | ||
1914 | glVertex3fv((pos-v4).mV); | ||
1915 | glEnd(); | ||
1916 | |||
1917 | |||
1918 | glBegin(GL_LINES); | ||
1919 | |||
1920 | //right | ||
1921 | glVertex3fv((pos+v1).mV); | ||
1922 | glVertex3fv((pos-v3).mV); | ||
1923 | |||
1924 | glVertex3fv((pos+v4).mV); | ||
1925 | glVertex3fv((pos-v2).mV); | ||
1926 | |||
1927 | //left | ||
1928 | glVertex3fv((pos+v2).mV); | ||
1929 | glVertex3fv((pos-v4).mV); | ||
1930 | |||
1931 | glVertex3fv((pos+v3).mV); | ||
1932 | glVertex3fv((pos-v1).mV); | ||
1933 | |||
1934 | glEnd(); | ||
1935 | |||
1936 | //render space partition trace | ||
1937 | glBegin(GL_LINE_STRIP); | ||
1938 | glColor4f(1,0,0,1); | ||
1939 | glVertex3fv(pos.mV); | ||
1940 | glColor4f(0,1,0,1); | ||
1941 | glVertex3dv(drawable->getPositionGroup().mdV); | ||
1942 | glColor4f(0,0,1,1); | ||
1943 | glVertex3fv(nodeCenter.mV); | ||
1944 | glColor4f(1,1,0,1); | ||
1945 | glVertex3fv(octCenter.mV); | ||
1946 | glEnd(); | ||
1947 | } | 2642 | } |
1948 | 2643 | ||
1949 | if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_CHAINS | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) | 2644 | if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) |
1950 | { | 2645 | { |
1951 | glLineWidth(3); | 2646 | renderTexturePriority(drawable); |
1952 | |||
1953 | for (int face=0; face<drawable->getNumFaces(); ++face) | ||
1954 | { | ||
1955 | LLFace *facep = drawable->getFace(face); | ||
1956 | |||
1957 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_FACE_CHAINS)) | ||
1958 | { | ||
1959 | LLGLDepthTest depth(GL_FALSE); | ||
1960 | if (facep->mNextFace) | ||
1961 | { | ||
1962 | glBegin(GL_LINE_STRIP); | ||
1963 | |||
1964 | if (facep->isState(LLFace::GLOBAL)) | ||
1965 | { | ||
1966 | glColor4f(0,1,0,1); | ||
1967 | } | ||
1968 | else | ||
1969 | { | ||
1970 | glColor4f(1,0.5f,0.25f,1); | ||
1971 | } | ||
1972 | |||
1973 | if (drawable->isActive()) | ||
1974 | { | ||
1975 | glVertex3fv(facep->mCenterLocal.mV); | ||
1976 | glVertex3fv(facep->mNextFace->mCenterLocal.mV); | ||
1977 | } | ||
1978 | else | ||
1979 | { | ||
1980 | glVertex3fv(facep->mCenterAgent.mV); | ||
1981 | glVertex3fv(facep->mNextFace->mCenterAgent.mV); | ||
1982 | } | ||
1983 | |||
1984 | glEnd(); | ||
1985 | } | ||
1986 | else | ||
1987 | { | ||
1988 | glPointSize(5); | ||
1989 | glBegin(GL_POINTS); | ||
1990 | |||
1991 | if (!facep->isState(LLFace::GLOBAL)) | ||
1992 | { | ||
1993 | glColor4f(1,0.75f,0,1); | ||
1994 | glVertex3fv(facep->mCenterLocal.mV); | ||
1995 | } | ||
1996 | else | ||
1997 | { | ||
1998 | glColor4f(0,0.75f,1,1); | ||
1999 | glVertex3fv(facep->mCenterAgent.mV); | ||
2000 | } | ||
2001 | |||
2002 | glEnd(); | ||
2003 | glPointSize(1); | ||
2004 | } | ||
2005 | } | ||
2006 | |||
2007 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) | ||
2008 | { | ||
2009 | LLVector4 cold(0,0,0.25f); | ||
2010 | LLVector4 hot(1,0.25f,0.25f); | ||
2011 | |||
2012 | LLVector4 boost_cold(0,0,0,0); | ||
2013 | LLVector4 boost_hot(0,1,0,1); | ||
2014 | |||
2015 | LLGLDisable blend(GL_BLEND); | ||
2016 | |||
2017 | LLViewerImage* imagep = facep->getTexture(); | ||
2018 | if (imagep) | ||
2019 | { | ||
2020 | |||
2021 | //F32 vsize = LLVOVolume::getTextureVirtualSize(facep); | ||
2022 | F32 vsize = imagep->mMaxVirtualSize; | ||
2023 | |||
2024 | if (vsize > sCurMaxTexPriority) | ||
2025 | { | ||
2026 | sCurMaxTexPriority = vsize; | ||
2027 | } | ||
2028 | |||
2029 | F32 t = vsize/sLastMaxTexPriority; | ||
2030 | |||
2031 | LLVector4 col = lerp(cold, hot, t); | ||
2032 | glColor4fv(col.mV); | ||
2033 | } | ||
2034 | else | ||
2035 | { | ||
2036 | glColor4f(1,0,1,1); | ||
2037 | } | ||
2038 | |||
2039 | LLVector3 center = (facep->mExtents[1]+facep->mExtents[0])*0.5f; | ||
2040 | LLVector3 size = (facep->mExtents[1]-facep->mExtents[0])*0.5f + LLVector3(0.01f, 0.01f, 0.01f); | ||
2041 | drawBox(center, size); | ||
2042 | |||
2043 | S32 boost = imagep->getBoostLevel(); | ||
2044 | if (boost) | ||
2045 | { | ||
2046 | F32 t = (F32) boost / (F32) (LLViewerImage::BOOST_MAX_LEVEL-1); | ||
2047 | LLVector4 col = lerp(boost_cold, boost_hot, t); | ||
2048 | LLGLEnable blend_on(GL_BLEND); | ||
2049 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | ||
2050 | glColor4fv(col.mV); | ||
2051 | drawBox(center, size); | ||
2052 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2053 | } | ||
2054 | |||
2055 | } | ||
2056 | } | ||
2057 | } | 2647 | } |
2058 | 2648 | ||
2059 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) | 2649 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_POINTS)) |
2060 | { | 2650 | { |
2061 | glPointSize(4); | 2651 | renderPoints(drawable); |
2062 | glColor4f(1,1,1,1); | 2652 | } |
2063 | glBegin(GL_POINTS); | 2653 | } |
2064 | S32 num_faces = drawable->getNumFaces(); | 2654 | |
2065 | for (S32 i = 0; i < num_faces; i++) | 2655 | for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) |
2656 | { | ||
2657 | std::vector<LLDrawInfo*>& draw_vec = i->second; | ||
2658 | for (std::vector<LLDrawInfo*>::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) | ||
2659 | { | ||
2660 | LLDrawInfo* draw_info = *j; | ||
2661 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)) | ||
2066 | { | 2662 | { |
2067 | LLStrider<LLVector3> vertices; | 2663 | renderTextureAnim(draw_info); |
2068 | drawable->getFace(i)->getVertices(vertices); | ||
2069 | |||
2070 | LLFace* face = drawable->getFace(i); | ||
2071 | |||
2072 | for (S32 v = 0; v < (S32)drawable->getFace(i)->getGeomCount(); v++) | ||
2073 | { | ||
2074 | if (!face->getDrawable()->isActive()) | ||
2075 | { | ||
2076 | //glVertex3fv(vertices[v].mV); | ||
2077 | } | ||
2078 | else | ||
2079 | { | ||
2080 | glVertex3fv((vertices[v]*face->getRenderMatrix()).mV); | ||
2081 | } | ||
2082 | } | ||
2083 | } | 2664 | } |
2084 | glEnd(); | ||
2085 | glPointSize(1); | ||
2086 | } | 2665 | } |
2087 | |||
2088 | glLineWidth(1); | ||
2089 | } | 2666 | } |
2090 | } | 2667 | } |
2091 | }; | 2668 | }; |
@@ -2096,8 +2673,8 @@ void LLSpatialPartition::renderDebug() | |||
2096 | LLPipeline::RENDER_DEBUG_OCCLUSION | | 2673 | LLPipeline::RENDER_DEBUG_OCCLUSION | |
2097 | LLPipeline::RENDER_DEBUG_BBOXES | | 2674 | LLPipeline::RENDER_DEBUG_BBOXES | |
2098 | LLPipeline::RENDER_DEBUG_POINTS | | 2675 | LLPipeline::RENDER_DEBUG_POINTS | |
2099 | LLPipeline::RENDER_DEBUG_FACE_CHAINS | | 2676 | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | |
2100 | LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) | 2677 | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM)) |
2101 | { | 2678 | { |
2102 | return; | 2679 | return; |
2103 | } | 2680 | } |
@@ -2105,7 +2682,7 @@ void LLSpatialPartition::renderDebug() | |||
2105 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) | 2682 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) |
2106 | { | 2683 | { |
2107 | //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); | 2684 | //sLastMaxTexPriority = lerp(sLastMaxTexPriority, sCurMaxTexPriority, gFrameIntervalSeconds); |
2108 | sLastMaxTexPriority = sCurMaxTexPriority; | 2685 | sLastMaxTexPriority = (F32) gCamera->getScreenPixelArea(); |
2109 | sCurMaxTexPriority = 0.f; | 2686 | sCurMaxTexPriority = 0.f; |
2110 | } | 2687 | } |
2111 | 2688 | ||
@@ -2119,78 +2696,50 @@ void LLSpatialPartition::renderDebug() | |||
2119 | 2696 | ||
2120 | LLOctreeRenderNonOccluded render_debug; | 2697 | LLOctreeRenderNonOccluded render_debug; |
2121 | render_debug.traverse(mOctree); | 2698 | render_debug.traverse(mOctree); |
2122 | |||
2123 | LLGLDisable cull_face(GL_CULL_FACE); | ||
2124 | 2699 | ||
2125 | { | 2700 | LLGLDisable cull_face(GL_CULL_FACE); |
2126 | LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); | ||
2127 | |||
2128 | //draw frustum | ||
2129 | glColor4f(0,0,1,0.5f); | ||
2130 | glBegin(GL_QUADS); | ||
2131 | //glVertex3fv(gCamera->mAgentFrustum[0].mV); | ||
2132 | //glVertex3fv(gCamera->mAgentFrustum[1].mV); | ||
2133 | //glVertex3fv(gCamera->mAgentFrustum[2].mV); | ||
2134 | //glVertex3fv(gCamera->mAgentFrustum[3].mV); | ||
2135 | 2701 | ||
2136 | //glVertex3fv(gCamera->mAgentFrustum[4].mV); | 2702 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && !mOccludedList.empty() && |
2137 | //glVertex3fv(gCamera->mAgentFrustum[5].mV); | 2703 | mOcclusionIndices.notNull()) |
2138 | //glVertex3fv(gCamera->mAgentFrustum[6].mV); | ||
2139 | //glVertex3fv(gCamera->mAgentFrustum[7].mV); | ||
2140 | |||
2141 | glVertex3fv(gCamera->mAgentFrustum[0].mV); | ||
2142 | glVertex3fv(gCamera->mAgentFrustum[1].mV); | ||
2143 | glVertex3fv(gCamera->mAgentFrustum[5].mV); | ||
2144 | glVertex3fv(gCamera->mAgentFrustum[4].mV); | ||
2145 | |||
2146 | glVertex3fv(gCamera->mAgentFrustum[1].mV); | ||
2147 | glVertex3fv(gCamera->mAgentFrustum[2].mV); | ||
2148 | glVertex3fv(gCamera->mAgentFrustum[6].mV); | ||
2149 | glVertex3fv(gCamera->mAgentFrustum[5].mV); | ||
2150 | |||
2151 | glVertex3fv(gCamera->mAgentFrustum[2].mV); | ||
2152 | glVertex3fv(gCamera->mAgentFrustum[3].mV); | ||
2153 | glVertex3fv(gCamera->mAgentFrustum[7].mV); | ||
2154 | glVertex3fv(gCamera->mAgentFrustum[6].mV); | ||
2155 | |||
2156 | glVertex3fv(gCamera->mAgentFrustum[3].mV); | ||
2157 | glVertex3fv(gCamera->mAgentFrustum[0].mV); | ||
2158 | glVertex3fv(gCamera->mAgentFrustum[4].mV); | ||
2159 | glVertex3fv(gCamera->mAgentFrustum[7].mV); | ||
2160 | |||
2161 | glEnd(); | ||
2162 | } | ||
2163 | |||
2164 | if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) | ||
2165 | { | 2704 | { |
2166 | LLGLDisable fog(GL_FOG); | 2705 | LLGLDisable fog(GL_FOG); |
2167 | LLGLDepthTest gls_depth(GL_FALSE); | 2706 | LLGLDepthTest gls_depth(GL_FALSE); |
2168 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); | 2707 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); |
2708 | mOcclusionIndices->setBuffer(0); | ||
2709 | U32* indicesp = (U32*) mOcclusionIndices->getIndicesPointer(); | ||
2710 | |||
2711 | LLGLEnable blend(GL_BLEND); | ||
2712 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | ||
2713 | LLGLEnable cull(GL_CULL_FACE); | ||
2714 | glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); | ||
2169 | 2715 | ||
2170 | for (std::vector<LLSpatialGroup*>::iterator i = mOccludedList.begin(); i != mOccludedList.end(); ++i) | 2716 | for (U32 i = 0; i < mOccludedList.size(); i++) |
2171 | { //draw occluded nodes | 2717 | { //draw occluded nodes |
2172 | LLSpatialGroup* node = *i; | 2718 | LLSpatialGroup* node = mOccludedList[i]; |
2173 | if (node->isDead()) | 2719 | if (node->isDead() || |
2720 | !node->isState(LLSpatialGroup::OCCLUDED) || | ||
2721 | node->mOcclusionVerts.isNull()) | ||
2174 | { | 2722 | { |
2175 | continue; | 2723 | continue; |
2176 | } | 2724 | } |
2177 | if (!node->isState(LLSpatialGroup::OCCLUDED)) | 2725 | |
2726 | node->mOcclusionVerts->setBuffer(LLVertexBuffer::MAP_VERTEX); | ||
2178 | { | 2727 | { |
2179 | continue; | 2728 | LLGLDepthTest depth_under(GL_TRUE, GL_FALSE, GL_GREATER); |
2729 | glColor4f(0.5, 0.5f, 0, 0.25f); | ||
2730 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, | ||
2731 | GL_UNSIGNED_INT, indicesp); | ||
2180 | } | 2732 | } |
2181 | else | 2733 | |
2182 | { | 2734 | { |
2183 | glColor4f(0.25f,0.125f,0.1f,0.125f); | 2735 | LLGLDepthTest depth_over(GL_TRUE, GL_FALSE, GL_LEQUAL); |
2736 | glColor4f(0.0,1.0f,1.0f,1.0f); | ||
2737 | glDrawRangeElements(GL_TRIANGLES, 0, 7, 36, | ||
2738 | GL_UNSIGNED_INT, indicesp); | ||
2184 | } | 2739 | } |
2185 | LLVector3 c; | ||
2186 | LLVector3 r; | ||
2187 | |||
2188 | c = node->mBounds[0]; | ||
2189 | r = node->mBounds[1]*SG_OCCLUSION_FUDGE + LLVector3(0.01f,0.01f,0.01f);; | ||
2190 | |||
2191 | drawBox(c,r); | ||
2192 | } | 2740 | } |
2193 | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 2741 | |
2742 | glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); | ||
2194 | } | 2743 | } |
2195 | } | 2744 | } |
2196 | 2745 | ||
@@ -2272,3 +2821,27 @@ LLDrawable* LLSpatialPartition::pickDrawable(const LLVector3& start, const LLVec | |||
2272 | collision.setVec(pick.mEnd); | 2821 | collision.setVec(pick.mEnd); |
2273 | return ret; | 2822 | return ret; |
2274 | } | 2823 | } |
2824 | |||
2825 | LLDrawInfo::LLDrawInfo(U32 start, U32 end, U32 count, U32 offset, | ||
2826 | LLViewerImage* texture, LLVertexBuffer* buffer, | ||
2827 | BOOL fullbright, U8 bump, BOOL particle, F32 part_size) | ||
2828 | : | ||
2829 | mVertexBuffer(buffer), | ||
2830 | mTexture(texture), | ||
2831 | mTextureMatrix(NULL), | ||
2832 | mStart(start), | ||
2833 | mEnd(end), | ||
2834 | mCount(count), | ||
2835 | mOffset(offset), | ||
2836 | mFullbright(fullbright), | ||
2837 | mBump(bump), | ||
2838 | mParticle(particle), | ||
2839 | mPartSize(part_size), | ||
2840 | mVSize(0.f) | ||
2841 | { | ||
2842 | } | ||
2843 | |||
2844 | LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) | ||
2845 | { | ||
2846 | return new LLVertexBuffer(type_mask, usage); | ||
2847 | } | ||