StapleGL
Header-only C++20 OpenGL wrapper
Loading...
Searching...
No Matches
vertex_array.hpp
Go to the documentation of this file.
1
25#pragma once
26#include "gl_functions.hpp"
27#include "index_buffer.hpp"
28#include "vertex_buffer.hpp"
30
31#include <cstdint>
32#include <list>
33#include <optional>
34
35namespace staplegl {
36
52public:
62 vertex_array() noexcept;
64
65 vertex_array(const vertex_array&) = delete;
66 auto operator=(const vertex_array&) -> vertex_array& = delete;
67
76 vertex_array(vertex_array&& other) noexcept
77 : m_id(other.m_id)
78 , m_vertex_buffers(std::move(other.m_vertex_buffers))
79 , m_instanced_vbo(std::move(other.m_instanced_vbo))
80 , m_index_buffer(std::move(other.m_index_buffer))
81 , attrib_index(other.attrib_index)
82 {
83 other.m_id = 0;
84 }
85
93 auto operator=(vertex_array&& other) noexcept -> vertex_array&
94 {
95 if (this != &other) {
96 m_id = other.m_id;
97 m_vertex_buffers = std::move(other.m_vertex_buffers);
98 m_instanced_vbo = std::move(other.m_instanced_vbo);
99 m_index_buffer = std::move(other.m_index_buffer);
100 attrib_index = other.attrib_index;
101
102 other.m_id = 0;
103 }
104 return *this;
105 }
106
111 using iterator_t = std::list<vertex_buffer>::iterator;
112
117 void bind() const;
118
123 static void unbind();
124
136
144
150
157 void set_index_buffer(index_buffer&& ibo);
158
159 // utility functions
160
165 [[nodiscard]] constexpr auto id() const -> uint32_t { return m_id; }
166
172 [[nodiscard]] constexpr auto buffers_data() -> std::list<vertex_buffer>& { return m_vertex_buffers; }
173
179 [[nodiscard]] constexpr auto instanced_data() -> std::optional<vertex_buffer_inst>& { return m_instanced_vbo; }
180
186 [[nodiscard]] constexpr auto index_data() -> index_buffer& { return m_index_buffer; }
187
188private:
189 std::uint32_t m_id {};
190 std::list<vertex_buffer> m_vertex_buffers;
191 std::optional<vertex_buffer_inst> m_instanced_vbo;
193
194 uint32_t attrib_index {};
195};
196
197/*
198
199 IMPLEMENTATIONS
200
201*/
202
204{
205 glGenVertexArrays(1, &m_id);
206}
207
209{
210 glDeleteVertexArrays(1, &m_id);
211}
212
213inline void vertex_array::bind() const
214{
215 glBindVertexArray(m_id);
216}
217
219{
220 glBindVertexArray(0);
221}
222
224{
225 m_vertex_buffers.push_back(std::move(vbo));
226 glBindVertexArray(m_id);
227
228 // get a reference to the newly added vertex buffer from the variant in the vector
229 vertex_buffer const& vbo_ref = m_vertex_buffers.back();
230
231 vbo_ref.bind();
232
233 for (const auto& [name, element_count, offset, type] : vbo_ref.layout().get_attributes()) {
234 glEnableVertexAttribArray(attrib_index);
235 glVertexAttribPointer(
236 attrib_index++,
237 static_cast<int32_t>(shader_data_type::component_count(type) * element_count),
239 GL_FALSE,
240 static_cast<int32_t>(vbo_ref.layout().stride()),
241 reinterpret_cast<const void*>(offset)); // NOLINT (reinterpret-cast)
242 }
243
244 return std::prev(m_vertex_buffers.end());
245}
246
248{
249 m_instanced_vbo = std::move(vbo);
250
251 glBindVertexArray(m_id);
252 m_instanced_vbo->bind();
253
254 for (const auto& [name, element_count, offset, type] : m_instanced_vbo->layout().get_attributes()) {
255 glEnableVertexAttribArray(attrib_index);
256 glVertexAttribPointer(
257 attrib_index++,
258 static_cast<int32_t>(shader_data_type::component_count(type) * element_count),
260 GL_FALSE,
261 static_cast<int32_t>(m_instanced_vbo->layout().stride()),
262 reinterpret_cast<const void*>(offset)); // NOLINT (reinterpret-cast)
263 glVertexAttribDivisor(attrib_index - 1, 1);
264 }
265}
266
268{
269 m_index_buffer = std::move(ibo);
270
271 glBindVertexArray(m_id);
273}
274}
Element Buffer Object (EBO) wrapper.
void bind() const
Bind the index buffer object.
Vertex Array Object (VAO) wrapper.
constexpr auto instanced_data() -> std::optional< vertex_buffer_inst > &
Get the instance buffer object.
void bind() const
Bind the vertex array object.
void set_index_buffer(index_buffer &&ibo)
Set the index buffer object.
constexpr auto id() const -> uint32_t
Get the vertex array object id.
static void unbind()
Unbind the vertex array object.
constexpr auto buffers_data() -> std::list< vertex_buffer > &
Get the vertex buffer object at the specified index.
auto operator=(vertex_array &&other) noexcept -> vertex_array &
Move assignment operator.
vertex_array(const vertex_array &)=delete
std::optional< vertex_buffer_inst > m_instanced_vbo
vertex_array() noexcept
Construct a new vertex array object.
void set_instance_buffer(vertex_buffer_inst &&vbo)
Set the instance buffer object.
std::list< vertex_buffer > m_vertex_buffers
auto operator=(const vertex_array &) -> vertex_array &=delete
constexpr auto index_data() -> index_buffer &
Get the index buffer object.
auto add_vertex_buffer(vertex_buffer &&vbo) -> vertex_array::iterator_t
Add a vertex buffer to the vertex array object.
vertex_array(vertex_array &&other) noexcept
Construct a new vertex array object from another one.
void clear_instance_buffer()
Clear the instance buffer object.
std::list< vertex_buffer >::iterator iterator_t
Iterator type returned from add_vertex_buffer.
A vertex buffer object for instanced rendering.
Vertex Buffer Object (VBO) wrapper.
constexpr auto layout() const -> const vertex_buffer_layout &
void bind() const
Bind the vertex buffer object.
Loads OpenGL functions.
Element Buffer Object (EBO) wrapper.
static constexpr auto component_count(u_type type) -> std::uint16_t
Get the number of components in the shader data type, useful for vector types.
static constexpr auto to_opengl_underlying_type(u_type type) -> std::uint32_t
Obtains the OpenGL type of the underlying type of the shader data type.
Vertex Buffer Object (VBO) wrapper.
Vertex buffer object for instanced rendering.