I am trying to code a thin wrapper around the OpenGL so I can use it more convenient. This class is not 100% done yet, but I don't want to do all typing for nothing. And I think the design is clear. I would hope some review anything they see with my C++ code or with the way I use OpenGL.
.hpp file
#pragma once
#include <GL\glew.h>
enum class BufferType : GLenum
{
VertexBuffer = GL_ARRAY_BUFFER,
IndexBuffer = GL_ELEMENT_ARRAY_BUFFER,
// Rest will be added when I need it
None
};
enum class AccessType // Used for mapping later
{
Read,
Write,
ReadWrite
};
enum class UsageType : GLenum
{
StreamDraw, // Fill these in when I need it
StreamRead,
StreamCopy,
StaticDraw = GL_STATIC_DRAW,
StaticRead = GL_STATIC_READ,
StaticCopy = GL_STATIC_COPY,
DynamicDraw,
DynamicRead,
DynamicCopy,
None
};
class OpenGLBuffer
{
public:
OpenGLBuffer();
OpenGLBuffer(BufferType Buffer, UsageType Usage);
~OpenGLBuffer();
bool Create(unsigned int Size);
bool Create();
//Maybe also make a Read/Write func that handles a vector ( bool WriteData(unsigned int Offset, unsgiedn int SizeOfObject, std::vector<void*>& data);
bool WriteData(unsigned int Offset, unsigned int Size, void* data);
bool ReadData(unsigned int Offset, unsigned int Size, void* data);
void Bind();
void Unbind();
bool Grow(unsigned int Size, bool Copy = true);
//Mapping functions, when I need those
bool IsCreated();
bool IsAutoResize();
void SetBufferType(BufferType Type);
void SetUsageType(UsageType Type);
void SetAutoResize(bool AutoResize, unsigned int Size = 100);
BufferType GetBufferType();
UsageType GetUsageType();
GLuint GetId();
unsigned int GetSize();
unsigned int GetDataUsed();
private:
GLuint m_Id = 0;
BufferType m_BufferType;
UsageType m_UsageType;
unsigned int m_Size = 0;
unsigned int m_DataUsed = 0;
bool m_IsCreated = false;
bool m_AutoResize = false;
unsigned int m_ResizeSize = 100; // Random, is there a better thing?
};
And this is the .cpp file:
#include "OpenGLBuffer.hpp"
OpenGLBuffer::OpenGLBuffer()
{
OpenGLBuffer(BufferType::None, UsageType::None);
}
OpenGLBuffer::OpenGLBuffer(BufferType Buffer, UsageType Usage)
{
m_BufferType = Buffer;
m_UsageType = Usage;
}
OpenGLBuffer::~OpenGLBuffer()
{
// Bind and delete it
}
bool OpenGLBuffer::Create(unsigned int Size)
{
if (m_BufferType == BufferType::None || m_UsageType == UsageType::None)
return false;
glGenBuffers(1, &m_Id);
Bind();
glBufferData(static_cast<GLenum>(m_BufferType), Size, 0, static_cast<GLenum>(m_UsageType));
m_IsCreated = true;
m_Size = Size;
return true;
}
bool OpenGLBuffer::Create()
{
return Create(m_ResizeSize);
}
bool OpenGLBuffer::WriteData(unsigned int Offset, unsigned int Size, void* data)
{
if (!m_IsCreated)
return false;
if (m_DataUsed + Size > m_Size)
{
if (m_AutoResize)
{
if (m_ResizeSize < m_DataUsed + Size)
if (!Grow(Size - m_DataUsed + m_ResizeSize))
return false;
else
if (!Grow(m_ResizeSize, true))
return false;
}
else
return false;
}
Bind(); // Is this a good idea?
glBufferSubData(static_cast<GLenum>(m_BufferType), m_DataUsed, Size, data);
//Have some checks
Unbind();
m_DataUsed += Size;
return true;
}
bool OpenGLBuffer::ReadData(unsigned int Offset, unsigned int Size, void* data)
{
if (!m_IsCreated)
return false;
// First ask if this a good approach
return false;
}
void OpenGLBuffer::Bind()
{
if(m_IsCreated)
glBindBuffer(static_cast<GLenum>(m_BufferType), m_Id);
}
void OpenGLBuffer::Unbind()
{
if(m_IsCreated)
glBindBuffer(static_cast<GLenum>(m_BufferType), 0);
}
bool OpenGLBuffer::Grow(unsigned int Size, bool Copy )
{
if (!m_IsCreated)
return false;
glBindBuffer(GL_COPY_READ_BUFFER, m_Id);
GLuint NewId;
glGenBuffers(1, &NewId);
glBindBuffer(GL_COPY_WRITE_BUFFER, NewId);
glBufferData(GL_COPY_WRITE_BUFFER, m_DataUsed + Size, 0, static_cast<GLenum>(m_UsageType));
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, m_DataUsed);
//Have some checks
//Delete old buffer ID
m_Id = NewId;
m_Size = Size + m_DataUsed;
return true;
}
bool OpenGLBuffer::IsCreated()
{
return m_IsCreated;
}
bool OpenGLBuffer::IsAutoResize()
{
return m_AutoResize;
}
void OpenGLBuffer::SetBufferType(BufferType Type)
{
m_BufferType = Type;
}
void OpenGLBuffer::SetUsageType(UsageType Type)
{
m_UsageType = Type;
}
void OpenGLBuffer::SetAutoResize(bool AutoResize, unsigned int Size)
{
m_AutoResize = AutoResize;
m_ResizeSize = Size;
}
BufferType OpenGLBuffer::GetBufferType()
{
return m_BufferType;
}
UsageType OpenGLBuffer::GetUsageType()
{
return m_UsageType;
}
GLuint OpenGLBuffer::GetId()
{
return m_Id;
}
unsigned int OpenGLBuffer::GetSize()
{
return m_Size;
}
unsigned int OpenGLBuffer::GetDataUsed()
{
return m_DataUsed;
}