Browse Source

Add VertexArray, BufferLayout, BufferElement

master
Riyyi 5 years ago
parent
commit
b90e5ed5dd
  1. 5
      assets/glsl/simple.frag
  2. 7
      assets/glsl/simple.vert
  3. 168
      inferno/src/inferno/render/buffer.cpp
  4. 102
      inferno/src/inferno/render/buffer.h

5
assets/glsl/simple.frag

@ -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;
} }

7
assets/glsl/simple.vert

@ -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);
} }

168
inferno/src/inferno/render/buffer.cpp

@ -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();
}
} }

102
inferno/src/inferno/render/buffer.h

@ -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

Loading…
Cancel
Save