Sparkle 0.0.1
Loading...
Searching...
No Matches
spk_buffer_object.hpp
1#pragma once
2
3#include "structure/design_pattern/spk_activable_object.hpp"
4#include "structure/design_pattern/spk_cached_data.hpp"
5#include "structure/design_pattern/spk_synchronizable_object.hpp"
6#include "structure/opengl/spk_opengl_includes.hpp"
7#include "utils/spk_opengl_utils.hpp"
8#include <cstdint>
9#include <cstring>
10#include <initializer_list>
11#include <stdexcept>
12#include <type_traits>
13#include <utility>
14#include <vector>
15
16namespace spk
17{
18 namespace OpenGL
19 {
33 {
34 private:
37
38 public:
42 enum class Type : GLenum
43 {
44 Unknow = GL_INVALID_ENUM,
45 Storage = GL_ARRAY_BUFFER,
46 Element = GL_ELEMENT_ARRAY_BUFFER,
47 Uniform = GL_UNIFORM_BUFFER,
48 Texture = GL_TEXTURE_BUFFER,
49 TransformFeedback = GL_TRANSFORM_FEEDBACK_BUFFER,
50 ShaderStorage = GL_SHADER_STORAGE_BUFFER,
51 PixelPack = GL_PIXEL_PACK_BUFFER,
52 PixelUnpack = GL_PIXEL_UNPACK_BUFFER,
53 DrawIndirect = GL_DRAW_INDIRECT_BUFFER,
54 AtomicCounter = GL_ATOMIC_COUNTER_BUFFER
55 };
56
60 enum class Usage : GLenum
61 {
62 Unknow = GL_INVALID_ENUM,
63 Static = GL_STATIC_DRAW,
64 Dynamic = GL_DYNAMIC_DRAW,
65 Stream = GL_STREAM_DRAW,
66 StaticRead = GL_STATIC_READ,
67 DynamicRead = GL_DYNAMIC_READ,
68 StreamRead = GL_STREAM_READ,
69 StaticCopy = GL_STATIC_COPY,
70 DynamicCopy = GL_DYNAMIC_COPY,
71 StreamCopy = GL_STREAM_COPY
72 };
73
77 using Buffer = std::vector<uint8_t>;
78
79 protected:
92
96 size_t _gpuCapacity = 0;
101
105 void _registerCallbacks();
106
107 protected:
111 void _onSynchronize() override;
112
113 public:
119 BufferObject(const Type &p_type, const Usage &p_usage);
124 BufferObject(const BufferObject &p_other);
130 BufferObject &operator=(const BufferObject &p_other);
131
136 void reserve(size_t p_size);
141 void resize(size_t p_size);
146 void swapData(std::vector<uint8_t> &p_data);
147
153 template <typename TType>
154 void setData(const std::vector<TType> &p_data)
155 {
156 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::setData requires a trivially copyable type");
157
158 const size_t byteSize = p_data.size() * sizeof(TType);
159 _content.resize(byteSize);
160
161 if (byteSize != 0)
162 {
163 std::memcpy(_content.data(), p_data.data(), byteSize);
164 }
165
167 }
168
174 template <typename TType>
175 void setData(std::initializer_list<TType> p_data)
176 {
177 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::setData requires a trivially copyable type");
178
179 const size_t byteSize = p_data.size() * sizeof(TType);
180 _content.resize(byteSize);
181
182 if (byteSize != 0)
183 {
184 std::memcpy(_content.data(), p_data.begin(), byteSize);
185 }
186
188 }
189
195 void setData(const void *p_data, size_t p_size);
196
202 void pushData(const void *p_data, size_t p_size);
203
209 template <typename TType>
210 void pushData(const TType &p_value)
211 {
212 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::pushData requires a trivially copyable type");
213 pushData(&p_value, sizeof(TType));
214 }
215
221 template <typename TType>
222 void pushData(const std::vector<TType> &p_values)
223 {
224 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::pushData(vector) requires a trivially copyable type");
225
226 if (p_values.empty())
227 {
228 return;
229 }
230
231 pushData(static_cast<const void *>(p_values.data()), p_values.size() * sizeof(TType));
232 }
233
239 template <typename TType>
240 void pushData(std::initializer_list<TType> p_values)
241 {
242 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::pushData(initializer_list) requires a trivially copyable type");
243
244 if (p_values.size() == 0)
245 {
246 return;
247 }
248
249 pushData(static_cast<const void *>(p_values.begin()), p_values.size() * sizeof(TType));
250 }
251
258 void editData(const void *p_data, size_t p_offset, size_t p_size);
259
266 template <typename TType>
267 void editData(const TType &p_value, size_t p_offset)
268 {
269 static_assert(std::is_trivially_copyable_v<TType>, "BufferObject::editData requires a trivially copyable type");
270
271 editData(static_cast<const void *>(&p_value), p_offset, sizeof(TType));
272 }
273
278 size_t size() const;
279
284 Buffer &buffer();
289 const Buffer &buffer() const;
290
295 Buffer::value_type *data();
300 const Buffer::value_type *data() const;
301 };
302 }
303}
Stateful helper toggling between activated/deactivated states.
Definition spk_activable_object.hpp:20
Lazily generates and caches a value with optional custom destructor.
Definition spk_cached_data.hpp:26
size_t _gpuCapacity
Capacity reserved on the GPU for the current buffer.
Definition spk_buffer_object.hpp:96
Buffer & buffer()
Mutable access to the CPU staging buffer.
Definition spk_buffer_object.cpp:173
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
std::vector< uint8_t > Buffer
CPU-side byte buffer used as staging before GPU upload.
Definition spk_buffer_object.hpp:77
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
BufferObject & operator=(const BufferObject &p_other)
Copies buffer configuration and staged content from another buffer.
Definition spk_buffer_object.cpp:74
Buffer _content
CPU staging area mirrored to GPU on synchronization.
Definition spk_buffer_object.hpp:100
Usage
Usage hints forwarded to the OpenGL driver.
Definition spk_buffer_object.hpp:61
void setData(std::initializer_list< TType > p_data)
Replaces buffer contents with an initializer list of values.
Definition spk_buffer_object.hpp:175
void resize(size_t p_size)
Resizes CPU-side buffer and marks for sync.
Definition spk_buffer_object.cpp:109
void pushData(const TType &p_value)
Appends a single trivially copyable value to the buffer.
Definition spk_buffer_object.hpp:210
void swapData(std::vector< uint8_t > &p_data)
Swaps CPU staging buffer with external vector.
Definition spk_buffer_object.cpp:114
void pushData(std::initializer_list< TType > p_values)
Appends an initializer list of trivially copyable values to the buffer.
Definition spk_buffer_object.hpp:240
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
void pushData(const std::vector< TType > &p_values)
Appends a vector of trivially copyable values to the buffer.
Definition spk_buffer_object.hpp:222
BufferObject(const Type &p_type, const Usage &p_usage)
Constructs a buffer with target type and usage hint.
Definition spk_buffer_object.cpp:45
Type
Supported OpenGL binding targets for buffer uploads.
Definition spk_buffer_object.hpp:43
size_t size() const
Returns the current CPU buffer size.
Definition spk_buffer_object.cpp:168
void _onSynchronize() override
Uploads staged data to the GPU when synchronization is requested.
Definition spk_buffer_object.cpp:12
Usage _usage
Driver usage hint selected at construction.
Definition spk_buffer_object.hpp:87
Type _type
Buffer target selected at construction.
Definition spk_buffer_object.hpp:83
void _registerCallbacks()
Registers GPU lifecycle callbacks with the cached buffer id.
Definition spk_buffer_object.cpp:33
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 editData(const TType &p_value, size_t p_offset)
Overwrites part of the buffer with a single value.
Definition spk_buffer_object.hpp:267
Base for objects requiring deferred synchronization hooks.
Definition spk_synchronizable_object.hpp:10
void forceSynchronization()
Forces synchronization regardless of current flag.
Definition spk_synchronizable_object.hpp:54
void requestSynchronization() noexcept
Marks the object as needing synchronization.
Definition spk_synchronizable_object.hpp:23
void synchronize()
Performs synchronization if requested.
Definition spk_synchronizable_object.hpp:40