History

first cut at new faster voxel pipeline

ZappoMan committed 13 years ago

Commit 793a14e1 parent 0f74d4b8 files · +214 −13Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 8 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+153−3
@@ -70,10 +70,12 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 69 unmodified lines
7070 _writeRenderFullVBO = true;
7171 _readRenderFullVBO = true;
7272 _tree = new VoxelTree();
73+ _tree->rootNode->setVoxelSystem(this);
7374 pthread_mutex_init(&_bufferWriteLock, NULL);
7475 pthread_mutex_init(&_treeLock, NULL);
7576
7677 VoxelNode::addDeleteHook(this);
78+ VoxelNode::addUpdateHook(this);
7779 _abandonedVBOSlots = 0;
7880 _falseColorizeBySource = false;
7981 _dataSourceID = UNKNOWN_NODE_ID;
@@ -96,6 +98,8 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 16 unmodified lines
9698 _writeVoxelDirtyArray = NULL;
9799 _readVoxelDirtyArray = NULL;
98100
101+ _inSetupNewVoxelsForDrawing = false;
102+ _useFastVoxelPipeline = false;
99103 }
100104
101105 void VoxelSystem::voxelDeleted(VoxelNode* node) {
@@ -104,6 +108,61 @@ void VoxelSystem::voxelDeleted(VoxelNode* node) { · 2 unmodified lines
104108 }
105109 }
106110
111+void VoxelSystem::setUseFastVoxelPipeline(bool useFastVoxelPipeline) {
112+ _useFastVoxelPipeline = useFastVoxelPipeline;
113+ printf("setUseFastVoxelPipeline() _useFastVoxelPipeline=%s\n", debug::valueOf(_useFastVoxelPipeline));
114+}
115+
116+void VoxelSystem::voxelUpdated(VoxelNode* node) {
117+
118+ //printf("VoxelSystem::voxelUpdated() _useFastVoxelPipeline=%s\n", debug::valueOf(_useFastVoxelPipeline));
119+
120+ // If we're in SetupNewVoxelsForDrawing() or _writeRenderFullVBO then bail..
121+ if (!_useFastVoxelPipeline || _inSetupNewVoxelsForDrawing || _writeRenderFullVBO) {
122+ return;
123+ }
124+
125+ if (node->getVoxelSystem() == this) {
126+ //printf("VoxelSystem::voxelUpdated()... node->getVoxelSystem() == this\n");
127+
128+ bool shouldRender = false; // assume we don't need to render it
129+ // if it's colored, we might need to render it!
130+ shouldRender = node->calculateShouldRender(_viewFrustum);
131+
132+ node->setShouldRender(shouldRender);
133+
134+ //printf("VoxelSystem::voxelUpdated() shouldRender=%s\n", debug::valueOf(shouldRender));
135+
136+ if (!node->isLeaf()) {
137+
138+ // As we check our children, see if any of them went from shouldRender to NOT shouldRender
139+ // then we probably dropped LOD and if we don't have color, we want to average our children
140+ // for a new color.
141+ int childrenGotHiddenCount = 0;
142+ for (int i = 0; i < NUMBER_OF_CHILDREN; i++) {
143+ VoxelNode* childNode = node->getChildAtIndex(i);
144+ if (childNode) {
145+ bool wasShouldRender = childNode->getShouldRender();
146+ bool isShouldRender = childNode->calculateShouldRender(_viewFrustum);
147+ if (wasShouldRender && !isShouldRender) {
148+ childrenGotHiddenCount++;
149+ }
150+ }
151+ }
152+ if (childrenGotHiddenCount > 0) {
153+ node->setColorFromAverageOfChildren();
154+ }
155+ }
156+
157+ updateNodeInArraysAsPartialVBO(node);
158+ _voxelsUpdated++;
159+
160+ node->clearDirtyBit(); // clear the dirty bit, do this before we potentially delete things.
161+
162+ setupNewVoxelsForDrawingSingleNode();
163+ }
164+}
165+
107166 // returns an available index, starts by reusing a previously freed index, but if there isn't one available
108167 // it will use the end of the VBO array and grow our accounting of that array.
109168 // and makes the index available for some other node to use
@@ -147,6 +206,7 @@ VoxelSystem::~VoxelSystem() { · 37 unmodified lines
147206 pthread_mutex_destroy(&_treeLock);
148207
149208 VoxelNode::removeDeleteHook(this);
209+ VoxelNode::removeUpdateHook(this);
150210 }
151211
152212 void VoxelSystem::setMaxVoxels(int maxVoxels) {
@@ -462,7 +522,11 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 309 unmodified lines
462522 break;
463523 }
464524
465− setupNewVoxelsForDrawing();
525+ //printf("VoxelSystem::parseData() _useFastVoxelPipeline=%s\n", debug::valueOf(_useFastVoxelPipeline));
526+
527+ if (!_useFastVoxelPipeline || _writeRenderFullVBO) {
528+ setupNewVoxelsForDrawing();
529+ }
466530
467531 pthread_mutex_unlock(&_treeLock);
468532
@@ -474,6 +538,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 5 unmodified lines
474538 void VoxelSystem::setupNewVoxelsForDrawing() {
475539 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
476540 "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated
541+ _inSetupNewVoxelsForDrawing = true;
477542 uint64_t start = usecTimestampNow();
478543 uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
479544
@@ -547,12 +612,92 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 67 unmodified lines
547612 int elapsedmsec = (end - start) / 1000;
548613 _setupNewVoxelsForDrawingLastFinished = end;
549614 _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
615+ _inSetupNewVoxelsForDrawing = false;
550616 }
551617
618+void VoxelSystem::setupNewVoxelsForDrawingSingleNode() {
619+ PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings),
620+ "setupNewVoxelsForDrawingSingleNode()"); // would like to include _voxelsInArrays, _voxelsUpdated
621+ uint64_t start = usecTimestampNow();
622+ uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000;
623+
624+ // clear up the VBOs for any nodes that have been recently deleted.
625+ clearFreeBufferIndexes();
626+
627+ bool iAmDebugging = false; // if you're debugging set this to true, so you won't get skipped for slow debugging
628+ if (!iAmDebugging && sinceLastTime <= std::max((float) _setupNewVoxelsForDrawingLastElapsed, SIXTY_FPS_IN_MILLISECONDS)) {
629+ return; // bail early, it hasn't been long enough since the last time we ran
630+ }
631+
632+ uint64_t sinceLastViewCulling = (start - _lastViewCulling) / 1000;
633+ // If the view frustum is no longer changing, but has changed, since last time, then remove nodes that are out of view
634+ if ((sinceLastViewCulling >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS))
635+ && !isViewChanging()) {
636+ _lastViewCulling = start;
637+
638+ // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove
639+ // them from tree, this makes our tree caclulations faster, but doesn't require us to fully rebuild the VBOs (which
640+ // can be expensive).
641+ removeOutOfView();
642+
643+ // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So,
644+ // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on
645+ // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary.
646+ cleanupRemovedVoxels();
647+
648+ uint64_t endViewCulling = usecTimestampNow();
649+ _lastViewCullingElapsed = (endViewCulling - start) / 1000;
650+ }
651+
652+ bool didWriteFullVBO = _writeRenderFullVBO;
653+
654+ if (_tree->isDirty()) {
655+ static char buffer[64] = { 0 };
656+ if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) {
657+ sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", debug::valueOf(_writeRenderFullVBO));
658+ };
659+ PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer);
660+ _callsToTreesToArrays++;
661+ if (_writeRenderFullVBO) {
662+ _voxelsInWriteArrays = 0; // reset our VBO
663+ _freeIndexes.clear(); // reset our free indexes
664+ _voxelsUpdated = newTreeToArrays(_tree->rootNode);
665+ _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean
666+ _abandonedVBOSlots = 0; // reset the count of our abandoned slots, why is this here and not earlier????
667+ }
668+
669+ // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are
670+ // ok again, until/unless we call removeOutOfView()
671+ _writeRenderFullVBO = false;
672+ } else {
673+ _voxelsUpdated = 0;
674+ }
675+
676+ // lock on the buffer write lock so we can't modify the data when the GPU is reading it
677+ pthread_mutex_lock(&_bufferWriteLock);
678+
679+ if (_voxelsUpdated) {
680+ _voxelsDirty=true;
681+ }
682+
683+ // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated
684+ copyWrittenDataToReadArrays(didWriteFullVBO);
685+
686+ // after...
687+ _voxelsUpdated = 0;
688+
689+ pthread_mutex_unlock(&_bufferWriteLock);
690+
691+ uint64_t end = usecTimestampNow();
692+ int elapsedmsec = (end - start) / 1000;
693+ _setupNewVoxelsForDrawingLastFinished = end;
694+ _setupNewVoxelsForDrawingLastElapsed = elapsedmsec;
695+}
552696 void VoxelSystem::cleanupRemovedVoxels() {
553697 PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "cleanupRemovedVoxels()");
554698 // This handles cleanup of voxels that were culled as part of our regular out of view culling operation
555699 if (!_removedVoxels.isEmpty()) {
700+ qDebug() << "cleanupRemovedVoxels().. _removedVoxels=" << _removedVoxels.count() << "\n";
556701 while (!_removedVoxels.isEmpty()) {
557702 delete _removedVoxels.extract();
558703 }
@@ -560,8 +705,9 @@ void VoxelSystem::cleanupRemovedVoxels() { · 1 unmodified line
560705 }
561706 // we also might have VBO slots that have been abandoned, if too many of our VBO slots
562707 // are abandonded we want to rerender our full VBOs
563− const float TOO_MANY_ABANDONED_RATIO = 0.25f;
708+ const float TOO_MANY_ABANDONED_RATIO = 0.5f;
564709 if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) {
710+ qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots ["<< _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n";
565711 _writeRenderFullVBO = true;
566712 }
567713 }
@@ -704,7 +850,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { · 136 unmodified lines
704850 return 1; // rendered
705851 } else {
706852 node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN);
707− node->setVoxelSystem(NULL);
853+ //node->setVoxelSystem(NULL);
708854 }
709855
710856 return 0; // not-rendered
@@ -805,6 +951,9 @@ void VoxelSystem::init() { · 94 unmodified lines
805951 // VBO for the verticesArray
806952 initVoxelMemory();
807953 _initialized = true;
954+
955+ // our own _removedVoxels doesn't need to be notified of voxel deletes
956+ VoxelNode::removeDeleteHook(&_removedVoxels);
808957 }
809958
810959 void VoxelSystem::changeTree(VoxelTree* newTree) {
@@ -812,6 +961,7 @@ void VoxelSystem::changeTree(VoxelTree* newTree) { · 1 unmodified line
812961
813962 _tree = newTree;
814963 _tree->setDirtyBit();
964+ _tree->rootNode->setVoxelSystem(this);
815965
816966 connect(_tree, SIGNAL(importSize(float,float,float)), SIGNAL(importSize(float,float,float)));
817967 connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int)));

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t