Add VertexArray, BufferLayout, BufferElement
This commit is contained in:
@@ -1,9 +1,116 @@
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include "inferno/core.h"
|
||||
#include "inferno/log.h"
|
||||
#include "inferno/render/buffer.h"
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
BufferElement::BufferElement(BufferElementType type, std::string name, bool normalized) :
|
||||
m_type(type),
|
||||
m_name(name),
|
||||
m_size(BufferElement::getTypeSize(type)),
|
||||
m_offset(0),
|
||||
m_normalized(normalized)
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeSize() const
|
||||
{
|
||||
return BufferElement::getTypeSize(m_type);
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeCount() const
|
||||
{
|
||||
return BufferElement::getTypeCount(m_type);
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeGL() const
|
||||
{
|
||||
return BufferElement::getTypeGL(m_type);
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeSize(const BufferElementType type)
|
||||
{
|
||||
switch (type) {
|
||||
case BufferElementType::None: return 0;
|
||||
case BufferElementType::Int: return sizeof(int32_t);
|
||||
case BufferElementType::Int2: return sizeof(int32_t) * 2;
|
||||
case BufferElementType::Int3: return sizeof(int32_t) * 3;
|
||||
case BufferElementType::Int4: return sizeof(int32_t) * 4;
|
||||
case BufferElementType::Mat3: return sizeof(float) * 3 * 3;
|
||||
case BufferElementType::Mat4: return sizeof(float) * 4 * 4;
|
||||
case BufferElementType::Vec: return sizeof(float);
|
||||
case BufferElementType::Vec2: return sizeof(float) * 2;
|
||||
case BufferElementType::Vec3: return sizeof(float) * 3;
|
||||
case BufferElementType::Vec4: return sizeof(float) * 4;
|
||||
};
|
||||
|
||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType size!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeCount(const BufferElementType type)
|
||||
{
|
||||
switch (type) {
|
||||
case BufferElementType::None: return 0;
|
||||
case BufferElementType::Int: return 1;
|
||||
case BufferElementType::Int2: return 2;
|
||||
case BufferElementType::Int3: return 3;
|
||||
case BufferElementType::Int4: return 4;
|
||||
case BufferElementType::Mat3: return 3 * 3;
|
||||
case BufferElementType::Mat4: return 4 * 4;
|
||||
case BufferElementType::Vec: return 1;
|
||||
case BufferElementType::Vec2: return 2;
|
||||
case BufferElementType::Vec3: return 3;
|
||||
case BufferElementType::Vec4: return 4;
|
||||
};
|
||||
|
||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType count!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t BufferElement::getTypeGL(const BufferElementType type)
|
||||
{
|
||||
switch (type) {
|
||||
case BufferElementType::None: return GL_NONE;
|
||||
case BufferElementType::Int: return GL_INT;
|
||||
case BufferElementType::Int2: return GL_INT;
|
||||
case BufferElementType::Int3: return GL_INT;
|
||||
case BufferElementType::Int4: return GL_INT;
|
||||
case BufferElementType::Mat3: return GL_FLOAT;
|
||||
case BufferElementType::Mat4: return GL_FLOAT;
|
||||
case BufferElementType::Vec: return GL_FLOAT;
|
||||
case BufferElementType::Vec2: return GL_FLOAT;
|
||||
case BufferElementType::Vec3: return GL_FLOAT;
|
||||
case BufferElementType::Vec4: return GL_FLOAT;
|
||||
};
|
||||
|
||||
NF_CORE_ASSERT(false, "BufferElement unknown BufferElementType GL!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
BufferLayout::BufferLayout(const std::initializer_list<BufferElement> &elements) :
|
||||
m_elements(elements), m_stride(0)
|
||||
{
|
||||
this->calculateOffsetsAndStride();
|
||||
}
|
||||
|
||||
void BufferLayout::calculateOffsetsAndStride()
|
||||
{
|
||||
m_stride = 0;
|
||||
for (auto &element : m_elements) {
|
||||
element.setOffset(m_stride);
|
||||
m_stride += element.getSize();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
VertexBuffer::VertexBuffer(float* vertices, size_t size)
|
||||
{
|
||||
glCreateBuffers(1, &m_id);
|
||||
@@ -11,6 +118,8 @@ namespace Inferno {
|
||||
|
||||
// Upload data to the GPU
|
||||
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
|
||||
|
||||
this->unbind();
|
||||
}
|
||||
|
||||
VertexBuffer::~VertexBuffer()
|
||||
@@ -38,6 +147,8 @@ namespace Inferno {
|
||||
|
||||
// Upload data to the GPU
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW);
|
||||
|
||||
this->unbind();
|
||||
}
|
||||
|
||||
IndexBuffer::~IndexBuffer()
|
||||
@@ -55,4 +166,61 @@ namespace Inferno {
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
VertexArray::VertexArray()
|
||||
{
|
||||
glCreateVertexArrays(1, &m_id);
|
||||
}
|
||||
|
||||
VertexArray::~VertexArray()
|
||||
{
|
||||
glDeleteVertexArrays(1, &m_id);
|
||||
}
|
||||
|
||||
void VertexArray::bind() const
|
||||
{
|
||||
glBindVertexArray(m_id);
|
||||
}
|
||||
|
||||
void VertexArray::unbind() const
|
||||
{
|
||||
glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void VertexArray::addVertexBuffer(const std::shared_ptr<VertexBuffer> &vertexBuffer)
|
||||
{
|
||||
this->bind();
|
||||
vertexBuffer->bind();
|
||||
|
||||
uint32_t index = 0;
|
||||
for (const auto &element : vertexBuffer->getLayout()) {
|
||||
glEnableVertexAttribArray(index);
|
||||
glVertexAttribPointer(
|
||||
index,
|
||||
element.getTypeCount(),
|
||||
element.getTypeGL(),
|
||||
element.getNormalized() ? GL_TRUE : GL_FALSE,
|
||||
vertexBuffer->getLayout().getStride(),
|
||||
(const void*)element.getOffset());
|
||||
|
||||
index++;
|
||||
}
|
||||
m_vertexBuffers.push_back(vertexBuffer);
|
||||
|
||||
this->unbind();
|
||||
vertexBuffer->unbind();
|
||||
}
|
||||
|
||||
void VertexArray::setIndexBuffer(const std::shared_ptr<IndexBuffer> &indexBuffer)
|
||||
{
|
||||
this->bind();
|
||||
indexBuffer->bind();
|
||||
|
||||
m_indexBuffer = indexBuffer;
|
||||
|
||||
this->unbind();
|
||||
indexBuffer->unbind();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,10 +3,81 @@
|
||||
|
||||
#include <cstddef> // std::size_t
|
||||
#include <cstdint> // std::uint32_t
|
||||
#include <memory> // std::shared_ptr
|
||||
#include <string> // std::string
|
||||
#include <vector> // std::vector
|
||||
|
||||
namespace Inferno {
|
||||
|
||||
// GPU memory which holds the raw vertex data
|
||||
enum class BufferElementType {
|
||||
None = 0,
|
||||
Int, Int2, Int3, Int4,
|
||||
Mat3, Mat4,
|
||||
Vec, Vec2, Vec3, Vec4,
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// Describes one element of the BufferLayout
|
||||
class BufferElement {
|
||||
public:
|
||||
BufferElement(BufferElementType type, std::string name, bool normalized = false);
|
||||
|
||||
uint32_t getTypeSize() const;
|
||||
uint32_t getTypeCount() const;
|
||||
uint32_t getTypeGL() const;
|
||||
static uint32_t getTypeSize(const BufferElementType type);
|
||||
static uint32_t getTypeCount(const BufferElementType type);
|
||||
static uint32_t getTypeGL(const BufferElementType type);
|
||||
|
||||
inline BufferElementType getType() const{ return m_type; }
|
||||
inline std::string getName() const { return m_name; }
|
||||
inline uint32_t getSize() const { return m_size; }
|
||||
inline uint32_t getOffset() const { return m_offset; }
|
||||
inline bool getNormalized() const { return m_normalized; }
|
||||
|
||||
inline void setType(const BufferElementType &type) { m_type = type; }
|
||||
inline void setName(const std::string &name) { m_name = name; }
|
||||
inline void setSize(const uint32_t &size) { m_size = size; }
|
||||
inline void setOffset(const uint32_t &offset) { m_offset = offset; }
|
||||
inline void setNormalized(const bool &normalized) { m_normalized = normalized; }
|
||||
|
||||
private:
|
||||
BufferElementType m_type;
|
||||
std::string m_name;
|
||||
uint32_t m_size;
|
||||
uint32_t m_offset;
|
||||
bool m_normalized;
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// Layout that describes raw vertex data
|
||||
class BufferLayout {
|
||||
public:
|
||||
BufferLayout() {}
|
||||
BufferLayout(const std::initializer_list<BufferElement> &elements);
|
||||
|
||||
inline const std::vector<BufferElement> &getElements() const { return m_elements; }
|
||||
inline uint32_t getStride() const { return m_stride; }
|
||||
|
||||
// Iterators
|
||||
std::vector<BufferElement>::iterator begin() { return m_elements.begin(); }
|
||||
std::vector<BufferElement>::iterator end() { return m_elements.end(); }
|
||||
std::vector<BufferElement>::const_iterator begin() const { return m_elements.begin(); }
|
||||
std::vector<BufferElement>::const_iterator end() const { return m_elements.end(); }
|
||||
|
||||
protected:
|
||||
void calculateOffsetsAndStride();
|
||||
|
||||
private:
|
||||
std::vector<BufferElement> m_elements;
|
||||
uint32_t m_stride;
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// GPU memory which holds raw vertex data
|
||||
class VertexBuffer {
|
||||
public:
|
||||
VertexBuffer(float* vertices, size_t size);
|
||||
@@ -15,8 +86,13 @@ namespace Inferno {
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
inline BufferLayout const &getLayout() const { return m_layout; }
|
||||
|
||||
inline void setLayout(const BufferLayout &layout) { m_layout = layout; }
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
BufferLayout m_layout;
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
@@ -30,8 +106,6 @@ namespace Inferno {
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
inline uint32_t getCount() const { return m_count; }
|
||||
|
||||
private:
|
||||
@@ -39,6 +113,28 @@ namespace Inferno {
|
||||
uint32_t m_count;
|
||||
};
|
||||
|
||||
// -----------------------------------------
|
||||
|
||||
// Array that holds the vertex attributes configuration
|
||||
class VertexArray {
|
||||
public:
|
||||
VertexArray();
|
||||
~VertexArray();
|
||||
|
||||
void bind() const;
|
||||
void unbind() const;
|
||||
|
||||
void addVertexBuffer(const std::shared_ptr<VertexBuffer> &vertexBuffer);
|
||||
void setIndexBuffer(const std::shared_ptr<IndexBuffer> &indexBuffer);
|
||||
|
||||
const std::vector<std::shared_ptr<VertexBuffer>> &getVertexBuffers() const { return m_vertexBuffers; }
|
||||
const std::shared_ptr<IndexBuffer> &getIndexBuffer() const { return m_indexBuffer; }
|
||||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
std::vector<std::shared_ptr<VertexBuffer>> m_vertexBuffers;
|
||||
std::shared_ptr<IndexBuffer> m_indexBuffer;
|
||||
};
|
||||
}
|
||||
|
||||
#endif // BUFFER_H
|
||||
|
||||
Reference in New Issue
Block a user