From a362fdc2ed37da917b759297b2181f9dff83af8a Mon Sep 17 00:00:00 2001 From: stojce Date: Tue, 10 Sep 2013 21:51:50 +0200 Subject: [PATCH 01/11] name the current domain server --- interface/src/Application.cpp | 8 ++- interface/src/Application.h | 4 +- libraries/shared/src/NodeList.cpp | 92 ++++++++++++++++++++++--------- libraries/shared/src/NodeList.h | 12 ++++ 4 files changed, 87 insertions(+), 29 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7989d8b715..089b1cd9fb 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -147,6 +147,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : NodeList::getInstance()->addHook(&_voxels); NodeList::getInstance()->addHook(this); + NodeList::getInstance()->addDomainListener(this); // network receive thread and voxel parsing thread are both controlled by the --nonblocking command line @@ -236,6 +237,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : Application::~Application() { NodeList::getInstance()->removeHook(&_voxels); NodeList::getInstance()->removeHook(this); + NodeList::getInstance()->removeDomainListener(this); _sharedVoxelSystem.changeTree(new VoxelTree); @@ -314,8 +316,6 @@ void Application::initializeGL() { char title[50]; sprintf(title, "Interface: %4.2f seconds\n", startupTime); qDebug("%s", title); - _window->setWindowTitle(title); - const char LOGSTASH_INTERFACE_START_TIME_KEY[] = "interface-start-time"; // ask the Logstash class to record the startup time @@ -3235,6 +3235,10 @@ void Application::attachNewHeadToNode(Node* newNode) { } } +void Application::domainChanged(QString domain) { + _window->setWindowTitle(domain); +} + void Application::nodeAdded(Node* node) { } diff --git a/interface/src/Application.h b/interface/src/Application.h index 6c9f2cf66d..7a21c3ca51 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -76,7 +76,7 @@ static const float NODE_KILLED_RED = 1.0f; static const float NODE_KILLED_GREEN = 0.0f; static const float NODE_KILLED_BLUE = 0.0f; -class Application : public QApplication, public NodeListHook, public PacketSenderNotify { +class Application : public QApplication, public NodeListHook, public PacketSenderNotify, public DomainChangeListener { Q_OBJECT friend class VoxelPacketProcessor; @@ -142,6 +142,8 @@ public: virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); virtual void packetSentNotification(ssize_t length); + + virtual void domainChanged(QString domain); public slots: void sendAvatarFaceVideoMessage(int frameCount, const QByteArray& data); diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index a982e22242..290b8ffb18 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -82,22 +82,20 @@ NodeList::~NodeList() { stopSilentNodeRemovalThread(); } -void NodeList::setDomainHostname(const char* domainHostname) { - memset(_domainHostname, 0, sizeof(_domainHostname)); - memcpy(_domainHostname, domainHostname, strlen(domainHostname)); - +void NodeList::setDomainHostname(const char* domainHostname) { // reset the domain IP so the hostname is checked again - setDomainIP(""); + resetDomainData(_domainHostname, domainHostname); } void NodeList::setDomainIP(const char* domainIP) { - memset(_domainIP, 0, sizeof(_domainIP)); - memcpy(_domainIP, domainIP, strlen(domainIP)); + resetDomainData(_domainIP, domainIP); } void NodeList::setDomainIPToLocalhost() { int ip = getLocalAddress(); - sprintf(_domainIP, "%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + char _localIP[INET_ADDRSTRLEN]; + sprintf(_localIP, "%d.%d.%d.%d", (ip & 0xFF), ((ip >> 8) & 0xFF),((ip >> 16) & 0xFF), ((ip >> 24) & 0xFF)); + setDomainIP(_localIP); } void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { @@ -269,25 +267,8 @@ void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNo } void NodeList::sendDomainServerCheckIn() { - static bool printedDomainServerIP = false; - - // Lookup the IP address of the domain server if we need to - if (atoi(_domainIP) == 0) { - printf("Looking up %s\n", _domainHostname); - struct hostent* pHostInfo; - if ((pHostInfo = gethostbyname(_domainHostname)) != NULL) { - sockaddr_in tempAddress; - memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); - strcpy(_domainIP, inet_ntoa(tempAddress.sin_addr)); - qDebug("Domain Server: %s\n", _domainHostname); - } else { - qDebug("Failed domain server lookup\n"); - } - } else if (!printedDomainServerIP) { - qDebug("Domain Server IP: %s\n", _domainIP); - printedDomainServerIP = true; - } + domainLookup(); static unsigned char* checkInPacket = NULL; static int checkInPacketSize = 0; @@ -650,6 +631,21 @@ void NodeListIterator::skipDeadAndStopIncrement() { } } +void NodeList::addDomainListener(DomainChangeListener* listener) { + _domainListeners.push_back(listener); + QString domain = (strlen(_domainHostname) > 0) ? _domainHostname : _domainIP; + listener->domainChanged(domain); +} + +void NodeList::removeDomainListener(DomainChangeListener* listener) { + for (int i = 0; i < _domainListeners.size(); i++) { + if (_domainListeners[i] == listener) { + _domainListeners.erase(_domainListeners.begin() + i); + return; + } + } +} + void NodeList::addHook(NodeListHook* hook) { _hooks.push_back(hook); } @@ -676,3 +672,47 @@ void NodeList::notifyHooksOfKilledNode(Node* node) { _hooks[i]->nodeKilled(node); } } + +void NodeList::notifyDomainChanged() { + QString domain = (strlen(_domainHostname) > 0) ? _domainHostname : _domainIP; + for (int i = 0; i < _domainListeners.size(); i++) { + _domainListeners[i]->domainChanged(domain); + } +} + +void NodeList::resetDomainData(char domainField[], const char* domainValue) { + memset(_domainHostname, 0, sizeof(_domainHostname)); + memcpy(_domainHostname, "", strlen("")); + + memset(_domainIP, 0, sizeof(_domainIP)); + memcpy(_domainIP, "", strlen("")); + + memset(domainField, 0, sizeof(&domainField)); + memcpy(domainField, domainValue, strlen(domainValue)); + + domainLookup(); + notifyDomainChanged(); +} + +void NodeList::domainLookup() { + static bool printedDomainServerIP = false; + + // Lookup the IP address of the domain server if we need to + if (atoi(_domainIP) == 0) { + printf("Looking up %s\n", _domainHostname); + struct hostent* pHostInfo; + if ((pHostInfo = gethostbyname(_domainHostname)) != NULL) { + sockaddr_in tempAddress; + memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); + strcpy(_domainIP, inet_ntoa(tempAddress.sin_addr)); + + qDebug("Domain Server: %s\n", _domainHostname); + } else { + qDebug("Failed domain server lookup\n"); + } + } else if (!printedDomainServerIP) { + notifyDomainChanged(); + qDebug("Domain Server IP: %s\n", _domainIP); + printedDomainServerIP = true; + } +} diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index ea94e8c080..e7d08ddda5 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -54,6 +54,10 @@ public: virtual void nodeKilled(Node* node) = 0; }; +class DomainChangeListener { +public: + virtual void domainChanged(QString domain) = 0; +}; class NodeList { public: @@ -130,6 +134,9 @@ public: void notifyHooksOfAddedNode(Node* node); void notifyHooksOfKilledNode(Node* node); + void addDomainListener(DomainChangeListener* listener); + void removeDomainListener(DomainChangeListener* listener); + private: static NodeList* _sharedInstance; @@ -158,6 +165,11 @@ private: void timePingReply(sockaddr *nodeAddress, unsigned char *packetData); std::vector _hooks; + std::vector _domainListeners; + + void resetDomainData(char domainField[], const char* domainData); + void notifyDomainChanged(); + void domainLookup(); }; class NodeListIterator : public std::iterator { From eb6af1afbfa037e4353dea7c56d04d62c5f73810 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Sep 2013 09:02:51 -0700 Subject: [PATCH 02/11] fix byte normals, fix crashes in switching between voxel shader and normal mode --- interface/src/VoxelSystem.cpp | 75 +++++++++++++++++++++++++------- interface/src/VoxelSystem.h | 4 ++ libraries/voxels/src/VoxelNode.h | 1 + 3 files changed, 65 insertions(+), 15 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index fe82da66a0..ed8de7f8a5 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -37,7 +37,7 @@ float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0, 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 }; -GLbyte identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1, +GLfloat identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1, 0,0,+1, 0,0,+1, 0,0,+1, 0,0,+1, 0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0, 0,-1,0, 0,-1,0, 0,+1,0, 0,+1,0, @@ -152,6 +152,10 @@ void VoxelSystem::setUseByteNormals(bool useByteNormals) { init(); } pthread_mutex_unlock(&_bufferWriteLock); + + if (wasInitialized) { + forceRedrawEntireTree(); + } } @@ -166,12 +170,17 @@ void VoxelSystem::setMaxVoxels(int maxVoxels) { init(); } pthread_mutex_unlock(&_bufferWriteLock); + + if (wasInitialized) { + forceRedrawEntireTree(); + } } void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; if (wasInitialized) { + clearAllNodesBufferIndex(); cleanupVoxelMemory(); } _useVoxelShader = useVoxelShader; @@ -179,6 +188,10 @@ void VoxelSystem::setUseVoxelShader(bool useVoxelShader) { init(); } pthread_mutex_unlock(&_bufferWriteLock); + + if (wasInitialized) { + forceRedrawEntireTree(); + } } void VoxelSystem::cleanupVoxelMemory() { @@ -266,7 +279,7 @@ void VoxelSystem::initVoxelMemory() { // populate the normalsArray for (int n = 0; n < _maxVoxels; n++) { for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = identityNormals[i]; + *(normalsArrayEndPointer++) = (identityNormals[i] * CHAR_MAX); } } @@ -750,20 +763,24 @@ void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& s float voxelScale, const nodeColor& color) { if (_useVoxelShader) { - VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex]; - writeVerticesAt->x = startVertex.x * TREE_SCALE; - writeVerticesAt->y = startVertex.y * TREE_SCALE; - writeVerticesAt->z = startVertex.z * TREE_SCALE; - writeVerticesAt->s = voxelScale * TREE_SCALE; - writeVerticesAt->r = color[RED_INDEX]; - writeVerticesAt->g = color[GREEN_INDEX]; - writeVerticesAt->b = color[BLUE_INDEX]; + if (_writeVoxelShaderData) { + VoxelShaderVBOData* writeVerticesAt = &_writeVoxelShaderData[nodeIndex]; + writeVerticesAt->x = startVertex.x * TREE_SCALE; + writeVerticesAt->y = startVertex.y * TREE_SCALE; + writeVerticesAt->z = startVertex.z * TREE_SCALE; + writeVerticesAt->s = voxelScale * TREE_SCALE; + writeVerticesAt->r = color[RED_INDEX]; + writeVerticesAt->g = color[GREEN_INDEX]; + writeVerticesAt->b = color[BLUE_INDEX]; + } } else { - for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { - GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); - *(writeColorsAt +j) = color[j % 3]; + if (_writeVerticesArray && _writeColorsArray) { + for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { + GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); + GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); + *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); + *(writeColorsAt +j) = color[j % 3]; + } } } } @@ -995,6 +1012,34 @@ void VoxelSystem::killLocalVoxels() { } +bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData) { + _nodeCount++; + node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); + return true; +} + +void VoxelSystem::clearAllNodesBufferIndex() { + _nodeCount = 0; + _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); + qDebug("clearing buffer index of %d nodes\n", _nodeCount); + _tree->setDirtyBit(); + setupNewVoxelsForDrawing(); +} + +bool VoxelSystem::forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData) { + _nodeCount++; + node->setDirtyBit(); + return true; +} + +void VoxelSystem::forceRedrawEntireTree() { + _nodeCount = 0; + _tree->recurseTreeWithOperation(forceRedrawEntireTreeOperation); + qDebug("forcing redraw of %d nodes\n", _nodeCount); + _tree->setDirtyBit(); + setupNewVoxelsForDrawing(); +} + bool VoxelSystem::randomColorOperation(VoxelNode* node, void* extraData) { _nodeCount++; if (node->isColored()) { diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5d3ac96d8c..39807f918e 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -126,6 +126,8 @@ public slots: void falseColorizeOccluded(); void falseColorizeOccludedV2(); void falseColorizeBySource(); + void forceRedrawEntireTree(); + void clearAllNodesBufferIndex(); void cancelImport(); void setUseByteNormals(bool useByteNormals); @@ -172,6 +174,8 @@ private: static bool falseColorizeOccludedV2Operation(VoxelNode* node, void* extraData); static bool falseColorizeBySourceOperation(VoxelNode* node, void* extraData); static bool killSourceVoxelsOperation(VoxelNode* node, void* extraData); + static bool forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData); + static bool clearAllNodesBufferIndexOperation(VoxelNode* node, void* extraData); int updateNodeInArraysAsFullVBO(VoxelNode* node); int updateNodeInArraysAsPartialVBO(VoxelNode* node); diff --git a/libraries/voxels/src/VoxelNode.h b/libraries/voxels/src/VoxelNode.h index b7f31e3b61..03a8fe3c57 100644 --- a/libraries/voxels/src/VoxelNode.h +++ b/libraries/voxels/src/VoxelNode.h @@ -70,6 +70,7 @@ public: void printDebugDetails(const char* label) const; bool isDirty() const { return _isDirty; } void clearDirtyBit() { _isDirty = false; } + void setDirtyBit() { _isDirty = true; } bool hasChangedSince(uint64_t time) const { return (_lastChanged > time); } void markWithChangedTime() { _lastChanged = usecTimestampNow(); } uint64_t getLastChanged() const { return _lastChanged; } From 605c2f30cfb8fc9820f44bb3d3fea5638f30233c Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Sep 2013 10:17:10 -0700 Subject: [PATCH 03/11] add memory usage debugging --- interface/src/Application.cpp | 20 ++++++--- interface/src/VoxelSystem.cpp | 85 +++++++++++++++++++++++++++++++++-- interface/src/VoxelSystem.h | 10 +++++ 3 files changed, 105 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7bf76466bc..7c223043d4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2822,28 +2822,36 @@ void Application::displayStats() { voxelStats << "Voxels Rendered: " << _voxels.getVoxelsRendered() / 1000.f << "K " << "Updated: " << _voxels.getVoxelsUpdated()/1000.f << "K " << "Max: " << _voxels.getMaxVoxels()/1000.f << "K "; - drawtext(10, statsVerticalOffset + 230, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + + voxelStats.str(""); + voxelStats << "Voxels Memory RAM: " << _voxels.getVoxelMemoryUsageRAM() / 1000000.f << "MB " << + "VBO: " << _voxels.getVoxelMemoryUsageVBO() / 1000000.f << "MB "; + if (_voxels.hasVoxelMemoryUsageGPU()) { + voxelStats << "GPU: " << _voxels.getVoxelMemoryUsageGPU() / 1000000.f << "MB "; + } + + drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); char* voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_VOXELS); voxelStats << "Voxels Sent from Server: " << voxelDetails; - drawtext(10, statsVerticalOffset + 250, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ELAPSED); voxelStats << "Scene Send Time from Server: " << voxelDetails; - drawtext(10, statsVerticalOffset + 270, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + drawtext(10, statsVerticalOffset + 290, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_ENCODE); voxelStats << "Encode Time on Server: " << voxelDetails; - drawtext(10, statsVerticalOffset + 290, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); voxelStats.str(""); voxelDetails = _voxelSceneStats.getItemValue(VoxelSceneStats::ITEM_MODE); voxelStats << "Sending Mode: " << voxelDetails; - drawtext(10, statsVerticalOffset + 310, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); + drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, (char *)voxelStats.str().c_str()); Node *avatarMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AVATAR_MIXER); char avatarMixerStats[200]; @@ -2856,7 +2864,7 @@ void Application::displayStats() { sprintf(avatarMixerStats, "No Avatar Mixer"); } - drawtext(10, statsVerticalOffset + 330, 0.10f, 0, 1.0, 0, avatarMixerStats); + drawtext(10, statsVerticalOffset + 350, 0.10f, 0, 1.0, 0, avatarMixerStats); drawtext(10, statsVerticalOffset + 450, 0.10f, 0, 1.0, 0, (char *)LeapManager::statusString().c_str()); if (_perfStatsOn) { diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index ed8de7f8a5..88661dd2bd 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -214,14 +214,17 @@ void VoxelSystem::cleanupVoxelMemory() { delete[] _writeVerticesArray; delete[] _readColorsArray; delete[] _writeColorsArray; - delete[] _writeVoxelDirtyArray; - delete[] _readVoxelDirtyArray; } + delete[] _writeVoxelDirtyArray; + delete[] _readVoxelDirtyArray; } _initialized = false; // no longer initialized } void VoxelSystem::initVoxelMemory() { + _initialMemoryUsageGPU = getFreeMemoryGPU(); + _memoryUsageRAM = 0; + _memoryUsageVBO = 0; // our VBO allocations as we know them if (_useVoxelShader) { qDebug("Using Voxel Shader...\n"); GLuint* indicesArray = new GLuint[_maxVoxels]; @@ -235,12 +238,13 @@ void VoxelSystem::initVoxelMemory() { // bind the indices VBO to the actual indices array glGenBuffers(1, &_vboVoxelsIndicesID); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboVoxelsIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, _maxVoxels, indicesArray, GL_STATIC_DRAW); - + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * _maxVoxels, indicesArray, GL_STATIC_DRAW); + _memoryUsageVBO += sizeof(GLuint) * _maxVoxels; glGenBuffers(1, &_vboVoxelsID); glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); glBufferData(GL_ARRAY_BUFFER, _maxVoxels * sizeof(VoxelShaderVBOData), NULL, GL_DYNAMIC_DRAW); + _memoryUsageVBO += _maxVoxels * sizeof(VoxelShaderVBOData); // delete the indices and normals arrays that are no longer needed delete[] indicesArray; @@ -248,12 +252,18 @@ void VoxelSystem::initVoxelMemory() { // we will track individual dirty sections with these arrays of bools _writeVoxelDirtyArray = new bool[_maxVoxels]; memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _memoryUsageRAM += (_maxVoxels * sizeof(bool)); + _readVoxelDirtyArray = new bool[_maxVoxels]; memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _memoryUsageRAM += (_maxVoxels * sizeof(bool)); // prep the data structures for incoming voxel data _writeVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); + _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; + _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); } else { GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; @@ -289,6 +299,7 @@ void VoxelSystem::initVoxelMemory() { glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, normalsArray, GL_STATIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; // delete the indices and normals arrays that are no longer needed delete[] normalsArray; @@ -310,6 +321,7 @@ void VoxelSystem::initVoxelMemory() { glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, normalsArray, GL_STATIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; // delete the indices and normals arrays that are no longer needed delete[] normalsArray; @@ -319,11 +331,13 @@ void VoxelSystem::initVoxelMemory() { glGenBuffers(1, &_vboVerticesID); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; // VBO for colorsArray glGenBuffers(1, &_vboColorsID); glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels; // VBO for the indicesArray glGenBuffers(1, &_vboIndicesID); @@ -331,6 +345,7 @@ void VoxelSystem::initVoxelMemory() { glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, indicesArray, GL_STATIC_DRAW); + _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; // delete the indices and normals arrays that are no longer needed delete[] indicesArray; @@ -339,15 +354,22 @@ void VoxelSystem::initVoxelMemory() { // we will track individual dirty sections with these arrays of bools _writeVoxelDirtyArray = new bool[_maxVoxels]; memset(_writeVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _memoryUsageRAM += (sizeof(bool) * _maxVoxels); + _readVoxelDirtyArray = new bool[_maxVoxels]; memset(_readVoxelDirtyArray, false, _maxVoxels * sizeof(bool)); + _memoryUsageRAM += (sizeof(bool) * _maxVoxels); // prep the data structures for incoming voxel data _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); // create our simple fragment shader if we're the first system to init @@ -1897,3 +1919,58 @@ void VoxelSystem::nodeKilled(Node* node) { } +unsigned long VoxelSystem::getFreeMemoryGPU() { + // We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free. + // So, we can record the free memory before we create our VBOs and the free memory after, and get a basic + // idea how how much we're using. + + _hasMemoryUsageGPU = false; // assume the worst + unsigned long freeMemory = 0; + const int NUM_RESULTS = 4; // see notes, these APIs return up to 4 results + GLint results[NUM_RESULTS] = { 0, 0, 0, 0}; + + // ATI + // http://www.opengl.org/registry/specs/ATI/meminfo.txt + // + // TEXTURE_FREE_MEMORY_ATI 0x87FC + // RENDERBUFFER_FREE_MEMORY_ATI 0x87FD + const GLenum VBO_FREE_MEMORY_ATI = 0x87FB; + glGetIntegerv(VBO_FREE_MEMORY_ATI, &results[0]); + GLenum errorATI = glGetError(); + + if (errorATI == GL_NO_ERROR) { + _hasMemoryUsageGPU = true; + freeMemory = results[0]; + } else { + + // NVIDIA + // http://developer.download.nvidia.com/opengl/specs/GL_NVX_gpu_memory_info.txt + // + //const GLenum GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX = 0x9047; + //const GLenum GPU_MEMORY_INFO_EVICTION_COUNT_NVX = 0x904A; + //const GLenum GPU_MEMORY_INFO_EVICTED_MEMORY_NVX = 0x904B; + //const GLenum GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX = 0x9048; + + const GLenum GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX = 0x9049; + results[0] = 0; + glGetIntegerv(GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &results[0]); + freeMemory += results[0]; + GLenum errorNVIDIA = glGetError(); + + if (errorNVIDIA == GL_NO_ERROR) { + _hasMemoryUsageGPU = true; + freeMemory = results[0]; + } + } + + const unsigned long BYTES_PER_KBYTE = 1024; + return freeMemory * BYTES_PER_KBYTE; // API results in KB, we want it in bytes +} + +unsigned long VoxelSystem::getVoxelMemoryUsageGPU() { + unsigned long currentFreeMemory = getFreeMemoryGPU(); + return (_initialMemoryUsageGPU - currentFreeMemory); +} + + + diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 39807f918e..5e56cfe8a6 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -69,6 +69,10 @@ public: void setMaxVoxels(int maxVoxels); long int getMaxVoxels() const { return _maxVoxels; } + unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; } + unsigned long getVoxelMemoryUsageVBO() const { return _memoryUsageVBO; } + bool hasVoxelMemoryUsageGPU() const { return _hasMemoryUsageGPU; } + unsigned long getVoxelMemoryUsageGPU(); long int getVoxelsCreated(); long int getVoxelsColored(); long int getVoxelsBytesRead(); @@ -185,6 +189,8 @@ private: void updateVBOs(); + unsigned long getFreeMemoryGPU(); + // these are kinda hacks, used by getDistanceFromViewRangeOperation() probably shouldn't be here static float _maxDistance; static float _minDistance; @@ -253,6 +259,10 @@ private: int _dataSourceID; int _voxelServerCount; + unsigned long _memoryUsageRAM; + unsigned long _memoryUsageVBO; + unsigned long _initialMemoryUsageGPU; + bool _hasMemoryUsageGPU; }; #endif From dbfc0956c1bfcf1de89b7658081a90d5eab9b62d Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Sep 2013 13:26:58 -0700 Subject: [PATCH 04/11] added normals to voxel shader --- interface/resources/shaders/voxel.geom | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/interface/resources/shaders/voxel.geom b/interface/resources/shaders/voxel.geom index 13b502357e..ca8f729542 100644 --- a/interface/resources/shaders/voxel.geom +++ b/interface/resources/shaders/voxel.geom @@ -26,14 +26,17 @@ const int VERTICES_PER_FACE = 4; const int COORD_PER_VERTEX = 3; const int COORD_PER_FACE = COORD_PER_VERTEX * VERTICES_PER_FACE; -void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec4 color) { +void faceOfVoxel(vec4 corner, float scale, float[COORD_PER_FACE] facePoints, vec4 color, vec4 normal) { for (int v = 0; v < VERTICES_PER_FACE; v++ ) { vec4 vertex = corner; for (int c = 0; c < COORD_PER_VERTEX; c++ ) { int cIndex = c + (v * COORD_PER_VERTEX); vertex[c] += (facePoints[cIndex] * scale); } - gl_FrontColor = color; + + gl_FrontColor = color * (gl_LightModel.ambient + gl_LightSource[0].ambient + + gl_LightSource[0].diffuse * max(0.0, dot(normal, gl_LightSource[0].position))); + gl_Position = gl_ModelViewProjectionMatrix * vertex; EmitVertex(); } @@ -54,14 +57,21 @@ void main() { float frontFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0 ); float backFace[COORD_PER_FACE] = float[COORD_PER_FACE]( 1, 0, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1 ); + vec4 bottomNormal = vec4(0.0, -1, 0.0, 0.0); + vec4 topNormal = vec4(0.0, 1, 0.0, 0.0); + vec4 rightNormal = vec4( -1, 0.0, 0.0, 0.0); + vec4 leftNormal = vec4( 1, 0.0, 0.0, 0.0); + vec4 frontNormal = vec4(0.0, 0.0, -1, 0.0); + vec4 backNormal = vec4(0.0, 0.0, 1, 0.0); + for(i = 0; i < gl_VerticesIn; i++) { corner = gl_PositionIn[i]; scale = voxelSize[i]; - faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i]); - faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i]); - faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i]); - faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i]); - faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i]); - faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i]); + faceOfVoxel(corner, scale, bottomFace, gl_FrontColorIn[i], bottomNormal); + faceOfVoxel(corner, scale, topFace, gl_FrontColorIn[i], topNormal ); + faceOfVoxel(corner, scale, rightFace, gl_FrontColorIn[i], rightNormal ); + faceOfVoxel(corner, scale, leftFace, gl_FrontColorIn[i], leftNormal ); + faceOfVoxel(corner, scale, frontFace, gl_FrontColorIn[i], frontNormal ); + faceOfVoxel(corner, scale, backFace, gl_FrontColorIn[i], backNormal ); } } \ No newline at end of file From 8cffa8d872d5292d9dbd9a4971673b71d6830dbf Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 27 Sep 2013 15:04:44 -0700 Subject: [PATCH 05/11] add support for global normals for voxels --- interface/src/Menu.cpp | 3 + interface/src/Menu.h | 1 + interface/src/VoxelSystem.cpp | 355 ++++++++++++++++++-------- interface/src/VoxelSystem.h | 12 + libraries/voxels/src/VoxelConstants.h | 6 + 5 files changed, 266 insertions(+), 111 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index fa42e4c274..784614043a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -256,6 +256,9 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseByteNormals, 0, false, Application::getInstance()->getVoxels(), SLOT(setUseByteNormals(bool))); + + addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseGlobalNormals, 0, + false, Application::getInstance()->getVoxels(), SLOT(setUseGlobalNormals(bool))); QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 7cbbdbdc11..a2d0267d58 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -207,6 +207,7 @@ namespace MenuOption { const QString Quit = "Quit"; const QString UseVoxelShader = "Use Voxel Shader"; const QString UseByteNormals = "Use Byte Normals"; + const QString UseGlobalNormals = "Use Global Normals"; 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 88661dd2bd..faeec9352b 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -33,9 +33,11 @@ #include "VoxelConstants.h" #include "VoxelSystem.h" -float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, - 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, - 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 }; +float identityVerticesGlobalNormals[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 }; + +float identityVertices[] = { 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, //0-7 + 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1, //8-15 + 0,0,0, 1,0,0, 1,1,0, 0,1,0, 0,0,1, 1,0,1, 1,1,1, 0,1,1 }; // 16-23 GLfloat identityNormals[] = { 0,0,-1, 0,0,-1, 0,0,-1, 0,0,-1, 0,0,+1, 0,0,+1, 0,0,+1, 0,0,+1, @@ -51,6 +53,13 @@ GLubyte identityIndices[] = { 0,2,1, 0,3,2, // Z- 10,11,15, 10,15,14, // Y+ 4,5,6, 4,6,7 }; // Z+ +GLubyte identityIndicesTop[] = { 2, 3, 7, 2, 7, 6 }; +GLubyte identityIndicesBottom[] = { 0, 1, 5, 0, 5, 4 }; +GLubyte identityIndicesLeft[] = { 0, 7, 3, 0, 4, 7 }; +GLubyte identityIndicesRight[] = { 1, 2, 6, 1, 6, 5 }; +GLubyte identityIndicesFront[] = { 0, 2, 1, 0, 3, 2 }; +GLubyte identityIndicesBack[] = { 4, 5, 6, 4, 6, 7 }; + VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) : NodeData(NULL), _treeScale(treeScale), @@ -77,6 +86,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) _useVoxelShader = false; _useByteNormals = false; + _useGlobalNormals = false; _writeVoxelShaderData = NULL; _readVoxelShaderData = NULL; @@ -145,6 +155,7 @@ void VoxelSystem::setUseByteNormals(bool useByteNormals) { pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; if (wasInitialized) { + clearAllNodesBufferIndex(); cleanupVoxelMemory(); } _useByteNormals = useByteNormals; @@ -158,11 +169,29 @@ void VoxelSystem::setUseByteNormals(bool useByteNormals) { } } +void VoxelSystem::setUseGlobalNormals(bool useGlobalNormals) { + pthread_mutex_lock(&_bufferWriteLock); + bool wasInitialized = _initialized; + if (wasInitialized) { + clearAllNodesBufferIndex(); + cleanupVoxelMemory(); + } + _useGlobalNormals = useGlobalNormals; + if (wasInitialized) { + init(); + } + pthread_mutex_unlock(&_bufferWriteLock); + + if (wasInitialized) { + forceRedrawEntireTree(); + } +} void VoxelSystem::setMaxVoxels(int maxVoxels) { pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; if (wasInitialized) { + clearAllNodesBufferIndex(); cleanupVoxelMemory(); } _maxVoxels = maxVoxels; @@ -206,9 +235,19 @@ void VoxelSystem::cleanupVoxelMemory() { } else { // Destroy glBuffers glDeleteBuffers(1, &_vboVerticesID); - glDeleteBuffers(1, &_vboNormalsID); glDeleteBuffers(1, &_vboColorsID); - glDeleteBuffers(1, &_vboIndicesID); + + if (!_useGlobalNormals) { + glDeleteBuffers(1, &_vboNormalsID); + glDeleteBuffers(1, &_vboIndicesID); + } else { + glDeleteBuffers(1, &_vboIndicesTop); + glDeleteBuffers(1, &_vboIndicesBottom); + glDeleteBuffers(1, &_vboIndicesLeft); + glDeleteBuffers(1, &_vboIndicesRight); + glDeleteBuffers(1, &_vboIndicesFront); + glDeleteBuffers(1, &_vboIndicesBack); + } delete[] _readVerticesArray; delete[] _writeVerticesArray; @@ -221,6 +260,34 @@ void VoxelSystem::cleanupVoxelMemory() { _initialized = false; // no longer initialized } +void VoxelSystem::setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]) { + GLuint* indicesArray = new GLuint[INDICES_PER_FACE * _maxVoxels]; + + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now + for (int n = 0; n < _maxVoxels; n++) { + // fill the indices array + int voxelIndexOffset = n * INDICES_PER_FACE; + GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; + int startIndex = (n * GLOBAL_NORMALS_VERTICES_PER_VOXEL); + + for (int i = 0; i < INDICES_PER_FACE; i++) { + // add indices for this side of the cube + currentIndicesPos[i] = startIndex + faceIdentityIndices[i]; + } + } + + glGenBuffers(1, &faceVBOID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, faceVBOID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + INDICES_PER_FACE * sizeof(GLuint) * _maxVoxels, + indicesArray, GL_STATIC_DRAW); + _memoryUsageVBO += INDICES_PER_FACE * sizeof(GLuint) * _maxVoxels; + + // delete the indices and normals arrays that are no longer needed + delete[] indicesArray; +} + void VoxelSystem::initVoxelMemory() { _initialMemoryUsageGPU = getFreeMemoryGPU(); _memoryUsageRAM = 0; @@ -265,91 +332,104 @@ void VoxelSystem::initVoxelMemory() { _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); } else { - GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; - - // populate the indicesArray - // this will not change given new voxels, so we can set it all up now - for (int n = 0; n < _maxVoxels; n++) { - // fill the indices array - int voxelIndexOffset = n * INDICES_PER_VOXEL; - GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; - int startIndex = (n * VERTICES_PER_VOXEL); - - for (int i = 0; i < INDICES_PER_VOXEL; i++) { - // add indices for this side of the cube - currentIndicesPos[i] = startIndex + identityIndices[i]; - } - } - - if (_useByteNormals) { - qDebug("Using Byte Normals...\n"); - GLbyte* normalsArray = new GLbyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLbyte* normalsArrayEndPointer = normalsArray; - - // populate the normalsArray - for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = (identityNormals[i] * CHAR_MAX); - } - } - - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; - - // delete the indices and normals arrays that are no longer needed - delete[] normalsArray; + if (_useGlobalNormals) { + // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead + // rendering the voxel faces in 6 passes that use a global call to glNormal3f() + qDebug("Using Global Normals...\n"); + setupFaceIndices(_vboIndicesTop, identityIndicesTop); + setupFaceIndices(_vboIndicesBottom, identityIndicesBottom); + setupFaceIndices(_vboIndicesLeft, identityIndicesLeft); + setupFaceIndices(_vboIndicesRight, identityIndicesRight); + setupFaceIndices(_vboIndicesFront, identityIndicesFront); + setupFaceIndices(_vboIndicesBack, identityIndicesBack); } else { - qDebug("Using Float Normals...\n"); - GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLfloat* normalsArrayEndPointer = normalsArray; + if (_useByteNormals) { + qDebug("Using Byte Normals...\n"); + GLbyte* normalsArray = new GLbyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + GLbyte* normalsArrayEndPointer = normalsArray; - // populate the normalsArray + // populate the normalsArray + for (int n = 0; n < _maxVoxels; n++) { + for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { + *(normalsArrayEndPointer++) = (identityNormals[i] * CHAR_MAX); + } + } + + // VBO for the normalsArray + glGenBuffers(1, &_vboNormalsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glBufferData(GL_ARRAY_BUFFER, + VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, + normalsArray, GL_STATIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; + + // delete the indices and normals arrays that are no longer needed + delete[] normalsArray; + } else { + qDebug("Using Float Normals...\n"); + GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; + GLfloat* normalsArrayEndPointer = normalsArray; + + // populate the normalsArray + for (int n = 0; n < _maxVoxels; n++) { + for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { + *(normalsArrayEndPointer++) = identityNormals[i]; + } + } + + // VBO for the normalsArray + glGenBuffers(1, &_vboNormalsID); + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glBufferData(GL_ARRAY_BUFFER, + VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, + normalsArray, GL_STATIC_DRAW); + _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; + + // delete the indices and normals arrays that are no longer needed + delete[] normalsArray; + } + + GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; + + // populate the indicesArray + // this will not change given new voxels, so we can set it all up now for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = identityNormals[i]; + // fill the indices array + int voxelIndexOffset = n * INDICES_PER_VOXEL; + GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; + int startIndex = (n * VERTICES_PER_VOXEL); + + for (int i = 0; i < INDICES_PER_VOXEL; i++) { + // add indices for this side of the cube + currentIndicesPos[i] = startIndex + identityIndices[i]; } } - - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; + + // VBO for the indicesArray + glGenBuffers(1, &_vboIndicesID); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, + indicesArray, GL_STATIC_DRAW); + _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; // delete the indices and normals arrays that are no longer needed - delete[] normalsArray; + delete[] indicesArray; + } - - + + // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel + int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; glGenBuffers(1, &_vboVerticesID); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; + glBufferData(GL_ARRAY_BUFFER, vertexPointsPerVoxel * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + _memoryUsageVBO += vertexPointsPerVoxel * sizeof(GLfloat) * _maxVoxels; // VBO for colorsArray glGenBuffers(1, &_vboColorsID); glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); - glBufferData(GL_ARRAY_BUFFER, VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte) * _maxVoxels; - - // VBO for the indicesArray - glGenBuffers(1, &_vboIndicesID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, - indicesArray, GL_STATIC_DRAW); - _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; - - // delete the indices and normals arrays that are no longer needed - delete[] indicesArray; - + glBufferData(GL_ARRAY_BUFFER, vertexPointsPerVoxel * sizeof(GLubyte) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); + _memoryUsageVBO += vertexPointsPerVoxel * sizeof(GLubyte) * _maxVoxels; // we will track individual dirty sections with these arrays of bools _writeVoxelDirtyArray = new bool[_maxVoxels]; @@ -361,15 +441,15 @@ void VoxelSystem::initVoxelMemory() { _memoryUsageRAM += (sizeof(bool) * _maxVoxels); // prep the data structures for incoming voxel data - _writeVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); - _readVerticesArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _memoryUsageRAM += (sizeof(GLfloat) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); + _writeVerticesArray = new GLfloat[vertexPointsPerVoxel * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLfloat) * vertexPointsPerVoxel * _maxVoxels); + _readVerticesArray = new GLfloat[vertexPointsPerVoxel * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLfloat) * vertexPointsPerVoxel * _maxVoxels); - _writeColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); - _readColorsArray = new GLubyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - _memoryUsageRAM += (sizeof(GLubyte) * VERTEX_POINTS_PER_VOXEL * _maxVoxels); + _writeColorsArray = new GLubyte[vertexPointsPerVoxel * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels); + _readColorsArray = new GLubyte[vertexPointsPerVoxel * _maxVoxels]; + _memoryUsageRAM += (sizeof(GLubyte) * vertexPointsPerVoxel * _maxVoxels); // create our simple fragment shader if we're the first system to init @@ -649,16 +729,19 @@ void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, void* writeDataAt = &_writeVoxelShaderData[segmentStart]; memcpy(readDataAt, writeDataAt, segmentSizeBytes); } else { - GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel + int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + + GLintptr segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLfloat); + GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * vertexPointsPerVoxel); + GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * vertexPointsPerVoxel); memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); - segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - GLubyte* readColorsAt = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); - GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLubyte); + segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLubyte); + GLubyte* readColorsAt = _readColorsArray + (segmentStart * vertexPointsPerVoxel); + GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * vertexPointsPerVoxel); memcpy(readColorsAt, writeColorsAt, segmentSizeBytes); } } @@ -797,10 +880,17 @@ void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& s } } else { if (_writeVerticesArray && _writeColorsArray) { - for (int j = 0; j < VERTEX_POINTS_PER_VOXEL; j++ ) { - GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * VERTEX_POINTS_PER_VOXEL); - *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); + int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + for (int j = 0; j < vertexPointsPerVoxel; j++ ) { + GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * vertexPointsPerVoxel); + GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * vertexPointsPerVoxel); + + if (_useGlobalNormals) { + *(writeVerticesAt+j) = startVertex[j % 3] + (identityVerticesGlobalNormals[j] * voxelScale); + } else { + *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); + } + *(writeColorsAt +j) = color[j % 3]; } } @@ -912,15 +1002,16 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); } else { + int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; int segmentLength = (segmentEnd - segmentStart) + 1; - GLintptr segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLsizeiptr segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat); - GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + GLintptr segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLfloat); + GLsizeiptr segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLfloat); + GLfloat* readVerticesFrom = _readVerticesArray + (segmentStart * vertexPointsPerVoxel); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); - segmentStartAt = segmentStart * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - segmentSizeBytes = segmentLength * VERTEX_POINTS_PER_VOXEL * sizeof(GLubyte); - GLubyte* readColorsFrom = _readColorsArray + (segmentStart * VERTEX_POINTS_PER_VOXEL); + segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLubyte); + segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLubyte); + GLubyte* readColorsFrom = _readColorsArray + (segmentStart * vertexPointsPerVoxel); glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readColorsFrom); } @@ -966,27 +1057,66 @@ void VoxelSystem::render(bool texture) { } else { // tell OpenGL where to find vertex and color information glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); glEnableClientState(GL_COLOR_ARRAY); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glVertexPointer(3, GL_FLOAT, 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glNormalPointer((_useByteNormals ? GL_BYTE : GL_FLOAT), 0, 0); - glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); + if (!_useGlobalNormals) { + glEnableClientState(GL_NORMAL_ARRAY); + glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); + glNormalPointer((_useByteNormals ? GL_BYTE : GL_FLOAT), 0, 0); + } else { + glNormal3f(0,1.0f,0); // hack for now + } + applyScaleAndBindProgram(texture); // for performance, enable backface culling glEnable(GL_CULL_FACE); - // draw the number of voxels we have - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, - 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + if (!_useGlobalNormals) { + // draw the number of voxels we have + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, + 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); + } else { + // 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); + + 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, _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); + } + glDisable(GL_CULL_FACE); @@ -994,9 +1124,12 @@ void VoxelSystem::render(bool texture) { // deactivate vertex and color arrays after drawing glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); glDisableClientState(GL_COLOR_ARRAY); + if (!_useGlobalNormals) { + glDisableClientState(GL_NORMAL_ARRAY); + } + // bind with 0 to switch back to normal operation glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5e56cfe8a6..bf5beb6263 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -135,6 +135,7 @@ public slots: void cancelImport(); void setUseByteNormals(bool useByteNormals); + void setUseGlobalNormals(bool useGlobalNormals); protected: float _treeScale; @@ -218,6 +219,7 @@ private: void cleanupVoxelMemory(); bool _useByteNormals; + bool _useGlobalNormals; bool _useVoxelShader; GLuint _vboVoxelsID; /// when using voxel shader, we'll use this VBO @@ -229,6 +231,14 @@ private: GLuint _vboNormalsID; GLuint _vboColorsID; GLuint _vboIndicesID; + + GLuint _vboIndicesTop; + GLuint _vboIndicesBottom; + GLuint _vboIndicesLeft; + GLuint _vboIndicesRight; + GLuint _vboIndicesFront; + GLuint _vboIndicesBack; + pthread_mutex_t _bufferWriteLock; pthread_mutex_t _treeLock; @@ -236,6 +246,8 @@ private: ViewFrustum _lastStableViewFrustum; ViewFrustum* _viewFrustum; + void setupFaceIndices(GLuint& faceVBOID, GLubyte faceIdentityIndices[]); + int newTreeToArrays(VoxelNode *currentNode); void cleanupRemovedVoxels(); diff --git a/libraries/voxels/src/VoxelConstants.h b/libraries/voxels/src/VoxelConstants.h index 391be29282..1871aa8e31 100644 --- a/libraries/voxels/src/VoxelConstants.h +++ b/libraries/voxels/src/VoxelConstants.h @@ -38,6 +38,12 @@ const int VERTEX_POINTS_PER_VOXEL = 3 * VERTICES_PER_VOXEL; // xyz for each VERT const int INDICES_PER_VOXEL = 3 * 12; // 6 sides * 2 triangles per size * 3 vertices per triangle const int COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * VERTICES_PER_VOXEL; +const int VERTICES_PER_FACE = 4; // 6 sides * 4 corners per side +const int INDICES_PER_FACE = 3 * 2; // 1 side * 2 triangles per size * 3 vertices per triangle +const int GLOBAL_NORMALS_VERTICES_PER_VOXEL = 8; // no need for 3 copies because they don't include normal +const int GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL = 3 * GLOBAL_NORMALS_VERTICES_PER_VOXEL; +const int GLOBAL_NORMALS_COLOR_VALUES_PER_VOXEL = NUMBER_OF_COLORS * GLOBAL_NORMALS_VERTICES_PER_VOXEL; + typedef unsigned long int glBufferIndex; const glBufferIndex GLBUFFER_INDEX_UNKNOWN = ULONG_MAX; From c78aa591c53ff9aec7aa4a87b18e668713eaa9f3 Mon Sep 17 00:00:00 2001 From: Freddy Date: Fri, 27 Sep 2013 15:08:10 -0700 Subject: [PATCH 06/11] Fix spinning while flying, top speed now about Mach 1 --- interface/src/avatar/MyAvatar.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cf1ed4d1fc..4f7535318a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -211,7 +211,7 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { // Damp avatar velocity const float LINEAR_DAMPING_STRENGTH = 0.5f; const float SPEED_BRAKE_POWER = _scale * 10.0f; - const float SQUARED_DAMPING_STRENGTH = 0.0f; + const float SQUARED_DAMPING_STRENGTH = 0.007f; float linearDamping = LINEAR_DAMPING_STRENGTH; const float AVATAR_DAMPING_FACTOR = 120.f; @@ -225,12 +225,15 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { } // pitch and roll the body as a function of forward speed and turning delta - const float BODY_PITCH_WHILE_WALKING = -20.0; - const float BODY_ROLL_WHILE_TURNING = 0.2; - float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); - orientation = orientation * glm::quat(glm::radians(glm::vec3( - BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, - BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + const float HIGH_VELOCITY = 10.f; + if (glm::length(_velocity) < HIGH_VELOCITY) { + const float BODY_PITCH_WHILE_WALKING = -20.0; + const float BODY_ROLL_WHILE_TURNING = 0.2; + float forwardComponentOfVelocity = glm::dot(getBodyFrontDirection(), _velocity); + orientation = orientation * glm::quat(glm::radians(glm::vec3( + BODY_PITCH_WHILE_WALKING * deltaTime * forwardComponentOfVelocity, 0.0f, + BODY_ROLL_WHILE_TURNING * deltaTime * _speed * _bodyYawDelta))); + } // these forces keep the body upright... const float BODY_UPRIGHT_FORCE = _scale * 10.0; @@ -648,8 +651,12 @@ void MyAvatar::updateThrust(float deltaTime, Transmitter * transmitter) { // If thrust keys are being held down, slowly increase thrust to allow reaching great speeds if (_driveKeys[FWD] || _driveKeys[BACK] || _driveKeys[RIGHT] || _driveKeys[LEFT] || _driveKeys[UP] || _driveKeys[DOWN]) { - const float THRUST_INCREASE_RATE = 1.0; - _thrustMultiplier *= 1.f + deltaTime * THRUST_INCREASE_RATE; + const float THRUST_INCREASE_RATE = 1.05; + const float MAX_THRUST_MULTIPLIER = 75.0; + //printf("m = %.3f\n", _thrustMultiplier); + if (_thrustMultiplier < MAX_THRUST_MULTIPLIER) { + _thrustMultiplier *= 1.f + deltaTime * THRUST_INCREASE_RATE; + } } else { _thrustMultiplier = 1.f; } From ad8c676feab3c4bc51792f694a80026cfec5ca47 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 27 Sep 2013 16:23:07 -0700 Subject: [PATCH 07/11] sensibly initialize _shouldStop to false --- assignment-client/src/Agent.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index aabf9fba66..60b226c677 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -16,7 +16,10 @@ #include "Agent.h" #include "voxels/VoxelScriptingInterface.h" -Agent::Agent(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { +Agent::Agent(const unsigned char* dataBuffer, int numBytes) : + Assignment(dataBuffer, numBytes), + _shouldStop(false) +{ } From 39cf3375e552c4ae140e5a9fe1605c5e38c52a94 Mon Sep 17 00:00:00 2001 From: PhilipRosedale Date: Fri, 27 Sep 2013 16:27:42 -0700 Subject: [PATCH 08/11] small change to README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d83e17dcd6..e0d85e3f6b 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,7 @@ and features are available via menus in the Interface application. Other components ======== -voxel-server, animation-server, audio-mixer, avatar-mixer, domain-server, +assignment-client, animation-server, domain-server, pairing-server and space-server are architectural components that will allow you to run the full stack of the virtual world should you choose to. From a0f23d409ed711587ecc078c322eef93b3bc8433 Mon Sep 17 00:00:00 2001 From: stojce Date: Sat, 28 Sep 2013 13:16:50 +0200 Subject: [PATCH 09/11] Merging changes --- interface/src/Application.cpp | 1 + interface/src/Application.h | 4 +++- libraries/shared/src/NodeList.cpp | 23 +++++++++++++++++++++++ 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 533a4b4246..f10f98c3b3 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3423,6 +3423,7 @@ void Application::attachNewHeadToNode(Node* newNode) { } void Application::domainChanged(QString domain) { + qDebug("Application title set to: %s.\n", domain.toStdString().c_str()); _window->setWindowTitle(domain); } diff --git a/interface/src/Application.h b/interface/src/Application.h index a8e84e5c2a..620d6d57f5 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -77,7 +77,7 @@ static const float NODE_KILLED_RED = 1.0f; static const float NODE_KILLED_GREEN = 0.0f; static const float NODE_KILLED_BLUE = 0.0f; -class Application : public QApplication, public NodeListHook, public PacketSenderNotify { +class Application : public QApplication, public NodeListHook, public PacketSenderNotify, public DomainChangeListener { Q_OBJECT friend class VoxelPacketProcessor; @@ -146,6 +146,8 @@ public: virtual void nodeKilled(Node* node); virtual void packetSentNotification(ssize_t length); + virtual void domainChanged(QString domain); + VoxelShader& getVoxelShader() { return _voxelShader; } public slots: diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 8901ca3271..7b31a2de15 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -109,6 +109,7 @@ void NodeList::setDomainHostname(const QString& domainHostname) { // reset our _domainIP to the null address so that a lookup happens on next check in _domainIP.clear(); + notifyDomainChanged(); } void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { @@ -585,6 +586,7 @@ void NodeList::loadData(QSettings *settings) { if (domainServerHostname.size() > 0) { _domainHostname = domainServerHostname; + notifyDomainChanged(); } settings->endGroup(); @@ -678,6 +680,21 @@ void NodeListIterator::skipDeadAndStopIncrement() { } } +void NodeList::addDomainListener(DomainChangeListener* listener) { + _domainListeners.push_back(listener); + QString domain = _domainHostname.isEmpty() ? _domainIP.toString() : _domainHostname; + listener->domainChanged(domain); +} + +void NodeList::removeDomainListener(DomainChangeListener* listener) { + for (int i = 0; i < _domainListeners.size(); i++) { + if (_domainListeners[i] == listener) { + _domainListeners.erase(_domainListeners.begin() + i); + return; + } + } +} + void NodeList::addHook(NodeListHook* hook) { _hooks.push_back(hook); } @@ -704,3 +721,9 @@ void NodeList::notifyHooksOfKilledNode(Node* node) { _hooks[i]->nodeKilled(node); } } + +void NodeList::notifyDomainChanged() { + for (int i = 0; i < _domainListeners.size(); i++) { + _domainListeners[i]->domainChanged(_domainHostname); + } +} From 9645cd98310651fb163cf8c4897ae0d38843b9f7 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Sat, 28 Sep 2013 15:18:59 -0700 Subject: [PATCH 10/11] Click on voxels as way of moving around --- interface/src/Application.cpp | 11 +++++++++++ interface/src/avatar/MyAvatar.cpp | 29 ++++++++++++++++++++++++++--- interface/src/avatar/MyAvatar.h | 3 +++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f10f98c3b3..ed1e513b91 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1001,6 +1001,17 @@ void Application::mousePressEvent(QMouseEvent* event) { _audio.startCollisionSound(1.0, frequency, 0.0, HOVER_VOXEL_DECAY); _isHoverVoxelSounding = true; + + const float PERCENTAGE_TO_MOVE_TOWARD = 0.90f; + glm::vec3 newTarget = getMouseVoxelWorldCoordinates(_hoverVoxel); + glm::vec3 myPosition = _myAvatar.getPosition(); + + // If there is not an action tool set (add, delete, color), move to this voxel + if (!(Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) || + Menu::getInstance()->isOptionChecked(MenuOption::VoxelDeleteMode) || + Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode))) { + _myAvatar.setMoveTarget(myPosition + (newTarget - myPosition) * PERCENTAGE_TO_MOVE_TOWARD); + } } } else if (event->button() == Qt::RightButton && Menu::getInstance()->isVoxelModeActionChecked()) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4f7535318a..96b9877ede 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -50,7 +50,9 @@ MyAvatar::MyAvatar(Node* owningNode) : _lastCollisionPosition(0, 0, 0), _speedBrakes(false), _isThrustOn(false), - _thrustMultiplier(1.0f) + _thrustMultiplier(1.0f), + _moveTarget(0,0,0), + _moveTargetStepCounter(0) { for (int i = 0; i < MAX_DRIVE_KEYS; i++) { _driveKeys[i] = false; @@ -64,6 +66,11 @@ void MyAvatar::reset() { _hand.reset(); } +void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) { + _moveTarget = moveTarget; + _moveTargetStepCounter = 0; +} + void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { glm::quat orientation = getOrientation(); @@ -165,8 +172,10 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { if (glm::length(_position - _lastCollisionPosition) > MIN_DISTANCE_AFTER_COLLISION_FOR_GRAVITY) { _velocity += _scale * _gravity * (GRAVITY_EARTH * deltaTime); } + + // Only collide if we are not moving to a target + if (_isCollisionsOn && (glm::length(_moveTarget) < EPSILON)) { - if (_isCollisionsOn) { Camera* myCamera = Application::getInstance()->getCamera(); if (myCamera->getMode() == CAMERA_MODE_FIRST_PERSON && !OculusManager::isConnected()) { @@ -324,7 +333,21 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { const float MOVING_SPEED_THRESHOLD = 0.01f; _moving = _speed > MOVING_SPEED_THRESHOLD; - // update position by velocity, and subtract the change added earlier for gravity + // If a move target is set, update position explicitly + const float MOVE_FINISHED_TOLERANCE = 0.1f; + const float MOVE_SPEED_FACTOR = 2.f; + const int MOVE_TARGET_MAX_STEPS = 250; + if ((glm::length(_moveTarget) > EPSILON) && (_moveTargetStepCounter < MOVE_TARGET_MAX_STEPS)) { + if (glm::length(_position - _moveTarget) > MOVE_FINISHED_TOLERANCE) { + _position += (_moveTarget - _position) * (deltaTime * MOVE_SPEED_FACTOR); + _moveTargetStepCounter++; + } else { + // Move completed + _moveTarget = glm::vec3(0,0,0); + _moveTargetStepCounter = 0; + } + } + _position += _velocity * deltaTime; // Zero thrust out now that we've added it to velocity in this frame diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index d0f7d74bf4..95c1efd5a8 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -31,6 +31,7 @@ public: void setOrientation(const glm::quat& orientation); void setNewScale(const float scale); void setWantCollisionsOn(bool wantCollisionsOn) { _isCollisionsOn = wantCollisionsOn; } + void setMoveTarget(const glm::vec3 moveTarget); // getters float getNewScale() const { return _newScale; } @@ -73,6 +74,8 @@ public: bool _isThrustOn; float _thrustMultiplier; float _collisionRadius; + glm::vec3 _moveTarget; + int _moveTargetStepCounter; // private methods float getBallRenderAlpha(int ball, bool lookingInMirror) const; From b6fe8befdc6ae9a2c25d0b63a8d44727cac2d524 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Mon, 30 Sep 2013 09:29:04 -0700 Subject: [PATCH 11/11] removed old normal support from voxel system only using global normals --- interface/src/Application.cpp | 1 - interface/src/Menu.cpp | 6 - interface/src/VoxelSystem.cpp | 235 ++++++--------------------- interface/src/VoxelSystem.h | 7 - libraries/voxels/src/ViewFrustum.cpp | 2 +- 5 files changed, 47 insertions(+), 204 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 61f7e416dd..1412a09401 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1577,7 +1577,6 @@ 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.setUseByteNormals(Menu::getInstance()->isOptionChecked(MenuOption::UseByteNormals)); _voxels.init(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index a9607ee49e..a60f2b6e55 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -254,12 +254,6 @@ Menu::Menu() : addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseVoxelShader, 0, false, this, SLOT(switchVoxelShader())); - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseByteNormals, 0, - false, Application::getInstance()->getVoxels(), SLOT(setUseByteNormals(bool))); - - addCheckableActionToQMenuAndActionHash(voxelOptionsMenu, MenuOption::UseGlobalNormals, 0, - false, Application::getInstance()->getVoxels(), SLOT(setUseGlobalNormals(bool))); - QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options"); addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true); diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index faeec9352b..97b482bbd4 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -85,9 +85,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) connect(_tree, SIGNAL(importProgress(int)), SIGNAL(importProgress(int))); _useVoxelShader = false; - _useByteNormals = false; - _useGlobalNormals = false; - + _writeVoxelShaderData = NULL; _readVoxelShaderData = NULL; @@ -151,42 +149,6 @@ VoxelSystem::~VoxelSystem() { VoxelNode::removeDeleteHook(this); } -void VoxelSystem::setUseByteNormals(bool useByteNormals) { - pthread_mutex_lock(&_bufferWriteLock); - bool wasInitialized = _initialized; - if (wasInitialized) { - clearAllNodesBufferIndex(); - cleanupVoxelMemory(); - } - _useByteNormals = useByteNormals; - if (wasInitialized) { - init(); - } - pthread_mutex_unlock(&_bufferWriteLock); - - if (wasInitialized) { - forceRedrawEntireTree(); - } -} - -void VoxelSystem::setUseGlobalNormals(bool useGlobalNormals) { - pthread_mutex_lock(&_bufferWriteLock); - bool wasInitialized = _initialized; - if (wasInitialized) { - clearAllNodesBufferIndex(); - cleanupVoxelMemory(); - } - _useGlobalNormals = useGlobalNormals; - if (wasInitialized) { - init(); - } - pthread_mutex_unlock(&_bufferWriteLock); - - if (wasInitialized) { - forceRedrawEntireTree(); - } -} - void VoxelSystem::setMaxVoxels(int maxVoxels) { pthread_mutex_lock(&_bufferWriteLock); bool wasInitialized = _initialized; @@ -237,17 +199,12 @@ void VoxelSystem::cleanupVoxelMemory() { glDeleteBuffers(1, &_vboVerticesID); glDeleteBuffers(1, &_vboColorsID); - if (!_useGlobalNormals) { - glDeleteBuffers(1, &_vboNormalsID); - glDeleteBuffers(1, &_vboIndicesID); - } else { - glDeleteBuffers(1, &_vboIndicesTop); - glDeleteBuffers(1, &_vboIndicesBottom); - glDeleteBuffers(1, &_vboIndicesLeft); - glDeleteBuffers(1, &_vboIndicesRight); - glDeleteBuffers(1, &_vboIndicesFront); - glDeleteBuffers(1, &_vboIndicesBack); - } + glDeleteBuffers(1, &_vboIndicesTop); + glDeleteBuffers(1, &_vboIndicesBottom); + glDeleteBuffers(1, &_vboIndicesLeft); + glDeleteBuffers(1, &_vboIndicesRight); + glDeleteBuffers(1, &_vboIndicesFront); + glDeleteBuffers(1, &_vboIndicesBack); delete[] _readVerticesArray; delete[] _writeVerticesArray; @@ -332,94 +289,19 @@ void VoxelSystem::initVoxelMemory() { _readVoxelShaderData = new VoxelShaderVBOData[_maxVoxels]; _memoryUsageRAM += (sizeof(VoxelShaderVBOData) * _maxVoxels); } else { - if (_useGlobalNormals) { - // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead - // rendering the voxel faces in 6 passes that use a global call to glNormal3f() - qDebug("Using Global Normals...\n"); - setupFaceIndices(_vboIndicesTop, identityIndicesTop); - setupFaceIndices(_vboIndicesBottom, identityIndicesBottom); - setupFaceIndices(_vboIndicesLeft, identityIndicesLeft); - setupFaceIndices(_vboIndicesRight, identityIndicesRight); - setupFaceIndices(_vboIndicesFront, identityIndicesFront); - setupFaceIndices(_vboIndicesBack, identityIndicesBack); - } else { - if (_useByteNormals) { - qDebug("Using Byte Normals...\n"); - GLbyte* normalsArray = new GLbyte[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLbyte* normalsArrayEndPointer = normalsArray; - // populate the normalsArray - for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = (identityNormals[i] * CHAR_MAX); - } - } - - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLbyte) * _maxVoxels; - - // delete the indices and normals arrays that are no longer needed - delete[] normalsArray; - } else { - qDebug("Using Float Normals...\n"); - GLfloat* normalsArray = new GLfloat[VERTEX_POINTS_PER_VOXEL * _maxVoxels]; - GLfloat* normalsArrayEndPointer = normalsArray; - - // populate the normalsArray - for (int n = 0; n < _maxVoxels; n++) { - for (int i = 0; i < VERTEX_POINTS_PER_VOXEL; i++) { - *(normalsArrayEndPointer++) = identityNormals[i]; - } - } - - // VBO for the normalsArray - glGenBuffers(1, &_vboNormalsID); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glBufferData(GL_ARRAY_BUFFER, - VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels, - normalsArray, GL_STATIC_DRAW); - _memoryUsageVBO += VERTEX_POINTS_PER_VOXEL * sizeof(GLfloat) * _maxVoxels; - - // delete the indices and normals arrays that are no longer needed - delete[] normalsArray; - } - - GLuint* indicesArray = new GLuint[INDICES_PER_VOXEL * _maxVoxels]; - - // populate the indicesArray - // this will not change given new voxels, so we can set it all up now - for (int n = 0; n < _maxVoxels; n++) { - // fill the indices array - int voxelIndexOffset = n * INDICES_PER_VOXEL; - GLuint* currentIndicesPos = indicesArray + voxelIndexOffset; - int startIndex = (n * VERTICES_PER_VOXEL); - - for (int i = 0; i < INDICES_PER_VOXEL; i++) { - // add indices for this side of the cube - currentIndicesPos[i] = startIndex + identityIndices[i]; - } - } - - // VBO for the indicesArray - glGenBuffers(1, &_vboIndicesID); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels, - indicesArray, GL_STATIC_DRAW); - _memoryUsageVBO += INDICES_PER_VOXEL * sizeof(GLuint) * _maxVoxels; - - // delete the indices and normals arrays that are no longer needed - delete[] indicesArray; - - } + // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead + // rendering the voxel faces in 6 passes that use a global call to glNormal3f() + qDebug("Using Global Normals...\n"); + setupFaceIndices(_vboIndicesTop, identityIndicesTop); + setupFaceIndices(_vboIndicesBottom, identityIndicesBottom); + setupFaceIndices(_vboIndicesLeft, identityIndicesLeft); + setupFaceIndices(_vboIndicesRight, identityIndicesRight); + setupFaceIndices(_vboIndicesFront, identityIndicesFront); + setupFaceIndices(_vboIndicesBack, identityIndicesBack); // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel - int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; glGenBuffers(1, &_vboVerticesID); glBindBuffer(GL_ARRAY_BUFFER, _vboVerticesID); glBufferData(GL_ARRAY_BUFFER, vertexPointsPerVoxel * sizeof(GLfloat) * _maxVoxels, NULL, GL_DYNAMIC_DRAW); @@ -730,7 +612,7 @@ void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, memcpy(readDataAt, writeDataAt, segmentSizeBytes); } else { // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel - int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; GLintptr segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLfloat); GLsizeiptr segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLfloat); @@ -880,17 +762,11 @@ void VoxelSystem::updateNodeInArrays(glBufferIndex nodeIndex, const glm::vec3& s } } else { if (_writeVerticesArray && _writeColorsArray) { - int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; for (int j = 0; j < vertexPointsPerVoxel; j++ ) { GLfloat* writeVerticesAt = _writeVerticesArray + (nodeIndex * vertexPointsPerVoxel); GLubyte* writeColorsAt = _writeColorsArray + (nodeIndex * vertexPointsPerVoxel); - - if (_useGlobalNormals) { - *(writeVerticesAt+j) = startVertex[j % 3] + (identityVerticesGlobalNormals[j] * voxelScale); - } else { - *(writeVerticesAt+j) = startVertex[j % 3] + (identityVertices[j] * voxelScale); - } - + *(writeVerticesAt+j) = startVertex[j % 3] + (identityVerticesGlobalNormals[j] * voxelScale); *(writeColorsAt +j) = color[j % 3]; } } @@ -1002,7 +878,7 @@ void VoxelSystem::updateVBOSegment(glBufferIndex segmentStart, glBufferIndex seg glBindBuffer(GL_ARRAY_BUFFER, _vboVoxelsID); glBufferSubData(GL_ARRAY_BUFFER, segmentStartAt, segmentSizeBytes, readVerticesFrom); } else { - int vertexPointsPerVoxel = _useGlobalNormals ? GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL : VERTEX_POINTS_PER_VOXEL; + int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; int segmentLength = (segmentEnd - segmentStart) + 1; GLintptr segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLfloat); GLsizeiptr segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLfloat); @@ -1065,57 +941,42 @@ void VoxelSystem::render(bool texture) { glBindBuffer(GL_ARRAY_BUFFER, _vboColorsID); glColorPointer(3, GL_UNSIGNED_BYTE, 0, 0); - if (!_useGlobalNormals) { - glEnableClientState(GL_NORMAL_ARRAY); - glBindBuffer(GL_ARRAY_BUFFER, _vboNormalsID); - glNormalPointer((_useByteNormals ? GL_BYTE : GL_FLOAT), 0, 0); - } else { - glNormal3f(0,1.0f,0); // hack for now - } - applyScaleAndBindProgram(texture); // for performance, enable backface culling glEnable(GL_CULL_FACE); - if (!_useGlobalNormals) { - // draw the number of voxels we have - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _vboIndicesID); - glDrawRangeElementsEXT(GL_TRIANGLES, 0, VERTICES_PER_VOXEL * _voxelsInReadArrays - 1, - 36 * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); - } else { - // draw voxels in 6 passes + // 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); + 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, _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, _vboIndicesBack); + glDrawRangeElementsEXT(GL_TRIANGLES, 0, INDICES_PER_FACE * _voxelsInReadArrays - 1, + INDICES_PER_FACE * _voxelsInReadArrays, GL_UNSIGNED_INT, 0); glDisable(GL_CULL_FACE); @@ -1126,10 +987,6 @@ void VoxelSystem::render(bool texture) { glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_COLOR_ARRAY); - if (!_useGlobalNormals) { - glDisableClientState(GL_NORMAL_ARRAY); - } - // bind with 0 to switch back to normal operation glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index bf5beb6263..f0d507c7ee 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -134,8 +134,6 @@ public slots: void clearAllNodesBufferIndex(); void cancelImport(); - void setUseByteNormals(bool useByteNormals); - void setUseGlobalNormals(bool useGlobalNormals); protected: float _treeScale; @@ -218,9 +216,6 @@ private: void initVoxelMemory(); void cleanupVoxelMemory(); - bool _useByteNormals; - bool _useGlobalNormals; - bool _useVoxelShader; 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 @@ -228,9 +223,7 @@ private: VoxelShaderVBOData* _readVoxelShaderData; GLuint _vboVerticesID; - GLuint _vboNormalsID; GLuint _vboColorsID; - GLuint _vboIndicesID; GLuint _vboIndicesTop; GLuint _vboIndicesBottom; diff --git a/libraries/voxels/src/ViewFrustum.cpp b/libraries/voxels/src/ViewFrustum.cpp index 7914ad0165..b6249ad3ab 100644 --- a/libraries/voxels/src/ViewFrustum.cpp +++ b/libraries/voxels/src/ViewFrustum.cpp @@ -443,7 +443,7 @@ void ViewFrustum::printDebugDetails() const { glm::vec2 ViewFrustum::projectPoint(glm::vec3 point, bool& pointInView) const { - glm::vec4 pointVec4 = glm::vec4(point,1) ; + glm::vec4 pointVec4 = glm::vec4(point,1); glm::vec4 projectedPointVec4 = _ourModelViewProjectionMatrix * pointVec4; pointInView = (projectedPointVec4.w > 0); // math! If the w result is negative then the point is behind the viewer