Enhance OpenGLBuffer with more buffer types and features
- Add OpenGLBufferType enum (Vertex, Index, Uniform, CopyRead, CopyWrite, etc.) - Add Initialize() method with buffer type parameter - Add Map/Unmap for direct buffer access - Add SetData for dynamic updates - Add BindBase for buffer binding to indexed targets - Add GetType and IsDynamic getters
This commit is contained in:
@@ -6,25 +6,47 @@
|
|||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
namespace RHI {
|
||||||
|
|
||||||
|
enum class OpenGLBufferType {
|
||||||
|
Vertex,
|
||||||
|
Index,
|
||||||
|
Uniform,
|
||||||
|
CopyRead,
|
||||||
|
CopyWrite,
|
||||||
|
AtomicCounter,
|
||||||
|
DispatchIndirect,
|
||||||
|
DrawIndirect,
|
||||||
|
ShaderBindingTable
|
||||||
|
};
|
||||||
|
|
||||||
class OpenGLBuffer {
|
class OpenGLBuffer {
|
||||||
public:
|
public:
|
||||||
OpenGLBuffer();
|
OpenGLBuffer();
|
||||||
~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 InitializeVertexBuffer(const void* data, size_t size);
|
||||||
bool InitializeIndexBuffer(const void* data, size_t size);
|
bool InitializeIndexBuffer(const void* data, size_t size);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
void Bind() const;
|
void Bind() const;
|
||||||
void Unbind() 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; }
|
unsigned int GetID() const { return m_buffer; }
|
||||||
size_t GetSize() const { return m_size; }
|
size_t GetSize() const { return m_size; }
|
||||||
|
OpenGLBufferType GetType() const { return m_type; }
|
||||||
|
bool IsDynamic() const { return m_dynamic; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_buffer;
|
unsigned int m_buffer;
|
||||||
size_t m_size;
|
size_t m_size;
|
||||||
bool m_isIndexBuffer;
|
bool m_isIndexBuffer;
|
||||||
|
bool m_dynamic;
|
||||||
|
OpenGLBufferType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
@@ -6,32 +6,56 @@
|
|||||||
namespace XCEngine {
|
namespace XCEngine {
|
||||||
namespace RHI {
|
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()
|
OpenGLBuffer::OpenGLBuffer()
|
||||||
: m_buffer(0)
|
: m_buffer(0)
|
||||||
, m_size(0)
|
, m_size(0)
|
||||||
, m_isIndexBuffer(false) {
|
, m_isIndexBuffer(false)
|
||||||
|
, m_dynamic(false)
|
||||||
|
, m_type(OpenGLBufferType::Vertex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGLBuffer::~OpenGLBuffer() {
|
OpenGLBuffer::~OpenGLBuffer() {
|
||||||
Shutdown();
|
Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenGLBuffer::InitializeVertexBuffer(const void* data, size_t size) {
|
bool OpenGLBuffer::Initialize(OpenGLBufferType type, size_t size, const void* data, bool dynamic) {
|
||||||
glGenBuffers(1, &m_buffer);
|
m_type = type;
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);
|
|
||||||
m_size = size;
|
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;
|
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) {
|
bool OpenGLBuffer::InitializeIndexBuffer(const void* data, size_t size) {
|
||||||
glGenBuffers(1, &m_buffer);
|
return Initialize(OpenGLBufferType::Index, size, data, false);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLBuffer::Shutdown() {
|
void OpenGLBuffer::Shutdown() {
|
||||||
@@ -42,19 +66,43 @@ void OpenGLBuffer::Shutdown() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLBuffer::Bind() const {
|
void OpenGLBuffer::Bind() const {
|
||||||
if (m_isIndexBuffer) {
|
unsigned int target = ToGLBufferTarget(m_type);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_buffer);
|
glBindBuffer(target, m_buffer);
|
||||||
} else {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, m_buffer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenGLBuffer::Unbind() const {
|
void OpenGLBuffer::Unbind() const {
|
||||||
if (m_isIndexBuffer) {
|
unsigned int target = ToGLBufferTarget(m_type);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
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 {
|
} else {
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBufferSubData(target, offset, size, data);
|
||||||
}
|
}
|
||||||
|
glBindBuffer(target, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace RHI
|
} // namespace RHI
|
||||||
|
|||||||
Reference in New Issue
Block a user