Add VertexArray, BufferLayout, BufferElement
This commit is contained in:
@@ -2,9 +2,10 @@
|
|||||||
|
|
||||||
layout(location = 0) out vec4 color;
|
layout(location = 0) out vec4 color;
|
||||||
|
|
||||||
in vec3 position;
|
in vec3 p_position;
|
||||||
|
in vec4 p_color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
color = vec4(position * 0.5f + 0.5f, 1.0f);
|
color = p_color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
#version 450 core
|
#version 450 core
|
||||||
|
|
||||||
layout(location = 0) in vec3 a_position;
|
layout(location = 0) in vec3 a_position;
|
||||||
|
layout(location = 1) in vec4 a_color;
|
||||||
|
|
||||||
out vec3 position;
|
out vec3 p_position;
|
||||||
|
out vec4 p_color;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
position = a_position;
|
p_position = a_position;
|
||||||
|
p_color = a_color;
|
||||||
gl_Position = vec4(a_position, 1.0f);
|
gl_Position = vec4(a_position, 1.0f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,116 @@
|
|||||||
#include <glad/glad.h>
|
#include <glad/glad.h>
|
||||||
|
|
||||||
|
#include "inferno/core.h"
|
||||||
|
#include "inferno/log.h"
|
||||||
#include "inferno/render/buffer.h"
|
#include "inferno/render/buffer.h"
|
||||||
|
|
||||||
namespace Inferno {
|
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)
|
VertexBuffer::VertexBuffer(float* vertices, size_t size)
|
||||||
{
|
{
|
||||||
glCreateBuffers(1, &m_id);
|
glCreateBuffers(1, &m_id);
|
||||||
@@ -11,6 +118,8 @@ namespace Inferno {
|
|||||||
|
|
||||||
// Upload data to the GPU
|
// Upload data to the GPU
|
||||||
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, size, vertices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
this->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexBuffer::~VertexBuffer()
|
VertexBuffer::~VertexBuffer()
|
||||||
@@ -38,6 +147,8 @@ namespace Inferno {
|
|||||||
|
|
||||||
// Upload data to the GPU
|
// Upload data to the GPU
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, size, indices, GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
this->unbind();
|
||||||
}
|
}
|
||||||
|
|
||||||
IndexBuffer::~IndexBuffer()
|
IndexBuffer::~IndexBuffer()
|
||||||
@@ -55,4 +166,61 @@ namespace Inferno {
|
|||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
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 <cstddef> // std::size_t
|
||||||
#include <cstdint> // std::uint32_t
|
#include <cstdint> // std::uint32_t
|
||||||
|
#include <memory> // std::shared_ptr
|
||||||
|
#include <string> // std::string
|
||||||
|
#include <vector> // std::vector
|
||||||
|
|
||||||
namespace Inferno {
|
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 {
|
class VertexBuffer {
|
||||||
public:
|
public:
|
||||||
VertexBuffer(float* vertices, size_t size);
|
VertexBuffer(float* vertices, size_t size);
|
||||||
@@ -15,8 +86,13 @@ namespace Inferno {
|
|||||||
void bind() const;
|
void bind() const;
|
||||||
void unbind() const;
|
void unbind() const;
|
||||||
|
|
||||||
|
inline BufferLayout const &getLayout() const { return m_layout; }
|
||||||
|
|
||||||
|
inline void setLayout(const BufferLayout &layout) { m_layout = layout; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
|
BufferLayout m_layout;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
@@ -30,8 +106,6 @@ namespace Inferno {
|
|||||||
void bind() const;
|
void bind() const;
|
||||||
void unbind() const;
|
void unbind() const;
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
|
|
||||||
inline uint32_t getCount() const { return m_count; }
|
inline uint32_t getCount() const { return m_count; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -39,6 +113,28 @@ namespace Inferno {
|
|||||||
uint32_t m_count;
|
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
|
#endif // BUFFER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user