#include "vertex_array.hpp" // Struktura pro informace o jednotlivych vertex atributu struct VertexAttribInfo { GLuint index; GLint size; GLenum type; GLboolean normalized; size_t byte_size; }; // Informace o jednotlivych vertex atributech static const VertexAttribInfo s_ATTR_INFO[] = { { 0, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3 }, // VA_POSITION { 1, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 3 }, // VA_NORMAL { 2, 4, GL_UNSIGNED_BYTE, GL_TRUE, 4 }, // VA_COLOR }; // Pocet typu vertex atributu static const size_t s_ATTR_COUNT = 3; gfx::VertexArray::VertexArray(int attrs, int flags) : m_usage(GL_STATIC_DRAW), m_num_indices(0) { glGenVertexArrays(1, &m_vao); glBindVertexArray(m_vao); if (flags & VF_DYNAMIC) m_usage = GL_DYNAMIC_DRAW; // vytvori buffer pro vrcholy m_vbo = std::make_unique(GL_ARRAY_BUFFER, m_usage); m_vbo->Bind(); // vypocet velikosti jednoho vrcholu size_t stride = 0U; for (size_t i = 0; i < s_ATTR_COUNT; i++) { if (attrs & (1 << i)) stride += s_ATTR_INFO[i].byte_size; } // povoli a nastavi jednotlive vertex atributy size_t offset = 0U; for (size_t i = 0; i < s_ATTR_COUNT; i++) { if (attrs & (1 << i)) { const auto& info = s_ATTR_INFO[i]; glEnableVertexAttribArray(info.index); glVertexAttribPointer(info.index, info.size, info.type, info.normalized, stride, (const void*)offset); offset += info.byte_size; } } // vytvori buffer pro indexy if (flags & VF_CREATE_EBO) { m_ebo = std::make_unique(GL_ELEMENT_ARRAY_BUFFER, m_usage); m_ebo->Bind(); } glBindVertexArray(0); } gfx::VertexArray::~VertexArray() { // uklid glDeleteVertexArrays(1, &m_vao); } // Nastavi data do VBO void gfx::VertexArray::SetVBOData(const void* data, size_t size) { glBindVertexArray(m_vao); m_vbo->SetData(data, size); glBindVertexArray(0); } // Nastavi indexy do EBO void gfx::VertexArray::SetIndices(const GLuint* data, size_t size) { glBindVertexArray(m_vao); m_ebo->SetData(data, size * sizeof(*data)); m_num_indices = size; glBindVertexArray(0); }