12#ifndef GAMP_GLSLSHADERPROGRAM_HPP_
13#define GAMP_GLSLSHADERPROGRAM_HPP_
15#include <unordered_set>
27 using namespace gamp::render::gl;
39 struct Private{
explicit Private() =
default; };
44 : m_programLinked(
false), m_programInUse(
false), m_shaderProgram(0), m_id(0) {
48 return std::make_shared<ShaderProgram>(Private());
51 constexpr bool linked() const noexcept {
return m_programLinked; }
53 constexpr bool inUse() const noexcept {
return m_programInUse; }
56 constexpr GLuint
program() const noexcept {
return m_shaderProgram; }
59 constexpr size_t id() const noexcept {
return m_id; }
88 if( m_programLinked ) {
91 for(
const auto & shaderCode : m_allShaderCode) {
92 if( 1 == m_attachedShaderCode.erase(shaderCode) ) {
95 if(destroyShaderCode) {
96 shaderCode->destroy(
gl);
99 m_allShaderCode.clear();
100 m_attachedShaderCode.clear();
101 if( 0 != m_shaderProgram ) {
102 glDeleteProgram(m_shaderProgram);
105 m_programLinked=
false;
121 auto res = m_allShaderCode.insert(shaderCode);
126 return m_allShaderCode.contains(shaderCode);
135 for(
const auto & shaderCode : m_allShaderCode) {
136 if(shaderCode->id() ==
id) {
155 if( 0 == m_shaderProgram ) {
156 m_shaderProgram = glCreateProgram();
158 return 0 != m_shaderProgram;
169 if( !
init(
gl) ) {
return false; }
170 if( m_allShaderCode.insert(shaderCode).second ) {
171 if( !shaderCode->compile(
gl,
verbose) ) {
174 if( m_attachedShaderCode.insert(shaderCode).second ) {
205 const bool shaderWasInUse =
inUse();
210 if( 1 == m_allShaderCode.erase(oldShader) && 1 == m_attachedShaderCode.erase(oldShader) ) {
215 if( m_attachedShaderCode.insert(newShader).second ) {
219 glLinkProgram(m_shaderProgram);
222 if ( m_programLinked && shaderWasInUse ) {
225 return m_programLinked;
243 m_programLinked =
false;
247 for(
const auto & shaderCode : m_allShaderCode) {
249 m_programLinked =
false;
252 if( m_attachedShaderCode.insert(shaderCode).second ) {
258 glLinkProgram(m_shaderProgram);
262 return m_programLinked;
266 if(
this==&rhs) {
return true; }
267 return m_id == rhs.m_id;
269 constexpr std::size_t
hash_code() const noexcept {
return m_id; }
273 sb.append(std::to_string(m_id))
274 .append(
", linked=").append(std::to_string(m_programLinked))
275 .append(
", inUse=").append(std::to_string(m_programInUse))
276 .append(
", program: ").append(std::to_string(m_shaderProgram)).append(
", ")
277 .append(std::to_string(m_allShaderCode.size())).append(
" code: ");
278 if( 0 < m_allShaderCode.size() ) {
279 for(
const auto & iter : m_allShaderCode) {
280 sb.append(
"\n").append(
" ").append(iter->toString());
304 if(on && !m_programLinked) {
308 if(m_programInUse==on) {
return; }
309 if( 0 == m_shaderProgram ) {
312 glUseProgram( on ? m_shaderProgram : 0 );
319 if(!m_programInUse) {
return; }
321 m_programInUse =
false;
324 m_programInUse =
false;
330 for(
const auto & iter : m_allShaderCode) {
337 bool m_programLinked;
339 GLuint m_shaderProgram;
341 std::unordered_set<ShaderCodeRef> m_allShaderCode, m_attachedShaderCode;
343 static size_t nextID() {
return m_nextID++; }
344 static std::atomic<size_t> m_nextID;
363 return a.hash_code();
368 return a->hash_code();
constexpr std::size_t hash_code() const noexcept
void unUseProgram(const GL &) noexcept
Disabled the shader program.
bool init(const GL &) noexcept
Creates the empty GL program object using GL2ES2#glCreateProgram(), if not already created.
constexpr size_t id() const noexcept
Returns the unique program id for successfully created instances, zero if instance creation failed.
void release(GL &gl) noexcept
Detaches all shader codes and deletes the program, but leaves the shader code intact.
string_t toString() const
void release(GL &gl, bool destroyShaderCode) noexcept
Detaches all shader codes and deletes the program.
constexpr GLuint program() const noexcept
Returns the shader program name, which is non zero if valid.
constexpr bool linked() const noexcept
ShaderProgram(Private) noexcept
Private ctor for `ShaderProgramRef create(...).
bool link(GL &gl, bool verbose=false)
Links the shader code to the program.
void destroy(GL &gl) noexcept
Detaches all shader codes and deletes the program.
void notifyNotInUse() noexcept
bool add(GL &gl, const ShaderCodeRef &shaderCode, bool verbose=false)
Adds a new shader to a this non running program.
static ShaderProgramRef create() noexcept
void useProgram(const GL &, bool on)
Enables or disabled the shader program.
constexpr bool operator==(const ShaderProgram &rhs) const noexcept
bool add(const ShaderCodeRef &shaderCode) noexcept
Adds a new shader to this program.
bool replaceShader(GL &gl, const ShaderCodeRef &oldShader, const ShaderCodeRef &newShader, bool verbose=false)
Replace a shader in a program and re-links the program.
bool contains(const ShaderCodeRef &shaderCode) const noexcept
constexpr bool inUse() const noexcept
bool validateProgram(GL &gl, bool verbose=false) noexcept
Performs GL2ES2#glValidateProgram(int) via ShaderUtil#isProgramExecStatusValid(GL,...
ShaderCodeRef getShader(size_t id) noexcept
Warning slow O(n) operation .
static void attachShader(GL &, GLuint program, const shader_list_t &shaders) noexcept
static void detachShader(GL &, GLuint program, const shader_list_t &shaders) noexcept
static bool isProgramExecStatusValid(GL &gl, GLuint programObj, bool verbose=false) noexcept
Performs GL2ES2#glValidateProgram(int).
static bool isProgramLinkStatusValid(GL &gl, GLuint programObj, bool verbose=false) noexcept
#define ERR_PRINT(...)
Use for unconditional error messages, prefix '[elapsed_time] Error @ FILE:LINE FUNC: '.
std::ostream & operator<<(std::ostream &os, const T v)
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::shared_ptr< ShaderCode > ShaderCodeRef
@ verbose
Verbose operations (debugging).
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
void PLAIN_PRINT(const bool printPrefix, const char *format,...) noexcept
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
std::size_t operator()(gamp::render::gl::glsl::ShaderProgramRef const &a) const noexcept
std::size_t operator()(gamp::render::gl::glsl::ShaderProgram const &a) const noexcept