#include "XCEngine/RHI/OpenGL/OpenGLBuffer.h" #include 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_dynamic(false) , m_type(OpenGLBufferType::Vertex) { } OpenGLBuffer::~OpenGLBuffer() { Shutdown(); } bool OpenGLBuffer::Initialize(OpenGLBufferType type, size_t size, const void* data, bool dynamic) { m_type = type; m_size = size; 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) { return Initialize(OpenGLBufferType::Index, size, data, false); } void OpenGLBuffer::Shutdown() { if (m_buffer) { glDeleteBuffers(1, &m_buffer); m_buffer = 0; } } void OpenGLBuffer::Bind() const { unsigned int target = ToGLBufferTarget(m_type); glBindBuffer(target, m_buffer); } void OpenGLBuffer::Unbind() const { 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 { glBufferSubData(target, offset, size, data); } glBindBuffer(target, 0); } } // namespace RHI } // namespace XCEngine