light/Engine/src/Platform/GraphicsAPI/OpenGL/glVertexLayout.cpp

97 lines
3.3 KiB
C++
Raw Normal View History

2021-05-29 15:40:15 +04:30
#include "glVertexLayout.h"
#include "glBuffers.h"
#include <glad/glad.h>
namespace Light {
glVertexLayout::glVertexLayout(Ref<VertexBuffer> buffer, const std::vector<std::pair<std::string, VertexElementType>>& elements)
2021-07-29 17:12:13 +04:30
: m_ArrayID(NULL)
2021-05-29 15:40:15 +04:30
{
// check
LT_ENGINE_ASSERT(std::dynamic_pointer_cast<glVertexBuffer>(buffer), "glVertexLayout::glVertexLayout: failed to cast 'VertexBuffer' to 'glVertexBuffer'");
LT_ENGINE_ASSERT(!elements.empty(), "glVertexLayout::glVertexLayout: 'elements' is empty");
2021-05-29 15:40:15 +04:30
// local
2021-05-30 16:45:54 +04:30
std::vector<glVertexElementDesc> elementsDesc;
elementsDesc.reserve(elements.size());
2021-05-29 15:40:15 +04:30
unsigned int stride = 0u;
// extract elements desc
2021-05-29 15:40:15 +04:30
for(const auto& element : elements)
{
2021-06-02 17:20:15 +04:30
elementsDesc.push_back(GetElementDesc(element.second, stride));
2021-05-29 15:40:15 +04:30
stride += elementsDesc.back().typeSize * elementsDesc.back().count;
}
// create vertex array
2021-05-29 15:40:15 +04:30
glCreateVertexArrays(1, &m_ArrayID);
// bind buffer and array
2021-05-29 15:40:15 +04:30
buffer->Bind();
Bind();
// enable vertex attributes
2021-05-29 15:40:15 +04:30
unsigned int index = 0u;
for (const auto& elementDesc : elementsDesc)
{
glVertexAttribPointer(index, elementDesc.count, elementDesc.type, GL_FALSE, stride, (const void*)elementDesc.offset);
glEnableVertexAttribArray(index++);
}
}
glVertexLayout::~glVertexLayout()
{
glDeleteVertexArrays(1, &m_ArrayID);
}
void glVertexLayout::Bind()
{
glBindVertexArray(m_ArrayID);
}
void glVertexLayout::UnBind()
{
glBindVertexArray(NULL);
}
glVertexElementDesc glVertexLayout::GetElementDesc(VertexElementType type, unsigned int offset)
{
switch (type)
{
/* byte */
case Light::VertexElementType::Byte1: return { GL_BYTE, 1u, sizeof(GLbyte), offset };
case Light::VertexElementType::Byte2: return { GL_BYTE, 1u, sizeof(GLbyte), offset };
case Light::VertexElementType::Byte4: return { GL_BYTE, 1u, sizeof(GLbyte), offset };
/* ubyte */
case Light::VertexElementType::UByte1: return { GL_UNSIGNED_BYTE, 1u, sizeof(GLubyte), offset };
case Light::VertexElementType::UByte2: return { GL_UNSIGNED_BYTE, 2u, sizeof(GLubyte), offset };
case Light::VertexElementType::UByte4: return { GL_UNSIGNED_BYTE, 4u, sizeof(GLubyte), offset };
/* int */
case VertexElementType::Int1: return { GL_INT, 1u, sizeof(GLint), offset };
case VertexElementType::Int2: return { GL_INT, 2u, sizeof(GLint), offset };
case VertexElementType::Int3: return { GL_INT, 3u, sizeof(GLint), offset };
case VertexElementType::Int4: return { GL_INT, 4u, sizeof(GLint), offset };
/* uint */
case VertexElementType::UInt1: return { GL_UNSIGNED_INT, 1u, sizeof(GLuint), offset };
case VertexElementType::UInt2: return { GL_UNSIGNED_INT, 2u, sizeof(GLuint), offset };
case VertexElementType::UInt3: return { GL_UNSIGNED_INT, 3u, sizeof(GLuint), offset };
case VertexElementType::UInt4: return { GL_UNSIGNED_INT, 4u, sizeof(GLuint), offset };
/* float */
case VertexElementType::Float1: return { GL_FLOAT, 1u, sizeof(GLfloat), offset };
case VertexElementType::Float2: return { GL_FLOAT, 2u, sizeof(GLfloat), offset };
case VertexElementType::Float3: return { GL_FLOAT, 3u, sizeof(GLfloat), offset };
case VertexElementType::Float4: return { GL_FLOAT, 4u, sizeof(GLfloat), offset };
2021-05-29 15:40:15 +04:30
default:
LT_ENGINE_ASSERT(false, "glVertexLayout::GetElementDesc: invalid 'VertexElementType'");
2021-05-29 15:40:15 +04:30
return {};
}
}
}