Showing the changes to interface/src/VoxelSystem.cpp (1 of 8 files). Show all
Unified · Split
| @@ -99,6 +99,9 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 98 unmodified lines | |||
| 99 | 99 | ||
| 100 | _culledOnce = false; | 100 | _culledOnce = false; |
| 101 | _inhideOutOfView = false; | 101 | _inhideOutOfView = false; |
| 102 | |||
| 103 | _lastKnownVoxelSizeScale = DEFAULT_OCTREE_SIZE_SCALE; | ||
| 104 | _lastKnownBoundaryLevelAdjust = 0; | ||
| 102 | } | 105 | } |
| 103 | 106 | ||
| 104 | void VoxelSystem::elementDeleted(OctreeElement* element) { | 107 | void VoxelSystem::elementDeleted(OctreeElement* element) { |
| @@ -249,6 +252,9 @@ VoxelSystem::~VoxelSystem() { · 144 unmodified lines | |||
| 249 | delete _tree; | 252 | delete _tree; |
| 250 | } | 253 | } |
| 251 | 254 | ||
| 255 | |||
| 256 | // This is called by the main application thread on both the initialization of the application and when | ||
| 257 | // the preferences dialog box is called/saved | ||
| 252 | void VoxelSystem::setMaxVoxels(int maxVoxels) { | 258 | void VoxelSystem::setMaxVoxels(int maxVoxels) { |
| 253 | if (maxVoxels == _maxVoxels) { | 259 | if (maxVoxels == _maxVoxels) { |
| 254 | return; | 260 | return; |
| @@ -267,6 +273,8 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { · 12 unmodified lines | |||
| 267 | } | 273 | } |
| 268 | } | 274 | } |
| 269 | 275 | ||
| 276 | // This is called by the main application thread on both the initialization of the application and when | ||
| 277 | // the use voxel shader menu item is chosen | ||
| 270 | void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { | 278 | void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { |
| 271 | if (_useVoxelShader == useVoxelShader) { | 279 | if (_useVoxelShader == useVoxelShader) { |
| 272 | return; | 280 | return; |
| @@ -330,7 +338,7 @@ void VoxelSystem::setVoxelsAsPoints(bool voxelsAsPoints) { · 57 unmodified lines | |||
| 330 | 338 | ||
| 331 | void VoxelSystem::cleanupVoxelMemory() { | 339 | void VoxelSystem::cleanupVoxelMemory() { |
| 332 | if (_initialized) { | 340 | if (_initialized) { |
| 333 | _bufferWriteLock.lock(); | 341 | _readArraysLock.lockForWrite(); |
| 334 | _initialized = false; // no longer initialized | 342 | _initialized = false; // no longer initialized |
| 335 | if (_useVoxelShader) { | 343 | if (_useVoxelShader) { |
| 336 | // these are used when in VoxelShader mode. | 344 | // these are used when in VoxelShader mode. |
| @@ -368,7 +376,7 @@ void VoxelSystem::cleanupVoxelMemory() { · 31 unmodified lines | |||
| 368 | delete[] _writeVoxelDirtyArray; | 376 | delete[] _writeVoxelDirtyArray; |
| 369 | delete[] _readVoxelDirtyArray; | 377 | delete[] _readVoxelDirtyArray; |
| 370 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; | 378 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; |
| 371 | _bufferWriteLock.unlock(); | 379 | _readArraysLock.unlock(); |
| 372 | } | 380 | } |
| 373 | } | 381 | } |
| 374 | 382 | ||
| @@ -401,7 +409,7 @@ void VoxelSystem::setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndice · 26 unmodified lines | |||
| 401 | } | 409 | } |
| 402 | 410 | ||
| 403 | void VoxelSystem::initVoxelMemory() { | 411 | void VoxelSystem::initVoxelMemory() { |
| 404 | _bufferWriteLock.lock(); | 412 | _readArraysLock.lockForWrite(); |
| 405 | 413 | ||
| 406 | _memoryUsageRAM = 0; | 414 | _memoryUsageRAM = 0; |
| 407 | _memoryUsageVBO = 0; // our VBO allocations as we know them | 415 | _memoryUsageVBO = 0; // our VBO allocations as we know them |
| @@ -516,7 +524,7 @@ void VoxelSystem::initVoxelMemory() { · 108 unmodified lines | |||
| 516 | 524 | ||
| 517 | _initialized = true; | 525 | _initialized = true; |
| 518 | 526 | ||
| 519 | _bufferWriteLock.unlock(); | 527 | _readArraysLock.unlock(); |
| 520 | } | 528 | } |
| 521 | 529 | ||
| 522 | void VoxelSystem::writeToSVOFile(const char* filename, VoxelTreeElement* element) const { | 530 | void VoxelSystem::writeToSVOFile(const char* filename, VoxelTreeElement* element) const { |
| @@ -646,7 +654,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 123 unmodified lines | |||
| 646 | } | 654 | } |
| 647 | 655 | ||
| 648 | _inSetupNewVoxelsForDrawing = true; | 656 | _inSetupNewVoxelsForDrawing = true; |
| 649 | 657 | ||
| 650 | bool didWriteFullVBO = _writeRenderFullVBO; | 658 | bool didWriteFullVBO = _writeRenderFullVBO; |
| 651 | if (_tree->isDirty()) { | 659 | if (_tree->isDirty()) { |
| 652 | static char buffer[64] = { 0 }; | 660 | static char buffer[64] = { 0 }; |
| @@ -673,7 +681,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 20 unmodified lines | |||
| 673 | } | 681 | } |
| 674 | 682 | ||
| 675 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 683 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 676 | _bufferWriteLock.lock(); | 684 | _readArraysLock.lockForWrite(); |
| 677 | 685 | ||
| 678 | if (_voxelsUpdated) { | 686 | if (_voxelsUpdated) { |
| 679 | _voxelsDirty=true; | 687 | _voxelsDirty=true; |
| @@ -682,7 +690,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 2 unmodified lines | |||
| 682 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated | 690 | // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated |
| 683 | copyWrittenDataToReadArrays(didWriteFullVBO); | 691 | copyWrittenDataToReadArrays(didWriteFullVBO); |
| 684 | 692 | ||
| 685 | _bufferWriteLock.unlock(); | 693 | _readArraysLock.unlock(); |
| 686 | 694 | ||
| 687 | quint64 end = usecTimestampNow(); | 695 | quint64 end = usecTimestampNow(); |
| 688 | int elapsedmsec = (end - start) / 1000; | 696 | int elapsedmsec = (end - start) / 1000; |
| @@ -713,8 +721,8 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 24 unmodified lines | |||
| 713 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it | 721 | // lock on the buffer write lock so we can't modify the data when the GPU is reading it |
| 714 | { | 722 | { |
| 715 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 723 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 716 | "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); | 724 | "setupNewVoxelsForDrawingSingleNode()... _readArraysLock.lockForWrite();" ); |
| 717 | _bufferWriteLock.lock(); | 725 | _readArraysLock.lockForWrite(); |
| 718 | } | 726 | } |
| 719 | 727 | ||
| 720 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty | 728 | _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty |
| @@ -725,7 +733,7 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 4 unmodified lines | |||
| 725 | // after... | 733 | // after... |
| 726 | _voxelsUpdated = 0; | 734 | _voxelsUpdated = 0; |
| 727 | 735 | ||
| 728 | _bufferWriteLock.unlock(); | 736 | _readArraysLock.unlock(); |
| 729 | 737 | ||
| 730 | quint64 end = usecTimestampNow(); | 738 | quint64 end = usecTimestampNow(); |
| 731 | int elapsedmsec = (end - start) / 1000; | 739 | int elapsedmsec = (end - start) / 1000; |
| @@ -733,8 +741,12 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { · 1 unmodified line | |||
| 733 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; | 741 | _setupNewVoxelsForDrawingLastElapsed = elapsedmsec; |
| 734 | } | 742 | } |
| 735 | 743 | ||
| 736 | void VoxelSystem::checkForCulling() { | 744 | void VoxelSystem::recreateVoxelGeometryInView() { |
| 745 | // this is a temporary solution... we need a full implementation that actually does a full redraw into clean VBOs | ||
| 746 | hideOutOfView(true); | ||
| 747 | } | ||
| 737 | 748 | ||
| 749 | void VoxelSystem::checkForCulling() { | ||
| 738 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()"); | 750 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "checkForCulling()"); |
| 739 | quint64 start = usecTimestampNow(); | 751 | quint64 start = usecTimestampNow(); |
| 740 | 752 | ||
| @@ -762,7 +774,20 @@ void VoxelSystem::checkForCulling() { · 21 unmodified lines | |||
| 762 | _hasRecentlyChanged = false; | 774 | _hasRecentlyChanged = false; |
| 763 | } | 775 | } |
| 764 | 776 | ||
| 765 | hideOutOfView(forceFullFrustum); | 777 | // This would be a good place to do a special processing pass, for example, switching the LOD of the scene |
| 778 | bool fullRedraw = (_lastKnownVoxelSizeScale != Menu::getInstance()->getVoxelSizeScale() || | ||
| 779 | _lastKnownBoundaryLevelAdjust != Menu::getInstance()->getBoundaryLevelAdjust()); | ||
| 780 | |||
| 781 | // track that these values | ||
| 782 | _lastKnownVoxelSizeScale = Menu::getInstance()->getVoxelSizeScale(); | ||
| 783 | _lastKnownBoundaryLevelAdjust = Menu::getInstance()->getBoundaryLevelAdjust(); | ||
| 784 | |||
| 785 | if (fullRedraw) { | ||
| 786 | // this will remove all old geometry and recreate the correct geometry for all in view voxels | ||
| 787 | recreateVoxelGeometryInView(); | ||
| 788 | } else { | ||
| 789 | hideOutOfView(forceFullFrustum); | ||
| 790 | } | ||
| 766 | 791 | ||
| 767 | if (forceFullFrustum) { | 792 | if (forceFullFrustum) { |
| 768 | quint64 endViewCulling = usecTimestampNow(); | 793 | quint64 endViewCulling = usecTimestampNow(); |
| @@ -1197,7 +1222,8 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg · 428 unmodified lines | |||
| 1197 | } | 1222 | } |
| 1198 | } | 1223 | } |
| 1199 | 1224 | ||
| 1200 | void VoxelSystem::render(bool texture) { | 1225 | void VoxelSystem::render() { |
| 1226 | bool texture = Menu::getInstance()->isOptionChecked(MenuOption::VoxelTextures); | ||
| 1201 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); | 1227 | bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); |
| 1202 | PerformanceWarning warn(showWarnings, "render()"); | 1228 | PerformanceWarning warn(showWarnings, "render()"); |
| 1203 | 1229 | ||
| @@ -1404,11 +1430,7 @@ void VoxelSystem::killLocalVoxels() { · 200 unmodified lines | |||
| 1404 | setupNewVoxelsForDrawing(); | 1430 | setupNewVoxelsForDrawing(); |
| 1405 | } | 1431 | } |
| 1406 | 1432 | ||
| 1407 | void VoxelSystem::redrawInViewVoxels() { | 1433 | // only called on main thread |
| 1408 | hideOutOfView(true); | ||
| 1409 | } | ||
| 1410 | |||
| 1411 | |||
| 1412 | bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData) { | 1434 | bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData) { |
| 1413 | _nodeCount++; | 1435 | _nodeCount++; |
| 1414 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; | 1436 | VoxelTreeElement* voxel = (VoxelTreeElement*)element; |
| @@ -1416,12 +1438,15 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(OctreeElement* element, void · 1 unmodified line | |||
| 1416 | return true; | 1438 | return true; |
| 1417 | } | 1439 | } |
| 1418 | 1440 | ||
| 1441 | // only called on main thread, and also always followed by a call to cleanupVoxelMemory() | ||
| 1442 | // you shouldn't be calling this on any other thread or without also cleaning up voxel memory | ||
| 1419 | void VoxelSystem::clearAllNodesBufferIndex() { | 1443 | void VoxelSystem::clearAllNodesBufferIndex() { |
| 1420 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), | 1444 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), |
| 1421 | "VoxelSystem::clearAllNodesBufferIndex()"); | 1445 | "VoxelSystem::clearAllNodesBufferIndex()"); |
| 1422 | _nodeCount = 0; | 1446 | _nodeCount = 0; |
| 1423 | _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read | 1447 | _tree->lockForRead(); // we won't change the tree so it's ok to treat this as a read |
| 1424 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); | 1448 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); |
| 1449 | clearFreeBufferIndexes(); // this should be called too | ||
| 1425 | _tree->unlock(); | 1450 | _tree->unlock(); |
| 1426 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | 1451 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { |
| 1427 | qDebug("clearing buffer index of %d nodes", _nodeCount); | 1452 | qDebug("clearing buffer index of %d nodes", _nodeCount); |