80 std::size_t new_cap { 0 };
87 new_cap =
static_cast<size_t>(
static_cast<double>(
capacity) * std::numbers::phi);
103 void resize_buffer(std::size_t old_capacity, std::size_t new_capacity)
noexcept
111 std::uint32_t new_id {};
112 glGenBuffers(1, &new_id);
114 glBindBuffer(GL_COPY_WRITE_BUFFER, new_id);
115 glBufferData(GL_COPY_WRITE_BUFFER,
static_cast<ptrdiff_t
>(old_capacity),
nullptr,
m_hint);
117 glBindBuffer(GL_COPY_READ_BUFFER,
m_id);
121 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0,
static_cast<ptrdiff_t
>(
m_count *
m_layout.
stride()));
123 glBindBuffer(GL_COPY_WRITE_BUFFER,
m_id);
124 glBufferData(GL_COPY_WRITE_BUFFER,
static_cast<ptrdiff_t
>(new_capacity),
nullptr,
m_hint);
126 glBindBuffer(GL_COPY_READ_BUFFER, new_id);
128 glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0,
static_cast<ptrdiff_t
>(
m_count *
m_layout.
stride()));
130 glDeleteBuffers(1, &new_id);
131 glBindBuffer(GL_ARRAY_BUFFER,
m_id);
158 void add_instance(std::span<const
float> instance_data) noexcept;
183 std::span<const
float> instance_data) noexcept;
201 if ((m_count + 1) * m_layout.stride() > m_capacity) [[unlikely]] {
202 auto new_capacity = calc_capacity(m_capacity);
203 resize_buffer(m_capacity, new_capacity);
206 update_instance(m_count, instance_data);
215 assert(index < m_count || instance_data.size_bytes() == m_layout.stride());
218 glBindBuffer(GL_ARRAY_BUFFER, m_id);
219 glBufferSubData(GL_ARRAY_BUFFER,
220 static_cast<ptrdiff_t
>(index * m_layout.stride()),
221 static_cast<ptrdiff_t
>(m_layout.stride()),
222 instance_data.data());
227 if (index >= m_count || index < 0) [[unlikely]] {
233 auto* last_instance_ptr =
static_cast<float*
>(glMapBufferRange(
235 static_cast<ptrdiff_t
>((m_count - 1) * m_layout.stride()),
236 static_cast<uint32_t
>(m_layout.stride()),
237 GL_MAP_WRITE_BIT | GL_MAP_READ_BIT));
241 auto last_instance = std::span<const float> { last_instance_ptr, m_layout.stride_elements() };
243 update_instance(index, last_instance);
246 glUnmapBuffer(GL_ARRAY_BUFFER);
A vertex buffer object for instanced rendering.
constexpr auto instance_count() const noexcept -> std::int32_t
void resize_buffer(std::size_t old_capacity, std::size_t new_capacity) noexcept
Resize the buffer to the given capacity.
auto delete_instance(std::int32_t index) noexcept -> int32_t
Delete an instance from the buffer, does not preserve the order of the instances.
std::size_t m_capacity
The capacity of the buffer, in bytes.
constexpr auto instance_size() const noexcept -> std::size_t
std::int32_t m_count
The number of instances in the buffer.
~vertex_buffer_inst() noexcept=default
vertex_buffer_inst(std::span< const float > instance_data, vertex_buffer_layout &&layout) noexcept
void add_instance(std::span< const float > instance_data) noexcept
Add an instance to the buffer.
vertex_buffer_inst(std::span< const float > instance_data) noexcept
constexpr auto calc_capacity(std::size_t capacity) const noexcept -> std::size_t
Compute the new capacity of the buffer, given the current capacity.
constexpr auto capacity() const noexcept -> std::size_t
void update_instance(std::int32_t index, std::span< const float > instance_data) noexcept
Update the data of an instance in the buffer.
constexpr auto stride() const noexcept -> std::size_t
Get the stride of the vertex buffer layout.
Vertex Buffer Object (VBO) wrapper.
constexpr auto layout() const -> const vertex_buffer_layout &
vertex_buffer_layout m_layout
staplegl::driver_draw_hint m_hint
constexpr auto size() const noexcept -> std::size_t
Get the number of vertices in the vertex buffer object.
Vertex Buffer Object (VBO) wrapper.
Vertex Buffer Layout abstraction.