From 8a45f2466910eba90cddd12ed15a59a807374fef Mon Sep 17 00:00:00 2001 From: Jarrett Johnson Date: Tue, 26 Mar 2024 14:21:40 -0400 Subject: [PATCH] PYMOL-4654: Generic Buffer cleanup (1st pass) --- layer0/GenericBuffer.cpp | 275 ++++++++++++++++++++++++++++++ layer0/GenericBuffer.h | 359 ++++++++++++--------------------------- layer1/CGO.cpp | 48 +++--- layer1/CGO.h | 6 +- 4 files changed, 408 insertions(+), 280 deletions(-) diff --git a/layer0/GenericBuffer.cpp b/layer0/GenericBuffer.cpp index ee68d389b..6be306897 100644 --- a/layer0/GenericBuffer.cpp +++ b/layer0/GenericBuffer.cpp @@ -194,6 +194,281 @@ std::size_t GetSizeOfVertexFormat(VertexFormat format) } } +GenericBuffer::GenericBuffer(buffer_layout layout, GLenum usage) + : m_buffer_usage(usage) + , m_layout(layout) +{ +} + +GenericBuffer::~GenericBuffer() +{ + for (auto i = 0; i < m_desc.size(); ++i) { + auto& glID = desc_glIDs[i]; + if (glID) { + glDeleteBuffers(1, &glID); + } + } + if (m_interleavedID) { + glDeleteBuffers(1, &m_interleavedID); + } +} + +bool GenericBuffer::bufferData(BufferDataDesc&& desc) +{ + m_desc = std::move(desc); + desc_glIDs = std::vector(m_desc.size()); + return evaluate(); +} + +bool GenericBuffer::bufferData( + BufferDataDesc&& desc, const void* data, size_t len, size_t stride) +{ + bool ok = true; + m_desc = std::move(desc); + desc_glIDs = std::vector(m_desc.size()); + m_interleaved = true; + m_stride = stride; + ok = genBuffer(m_interleavedID, len, data); + return ok; +} + +void GenericBuffer::bufferSubData(size_t offset, size_t size, void* data, size_t index) +{ + assert("Invalid Desc index" && index < m_desc.size()); + assert("Invalid GLDesc index" && index < desc_glIDs.size()); + auto glID = m_interleaved ? m_interleavedID : desc_glIDs[index]; + glBindBuffer(bufferType(), glID); + glBufferSubData(bufferType(), offset, size, data); +} + +void GenericBuffer::bufferReplaceData(size_t offset, size_t len, const void* data) +{ + glBindBuffer(bufferType(), m_interleavedID); + glBufferSubData(bufferType(), offset, len, data); +} + +bool GenericBuffer::evaluate() +{ + if (bufferType() == GL_ELEMENT_ARRAY_BUFFER) { + return seqBufferData(); + } else { + switch (m_layout) { + case buffer_layout::SEPARATE: + return sepBufferData(); + break; + case buffer_layout::SEQUENTIAL: + return seqBufferData(); + break; + case buffer_layout::INTERLEAVED: + return interleaveBufferData(); + break; + } + } + return true; // unreacheable/Should be false? +} + +bool GenericBuffer::sepBufferData() +{ + for (auto i = 0; i < m_desc.size(); ++i) { + // If the specified size is 0 but we have a valid pointer + // then we are going to glVertexAttribXfv X in {1,2,3,4} + const auto& d = m_desc[i]; + auto& glID = desc_glIDs[i]; + if (d.data_ptr && (m_buffer_usage == GL_STATIC_DRAW)) { + if (d.data_size) { + if (!genBuffer(glID, d.data_size, d.data_ptr)) { + return false; + } + } + } + } + return true; +} + +bool GenericBuffer::seqBufferData() { + // this is only going to use a single opengl vbo + m_interleaved = true; + + size_t buffer_size { 0 }; + for ( auto & d : m_desc ) { + buffer_size += d.data_size; + } + + std::vector buffer_data(buffer_size); + auto data_ptr = buffer_data.data(); + size_t offset = 0; + + for ( auto & d : m_desc ) { + d.offset = offset; + if (d.data_ptr) + memcpy(data_ptr, d.data_ptr, d.data_size); + else + memset(data_ptr, 0, d.data_size); + data_ptr += d.data_size; + offset += d.data_size; + } + + return genBuffer(m_interleavedID, buffer_size, buffer_data.data()); +} + +bool GenericBuffer::interleaveBufferData() +{ + const std::size_t bufferCount = m_desc.size(); + std::size_t stride = 0; + std::vector data_table(bufferCount); + std::vector ptr_table(bufferCount); + std::vector size_table(bufferCount); + std::size_t count = + m_desc[0].data_size / GetSizeOfVertexFormat(m_desc[0].m_format); + + // Maybe assert that all pointers in d_desc are valid? + for (size_t i = 0; i < bufferCount; ++i) { + auto& d = m_desc[i]; + // offset is the current stride + d.offset = stride; + + // These must come after so that offset starts at 0 + // Size of 3 normals or whatever the current type is + size_table[i] = GetSizeOfVertexFormat(d.m_format); + + // Increase our current estimate of the stride by this amount + stride += size_table[i]; + + // Does the addition of that previous stride leave us on a word boundry? + int m = stride % 4; + stride = (m ? (stride + (4 - m)) : stride); + + // data_table a pointer to the begining of each array + data_table[i] = static_cast(d.data_ptr); + + // We will move these pointers along by the values in the size table + ptr_table[i] = data_table[i]; + } + + m_stride = stride; + + std::size_t interleavedSize = count * stride; + + std::vector interleavedData(interleavedSize); + auto iPtr = interleavedData.data(); + + while (iPtr != (interleavedData.data() + interleavedSize)) { + for (size_t i = 0; i < bufferCount; ++i) { + if (ptr_table[i]) { + memcpy(iPtr, ptr_table[i], size_table[i]); + ptr_table[i] += size_table[i]; + } + iPtr += size_table[i]; + } + } + + m_interleaved = true; + return genBuffer(m_interleavedID, interleavedSize, interleavedData.data()); +} + +bool GenericBuffer::genBuffer(GLuint& id, size_t size, const void* ptr) +{ + glGenBuffers(1, &id); + if (!glCheckOkay()) + return false; + glBindBuffer(bufferType(), id); + if (!glCheckOkay()) + return false; + glBufferData(bufferType(), size, ptr, GL_STATIC_DRAW); + if (!glCheckOkay()) + return false; + return true; +} + +void VertexBuffer::bind_attrib(GLuint prg, const BufferDesc& d, GLuint glID) +{ + GLint loc = glGetAttribLocation(prg, d.attr_name); + auto type_dim = VertexFormatToGLSize(d.m_format); + auto type = VertexFormatToGLType(d.m_format); + auto data_norm = VertexFormatToGLNormalized(d.m_format); + bool masked = false; + for (GLint lid : m_attribmask) + if (lid == loc) + masked = true; + if (loc >= 0) + m_locs.push_back(loc); + if (loc >= 0 && !masked) { + if (!m_interleaved && glID) + glBindBuffer(bufferType(), glID); + glEnableVertexAttribArray(loc); + glVertexAttribPointer(loc, type_dim, type, data_norm, m_stride, + reinterpret_cast(d.offset)); + } +}; + +VertexBuffer::VertexBuffer(buffer_layout layout, GLenum usage) + : GenericBuffer(layout, usage) +{ +} + +void VertexBuffer::bind() const +{ + // we shouldn't use this one + if (m_interleaved) + glBindBuffer(bufferType(), m_interleavedID); +} + +void VertexBuffer::bind(GLuint prg, int index) +{ + if (index >= 0) { + glBindBuffer(bufferType(), m_interleavedID); + bind_attrib(prg, m_desc[index], desc_glIDs[index]); + } else { + if (m_interleaved && m_interleavedID) + glBindBuffer(bufferType(), m_interleavedID); + for (auto i = 0; i < m_desc.size(); ++i) { + const auto& d = m_desc[i]; + auto glID = desc_glIDs[i]; + bind_attrib(prg, d, glID); + } + m_attribmask.clear(); + } +} + +void VertexBuffer::unbind() +{ + for (auto& d : m_locs) { + glDisableVertexAttribArray(d); + } + m_locs.clear(); + glBindBuffer(bufferType(), 0); +} + +void VertexBuffer::maskAttributes(std::vector attrib_locs) +{ + m_attribmask = std::move(attrib_locs); +} + +void VertexBuffer::maskAttribute(GLint attrib_loc) +{ + m_attribmask.push_back(attrib_loc); +} + +std::uint32_t VertexBuffer::bufferType() const +{ + return GL_ARRAY_BUFFER; +} + +void IndexBuffer::bind() const +{ + glBindBuffer(bufferType(), m_interleavedID); +} + +void IndexBuffer::unbind() +{ + glBindBuffer(bufferType(), 0); +} + +std::uint32_t IndexBuffer::bufferType() const +{ + return GL_ELEMENT_ARRAY_BUFFER; +} + /*********************************************************************** * RENDERBUFFER ***********************************************************************/ diff --git a/layer0/GenericBuffer.h b/layer0/GenericBuffer.h index c83528200..8ec907860 100644 --- a/layer0/GenericBuffer.h +++ b/layer0/GenericBuffer.h @@ -245,6 +245,12 @@ class gpuBuffer_t { size_t _hashid { 0 }; }; +enum class buffer_layout { + SEPARATE, // multiple vbos + SEQUENTIAL, // single vbo + INTERLEAVED // single vbo +}; + // ----------------------------------------------------------------------------- /* Vertexbuffer rules: * ----------------------------------------------------------------------------- @@ -264,288 +270,135 @@ class gpuBuffer_t { * INTERLEAVED: * vbo [ data1[0], data2[0], ..., dataN[0] | ... | data1[M], data2[M], ..., dataN[M] ] */ -template -class GenericBuffer : public gpuBuffer_t { +class GenericBuffer : public gpuBuffer_t +{ friend class CShaderMgr; -public: - static const GLenum TYPE = _TYPE; - enum buffer_layout { - SEPARATE, // multiple vbos - SEQUENTIAL, // single vbo - INTERLEAVED // single vbo - }; +public: - GenericBuffer( buffer_layout layout = SEPARATE, GLenum usage = GL_STATIC_DRAW ) : - m_buffer_usage(usage), m_layout(layout) {} - - ~GenericBuffer() { - for (auto i = 0; i < m_desc.size(); ++i) { - auto& glID = desc_glIDs[i]; - if (glID) { - glDeleteBuffers(1, &glID); - } - } - if (m_interleavedID) { - glDeleteBuffers(1, &m_interleavedID); - } - } + GenericBuffer(buffer_layout layout = buffer_layout::SEPARATE, GLenum usage = GL_STATIC_DRAW); + GenericBuffer(const GenericBuffer&) = delete; + GenericBuffer& operator=(const GenericBuffer&) = delete; + GenericBuffer(GenericBuffer&&) = delete; + GenericBuffer& operator=(GenericBuffer&&) = delete; + ~GenericBuffer(); - /*********************************************************************** - * bufferData - *---------------------------------------------------------------------- - * Takes a vector of the struct at the top of this file which describes - * the layout of the vbo object. The supplied data ptr in the struct can + /** + * Conditionally generates a GPU buffer for the given data descriptor + * @param desc The buffer data descriptor + * @return Whether the buffer data was successfully buffered + * @note The supplied data ptr in the struct can * be zero, in which case if the default usage is STATIC_DRAW then no * opengl buffer will be generated for that, else it is assumed that the * data will be supplied at a later point because it's dynamic draw. - ***********************************************************************/ - bool bufferData(BufferDataDesc && desc) { - m_desc = std::move(desc); - desc_glIDs = std::vector(m_desc.size()); - return evaluate(); - } + */ + bool bufferData(BufferDataDesc&& desc); - bool bufferData(BufferDataDesc && desc, const void * data, size_t len, size_t stride) { - bool ok = true; - m_desc = std::move(desc); - desc_glIDs = std::vector(m_desc.size()); - m_interleaved = true; - m_stride = stride; - ok = genBuffer(m_interleavedID, len, data); - return ok; - } + /** + * Generates a GPU buffer for the given data descriptor + * @param desc The buffer data descriptor + * @param data The data to buffer + * @param len The length of the data + * @param stride The stride of the data + * @note assumes the data is interleaved + */ + bool bufferData( + BufferDataDesc&& desc, const void* data, size_t len, size_t stride); // ----------------------------------------------------------------------------- - // bufferSubData : - // This function assumes that the data layout hasn't change - void bufferSubData(size_t offset, size_t size, void * data, size_t index = 0) { - assert("Invalid Desc index" && index < m_desc.size()); - assert("Invalid GLDesc index" && index < desc_glIDs.size()); - auto glID = m_interleaved ? m_interleavedID : desc_glIDs[index]; - glBindBuffer(TYPE, glID); - glBufferSubData(TYPE, offset, size, data); - } - // for interleaved dat only, replaces the whole interleaved vbo - void bufferReplaceData(size_t offset, size_t len, const void * data) { - glBindBuffer(TYPE, m_interleavedID); - glBufferSubData(TYPE, offset, len, data); - } + /** + * Updates (a portion of) the buffer data + * @param offset The offset to start updating the buffer data + * @param size The size of the data to update + * @param data The data to update + * @param index The index of the buffer data to update + * @note This function assumes that the data layout hasn't changed + */ + void bufferSubData(size_t offset, size_t size, void* data, size_t index = 0); + /** + * Replaces the whole interleaved buffer data + * @param data The data to replace the buffer data with + * @param len The length of the data + * @param data The data to replace the buffer data with + * @note This function assumes that the data layout hasn't changed + */ + void bufferReplaceData(size_t offset, size_t len, const void* data); protected: - bool evaluate() { - bool ok = true; - if (TYPE == GL_ELEMENT_ARRAY_BUFFER) { - ok = seqBufferData(); - } else { - switch (m_layout) { - case SEPARATE: - ok = sepBufferData(); - break; - case SEQUENTIAL: - ok = seqBufferData(); - break; - case INTERLEAVED: - ok = interleaveBufferData(); - break; - } - } - return ok; - } + /** + * Generates GPU buffer(s) for the given data descriptor + * @return Whether the buffer data was successfully buffered + */ + bool evaluate(); // USAGE PATTERNS - bool sepBufferData() { - for (auto i = 0; i < m_desc.size(); ++i) { - // If the specified size is 0 but we have a valid pointer - // then we are going to glVertexAttribXfv X in {1,2,3,4} - const auto& d = m_desc[i]; - auto& glID = desc_glIDs[i]; - if (d.data_ptr && (m_buffer_usage == GL_STATIC_DRAW)) { - if (d.data_size) { - if (!genBuffer(glID, d.data_size, d.data_ptr)) { - return false; - } - } - } - } - return true; - } - bool seqBufferData() { - // this is only going to use a single opengl vbo - m_interleaved = true; - - size_t buffer_size { 0 }; - for ( auto & d : m_desc ) { - buffer_size += d.data_size; - } - - std::vector buffer_data(buffer_size); - auto data_ptr = buffer_data.data(); - size_t offset = 0; - - for ( auto & d : m_desc ) { - d.offset = offset; - if (d.data_ptr) - memcpy(data_ptr, d.data_ptr, d.data_size); - else - memset(data_ptr, 0, d.data_size); - data_ptr += d.data_size; - offset += d.data_size; - } - - return genBuffer(m_interleavedID, buffer_size, buffer_data.data()); - } + /** + * Generates a separate buffer for each data descriptor + * @return Whether the buffer data was successfully buffered + */ + bool sepBufferData(); - bool interleaveBufferData() { - size_t interleaved_size = 0; - const size_t buffer_count = m_desc.size(); - size_t stride = 0; - std::vector data_table(buffer_count); - std::vector ptr_table(buffer_count); - std::vector size_table(buffer_count); - size_t count = m_desc[0].data_size / GetSizeOfVertexFormat(m_desc[0].m_format); - - // Maybe assert that all pointers in d_desc are valid? - for ( size_t i = 0; i < buffer_count; ++i ) { - auto &d = m_desc[i]; - // offset is the current stride - d.offset = stride; - - // These must come after so that offset starts at 0 - // Size of 3 normals or whatever the current type is - size_table[i] = GetSizeOfVertexFormat(d.m_format); - - // Increase our current estimate of the stride by this amount - stride += size_table[i]; - - // Does the addition of that previous stride leave us on a word boundry? - int m = stride % 4; - stride = (m ? (stride + (4 - m)) : stride); - - // data_table a pointer to the begining of each array - data_table[i] = (uint8_t *)d.data_ptr; - - // We will move these pointers along by the values in the size table - ptr_table[i] = data_table[i]; - - } - - m_stride = stride; - - interleaved_size = count * stride; - - uint8_t *interleaved_data = (uint8_t *)calloc(interleaved_size, sizeof(uint8_t)); - uint8_t *i_ptr = interleaved_data; - - while (i_ptr != (interleaved_data + interleaved_size)) { - for ( size_t i = 0; i < buffer_count; ++i ) { - if (ptr_table[i]){ - memcpy( i_ptr, ptr_table[i], size_table[i] ); - ptr_table[i] += size_table[i]; - } - i_ptr += size_table[i]; - } - } - - bool ok = true; - ok = genBuffer(m_interleavedID, interleaved_size, interleaved_data); - m_interleaved = true; - free(interleaved_data); - return ok; - } + /** + * Generates a single sequential buffer for all data descriptors + * @return Whether the buffer data was successfully buffered + */ + bool seqBufferData(); - bool genBuffer(GLuint &id, size_t size, const void * ptr) { - glGenBuffers(1, &id); - if (!glCheckOkay()) - return false; - glBindBuffer(TYPE, id); - if (!glCheckOkay()) - return false; - glBufferData(TYPE, size, ptr, GL_STATIC_DRAW); - if (!glCheckOkay()) - return false; - return true; - } + /** + * Generates a single interleaved buffer for all data descriptors + * @return Whether the buffer data was successfully buffered + */ + bool interleaveBufferData(); + + /** + * Generates an OpenGL buffer with given size and data + * @param id The OpenGL buffer ID + * @param size The size of the buffer + * @param ptr The data to buffer + * @return Whether the buffer was successfully generated + */ + bool genBuffer(GLuint& id, size_t size, const void* ptr); + + /** + * @return OpenGL buffer type + */ + virtual GLenum bufferType() const = 0; protected: - bool m_status { false }; - bool m_interleaved { false }; - GLuint m_interleavedID { 0 }; - const GLenum m_buffer_usage { GL_STATIC_DRAW }; - const buffer_layout m_layout { SEPARATE }; - size_t m_stride { 0 }; - BufferDataDesc m_desc; + bool m_status{false}; + bool m_interleaved{false}; + GLuint m_interleavedID{0}; + const GLenum m_buffer_usage{GL_STATIC_DRAW}; + const buffer_layout m_layout{ buffer_layout::SEPARATE }; + size_t m_stride{0}; + BufferDataDesc m_desc; std::vector desc_glIDs; // m_desc's gl buffer IDs }; /** * Vertex buffer specialization */ -class VertexBuffer : public GenericBuffer { - void bind_attrib(GLuint prg, const BufferDesc& d, GLuint glID) { - GLint loc = glGetAttribLocation(prg, d.attr_name); - auto type_dim = VertexFormatToGLSize(d.m_format); - auto type = VertexFormatToGLType(d.m_format); - auto data_norm = VertexFormatToGLNormalized(d.m_format); - bool masked = false; - for (GLint lid : m_attribmask) - if (lid == loc) - masked = true; - if ( loc >= 0 ) - m_locs.push_back(loc); - if ( loc >= 0 && !masked ) { - if (!m_interleaved && glID) - glBindBuffer( TYPE, glID); - glEnableVertexAttribArray( loc ); - glVertexAttribPointer(loc, type_dim, type, data_norm, m_stride, - reinterpret_cast(d.offset)); - } - }; +class VertexBuffer : public GenericBuffer { + void bind_attrib(GLuint prg, const BufferDesc& d, GLuint glID); public: - VertexBuffer( buffer_layout layout = SEPARATE, GLenum usage = GL_STATIC_DRAW ) : GenericBuffer(layout, usage){} + VertexBuffer(buffer_layout layout = buffer_layout::SEPARATE, + GLenum usage = GL_STATIC_DRAW); - void bind() const { - // we shouldn't use this one - if (m_interleaved) - glBindBuffer(TYPE, m_interleavedID); - } + void bind() const; - void bind(GLuint prg, int index = -1) { - if (index >= 0) { - glBindBuffer( TYPE, m_interleavedID ); - bind_attrib(prg, m_desc[index], desc_glIDs[index]); - } else { - if (m_interleaved && m_interleavedID) - glBindBuffer( TYPE, m_interleavedID ); - for (auto i = 0; i < m_desc.size(); ++i) { - const auto& d = m_desc[i]; - auto glID = desc_glIDs[i]; - bind_attrib(prg, d, glID); - } - m_attribmask.clear(); - } - } + void bind(GLuint prg, int index = -1); - void unbind() { - for (auto &d : m_locs) { - glDisableVertexAttribArray(d); - } - m_locs.clear(); - glBindBuffer(TYPE, 0); - } + void unbind(); - void maskAttributes(std::vector attrib_locs) { - m_attribmask = std::move(attrib_locs); - } + void maskAttributes(std::vector attrib_locs); + void maskAttribute(GLint attrib_loc); - void maskAttribute(GLint attrib_loc) { - m_attribmask.push_back(attrib_loc); - } + GLenum bufferType() const override; private: // m_locs is only for interleaved data @@ -556,17 +409,13 @@ class VertexBuffer : public GenericBuffer { /** * Index buffer specialization */ -class IndexBuffer : public GenericBuffer { +class IndexBuffer : public GenericBuffer { public: using GenericBuffer::GenericBuffer; - void bind() const { - glBindBuffer(TYPE, m_interleavedID); - } - - void unbind() { - glBindBuffer(TYPE, 0); - } + void bind() const; + void unbind(); + GLenum bufferType() const override; }; // Forward Decls diff --git a/layer1/CGO.cpp b/layer1/CGO.cpp index 1cf7ecf3e..92fc3cea6 100644 --- a/layer1/CGO.cpp +++ b/layer1/CGO.cpp @@ -2869,7 +2869,7 @@ CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders, float * if (ok){ auto fmt = GetNormalColorFormatSize(G); - VertexBuffer * vbo = G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL); + VertexBuffer * vbo = G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL); BufferDataDesc bufData = {{"a_Vertex", VertexFormat::Float3, sizeof(float) * num_total_indexes * 3, vertexVals}}; if (has_normals) { @@ -2887,7 +2887,7 @@ CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders, float * size_t vboid = vbo->get_hash_id(); // picking VBO: generate a buffer twice the size needed, for each picking pass - VertexBuffer * pickvbo = G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok = pickvbo->bufferData({ BufferDesc{"a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes}, BufferDesc{"a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes} @@ -3113,7 +3113,7 @@ CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders, float * { auto fmt = GetNormalColorFormatSize(G); - VertexBuffer * vbo = G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL); + VertexBuffer * vbo = G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL); BufferDataDesc bufData = {{"a_Vertex", VertexFormat::Float3, sizeof(float) * num_total_indexes_lines * 3, vertexVals}}; @@ -3129,7 +3129,7 @@ CGO *CGOOptimizeToVBONotIndexed(const CGO * I, int est, bool addshaders, float * size_t vboid = vbo->get_hash_id(); // picking VBO: generate a buffer twice the size needed, for each picking pass - VertexBuffer * pickvbo = G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok &= pickvbo->bufferData({ BufferDesc("a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes_lines), BufferDesc("a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes_lines) @@ -3508,7 +3508,7 @@ CGO *CGOOptimizeToVBOIndexed(const CGO * I, int est, size_t vboid = vbo->get_hash_id(); size_t iboid = ibo->get_hash_id(); - VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok &= pickvbo->bufferData({ BufferDesc{"a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes}, BufferDesc{"a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes} @@ -3772,7 +3772,7 @@ CGO *CGOOptimizeToVBOIndexed(const CGO * I, int est, size_t vboid = vbo->get_hash_id(); size_t iboid = ibo->get_hash_id(); - VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok &= pickvbo->bufferData({ BufferDesc("a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes), BufferDesc("a_Color", VertexFormat::UByte4Norm, sizeof(float) * num_total_indexes) @@ -4022,7 +4022,7 @@ static bool PopulateGLBufferOptimizedSphereData(const CGO* I, CGO* cgo, bool add }); size_t vboid = vbo->get_hash_id(); - VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok &= pickvbo->bufferData({ BufferDesc("a_Color", VertexFormat::UByte4Norm, 0), BufferDesc("a_Color", VertexFormat::UByte4Norm, sizeof(float) * sphereData.total_vert) @@ -4679,7 +4679,7 @@ CGO *CGOOptimizeTextures(const CGO * I, int est) ok &= !I->G->Interrupt; } if (ok) { - VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL); + VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL); ok &= vbo->bufferData({ BufferDesc("attr_worldpos", VertexFormat::Float3, sizeof(float) * num_total_textures * 18, worldPos), BufferDesc("attr_screenoffset", VertexFormat::Float3, sizeof(float) * num_total_textures * 18, screenValues), @@ -4789,7 +4789,7 @@ CGO *CGOConvertToLabelShader(const CGO *I, CGO * addTo){ AttribDataOp pickOp = { { CGO_PICK_COLOR, 1, UINT_INT_TO_PICK_DATA, 0, 0 } }; AttribDataDesc pickDesc = {{"attr_pickcolor", VertexFormat::UByte4Norm, pickOp}}; - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED, true); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED, true); } CGO *CGOOptimizeLabels(const CGO * I, int est, bool addshaders) @@ -4899,7 +4899,7 @@ CGO *CGOOptimizeLabels(const CGO * I, int est, bool addshaders) } if (ok) { // Static Vertex Data - VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL); + VertexBuffer * vbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL); ok &= vbo->bufferData({ BufferDesc("attr_worldpos", VertexFormat::Float3, sizeof(float) * num_total_labels * 18, worldPos), BufferDesc("attr_targetpos", VertexFormat::Float3, sizeof(float) * num_total_labels * 18, targetPos), @@ -4910,7 +4910,7 @@ CGO *CGOOptimizeLabels(const CGO * I, int est, bool addshaders) }); size_t vboid = vbo->get_hash_id(); - VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + VertexBuffer * pickvbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); ok &= pickvbo->bufferData({ BufferDesc("attr_pickcolor", VertexFormat::UByteNorm, 0), BufferDesc("attr_pickcolor", VertexFormat::UByteNorm, sizeof(float) * num_total_labels * 6) @@ -8662,11 +8662,11 @@ void PopulateOpsIntoStructuresForConversion(std::map &opToCntPer, * */ CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc &pickData, int mode, - const VertexBuffer::buffer_layout layout, bool check_attr_for_data, + const buffer_layout layout, bool check_attr_for_data, int *idx_array, int nvertsperfrag, int nfragspergroup){ CGO *cgo; int ok = true; - bool isInterleaved = (layout == VertexBuffer::INTERLEAVED); + bool isInterleaved = (layout == buffer_layout::INTERLEAVED); bool has_picking = true; std::map attrToDesc; @@ -8747,7 +8747,7 @@ CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc & VertexBuffer *vbo = I->G->ShaderMgr->newGPUBuffer(layout); VertexBuffer *pickvbo = nullptr; if (pickDataSize){ - pickvbo = I->G->ShaderMgr->newGPUBuffer(VertexBuffer::SEQUENTIAL, GL_DYNAMIC_DRAW); + pickvbo = I->G->ShaderMgr->newGPUBuffer(buffer_layout::SEQUENTIAL, GL_DYNAMIC_DRAW); pickvbohash = pickvbo->get_hash_id(); } @@ -8994,8 +8994,8 @@ CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc & /* Generate VBO Buffers with all pick attributes based on the VertexBuffer type SEPARATE/SEQUENTIAL/INTERLEAVED*/ BufferDataDesc bufferData; switch (layout){ - case VertexBuffer::SEPARATE: - case VertexBuffer::SEQUENTIAL: + case buffer_layout::SEPARATE: + case buffer_layout::SEQUENTIAL: { auto attrDataIt = attrData.begin(); auto dataPtrIt = dataPtrs.begin(); @@ -9013,7 +9013,7 @@ CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc & break; } break; - case VertexBuffer::INTERLEAVED: + case buffer_layout::INTERLEAVED: { auto attrDataIt = attrData.begin(); auto attrOffsetIt = attrOffset.begin(); @@ -9174,7 +9174,7 @@ CGO *CGOConvertToTrilinesShader(const CGO *I, CGO *addTo, bool add_color){ attrDesc.erase(attrDesc.begin()+2); // a_Color2 } - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED); } CGO *CGOConvertToLinesShader(const CGO *I, CGO *addTo, bool add_color){ @@ -9223,7 +9223,7 @@ CGO *CGOConvertToLinesShader(const CGO *I, CGO *addTo, bool add_color){ attrDesc.erase(attrDesc.begin()+1); // a_Color } - return CGOConvertToShader(I, attrDesc, pickDesc, GL_LINES, VertexBuffer::INTERLEAVED); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_LINES, buffer_layout::INTERLEAVED); } CGO *CGOConvertLinesToCylinderShader(const CGO *I, CGO *addTo, bool add_color){ @@ -9298,7 +9298,7 @@ CGO *CGOConvertLinesToCylinderShader(const CGO *I, CGO *addTo, bool add_color){ AttribDataDesc pickDesc = { {"a_Color", VertexFormat::UByte4Norm, extraPickColorOps}, {"a_Color2", VertexFormat::UByte4Norm, extraPickColor2Ops}}; - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED, true, box_indices_ptr, 36); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED, true, box_indices_ptr, 36); } struct CrossSizeData { @@ -9368,7 +9368,7 @@ CGO *CGOConvertCrossesToCylinderShader(const CGO *I, CGO *addTo, float cross_siz AttribDataOp extraPickColor2Ops = { { CGO_PICK_COLOR, 2, UINT_INT_TO_PICK_DATA, 0, 0 } }; AttribDataDesc pickDesc = {{"a_Color", VertexFormat::UByte4Norm, extraPickColorOps}, {"a_Color2", VertexFormat::UByte4Norm, extraPickColor2Ops}}; - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED, true, box_indices_ptr, 36, 3); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED, true, box_indices_ptr, 36, 3); } struct CrossSizeDataLines { @@ -9423,7 +9423,7 @@ CGO *CGOConvertCrossesToLinesShader(const CGO *I, CGO *addTo, float cross_size_a lpdesc->repeat_value = flip_bits; } #endif - return CGOConvertToShader(I, attrDesc, pickDesc, GL_LINES, VertexBuffer::INTERLEAVED); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_LINES, buffer_layout::INTERLEAVED); } static void CrossVertexConversionTrilines(void *varData, const float * pc, void *crossData, int idx){ @@ -9475,7 +9475,7 @@ CGO *CGOConvertCrossesToTrilinesShader(const CGO *I, CGO *addTo, float cross_siz addTo->add(G->ShaderMgr->GetAttributeUID("a_interpolate"), 0.f); - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED); } cgo::draw::shadercylinder2ndcolor::shadercylinder2ndcolor(CGO *I, const float *_origin, @@ -9605,7 +9605,7 @@ CGO *CGOConvertShaderCylindersToCylinderShader(const CGO *I, CGO *addTo){ { CGO_SHADER_CYLINDER_WITH_2ND_COLOR, 5, UINT_INT_TO_PICK_DATA, offsetof(cgo::draw::shadercylinder2ndcolor, pick_color_index), 0 } }; AttribDataDesc pickDesc = {{"a_Color", VertexFormat::UByte4Norm, extraPickColorOps}, {"a_Color2", VertexFormat::UByte4Norm, extraPickColor2Ops}}; - return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, VertexBuffer::INTERLEAVED, true, box_indices_ptr, 36); + return CGOConvertToShader(I, attrDesc, pickDesc, GL_TRIANGLES, buffer_layout::INTERLEAVED, true, box_indices_ptr, 36); } /** diff --git a/layer1/CGO.h b/layer1/CGO.h index 27c1f78e9..a19a85559 100644 --- a/layer1/CGO.h +++ b/layer1/CGO.h @@ -1184,7 +1184,11 @@ int CGOUniform3f(CGO *I, int uniform_id, const float *value); CGO *CGOConvertSpheresToPoints(const CGO *I); -CGO *CGOConvertToShader(const CGO *I, AttribDataDesc &attrData, AttribDataDesc &pickData, int mode, const VertexBuffer::buffer_layout layout=VertexBuffer::INTERLEAVED, bool check_attr_for_data=true, int *idx_array=nullptr, int nindicesperfrag=0, int nfragspergroup = 1); +CGO* CGOConvertToShader(const CGO* I, AttribDataDesc& attrData, + AttribDataDesc& pickData, int mode, + const buffer_layout layout = buffer_layout::INTERLEAVED, + bool check_attr_for_data = true, int* idx_array = nullptr, + int nindicesperfrag = 0, int nfragspergroup = 1); bool CGOCheckSplitLineInterpolationIsSame(const CGO *I, bool &interp_value);