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
268268 *(writeColorsAt +j) = node->getColor()[j % 3];
269269 }
270270 node->setBufferIndex(nodeIndex);
271+ _voxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode
271272 _voxelsInWriteArrays++; // our know vertices in the arrays
272273 return 1; // rendered
273274 }
@@ -280,8 +281,8 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 6 unmodified lines
280281 return 0;
281282 }
282283
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()) {
285286 glm::vec3 startVertex;
286287 float voxelScale = 0;
287288 // If we're should render, use our legit location and scale,
@@ -301,8 +302,9 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 13 unmodified lines
301302 nodeIndex = node->getBufferIndex();
302303 } else {
303304 nodeIndex = _voxelsInWriteArrays;
305+ node->setBufferIndex(nodeIndex);
306+ _voxelsInWriteArrays++;
304307 }
305−
306308 _voxelDirtyArray[nodeIndex] = true;
307309
308310 // populate the array with points for the 8 vertices
@@ -313,10 +315,6 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { · 4 unmodified lines
313315 *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale);
314316 *(writeColorsAt +j) = node->getColor()[j % 3];
315317 }
316− if (!node->isKnownBufferIndex()) {
317− node->setBufferIndex(nodeIndex);
318− _voxelsInWriteArrays++; // our know vertices in the arrays
319− }
320318 return 1; // updated!
321319 }
322320 return 0; // not-updated
@@ -424,11 +422,10 @@ void VoxelSystem::updateFullVBOs() { · 101 unmodified lines
424422 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom);
425423
426424 // consider the _voxelDirtyArray[] clean!
427− memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool));
425+ memset(_voxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool));
428426 }
429427
430428 void VoxelSystem::updatePartialVBOs() {
431− int segmentCount = 0;
432429 glBufferIndex segmentStart = 0;
433430 glBufferIndex segmentEnd = 0;
434431 bool inSegment = false;
@@ -457,11 +454,6 @@ void VoxelSystem::updatePartialVBOs() { · 22 unmodified lines
457454 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
458455 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
459456 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);
465457 }
466458 _voxelDirtyArray[i] = false; // consider us clean!
467459 }
@@ -482,43 +474,7 @@ void VoxelSystem::updatePartialVBOs() { · 14 unmodified lines
482474 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
483475 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
484476 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+ }
522478 }
523479
524480 void VoxelSystem::updateJustEnoughVBOs() {
@@ -538,31 +494,17 @@ void VoxelSystem::updateJustEnoughVBOs() { · 13 unmodified lines
538494 if (somethingDirty) {
539495 glBufferIndex segmentStart = minDirty;
540496 glBufferIndex segmentEnd = maxDirty;
541−
542−glGetError(); // clear errors
543−
544497 int segmentLength = (segmentEnd - segmentStart) + 1;
545498 GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
546499 GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat);
547500 GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
548501 glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID);
549−debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID)");
550−
551502 glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom);
552−debugOpenGLError("glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom)");
553−
554503 segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
555504 segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte);
556505 GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL);
557−
558506 glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID);
559−debugOpenGLError("glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID)");
560−
561507 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);
566508 }
567509 }
568510
@@ -574,8 +516,7 @@ void VoxelSystem::updateVBOs() { · 5 unmodified lines
574516 PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays
575517 if (_voxelsDirty) {
576518 // updatePartialVBOs() is not yet working. For now, ALWAYS call updateFullVBOs()
577− bool alwaysRenderFullVBO = true;
578− if (alwaysRenderFullVBO || _renderFullVBO) {
519+ if (_renderFullVBO) {
579520 updateFullVBOs();
580521 } else {
581522 updateJustEnoughVBOs();
@@ -832,6 +773,9 @@ void VoxelSystem::removeOutOfView() { · 250 unmodified lines
832773 removeOutOfViewArgs args(this);
833774 _tree->recurseTreeWithOperation(removeOutOfViewOperation,(void*)&args);
834775
776+ if (args.nodesRemoved) {
777+ _tree->setDirtyBit();
778+ }
835779 bool showRemoveDebugDetails = false;
836780 if (showRemoveDebugDetails) {
837781 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
841785 }
842786 }
843787
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+
844804 class falseColorizeRandomEveryOtherArgs {
845805 public:
846806 falseColorizeRandomEveryOtherArgs() : totalNodes(0), colorableNodes(0), coloredNodes(0), colorThis(true) {};
@@ -872,19 +832,101 @@ void VoxelSystem::falseColorizeRandomEveryOther() { · 25 unmodified lines
872832 setupNewVoxelsForDrawing();
873833 }
874834
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++;
880868 }
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!
889894 }
890895
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+}