diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index a199c6b10e..86c3f5ff35 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -267,7 +267,7 @@ void RenderableParticleEffectEntityItem::updateRenderItem() { if (numBytes == 0) { return; } - memcpy(particleBuffer->editData(), particlePrimitives->data(), numBytes); + particleBuffer->setData(numBytes, (const gpu::Byte*)particlePrimitives->data()); // Update transform and bounds payload.setModelTransform(transform); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index d9ead354ea..672a29538b 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -65,15 +65,22 @@ public: class GLBuffer : public GPUObject { public: - Stamp _stamp; - GLuint _buffer; - GLuint _size; + const GLuint _buffer; + const GLuint _size; + const Stamp _stamp; - GLBuffer(); + GLBuffer(const Buffer& buffer, GLBuffer* original = nullptr); ~GLBuffer(); - void setSize(GLuint size); + void transfer(); + + private: + bool getNextTransferBlock(GLintptr& outOffset, GLsizeiptr& outSize, size_t& currentPage) const; + + // The owning texture + const Buffer& _gpuBuffer; }; + static GLBuffer* syncGPUObject(const Buffer& buffer); static GLuint getBufferID(const Buffer& buffer); diff --git a/libraries/gpu/src/gpu/GLBackendBuffer.cpp b/libraries/gpu/src/gpu/GLBackendBuffer.cpp index 080d743104..7098fd1feb 100755 --- a/libraries/gpu/src/gpu/GLBackendBuffer.cpp +++ b/libraries/gpu/src/gpu/GLBackendBuffer.cpp @@ -12,12 +12,40 @@ using namespace gpu; -GLBackend::GLBuffer::GLBuffer() : - _stamp(0), - _buffer(0), - _size(0) -{ +GLuint allocateSingleBuffer() { + GLuint result; + glGenBuffers(1, &result); + (void)CHECK_GL_ERROR(); + return result; +} + +GLBackend::GLBuffer::GLBuffer(const Buffer& buffer, GLBuffer* original) : + _buffer(allocateSingleBuffer()), + _size((GLuint)buffer._sysmem.getSize()), + _stamp(buffer._sysmem.getStamp()), + _gpuBuffer(buffer) { + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + if (GLEW_VERSION_4_4 || GLEW_ARB_buffer_storage) { + glBufferStorage(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_STORAGE_BIT); + (void)CHECK_GL_ERROR(); + } else { + glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW); + (void)CHECK_GL_ERROR(); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); + + if (original) { + glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer); + glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer); + glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size); + glBindBuffer(GL_COPY_WRITE_BUFFER, 0); + glBindBuffer(GL_COPY_READ_BUFFER, 0); + (void)CHECK_GL_ERROR(); + } + + Backend::setGPUObject(buffer, this); Backend::incrementBufferGPUCount(); + Backend::updateBufferGPUMemoryUsage(0, _size); } GLBackend::GLBuffer::~GLBuffer() { @@ -28,37 +56,56 @@ GLBackend::GLBuffer::~GLBuffer() { Backend::decrementBufferGPUCount(); } -void GLBackend::GLBuffer::setSize(GLuint size) { - Backend::updateBufferGPUMemoryUsage(_size, size); - _size = size; +void GLBackend::GLBuffer::transfer() { + glBindBuffer(GL_ARRAY_BUFFER, _buffer); + (void)CHECK_GL_ERROR(); + GLintptr offset; + GLsizeiptr size; + size_t currentPage { 0 }; + auto data = _gpuBuffer.getSysmem().readData(); + while (getNextTransferBlock(offset, size, currentPage)) { + glBufferSubData(GL_ARRAY_BUFFER, offset, size, data + offset); + (void)CHECK_GL_ERROR(); + } + glBindBuffer(GL_ARRAY_BUFFER, 0); + (void)CHECK_GL_ERROR(); + _gpuBuffer._flags &= ~Buffer::DIRTY; +} + +bool GLBackend::GLBuffer::getNextTransferBlock(GLintptr& outOffset, GLsizeiptr& outSize, size_t& currentPage) const { + size_t pageCount = _gpuBuffer._pages.size(); + // Advance to the first dirty page + while (currentPage < pageCount && (0 == (Buffer::DIRTY & _gpuBuffer._pages[currentPage]))) { + ++currentPage; + } + + // If we got to the end, we're done + if (currentPage >= pageCount) { + return false; + } + + // Advance to the next clean page + outOffset = static_cast(currentPage * _gpuBuffer._pageSize); + while (currentPage < pageCount && (0 != (Buffer::DIRTY & _gpuBuffer._pages[currentPage]))) { + _gpuBuffer._pages[currentPage] &= ~Buffer::DIRTY; + ++currentPage; + } + outSize = static_cast((currentPage * _gpuBuffer._pageSize) - outOffset); + return true; } GLBackend::GLBuffer* GLBackend::syncGPUObject(const Buffer& buffer) { GLBuffer* object = Backend::getGPUObject(buffer); - if (object && (object->_stamp == buffer.getSysmem().getStamp())) { - return object; + // Has the storage size changed? + if (!object || object->_stamp != buffer.getSysmem().getStamp()) { + object = new GLBuffer(buffer, object); } - // need to have a gpu object? - if (!object) { - object = new GLBuffer(); - glGenBuffers(1, &object->_buffer); - (void) CHECK_GL_ERROR(); - Backend::setGPUObject(buffer, object); + if (0 != (buffer._flags & Buffer::DIRTY)) { + object->transfer(); } - // Now let's update the content of the bo with the sysmem version - // TODO: in the future, be smarter about when to actually upload the glBO version based on the data that did change - //if () { - glBindBuffer(GL_ARRAY_BUFFER, object->_buffer); - glBufferData(GL_ARRAY_BUFFER, buffer.getSysmem().getSize(), buffer.getSysmem().readData(), GL_DYNAMIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); - object->_stamp = buffer.getSysmem().getStamp(); - object->setSize((GLuint)buffer.getSysmem().getSize()); - //} - (void) CHECK_GL_ERROR(); - return object; } diff --git a/libraries/gpu/src/gpu/Resource.cpp b/libraries/gpu/src/gpu/Resource.cpp index deb17300c3..7dbe662cbc 100644 --- a/libraries/gpu/src/gpu/Resource.cpp +++ b/libraries/gpu/src/gpu/Resource.cpp @@ -109,40 +109,18 @@ void Resource::Sysmem::deallocateMemory(Byte* dataAllocated, Size size) { } } -Resource::Sysmem::Sysmem() : - _stamp(0), - _size(0), - _data(NULL) -{ -} +Resource::Sysmem::Sysmem() {} -Resource::Sysmem::Sysmem(Size size, const Byte* bytes) : - _stamp(0), - _size(0), - _data(NULL) -{ - if (size > 0) { - _size = allocateMemory(&_data, size); - if (_size >= size) { - if (bytes) { - memcpy(_data, bytes, size); - } - } +Resource::Sysmem::Sysmem(Size size, const Byte* bytes) { + if (size > 0 && bytes) { + setData(_size, bytes); } } -Resource::Sysmem::Sysmem(const Sysmem& sysmem) : - _stamp(0), - _size(0), - _data(NULL) -{ +Resource::Sysmem::Sysmem(const Sysmem& sysmem) { if (sysmem.getSize() > 0) { - _size = allocateMemory(&_data, sysmem.getSize()); - if (_size >= sysmem.getSize()) { - if (sysmem.readData()) { - memcpy(_data, sysmem.readData(), sysmem.getSize()); - } - } + allocate(sysmem._size); + setData(_size, sysmem._data); } } @@ -208,7 +186,6 @@ Resource::Size Resource::Sysmem::setData( Size size, const Byte* bytes ) { if (allocate(size) == size) { if (size && bytes) { memcpy( _data, bytes, _size ); - _stamp++; } } return _size; @@ -217,7 +194,6 @@ Resource::Size Resource::Sysmem::setData( Size size, const Byte* bytes ) { Resource::Size Resource::Sysmem::setSubData( Size offset, Size size, const Byte* bytes) { if (size && ((offset + size) <= getSize()) && bytes) { memcpy( _data + offset, bytes, size ); - _stamp++; return size; } return 0; @@ -264,65 +240,105 @@ Buffer::Size Buffer::getBufferGPUMemoryUsage() { return Context::getBufferGPUMemoryUsage(); } -Buffer::Buffer() : - Resource(), - _sysmem(new Sysmem()) { +Buffer::Buffer(Size pageSize) : + _pageSize(pageSize) { _bufferCPUCount++; - } -Buffer::Buffer(Size size, const Byte* bytes) : - Resource(), - _sysmem(new Sysmem(size, bytes)) { - _bufferCPUCount++; - Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize()); +Buffer::Buffer(Size size, const Byte* bytes, Size pageSize) : Buffer(pageSize) { + setData(size, bytes); } -Buffer::Buffer(const Buffer& buf) : - Resource(), - _sysmem(new Sysmem(buf.getSysmem())) { - _bufferCPUCount++; - Buffer::updateBufferCPUMemoryUsage(0, _sysmem->getSize()); +Buffer::Buffer(const Buffer& buf) : Buffer(buf._pageSize) { + setData(buf.getSize(), buf.getData()); } Buffer& Buffer::operator=(const Buffer& buf) { - (*_sysmem) = buf.getSysmem(); + const_cast(_pageSize) = buf._pageSize; + setData(buf.getSize(), buf.getData()); return (*this); } Buffer::~Buffer() { _bufferCPUCount--; - - if (_sysmem) { - Buffer::updateBufferCPUMemoryUsage(_sysmem->getSize(), 0); - delete _sysmem; - _sysmem = NULL; - } + Buffer::updateBufferCPUMemoryUsage(_sysmem.getSize(), 0); } Buffer::Size Buffer::resize(Size size) { + _end = size; auto prevSize = editSysmem().getSize(); - auto newSize = editSysmem().resize(size); - Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); - return newSize; + if (prevSize < size) { + auto newPages = getRequiredPageCount(); + auto newSize = newPages * _pageSize; + editSysmem().resize(newSize); + // All new pages start off as clean, because they haven't been populated by data + _pages.resize(newPages, 0); + Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); + } + return _end; } +void Buffer::markDirty(Size offset, Size bytes) { + if (!bytes) { + return; + } + _flags |= DIRTY; + // Find the starting page + Size startPage = (offset / _pageSize); + // Non-zero byte count, so at least one page is dirty + Size pageCount = 1; + // How much of the page is after the offset? + Size remainder = _pageSize - (offset % _pageSize); + // If there are more bytes than page space remaining, we need to increase the page count + if (bytes > remainder) { + // Get rid of the amount that will fit in the current page + bytes -= remainder; + + pageCount += (bytes / _pageSize); + if (bytes % _pageSize) { + ++pageCount; + } + } + + // Mark the pages dirty + for (Size i = 0; i < pageCount; ++i) { + _pages[i + startPage] |= DIRTY; + } +} + + Buffer::Size Buffer::setData(Size size, const Byte* data) { - auto prevSize = editSysmem().getSize(); - auto newSize = editSysmem().setData(size, data); - Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); - return newSize; + resize(size); + setSubData(0, size, data); + return _end; } Buffer::Size Buffer::setSubData(Size offset, Size size, const Byte* data) { - return editSysmem().setSubData( offset, size, data); + auto changedBytes = editSysmem().setSubData(offset, size, data); + if (changedBytes) { + markDirty(offset, changedBytes); + } + return changedBytes; } Buffer::Size Buffer::append(Size size, const Byte* data) { - auto prevSize = editSysmem().getSize(); - auto newSize = editSysmem().append( size, data); - Buffer::updateBufferCPUMemoryUsage(prevSize, newSize); - return newSize; + auto offset = _end; + resize(_end + size); + setSubData(offset, size, data); + return _end; +} + +Buffer::Size Buffer::getSize() const { + Q_ASSERT(getSysmem().getSize() >= _end); + return _end; +} + +Buffer::Size Buffer::getRequiredPageCount() const { + Size result = _end / _pageSize; + if (_end % _pageSize) { + ++result; + } + return result; } const Element BufferView::DEFAULT_ELEMENT = Element( gpu::SCALAR, gpu::UINT8, gpu::RAW ); diff --git a/libraries/gpu/src/gpu/Resource.h b/libraries/gpu/src/gpu/Resource.h index 570aff00fc..70292f215b 100644 --- a/libraries/gpu/src/gpu/Resource.h +++ b/libraries/gpu/src/gpu/Resource.h @@ -88,10 +88,10 @@ protected: // Access the byte array. // The edit version allow to map data. const Byte* readData() const { return _data; } - Byte* editData() { _stamp++; return _data; } + Byte* editData() { return _data; } template< typename T > const T* read() const { return reinterpret_cast< T* > ( _data ); } - template< typename T > T* edit() { _stamp++; return reinterpret_cast< T* > ( _data ); } + template< typename T > T* edit() { return reinterpret_cast< T* > ( _data ); } // Access the current version of the sysmem, used to compare if copies are in sync Stamp getStamp() const { return _stamp; } @@ -102,9 +102,9 @@ protected: bool isAvailable() const { return (_data != 0); } private: - Stamp _stamp; - Size _size; - Byte* _data; + Stamp _stamp { 0 }; + Size _size { 0 }; + Byte* _data { nullptr }; }; }; @@ -115,22 +115,28 @@ class Buffer : public Resource { static void updateBufferCPUMemoryUsage(Size prevObjectSize, Size newObjectSize); public: + enum Flag { + DIRTY = 0x01, + }; + + // Currently only one flag... 'dirty' + using PageFlags = std::vector; + static const Size DEFAULT_PAGE_SIZE = 4096; static uint32_t getBufferCPUCount(); static Size getBufferCPUMemoryUsage(); static uint32_t getBufferGPUCount(); static Size getBufferGPUMemoryUsage(); - Buffer(); - Buffer(Size size, const Byte* bytes); + Buffer(Size pageSize = DEFAULT_PAGE_SIZE); + Buffer(Size size, const Byte* bytes, Size pageSize = DEFAULT_PAGE_SIZE); Buffer(const Buffer& buf); // deep copy of the sysmem buffer Buffer& operator=(const Buffer& buf); // deep copy of the sysmem buffer ~Buffer(); // The size in bytes of data stored in the buffer - Size getSize() const { return getSysmem().getSize(); } + Size getSize() const; const Byte* getData() const { return getSysmem().readData(); } - Byte* editData() { return editSysmem().editData(); } - + // Resize the buffer // Keep previous data [0 to min(pSize, mSize)] Size resize(Size pSize); @@ -143,6 +149,23 @@ public: // \return the number of bytes copied Size setSubData(Size offset, Size size, const Byte* data); + template + Size setSubData(Size index, const T& t) { + Size offset = index * sizeof(T); + Size size = sizeof(T); + return setSubData(offset, size, reinterpret_cast(&t)); + } + + template + Size setSubData(Size index, const std::vector& t) { + if (t.empty()) { + return 0; + } + Size offset = index * sizeof(T); + Size size = t.size() * sizeof(T); + return setSubData(offset, size, reinterpret_cast(&t[0])); + } + // Append new data at the end of the current buffer // do a resize( size + getSize) and copy the new data // \return the number of bytes copied @@ -155,18 +178,38 @@ public: template Size append(const std::vector& t) { + if (t.empty()) { + return _end; + } return append(sizeof(T) * t.size(), reinterpret_cast(&t[0])); } - // Access the sysmem object. - const Sysmem& getSysmem() const { assert(_sysmem); return (*_sysmem); } - Sysmem& editSysmem() { assert(_sysmem); return (*_sysmem); } - const GPUObjectPointer gpuObject {}; protected: + void markDirty(Size offset, Size bytes); - Sysmem* _sysmem = NULL; + template + void markDirty(Size index, Size count = 1) { + markDirty(sizeof(T) * index, sizeof(T) * count); + } + + // Access the sysmem object, limited to ourselves and GPUObject derived classes + const Sysmem& getSysmem() const { return _sysmem; } + Sysmem& editSysmem() { return _sysmem; } + Byte* editData() { return editSysmem().editData(); } + + Size getRequiredPageCount() const; + + Size _end { 0 }; + mutable uint8_t _flags; + mutable PageFlags _pages; + const Size _pageSize; + Sysmem _sysmem; + + // FIXME find a more generic way to do this. + friend class GLBackend; + friend class BufferView; }; typedef std::shared_ptr BufferPointer; @@ -290,8 +333,14 @@ public: int _stride; }; +#if 0 + // Direct memory access to the buffer contents is incompatible with the paging memory scheme template Iterator begin() { return Iterator(&edit(0), _stride); } template Iterator end() { return Iterator(&edit(getNum()), _stride); } +#else + template Iterator begin() const { return Iterator(&get(), _stride); } + template Iterator end() const { return Iterator(&get(getNum()), _stride); } +#endif template Iterator cbegin() const { return Iterator(&get(), _stride); } template Iterator cend() const { return Iterator(&get(getNum()), _stride); } @@ -328,6 +377,7 @@ public: qDebug() << "Accessing buffer outside the BufferView range, element size = " << sizeof(T) << " when bufferView size = " << _size; } #endif + _buffer->markDirty(_offset, sizeof(T)); T* t = (reinterpret_cast (_buffer->editData() + _offset)); return *(t); } @@ -361,6 +411,7 @@ public: qDebug() << "Accessing buffer outside the BufferView range, index = " << index << " number elements = " << getNum(); } #endif + _buffer->markDirty(elementOffset, sizeof(T)); return *(reinterpret_cast (_buffer->editData() + elementOffset)); } }; diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 220b673591..11c43eaee4 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -118,29 +118,18 @@ AnimDebugDraw::AnimDebugDraw() : // HACK: add red, green and blue axis at (1,1,1) _animDebugDrawData->_vertexBuffer->resize(sizeof(Vertex) * 6); - Vertex* data = (Vertex*)_animDebugDrawData->_vertexBuffer->editData(); - - data[0].pos = glm::vec3(1.0, 1.0f, 1.0f); - data[0].rgba = toRGBA(255, 0, 0, 255); - data[1].pos = glm::vec3(2.0, 1.0f, 1.0f); - data[1].rgba = toRGBA(255, 0, 0, 255); - - data[2].pos = glm::vec3(1.0, 1.0f, 1.0f); - data[2].rgba = toRGBA(0, 255, 0, 255); - data[3].pos = glm::vec3(1.0, 2.0f, 1.0f); - data[3].rgba = toRGBA(0, 255, 0, 255); - - data[4].pos = glm::vec3(1.0, 1.0f, 1.0f); - data[4].rgba = toRGBA(0, 0, 255, 255); - data[5].pos = glm::vec3(1.0, 1.0f, 2.0f); - data[5].rgba = toRGBA(0, 0, 255, 255); - - _animDebugDrawData->_indexBuffer->resize(sizeof(uint16_t) * 6); - uint16_t* indices = (uint16_t*)_animDebugDrawData->_indexBuffer->editData(); - for (int i = 0; i < 6; i++) { - indices[i] = i; - } - + + static std::vector vertices({ + Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, + Vertex { glm::vec3(2.0, 1.0f, 1.0f), toRGBA(255, 0, 0, 255) }, + Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 255, 0, 255) }, + Vertex { glm::vec3(1.0, 2.0f, 1.0f), toRGBA(0, 255, 0, 255) }, + Vertex { glm::vec3(1.0, 1.0f, 1.0f), toRGBA(0, 0, 255, 255) }, + Vertex { glm::vec3(1.0, 1.0f, 2.0f), toRGBA(0, 0, 255, 255) }, + }); + static std::vector indices({ 0, 1, 2, 3, 4, 5 }); + _animDebugDrawData->_vertexBuffer->setSubData(0, vertices); + _animDebugDrawData->_indexBuffer->setSubData(0, indices); } AnimDebugDraw::~AnimDebugDraw() { @@ -356,9 +345,13 @@ void AnimDebugDraw::update() { numVerts += (int)DebugDraw::getInstance().getRays().size() * VERTICES_PER_RAY; // allocate verts! - data._vertexBuffer->resize(sizeof(Vertex) * numVerts); - Vertex* verts = (Vertex*)data._vertexBuffer->editData(); - Vertex* v = verts; + std::vector vertices; + vertices.resize(numVerts); + //Vertex* verts = (Vertex*)data._vertexBuffer->editData(); + Vertex* v = nullptr; + if (numVerts) { + v = &vertices[0]; + } // draw absolute poses for (auto& iter : _absolutePoses) { @@ -381,6 +374,8 @@ void AnimDebugDraw::update() { } } } + data._vertexBuffer->resize(sizeof(Vertex) * numVerts); + data._vertexBuffer->setSubData(0, vertices); // draw markers from shared DebugDraw singleton for (auto& iter : markerMap) { @@ -408,20 +403,19 @@ void AnimDebugDraw::update() { } DebugDraw::getInstance().clearRays(); - assert(numVerts == (v - verts)); + assert((!numVerts && !v) || (numVerts == (v - &vertices[0]))); render::Item::Bound theBound; for (int i = 0; i < numVerts; i++) { - theBound += verts[i].pos; + theBound += vertices[i].pos; } data._bound = theBound; data._isVisible = (numVerts > 0); data._indexBuffer->resize(sizeof(uint16_t) * numVerts); - uint16_t* indices = (uint16_t*)data._indexBuffer->editData(); for (int i = 0; i < numVerts; i++) { - indices[i] = i; + data._indexBuffer->setSubData(i, (uint16_t)i);; } }); scene->enqueuePendingChanges(pendingChanges); diff --git a/libraries/render/src/render/DrawStatus.cpp b/libraries/render/src/render/DrawStatus.cpp index c2724fce42..bfbd123382 100644 --- a/libraries/render/src/render/DrawStatus.cpp +++ b/libraries/render/src/render/DrawStatus.cpp @@ -116,35 +116,25 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, // FIrst thing, we collect the bound and the status for all the items we want to render int nbItems = 0; { - if (!_itemBounds) { - _itemBounds = std::make_shared(); - } - if (!_itemStatus) { - _itemStatus = std::make_shared();; - } - if (!_itemCells) { - _itemCells = std::make_shared();; - } + _itemBounds.resize(inItems.size()); + _itemStatus.resize(inItems.size()); + _itemCells.resize(inItems.size()); - _itemBounds->resize((inItems.size() * sizeof(AABox))); - _itemStatus->resize((inItems.size() * NUM_STATUS_VEC4_PER_ITEM * sizeof(glm::vec4))); - _itemCells->resize((inItems.size() * sizeof(Octree::Location))); - - AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); - glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); - Octree::Location* itemCell = reinterpret_cast (_itemCells->editData()); - for (auto& item : inItems) { +// AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); +// glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); +// Octree::Location* itemCell = reinterpret_cast (_itemCells->editData()); + for (size_t i = 0; i < inItems.size(); ++i) { + const auto& item = inItems[i]; if (!item.bound.isInvalid()) { if (!item.bound.isNull()) { - (*itemAABox) = item.bound; + _itemBounds[i] = item.bound; } else { - (*itemAABox).setBox(item.bound.getCorner(), 0.1f); + _itemBounds[i].setBox(item.bound.getCorner(), 0.1f); } auto& itemScene = scene->getItem(item.id); - - (*itemCell) = scene->getSpatialTree().getCellLocation(itemScene.getCell()); + _itemCells[i] = scene->getSpatialTree().getCellLocation(itemScene.getCell()); auto itemStatusPointer = itemScene.getStatus(); if (itemStatusPointer) { @@ -152,25 +142,19 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, auto&& currentStatusValues = itemStatusPointer->getCurrentValues(); int valueNum = 0; for (int vec4Num = 0; vec4Num < NUM_STATUS_VEC4_PER_ITEM; vec4Num++) { - (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); + auto& value = (vec4Num ? _itemStatus[i].first : _itemStatus[i].second); + value = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); for (int component = 0; component < VEC4_LENGTH; component++) { valueNum = vec4Num * VEC4_LENGTH + component; if (valueNum < (int)currentStatusValues.size()) { - (*itemStatus)[component] = currentStatusValues[valueNum].getPackedData(); + value[component] = currentStatusValues[valueNum].getPackedData(); } } - itemStatus++; } } else { - (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); - itemStatus++; - (*itemStatus) = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); - itemStatus++; + _itemStatus[i].first = _itemStatus[i].second = glm::ivec4(Item::Status::Value::INVALID.getPackedData()); } - nbItems++; - itemAABox++; - itemCell++; } } } @@ -194,25 +178,20 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, // bind the one gpu::Pipeline we need batch.setPipeline(getDrawItemBoundsPipeline()); - AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); - glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); - Octree::Location* itemCell = reinterpret_cast (_itemCells->editData()); + //AABox* itemAABox = reinterpret_cast (_itemBounds->editData()); + //glm::ivec4* itemStatus = reinterpret_cast (_itemStatus->editData()); + //Octree::Location* itemCell = reinterpret_cast (_itemCells->editData()); const unsigned int VEC3_ADRESS_OFFSET = 3; if (_showDisplay) { for (int i = 0; i < nbItems; i++) { - batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*) (itemAABox + i)); - batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); - - - glm::ivec4 cellLocation(itemCell->pos.x, itemCell->pos.y, itemCell->pos.z, itemCell->depth); + batch._glUniform3fv(_drawItemBoundPosLoc, 1, (const float*)&(_itemBounds[i])); + batch._glUniform3fv(_drawItemBoundDimLoc, 1, ((const float*)&(_itemBounds[i])) + VEC3_ADRESS_OFFSET); + glm::ivec4 cellLocation(_itemCells[i].pos, _itemCells[i].depth); batch._glUniform4iv(_drawItemCellLocLoc, 1, ((const int*)(&cellLocation))); - - batch.draw(gpu::LINES, 24, 0); - itemCell++; } } @@ -222,10 +201,10 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, if (_showNetwork) { for (int i = 0; i < nbItems; i++) { - batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*) (itemAABox + i)); - batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*) (itemAABox + i)) + VEC3_ADRESS_OFFSET); - batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i)); - batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)(itemStatus + NUM_STATUS_VEC4_PER_ITEM * i + 1)); + batch._glUniform3fv(_drawItemStatusPosLoc, 1, (const float*)&(_itemBounds[i])); + batch._glUniform3fv(_drawItemStatusDimLoc, 1, ((const float*)&(_itemBounds[i])) + VEC3_ADRESS_OFFSET); + batch._glUniform4iv(_drawItemStatusValue0Loc, 1, (const int*)&(_itemStatus[i].first)); + batch._glUniform4iv(_drawItemStatusValue1Loc, 1, (const int*)&(_itemStatus[i].second)); batch.draw(gpu::TRIANGLES, 24 * NUM_STATUS_VEC4_PER_ITEM, 0); } } diff --git a/libraries/render/src/render/DrawStatus.h b/libraries/render/src/render/DrawStatus.h index 839a98b373..e60cb58779 100644 --- a/libraries/render/src/render/DrawStatus.h +++ b/libraries/render/src/render/DrawStatus.h @@ -68,9 +68,13 @@ namespace render { gpu::Stream::FormatPointer _drawItemFormat; gpu::PipelinePointer _drawItemBoundsPipeline; gpu::PipelinePointer _drawItemStatusPipeline; - gpu::BufferPointer _itemBounds; - gpu::BufferPointer _itemCells; - gpu::BufferPointer _itemStatus; + + std::vector _itemBounds; + std::vector> _itemStatus; + std::vector _itemCells; + //gpu::BufferPointer _itemBounds; + //gpu::BufferPointer _itemCells; + //gpu::BufferPointer _itemStatus; gpu::TexturePointer _statusIconMap; }; }