History

fixed partial VBO updates

ZappoMan committed 13 years ago

Commit 33fc9f51 parent 7b223005 files · +144 −82Browse files

Showing the changes to interface/src/VoxelSystem.cpp (1 of 5 files). Show all

Unified · Split

interface/src/VoxelSystem.cpp+122−80
@@ -268,6 +268,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { · 267 unmodified lines
268 *(writeColorsAt +j) = node->getColor()[j % 3];268 *(writeColorsAt +j) = node->getColor()[j % 3];
269 }269 }
270 node->setBufferIndex(nodeIndex);270 node->setBufferIndex(nodeIndex);
271 _voxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode
271 _voxelsInWriteArrays++; // our know vertices in the arrays272 _voxelsInWriteArrays++; // our know vertices in the arrays
272 return 1; // rendered273 return 1; // rendered
273 } 274 }
@@ -280,8 +281,8 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 6 unmodified lines
280 return 0;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 us284 // Now, if we've changed any attributes (our renderness, our color, etc) then update the Arrays...
284 if (node->isDirty() && (node->getShouldRender() || node->isKnownBufferIndex())) {285 if (node->isDirty()) {
285 glm::vec3 startVertex;286 glm::vec3 startVertex;
286 float voxelScale = 0;287 float voxelScale = 0;
287 // If we're should render, use our legit location and scale, 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 nodeIndex = node->getBufferIndex();302 nodeIndex = node->getBufferIndex();
302 } else {303 } else {
303 nodeIndex = _voxelsInWriteArrays;304 nodeIndex = _voxelsInWriteArrays;
305 node->setBufferIndex(nodeIndex);
306 _voxelsInWriteArrays++;
304 }307 }
305
306 _voxelDirtyArray[nodeIndex] = true;308 _voxelDirtyArray[nodeIndex] = true;
307 309
308 // populate the array with points for the 8 vertices310 // populate the array with points for the 8 vertices
@@ -313,10 +315,6 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 4 unmodified lines
313 *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);315 *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
314 *(writeColorsAt +j) = node->getColor()[j % 3];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 return 1; // updated!318 return 1; // updated!
321 }319 }
322 return 0; // not-updated320 return 0; // not-updated
@@ -424,11 +422,10 @@ void VoxelSystem::updateFullVBOs() { · 101 unmodified lines
424 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);422 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
425 423
426 // consider the _voxelDirtyArray[] clean!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
430void VoxelSystem::updatePartialVBOs() {428void VoxelSystem::updatePartialVBOs() {
431 int segmentCount = 0;
432 glBufferIndex segmentStart = 0;429 glBufferIndex segmentStart = 0;
433 glBufferIndex segmentEnd = 0;430 glBufferIndex segmentEnd = 0;
434 bool inSegment = false;431 bool inSegment = false;
@@ -457,11 +454,6 @@ void VoxelSystem::updatePartialVBOs() { · 22 unmodified lines
457 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);454 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
458 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);455 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
459 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);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 _voxelDirtyArray[i] = false; // consider us clean!458 _voxelDirtyArray[i] = false; // consider us clean!
467 }459 }
@@ -482,43 +474,7 @@ void VoxelSystem::updatePartialVBOs() { · 14 unmodified lines
482 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);474 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
483 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);475 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
484 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);476 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
485 477 }
486 // debug
487 segmentCount++;
488 printLog("updatePartialVBOs() start=%ld, end=%ld, length=%ld, segmentCount=%d \n",
489 segmentStart, segmentEnd, segmentLength, segmentCount);
490 }
491}
492
493void 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);
522}478}
523 479
524void VoxelSystem::updateJustEnoughVBOs() {480void VoxelSystem::updateJustEnoughVBOs() {
@@ -538,31 +494,17 @@ void VoxelSystem::updateJustEnoughVBOs() { · 13 unmodified lines
538 if (somethingDirty) {494 if (somethingDirty) {
539 glBufferIndex segmentStart = minDirty;495 glBufferIndex segmentStart = minDirty;
540 glBufferIndex segmentEnd = maxDirty;496 glBufferIndex segmentEnd = maxDirty;
541
542glGetError(); // clear errors
543
544 int segmentLength = (segmentEnd - segmentStart) + 1;497 int segmentLength = (segmentEnd - segmentStart) + 1;
545 GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);498 GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
546 GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);499 GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
547 GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);500 GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
548 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);501 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
549debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID)");
550
551 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);502 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
552debugOpenGLError("glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom)");
553
554 segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);503 segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
555 segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);504 segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
556 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);505 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
557
558 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);506 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
559debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID)");
560
561 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);507 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
562debugOpenGLError("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 PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays516 PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
575 if (_voxelsDirty) {517 if (_voxelsDirty) {
576 // updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()518 // updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()
577 bool alwaysRenderFullVBO = true;519 if (_renderFullVBO) {
578 if (alwaysRenderFullVBO || _renderFullVBO) {
579 updateFullVBOs();520 updateFullVBOs();
580 } else {521 } else {
581 updateJustEnoughVBOs();522 updateJustEnoughVBOs();
@@ -832,6 +773,9 @@ void VoxelSystem::removeOutOfView() { · 250 unmodified lines
832 removeOutOfViewArgs args(this);773 removeOutOfViewArgs args(this);
833 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);774 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
834 775
776 if (args.nodesRemoved) {
777 _tree->setDirtyBit();
778 }
835 bool showRemoveDebugDetails = false;779 bool showRemoveDebugDetails = false;
836 if (showRemoveDebugDetails) {780 if (showRemoveDebugDetails) {
837 printLog("removeOutOfView() scanned=%ld removed=%ld inside=%ld intersect=%ld outside=%ld _removedVoxels.count()=%d \n", 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
788bool 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
844class falseColorizeRandomEveryOtherArgs {804class falseColorizeRandomEveryOtherArgs {
845public:805public:
846 falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};806 falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};
@@ -872,19 +832,101 @@ void VoxelSystem::falseColorizeRandomEveryOther() { · 25 unmodified lines
872 setupNewVoxelsForDrawing();832 setupNewVoxelsForDrawing();
873}833}
874 834
875bool VoxelSystem::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction,835class collectStatsForTreesAndVBOsArgs {
876 VoxelDetail& detail, float& distance, BoxFace& face) {836public:
877 VoxelNode* node;837 collectStatsForTreesAndVBOsArgs() :
878 if (!_tree->findRayIntersection(origin, direction, node, distance, face)) {838 totalNodes(0),
879 return false;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
862bool 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;869
882 detail.y = node->getCorner().y;870 if (node->getShouldRender()) {
883 detail.z = node->getCorner().z;871 args->shouldRenderNodes++;
884 detail.s = node->getScale();872 }
885 detail.red = node->getColor()[0];873
886 detail.green = node->getColor()[1];874 if (node->isDirty()) {
887 detail.blue = node->getColor()[2];875 args->dirtyNodes++;
888 return true;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
896void 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}