3#include "structure/design_pattern/spk_synchronizable_object.hpp"
4#include "structure/opengl/spk_buffer_object.hpp"
5#include "structure/opengl/spk_opengl_includes.hpp"
8#include <initializer_list>
80 friend class VertexBufferObject;
82 std::vector<Attribute> _attributes;
84 const VertexBufferObject *_owner;
86 struct AttributeFormat
95 static size_t _computeStride(
const std::vector<Attribute> &p_attributes);
97 void _configureAttributes();
120 const std::vector<Attribute> &
attributes()
const;
141 void _ensureStrideForLayout(
size_t p_vertexSize);
190 template <
typename TVertex>
196 std::vector<TVertex>
pull()
const
198 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
202 const auto rawData = spk::OpenGLUtils::readBuffer(
static_cast<GLenum
>(
_type),
static_cast<GLuint
>(
_id));
208 if (rawData.size() %
sizeof(TVertex) != 0)
210 throw std::runtime_error(
"VertexBufferObject::pull: GPU buffer size is not a multiple of TVertex");
213 std::vector<TVertex>
vertices(rawData.size() /
sizeof(TVertex));
214 std::memcpy(
vertices.data(), rawData.data(), rawData.size());
218 template <
typename TVertex>
226 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
228 _ensureStrideForLayout(
sizeof(TVertex));
232 template <
typename TVertex>
240 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
242 _ensureStrideForLayout(
sizeof(TVertex));
246 template <
typename TVertex>
254 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
256 _ensureStrideForLayout(
sizeof(TVertex));
260 template <
typename TVertex>
268 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
270 if (p_vertices.empty())
275 _ensureStrideForLayout(
sizeof(TVertex));
279 template <
typename TVertex>
287 static_assert(std::is_trivially_copyable_v<TVertex>,
"VertexBufferObject requires trivially copyable vertex types");
289 if (p_vertices.size() == 0)
294 _ensureStrideForLayout(
sizeof(TVertex));
298 template <
typename TVertex>
310 template <
typename TVertex>
323 using VBO = VertexBufferObject;
Base layout container that arranges resizable elements.
Definition spk_layout.hpp:24
Owns an OpenGL buffer with CPU-side staging and synchronization to GPU.
Definition spk_buffer_object.hpp:33
void reserve(size_t p_size)
Reserves CPU-side storage without changing size.
Definition spk_buffer_object.cpp:104
spk::CachedData< GLuint > _id
Lazily created GPU buffer identifier.
Definition spk_buffer_object.hpp:91
void pushData(const void *p_data, size_t p_size)
Appends raw data to CPU buffer.
Definition spk_buffer_object.cpp:132
Buffer::value_type * data()
Mutable pointer to underlying bytes.
Definition spk_buffer_object.cpp:183
Usage
Usage hints forwarded to the OpenGL driver.
Definition spk_buffer_object.hpp:61
void resize(size_t p_size)
Resizes CPU-side buffer and marks for sync.
Definition spk_buffer_object.cpp:109
void swapData(std::vector< uint8_t > &p_data)
Swaps CPU staging buffer with external vector.
Definition spk_buffer_object.cpp:114
void editData(const void *p_data, size_t p_offset, size_t p_size)
Overwrites a range of the CPU buffer.
Definition spk_buffer_object.cpp:144
size_t size() const
Returns the current CPU buffer size.
Definition spk_buffer_object.cpp:168
Type _type
Buffer target selected at construction.
Definition spk_buffer_object.hpp:83
void setData(const std::vector< TType > &p_data)
Replaces buffer contents with a vector of trivially copyable values.
Definition spk_buffer_object.hpp:154
void addAttribute(Attribute p_attribute)
Adds an attribute definition; synchronizes on apply.
Definition spk_vertex_buffer_object.cpp:147
Layout(const VertexBufferObject *p_owner)
Creates a layout bound to a vertex buffer owner.
Definition spk_vertex_buffer_object.cpp:142
size_t stride() const
Byte stride for each vertex.
Definition spk_vertex_buffer_object.cpp:170
const std::vector< Attribute > & attributes() const
Returns attribute list.
Definition spk_vertex_buffer_object.cpp:165
Convenience wrapper for array buffers with vertex layout management.
Definition spk_vertex_buffer_object.hpp:24
std::span< TVertex > vertices()
Provides mutable access to the CPU-side vertex span.
Definition spk_vertex_buffer_object.hpp:304
void _onSynchronize() override
Uploads vertex data to GPU and configures attributes when requested.
Definition spk_vertex_buffer_object.cpp:188
std::span< const TVertex > vertices() const
Provides immutable access to the CPU-side vertex span.
Definition spk_vertex_buffer_object.hpp:316
Layout & layout()
Access layout descriptor.
Definition spk_vertex_buffer_object.cpp:253
void _ensureStrideForRead(size_t p_vertexSize) const
Validates that the layout stride matches a requested vertex size.
Definition spk_vertex_buffer_object.cpp:194
std::vector< TVertex > pull() const
Downloads vertices from GPU memory.
Definition spk_vertex_buffer_object.hpp:196
VertexBufferObject(Usage p_usage)
Constructs VBO with a usage hint.
Definition spk_vertex_buffer_object.cpp:207
void pushVertex(const TVertex &p_vertex)
Appends a single vertex to the buffer.
Definition spk_vertex_buffer_object.hpp:252
void pushVertices(const std::vector< TVertex > &p_vertices)
Appends multiple vertices to the buffer.
Definition spk_vertex_buffer_object.hpp:266
void pushVertices(std::initializer_list< TVertex > p_vertices)
Appends vertices from an initializer list.
Definition spk_vertex_buffer_object.hpp:285
VertexBufferObject & operator=(const VertexBufferObject &p_other)
Copies GPU handle ownership and layout from another VBO.
Definition spk_vertex_buffer_object.cpp:227
void setVertices(std::initializer_list< TVertex > p_vertices)
Replaces buffer contents with initializer list of vertices.
Definition spk_vertex_buffer_object.hpp:238
size_t vertexCount() const
Number of vertices based on current stride and size.
Definition spk_vertex_buffer_object.cpp:263
void setVertices(const std::vector< TVertex > &p_vertices)
Replaces buffer contents with provided vertices.
Definition spk_vertex_buffer_object.hpp:224
Base for objects requiring deferred synchronization hooks.
Definition spk_synchronizable_object.hpp:10
Describes a vertex attribute entry in the layout.
Definition spk_vertex_buffer_object.hpp:38
Type type
Data interpretation for this attribute.
Definition spk_vertex_buffer_object.hpp:76
Type
Supported attribute data encodings.
Definition spk_vertex_buffer_object.hpp:48
GLuint Index
Attribute location index used for glVertexAttribPointer.
Definition spk_vertex_buffer_object.hpp:42
Index index
Attribute slot index used when enabling the vertex attribute.
Definition spk_vertex_buffer_object.hpp:72