Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -111,6 +111,11 @@ void VoxelSystem::voxelDeleted(VoxelNode* node) { · 110 unmodified lines | ||
| 111 | 111 | void VoxelSystem::setUseFastVoxelPipeline(bool useFastVoxelPipeline) { |
| 112 | 112 | _useFastVoxelPipeline = useFastVoxelPipeline; |
| 113 | 113 | printf("setUseFastVoxelPipeline() _useFastVoxelPipeline=%s\n", debug::valueOf(_useFastVoxelPipeline)); |
| 114 | + //forceRedrawEntireTree(); | |
| 115 | + if (_voxelsUpdated < 1) { | |
| 116 | + _voxelsUpdated = 1; | |
| 117 | + } | |
| 118 | + setupNewVoxelsForDrawing(); | |
| 114 | 119 | } |
| 115 | 120 | |
| 116 | 121 | void VoxelSystem::voxelUpdated(VoxelNode* node) { |
| @@ -131,8 +136,6 @@ void VoxelSystem::voxelUpdated(VoxelNode* node) { · 14 unmodified lines | ||
| 131 | 136 | |
| 132 | 137 | node->setShouldRender(shouldRender); |
| 133 | 138 | |
| 134 | − //printf("VoxelSystem::voxelUpdated() shouldRender=%s\n", debug::valueOf(shouldRender)); | |
| 135 | − | |
| 136 | 139 | if (!node->isLeaf()) { |
| 137 | 140 | |
| 138 | 141 | // As we check our children, see if any of them went from shouldRender to NOT shouldRender |
| @@ -522,7 +525,6 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 383 unmodified lines | ||
| 522 | 525 | break; |
| 523 | 526 | } |
| 524 | 527 | |
| 525 | − //printf("VoxelSystem::parseData() _useFastVoxelPipeline=%s\n", debug::valueOf(_useFastVoxelPipeline)); | |
| 526 | 528 | |
| 527 | 529 | if (!_useFastVoxelPipeline || _writeRenderFullVBO) { |
| 528 | 530 | setupNewVoxelsForDrawing(); |
| @@ -538,7 +540,6 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 9 unmodified lines | ||
| 538 | 540 | void VoxelSystem::setupNewVoxelsForDrawing() { |
| 539 | 541 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 540 | 542 | "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated |
| 541 | − _inSetupNewVoxelsForDrawing = true; | |
| 542 | 543 | uint64_t start = usecTimestampNow(); |
| 543 | 544 | uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000; |
| 544 | 545 | |
| @@ -550,25 +551,9 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 5 unmodified lines | ||
| 550 | 551 | return; // bail early, it hasn't been long enough since the last time we ran |
| 551 | 552 | } |
| 552 | 553 | |
| 553 | − uint64_t sinceLastViewCulling = (start - _lastViewCulling) / 1000; | |
| 554 | − // If the view frustum is no longer changing, but has changed, since last time, then remove nodes that are out of view | |
| 555 | − if ((sinceLastViewCulling >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) | |
| 556 | − && !isViewChanging()) { | |
| 557 | − _lastViewCulling = start; | |
| 558 | − | |
| 559 | − // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove | |
| 560 | − // them from tree, this makes our tree caclulations faster, but doesn't require us to fully rebuild the VBOs (which | |
| 561 | − // can be expensive). | |
| 562 | − removeOutOfView(); | |
| 563 | − | |
| 564 | − // Once we call cleanupRemovedVoxels() we do need to rebuild our VBOs (if anything was actually removed). So, | |
| 565 | − // we should consider putting this someplace else... as this might be able to occur less frequently, and save us on | |
| 566 | − // VBO reubuilding. Possibly we should do this only if our actual VBO usage crosses some lower boundary. | |
| 567 | − cleanupRemovedVoxels(); | |
| 554 | + _inSetupNewVoxelsForDrawing = true; | |
| 568 | 555 | |
| 569 | − uint64_t endViewCulling = usecTimestampNow(); | |
| 570 | − _lastViewCullingElapsed = (endViewCulling - start) / 1000; | |
| 571 | − } | |
| 556 | + checkForCulling(); // check for out of view and deleted voxels... | |
| 572 | 557 | |
| 573 | 558 | bool didWriteFullVBO = _writeRenderFullVBO; |
| 574 | 559 | if (_tree->isDirty()) { |
| @@ -616,11 +601,13 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 41 unmodified lines | ||
| 616 | 601 | } |
| 617 | 602 | |
| 618 | 603 | void VoxelSystem::setupNewVoxelsForDrawingSingleNode() { |
| 604 | + | |
| 619 | 605 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 620 | 606 | "setupNewVoxelsForDrawingSingleNode()"); // would like to include _voxelsInArrays, _voxelsUpdated |
| 607 | + | |
| 621 | 608 | uint64_t start = usecTimestampNow(); |
| 622 | 609 | uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000; |
| 623 | − | |
| 610 | + | |
| 624 | 611 | // clear up the VBOs for any nodes that have been recently deleted. |
| 625 | 612 | clearFreeBufferIndexes(); |
| 626 | 613 | |
| @@ -629,10 +616,37 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode() { · 2 unmodified lines | ||
| 629 | 616 | return; // bail early, it hasn't been long enough since the last time we ran |
| 630 | 617 | } |
| 631 | 618 | |
| 619 | + | |
| 620 | + checkForCulling(); // check for out of view and deleted voxels... | |
| 621 | + | |
| 622 | + // lock on the buffer write lock so we can't modify the data when the GPU is reading it | |
| 623 | + pthread_mutex_lock(&_bufferWriteLock); | |
| 624 | + | |
| 625 | + _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | |
| 626 | + | |
| 627 | + // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated | |
| 628 | + copyWrittenDataToReadArrays(_writeRenderFullVBO); | |
| 629 | + | |
| 630 | + // after... | |
| 631 | + _voxelsUpdated = 0; | |
| 632 | + | |
| 633 | + pthread_mutex_unlock(&_bufferWriteLock); | |
| 634 | + | |
| 635 | + uint64_t end = usecTimestampNow(); | |
| 636 | + int elapsedmsec = (end - start) / 1000; | |
| 637 | + _setupNewVoxelsForDrawingLastFinished = end; | |
| 638 | + _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; | |
| 639 | +} | |
| 640 | + | |
| 641 | +void VoxelSystem::checkForCulling() { | |
| 642 | + | |
| 643 | + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()"); | |
| 644 | + uint64_t start = usecTimestampNow(); | |
| 632 | 645 | uint64_t sinceLastViewCulling = (start - _lastViewCulling) / 1000; |
| 633 | 646 | // If the view frustum is no longer changing, but has changed, since last time, then remove nodes that are out of view |
| 634 | 647 | if ((sinceLastViewCulling >= std::max((float) _lastViewCullingElapsed, VIEW_CULLING_RATE_IN_MILLISECONDS)) |
| 635 | 648 | && !isViewChanging()) { |
| 649 | + | |
| 636 | 650 | _lastViewCulling = start; |
| 637 | 651 | |
| 638 | 652 | // When we call removeOutOfView() voxels, we don't actually remove the voxels from the VBOs, but we do remove |
| @@ -648,56 +662,15 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode() { · 9 unmodified lines | ||
| 648 | 662 | uint64_t endViewCulling = usecTimestampNow(); |
| 649 | 663 | _lastViewCullingElapsed = (endViewCulling - start) / 1000; |
| 650 | 664 | } |
| 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 | 665 | } |
| 666 | + | |
| 696 | 667 | void VoxelSystem::cleanupRemovedVoxels() { |
| 697 | 668 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "cleanupRemovedVoxels()"); |
| 698 | 669 | // This handles cleanup of voxels that were culled as part of our regular out of view culling operation |
| 699 | 670 | if (!_removedVoxels.isEmpty()) { |
| 700 | − qDebug() << "cleanupRemovedVoxels().. _removedVoxels=" << _removedVoxels.count() << "\n"; | |
| 671 | + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | |
| 672 | + qDebug() << "cleanupRemovedVoxels().. _removedVoxels=" << _removedVoxels.count() << "\n"; | |
| 673 | + } | |
| 701 | 674 | while (!_removedVoxels.isEmpty()) { |
| 702 | 675 | delete _removedVoxels.extract(); |
| 703 | 676 | } |
| @@ -707,7 +680,10 @@ void VoxelSystem::cleanupRemovedVoxels() { · 3 unmodified lines | ||
| 707 | 680 | // are abandonded we want to rerender our full VBOs |
| 708 | 681 | const float TOO_MANY_ABANDONED_RATIO = 0.5f; |
| 709 | 682 | if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) { |
| 710 | − qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots ["<< _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n"; | |
| 683 | + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | |
| 684 | + qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots [" | |
| 685 | + << _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO \n"; | |
| 686 | + } | |
| 711 | 687 | _writeRenderFullVBO = true; |
| 712 | 688 | } |
| 713 | 689 | } |
| @@ -1181,7 +1157,7 @@ int VoxelSystem::_nodeCount = 0; · 467 unmodified lines | ||
| 1181 | 1157 | void VoxelSystem::killLocalVoxels() { |
| 1182 | 1158 | _tree->eraseAllVoxels(); |
| 1183 | 1159 | _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this?? |
| 1184 | − //setupNewVoxelsForDrawing(); | |
| 1160 | + setupNewVoxelsForDrawing(); | |
| 1185 | 1161 | } |
| 1186 | 1162 | |
| 1187 | 1163 | |