3#include "structure/container/spk_buffer_layout.hpp"
4#include "structure/opengl/spk_buffer_object.hpp"
5#include "structure/opengl/spk_buffer_set_object.hpp"
6#include "structure/opengl/spk_frame_buffer_object.hpp"
7#include "structure/opengl/spk_program.hpp"
8#include "structure/opengl/spk_sampler_object.hpp"
9#include "structure/opengl/spk_shader_storage_buffer_object.hpp"
10#include "structure/opengl/spk_uniform_buffer_object.hpp"
11#include "structure/opengl/spk_vertex_buffer_object.hpp"
12#include "utils/spk_string_utils.hpp"
20#include <unordered_map>
60 Kind _kind = Kind::None;
61 GLuint _bindingPoint = 0;
62 std::size_t _size = 0;
63 std::variant<std::monostate, spk::OpenGL::UBO, spk::OpenGL::SSBO, spk::OpenGL::SamplerObject> _data;
65 template <
typename TCallable>
66 void _withResource(TCallable &&p_callable)
69 [&](
auto &p_resource) {
70 using ResourceType = std::decay_t<
decltype(p_resource)>;
71 if constexpr (std::is_same_v<ResourceType, std::monostate>)
73 throw std::runtime_error(
"Pipeline constant not initialized");
77 p_callable(p_resource);
83 template <
typename TResource>
86 if (
auto ptr = std::get_if<TResource>(&_data))
90 throw std::runtime_error(
"Pipeline constant does not hold requested resource type");
93 template <
typename TResource>
94 const TResource &_get()
const
96 if (
auto ptr = std::get_if<TResource>(&_data))
100 throw std::runtime_error(
"Pipeline constant does not hold requested resource type");
135 return _bindingPoint;
141 std::size_t
size() const noexcept
155 _bindingPoint = p_bindingPoint;
157 _data.emplace<spk::OpenGL::UBO>(p_bindingPoint, p_usage, p_size);
169 _bindingPoint = p_bindingPoint;
171 _data.emplace<spk::OpenGL::SSBO>(p_bindingPoint, p_usage, p_size);
179 void setSampler(GLint p_uniformLocation, GLuint p_textureUnitIndex)
181 _kind = Kind::Sampler;
182 _bindingPoint = p_textureUnitIndex;
192 _withResource([](
auto &p_resource) {
193 p_resource.activate();
202 _withResource([](
auto &p_resource) {
203 p_resource.deactivate();
213 return _get<spk::OpenGL::UBO>();
219 const spk::OpenGL::UBO &
ubo()
const
221 return _get<spk::OpenGL::UBO>();
230 return _get<spk::OpenGL::SSBO>();
236 const spk::OpenGL::SSBO &
ssbo()
const
238 return _get<spk::OpenGL::SSBO>();
247 return _get<spk::OpenGL::SamplerObject>();
255 return _get<spk::OpenGL::SamplerObject>();
262 operator spk::OpenGL::UBO &()
264 return _get<spk::OpenGL::UBO>();
271 operator const spk::OpenGL::UBO &()
const
273 return _get<spk::OpenGL::UBO>();
280 operator spk::OpenGL::SSBO &()
282 return _get<spk::OpenGL::SSBO>();
289 operator const spk::OpenGL::SSBO &()
const
291 return _get<spk::OpenGL::SSBO>();
300 return _get<spk::OpenGL::SamplerObject>();
309 return _get<spk::OpenGL::SamplerObject>();
325 friend class Pipeline;
347 Kind _kind = Kind::None;
348 GLuint _bindingPoint = 0;
349 std::size_t _size = 0;
350 GLint _uniformLocation = -1;
351 std::variant<std::monostate, spk::OpenGL::UBO, spk::OpenGL::SSBO, spk::OpenGL::SamplerObject> _resource;
353 template <
typename TResource>
354 TResource &_getResource()
356 if (
auto ptr = std::get_if<TResource>(&_resource))
360 throw std::runtime_error(
"Pipeline attribute does not hold requested resource type");
363 template <
typename TResource>
364 const TResource &_getResource()
const
366 if (
auto ptr = std::get_if<TResource>(&_resource))
370 throw std::runtime_error(
"Pipeline attribute does not hold requested resource type");
416 return _bindingPoint;
423 std::size_t
size() const noexcept
434 return _uniformLocation;
446 _bindingPoint = p_bindingPoint;
448 _resource.emplace<spk::OpenGL::UBO>(p_bindingPoint, p_usage, p_size);
460 _bindingPoint = p_bindingPoint;
462 _resource.emplace<spk::OpenGL::SSBO>(p_bindingPoint, p_usage, p_size);
470 void setSampler(GLint p_uniformLocation, GLuint p_textureUnitIndex)
472 _kind = Kind::Sampler;
473 _bindingPoint = p_textureUnitIndex;
475 _uniformLocation = p_uniformLocation;
485 [](
auto &p_resource) {
486 using ResourceType = std::decay_t<
decltype(p_resource)>;
487 if constexpr (std::is_same_v<ResourceType, std::monostate>)
493 p_resource.activate();
505 [](
auto &p_resource) {
506 using ResourceType = std::decay_t<
decltype(p_resource)>;
507 if constexpr (std::is_same_v<ResourceType, std::monostate>)
513 p_resource.deactivate();
525 return _getResource<spk::OpenGL::UBO>();
532 const spk::OpenGL::UBO &
ubo()
const
534 return _getResource<spk::OpenGL::UBO>();
543 return _getResource<spk::OpenGL::SSBO>();
550 const spk::OpenGL::SSBO &
ssbo()
const
552 return _getResource<spk::OpenGL::SSBO>();
561 return _getResource<spk::OpenGL::SamplerObject>();
570 return _getResource<spk::OpenGL::SamplerObject>();
578 template <
typename TResourceType>
582 std::is_same_v<TResourceType, spk::OpenGL::UBO> ||
583 std::is_same_v<TResourceType, spk::OpenGL::SSBO> ||
584 std::is_same_v<TResourceType, spk::OpenGL::SamplerObject>,
585 "Pipeline::Object::Attribute::as only supports UBO, SSBO, or SamplerObject");
587 return _getResource<TResourceType>();
595 template <
typename TResourceType>
596 const TResourceType &
as()
const
599 std::is_same_v<TResourceType, spk::OpenGL::UBO> ||
600 std::is_same_v<TResourceType, spk::OpenGL::SSBO> ||
601 std::is_same_v<TResourceType, spk::OpenGL::SamplerObject>,
602 "Pipeline::Object::Attribute::as only supports UBO, SSBO, or SamplerObject");
604 return _getResource<TResourceType>();
609 Pipeline *_owner =
nullptr;
610 std::shared_ptr<spk::OpenGL::BufferSetObject> _bufferSet =
nullptr;
611 std::unordered_map<std::wstring, Attribute> _attributes;
613 explicit Object(Pipeline *p_owner) :
616 _attributes(_owner->_constructObjectAttributes())
630 void render(GLsizei p_instanceCount = 1);
636 std::shared_ptr<spk::OpenGL::BufferSetObject> &
bufferSet()
645 const std::shared_ptr<spk::OpenGL::BufferSetObject> &
bufferSet()
const
654 void setBufferSet(
const std::shared_ptr<spk::OpenGL::BufferSetObject> &p_bufferSet)
656 _bufferSet = p_bufferSet;
667 return _attribute(p_name);
678 return _attribute(p_name);
682 Attribute &_attribute(
const std::wstring &p_name)
684 if (_attributes.contains(p_name) ==
false)
686 throw std::runtime_error(
"No attribute [" + spk::StringUtils::wstringToString(p_name) +
"] created in pipeline");
688 return _attributes.at(p_name);
691 const Attribute &_attribute(
const std::wstring &p_name)
const
693 if (_attributes.contains(p_name) ==
false)
695 throw std::runtime_error(
"No attribute [" + spk::StringUtils::wstringToString(p_name) +
"] created in pipeline");
697 return _attributes.at(p_name);
706 static std::unordered_map<std::wstring, Constant> _constants;
707 static GLuint _nextBindingPoint;
709 std::unique_ptr<State> _state;
711 void _ensureBlockBindingsLinked();
714 void _activateConstants();
715 void _deactivateConstants();
716 void _render(GLsizei p_indexCount, GLsizei p_instanceCount);
718 std::unordered_map<std::wstring, Object::Attribute> _constructObjectAttributes()
const;
719 spk::OpenGL::BufferSetObject _constructObjectBufferSet()
const;
721 explicit Pipeline(std::unique_ptr<State> p_state);
728 explicit Pipeline(
const std::string &p_input);
740 Pipeline &
operator=(Pipeline &&p_other)
noexcept =
default;
741 Pipeline(
const Pipeline &) =
delete;
742 Pipeline &
operator=(
const Pipeline &) =
delete;
748 static Pipeline
fromFile(
const std::filesystem::path &p_filePath);
Encapsulates a shader resource (UBO, SSBO, or sampler) bound by a pipeline.
Definition spk_pipeline.hpp:45
Constant()=default
Default constructor for an empty constant.
Constant(Constant &&)=default
Move-constructs a constant, transferring ownership of the underlying resource.
Constant & operator=(Constant &&)=default
Move-assigns from another constant instance.
const spk::OpenGL::UBO & ubo() const
Accesses the constant as a uniform buffer object.
Definition spk_pipeline.hpp:219
std::size_t size() const noexcept
Size of the buffer-backed constant in bytes.
Definition spk_pipeline.hpp:141
spk::OpenGL::SamplerObject & sampler()
Accesses the constant as a sampler object.
Definition spk_pipeline.hpp:245
Kind kind() const noexcept
Reports the currently configured resource type.
Definition spk_pipeline.hpp:125
void setSampler(GLint p_uniformLocation, GLuint p_textureUnitIndex)
Initializes the constant as a sampler bound to a texture unit.
Definition spk_pipeline.hpp:179
void deactivate()
Deactivates the underlying resource on the GPU.
Definition spk_pipeline.hpp:200
const spk::OpenGL::SamplerObject & sampler() const
Accesses the constant as a sampler object.
Definition spk_pipeline.hpp:253
void activate()
Activates the underlying resource on the GPU.
Definition spk_pipeline.hpp:190
GLuint bindingPoint() const noexcept
Binding slot used when the constant represents a buffer or sampler.
Definition spk_pipeline.hpp:133
Kind
Enumerates the supported constant types.
Definition spk_pipeline.hpp:52
void setUBO(GLuint p_bindingPoint, std::size_t p_size, spk::OpenGL::BufferObject::Usage p_usage)
Initializes the constant as a uniform buffer.
Definition spk_pipeline.hpp:152
spk::OpenGL::UBO & ubo()
Accesses the constant as a uniform buffer object.
Definition spk_pipeline.hpp:211
const spk::OpenGL::SSBO & ssbo() const
Accesses the constant as a shader storage buffer object.
Definition spk_pipeline.hpp:236
spk::OpenGL::SSBO & ssbo()
Accesses the constant as a shader storage buffer object.
Definition spk_pipeline.hpp:228
void setSSBO(GLuint p_bindingPoint, std::size_t p_size, spk::OpenGL::BufferObject::Usage p_usage)
Initializes the constant as a shader storage buffer.
Definition spk_pipeline.hpp:166
Attribute instance holding shared OpenGL resources.
Definition spk_pipeline.hpp:332
Attribute(const Attribute &p_other)=default
Copies an attribute and its resource handle.
GLuint bindingPoint() const noexcept
Returns the binding point associated with this attribute.
Definition spk_pipeline.hpp:414
Kind
Enumerates supported attribute resource types.
Definition spk_pipeline.hpp:339
std::size_t size() const noexcept
Returns the attribute resource size in bytes.
Definition spk_pipeline.hpp:423
Attribute(Attribute &&p_other) noexcept=default
Moves an attribute and its resource handle.
TResourceType & as()
Returns the attribute as the requested resource type.
Definition spk_pipeline.hpp:579
void setUBO(GLuint p_bindingPoint, std::size_t p_size, spk::OpenGL::BufferObject::Usage p_usage)
Configures the attribute as a UBO resource.
Definition spk_pipeline.hpp:443
const spk::OpenGL::SamplerObject & sampler() const
Returns the attribute as a sampler resource.
Definition spk_pipeline.hpp:568
Attribute()=default
Builds an empty attribute with no bound resource.
const spk::OpenGL::UBO & ubo() const
Returns the attribute as a UBO resource.
Definition spk_pipeline.hpp:532
const TResourceType & as() const
Returns the attribute as the requested resource type.
Definition spk_pipeline.hpp:596
void deactivate()
Deactivates the underlying resource after rendering.
Definition spk_pipeline.hpp:502
spk::OpenGL::SSBO & ssbo()
Returns the attribute as an SSBO resource.
Definition spk_pipeline.hpp:541
void setSampler(GLint p_uniformLocation, GLuint p_textureUnitIndex)
Configures the attribute as a sampler resource.
Definition spk_pipeline.hpp:470
GLint uniformLocation() const noexcept
Returns the uniform location for sampler attributes.
Definition spk_pipeline.hpp:432
Kind kind() const noexcept
Returns the attribute resource kind.
Definition spk_pipeline.hpp:405
Attribute & operator=(const Attribute &p_other)=default
Copies an attribute and its resource handle.
const spk::OpenGL::SSBO & ssbo() const
Returns the attribute as an SSBO resource.
Definition spk_pipeline.hpp:550
spk::OpenGL::SamplerObject & sampler()
Returns the attribute as a sampler resource.
Definition spk_pipeline.hpp:559
void activate()
Activates the underlying resource for rendering.
Definition spk_pipeline.hpp:482
void setSSBO(GLuint p_bindingPoint, std::size_t p_size, spk::OpenGL::BufferObject::Usage p_usage)
Configures the attribute as an SSBO resource.
Definition spk_pipeline.hpp:457
spk::OpenGL::UBO & ubo()
Returns the attribute as a UBO resource.
Definition spk_pipeline.hpp:523
Attribute & operator=(Attribute &&p_other) noexcept=default
Moves an attribute and its resource handle.
Represents a drawable entity configured with pipeline attributes.
Definition spk_pipeline.hpp:324
std::shared_ptr< spk::OpenGL::BufferSetObject > & bufferSet()
Provides mutable access to the buffer set associated with this object.
Definition spk_pipeline.hpp:636
void render(GLsizei p_instanceCount=1)
Issues a draw call using the object's buffers and configured attributes.
Definition spk_pipeline.cpp:973
void setBufferSet(const std::shared_ptr< spk::OpenGL::BufferSetObject > &p_bufferSet)
Replaces the buffer set used by this object.
Definition spk_pipeline.hpp:654
Object()=default
Constructs an empty pipeline object; attributes become available after assignment from createObject()...
const Attribute & attribute(const std::wstring &p_name) const
Retrieves a named attribute configured on the pipeline.
Definition spk_pipeline.hpp:676
const std::shared_ptr< spk::OpenGL::BufferSetObject > & bufferSet() const
Provides read-only access to the object's buffer set.
Definition spk_pipeline.hpp:645
Attribute & attribute(const std::wstring &p_name)
Retrieves a named attribute configured on the pipeline.
Definition spk_pipeline.hpp:665
Pipeline & operator=(Pipeline &&p_other) noexcept=default
Move-assigns pipeline ownership.
static bool containConstant(const std::wstring &p_name)
Check if the constant defined by name exist in the global registry.
Definition spk_pipeline.cpp:803
static Pipeline fromFile(const std::filesystem::path &p_filePath)
Loads a pipeline definition from disk.
Definition spk_pipeline.cpp:729
std::shared_ptr< spk::OpenGL::BufferSetObject > createBufferSet() const
Creates a buffer set matching the pipeline's vertex layout.
Definition spk_pipeline.cpp:754
Pipeline(Pipeline &&p_other) noexcept=default
Moves pipeline ownership to a new instance.
static Constant & insertConstant(const std::string &p_jsonBlock)
Inserts a global constant from a JSON description block.
Definition spk_pipeline.cpp:759
static Constant & getOrCreateConstant(const std::string &p_jsonBlock)
Retrieves or creates a constant from a JSON description block.
Definition spk_pipeline.cpp:821
spk::OpenGL::FrameBufferObject & frameBuffer(const std::wstring &p_name)
Accesses a framebuffer configured on the pipeline.
Definition spk_pipeline.cpp:852
Object createObject()
Instantiates a drawable object using the pipeline layout.
Definition spk_pipeline.cpp:749
static Constant & constant(const std::wstring &p_name)
Retrieves a mutable constant defined by name in the global registry.
Definition spk_pipeline.cpp:808
Usage
Usage hints forwarded to the OpenGL driver.
Definition spk_buffer_object.hpp:61
RAII wrapper for an OpenGL framebuffer with typed attachments.
Definition spk_frame_buffer_object.hpp:31
Binds a TextureObject to a uniform sampler location and texture unit.
Definition spk_sampler_object.hpp:18