Showing the changes to interface/src/VoxelSystem.cpp (1 of 5 files). Show all
Unified · Split
| @@ -268,6 +268,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { · 267 unmodified lines | ||
| 268 | 268 | *(writeColorsAt +j) = node->getColor()[j % 3]; |
| 269 | 269 | } |
| 270 | 270 | node->setBufferIndex(nodeIndex); |
| 271 | + _voxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode | |
| 271 | 272 | _voxelsInWriteArrays++; // our know vertices in the arrays |
| 272 | 273 | return 1; // rendered |
| 273 | 274 | } |
| @@ -280,8 +281,8 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 6 unmodified lines | ||
| 280 | 281 | return 0; |
| 281 | 282 | } |
| 282 | 283 | |
| 283 | − // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays... for us | |
| 284 | − if (node->isDirty() && (node->getShouldRender() || node->isKnownBufferIndex())) { | |
| 284 | + // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays... | |
| 285 | + if (node->isDirty()) { | |
| 285 | 286 | glm::vec3 startVertex; |
| 286 | 287 | float voxelScale = 0; |
| 287 | 288 | // If we're should render, use our legit location and scale, |
| @@ -301,8 +302,9 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 13 unmodified lines | ||
| 301 | 302 | nodeIndex = node->getBufferIndex(); |
| 302 | 303 | } else { |
| 303 | 304 | nodeIndex = _voxelsInWriteArrays; |
| 305 | + node->setBufferIndex(nodeIndex); | |
| 306 | + _voxelsInWriteArrays++; | |
| 304 | 307 | } |
| 305 | − | |
| 306 | 308 | _voxelDirtyArray[nodeIndex] = true; |
| 307 | 309 | |
| 308 | 310 | // populate the array with points for the 8 vertices |
| @@ -313,10 +315,6 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 4 unmodified lines | ||
| 313 | 315 | *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); |
| 314 | 316 | *(writeColorsAt +j) = node->getColor()[j % 3]; |
| 315 | 317 | } |
| 316 | − if (!node->isKnownBufferIndex()) { | |
| 317 | − node->setBufferIndex(nodeIndex); | |
| 318 | − _voxelsInWriteArrays++; // our know vertices in the arrays | |
| 319 | − } | |
| 320 | 318 | return 1; // updated! |
| 321 | 319 | } |
| 322 | 320 | return 0; // not-updated |
| @@ -424,11 +422,10 @@ void VoxelSystem::updateFullVBOs() { · 101 unmodified lines | ||
| 424 | 422 | glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); |
| 425 | 423 | |
| 426 | 424 | // consider the _voxelDirtyArray[] clean! |
| 427 | − memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); | |
| 425 | + memset(_voxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); | |
| 428 | 426 | } |
| 429 | 427 | |
| 430 | 428 | void VoxelSystem::updatePartialVBOs() { |
| 431 | − int segmentCount = 0; | |
| 432 | 429 | glBufferIndex segmentStart = 0; |
| 433 | 430 | glBufferIndex segmentEnd = 0; |
| 434 | 431 | bool inSegment = false; |
| @@ -457,11 +454,6 @@ void VoxelSystem::updatePartialVBOs() { · 22 unmodified lines | ||
| 457 | 454 | GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); |
| 458 | 455 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); |
| 459 | 456 | glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); |
| 460 | − | |
| 461 | − // debug | |
| 462 | − segmentCount++; | |
| 463 | − printLog("updatePartialVBOs() start=%ld, end=%ld, length=%ld, segmentCount=%d \n", | |
| 464 | − segmentStart, segmentEnd, segmentLength, segmentCount); | |
| 465 | 457 | } |
| 466 | 458 | _voxelDirtyArray[i] = false; // consider us clean! |
| 467 | 459 | } |
| @@ -482,43 +474,7 @@ void VoxelSystem::updatePartialVBOs() { · 14 unmodified lines | ||
| 482 | 474 | GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); |
| 483 | 475 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); |
| 484 | 476 | glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); |
| 485 | − | |
| 486 | − // debug | |
| 487 | − segmentCount++; | |
| 488 | − printLog("updatePartialVBOs() start=%ld, end=%ld, length=%ld, segmentCount=%d \n", | |
| 489 | − segmentStart, segmentEnd, segmentLength, segmentCount); | |
| 490 | − } | |
| 491 | −} | |
| 492 | − | |
| 493 | −void debugOpenGLError(const char* label) { | |
| 494 | − GLenum error = glGetError(); | |
| 495 | − const char* errorMessage; | |
| 496 | − switch (error) { | |
| 497 | − case GL_NO_ERROR: | |
| 498 | − return; | |
| 499 | − case GL_INVALID_ENUM: | |
| 500 | − errorMessage = "GL_INVALID_ENUM"; | |
| 501 | − break; | |
| 502 | − case GL_INVALID_VALUE: | |
| 503 | − errorMessage = "GL_INVALID_VALUE"; | |
| 504 | − break; | |
| 505 | − case GL_INVALID_OPERATION: | |
| 506 | − errorMessage = "GL_INVALID_OPERATION"; | |
| 507 | − break; | |
| 508 | − case GL_STACK_OVERFLOW: | |
| 509 | − errorMessage = "GL_STACK_OVERFLOW"; | |
| 510 | − break; | |
| 511 | − case GL_STACK_UNDERFLOW: | |
| 512 | − errorMessage = "GL_STACK_UNDERFLOW"; | |
| 513 | − break; | |
| 514 | − case GL_OUT_OF_MEMORY: | |
| 515 | − errorMessage = "GL_OUT_OF_MEMORY"; | |
| 516 | − break; | |
| 517 | − case GL_INVALID_FRAMEBUFFER_OPERATION: | |
| 518 | − errorMessage = "GL_INVALID_FRAMEBUFFER_OPERATION"; | |
| 519 | − break; | |
| 520 | − } | |
| 521 | − printLog("%s generated %s", label, errorMessage); | |
| 477 | + } | |
| 522 | 478 | } |
| 523 | 479 | |
| 524 | 480 | void VoxelSystem::updateJustEnoughVBOs() { |
| @@ -538,31 +494,17 @@ void VoxelSystem::updateJustEnoughVBOs() { · 13 unmodified lines | ||
| 538 | 494 | if (somethingDirty) { |
| 539 | 495 | glBufferIndex segmentStart = minDirty; |
| 540 | 496 | glBufferIndex segmentEnd = maxDirty; |
| 541 | − | |
| 542 | −glGetError(); // clear errors | |
| 543 | − | |
| 544 | 497 | int segmentLength = (segmentEnd - segmentStart) + 1; |
| 545 | 498 | GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); |
| 546 | 499 | GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); |
| 547 | 500 | GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); |
| 548 | 501 | glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); |
| 549 | −debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID)"); | |
| 550 | − | |
| 551 | 502 | glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); |
| 552 | −debugOpenGLError("glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom)"); | |
| 553 | − | |
| 554 | 503 | segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); |
| 555 | 504 | segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); |
| 556 | 505 | GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); |
| 557 | − | |
| 558 | 506 | glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); |
| 559 | −debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID)"); | |
| 560 | − | |
| 561 | 507 | glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); |
| 562 | −debugOpenGLError("glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom)"); | |
| 563 | − | |
| 564 | − // debug | |
| 565 | − printLog("updateJustEnoughVBOs() start=%ld, end=%ld, length=%ld, \n", segmentStart, segmentEnd, segmentLength); | |
| 566 | 508 | } |
| 567 | 509 | } |
| 568 | 510 | |
| @@ -574,8 +516,7 @@ void VoxelSystem::updateVBOs() { · 5 unmodified lines | ||
| 574 | 516 | PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays |
| 575 | 517 | if (_voxelsDirty) { |
| 576 | 518 | // updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs() |
| 577 | − bool alwaysRenderFullVBO = true; | |
| 578 | − if (alwaysRenderFullVBO || _renderFullVBO) { | |
| 519 | + if (_renderFullVBO) { | |
| 579 | 520 | updateFullVBOs(); |
| 580 | 521 | } else { |
| 581 | 522 | updateJustEnoughVBOs(); |
| @@ -832,6 +773,9 @@ void VoxelSystem::removeOutOfView() { · 250 unmodified lines | ||
| 832 | 773 | removeOutOfViewArgs args(this); |
| 833 | 774 | _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args); |
| 834 | 775 | |
| 776 | + if (args.nodesRemoved) { | |
| 777 | + _tree->setDirtyBit(); | |
| 778 | + } | |
| 835 | 779 | bool showRemoveDebugDetails = false; |
| 836 | 780 | if (showRemoveDebugDetails) { |
| 837 | 781 | printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n", |
| @@ -841,6 +785,22 @@ void VoxelSystem::removeOutOfView() { · 3 unmodified lines | ||
| 841 | 785 | } |
| 842 | 786 | } |
| 843 | 787 | |
| 788 | +bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, | |
| 789 | + VoxelDetail& detail, float& distance, BoxFace& face) { | |
| 790 | + VoxelNode* node; | |
| 791 | + if (!_tree->findRayIntersection(origin, direction, node, distance, face)) { | |
| 792 | + return false; | |
| 793 | + } | |
| 794 | + detail.x = node->getCorner().x; | |
| 795 | + detail.y = node->getCorner().y; | |
| 796 | + detail.z = node->getCorner().z; | |
| 797 | + detail.s = node->getScale(); | |
| 798 | + detail.red = node->getColor()[0]; | |
| 799 | + detail.green = node->getColor()[1]; | |
| 800 | + detail.blue = node->getColor()[2]; | |
| 801 | + return true; | |
| 802 | +} | |
| 803 | + | |
| 844 | 804 | class falseColorizeRandomEveryOtherArgs { |
| 845 | 805 | public: |
| 846 | 806 | falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {}; |
| @@ -872,19 +832,101 @@ void VoxelSystem::falseColorizeRandomEveryOther() { · 25 unmodified lines | ||
| 872 | 832 | setupNewVoxelsForDrawing(); |
| 873 | 833 | } |
| 874 | 834 | |
| 875 | −bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, | |
| 876 | − VoxelDetail& detail, float& distance, BoxFace& face) { | |
| 877 | − VoxelNode* node; | |
| 878 | − if (!_tree->findRayIntersection(origin, direction, node, distance, face)) { | |
| 879 | − return false; | |
| 835 | +class collectStatsForTreesAndVBOsArgs { | |
| 836 | +public: | |
| 837 | + collectStatsForTreesAndVBOsArgs() : | |
| 838 | + totalNodes(0), | |
| 839 | + dirtyNodes(0), | |
| 840 | + shouldRenderNodes(0), | |
| 841 | + coloredNodes(0), | |
| 842 | + nodesInVBO(0), | |
| 843 | + nodesInVBOOverExpectedMax(0), | |
| 844 | + duplicateVBOIndex(0) | |
| 845 | + { | |
| 846 | + memset(hasIndexFound, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); | |
| 847 | + }; | |
| 848 | + | |
| 849 | + unsigned long totalNodes; | |
| 850 | + unsigned long dirtyNodes; | |
| 851 | + unsigned long shouldRenderNodes; | |
| 852 | + unsigned long coloredNodes; | |
| 853 | + unsigned long nodesInVBO; | |
| 854 | + unsigned long nodesInVBOOverExpectedMax; | |
| 855 | + unsigned long duplicateVBOIndex; | |
| 856 | + unsigned long expectedMax; | |
| 857 | + | |
| 858 | + bool colorThis; | |
| 859 | + bool hasIndexFound[MAX_VOXELS_PER_SYSTEM]; | |
| 860 | +}; | |
| 861 | + | |
| 862 | +bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) { | |
| 863 | + collectStatsForTreesAndVBOsArgs* args = (collectStatsForTreesAndVBOsArgs*)extraData; | |
| 864 | + args->totalNodes++; | |
| 865 | + | |
| 866 | + if (node->isColored()) { | |
| 867 | + args->coloredNodes++; | |
| 880 | 868 | } |
| 881 | − detail.x = node->getCorner().x; | |
| 882 | − detail.y = node->getCorner().y; | |
| 883 | − detail.z = node->getCorner().z; | |
| 884 | − detail.s = node->getScale(); | |
| 885 | − detail.red = node->getColor()[0]; | |
| 886 | − detail.green = node->getColor()[1]; | |
| 887 | − detail.blue = node->getColor()[2]; | |
| 888 | − return true; | |
| 869 | + | |
| 870 | + if (node->getShouldRender()) { | |
| 871 | + args->shouldRenderNodes++; | |
| 872 | + } | |
| 873 | + | |
| 874 | + if (node->isDirty()) { | |
| 875 | + args->dirtyNodes++; | |
| 876 | + } | |
| 877 | + | |
| 878 | + if (node->isKnownBufferIndex()) { | |
| 879 | + args->nodesInVBO++; | |
| 880 | + unsigned long nodeIndex = node->getBufferIndex(); | |
| 881 | + if (args->hasIndexFound[nodeIndex]) { | |
| 882 | + args->duplicateVBOIndex++; | |
| 883 | + printLog("duplicateVBO found... index=%ld, isDirty=%s, shouldRender=%s \n", nodeIndex, | |
| 884 | + node->isDirty() ? "yes" : "no" , node->getShouldRender() ? "yes" : "no" ); | |
| 885 | + } else { | |
| 886 | + args->hasIndexFound[nodeIndex] = true; | |
| 887 | + } | |
| 888 | + if (nodeIndex > args->expectedMax) { | |
| 889 | + args->nodesInVBOOverExpectedMax++; | |
| 890 | + } | |
| 891 | + } | |
| 892 | + | |
| 893 | + return true; // keep going! | |
| 889 | 894 | } |
| 890 | 895 | |
| 896 | +void VoxelSystem::collectStatsForTreesAndVBOs() { | |
| 897 | + | |
| 898 | + glBufferIndex minDirty = GLBUFFER_INDEX_UNKNOWN; | |
| 899 | + glBufferIndex maxDirty = 0; | |
| 900 | + | |
| 901 | + for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { | |
| 902 | + if (_voxelDirtyArray[i]) { | |
| 903 | + minDirty = std::min(minDirty,i); | |
| 904 | + maxDirty = std::max(maxDirty,i); | |
| 905 | + } | |
| 906 | + } | |
| 907 | + | |
| 908 | + collectStatsForTreesAndVBOsArgs args; | |
| 909 | + args.expectedMax = _voxelsInWriteArrays; | |
| 910 | + _tree->recurseTreeWithOperation(collectStatsForTreesAndVBOsOperation,&args); | |
| 911 | + | |
| 912 | + printLog("_voxelsDirty=%s _voxelsInWriteArrays=%ld minDirty=%ld maxDirty=%ld \n", (_voxelsDirty ? "yes" : "no"), | |
| 913 | + _voxelsInWriteArrays, minDirty, maxDirty); | |
| 914 | + | |
| 915 | + printLog("stats: total %ld, dirty %ld, colored %ld, shouldRender %ld, inVBO %ld, nodesInVBOOverExpectedMax %ld, duplicateVBOIndex %ld\n", | |
| 916 | + args.totalNodes, args.dirtyNodes, args.coloredNodes, args.shouldRenderNodes, | |
| 917 | + args.nodesInVBO, args.nodesInVBOOverExpectedMax, args.duplicateVBOIndex); | |
| 918 | + | |
| 919 | + glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; | |
| 920 | + glBufferIndex maxInVBO = 0; | |
| 921 | + | |
| 922 | + for (glBufferIndex i = 0; i < MAX_VOXELS_PER_SYSTEM; i++) { | |
| 923 | + if (args.hasIndexFound[i]) { | |
| 924 | + minInVBO = std::min(minInVBO,i); | |
| 925 | + maxInVBO = std::max(maxInVBO,i); | |
| 926 | + } | |
| 927 | + } | |
| 928 | + | |
| 929 | + printLog("minInVBO=%ld maxInVBO=%ld _voxelsInWriteArrays=%ld _voxelsInReadArrays=%ld\n", | |
| 930 | + minInVBO, maxInVBO, _voxelsInWriteArrays, _voxelsInReadArrays); | |
| 931 | + | |
| 932 | +} | |