Showing the changes to interface/src/VoxelSystem.cpp (1 of 3 files). Show all
Unified · Split
| @@ -109,8 +109,14 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 108 unmodified lines | ||
| 109 | 109 | } |
| 110 | 110 | |
| 111 | 111 | void VoxelSystem::voxelDeleted(VoxelNode* node) { |
| 112 | − if (node->isKnownBufferIndex() && (node->getVoxelSystem() == this)) { | |
| 113 | − forceRemoveNodeFromArrays(node); | |
| 112 | + if (node->getVoxelSystem() == this) { | |
| 113 | + if (_voxelsInWriteArrays != 0) { | |
| 114 | + forceRemoveNodeFromArrays(node); | |
| 115 | + } else { | |
| 116 | + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | |
| 117 | + printf("VoxelSystem::voxelDeleted() while _voxelsInWriteArrays==0, is that expected? \n"); | |
| 118 | + } | |
| 119 | + } | |
| 114 | 120 | } |
| 115 | 121 | } |
| 116 | 122 | |
| @@ -223,10 +229,15 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) { · 106 unmodified lines | ||
| 223 | 229 | // This will run through the list of _freeIndexes and reset their VBO array values to be "invisible". |
| 224 | 230 | void VoxelSystem::clearFreeBufferIndexes() { |
| 225 | 231 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "###### clearFreeBufferIndexes()"); |
| 232 | + _voxelsInWriteArrays = 0; // reset our VBO | |
| 233 | + _abandonedVBOSlots = 0; | |
| 234 | + | |
| 235 | + // clear out freeIndexes | |
| 226 | 236 | pthread_mutex_lock(&_freeIndexLock); |
| 227 | 237 | _freeIndexes.clear(); |
| 228 | − _abandonedVBOSlots = 0; | |
| 229 | 238 | pthread_mutex_unlock(&_freeIndexLock); |
| 239 | + | |
| 240 | + clearAllNodesBufferIndex(); | |
| 230 | 241 | } |
| 231 | 242 | |
| 232 | 243 | VoxelSystem::~VoxelSystem() { |
| @@ -438,7 +449,6 @@ void VoxelSystem::initVoxelMemory() { · 205 unmodified lines | ||
| 438 | 449 | |
| 439 | 450 | // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead |
| 440 | 451 | // rendering the voxel faces in 6 passes that use a global call to glNormal3f() |
| 441 | − qDebug("Using Global Normals...\n"); | |
| 442 | 452 | setupFaceIndices(_vboIndicesTop, identityIndicesTop); |
| 443 | 453 | setupFaceIndices(_vboIndicesBottom, identityIndicesBottom); |
| 444 | 454 | setupFaceIndices(_vboIndicesLeft, identityIndicesLeft); |
| @@ -596,11 +606,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { · 151 unmodified lines | ||
| 596 | 606 | |
| 597 | 607 | while (totalLength <= numBytes) { |
| 598 | 608 | if (0==strcmp(command,(char*)"erase all")) { |
| 599 | − qDebug("got Z message == erase all\n"); | |
| 600 | − pthread_mutex_lock(&_treeLock); | |
| 601 | − _tree->eraseAllVoxels(); | |
| 602 | − pthread_mutex_unlock(&_treeLock); | |
| 603 | − _voxelsInReadArrays = _voxelsInWriteArrays = 0; // better way to do this?? | |
| 609 | + qDebug("got Z message == erase all - NOT SUPPORTED ON INTERFACE\n"); | |
| 604 | 610 | } |
| 605 | 611 | if (0==strcmp(command,(char*)"add scene")) { |
| 606 | 612 | qDebug("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n"); |
| @@ -652,8 +658,6 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 45 unmodified lines | ||
| 652 | 658 | PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); |
| 653 | 659 | _callsToTreesToArrays++; |
| 654 | 660 | if (_writeRenderFullVBO) { |
| 655 | − printf("resetting _freeIndexes and _voxelsInWriteArrays\n"); | |
| 656 | − _voxelsInWriteArrays = 0; // reset our VBO | |
| 657 | 661 | clearFreeBufferIndexes(); |
| 658 | 662 | } |
| 659 | 663 | _voxelsUpdated = newTreeToArrays(_tree->rootNode); |
| @@ -972,10 +976,10 @@ int VoxelSystem::updateNodeInArrays(VoxelNode* node, bool reuseIndex, bool force · 312 unmodified lines | ||
| 972 | 976 | updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); |
| 973 | 977 | return 1; // updated! |
| 974 | 978 | } else { |
| 975 | − // If we shouldn't render, but we did have a known index, then we will need to release our index | |
| 976 | − if (reuseIndex && node->isKnownBufferIndex()) { | |
| 977 | − forceRemoveNodeFromArrays(node); | |
| 978 | − return 1; // updated! | |
| 979 | + // If we shouldn't render, and we're in reuseIndex mode, then free our index, this only operates | |
| 980 | + // on nodes with known index values, so it's safe to call for any node. | |
| 981 | + if (reuseIndex) { | |
| 982 | + return forceRemoveNodeFromArrays(node); | |
| 979 | 983 | } |
| 980 | 984 | } |
| 981 | 985 | } |
| @@ -1284,8 +1288,11 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { · 302 unmodified lines | ||
| 1284 | 1288 | int VoxelSystem::_nodeCount = 0; |
| 1285 | 1289 | |
| 1286 | 1290 | void VoxelSystem::killLocalVoxels() { |
| 1291 | + pthread_mutex_lock(&_treeLock); | |
| 1287 | 1292 | _tree->eraseAllVoxels(); |
| 1288 | − _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this?? | |
| 1293 | + pthread_mutex_unlock(&_treeLock); | |
| 1294 | + clearFreeBufferIndexes(); | |
| 1295 | + _voxelsInReadArrays = 0; // do we need to do this? | |
| 1289 | 1296 | setupNewVoxelsForDrawing(); |
| 1290 | 1297 | } |
| 1291 | 1298 | |
| @@ -1298,8 +1305,12 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extra · 6 unmodified lines | ||
| 1298 | 1305 | |
| 1299 | 1306 | void VoxelSystem::clearAllNodesBufferIndex() { |
| 1300 | 1307 | _nodeCount = 0; |
| 1308 | + pthread_mutex_lock(&_treeLock); | |
| 1301 | 1309 | _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); |
| 1302 | − qDebug("clearing buffer index of %d nodes\n", _nodeCount); | |
| 1310 | + pthread_mutex_unlock(&_treeLock); | |
| 1311 | + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | |
| 1312 | + qDebug("clearing buffer index of %d nodes\n", _nodeCount); | |
| 1313 | + } | |
| 1303 | 1314 | } |
| 1304 | 1315 | |
| 1305 | 1316 | bool VoxelSystem::forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData) { |
| @@ -1700,8 +1711,7 @@ bool VoxelSystem::hideAllSubTreeOperation(VoxelNode* node, void* extraData) { · 394 unmodified lines | ||
| 1700 | 1711 | if (node->isKnownBufferIndex()) { |
| 1701 | 1712 | args->nodesRemoved++; |
| 1702 | 1713 | VoxelSystem* thisVoxelSystem = args->thisVoxelSystem; |
| 1703 | − thisVoxelSystem->forceRemoveNodeFromArrays(node); | |
| 1704 | − thisVoxelSystem->_voxelsUpdated++; | |
| 1714 | + thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->forceRemoveNodeFromArrays(node); | |
| 1705 | 1715 | thisVoxelSystem->setupNewVoxelsForDrawingSingleNode(); |
| 1706 | 1716 | } |
| 1707 | 1717 | |
| @@ -1714,10 +1724,10 @@ bool VoxelSystem::showAllSubTreeOperation(VoxelNode* node, void* extraData) { · 6 unmodified lines | ||
| 1714 | 1724 | args->nodesInside++; |
| 1715 | 1725 | |
| 1716 | 1726 | if (node->getShouldRender() && !node->isKnownBufferIndex()) { |
| 1717 | − node->setDirtyBit(); // will this make it draw? | |
| 1727 | + node->setDirtyBit(); // will this make it draw! | |
| 1718 | 1728 | } |
| 1719 | 1729 | |
| 1720 | − return true; | |
| 1730 | + return true; // keep recursing! | |
| 1721 | 1731 | } |
| 1722 | 1732 | |
| 1723 | 1733 | |
| @@ -1841,7 +1851,7 @@ void VoxelSystem::falseColorizeRandomEveryOther() { · 117 unmodified lines | ||
| 1841 | 1851 | |
| 1842 | 1852 | class collectStatsForTreesAndVBOsArgs { |
| 1843 | 1853 | public: |
| 1844 | − collectStatsForTreesAndVBOsArgs() : | |
| 1854 | + collectStatsForTreesAndVBOsArgs(int maxVoxels) : | |
| 1845 | 1855 | totalNodes(0), |
| 1846 | 1856 | dirtyNodes(0), |
| 1847 | 1857 | shouldRenderNodes(0), |
| @@ -1852,8 +1862,13 @@ public: · 4 unmodified lines | ||
| 1852 | 1862 | duplicateVBOIndex(0), |
| 1853 | 1863 | leafNodes(0) |
| 1854 | 1864 | { |
| 1855 | − memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool)); | |
| 1865 | + hasIndexFound = new bool[maxVoxels]; | |
| 1866 | + memset(hasIndexFound, false, maxVoxels * sizeof(bool)); | |
| 1856 | 1867 | }; |
| 1868 | + | |
| 1869 | + ~collectStatsForTreesAndVBOsArgs() { | |
| 1870 | + delete[] hasIndexFound; | |
| 1871 | + } | |
| 1857 | 1872 | |
| 1858 | 1873 | unsigned long totalNodes; |
| 1859 | 1874 | unsigned long dirtyNodes; |
| @@ -1867,7 +1882,7 @@ public: · 7 unmodified lines | ||
| 1867 | 1882 | |
| 1868 | 1883 | unsigned long expectedMax; |
| 1869 | 1884 | |
| 1870 | − bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM]; | |
| 1885 | + bool* hasIndexFound; | |
| 1871 | 1886 | }; |
| 1872 | 1887 | |
| 1873 | 1888 | bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) { |
| @@ -1934,7 +1949,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 60 unmodified lines | ||
| 1934 | 1949 | } |
| 1935 | 1950 | } |
| 1936 | 1951 | |
| 1937 | − collectStatsForTreesAndVBOsArgs args; | |
| 1952 | + collectStatsForTreesAndVBOsArgs args(_maxVoxels); | |
| 1938 | 1953 | args.expectedMax = _voxelsInWriteArrays; |
| 1939 | 1954 | |
| 1940 | 1955 | qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n"); |
| @@ -1953,7 +1968,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 12 unmodified lines | ||
| 1953 | 1968 | glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; |
| 1954 | 1969 | glBufferIndex maxInVBO = 0; |
| 1955 | 1970 | |
| 1956 | − for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) { | |
| 1971 | + for (glBufferIndex i = 0; i < _maxVoxels; i++) { | |
| 1957 | 1972 | if (args.hasIndexFound[i]) { |
| 1958 | 1973 | minInVBO = std::min(minInVBO,i); |
| 1959 | 1974 | maxInVBO = std::max(maxInVBO,i); |
| @@ -1972,13 +1987,12 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 12 unmodified lines | ||
| 1972 | 1987 | |
| 1973 | 1988 | void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { |
| 1974 | 1989 | pthread_mutex_lock(&_treeLock); |
| 1975 | − | |
| 1976 | 1990 | _tree->deleteVoxelAt(x, y, z, s); |
| 1991 | + pthread_mutex_unlock(&_treeLock); | |
| 1977 | 1992 | |
| 1978 | 1993 | // redraw! |
| 1979 | 1994 | setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in? |
| 1980 | 1995 | |
| 1981 | − pthread_mutex_unlock(&_treeLock); | |
| 1982 | 1996 | }; |
| 1983 | 1997 | |
| 1984 | 1998 | VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { |
| @@ -2313,17 +2327,22 @@ void VoxelSystem::nodeKilled(Node* node) { · 328 unmodified lines | ||
| 2313 | 2327 | |
| 2314 | 2328 | if (_voxelServerCount > 0) { |
| 2315 | 2329 | // Kill any voxels from the local tree that match this nodeID |
| 2330 | + pthread_mutex_lock(&_treeLock); | |
| 2316 | 2331 | _tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeID); |
| 2332 | + pthread_mutex_unlock(&_treeLock); | |
| 2317 | 2333 | _tree->setDirtyBit(); |
| 2334 | + setupNewVoxelsForDrawing(); | |
| 2318 | 2335 | } else { |
| 2319 | 2336 | // Last server, take the easy way and kill all the local voxels! |
| 2320 | − _tree->eraseAllVoxels(); | |
| 2321 | − _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this?? | |
| 2337 | + killLocalVoxels(); | |
| 2322 | 2338 | } |
| 2323 | − setupNewVoxelsForDrawing(); | |
| 2324 | 2339 | } |
| 2325 | 2340 | } |
| 2326 | 2341 | |
| 2342 | +void VoxelSystem::domainChanged(QString domain) { | |
| 2343 | + killLocalVoxels(); | |
| 2344 | +} | |
| 2345 | + | |
| 2327 | 2346 | |
| 2328 | 2347 | unsigned long VoxelSystem::getFreeMemoryGPU() { |
| 2329 | 2348 | // We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free. |