From c6981d1912e9b946a0be7856fdd403ad75eccabf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 7 Oct 2013 17:32:55 -0700 Subject: [PATCH 1/5] have animation server set an appropriate PPS based on it's voxel edit messages --- animation-server/src/main.cpp | 39 +++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index 2ffc46ee2e..125a14f6b6 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -594,8 +594,12 @@ void* animateVoxels(void* args) { timeval lastSendTime; + bool firstTime = true; + while (true) { gettimeofday(&lastSendTime, NULL); + + int packetsStarting = ::voxelEditPacketSender->packetsToSendCount(); // some animations //sendVoxelBlinkMessage(); @@ -619,12 +623,22 @@ void* animateVoxels(void* args) { if (::buildStreet) { doBuildStreet(); } + + ::voxelEditPacketSender->releaseQueuedMessages(); + int packetsEnding = ::voxelEditPacketSender->packetsToSendCount(); - if (::voxelEditPacketSender) { - ::voxelEditPacketSender->releaseQueuedMessages(); - if (::nonThreadedPacketSender) { - ::voxelEditPacketSender->process(); - } + if (firstTime) { + int packetsPerSecond = (packetsEnding - packetsStarting) * (ACTUAL_FPS); + + std::cout << "Setting PPS to " << packetsPerSecond << "\n"; + + ::voxelEditPacketSender->setPacketsPerSecond(packetsPerSecond); + firstTime = false; + } + + + if (::nonThreadedPacketSender) { + ::voxelEditPacketSender->process(); } uint64_t end = usecTimestampNow(); @@ -715,14 +729,13 @@ int main(int argc, const char * argv[]) // Create out VoxelEditPacketSender ::voxelEditPacketSender = new VoxelEditPacketSender; - if (::voxelEditPacketSender) { - ::voxelEditPacketSender->initialize(!::nonThreadedPacketSender); - if (::jurisdictionListener) { - ::voxelEditPacketSender->setVoxelServerJurisdictions(::jurisdictionListener->getJurisdictions()); - } - if (::nonThreadedPacketSender) { - ::voxelEditPacketSender->setProcessCallIntervalHint(ANIMATE_VOXELS_INTERVAL_USECS); - } + ::voxelEditPacketSender->initialize(!::nonThreadedPacketSender); + + if (::jurisdictionListener) { + ::voxelEditPacketSender->setVoxelServerJurisdictions(::jurisdictionListener->getJurisdictions()); + } + if (::nonThreadedPacketSender) { + ::voxelEditPacketSender->setProcessCallIntervalHint(ANIMATE_VOXELS_INTERVAL_USECS); } srand((unsigned)time(0)); From 8baa863242ad0450089fcca4793a592d8bd49769 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 7 Oct 2013 17:34:41 -0700 Subject: [PATCH 2/5] fixed PPS bugs in threaded version of PacketSender class --- libraries/shared/src/PacketSender.cpp | 11 ++++++++--- libraries/shared/src/PacketSender.h | 2 +- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index 41d5db87d1..5f6de128ba 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -85,7 +85,8 @@ bool PacketSender::process() { int packetsLeft = _packets.size(); bool keepGoing = packetsLeft > 0; while (keepGoing) { - + uint64_t SEND_INTERVAL_USECS = (_packetsPerSecond == 0) ? USECS_PER_SECOND : (USECS_PER_SECOND / _packetsPerSecond); + NetworkPacket& packet = _packets.front(); // send the packet through the NodeList... @@ -93,7 +94,7 @@ bool PacketSender::process() { nodeSocket->send(&packet.getAddress(), packet.getData(), packet.getLength()); packetsThisCall++; - + if (_notify) { _notify->packetSentNotification(packet.getLength()); } @@ -110,11 +111,15 @@ bool PacketSender::process() { // dynamically sleep until we need to fire off the next set of voxels we only sleep in threaded mode if (keepGoing) { + now = usecTimestampNow(); uint64_t elapsed = now - _lastSendTime; - int usecToSleep = std::max(SEND_INTERVAL_USECS, SEND_INTERVAL_USECS - elapsed); + int usecToSleep = SEND_INTERVAL_USECS - elapsed; // we only sleep in non-threaded mode if (usecToSleep > 0) { + if (usecToSleep > SEND_INTERVAL_USECS) { + usecToSleep = SEND_INTERVAL_USECS; + } usleep(usecToSleep); } } diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index 84ae6ae9ca..9197c3c7d7 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -36,7 +36,7 @@ public: /// \thread any thread, typically the application thread void queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength); - void setPacketsPerSecond(int packetsPerSecond) { _packetsPerSecond = std::min(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); } + void setPacketsPerSecond(int packetsPerSecond) { _packetsPerSecond = std::max(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); } int getPacketsPerSecond() const { return _packetsPerSecond; } void setPacketSenderNotify(PacketSenderNotify* notify) { _notify = notify; } From f6981feacf78e37c0728bd6735f9eb3121abfb51 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 7 Oct 2013 17:46:22 -0700 Subject: [PATCH 3/5] added various render mode options, including voxels as points --- interface/src/Application.cpp | 1 + interface/src/Menu.cpp | 17 ++-- interface/src/Menu.h | 9 +- interface/src/VoxelSystem.cpp | 187 ++++++++++++++++++++++++---------- interface/src/VoxelSystem.h | 7 +- 5 files changed, 153 insertions(+), 68 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6d7686328f..46a2b9afde 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1589,6 +1589,7 @@ void Application::init() { // Set up VoxelSystem after loading preferences so we can get the desired max voxel count _voxels.setMaxVoxels(Menu::getInstance()->getMaxVoxels()); _voxels.setUseVoxelShader(Menu::getInstance()->isOptionChecked(MenuOption::UseVoxelShader)); + _voxels.setVoxelsAsPoints(Menu::getInstance()->isOptionChecked(MenuOption::VoxelsAsPoints)); _voxels.setUseFastVoxelPipeline(Menu::getInstance()->isOptionChecked(MenuOption::FastVoxelPipeline)); _voxels.init(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ededcbccd0..8b92448e71 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -240,12 +240,18 @@ Menu::Menu() : appInstance, SLOT(setRenderVoxels(bool))); addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontRenderVoxels); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, - false, this, SLOT(switchVoxelShader())); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::DontCallOpenGLForVoxels); + + _useVoxelShader = addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, + false, appInstance->getVoxels(), SLOT(setUseVoxelShader(bool))); + + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelsAsPoints, 0, + false, appInstance->getVoxels(), SLOT(setVoxelsAsPoints(bool))); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::FastVoxelPipeline, 0, false, appInstance->getVoxels(), SLOT(setUseFastVoxelPipeline(bool))); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::VoxelTextures); + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::AmbientOcclusion); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); @@ -1005,7 +1011,4 @@ void Menu::updateFrustumRenderModeAction() { } } -void Menu::switchVoxelShader() { - Application::getInstance()->getVoxels()->setUseVoxelShader(isOptionChecked(MenuOption::UseVoxelShader)); -} diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 5c21a35b35..f54d3767a1 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -54,6 +54,7 @@ public: ViewFrustumOffset getViewFrustumOffset() const { return _viewFrustumOffset; } VoxelStatsDialog* getVoxelStatsDialog() const { return _voxelStatsDialog; } int getMaxVoxels() const { return _maxVoxels; } + QAction* getUseVoxelShader() const { return _useVoxelShader; } void handleViewFrustumOffsetKeyModifier(int key); @@ -78,7 +79,6 @@ private slots: void chooseVoxelPaintColor(); void runTests(); void resetSwatchColors(); - void switchVoxelShader(); private: static Menu* _instance; @@ -116,6 +116,7 @@ private: QActionGroup* _voxelModeActionsGroup; VoxelStatsDialog* _voxelStatsDialog; int _maxVoxels; + QAction* _useVoxelShader; }; namespace MenuOption { @@ -138,7 +139,8 @@ namespace MenuOption { const QString DestructiveAddVoxel = "Create Voxel is Destructive"; const QString DeltaSending = "Delta Sending"; const QString DisplayFrustum = "Display Frustum"; - const QString DontRenderVoxels = "Don't Render Voxels"; + const QString DontRenderVoxels = "Don't call _voxels.render()"; + const QString DontCallOpenGLForVoxels = "Don't call glDrawElements()/glDrawRangeElementsEXT() for Voxels"; const QString EchoAudio = "Echo Audio"; const QString ExportVoxels = "Export Voxels"; const QString HeadMouse = "Head Mouse"; @@ -205,8 +207,7 @@ namespace MenuOption { const QString UsePerlinFace = "Use Perlin's Face"; const QString Quit = "Quit"; const QString UseVoxelShader = "Use Voxel Shader"; - const QString UseByteNormals = "Use Byte Normals"; - const QString UseGlobalNormals = "Use Global Normals"; + const QString VoxelsAsPoints = "Draw Voxels as Points"; const QString Voxels = "Voxels"; const QString VoxelAddMode = "Add Voxel Mode"; const QString VoxelColorMode = "Color Voxel Mode"; diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index f0d6777053..634486d8dc 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -90,6 +90,8 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int))); _useVoxelShader = false; + _voxelsAsPoints = false; + _voxelShaderModeWhenVoxelsAsPointsEnabled = false; _writeVoxelShaderData = NULL; _readVoxelShaderData = NULL; @@ -219,7 +221,6 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { if (maxVoxels == _maxVoxels) { return; } - pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; if (wasInitialized) { clearAllNodesBufferIndex(); @@ -227,9 +228,8 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { } _maxVoxels = maxVoxels; if (wasInitialized) { - init(); + initVoxelMemory(); } - pthread_mutex_unlock(&_bufferWriteLock); if (wasInitialized) { forceRedrawEntireTree(); } @@ -240,7 +240,6 @@ void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { return; } - pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; if (wasInitialized) { clearAllNodesBufferIndex(); @@ -248,17 +247,59 @@ void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { } _useVoxelShader = useVoxelShader; if (wasInitialized) { - init(); + initVoxelMemory(); } - pthread_mutex_unlock(&_bufferWriteLock); if (wasInitialized) { forceRedrawEntireTree(); } } +void VoxelSystem::setVoxelsAsPoints(bool voxelsAsPoints) { + if (_voxelsAsPoints == voxelsAsPoints) { + return; + } + + bool wasInitialized = _initialized; + + // If we're "turning on" Voxels as points, we need to double check that we're in voxel shader mode. + // Voxels as points uses the VoxelShader memory model, so if we're not in voxel shader mode, + // then set it to voxel shader mode. + if (voxelsAsPoints) { + Menu::getInstance()->getUseVoxelShader()->setEnabled(false); + + // If enabling this... then do it before checking voxel shader status, that way, if voxel + // shader is already enabled, we just start drawing as points. + _voxelsAsPoints = true; + + if (!_useVoxelShader) { + setUseVoxelShader(true); + _voxelShaderModeWhenVoxelsAsPointsEnabled = false; + } else { + _voxelShaderModeWhenVoxelsAsPointsEnabled = true; + } + } else { + Menu::getInstance()->getUseVoxelShader()->setEnabled(true); + // if we're turning OFF voxels as point mode, then we check what the state of voxel shader was when we enabled + // voxels as points, if it was OFF, then we return it to that value. + if (_voxelShaderModeWhenVoxelsAsPointsEnabled == false) { + setUseVoxelShader(false); + } + // If disabling this... then do it AFTER checking previous voxel shader status, that way, if voxel + // shader is was not enabled, we switch back to normal mode before turning off points. + _voxelsAsPoints = false; + } + + // Set our voxels as points + if (wasInitialized) { + forceRedrawEntireTree(); + } +} + void VoxelSystem::cleanupVoxelMemory() { if (_initialized) { + pthread_mutex_lock(&_bufferWriteLock); + _initialized = false; // no longer initialized if (_useVoxelShader) { // these are used when in VoxelShader mode. glDeleteBuffers(1, &_vboVoxelsID); @@ -266,6 +307,9 @@ void VoxelSystem::cleanupVoxelMemory() { delete[] _writeVoxelShaderData; delete[] _readVoxelShaderData; + + _writeVoxelShaderData = _readVoxelShaderData = NULL; + } else { // Destroy glBuffers glDeleteBuffers(1, &_vboVerticesID); @@ -282,11 +326,18 @@ void VoxelSystem::cleanupVoxelMemory() { delete[] _writeVerticesArray; delete[] _readColorsArray; delete[] _writeColorsArray; + + _readVerticesArray = NULL; + _writeVerticesArray = NULL; + _readColorsArray = NULL; + _writeColorsArray = NULL; + } delete[] _writeVoxelDirtyArray; delete[] _readVoxelDirtyArray; + _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; + pthread_mutex_unlock(&_bufferWriteLock); } - _initialized = false; // no longer initialized } void VoxelSystem::setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]) { @@ -318,11 +369,11 @@ void VoxelSystem::setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndice } void VoxelSystem::initVoxelMemory() { - _initialMemoryUsageGPU = getFreeMemoryGPU(); + pthread_mutex_lock(&_bufferWriteLock); + _memoryUsageRAM = 0; _memoryUsageVBO = 0; // our VBO allocations as we know them if (_useVoxelShader) { - qDebug("Using Voxel Shader...\n"); GLuint* indicesArray = new GLuint[_maxVoxels]; // populate the indicesArray @@ -418,6 +469,10 @@ void VoxelSystem::initVoxelMemory() { _perlinModulateProgram.release(); } } + + _initialized = true; + + pthread_mutex_unlock(&_bufferWriteLock); } void VoxelSystem::loadVoxelsFile(const char* fileName, bool wantColorRandomizer) { @@ -544,7 +599,12 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { void VoxelSystem::setupNewVoxelsForDrawing() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "setupNewVoxelsForDrawing()"); // would like to include _voxelsInArrays, _voxelsUpdated + "setupNewVoxelsForDrawing()"); + + if (!_initialized) { + return; // bail early if we're not initialized + } + uint64_t start = usecTimestampNow(); uint64_t sinceLastTime = (start - _setupNewVoxelsForDrawingLastFinished) / 1000; @@ -587,7 +647,11 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } // lock on the buffer write lock so we can't modify the data when the GPU is reading it - pthread_mutex_lock(&_bufferWriteLock); + { + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "setupNewVoxelsForDrawing()... pthread_mutex_lock(&_bufferWriteLock)"); + pthread_mutex_lock(&_bufferWriteLock); + } if (_voxelsUpdated) { _voxelsDirty=true; @@ -957,14 +1021,13 @@ void VoxelSystem::init() { _setupNewVoxelsForDrawingLastElapsed = 0; _lastViewCullingElapsed = _lastViewCulling = 0; - // When we change voxels representations in the arrays, we'll update this _voxelsDirty = false; _voxelsInWriteArrays = 0; _voxelsInReadArrays = 0; // VBO for the verticesArray + _initialMemoryUsageGPU = getFreeMemoryGPU(); initVoxelMemory(); - _initialized = true; // our own _removedVoxels doesn't need to be notified of voxel deletes VoxelNode::removeDeleteHook(&_removedVoxels); @@ -1071,16 +1134,14 @@ void VoxelSystem::render(bool texture) { return; } - // get the lock so that the update thread won't change anything - pthread_mutex_lock(&_bufferWriteLock); - updateVBOs(); - + + bool dontCallOpenGLDraw = Menu::getInstance()->isOptionChecked(MenuOption::DontCallOpenGLForVoxels); + // if not don't... then do... if (_useVoxelShader) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "render().. _useVoxelShader openGL.."); - - Application::getInstance()->getVoxelShader().begin(); + //Define this somewhere in your header file #define BUFFER_OFFSET(i) ((void*)(i)) @@ -1088,14 +1149,29 @@ void VoxelSystem::render(bool texture) { glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(0)); //The starting point of the VBO, for the vertices - int loc = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn"); - glEnableVertexAttribArray(loc); - glVertexAttribPointer(loc, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float))); + + int attributeLocation; + + if (!_voxelsAsPoints) { + Application::getInstance()->getVoxelShader().begin(); + + attributeLocation = Application::getInstance()->getVoxelShader().attributeLocation("voxelSizeIn"); + glEnableVertexAttribArray(attributeLocation); + glVertexAttribPointer(attributeLocation, 1, GL_FLOAT, false, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(3*sizeof(float))); + } else { + const float POINT_SIZE = 4.0; + glPointSize(POINT_SIZE); + } + + glEnableClientState(GL_COLOR_ARRAY); glColorPointer(3, GL_UNSIGNED_BYTE, sizeof(VoxelShaderVBOData), BUFFER_OFFSET(4*sizeof(float)));//The starting point of colors glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); - glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO + + if (!dontCallOpenGLDraw) { + glDrawElements(GL_POINTS, _voxelsInReadArrays, GL_UNSIGNED_INT, BUFFER_OFFSET(0)); //The starting point of the IBO + } // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); @@ -1105,11 +1181,13 @@ void VoxelSystem::render(bool texture) { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - Application::getInstance()->getVoxelShader().end(); - + if (!_voxelsAsPoints) { + Application::getInstance()->getVoxelShader().end(); + glDisableVertexAttribArray(attributeLocation); + } } else { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "render().. openGL..."); - + // tell OpenGL where to find vertex and color information glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); @@ -1121,47 +1199,48 @@ void VoxelSystem::render(bool texture) { glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); applyScaleAndBindProgram(texture); - + // for performance, enable backface culling glEnable(GL_CULL_FACE); // draw voxels in 6 passes - glNormal3f(0,1.0f,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesTop); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + if (!dontCallOpenGLDraw) { + glNormal3f(0,1.0f,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesTop); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - glNormal3f(0,-1.0f,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesBottom); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + glNormal3f(0,-1.0f,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesBottom); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - glNormal3f(-1.0f,0,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesLeft); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + glNormal3f(-1.0f,0,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesLeft); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - glNormal3f(1.0f,0,0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesRight); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + glNormal3f(1.0f,0,0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesRight); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - glNormal3f(0,0,-1.0f); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesFront); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - - glNormal3f(0,0,1.0f); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesBack); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, - INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + glNormal3f(0,0,-1.0f); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesFront); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + glNormal3f(0,0,1.0f); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesBack); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + } glDisable(GL_CULL_FACE); removeScaleAndReleaseProgram(texture); - + // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); @@ -1170,8 +1249,6 @@ void VoxelSystem::render(bool texture) { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - - pthread_mutex_unlock(&_bufferWriteLock); } void VoxelSystem::applyScaleAndBindProgram(bool texture) { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 4def28cfd2..456a9bc8c6 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -65,8 +65,6 @@ public: bool readFromSquareARGB32Pixels(const char* filename); bool readFromSchematicFile(const char* filename); - void setUseVoxelShader(bool useVoxelShader); - void setMaxVoxels(int maxVoxels); long int getMaxVoxels() const { return _maxVoxels; } unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; } @@ -137,6 +135,8 @@ public slots: void cancelImport(); void setUseFastVoxelPipeline(bool useFastVoxelPipeline); + void setUseVoxelShader(bool useVoxelShader); + void setVoxelsAsPoints(bool voxelsAsPoints); protected: float _treeScale; @@ -224,6 +224,9 @@ private: void cleanupVoxelMemory(); bool _useVoxelShader; + bool _voxelsAsPoints; + bool _voxelShaderModeWhenVoxelsAsPointsEnabled; + GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO GLuint _vboVoxelsIndicesID; /// when using voxel shader, we'll use this VBO for our indexes VoxelShaderVBOData* _writeVoxelShaderData; From 54364a235dd2b8bb31e73da8d6d74160e3b479c0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 7 Oct 2013 19:43:45 -0700 Subject: [PATCH 4/5] tighten up mutex locks to keep at 60 fps --- interface/src/VoxelPacketProcessor.cpp | 4 ---- interface/src/VoxelSystem.cpp | 16 +++++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index 8dc5092a64..e33f377edc 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -47,11 +47,7 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress); if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) { - - voxelServer->lock(); // do we really need to lock this? just to get the ID? int nodeID = voxelServer->getNodeID(); - voxelServer->unlock(); - if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) { app->_environment.parseData(&senderAddress, packetData, messageLength); } else { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 634486d8dc..087662d92a 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -538,15 +538,15 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { int numBytesPacketHeader = numBytesForPacketHeader(sourceBuffer); unsigned char* voxelData = sourceBuffer + numBytesPacketHeader; - pthread_mutex_lock(&_treeLock); - switch(command) { case PACKET_TYPE_VOXEL_DATA: { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "readBitstreamToTree()"); // ask the VoxelTree to read the bitstream into the tree ReadBitstreamToTreeParams args(WANT_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceID()); + pthread_mutex_lock(&_treeLock); _tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args); + pthread_mutex_unlock(&_treeLock); } break; case PACKET_TYPE_VOXEL_DATA_MONOCHROME: { @@ -554,7 +554,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { "readBitstreamToTree()"); // ask the VoxelTree to read the MONOCHROME bitstream into the tree ReadBitstreamToTreeParams args(NO_COLOR, WANT_EXISTS_BITS, NULL, getDataSourceID()); + pthread_mutex_lock(&_treeLock); _tree->readBitstreamToTree(voxelData, numBytes - numBytesPacketHeader, args); + pthread_mutex_unlock(&_treeLock); } break; case PACKET_TYPE_Z_COMMAND: @@ -572,7 +574,9 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { while (totalLength <= numBytes) { if (0==strcmp(command,(char*)"erase all")) { qDebug("got Z message == erase all\n"); + pthread_mutex_lock(&_treeLock); _tree->eraseAllVoxels(); + pthread_mutex_unlock(&_treeLock); _voxelsInReadArrays = _voxelsInWriteArrays = 0; // better way to do this?? } if (0==strcmp(command,(char*)"add scene")) { @@ -590,8 +594,6 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { setupNewVoxelsForDrawingSingleNode(DONT_BAIL_EARLY); } - pthread_mutex_unlock(&_treeLock); - Application::getInstance()->getBandwidthMeter()->inputStream(BandwidthMeter::VOXELS).updateValue(numBytes); return numBytes; @@ -1824,13 +1826,13 @@ VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { void VoxelSystem::createVoxel(float x, float y, float z, float s, unsigned char red, unsigned char green, unsigned char blue, bool destructive) { - pthread_mutex_lock(&_treeLock); //qDebug("VoxelSystem::createVoxel(%f,%f,%f,%f)\n",x,y,z,s); + pthread_mutex_lock(&_treeLock); _tree->createVoxel(x, y, z, s, red, green, blue, destructive); - setupNewVoxelsForDrawing(); - pthread_mutex_unlock(&_treeLock); + + setupNewVoxelsForDrawing(); }; void VoxelSystem::createLine(glm::vec3 point1, glm::vec3 point2, float unitSize, rgbColor color, bool destructive) { From aa80ec3497d58549df7a764846e78c319f3c2c73 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 7 Oct 2013 19:46:52 -0700 Subject: [PATCH 5/5] cleanup code for PR --- interface/src/VoxelSystem.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 087662d92a..24ca83b8a3 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -649,11 +649,7 @@ void VoxelSystem::setupNewVoxelsForDrawing() { } // lock on the buffer write lock so we can't modify the data when the GPU is reading it - { - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "setupNewVoxelsForDrawing()... pthread_mutex_lock(&_bufferWriteLock)"); - pthread_mutex_lock(&_bufferWriteLock); - } + pthread_mutex_lock(&_bufferWriteLock); if (_voxelsUpdated) { _voxelsDirty=true;