From 3eb7314c98684c00a18e16a3fe16f82ebd82e0cc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Thu, 11 Dec 2014 14:13:44 -0800 Subject: [PATCH] remove PrimitiveRenderer --- interface/src/voxels/PrimitiveRenderer.cpp | 742 --------------------- interface/src/voxels/PrimitiveRenderer.h | 503 -------------- interface/src/voxels/VoxelSystem.cpp | 534 ++------------- interface/src/voxels/VoxelSystem.h | 15 - 4 files changed, 61 insertions(+), 1733 deletions(-) delete mode 100644 interface/src/voxels/PrimitiveRenderer.cpp delete mode 100644 interface/src/voxels/PrimitiveRenderer.h diff --git a/interface/src/voxels/PrimitiveRenderer.cpp b/interface/src/voxels/PrimitiveRenderer.cpp deleted file mode 100644 index a212245289..0000000000 --- a/interface/src/voxels/PrimitiveRenderer.cpp +++ /dev/null @@ -1,742 +0,0 @@ -// -// PrimitiveRenderer.cpp -// interface/src/voxels -// -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#include - -#include "InterfaceConfig.h" -#include "OctreeElement.h" -#include "PrimitiveRenderer.h" - -Primitive::Primitive() { -} - -Primitive::~Primitive() { -} - -// Simple dispatch between API and SPI - -const VertexElementList& Primitive::vertexElements() const { - return vVertexElements(); -} - -VertexElementIndexList& Primitive::vertexElementIndices() { - return vVertexElementIndices(); -} - -TriElementList& Primitive::triElements() { - return vTriElements(); -} - -void Primitive::releaseVertexElements() { - vReleaseVertexElements(); -} - -unsigned long Primitive::getMemoryUsage() { - return vGetMemoryUsage(); -} - - -Cube::Cube( - float x, - float y, - float z, - float s, - unsigned char r, - unsigned char g, - unsigned char b, - unsigned char faceExclusions - ) : - _cpuMemoryUsage(0) { - init(x, y, z, s, r, g, b, faceExclusions); -} - -Cube::~Cube() { - terminate(); -} - -void Cube::init( - float x, - float y, - float z, - float s, - unsigned char r, - unsigned char g, - unsigned char b, - unsigned char faceExclusions - ) { - - initializeVertices(x, y, z, s, r, g, b, faceExclusions); - initializeTris(faceExclusions); -} - -void Cube::terminate() { - - terminateTris(); - terminateVertices(); -} - -void Cube::initializeVertices( - float x, - float y, - float z, - float s, - unsigned char r, - unsigned char g, - unsigned char b, - unsigned char faceExclusions - ) { - - for (int i = 0; i < _sNumVerticesPerCube; i++) { - // Check whether the vertex is necessary for the faces indicated by faceExclusions bit mask. - // uncomment this line to load all faces: if (~0x00 & _sFaceIndexToHalfSpaceMask[i >> 2]) { - // uncomment this line to include shared faces: if (faceExclusions & _sFaceIndexToHalfSpaceMask[i >> 2]) { - // uncomment this line to exclude shared faces: - if (~faceExclusions & _sFaceIndexToHalfSpaceMask[i >> 2]) { - - VertexElement* v = new VertexElement(); - if (v) { - // Construct vertex position - v->position.x = x + s * _sVertexIndexToConstructionVector[i][0]; - v->position.y = y + s * _sVertexIndexToConstructionVector[i][1]; - v->position.z = z + s * _sVertexIndexToConstructionVector[i][2]; - - // Construct vertex normal - v->normal.x = _sVertexIndexToNormalVector[i >> 2][0]; - v->normal.y = _sVertexIndexToNormalVector[i >> 2][1]; - v->normal.z = _sVertexIndexToNormalVector[i >> 2][2]; - - // Construct vertex color -//#define FALSE_COLOR -#ifndef FALSE_COLOR - v->color.r = r; - v->color.g = g; - v->color.b = b; - v->color.a = 255; -#else - static unsigned char falseColor[6][3] = { - 192, 0, 0, // Bot - 0, 192, 0, // Top - 0, 0, 192, // Right - 192, 0, 192, // Left - 192, 192, 0, // Near - 192, 192, 192 // Far - }; - v->color.r = falseColor[i >> 2][0]; - v->color.g = falseColor[i >> 2][1]; - v->color.b = falseColor[i >> 2][2]; - v->color.a = 255; -#endif - - // Add vertex element to list - _vertices.push_back(v); - _cpuMemoryUsage += sizeof(VertexElement); - _cpuMemoryUsage += sizeof(VertexElement*); - } - } - } -} - -void Cube::terminateVertices() { - - for (VertexElementList::iterator it = _vertices.begin(); it != _vertices.end(); ++it) { - delete *it; - } - _cpuMemoryUsage -= _vertices.size() * (sizeof(VertexElement) + sizeof(VertexElement*)); - _vertices.clear(); -} - -void Cube::initializeTris( - unsigned char faceExclusions - ) { - - int index = 0; - for (int i = 0; i < _sNumFacesPerCube; i++) { - // Check whether the vertex is necessary for the faces indicated by faceExclusions bit mask. - // uncomment this line to load all faces: if (~0x00 & _sFaceIndexToHalfSpaceMask[i]) { - // uncomment this line to include shared faces: if (faceExclusions & _sFaceIndexToHalfSpaceMask[i]) { - // uncomment this line to exclude shared faces: - if (~faceExclusions & _sFaceIndexToHalfSpaceMask[i]) { - - int start = index; - // Create the triangulated face, two tris, six indices referencing four vertices, both - // with cw winding order, such that: - - // A-B - // |\| - // D-C - - // Store triangle ABC - - TriElement* tri = new TriElement(); - if (tri) { - tri->indices[0] = index++; - tri->indices[1] = index++; - tri->indices[2] = index; - - // Add tri element to list - _tris.push_back(tri); - _cpuMemoryUsage += sizeof(TriElement); - _cpuMemoryUsage += sizeof(TriElement*); - } - - // Now store triangle ACD - tri = new TriElement(); - if (tri) { - tri->indices[0] = start; - tri->indices[1] = index++; - tri->indices[2] = index++; - - // Add tri element to list - _tris.push_back(tri); - _cpuMemoryUsage += sizeof(TriElement); - _cpuMemoryUsage += sizeof(TriElement*); - } - } - } -} - -void Cube::terminateTris() { - - for (TriElementList::iterator it = _tris.begin(); it != _tris.end(); ++it) { - delete *it; - } - _cpuMemoryUsage -= _tris.size() * (sizeof(TriElement) + sizeof(TriElement*)); - _tris.clear(); -} - -const VertexElementList& Cube::vVertexElements() const { - return _vertices; -} - -VertexElementIndexList& Cube::vVertexElementIndices() { - return _vertexIndices; -} - -TriElementList& Cube::vTriElements() { - return _tris; -} - -void Cube::vReleaseVertexElements() { - terminateVertices(); -} - -unsigned long Cube::vGetMemoryUsage() { - return _cpuMemoryUsage; -} - -unsigned char Cube::_sFaceIndexToHalfSpaceMask[6] = { - OctreeElement::HalfSpace::Bottom, - OctreeElement::HalfSpace::Top, - OctreeElement::HalfSpace::Right, - OctreeElement::HalfSpace::Left, - OctreeElement::HalfSpace::Near, - OctreeElement::HalfSpace::Far, -}; - -// Construction vectors ordered such that the vertices of each face are -// clockwise in a right-handed coordinate system with B-L-N at 0,0,0. -float Cube::_sVertexIndexToConstructionVector[24][3] = { - // Bottom - { 0,0,0 }, - { 1,0,0 }, - { 1,0,1 }, - { 0,0,1 }, - // Top - { 0,1,0 }, - { 0,1,1 }, - { 1,1,1 }, - { 1,1,0 }, - // Right - { 1,0,0 }, - { 1,1,0 }, - { 1,1,1 }, - { 1,0,1 }, - // Left - { 0,0,0 }, - { 0,0,1 }, - { 0,1,1 }, - { 0,1,0 }, - // Near - { 0,0,0 }, - { 0,1,0 }, - { 1,1,0 }, - { 1,0,0 }, - // Far - { 0,0,1 }, - { 1,0,1 }, - { 1,1,1 }, - { 0,1,1 }, -}; - -// Normals for a right-handed coordinate system -float Cube::_sVertexIndexToNormalVector[6][3] = { - { 0,-1, 0 }, // Bottom - { 0, 1, 0 }, // Top - { 1, 0, 0 }, // Right - { -1, 0, 0 }, // Left - { 0, 0,-1 }, // Near - { 0, 0, 1 }, // Far -}; - -Renderer::Renderer() { -} - -Renderer::~Renderer() { -} - -// Simple dispatch between API and SPI -int Renderer::add( - Primitive* primitive - ) { - return vAdd(primitive); -} - -void Renderer::remove( - int id - ) { - vRemove(id); -} - -void Renderer::release() { - vRelease(); -} - -void Renderer::render() { - vRender(); -} - -unsigned long Renderer::getMemoryUsage() { - return vGetMemoryUsage(); -} - -unsigned long Renderer::getMemoryUsageGPU() { - return vGetMemoryUsageGPU(); -} - -PrimitiveRenderer::PrimitiveRenderer( - int maxCount - ) : - _maxCount(maxCount), - _triBufferId(0), - _vertexBufferId(0), - - _vertexElementCount(0), - _maxVertexElementCount(0), - - _triElementCount(0), - _maxTriElementCount(0), - - _primitives(), - _primitiveCount(0), - - _gpuMemoryUsage(0), - _cpuMemoryUsage(0) - -{ - init(); -} - -PrimitiveRenderer::~PrimitiveRenderer() { - - terminate(); -} - -void PrimitiveRenderer::init() { - - initializeGL(); - initializeBookkeeping(); -} - -void PrimitiveRenderer::initializeGL() { - - glGenBuffers(1, &_triBufferId); - glGenBuffers(1, &_vertexBufferId); - - // Set up the element array buffer containing the index ids - _maxTriElementCount = _maxCount * 2; - int size = _maxTriElementCount * _sIndicesPerTri * sizeof(GLint); - _gpuMemoryUsage += size; - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - // Set up the array buffer in the form of array of structures - // I chose AOS because it maximizes the amount of data tranferred - // by a single glBufferSubData call. - _maxVertexElementCount = _maxCount * 8; - size = _maxVertexElementCount * sizeof(VertexElement); - _gpuMemoryUsage += size; - - glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId); - glBufferData(GL_ARRAY_BUFFER, size, 0, GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - - // Initialize the first tri element in the buffer to all zeros, the - // degenerate case - deconstructTriElement(0); - - // Initialize the first vertex element in the buffer to all zeros, the - // degenerate case - deconstructVertexElement(0); -} - -void PrimitiveRenderer::initializeBookkeeping() { - - // Start primitive count at one, because zero is reserved for the degenerate triangle - _primitives.resize(_maxCount + 1); - - // Set the counters - _primitiveCount = 1; - _vertexElementCount = 1; - _triElementCount = 1; - - // Guesstimate the memory consumption - _cpuMemoryUsage = sizeof(PrimitiveRenderer); - _cpuMemoryUsage += _availablePrimitiveIndex.capacity() * sizeof(int); - _cpuMemoryUsage += _availableVertexElementIndex.capacity() * sizeof(int); - _cpuMemoryUsage += _availableTriElementIndex.capacity() * sizeof(int); - _cpuMemoryUsage += _deconstructTriElementIndex.capacity() * sizeof(int); - _cpuMemoryUsage += _constructPrimitiveIndex.capacity() * sizeof(int); -} - -void PrimitiveRenderer::terminate() { - - terminateBookkeeping(); - terminateGL(); -} - -void PrimitiveRenderer::terminateGL() { - - if (_vertexBufferId) { - glDeleteBuffers(1, &_vertexBufferId); - _vertexBufferId = 0; - } - - if (_triBufferId) { - glDeleteBuffers(1, &_triBufferId); - _triBufferId = 0; - } -} - -void PrimitiveRenderer::terminateBookkeeping() { - - // Delete all of the primitives - for (int i = _primitiveCount + 1; --i > 0; ) { - Primitive* primitive = _primitives[i]; - if (primitive) { - _cpuMemoryUsage -= primitive->getMemoryUsage(); - _primitives[i] = 0; - delete primitive; - } - } - - // Drain the queues - _availablePrimitiveIndex.clear(); - _availableVertexElementIndex.clear(); - _availableTriElementIndex.clear(); - _deconstructTriElementIndex.clear(); - _constructPrimitiveIndex.clear(); - - _cpuMemoryUsage = sizeof(PrimitiveRenderer) + _primitives.size() * sizeof(Primitive *); -} - -void PrimitiveRenderer::constructElements( - Primitive* primitive - ) { - - // Load vertex elements - VertexElementIndexList& vertexElementIndexList = primitive->vertexElementIndices(); - const VertexElementList& vertices = primitive->vertexElements(); - { - for (VertexElementList::const_iterator it = vertices.begin(); it != vertices.end(); ++it ) { - int index = getAvailableVertexElementIndex(); - if (index != 0) { - // Store the vertex element index in the primitive's - // vertex element index list - vertexElementIndexList.push_back(index); - - VertexElement* vertex = *it; - transferVertexElement(index, vertex); - } else { - break; - } - } - } - - // Load tri elements - if (vertexElementIndexList.size() == vertices.size()) { - TriElementList& tris = primitive->triElements(); - - for (TriElementList::iterator it = tris.begin(); it != tris.end(); ++it) { - TriElement* tri = *it; - int index = getAvailableTriElementIndex(); - if (index != 0) { - int k; - k = tri->indices[0]; - tri->indices[0] = vertexElementIndexList[k]; - - k = tri->indices[1]; - tri->indices[1] = vertexElementIndexList[k]; - - k = tri->indices[2]; - tri->indices[2] = vertexElementIndexList[k]; - - tri->id = index; - transferTriElement(index, tri->indices); - } else { - break; - } - } - } else { - // TODO: failure mode - } -} - -void PrimitiveRenderer::deconstructElements( - Primitive* primitive - ) { - - // Schedule the tri elements of the face for deconstruction - { - TriElementList& tris = primitive->triElements(); - - for (TriElementList::const_iterator it = tris.begin(); it != tris.end(); ++it) { - const TriElement* tri = *it; - - if (tri->id) { - // Put the tri element index into decon queue - _deconstructTriElementIndex.push(tri->id); - } - } - } - - // Return the vertex element index to the available queue, it is not necessary - // to zero the data - { - VertexElementIndexList& vertexIndexList = primitive->vertexElementIndices(); - - for (VertexElementIndexList::const_iterator it = vertexIndexList.begin(); it != vertexIndexList.end(); ++it) { - int index = *it; - - if (index) { - // Put the vertex element index into the available queue - _availableVertexElementIndex.push(index); - } - } - } - - delete primitive; -} - -int PrimitiveRenderer::getAvailablePrimitiveIndex() { - - int index; - - // Check the available primitive index queue first for an available index. - if (!_availablePrimitiveIndex.isEmpty()) { - index = _availablePrimitiveIndex.pop(); - } else if (_primitiveCount < _maxCount) { - // There are no primitive indices available from the queue, - // make one up - index = _primitiveCount++; - } else { - index = 0; - } - return index; -} - -int PrimitiveRenderer::getAvailableVertexElementIndex() { - - int index; - - // Check the available vertex element queue first for an available index. - if (!_availableVertexElementIndex.isEmpty()) { - index = _availableVertexElementIndex.pop(); - } else if (_vertexElementCount < _maxVertexElementCount) { - // There are no vertex elements available from the queue, - // grab one from the end of the list - index = _vertexElementCount++; - } else { - index = 0; - } - return index; -} - -int PrimitiveRenderer::getAvailableTriElementIndex() { - - int index; - - // Check the tri elements scheduled for deconstruction queue first to - // intercept and reuse an index without it having to be destroyed - if (!_deconstructTriElementIndex.isEmpty()) { - index = _deconstructTriElementIndex.pop(); - } else if (!_availableTriElementIndex.isEmpty()) { - // Nothing available in the deconstruction queue, now - // check the available tri element queue for an available index. - index = _availableTriElementIndex.pop(); - } else if (_triElementCount < _maxTriElementCount) { - // There are no reusable tri elements available from the queue, - // grab one from the end of the list - index = _triElementCount++; - } else { - index = 0; - } - return index; -} - -void PrimitiveRenderer::deconstructTriElement( - int idx - ) { - - // Set the tri element to the degenerate case. - static int degenerate[3] = { 0, 0, 0 }; - transferTriElement(idx, degenerate); - -} - -void PrimitiveRenderer::deconstructVertexElement( - int idx - ) { - - // Set the vertex element to the degenerate case. - VertexElement degenerate; - memset(°enerate, 0, sizeof(degenerate)); - - transferVertexElement(idx, °enerate); - -} - -void PrimitiveRenderer::transferVertexElement( - int idx, - VertexElement* vertex - ) { - - glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId); - glBufferSubData(GL_ARRAY_BUFFER, idx * sizeof(VertexElement), sizeof(VertexElement), vertex); - glBindBuffer(GL_ARRAY_BUFFER, 0); -} - -void PrimitiveRenderer::transferTriElement( - int idx, - int tri[3] - ) { - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId); - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, idx * _sBytesPerTriElement, _sBytesPerTriElement, tri); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); -} - -int PrimitiveRenderer::vAdd( - Primitive* primitive - ) { - - QMutexLocker lock(&_guard); - int id = getAvailablePrimitiveIndex(); - if (id != 0) { - // Take ownership of primitive, including responsibility - // for destruction - _primitives[id] = primitive; - _constructPrimitiveIndex.push(id); - _cpuMemoryUsage += primitive->getMemoryUsage(); - } - return id; -} - -void PrimitiveRenderer::vRemove( - int id - ) { - - if (id != 0) { - QMutexLocker lock(&_guard); - - // Locate and remove the primitive by id in the vector map - Primitive* primitive = _primitives[id]; - if (primitive) { - _primitives[id] = 0; - _cpuMemoryUsage -= primitive->getMemoryUsage(); - deconstructElements(primitive); - - // Queue the index onto the available primitive stack. - _availablePrimitiveIndex.push(id); - } - } -} - -void PrimitiveRenderer::vRelease() { - - QMutexLocker lock(&_guard); - - terminateBookkeeping(); - initializeBookkeeping(); -} - -void PrimitiveRenderer::vRender() { - - int id; - QMutexLocker lock(&_guard); - - // Iterate over the set of triangle element array buffer ids scheduled for - // destruction. Set the triangle element to the degenerate case. Queue the id - // onto the available tri element stack. - while (!_deconstructTriElementIndex.isEmpty()) { - id = _deconstructTriElementIndex.pop(); - deconstructTriElement(id); - _availableTriElementIndex.push(id); - } - - // Iterate over the set of primitive ids scheduled for construction. Transfer - // primitive data to the GPU. - while (!_constructPrimitiveIndex.isEmpty()) { - id = _constructPrimitiveIndex.pop(); - Primitive* primitive = _primitives[id]; - if (primitive) { - constructElements(primitive); - - // No need to keep an extra copy of the vertices - _cpuMemoryUsage -= primitive->getMemoryUsage(); - primitive->releaseVertexElements(); - _cpuMemoryUsage += primitive->getMemoryUsage(); - } - } - - // The application uses clockwise winding for the definition of front face, this renderer - // aalso uses clockwise (that is the gl default) to construct the triangulation - // so... - //glFrontFace(GL_CW); - glEnable(GL_CULL_FACE); - - glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferId); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, sizeof(VertexElement), 0); - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, sizeof(VertexElement), (const GLvoid*)12); - - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(VertexElement), (const GLvoid*)24); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _triBufferId); - glDrawElements(GL_TRIANGLES, 3 * _triElementCount, GL_UNSIGNED_INT, 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - - glDisable(GL_CULL_FACE); -} - -unsigned long PrimitiveRenderer::vGetMemoryUsage() { - return _cpuMemoryUsage; -} - -unsigned long PrimitiveRenderer::vGetMemoryUsageGPU() { - return _gpuMemoryUsage; -} diff --git a/interface/src/voxels/PrimitiveRenderer.h b/interface/src/voxels/PrimitiveRenderer.h deleted file mode 100644 index 06dac119b0..0000000000 --- a/interface/src/voxels/PrimitiveRenderer.h +++ /dev/null @@ -1,503 +0,0 @@ -// -// PrimitiveRenderer.h -// interface/src/voxels -// -// Created by Norman Craft. -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -#ifndef hifi_PrimitiveRenderer_h -#define hifi_PrimitiveRenderer_h - -#include -#include -#include - -/// Vertex element structure. -/// Using the array of structures approach to specifying -/// vertex data to GL cuts down on the calls to glBufferSubData -/// -typedef - struct __VertexElement { - struct __position { - float x; - float y; - float z; - } position; - struct __normal { - float x; - float y; - float z; - } normal; - struct __color { - unsigned char r; - unsigned char g; - unsigned char b; - unsigned char a; - } color; - } VertexElement; - -/// Triangle element index structure. -/// Specify the vertex indices of the triangle and its element index. -/// -typedef - struct __TriElement { - int indices[3]; - int id; - - } TriElement; - -/// Vertex element list container. -/// -typedef QVector VertexElementList; - -/// Vertex element index list container. -/// -typedef QVector VertexElementIndexList; - -/// Triangle element list container -/// -typedef QVector TriElementList; - -/// -/// @class Primitive -/// Primitive Interface class. -/// Abstract class for accessing vertex and tri elements of geometric primitives -/// -/// -class Primitive { -public: - virtual ~Primitive(); - - // API methods go here - - /// Vertex element accessor. - /// @return A list of vertex elements of the primitive - /// - const VertexElementList& vertexElements() const; - - /// Vertex element index accessor. - /// @return A list of vertex element indices of the primitive - /// - VertexElementIndexList& vertexElementIndices(); - - /// Tri element accessor. - /// @return A list of tri elements of the primitive - /// - TriElementList& triElements(); - - /// Release vertex elements. - /// - void releaseVertexElements(); - - /// Get memory usage. - /// - unsigned long getMemoryUsage(); - -protected: - /// Default constructor prohibited to API user, restricted to service implementer. - /// - Primitive(); - -private: - /// Copy constructor prohibited. - /// - Primitive( - const Primitive& copy - ); - - // SPI methods are defined here - - /// Vertex element accessor. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual const VertexElementList& vVertexElements() const = 0; - - /// Vertex element index accessor. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual VertexElementIndexList& vVertexElementIndices() = 0; - - /// Tri element accessor. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual TriElementList& vTriElements() = 0; - - /// Release vertex elements. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual void vReleaseVertexElements() = 0; - - /// Get memory usage. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual unsigned long vGetMemoryUsage() = 0; - -}; - - -/// -/// @class Cube -/// Class for accessing the vertex and triangle elements of a cube -/// -class Cube: public Primitive { -public: - /// Configuration dependency injection constructor. - /// - Cube( - float x, ///< Cube location on X-axis - float y, ///< Cube location on Y-axis - float z, ///< Cube location on Z-axis - float s, ///< Cube size - unsigned char r, ///< Cube red color component - unsigned char g, ///< Cube green color component - unsigned char b, ///< Cube blue color component - unsigned char faces ///< Bitmask of faces of cube excluded from construction - ); - - ~Cube(); - -private: - /// Copy constructor prohibited. - /// - Cube ( - const Cube& cube - ); - - /// Cube initialization - /// - void init( - float x, ///< Cube location on X-axis - float y, ///< Cube location on Y-axis - float z, ///< Cube location on Z-axis - float s, ///< Cube size - unsigned char r, ///< Cube red color component - unsigned char g, ///< Cube green color component - unsigned char b, ///< Cube blue color component - unsigned char faceExclusions ///< Bitmask of faces of cube excluded from construction - ); - - /// Cube termination - /// - void terminate(); - - /// Initialize cube's vertex list - /// - void initializeVertices( - float x, ///< Cube location on X-axis - float y, ///< Cube location on Y-axis - float z, ///< Cube location on Z-axis - float s, ///< Cube size - unsigned char r, ///< Cube red color component - unsigned char g, ///< Cube green color component - unsigned char b, ///< Cube blue color component - unsigned char faceExclusions ///< Bitmask of faces of cube excluded from construction - ); - - /// Terminate cube's vertex list - /// - void terminateVertices(); - - /// Initialize cube's triangle list - /// - void initializeTris( - unsigned char faceExclusions - ); - - /// Terminate cube's triangle list - /// - void terminateTris(); - - // SPI virtual override methods go here - - const VertexElementList& vVertexElements() const; - VertexElementIndexList& vVertexElementIndices(); - TriElementList& vTriElements(); - void vReleaseVertexElements(); - unsigned long vGetMemoryUsage(); - -private: - VertexElementList _vertices; ///< Vertex element list - VertexElementIndexList _vertexIndices; ///< Vertex element index list - TriElementList _tris; ///< Tri element list - - unsigned long _cpuMemoryUsage; ///< Memory allocation of object - - static const int _sNumFacesPerCube = 6; ///< Number of faces per cube - static const int _sNumVerticesPerCube = 24; ///< Number of vertices per cube - static unsigned char _sFaceIndexToHalfSpaceMask[6]; ///< index to bitmask map - static float _sVertexIndexToConstructionVector[24][3]; ///< Vertex index to construction vector map - static float _sVertexIndexToNormalVector[6][3]; ///< Vertex index to normal vector map - -}; - - -/// -/// @class Renderer -/// GL renderer interface class. -/// Abstract class for rendering geometric primitives in GL -/// -class Renderer { -public: - virtual ~Renderer(); - - // API methods go here - - /// Add primitive to renderer database. - /// - int add( - Primitive* primitive ///< Primitive instance to be added - ); - - /// Remove primitive from renderer database. - /// - void remove( - int id ///< Primitive id to be removed - ); - - /// Clear all primitives from renderer database - /// - void release(); - - /// Render primitive database. - /// The render method assumes appropriate GL context and state has - /// already been provided for - /// - void render(); - - /// Get memory usage. - /// - unsigned long getMemoryUsage(); - - /// Get GPU memory usage. - /// - unsigned long getMemoryUsageGPU(); - -protected: - /// Default constructor prohibited to API user, restricted to service implementer. - /// - Renderer(); - -private: - /// Copy constructor prohibited. - /// - Renderer( - const Renderer& copy - ); - - // SPI methods are defined here - - /// Add primitive to renderer database. - /// Service implementer to provide private override for this method - /// in derived class - /// @return Primitive id - /// - virtual int vAdd( - Primitive* primitive ///< Primitive instance to be added - ) = 0; - - /// Remove primitive from renderer database. - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual void vRemove( - int id ///< Primitive id - ) = 0; - - /// Clear all primitives from renderer database - /// Service implementer to provide private override for this method - /// in derived class - /// - virtual void vRelease() = 0; - - /// Render primitive database. - /// Service implementer to provide private virtual override for this method - /// in derived class - /// - virtual void vRender() = 0; - - /// Get memory usage. - /// - virtual unsigned long vGetMemoryUsage() = 0; - - /// Get GPU memory usage. - /// - virtual unsigned long vGetMemoryUsageGPU() = 0; - -}; - -/// -/// @class PrimitiveRenderer -/// Renderer implementation class for the rendering of geometric primitives -/// using GL element array and GL array buffers -/// -class PrimitiveRenderer : public Renderer { -public: - /// Configuration dependency injection constructor. - /// - PrimitiveRenderer( - int maxCount ///< Max count - ); - - ~PrimitiveRenderer(); - -private: - /// Default constructor prohibited. - /// - PrimitiveRenderer(); - - /// Copy constructor prohibited. - /// - PrimitiveRenderer( - const PrimitiveRenderer& renderer - ); - - void init(); - void terminate(); - - /// Allocate and initialize GL buffers. - /// - void initializeGL(); - - /// Terminate and deallocate GL buffers. - /// - void terminateGL(); - - void initializeBookkeeping(); - void terminateBookkeeping(); - - /// Construct the elements of the faces of the primitive. - /// - void constructElements( - Primitive* primitive ///< Primitive instance - ); - - /// Deconstruct the elements of the faces of the primitive. - /// - void deconstructElements( - Primitive* primitive ///< Primitive instance - ); - - /// Deconstruct the triangle element from the GL buffer. - /// - void deconstructTriElement( - int idx ///< Triangle element index - ); - - /// Deconstruct the vertex element from the GL buffer. - /// - void deconstructVertexElement( - int idx ///< Vertex element index - ); - - /// Transfer the vertex element to the GL buffer. - /// - void transferVertexElement( - int idx, ///< Vertex element index - VertexElement *vertex ///< Vertex element instance - ); - - /// Transfer the triangle element to the GL buffer. - /// - void transferTriElement( - int idx, ///< Triangle element index - int tri[3] ///< Triangle element data - ); - - /// Get available primitive index. - /// Get an available primitive index from either the recycling - /// queue or incrementing the counter - /// - int getAvailablePrimitiveIndex(); - - /// Get available vertex element index. - /// Get an available vertex element index from either the recycling - /// queue or incrementing the counter - /// - int getAvailableVertexElementIndex(); - - /// Get available triangle element index. - /// Get an available triangle element index from either the elements - /// scheduled for deconstruction queue, the recycling - /// queue or incrementing the counter - /// - int getAvailableTriElementIndex(); - - // SPI virtual override methods go here - - /// Add primitive to renderer database. - /// - int vAdd( - Primitive* primitive ///< Primitive instance to be added - ); - - /// Remove primitive from renderer database. - /// - void vRemove( - int id ///< Primitive id to be removed - ); - - /// Clear all primitives from renderer database - /// - void vRelease(); - - /// Render triangle database. - /// - void vRender(); - - /// Get memory usage. - /// - unsigned long vGetMemoryUsage(); - - /// Get gpu memory usage. - /// - unsigned long vGetMemoryUsageGPU(); - -private: - - int _maxCount; ///< Maximum count of tris - - // GL related parameters - - GLuint _triBufferId; ///< GL element array buffer id - GLuint _vertexBufferId; ///< GL vertex array buffer id - - // Book keeping parameters - - int _vertexElementCount; ///< Count of vertices - int _maxVertexElementCount; ///< Max count of vertices - - int _triElementCount; ///< Count of triangles - int _maxTriElementCount; ///< Max count of triangles - - QVector _primitives; ///< Vector of primitive - int _primitiveCount; ///< Count of primitives - - QStack _availablePrimitiveIndex; ///< Queue of primitive indices available - QStack _availableVertexElementIndex; ///< Queue of vertex element indices available - QStack _availableTriElementIndex; ///< Queue of triangle element indices available - QStack _deconstructTriElementIndex; ///< Queue of triangle element indices requiring deletion from GL - QStack _constructPrimitiveIndex; ///< Queue of primitives requiring addition to GL - - QMutex _guard; - - // Statistics parameters, not necessary for proper operation - - unsigned long _gpuMemoryUsage; ///< GPU memory used by this instance - unsigned long _cpuMemoryUsage; ///< CPU memory used by this instance - - - static const int _sIndicesPerTri = 3; - static const int _sBytesPerTriElement = sizeof(GLint) * _sIndicesPerTri; -}; - - -#endif // hifi_PrimitiveRenderer_h diff --git a/interface/src/voxels/VoxelSystem.cpp b/interface/src/voxels/VoxelSystem.cpp index 8fbaf65f37..2f4fd3f0fa 100644 --- a/interface/src/voxels/VoxelSystem.cpp +++ b/interface/src/voxels/VoxelSystem.cpp @@ -68,10 +68,6 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) _initialized(false), _writeArraysLock(QReadWriteLock::Recursive), _readArraysLock(QReadWriteLock::Recursive), - _inOcclusions(false), - _showCulledSharedFaces(false), - _usePrimitiveRenderer(false), - _renderer(0), _drawHaze(false), _farHazeDistance(300.0f), _hazeColor(grayColor) @@ -112,7 +108,7 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels, VoxelTree* tree) void VoxelSystem::elementDeleted(OctreeElement* element) { VoxelTreeElement* voxel = (VoxelTreeElement*)element; if (voxel->getVoxelSystem() == this) { - if ((_voxelsInWriteArrays != 0) || _usePrimitiveRenderer) { + if ((_voxelsInWriteArrays != 0)) { forceRemoveNodeFromArrays(voxel); } else { if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { @@ -288,9 +284,6 @@ void VoxelSystem::cleanupVoxelMemory() { _readColorsArray = NULL; _writeColorsArray = NULL; - delete _renderer; - _renderer = 0; - delete[] _writeVoxelDirtyArray; delete[] _readVoxelDirtyArray; _writeVoxelDirtyArray = _readVoxelDirtyArray = NULL; @@ -384,8 +377,6 @@ void VoxelSystem::initVoxelMemory() { Application::resourcesPath() + "shaders/voxel.frag"); _program.link(); } - _renderer = new PrimitiveRenderer(_maxVoxels); - _initialized = true; _writeArraysLock.unlock(); @@ -511,10 +502,6 @@ void VoxelSystem::setupNewVoxelsForDrawing() { _callsToTreesToArrays++; if (_writeRenderFullVBO) { - if (_usePrimitiveRenderer) { - _renderer->release(); - clearAllNodesBufferIndex(); - } clearFreeBufferIndexes(); } _voxelsUpdated = newTreeToArrays(_tree->getRoot()); @@ -525,24 +512,17 @@ void VoxelSystem::setupNewVoxelsForDrawing() { _voxelsUpdated = 0; } - if (_usePrimitiveRenderer) { - if (_voxelsUpdated) { - _voxelsDirty=true; - } - } else { - // lock on the buffer write lock so we can't modify the data when the GPU is reading it - _readArraysLock.lockForWrite(); - - if (_voxelsUpdated) { - _voxelsDirty=true; - } - - // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated - copyWrittenDataToReadArrays(didWriteFullVBO); - _readArraysLock.unlock(); + // lock on the buffer write lock so we can't modify the data when the GPU is reading it + _readArraysLock.lockForWrite(); + if (_voxelsUpdated) { + _voxelsDirty=true; } + // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated + copyWrittenDataToReadArrays(didWriteFullVBO); + _readArraysLock.unlock(); + quint64 end = usecTimestampNow(); int elapsedmsec = (end - start) / 1000; _setupNewVoxelsForDrawingLastFinished = end; @@ -569,26 +549,22 @@ void VoxelSystem::setupNewVoxelsForDrawingSingleNode(bool allowBailEarly) { return; // bail early, it hasn't been long enough since the last time we ran } - if (_usePrimitiveRenderer) { - _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty - _voxelsUpdated = 0; - } else { - // 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), - "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); - _readArraysLock.lockForWrite(); - } - - _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty - - // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated - copyWrittenDataToReadArrays(_writeRenderFullVBO); - - // after... - _voxelsUpdated = 0; - _readArraysLock.unlock(); + // 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), + "setupNewVoxelsForDrawingSingleNode()... _bufferWriteLock.lock();" ); + _readArraysLock.lockForWrite(); } + + _voxelsDirty = true; // if we got this far, then we can assume some voxels are dirty + + // copy the newly written data to the arrays designated for reading, only does something if _voxelsDirty && _voxelsUpdated + copyWrittenDataToReadArrays(_writeRenderFullVBO); + + // after... + _voxelsUpdated = 0; + _readArraysLock.unlock(); + quint64 end = usecTimestampNow(); int elapsedmsec = (end - start) / 1000; _setupNewVoxelsForDrawingLastFinished = end; @@ -862,22 +838,13 @@ int VoxelSystem::forceRemoveNodeFromArrays(VoxelTreeElement* node) { return 0; } - if (_usePrimitiveRenderer) { - if (node->isKnownBufferIndex()) { - int primitiveIndex = node->getBufferIndex(); - _renderer->remove(primitiveIndex); - node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); - return 1; - } - } else { - // if the node is not in the VBOs then we have nothing to do! - if (node->isKnownBufferIndex()) { - // If this node has not yet been written to the array, then add it to the end of the array. - glBufferIndex nodeIndex = node->getBufferIndex(); - node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); - freeBufferIndex(nodeIndex); // NOTE: This will make the node invisible! - return 1; // updated! - } + // if the node is not in the VBOs then we have nothing to do! + if (node->isKnownBufferIndex()) { + // If this node has not yet been written to the array, then add it to the end of the array. + glBufferIndex nodeIndex = node->getBufferIndex(); + node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); + freeBufferIndex(nodeIndex); // NOTE: This will make the node invisible! + return 1; // updated! } return 0; // not-updated } @@ -909,43 +876,17 @@ int VoxelSystem::updateNodeInArrays(VoxelTreeElement* node, bool reuseIndex, boo float voxelScale = node->getScale(); nodeColor const & color = node->getColor(); - if (_usePrimitiveRenderer) { - if (node->isKnownBufferIndex()) { - int primitiveIndex = node->getBufferIndex(); - _renderer->remove(primitiveIndex); - node->setBufferIndex(GLBUFFER_INDEX_UNKNOWN); - } else { - node->setVoxelSystem(this); - } - unsigned char occlusions; - if (_showCulledSharedFaces) { - occlusions = ~node->getInteriorOcclusions(); - } else { - occlusions = node->getInteriorOcclusions(); - } - if (occlusions != OctreeElement::HalfSpace::All) { - Cube* cube = new Cube( - startVertex.x, startVertex.y, startVertex.z, voxelScale, - color[RED_INDEX], color[GREEN_INDEX], color[BLUE_INDEX], - occlusions); - if (cube) { - int primitiveIndex = _renderer->add(cube); - node->setBufferIndex(primitiveIndex); - } - } + glBufferIndex nodeIndex = GLBUFFER_INDEX_UNKNOWN; + if (reuseIndex && node->isKnownBufferIndex()) { + nodeIndex = node->getBufferIndex(); } else { - glBufferIndex nodeIndex = GLBUFFER_INDEX_UNKNOWN; - if (reuseIndex && node->isKnownBufferIndex()) { - nodeIndex = node->getBufferIndex(); - } else { - nodeIndex = getNextBufferIndex(); - node->setBufferIndex(nodeIndex); - node->setVoxelSystem(this); - } - - // populate the array with points for the 8 vertices and RGB color for each added vertex - updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); + nodeIndex = getNextBufferIndex(); + node->setBufferIndex(nodeIndex); + node->setVoxelSystem(this); } + + // populate the array with points for the 8 vertices and RGB color for each added vertex + updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); return 1; // updated! } else { // If we shouldn't render, and we're in reuseIndex mode, then free our index, this only operates @@ -1072,24 +1013,22 @@ void VoxelSystem::updateVBOs() { }; // would like to include _callsToTreesToArrays PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); - if (! _usePrimitiveRenderer) { - if (_voxelsDirty) { - - // attempt to lock the read arrays, to for copying from them to the actual GPU VBOs. - // if we fail to get the lock, that's ok, our VBOs will update on the next frame... - const int WAIT_FOR_LOCK_IN_MS = 5; - if (_readArraysLock.tryLockForRead(WAIT_FOR_LOCK_IN_MS)) { - if (_readRenderFullVBO) { - updateFullVBOs(); - } else { - updatePartialVBOs(); - } - _voxelsDirty = false; - _readRenderFullVBO = false; - _readArraysLock.unlock(); + if (_voxelsDirty) { + + // attempt to lock the read arrays, to for copying from them to the actual GPU VBOs. + // if we fail to get the lock, that's ok, our VBOs will update on the next frame... + const int WAIT_FOR_LOCK_IN_MS = 5; + if (_readArraysLock.tryLockForRead(WAIT_FOR_LOCK_IN_MS)) { + if (_readRenderFullVBO) { + updateFullVBOs(); } else { - qDebug() << "updateVBOs().... couldn't get _readArraysLock.tryLockForRead()"; + updatePartialVBOs(); } + _voxelsDirty = false; + _readRenderFullVBO = false; + _readArraysLock.unlock(); + } else { + qDebug() << "updateVBOs().... couldn't get _readArraysLock.tryLockForRead()"; } } _callsToTreesToArrays = 0; // clear it @@ -1143,11 +1082,11 @@ void VoxelSystem::render() { updateVBOs(); - if (!_usePrimitiveRenderer) { - if (_drawHaze) { - glEnable(GL_FOG); - } + if (_drawHaze) { + glEnable(GL_FOG); + } + { PerformanceWarning warn(showWarnings, "render().. TRIANGLES..."); { @@ -1223,16 +1162,10 @@ void VoxelSystem::render() { glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } - - if (_drawHaze) { - glDisable(GL_FOG); - } } - else { - applyScaleAndBindProgram(texture); - _renderer->render(); - removeScaleAndReleaseProgram(texture); - + + if (_drawHaze) { + glDisable(GL_FOG); } } @@ -1275,12 +1208,6 @@ void VoxelSystem::killLocalVoxels() { _tree->getRoot()->setVoxelSystem(voxelSystem); _tree->unlock(); clearFreeBufferIndexes(); - if (_usePrimitiveRenderer) { - if (_renderer) { - _renderer->release(); - } - clearAllNodesBufferIndex(); - } _voxelsInReadArrays = 0; // do we need to do this? setupNewVoxelsForDrawing(); } @@ -1308,178 +1235,6 @@ void VoxelSystem::clearAllNodesBufferIndex() { } } -bool VoxelSystem::inspectForInteriorOcclusionsOperation(OctreeElement* element, void* extraData) { - _nodeCount++; - VoxelTreeElement* voxel = (VoxelTreeElement*)element; - - // Nothing to do at the leaf level - if (voxel->isLeaf()) { - return false; - } - - // Bit mask of occluded shared faces indexed by child - unsigned char occludedSharedFace[NUMBER_OF_CHILDREN] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - // Traverse all pair combinations of children - for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { - - VoxelTreeElement* childA = voxel->getChildAtIndex(i); - if (childA) { - - // Get the child A's occluding faces, for a leaf that will be - // all six voxel faces, and for a non leaf, that will be - // all faces which are completely covered by four child octants. - unsigned char exteriorOcclusionsA = childA->getExteriorOcclusions(); - - for (int j = i; --j >= 0; ) { - - VoxelTreeElement* childB = voxel->getChildAtIndex(j); - if (childB) { - - // Get child B's occluding faces - unsigned char exteriorOcclusionsB = childB->getExteriorOcclusions(); - - // Determine the shared halfspace partition between siblings A and B, - // i.e., near/far, left/right, or top/bottom - unsigned char partitionA = _sOctantIndexToSharedBitMask[i][j] & - exteriorOcclusionsA; - unsigned char partitionB = _sOctantIndexToSharedBitMask[i][j] & - exteriorOcclusionsB; - - // Determine which face of each sibling is occluded. - - // The _sOctantIndexToBitMask is a partition occupancy mask. For - // example, if the near-left-top (NLT) and near-left-bottom (NLB) child voxels - // exist, the shared partition is top-bottom (TB), and thus the occluded - // shared face of the NLT voxel is its bottom face. - occludedSharedFace[i] |= (partitionB & _sOctantIndexToBitMask[i]); - occludedSharedFace[j] |= (partitionA & _sOctantIndexToBitMask[j]); - } - } - // Exchange bit pairs, left to right, vice versa, etc. - occludedSharedFace[i] = _sSwizzledOcclusionBits[occludedSharedFace[i]]; - // Combine this voxel's interior excluded shared face only to those children which are coincident - // with the excluded face. - occludedSharedFace[i] |= (voxel->getInteriorOcclusions() & _sOctantIndexToBitMask[i]); - - // Inform the child - childA->setInteriorOcclusions(occludedSharedFace[i]); - if (occludedSharedFace[i] != OctreeElement::HalfSpace::None) { - //const glm::vec3& v = voxel->getCorner(); - //float s = voxel->getScale(); - - //qDebug("Child %d of voxel at %f %f %f size: %f has %02x occlusions", i, v.x, v.y, v.z, s, occludedSharedFace[i]); - } - } - } - return true; -} - -bool VoxelSystem::inspectForExteriorOcclusionsOperation(OctreeElement* element, void* extraData) { - _nodeCount++; - VoxelTreeElement* voxel = (VoxelTreeElement*)element; - - // Nothing to do at the leaf level - if (voxel->isLeaf()) { - // By definition the the exterior faces of a leaf voxel are - // always occluders. - voxel->setExteriorOcclusions(OctreeElement::HalfSpace::All); - // And the sibling occluders - voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); - return false; - } else { - voxel->setExteriorOcclusions(OctreeElement::HalfSpace::None); - voxel->setInteriorOcclusions(OctreeElement::HalfSpace::None); - } - - // Count of exterior occluding faces of this voxel element indexed - // by half space partition - unsigned int exteriorOcclusionsCt[6] = { 0, 0, 0, 0, 0, 0 }; - - // Traverse all children - for (int i = NUMBER_OF_CHILDREN; --i >= 0; ) { - - VoxelTreeElement* child = voxel->getChildAtIndex(i); - if (child) { - - // Get the child's occluding faces, for a leaf, that will be - // all six voxel faces, and for a non leaf, that will be - // all faces which are completely covered by four child octants. - unsigned char exteriorOcclusionsOfChild = child->getExteriorOcclusions(); - exteriorOcclusionsOfChild &= _sOctantIndexToBitMask[i]; - - for (int j = 6; --j >= 0; ) { - - // Determine if the halfspace partition indexed by 1 << j is - // present in the exterior occlusions of the child. - unsigned char partition = exteriorOcclusionsOfChild & (1 << j); - - if (partition) { - exteriorOcclusionsCt[j]++; - } - } - } - } - { - // Derive the exterior occlusions of the voxel elements from the exclusions - // of its children - unsigned char exteriorOcclusions = OctreeElement::HalfSpace::None; - for (int i = 6; --i >= 0; ) { - if (exteriorOcclusionsCt[i] == _sNumOctantsPerHemiVoxel) { - - // Exactly four octants qualify for full exterior occlusion - exteriorOcclusions |= (1 << i); - } - } - - // Inform the voxel element - voxel->setExteriorOcclusions(exteriorOcclusions); - - if (exteriorOcclusions == OctreeElement::HalfSpace::All) { - //const glm::vec3& v = voxel->getCorner(); - //float s = voxel->getScale(); - - //qDebug("Completely occupied voxel at %f %f %f size: %f", v.x, v.y, v.z, s); - - // All of the exterior faces of this voxel element are - // occluders, which means that this element is completely - // occupied. Hence, the subtree from this node could be - // pruned and replaced by a leaf voxel, if the visible - // properties of the children are the same - - } else if (exteriorOcclusions != OctreeElement::HalfSpace::None) { - //const glm::vec3& v = voxel->getCorner(); - //float s = voxel->getScale(); - - //qDebug("Partially occupied voxel at %f %f %f size: %f with %02x", v.x, v.y, v.z, s, exteriorOcclusions); - } - } - return true; -} - -void VoxelSystem::inspectForOcclusions() { - - if (_inOcclusions) { - return; - } - _inOcclusions = true; - _nodeCount = 0; - - bool showDebugDetails = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showDebugDetails, "inspectForOcclusions()"); - - _tree->lockForRead(); - _tree->recurseTreeWithPostOperation(inspectForExteriorOcclusionsOperation); - _nodeCount = 0; - _tree->recurseTreeWithOperation(inspectForInteriorOcclusionsOperation); - _tree->unlock(); - - if (showDebugDetails) { - qDebug("inspecting all occlusions of %d nodes", _nodeCount); - } - _inOcclusions = false; -} - bool VoxelSystem::forceRedrawEntireTreeOperation(OctreeElement* element, void* extraData) { _nodeCount++; element->setDirtyBit(); @@ -1904,170 +1659,3 @@ void VoxelSystem::bindPerlinModulateProgram() { } } -// Swizzle value of bit pairs of the value of index -unsigned short VoxelSystem::_sSwizzledOcclusionBits[64] = { - 0x0000, // 00000000 - 0x0002, // 00000001 - 0x0001, // 00000010 - 0x0003, // 00000011 - 0x0008, // 00000100 - 0x000a, // 00000101 - 0x0009, // 00000110 - 0x000b, // 00000111 - 0x0004, // 00001000 - 0x0006, // 00001001 - 0x0005, // 00001010 - 0x0007, // 00001011 - 0x000c, // 00001100 - 0x000e, // 00001101 - 0x000d, // 00001110 - 0x000f, // 00001111 - 0x0020, // 00010000 - 0x0022, // 00010001 - 0x0021, // 00010010 - 0x0023, // 00010011 - 0x0028, // 00010100 - 0x002a, // 00010101 - 0x0029, // 00010110 - 0x002b, // 00010111 - 0x0024, // 00011000 - 0x0026, // 00011001 - 0x0025, // 00011010 - 0x0027, // 00011011 - 0x002c, // 00011100 - 0x002e, // 00011101 - 0x002d, // 00011110 - 0x002f, // 00011111 - 0x0010, // 00100000 - 0x0012, // 00100001 - 0x0011, // 00100010 - 0x0013, // 00100011 - 0x0018, // 00100100 - 0x001a, // 00100101 - 0x0019, // 00100110 - 0x001b, // 00100111 - 0x0014, // 00101000 - 0x0016, // 00101001 - 0x0015, // 00101010 - 0x0017, // 00101011 - 0x001c, // 00101100 - 0x001e, // 00101101 - 0x001d, // 00101110 - 0x001f, // 00101111 - 0x0030, // 00110000 - 0x0032, // 00110001 - 0x0031, // 00110010 - 0x0033, // 00110011 - 0x0038, // 00110100 - 0x003a, // 00110101 - 0x0039, // 00110110 - 0x003b, // 00110111 - 0x0034, // 00111000 - 0x0036, // 00111001 - 0x0035, // 00111010 - 0x0037, // 00111011 - 0x003c, // 00111100 - 0x003e, // 00111101 - 0x003d, // 00111110 - 0x003f, // 00111111 -}; - -// Octant bitmask array indexed by octant. The mask value indicates the octant's halfspace partitioning. The index -// value corresponds to the voxel's octal code derived in "pointToVoxel" in SharedUtil.cpp, which, BTW, does *not* -// correspond to the "ChildIndex" enum value in OctreeElement.h -unsigned char VoxelSystem::_sOctantIndexToBitMask[8] = { - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, - OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Near, - OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Left | OctreeElement::HalfSpace::Far, - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, - OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Near, - OctreeElement::HalfSpace::Top | OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Far, -}; - -// Two dimensional array map indexed by octant row and column. The mask value -// indicates the two faces shared by the octants -unsigned char VoxelSystem::_sOctantIndexToSharedBitMask[8][8] = { - { // Index 0: Bottom-Left-Near - 0, // Bottom-Left-Near - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Far - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Near - 0, // Top-Left-Far - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Near - 0, // Bottom-Right-Far - 0, // Top-Right-Near - 0, // Top-Right-Far - }, - { // Index 1: Bottom-Left-Far - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Left-Near - 0, // Bottom-Left-Far - 0, // Top-Left-Near - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Left-Far - 0, // Bottom-Right-Near - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Right-Far - 0, // Top-Right-Near - 0, // Top-Right-Far - }, - { // Index 2: Top-Left-Near - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Near - 0, // Bottom-Left-Far - 0, // Top-Left-Near - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Far - 0, // Bottom-Right-Near - 0, // Bottom-Right-Far - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Near - 0, // Top-Right-Far - }, - { // Index 3: Top-Left-Far - 0, // Bottom-Left-Near - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Left-Far - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Left-Near - 0, // Top-Left-Far - 0, // Bottom-Right-Near - 0, // Bottom-Right-Far - 0, // Top-Right-Near - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Right-Far - }, - { // Index 4: Bottom-Right-Near - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Near - 0, // Bottom-Left-Far - 0, // Top-Left-Near - 0, // Top-Left-Far - 0, // Bottom-Right-Near - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Far - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Near - 0, // Top-Right-Far - }, - { // Index 5: Bottom-Right-Far - 0, // Bottom-Left-Near - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Bottom-Left-Far - 0, // Top-Left-Near - 0, // Top-Left-Far - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Bottom-Right-Near - 0, // Bottom-Right-Far - 0, // Top-Right-Near - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Top-Right-Far - }, - { // Index 6: Top-Right-Near - 0, // Bottom-Left-Near - 0, // Bottom-Left-Far - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Near - 0, // Top-Left-Far - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Near - 0, // Bottom-Right-Far - 0, // Top-Right-Near - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Far - }, - { // Index 7: Top-Right-Far - 0, // Bottom-Left-Near - 0, // Bottom-Left-Far - 0, // Top-Left-Near - OctreeElement::HalfSpace::Right | OctreeElement::HalfSpace::Left, // Top-Left-Far - 0, // Bottom-Right-Near - OctreeElement::HalfSpace::Bottom | OctreeElement::HalfSpace::Top, // Bottom-Right-Far - OctreeElement::HalfSpace::Near | OctreeElement::HalfSpace::Far, // Top-Right-Near - 0, // Top-Right-Far - }, -}; - diff --git a/interface/src/voxels/VoxelSystem.h b/interface/src/voxels/VoxelSystem.h index 4f4c624e15..b6413a0f68 100644 --- a/interface/src/voxels/VoxelSystem.h +++ b/interface/src/voxels/VoxelSystem.h @@ -25,7 +25,6 @@ #include "Camera.h" #include "Util.h" #include "world.h" -#include "PrimitiveRenderer.h" class ProgramObject; @@ -71,7 +70,6 @@ public: void killLocalVoxels(); virtual void hideOutOfView(bool forceFullFrustum = false); - void inspectForOcclusions(); bool hasViewChanged(); bool isViewChanging(); @@ -129,8 +127,6 @@ private: static bool killSourceVoxelsOperation(OctreeElement* element, void* extraData); static bool forceRedrawEntireTreeOperation(OctreeElement* element, void* extraData); static bool clearAllNodesBufferIndexOperation(OctreeElement* element, void* extraData); - static bool inspectForExteriorOcclusionsOperation(OctreeElement* element, void* extraData); - static bool inspectForInteriorOcclusionsOperation(OctreeElement* element, void* extraData); static bool hideOutOfViewOperation(OctreeElement* element, void* extraData); static bool hideAllSubTreeOperation(OctreeElement* element, void* extraData); static bool showAllSubTreeOperation(OctreeElement* element, void* extraData); @@ -241,17 +237,6 @@ private: float _lastKnownVoxelSizeScale; int _lastKnownBoundaryLevelAdjust; - bool _inOcclusions; - bool _showCulledSharedFaces; ///< Flag visibility of culled faces - bool _usePrimitiveRenderer; ///< Flag primitive renderer for use - PrimitiveRenderer* _renderer; ///< Voxel renderer - - static const unsigned int _sNumOctantsPerHemiVoxel = 4; - static int _sCorrectedChildIndex[8]; - static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index - static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask - static unsigned char _sOctantIndexToSharedBitMask[8][8]; ///< Map octant indices to shared partition mask - // haze bool _drawHaze; float _farHazeDistance;