From 85dc14bb94d995206f7c8cb7eee7bf3245e5ebeb Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 12:01:33 -0700 Subject: [PATCH 1/4] Drag support for adding/removing (as well as coloring) voxels. I had to ensure that the "last" voxel edited was the one under the cursor after the operation, not the one operated on. --- interface/src/Application.cpp | 51 +++++++++++++++++++++-------------- interface/src/Application.h | 3 ++- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7974b2bdf8..f5f0970394 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -138,6 +138,7 @@ Application::Application(int& argc, char** argv) : _mouseY(0), _mousePressed(false), _mouseVoxelScale(1.0f / 1024.0f), + _justEditedVoxel(false), _paintOn(false), _dominantColor(0), _perfStatsOn(false), @@ -737,8 +738,13 @@ void Application::mouseMoveEvent(QMouseEvent* event) { // detect drag glm::vec3 mouseVoxelPos(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); - if (_colorVoxelMode->isChecked() && event->buttons().testFlag(Qt::LeftButton) && mouseVoxelPos != _lastMouseVoxelPos) { - addVoxelUnderCursor(); + if (!_justEditedVoxel && mouseVoxelPos != _lastMouseVoxelPos) { + if (event->buttons().testFlag(Qt::LeftButton)) { + maybeEditVoxelUnderCursor(); + + } else if (event->buttons().testFlag(Qt::RightButton) && checkedVoxelModeAction() != 0) { + deleteVoxelUnderCursor(); + } } } @@ -747,13 +753,8 @@ void Application::mousePressEvent(QMouseEvent* event) { _mouseX = event->x(); _mouseY = event->y(); _mousePressed = true; - - if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { - addVoxelUnderCursor(); + maybeEditVoxelUnderCursor(); - } else if (_deleteVoxelMode->isChecked()) { - deleteVoxelUnderCursor(); - } } else if (event->button() == Qt::RightButton && checkedVoxelModeAction() != 0) { deleteVoxelUnderCursor(); } @@ -926,6 +927,12 @@ void Application::idle() { _mouseVoxel.green = paintColor.green(); _mouseVoxel.blue = paintColor.blue(); } + + // if we just edited, use the currently selected voxel as the "last" for drag detection + if (_justEditedVoxel) { + _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + _justEditedVoxel = false; + } } // walking triggers the handControl to stop @@ -2015,18 +2022,22 @@ void Application::shiftPaintingColor() { _paintingVoxel.blue = (_dominantColor == 2) ? randIntInRange(200, 255) : randIntInRange(40, 100); } -void Application::addVoxelUnderCursor() { - if (_mouseVoxel.s != 0) { - PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? - PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); - sendVoxelEditMessage(message, _mouseVoxel); +void Application::maybeEditVoxelUnderCursor() { + if (_addVoxelMode->isChecked() || _colorVoxelMode->isChecked()) { + if (_mouseVoxel.s != 0) { + PACKET_HEADER message = (_destructiveAddVoxel->isChecked() ? + PACKET_HEADER_SET_VOXEL_DESTRUCTIVE : PACKET_HEADER_SET_VOXEL); + sendVoxelEditMessage(message, _mouseVoxel); + + // create the voxel locally so it appears immediately + _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, + _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked()); - // create the voxel locally so it appears immediately - _voxels.createVoxel(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s, - _mouseVoxel.red, _mouseVoxel.green, _mouseVoxel.blue, _destructiveAddVoxel->isChecked()); - - // remember the position for drag detection - _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + // remember the position for drag detection + _justEditedVoxel = true; + } + } else if (_deleteVoxelMode->isChecked()) { + deleteVoxelUnderCursor(); } } @@ -2038,7 +2049,7 @@ void Application::deleteVoxelUnderCursor() { _voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); // remember the position for drag detection - _lastMouseVoxelPos = glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z); + _justEditedVoxel = true; } } diff --git a/interface/src/Application.h b/interface/src/Application.h index da3898ab9f..87ea615ad8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -116,7 +116,7 @@ private: void setupPaintingVoxel(); void shiftPaintingColor(); - void addVoxelUnderCursor(); + void maybeEditVoxelUnderCursor(); void deleteVoxelUnderCursor(); void resetSensors(); @@ -202,6 +202,7 @@ private: VoxelDetail _mouseVoxel; // details of the voxel under the mouse cursor float _mouseVoxelScale; // the scale for adding/removing voxels glm::vec3 _lastMouseVoxelPos; // the position of the last mouse voxel edit + bool _justEditedVoxel; // set when we've just added/deleted/colored a voxel bool _paintOn; // Whether to paint voxels as you fly around unsigned char _dominantColor; // The dominant color of the voxel we're painting From 3f0fd2f9766bff7efc67059a23b5f4e81b8461a7 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 12:13:23 -0700 Subject: [PATCH 2/4] Added toggle for voxel textures; they may be slowing some machines down. --- interface/src/Application.cpp | 4 +++- interface/src/Application.h | 1 + interface/src/VoxelSystem.cpp | 18 +++++++++++------- interface/src/VoxelSystem.h | 2 +- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f5f0970394..119fd0f509 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1204,6 +1204,8 @@ void Application::initMenu() { (_renderVoxels = renderMenu->addAction("Voxels"))->setCheckable(true); _renderVoxels->setChecked(true); _renderVoxels->setShortcut(Qt::Key_V); + (_renderVoxelTextures = renderMenu->addAction("Voxel Textures"))->setCheckable(true); + _renderVoxelTextures->setChecked(true); (_renderStarsOn = renderMenu->addAction("Stars"))->setCheckable(true); _renderStarsOn->setChecked(true); _renderStarsOn->setShortcut(Qt::Key_Asterisk); @@ -1680,7 +1682,7 @@ void Application::displaySide(Camera& whichCamera) { // Draw voxels if (_renderVoxels->isChecked()) { - _voxels.render(); + _voxels.render(_renderVoxelTextures->isChecked()); } // indicate what we'll be adding/removing in mouse mode, if anything diff --git a/interface/src/Application.h b/interface/src/Application.h index 87ea615ad8..713b50e4ef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -134,6 +134,7 @@ private: QAction* _lookingInMirror; // Are we currently rendering one's own head as if in mirror? QAction* _gyroLook; // Whether to allow the gyro data from head to move your view QAction* _renderVoxels; // Whether to render voxels + QAction* _renderVoxelTextures; // Whether to render noise textures on voxels QAction* _renderStarsOn; // Whether to display the stars QAction* _renderAtmosphereOn; // Whether to display the atmosphere QAction* _renderAvatarsOn; // Whether to render avatars diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index d578bb3504..914d4b630a 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -617,7 +617,7 @@ void VoxelSystem::updateVBOs() { _callsToTreesToArrays = 0; // clear it } -void VoxelSystem::render() { +void VoxelSystem::render(bool texture) { PerformanceWarning warn(_renderWarningsOn, "render()"); glPushMatrix(); updateVBOs(); @@ -635,9 +635,11 @@ void VoxelSystem::render() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); - _perlinModulateProgram->bind(); - glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID); - + if (texture) { + _perlinModulateProgram->bind(); + glBindTexture(GL_TEXTURE_2D, _permutationNormalTextureID); + } + // for performance, disable blending and enable backface culling glDisable(GL_BLEND); glEnable(GL_CULL_FACE); @@ -650,9 +652,11 @@ void VoxelSystem::render() { glEnable(GL_BLEND); glDisable(GL_CULL_FACE); - _perlinModulateProgram->release(); - glBindTexture(GL_TEXTURE_2D, 0); - + if (texture) { + _perlinModulateProgram->release(); + glBindTexture(GL_TEXTURE_2D, 0); + } + // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_NORMAL_ARRAY); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 2d6d9717f6..d9dd844657 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -36,7 +36,7 @@ public: void init(); void simulate(float deltaTime) { }; - void render(); + void render(bool texture); unsigned long getVoxelsUpdated() const {return _voxelsUpdated;}; unsigned long getVoxelsRendered() const {return _voxelsInReadArrays;}; From 8d522cd3edad7c69894581ac73ba1acc1b67777d Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 15:15:44 -0700 Subject: [PATCH 3/4] I believe the problem with voxel rendering is caused by the update thread's writing the data while the render thread is attempting to read it. This should fix the issue. --- interface/src/VoxelSystem.cpp | 79 ++++++++++++++++++++--------------- interface/src/VoxelSystem.h | 6 ++- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 914d4b630a..01e7a9940f 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -46,7 +46,8 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- . VoxelSystem::VoxelSystem() { _voxelsInReadArrays = _voxelsInWriteArrays = _voxelsUpdated = 0; - _renderFullVBO = true; + _writeRenderFullVBO = true; + _readRenderFullVBO = true; _tree = new VoxelTree(); pthread_mutex_init(&_bufferWriteLock, NULL); pthread_mutex_init(&_treeLock, NULL); @@ -57,7 +58,8 @@ VoxelSystem::~VoxelSystem() { delete[] _writeVerticesArray; delete[] _readColorsArray; delete[] _writeColorsArray; - delete[] _voxelDirtyArray; + delete[] _writeVoxelDirtyArray; + delete[] _readVoxelDirtyArray; delete _tree; pthread_mutex_destroy(&_bufferWriteLock); pthread_mutex_destroy(&_treeLock); @@ -183,11 +185,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() { if (_tree->isDirty()) { static char buffer[64] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "newTreeToArrays() _renderFullVBO=%s", (_renderFullVBO ? "yes" : "no")); + sprintf(buffer, "newTreeToArrays() _writeRenderFullVBO=%s", (_writeRenderFullVBO ? "yes" : "no")); }; PerformanceWarning warn(_renderWarningsOn, buffer); _callsToTreesToArrays++; - if (_renderFullVBO) { + if (_writeRenderFullVBO) { _voxelsInWriteArrays = 0; // reset our VBO } _voxelsUpdated = newTreeToArrays(_tree->rootNode); @@ -195,10 +197,14 @@ void VoxelSystem::setupNewVoxelsForDrawing() { // since we called treeToArrays, we can assume that our VBO is in sync, and so partial updates to the VBOs are // ok again, until/unless we call removeOutOfView() - _renderFullVBO = false; + _writeRenderFullVBO = false; } else { _voxelsUpdated = 0; } + + // lock on the buffer write lock so we can't modify the data when the GPU is reading it + pthread_mutex_lock(&_bufferWriteLock); + if (_voxelsUpdated) { _voxelsDirty=true; } @@ -206,6 +212,8 @@ void VoxelSystem::setupNewVoxelsForDrawing() { // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated copyWrittenDataToReadArrays(); + pthread_mutex_unlock(&_bufferWriteLock); + double end = usecTimestampNow(); double elapsedmsec = (end - start) / 1000.0; _setupNewVoxelsForDrawingLastFinished = end; @@ -218,30 +226,25 @@ void VoxelSystem::cleanupRemovedVoxels() { while (!_removedVoxels.isEmpty()) { delete _removedVoxels.extract(); } - _renderFullVBO = true; // if we remove voxels, we must update our full VBOs + _writeRenderFullVBO = true; // if we remove voxels, we must update our full VBOs } } void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); int bytesOfVertices = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLfloat); int bytesOfColors = (_voxelsInWriteArrays * VERTEX_POINTS_PER_VOXEL) * sizeof(GLubyte); memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); _voxelsInReadArrays = _voxelsInWriteArrays; - pthread_mutex_unlock(&_bufferWriteLock); } void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); - glBufferIndex segmentStart = 0; glBufferIndex segmentEnd = 0; bool inSegment = false; for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - bool thisVoxelDirty = _voxelDirtyArray[i]; + bool thisVoxelDirty = _writeVoxelDirtyArray[i]; + _readVoxelDirtyArray[i] |= thisVoxelDirty; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; @@ -290,14 +293,15 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { // update our length _voxelsInReadArrays = _voxelsInWriteArrays; - - pthread_mutex_unlock(&_bufferWriteLock); + + // clear our dirty flags + memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); } void VoxelSystem::copyWrittenDataToReadArrays() { PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); if (_voxelsDirty && _voxelsUpdated) { - if (_renderFullVBO) { + if (_readRenderFullVBO) { copyWrittenDataToReadArraysFullVBOs(); } else { copyWrittenDataToReadArraysPartialVBOs(); @@ -327,7 +331,7 @@ int VoxelSystem::newTreeToArrays(VoxelNode* node) { } } } - if (_renderFullVBO) { + if (_writeRenderFullVBO) { voxelsUpdated += updateNodeInArraysAsFullVBO(node); } else { voxelsUpdated += updateNodeInArraysAsPartialVBO(node); @@ -365,7 +369,7 @@ int VoxelSystem::updateNodeInArraysAsFullVBO(VoxelNode* node) { *(writeColorsAt +j) = node->getColor()[j % 3]; } node->setBufferIndex(nodeIndex); - _voxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode + _writeVoxelDirtyArray[nodeIndex] = true; // just in case we switch to Partial mode _voxelsInWriteArrays++; // our know vertices in the arrays return 1; // rendered } @@ -402,7 +406,7 @@ int VoxelSystem::updateNodeInArraysAsPartialVBO(VoxelNode* node) { node->setBufferIndex(nodeIndex); _voxelsInWriteArrays++; } - _voxelDirtyArray[nodeIndex] = true; + _writeVoxelDirtyArray[nodeIndex] = true; // populate the array with points for the 8 vertices // and RGB color for each added vertex @@ -431,9 +435,11 @@ void VoxelSystem::init() { _voxelsInReadArrays = 0; _unusedArraySpace = 0; - // we will track individual dirty sections with this array of bools - _voxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; - memset(_voxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + // we will track individual dirty sections with these arrays of bools + _writeVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; + memset(_writeVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + _readVoxelDirtyArray = new bool[MAX_VOXELS_PER_SYSTEM]; + memset(_readVoxelDirtyArray, false, MAX_VOXELS_PER_SYSTEM * sizeof(bool)); // prep the data structures for incoming voxel data _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * MAX_VOXELS_PER_SYSTEM]; @@ -530,7 +536,7 @@ void VoxelSystem::init() { void VoxelSystem::updateFullVBOs() { glBufferIndex segmentStart = 0; - glBufferIndex segmentEnd = _voxelsInWriteArrays; + glBufferIndex segmentEnd = _voxelsInReadArrays; int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); @@ -544,21 +550,21 @@ void VoxelSystem::updateFullVBOs() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); - // consider the _voxelDirtyArray[] clean! - memset(_voxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); + // consider the _readVoxelDirtyArray[] clean! + memset(_readVoxelDirtyArray, false, _voxelsInReadArrays * sizeof(bool)); } void VoxelSystem::updatePartialVBOs() { glBufferIndex segmentStart = 0; glBufferIndex segmentEnd = 0; bool inSegment = false; - for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - bool thisVoxelDirty = _voxelDirtyArray[i]; + for (glBufferIndex i = 0; i < _voxelsInReadArrays; i++) { + bool thisVoxelDirty = _readVoxelDirtyArray[i]; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; inSegment = true; - _voxelDirtyArray[i] = false; // consider us clean! + _readVoxelDirtyArray[i] = false; // consider us clean! } } else { if (!thisVoxelDirty) { @@ -578,13 +584,13 @@ void VoxelSystem::updatePartialVBOs() { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); } - _voxelDirtyArray[i] = false; // consider us clean! + _readVoxelDirtyArray[i] = false; // consider us clean! } } // if we got to the end of the array, and we're in an active dirty segment... if (inSegment) { - segmentEnd = _voxelsInWriteArrays - 1; + segmentEnd = _voxelsInReadArrays - 1; inSegment = false; int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); @@ -603,22 +609,27 @@ void VoxelSystem::updatePartialVBOs() { void VoxelSystem::updateVBOs() { static char buffer[40] = { 0 }; if (_renderWarningsOn) { - sprintf(buffer, "updateVBOs() _renderFullVBO=%s", (_renderFullVBO ? "yes" : "no")); + sprintf(buffer, "updateVBOs() _readRenderFullVBO=%s", (_readRenderFullVBO ? "yes" : "no")); }; PerformanceWarning warn(_renderWarningsOn, buffer); // would like to include _callsToTreesToArrays if (_voxelsDirty) { - if (_renderFullVBO) { + if (_readRenderFullVBO) { updateFullVBOs(); } else { updatePartialVBOs(); } _voxelsDirty = false; + _readRenderFullVBO = false; } _callsToTreesToArrays = 0; // clear it } void VoxelSystem::render(bool texture) { PerformanceWarning warn(_renderWarningsOn, "render()"); + + // get the lock so that the update thread won't change anything + pthread_mutex_lock(&_bufferWriteLock); + glPushMatrix(); updateVBOs(); // tell OpenGL where to find vertex and color information @@ -668,6 +679,8 @@ void VoxelSystem::render(bool texture) { // scale back down to 1 so heads aren't massive glPopMatrix(); + + pthread_mutex_unlock(&_bufferWriteLock); } int VoxelSystem::_nodeCount = 0; @@ -1016,7 +1029,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { glBufferIndex maxDirty = 0; for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { - if (_voxelDirtyArray[i]) { + if (_writeVoxelDirtyArray[i]) { minDirty = std::min(minDirty,i); maxDirty = std::max(maxDirty,i); } diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index d9dd844657..0e955c90a5 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -118,13 +118,15 @@ private: GLubyte* _readColorsArray; GLfloat* _writeVerticesArray; GLubyte* _writeColorsArray; - bool* _voxelDirtyArray; + bool* _writeVoxelDirtyArray; + bool* _readVoxelDirtyArray; unsigned long _voxelsUpdated; unsigned long _voxelsInWriteArrays; unsigned long _voxelsInReadArrays; unsigned long _unusedArraySpace; - bool _renderFullVBO; + bool _writeRenderFullVBO; + bool _readRenderFullVBO; double _setupNewVoxelsForDrawingLastElapsed; double _setupNewVoxelsForDrawingLastFinished; From 06c78c2f1240f7d175b1cbe3397e32b735bb9d4f Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Mon, 20 May 2013 15:41:19 -0700 Subject: [PATCH 4/4] Tweak: let the reader know when it needs to load the full VBO. --- interface/src/VoxelSystem.cpp | 17 +++++++++++------ interface/src/VoxelSystem.h | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 01e7a9940f..b345f34709 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -182,6 +182,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { _lastViewCullingElapsed = (endViewCulling - start) / 1000.0; } + bool didWriteFullVBO = _writeRenderFullVBO; if (_tree->isDirty()) { static char buffer[64] = { 0 }; if (_renderWarningsOn) { @@ -210,7 +211,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated - copyWrittenDataToReadArrays(); + copyWrittenDataToReadArrays(didWriteFullVBO); pthread_mutex_unlock(&_bufferWriteLock); @@ -236,6 +237,12 @@ void VoxelSystem::copyWrittenDataToReadArraysFullVBOs() { memcpy(_readVerticesArray, _writeVerticesArray, bytesOfVertices); memcpy(_readColorsArray, _writeColorsArray, bytesOfColors ); _voxelsInReadArrays = _voxelsInWriteArrays; + + // clear our dirty flags + memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); + + // let the reader know to get the full array + _readRenderFullVBO = true; } void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { @@ -245,6 +252,7 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { for (glBufferIndex i = 0; i < _voxelsInWriteArrays; i++) { bool thisVoxelDirty = _writeVoxelDirtyArray[i]; _readVoxelDirtyArray[i] |= thisVoxelDirty; + _writeVoxelDirtyArray[i] = false; if (!inSegment) { if (thisVoxelDirty) { segmentStart = i; @@ -293,15 +301,12 @@ void VoxelSystem::copyWrittenDataToReadArraysPartialVBOs() { // update our length _voxelsInReadArrays = _voxelsInWriteArrays; - - // clear our dirty flags - memset(_writeVoxelDirtyArray, false, _voxelsInWriteArrays * sizeof(bool)); } -void VoxelSystem::copyWrittenDataToReadArrays() { +void VoxelSystem::copyWrittenDataToReadArrays(bool fullVBOs) { PerformanceWarning warn(_renderWarningsOn, "copyWrittenDataToReadArrays()"); if (_voxelsDirty && _voxelsUpdated) { - if (_readRenderFullVBO) { + if (fullVBOs) { copyWrittenDataToReadArraysFullVBOs(); } else { copyWrittenDataToReadArraysPartialVBOs(); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 0e955c90a5..6ce5855080 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -150,7 +150,7 @@ private: void cleanupRemovedVoxels(); void setupNewVoxelsForDrawing(); - void copyWrittenDataToReadArrays(); + void copyWrittenDataToReadArrays(bool fullVBOs); bool _voxelsDirty;