diff --git a/engine/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h b/engine/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h index 05c768c5..3e982285 100644 --- a/engine/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h +++ b/engine/include/XCEngine/RHI/OpenGL/OpenGLBuffer.h @@ -6,25 +6,47 @@ namespace XCEngine { namespace RHI { +enum class OpenGLBufferType { + Vertex, + Index, + Uniform, + CopyRead, + CopyWrite, + AtomicCounter, + DispatchIndirect, + DrawIndirect, + ShaderBindingTable +}; + class OpenGLBuffer { public: OpenGLBuffer(); ~OpenGLBuffer(); + bool Initialize(OpenGLBufferType type, size_t size, const void* data = nullptr, bool dynamic = false); bool InitializeVertexBuffer(const void* data, size_t size); bool InitializeIndexBuffer(const void* data, size_t size); void Shutdown(); void Bind() const; void Unbind() const; + void BindBase(unsigned int target, unsigned int index) const; + + void* Map(); + void Unmap(); + void SetData(const void* data, size_t size, size_t offset = 0); unsigned int GetID() const { return m_buffer; } size_t GetSize() const { return m_size; } + OpenGLBufferType GetType() const { return m_type; } + bool IsDynamic() const { return m_dynamic; } private: unsigned int m_buffer; size_t m_size; bool m_isIndexBuffer; + bool m_dynamic; + OpenGLBufferType m_type; }; } // namespace RHI diff --git a/engine/src/RHI/OpenGL/OpenGLBuffer.cpp b/engine/src/RHI/OpenGL/OpenGLBuffer.cpp index 3072d2a9..d05b2c8d 100644 --- a/engine/src/RHI/OpenGL/OpenGLBuffer.cpp +++ b/engine/src/RHI/OpenGL/OpenGLBuffer.cpp @@ -6,32 +6,56 @@ namespace XCEngine { namespace RHI { +static unsigned int ToGLBufferTarget(OpenGLBufferType type) { + switch (type) { + case OpenGLBufferType::Vertex: return GL_ARRAY_BUFFER; + case OpenGLBufferType::Index: return GL_ELEMENT_ARRAY_BUFFER; + case OpenGLBufferType::Uniform: return GL_UNIFORM_BUFFER; + case OpenGLBufferType::CopyRead: return GL_COPY_READ_BUFFER; + case OpenGLBufferType::CopyWrite: return GL_COPY_WRITE_BUFFER; + case OpenGLBufferType::AtomicCounter: return GL_ATOMIC_COUNTER_BUFFER; + case OpenGLBufferType::DispatchIndirect: return GL_DISPATCH_INDIRECT_BUFFER; + case OpenGLBufferType::DrawIndirect: return GL_DRAW_INDIRECT_BUFFER; + case OpenGLBufferType::ShaderBindingTable: return GL_SHADER_STORAGE_BUFFER; + default: return GL_ARRAY_BUFFER; + } +} + OpenGLBuffer::OpenGLBuffer() : m_buffer(0) , m_size(0) - , m_isIndexBuffer(false) { + , m_isIndexBuffer(false) + , m_dynamic(false) + , m_type(OpenGLBufferType::Vertex) { } OpenGLBuffer::~OpenGLBuffer() { Shutdown(); } -bool OpenGLBuffer::InitializeVertexBuffer(const void* data, size_t size) { - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); +bool OpenGLBuffer::Initialize(OpenGLBufferType type, size_t size, const void* data, bool dynamic) { + m_type = type; m_size = size; - m_isIndexBuffer = false; + m_dynamic = dynamic; + m_isIndexBuffer = (type == OpenGLBufferType::Index); + + unsigned int target = ToGLBufferTarget(type); + GLenum usage = dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW; + + glGenBuffers(1, &m_buffer); + glBindBuffer(target, m_buffer); + glBufferData(target, size, data, usage); + glBindBuffer(target, 0); + return true; } +bool OpenGLBuffer::InitializeVertexBuffer(const void* data, size_t size) { + return Initialize(OpenGLBufferType::Vertex, size, data, false); +} + bool OpenGLBuffer::InitializeIndexBuffer(const void* data, size_t size) { - glGenBuffers(1, &m_buffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, data, GL_STATIC_DRAW); - m_size = size; - m_isIndexBuffer = true; - return true; + return Initialize(OpenGLBufferType::Index, size, data, false); } void OpenGLBuffer::Shutdown() { @@ -42,19 +66,43 @@ void OpenGLBuffer::Shutdown() { } void OpenGLBuffer::Bind() const { - if (m_isIndexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer); - } else { - glBindBuffer(GL_ARRAY_BUFFER, m_buffer); - } + unsigned int target = ToGLBufferTarget(m_type); + glBindBuffer(target, m_buffer); } void OpenGLBuffer::Unbind() const { - if (m_isIndexBuffer) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + unsigned int target = ToGLBufferTarget(m_type); + glBindBuffer(target, 0); +} + +void OpenGLBuffer::BindBase(unsigned int target, unsigned int index) const { + glBindBufferBase(target, index, m_buffer); +} + +void* OpenGLBuffer::Map() { + unsigned int target = ToGLBufferTarget(m_type); + glBindBuffer(target, m_buffer); + void* ptr = glMapBuffer(target, GL_WRITE_ONLY); + glBindBuffer(target, 0); + return ptr; +} + +void OpenGLBuffer::Unmap() { + unsigned int target = ToGLBufferTarget(m_type); + glBindBuffer(target, m_buffer); + glUnmapBuffer(target); + glBindBuffer(target, 0); +} + +void OpenGLBuffer::SetData(const void* data, size_t size, size_t offset) { + unsigned int target = ToGLBufferTarget(m_type); + glBindBuffer(target, m_buffer); + if (offset == 0 && size == m_size) { + glBufferData(target, size, data, m_dynamic ? GL_DYNAMIC_DRAW : GL_STATIC_DRAW); } else { - glBindBuffer(GL_ARRAY_BUFFER, 0); + glBufferSubData(target, offset, size, data); } + glBindBuffer(target, 0); } } // namespace RHI