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<ShaderCodeSRef> 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.
ShaderCodeSRef getShader(size_t id) noexcept
Warning slow O(n) operation .
bool init(const GL &) noexcept
Creates the empty GL program object using GL2ES2#glCreateProgram(), if not already created.
static ShaderProgramSRef create() noexcept
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.
bool replaceShader(GL &gl, const ShaderCodeSRef &oldShader, const ShaderCodeSRef &newShader, bool verbose=false)
Replace a shader in a program and re-links the program.
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(const ShaderCodeSRef &shaderCode) noexcept
Adds a new shader to this program.
bool contains(const ShaderCodeSRef &shaderCode) const noexcept
void useProgram(const GL &, bool on)
Enables or disabled the shader program.
constexpr bool operator==(const ShaderProgram &rhs) const noexcept
constexpr bool inUse() const noexcept
bool validateProgram(GL &gl, bool verbose=false) noexcept
Performs GL2ES2#glValidateProgram(int) via ShaderUtil#isProgramExecStatusValid(GL,...
bool add(GL &gl, const ShaderCodeSRef &shaderCode, bool verbose=false)
Adds a new shader to a this non running program.
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 jau_PLAIN_PRINT(printPrefix, fmt,...)
Use for unconditional plain messages, prefix '[elapsed_time] ' if printPrefix == true.
#define jau_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< ShaderCode > ShaderCodeSRef
std::shared_ptr< ShaderProgram > ShaderProgramSRef
@ verbose
Verbose operations (debugging).
Gamp: Graphics, Audio, Multimedia and Processing Framework (Native C++, WebAssembly,...
std::size_t operator()(gamp::render::gl::glsl::ShaderProgramSRef const &a) const noexcept
std::size_t operator()(gamp::render::gl::glsl::ShaderProgram const &a) const noexcept