Showing the changes to interface/src/VoxelSystem.cpp (1 of 2 files). Show all
Unified · Split
| @@ -60,6 +60,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) · 59 unmodified lines | |||
| 60 | _treeScale(treeScale), | 60 | _treeScale(treeScale), |
| 61 | _maxVoxels(maxVoxels), | 61 | _maxVoxels(maxVoxels), |
| 62 | _initialized(false), | 62 | _initialized(false), |
| 63 | _showCulledSharedFaces(false), | ||
| 63 | _usePrimitiveRenderer(false), | 64 | _usePrimitiveRenderer(false), |
| 64 | _renderer(0) { | 65 | _renderer(0) { |
| 65 | 66 | ||
| @@ -350,8 +351,7 @@ void VoxelSystem::cleanupVoxelMemory() { · 284 unmodified lines | |||
| 350 | 351 | ||
| 351 | _writeVoxelShaderData = _readVoxelShaderData = NULL; | 352 | _writeVoxelShaderData = _readVoxelShaderData = NULL; |
| 352 | 353 | ||
| 353 | } else | 354 | } else { |
| 354 | if (! _usePrimitiveRenderer) { | ||
| 355 | // Destroy glBuffers | 355 | // Destroy glBuffers |
| 356 | glDeleteBuffers(1, &_vboVerticesID); | 356 | glDeleteBuffers(1, &_vboVerticesID); |
| 357 | glDeleteBuffers(1, &_vboColorsID); | 357 | glDeleteBuffers(1, &_vboColorsID); |
| @@ -373,10 +373,8 @@ void VoxelSystem::cleanupVoxelMemory() { · 15 unmodified lines | |||
| 373 | _readColorsArray = NULL; | 373 | _readColorsArray = NULL; |
| 374 | _writeColorsArray = NULL; | 374 | _writeColorsArray = NULL; |
| 375 | } | 375 | } |
| 376 | else { | 376 | delete _renderer; |
| 377 | delete _renderer; | 377 | _renderer = 0; |
| 378 | _renderer = 0; | ||
| 379 | } | ||
| 380 | delete[] _writeVoxelDirtyArray; | 378 | delete[] _writeVoxelDirtyArray; |
| 381 | delete[] _readVoxelDirtyArray; | 379 | delete[] _readVoxelDirtyArray; |
| 382 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; | 380 | _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; |
| @@ -461,8 +459,7 @@ void VoxelSystem::initVoxelMemory() { · 78 unmodified lines | |||
| 461 | 459 | ||
| 462 | _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; | 460 | _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; |
| 463 | _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); | 461 | _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); |
| 464 | } else | 462 | } else { |
| 465 | if (! _usePrimitiveRenderer) { | ||
| 466 | 463 | ||
| 467 | // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead | 464 | // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead |
| 468 | // rendering the voxel faces in 6 passes that use a global call to glNormal3f() | 465 | // rendering the voxel faces in 6 passes that use a global call to glNormal3f() |
| @@ -525,27 +522,7 @@ void VoxelSystem::initVoxelMemory() { · 56 unmodified lines | |||
| 525 | _shadowMapProgram.release(); | 522 | _shadowMapProgram.release(); |
| 526 | } | 523 | } |
| 527 | } | 524 | } |
| 528 | else { | 525 | _renderer = new PrimitiveRenderer(_maxVoxels); |
| 529 | _renderer = new PrimitiveRenderer(_maxVoxels); | ||
| 530 | // create our simple fragment shader if we're the first system to init | ||
| 531 | if (!_perlinModulateProgram.isLinked()) { | ||
| 532 | switchToResourcesParentIfRequired(); | ||
| 533 | _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Vertex, "resources/shaders/perlin_modulate.vert"); | ||
| 534 | _perlinModulateProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/perlin_modulate.frag"); | ||
| 535 | _perlinModulateProgram.link(); | ||
| 536 | |||
| 537 | _perlinModulateProgram.bind(); | ||
| 538 | _perlinModulateProgram.setUniformValue("permutationNormalTexture", 0); | ||
| 539 | _perlinModulateProgram.release(); | ||
| 540 | |||
| 541 | _shadowMapProgram.addShaderFromSourceFile(QGLShader::Fragment, "resources/shaders/shadow_map.frag"); | ||
| 542 | _shadowMapProgram.link(); | ||
| 543 | |||
| 544 | _shadowMapProgram.bind(); | ||
| 545 | _shadowMapProgram.setUniformValue("shadowMap", 0); | ||
| 546 | _shadowMapProgram.release(); | ||
| 547 | } | ||
| 548 | } | ||
| 549 | 526 | ||
| 550 | _initialized = true; | 527 | _initialized = true; |
| 551 | 528 | ||
| @@ -690,12 +667,9 @@ void VoxelSystem::setupNewVoxelsForDrawing() { · 138 unmodified lines | |||
| 690 | 667 | ||
| 691 | if (_writeRenderFullVBO) { | 668 | if (_writeRenderFullVBO) { |
| 692 | if (_usePrimitiveRenderer) { | 669 | if (_usePrimitiveRenderer) { |
| 693 | delete _renderer; | 670 | _renderer->release(); |
| 694 | _renderer = new PrimitiveRenderer(_maxVoxels); | ||
| 695 | } | ||
| 696 | else { | ||
| 697 | clearFreeBufferIndexes(); | ||
| 698 | } | 671 | } |
| 672 | clearFreeBufferIndexes(); | ||
| 699 | } | 673 | } |
| 700 | _voxelsUpdated = newTreeToArrays(_tree->getRoot()); | 674 | _voxelsUpdated = newTreeToArrays(_tree->getRoot()); |
| 701 | _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean | 675 | _tree->clearDirtyBit(); // after we pull the trees into the array, we can consider the tree clean |
| @@ -851,7 +825,8 @@ void VoxelSystem::cleanupRemovedVoxels() { · 149 unmodified lines | |||
| 851 | // we also might have VBO slots that have been abandoned, if too many of our VBO slots | 825 | // we also might have VBO slots that have been abandoned, if too many of our VBO slots |
| 852 | // are abandonded we want to rerender our full VBOs | 826 | // are abandonded we want to rerender our full VBOs |
| 853 | const float TOO_MANY_ABANDONED_RATIO = 0.5f; | 827 | const float TOO_MANY_ABANDONED_RATIO = 0.5f; |
| 854 | if (!_writeRenderFullVBO && (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) { | 828 | if (!_usePrimitiveRenderer && !_writeRenderFullVBO && |
| 829 | (_abandonedVBOSlots > (_voxelsInWriteArrays * TOO_MANY_ABANDONED_RATIO))) { | ||
| 855 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { | 830 | if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { |
| 856 | qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots [" | 831 | qDebug() << "cleanupRemovedVoxels().. _abandonedVBOSlots [" |
| 857 | << _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO"; | 832 | << _abandonedVBOSlots << "] > TOO_MANY_ABANDONED_RATIO"; |
| @@ -1054,12 +1029,17 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo · 196 unmodified lines | |||
| 1054 | node->setVoxelSystem(this); | 1029 | node->setVoxelSystem(this); |
| 1055 | } | 1030 | } |
| 1056 | inspectForInteriorOcclusionsOperation(node, 0); | 1031 | inspectForInteriorOcclusionsOperation(node, 0); |
| 1057 | 1032 | unsigned char occlusions; | |
| 1058 | if (node->getInteriorOcclusions() != OctreeElement::HalfSpace::All) { | 1033 | if (_showCulledSharedFaces) { |
| 1034 | occlusions = ~node->getInteriorOcclusions(); | ||
| 1035 | } else { | ||
| 1036 | occlusions = node->getInteriorOcclusions(); | ||
| 1037 | } | ||
| 1038 | if (occlusions != OctreeElement::HalfSpace::All) { | ||
| 1059 | Cube* cube = new Cube( | 1039 | Cube* cube = new Cube( |
| 1060 | startVertex.x, startVertex.y, startVertex.z, voxelScale, | 1040 | startVertex.x, startVertex.y, startVertex.z, voxelScale, |
| 1061 | color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX], | 1041 | color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX], |
| 1062 | node->getInteriorOcclusions()); | 1042 | occlusions); |
| 1063 | if (cube) { | 1043 | if (cube) { |
| 1064 | primitiveIndex = _renderer->add(cube); | 1044 | primitiveIndex = _renderer->add(cube); |
| 1065 | node->setPrimitiveIndex(primitiveIndex); | 1045 | node->setPrimitiveIndex(primitiveIndex); |
| @@ -1491,6 +1471,7 @@ void VoxelSystem::killLocalVoxels() { · 425 unmodified lines | |||
| 1491 | _tree->eraseAllOctreeElements(); | 1471 | _tree->eraseAllOctreeElements(); |
| 1492 | unlockTree(); | 1472 | unlockTree(); |
| 1493 | clearFreeBufferIndexes(); | 1473 | clearFreeBufferIndexes(); |
| 1474 | _renderer->release(); | ||
| 1494 | _voxelsInReadArrays = 0; // do we need to do this? | 1475 | _voxelsInReadArrays = 0; // do we need to do this? |
| 1495 | setupNewVoxelsForDrawing(); | 1476 | setupNewVoxelsForDrawing(); |
| 1496 | } | 1477 | } |
| @@ -1541,7 +1522,7 @@ bool VoxelSystem::inspectForInteriorOcclusionsOperation(OctreeElement* element, · 44 unmodified lines | |||
| 1541 | // all faces which are completely covered by four child octants. | 1522 | // all faces which are completely covered by four child octants. |
| 1542 | unsigned char exteriorOcclusionsA = childA->getExteriorOcclusions(); | 1523 | unsigned char exteriorOcclusionsA = childA->getExteriorOcclusions(); |
| 1543 | 1524 | ||
| 1544 | if (exteriorOcclusionsA == 0) { | 1525 | if (exteriorOcclusionsA == OctreeElement::HalfSpace::None) { |
| 1545 | // There is nothing to be done with this child, next... | 1526 | // There is nothing to be done with this child, next... |
| 1546 | continue; | 1527 | continue; |
| 1547 | } | 1528 | } |
| @@ -1554,7 +1535,7 @@ bool VoxelSystem::inspectForInteriorOcclusionsOperation(OctreeElement* element, · 6 unmodified lines | |||
| 1554 | // Get child B's occluding faces | 1535 | // Get child B's occluding faces |
| 1555 | unsigned char exteriorOcclusionsB = childB->getExteriorOcclusions(); | 1536 | unsigned char exteriorOcclusionsB = childB->getExteriorOcclusions(); |
| 1556 | 1537 | ||
| 1557 | if (exteriorOcclusionsB == 0) { | 1538 | if (exteriorOcclusionsB == OctreeElement::HalfSpace::None) { |
| 1558 | // There is nothing to be done with this child, next... | 1539 | // There is nothing to be done with this child, next... |
| 1559 | continue; | 1540 | continue; |
| 1560 | } | 1541 | } |
| @@ -1580,7 +1561,7 @@ bool VoxelSystem::inspectForInteriorOcclusionsOperation(OctreeElement* element, · 19 unmodified lines | |||
| 1580 | 1561 | ||
| 1581 | // Inform the child | 1562 | // Inform the child |
| 1582 | childA->setInteriorOcclusions(occludedSharedFace[i]); | 1563 | childA->setInteriorOcclusions(occludedSharedFace[i]); |
| 1583 | if (occludedSharedFace[i]) { | 1564 | if (occludedSharedFace[i] != OctreeElement::HalfSpace::None) { |
| 1584 | //const glm::vec3& v = voxel->getCorner(); | 1565 | //const glm::vec3& v = voxel->getCorner(); |
| 1585 | //float s = voxel->getScale(); | 1566 | //float s = voxel->getScale(); |
| 1586 | 1567 | ||
| @@ -1630,7 +1611,7 @@ bool VoxelSystem::inspectForExteriorOcclusionsOperation(OctreeElement* element, · 43 unmodified lines | |||
| 1630 | { | 1611 | { |
| 1631 | // Derive the exterior occlusions of the voxel elements from the exclusions | 1612 | // Derive the exterior occlusions of the voxel elements from the exclusions |
| 1632 | // of its children | 1613 | // of its children |
| 1633 | unsigned char exteriorOcclusions = 0; | 1614 | unsigned char exteriorOcclusions = OctreeElement::HalfSpace::None; |
| 1634 | for (int i = 6; --i >= 0; ) { | 1615 | for (int i = 6; --i >= 0; ) { |
| 1635 | if (exteriorOcclusionsCt[i] == 4) { | 1616 | if (exteriorOcclusionsCt[i] == 4) { |
| 1636 | 1617 | ||
| @@ -1653,7 +1634,7 @@ bool VoxelSystem::inspectForExteriorOcclusionsOperation(OctreeElement* element, · 16 unmodified lines | |||
| 1653 | // occupied. Hence, the subtree from this node could be | 1634 | // occupied. Hence, the subtree from this node could be |
| 1654 | // pruned and replaced by a leaf voxel, if the visible | 1635 | // pruned and replaced by a leaf voxel, if the visible |
| 1655 | // properties of the children are the same | 1636 | // properties of the children are the same |
| 1656 | } else if (exteriorOcclusions) { | 1637 | } else if (exteriorOcclusions != OctreeElement::HalfSpace::None) { |
| 1657 | //const glm::vec3& v = voxel->getCorner(); | 1638 | //const glm::vec3& v = voxel->getCorner(); |
| 1658 | //float s = voxel->getScale(); | 1639 | //float s = voxel->getScale(); |
| 1659 | 1640 | ||
| @@ -1675,11 +1656,11 @@ bool VoxelSystem::clearOcclusionsOperation(OctreeElement* element, void* extraDa · 15 unmodified lines | |||
| 1675 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::All); | 1656 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::All); |
| 1676 | 1657 | ||
| 1677 | // And the sibling occluders | 1658 | // And the sibling occluders |
| 1678 | voxel->setInteriorOcclusions(0); | 1659 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1679 | rc = false; | 1660 | rc = false; |
| 1680 | } else { | 1661 | } else { |
| 1681 | voxel->setExteriorOcclusions(0); | 1662 | voxel->setExteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1682 | voxel->setInteriorOcclusions(0); | 1663 | voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); |
| 1683 | rc = true; | 1664 | rc = true; |
| 1684 | } | 1665 | } |
| 1685 | 1666 | ||
| @@ -1690,10 +1671,9 @@ void VoxelSystem::cullSharedFaces() { · 4 unmodified lines | |||
| 1690 | _nodeCount = 0; | 1671 | _nodeCount = 0; |
| 1691 | 1672 | ||
| 1692 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { | 1673 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { |
| 1693 | cleanupVoxelMemory(); | ||
| 1694 | _useVoxelShader = false; | 1674 | _useVoxelShader = false; |
| 1695 | _usePrimitiveRenderer = true; | 1675 | _usePrimitiveRenderer = true; |
| 1696 | initVoxelMemory(); | 1676 | _renderer->release(); |
| 1697 | clearAllNodesBufferIndex(); | 1677 | clearAllNodesBufferIndex(); |
| 1698 | lockTree(); | 1678 | lockTree(); |
| 1699 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); | 1679 | _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); |
| @@ -1706,9 +1686,8 @@ void VoxelSystem::cullSharedFaces() { · 6 unmodified lines | |||
| 1706 | unlockTree(); | 1686 | unlockTree(); |
| 1707 | qDebug("culling shared faces in %d nodes", _nodeCount); | 1687 | qDebug("culling shared faces in %d nodes", _nodeCount); |
| 1708 | } else { | 1688 | } else { |
| 1709 | cleanupVoxelMemory(); | ||
| 1710 | _usePrimitiveRenderer = false; | 1689 | _usePrimitiveRenderer = false; |
| 1711 | initVoxelMemory(); | 1690 | _renderer->release(); |
| 1712 | clearAllNodesBufferIndex(); | 1691 | clearAllNodesBufferIndex(); |
| 1713 | lockTree(); | 1692 | lockTree(); |
| 1714 | _tree->recurseTreeWithOperation(clearOcclusionsOperation); | 1693 | _tree->recurseTreeWithOperation(clearOcclusionsOperation); |
| @@ -1723,6 +1702,18 @@ void VoxelSystem::cullSharedFaces() { · 8 unmodified lines | |||
| 1723 | 1702 | ||
| 1724 | } | 1703 | } |
| 1725 | 1704 | ||
| 1705 | void VoxelSystem::showCulledSharedFaces() { | ||
| 1706 | |||
| 1707 | if (Menu::getInstance()->isOptionChecked(MenuOption::ShowCulledSharedFaces)) { | ||
| 1708 | _showCulledSharedFaces = true; | ||
| 1709 | } else { | ||
| 1710 | _showCulledSharedFaces = false; | ||
| 1711 | } | ||
| 1712 | if (Menu::getInstance()->isOptionChecked(MenuOption::CullSharedFaces)) { | ||
| 1713 | cullSharedFaces(); | ||
| 1714 | } | ||
| 1715 | } | ||
| 1716 | |||
| 1726 | bool VoxelSystem::forceRedrawEntireTreeOperation(OctreeElement* element, void* extraData) { | 1717 | bool VoxelSystem::forceRedrawEntireTreeOperation(OctreeElement* element, void* extraData) { |
| 1727 | _nodeCount++; | 1718 | _nodeCount++; |
| 1728 | element->setDirtyBit(); | 1719 | element->setDirtyBit(); |
| @@ -2650,31 +2641,37 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { · 921 unmodified lines | |||
| 2650 | qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n", | 2641 | qDebug("Local Voxel Tree Statistics:\n total nodes %ld \n leaves %ld \n dirty %ld \n colored %ld \n shouldRender %ld \n", |
| 2651 | args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes); | 2642 | args.totalNodes, args.leafNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes); |
| 2652 | 2643 | ||
| 2653 | qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld", debug::valueOf(_voxelsDirty), | 2644 | if (!_usePrimitiveRenderer) { |
| 2654 | _voxelsInWriteArrays, minDirty, maxDirty); | 2645 | qDebug(" _voxelsDirty=%s \n _voxelsInWriteArrays=%ld \n minDirty=%ld \n maxDirty=%ld", debug::valueOf(_voxelsDirty), |
| 2646 | _voxelsInWriteArrays, minDirty, maxDirty); | ||
| 2655 | 2647 | ||
| 2656 | qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld", | 2648 | qDebug(" inVBO %ld \n nodesInVBOOverExpectedMax %ld \n duplicateVBOIndex %ld \n nodesInVBONotShouldRender %ld", |
| 2657 | args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender); | 2649 | args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex, args.nodesInVBONotShouldRender); |
| 2658 | 2650 | ||
| 2659 | qDebug(" inPrimitiveRenderer %ld \n completely culled %ld \n", | 2651 | qDebug(" memory usage %ld \n gpu memory usage %ld \n", _memoryUsageRAM, _memoryUsageVBO); |
| 2660 | args.nodesInPrimitiveRenderer, args.culledLeafNodes); | ||
| 2661 | 2652 | ||
| 2662 | glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; | 2653 | glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; |
| 2663 | glBufferIndex maxInVBO = 0; | 2654 | glBufferIndex maxInVBO = 0; |
| 2664 | 2655 | ||
| 2665 | for (glBufferIndex i = 0; i < _maxVoxels; i++) { | 2656 | for (glBufferIndex i = 0; i < _maxVoxels; i++) { |
| 2666 | if (args.hasIndexFound[i]) { | 2657 | if (args.hasIndexFound[i]) { |
| 2667 | minInVBO = std::min(minInVBO,i); | 2658 | minInVBO = std::min(minInVBO,i); |
| 2668 | maxInVBO = std::max(maxInVBO,i); | 2659 | maxInVBO = std::max(maxInVBO,i); |
| 2660 | } | ||
| 2669 | } | 2661 | } |
| 2670 | } | ||
| 2671 | 2662 | ||
| 2672 | qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld", | 2663 | qDebug(" minInVBO=%ld \n maxInVBO=%ld \n _voxelsInWriteArrays=%ld \n _voxelsInReadArrays=%ld", |
| 2673 | minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays); | 2664 | minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays); |
| 2674 | 2665 | ||
| 2675 | qDebug(" _freeIndexes.size()=%ld", | 2666 | qDebug(" _freeIndexes.size()=%ld", |
| 2676 | _freeIndexes.size()); | 2667 | _freeIndexes.size()); |
| 2668 | } else { | ||
| 2669 | qDebug(" PrimitiveRenderer nodes %ld \n completely culled nodes %ld \n", | ||
| 2670 | args.nodesInPrimitiveRenderer, args.culledLeafNodes); | ||
| 2677 | 2671 | ||
| 2672 | qDebug(" memory usage %ld \n gpu memory usage %ld \n", | ||
| 2673 | _renderer->getMemoryUsage(), _renderer->getMemoryUsageGPU()); | ||
| 2674 | } | ||
| 2678 | qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>"); | 2675 | qDebug("DONE WITH Local Voxel Tree Statistics >>>>>>>>>>>>"); |
| 2679 | } | 2676 | } |
| 2680 | 2677 | ||