12#ifndef GAMP_GLSLSHADERSTATE_HPP_
13#define GAMP_GLSLSHADERSTATE_HPP_
30 using namespace gamp::render::gl;
31 using namespace gamp::render::gl::data;
85 if(m_shaderProgram->linked()) {
86 m_shaderProgram->useProgram(
gl,
true);
87 if(m_resetAllShaderData) {
88 resetAllAttributes(
gl);
92 if(m_resetAllShaderData) {
95 if(!m_shaderProgram->link(
gl,
verbose())) {
98 m_shaderProgram->useProgram(
gl,
true);
99 if(m_resetAllShaderData) {
100 resetAllUniforms(
gl);
103 m_resetAllShaderData =
false;
105 m_shaderProgram->useProgram(
gl,
false);
111 return m_shaderProgram ? m_shaderProgram->linked() :
false;
116 return m_shaderProgram ? m_shaderProgram->inUse() :
false;
137 const size_t curId = m_shaderProgram ? m_shaderProgram->id() : 0;
138 const size_t newId = prog ? prog->id() : 0;
139 jau::INFO_PRINT(
"ShaderState: attachShaderProgram: %zu -> %zu (enable: %d)\n\t%s\n\t%s",
140 curId, newId, enable,
141 (m_shaderProgram ? m_shaderProgram->toString().c_str() :
"null"),
142 (prog ? prog->toString().c_str() :
"null"));
144 if(m_shaderProgram) {
145 if(m_shaderProgram == prog) {
151 jau::INFO_PRINT(
"ShaderState: attachShaderProgram: No switch, equal id: %zu , enabling %d",
152 m_shaderProgram->id(), enable);
156 if(m_shaderProgram->inUse()) {
158 m_shaderProgram->notifyNotInUse();
164 m_resetAllShaderData =
true;
168 m_shaderProgram = prog;
170 if(m_shaderProgram) {
173 if(m_resetAllShaderData || enable) {
217 void release(
GL&
gl,
bool destroyBoundAttributes,
bool destroyShaderProgram,
bool destroyShaderCode) {
218 if(m_shaderProgram && m_shaderProgram->linked() ) {
219 m_shaderProgram->useProgram(
gl,
false);
221 if(destroyBoundAttributes) {
228 if(m_shaderProgram && destroyShaderProgram) {
229 m_shaderProgram->release(
gl, destroyShaderCode);
249 return m_activeAttribLocationMap.get(
name);
268 return m_activeAttribDataMap.get(
name);
272 return attribute == m_activeAttribDataMap.get(attribute->name());
302 attr->setLocation(location);
304 m_managedAttributes.push_back(attr);
306 std::erase(m_managedAttributes, attr);
308 attr->associate(*
this, own);
312 return m_managedAttributes.end() != std::find(m_managedAttributes.begin(), m_managedAttributes.end(), attribute);
330 m_activeAttribLocationMap.put(
name, location);
331 ::glBindAttribLocation(m_shaderProgram->program(), location,
name.c_str());
352 m_activeAttribLocationMap.put(
name, location);
353 attr->setLocation(
gl, m_shaderProgram->program(), location);
354 m_activeAttribDataMap.put(
name, attr);
355 ::glBindAttribLocation(m_shaderProgram->program(), location,
name.c_str());
379 location = ::glGetAttribLocation(m_shaderProgram->program(),
name.c_str());
381 m_activeAttribLocationMap.put(
name, location);
386 jau::INFO_PRINT(
"ShaderState: glGetAttribLocation failed, no location for: %s, loc: %d",
name.c_str(), location);
416 data->setLocation(location);
419 location =
data->setLocation(
gl, m_shaderProgram->program());
421 m_activeAttribLocationMap.put(
name, location);
423 jau::INFO_PRINT(
"ShaderState: glGetAttribLocation: %s, loc: %d",
data->name().c_str(), location);
426 jau::INFO_PRINT(
"ShaderState: glGetAttribLocation failed, no location for: %s",
data->name().c_str());
429 m_activeAttribDataMap.put(
data->name(),
data);
441 return m_enabledAttribDataMap.get(
name);
452 bool enableVertexAttribArray(
const GL&
gl,
const string_t&
name, GLint location) {
453 m_enabledAttribDataMap.
put(
name,
true);
458 jau::INFO_PRINT(
"ShaderState: glEnableVertexAttribArray failed, no location for: %s",
name.c_str());
464 jau::INFO_PRINT(
"ShaderState: glEnableVertexAttribArray: %s, loc: %d",
name.c_str(), location);
466 ::glEnableVertexAttribArray(location);
490 return enableVertexAttribArray(
gl,
name, -1);
516 if(0 >
data->location()) {
520 m_activeAttribDataMap.put(
data->name(),
data);
522 return enableVertexAttribArray(
gl,
data->name(),
data->location());
526 bool disableVertexAttribArray(
const GL&
gl,
const string_t&
name, GLint location) {
527 m_enabledAttribDataMap.
put(
name,
false);
532 jau::INFO_PRINT(
"ShaderState: glDisableVertexAttribArray failed, no location for: %s",
name.c_str());
538 jau::INFO_PRINT(
"ShaderState: glDisableVertexAttribArray: %s, %d",
name.c_str(), location);
540 ::glDisableVertexAttribArray(location);
565 return disableVertexAttribArray(
gl,
name, -1);
590 if(0 >
data->location()) {
593 return disableVertexAttribArray(
gl,
data->name(),
data->location());
615 GLint location =
data->location();
621 jau::INFO_PRINT(
"ShaderState: glVertexAttribPointer failed, no location for: %s",
data->name().c_str());
627 jau::INFO_PRINT(
"ShaderState: glVertexAttribPointer: %s, location %d",
data->name().c_str(), location);
629 data->glVertexAttribPointer(
gl);
647 if(m_shaderProgram) {
648 for (
const std::pair<const std::string, GLArrayDataRef>& n : m_activeAttribDataMap.map()) {
649 disableVertexAttribArray(
gl, n.second);
652 m_activeAttribDataMap.clear();
653 m_enabledAttribDataMap.clear();
654 m_activeAttribLocationMap.clear();
655 m_managedAttributes.clear();
676 for (
const std::pair<const std::string, bool>& n : m_enabledAttribDataMap.map()) {
678 if(removeFromState) {
679 m_enabledAttribDataMap.remove(
name);
683 ::glDisableVertexAttribArray(index);
692 const GLint loc = attribute.
setLocation(
gl, m_shaderProgram->program());
694 m_activeAttribLocationMap.
put(
name, loc);
700 ::glEnableVertexAttribArray(loc);
703 if( attribute.
isVBO() ) {
704 ::glBindBuffer(GL_ARRAY_BUFFER, attribute.
vboName());
706 ::glBindBuffer(GL_ARRAY_BUFFER, 0);
734 void resetAllAttributes(
const GL& gl) {
735 if(!m_shaderProgram->linked())
throw RenderException(
"Program is not linked",
E_FILE_LINE);
736 m_activeAttribLocationMap.clear();
741 for (
const std::pair<const std::string, GLArrayDataRef>& n : m_activeAttribDataMap.map()) {
742 relocateAttribute(gl, *n.second);
746 void setAttribute(
const GL& gl,
const GLArrayData& attribute) {
749 const GLint loc = attribute.
location();
756 ::glEnableVertexAttribArray(loc);
759 if( attribute.
isVBO() ) {
760 ::glBindBuffer(GL_ARRAY_BUFFER, attribute.
vboName());
762 ::glBindBuffer(GL_ARRAY_BUFFER, 0);
772 void setAllAttributes(
const GL& gl) {
773 for (
const std::pair<const std::string, GLArrayDataRef>& n : m_activeAttribDataMap.map()) {
774 setAttribute(gl, *n.second);
790 return m_activeUniformLocationMap.get(
name);
811 data->setLocation(location);
813 m_activeUniformDataMap.put(
data->name(),
data);
814 m_managedUniforms.push_back(
data);
816 m_activeUniformDataMap.remove(
data->name());
817 std::erase(m_managedUniforms,
data);
822 return m_managedUniforms.end() != std::find(m_managedUniforms.begin(), m_managedUniforms.end(), uniform);
849 location = ::glGetUniformLocation(m_shaderProgram->program(),
name.c_str());
851 m_activeUniformLocationMap.put(
name, location);
884 data->setLocation(location);
887 location =
data->setLocation(
gl, m_shaderProgram->program());
889 m_activeUniformLocationMap.put(
name, location);
891 jau::INFO_PRINT(
"ShaderState: glUniform failed, no location for: %s",
data->name().c_str());
894 m_activeUniformDataMap.put(
name,
data);
916 GLint location =
data->location();
922 jau::INFO_PRINT(
"ShaderState: glUniform failed, no location for: %s",
data->name().c_str());
928 jau::INFO_PRINT(
"ShaderState: glUniform: %s, location %d",
data->name().c_str(), location);
941 for (
const std::pair<const std::string, GLUniformDataRef>& n : m_activeUniformDataMap.map()) {
953 return m_activeUniformDataMap.get(
name);
961 m_activeUniformDataMap.clear();
962 m_activeUniformLocationMap.clear();
963 m_managedUniforms.clear();
982 void resetAllUniforms(
const GL&
gl) {
984 m_activeUniformLocationMap.
clear();
988 for (
const std::pair<const std::string, GLUniformDataRef>& n : m_activeUniformDataMap.
map()) {
990 GLint loc =
data->setLocation(
gl, m_shaderProgram->program());
993 m_activeUniformLocationMap.
put(
data->name(), loc);
1005 sb.append(
"ShaderState[\n ");
1006 if(m_shaderProgram) {
1007 sb.append(m_shaderProgram->toString());
1009 sb.append(
"ShaderProgram: null");
1011 sb.append(
"\n").append(
" enabledAttributes [");
1012 for (
const std::pair<const std::string, bool>& n : m_enabledAttribDataMap.map()) {
1013 sb.append(
"\n ").append(n.first).append(
": ").append(n.second?
"enabled":
"disabled");
1015 sb.append(
"\n ],").append(
" activeAttributes [");
1016 for (
const std::pair<const std::string, GLArrayDataRef>& n : m_activeAttribDataMap.map()) {
1017 if( alsoUnlocated || 0 <= n.second->location() ) {
1018 sb.append(
"\n ").append(n.second->toString());
1021 sb.append(
"\n ],").append(
" managedAttributes [");
1023 if( alsoUnlocated || 0 <= ad->location() ) {
1024 sb.append(
"\n ").append(ad->toString());
1027 sb.append(
"\n ],").append(
" activeUniforms [");
1028 for (
const std::pair<const std::string, GLUniformDataRef>& n : m_activeUniformDataMap.map()) {
1030 if( alsoUnlocated || 0 <= ud->location() ) {
1031 sb.append(
"\n ").append(ud->toString());
1034 sb.append(
"\n ],").append(
" managedUniforms [");
1036 if( alsoUnlocated || 0 <= ud->location() ) {
1037 sb.append(
"\n ").append(ud->toString());
1040 sb.append(
"\n ]").append(
"\n]");
1045 bool m_verbose =
false;
1047 bool m_resetAllShaderData =
false;
1052 std::vector<GLArrayDataRef> m_managedAttributes;
1056 std::vector<GLUniformDataRef> m_managedUniforms;
void clear()
Clears the hash map.
jau::StringHashMap< Value_type > & map() noexcept
Value_type put(std::string_view key, const Value_type &obj)
Maps the value for the given name, overwrites old mapping if exists.
Interface for a generic data buffer to be used for OpenGL arrays.
virtual std::string toString() const noexcept
constexpr const std::string & name() const noexcept
The name of the reflecting shader array attribute.
void glVertexAttribPointer(const GL &) const noexcept
Associates the vboName() buffer as an vertex attribute on the GPU, or sends the data if !...
constexpr GLuint vboName() const noexcept
The VBO name or 0 if not a VBO.
constexpr bool isVBO() const noexcept
Determines whether the data is server side (VBO) and enabled, or a client side array (false).
constexpr GLint location() const noexcept
Returns the shader attribute location for this name, -1 if not yet determined.
void setLocation(GLint loc) noexcept
Sets the given location of the shader attribute.
ShaderState allows to sharing data between shader programs, while updating the attribute and uniform ...
AttachableRef attachObject(std::string_view key, const AttachableRef &obj)
Attaches user object for the given name, overwrites old mapping if exists.
void bindAttribLocation(const GL &, GLint location, const string_t &name)
Binds a shader attribute to a location.
bool vertexAttribPointer(const GL &gl, const GLArrayDataRef &data)
Set the GLArrayData vertex attribute data, if it's location is valid, i.e.
bool enableVertexAttribArray(const GL &gl, const string_t &name)
Enables a vertex attribute array.
bool pushUniform(const GL &gl, const GLUniformDataRef &data)
Set the uniform data, if it's location is valid, i.e.
bool isVertexAttribArrayEnabled(const GLArrayDataRef &data) const
bool ownsAttribute(const GLArrayDataRef &attribute) const
bool inUse() const noexcept
Returns true if the shaderProgram() is in use, see ShaderProgram::inUse().
GLint getAttribLocation(const GL &, const string_t &name)
Gets the location of a shader attribute with given name.
bool disableVertexAttribArray(const GL &gl, const string_t &name)
Disables a vertex attribute array.
void setVerbose(bool v) noexcept
bool pushUniform(const GL &gl, const stringview_t &name)
Same as pushUniform(), but retrieves GLUniformDataRef by name first.
bool isVertexAttribArrayEnabled(stringview_t name) const
bool isActiveAttribute(const GLArrayDataRef &attribute) const
GLint getCachedUniformLocation(const stringview_t &name)
Gets the cached location of the shader uniform.
void destroy(GL &gl)
Calls release(gl, true, true, true).
const GLUniformDataRef getUniform(const stringview_t &name)
Get the uniform data, previously set.
bool linked() const noexcept
Returns true if the shaderProgram() is linked, see ShaderProgram::linked().
void releaseAllData(GL &gl)
Calls release(gl, false, false, false).
void ownUniform(const GLUniformDataRef &data, bool own)
Bind the GLUniform lifecycle to this ShaderState.
bool verbose() const noexcept
ShaderState() noexcept=default
void release(GL &gl, bool destroyBoundAttributes, bool destroyShaderProgram, bool destroyShaderCode)
void disableAllVertexAttributeArrays(const GL &gl, bool removeFromState)
Disables all vertex attribute arrays.
void bindAttribLocation(const GL &gl, GLint location, const GLArrayDataRef &attr)
Binds a shader GLArrayData attribute to a location.
void releaseAllUniforms()
Releases all mapped uniform data and loses all indices.
void clearAttachedObjects()
Clears the attachment map.
void useProgram(GL &gl, bool on)
Turns the shader program on or off.
void pushAllUniforms(const GL &gl)
Same as pushUniform(), but for all active uniforms.
void ownAttribute(const GLArrayDataRef &attr, bool own)
Binds or unbinds the GLArrayData lifecycle to this ShaderState.
GLint getAttribLocation(const GL &gl, const GLArrayDataRef &data)
Validates and returns the location of a shader attribute.
bool disableVertexAttribArray(const GL &gl, const GLArrayDataRef &data)
Disables a vertex attribute array.
bool ownsUniform(const GLUniformDataRef &uniform)
AttachableRef detachObject(std::string_view key)
Removes attached object if exists and returns it, otherwise returns nullptr.
GLArrayDataRef getAttribute(stringview_t name) const
Get the previous cached vertex attribute data.
bool enableVertexAttribArray(const GL &gl, const GLArrayDataRef &data)
Enables a vertex attribute array, usually invoked by GLArrayDataEditable#enableBuffer(GL,...
void releaseAllAttributes(const GL &gl)
Releases all mapped vertex attribute data, disables all enabled attributes and loses all indices.
AttachableRef getAttachedObject(std::string_view key) const
Returns the attached user object for the given name.
GLint getUniformLocation(const GL &gl, const GLUniformDataRef &data)
Validates and returns the location of a shader uniform.
string_t toString(bool alsoUnlocated=DEBUG_STATE) const
bool attachShaderProgram(GL &gl, const ShaderProgramRef &prog, bool enable)
Attach or switch a shader program.
GLint getUniformLocation(const GL &, const string_t &name)
Gets the location of a shader uniform with given name.
const ShaderProgramRef & shaderProgram() const noexcept
Returns the attachedShaderProgram() or nullptr.
GLint getCachedAttribLocation(const stringview_t &name) const
Gets the cached location of a shader attribute.
consteval_cxx20 std::string_view name() noexcept
std::ostream & operator<<(std::ostream &os, const T v)
std::shared_ptr< GLArrayData > GLArrayDataRef
std::shared_ptr< GLUniformData > GLUniformDataRef
std::shared_ptr< ShaderProgram > ShaderProgramRef
std::string_view stringview_t
std::shared_ptr< Attachable > AttachableRef
StringHashMapWrap< AttachableRef, std::nullptr_t, nullptr > StringAttachables
void INFO_PRINT(const char *format,...) noexcept
Use for unconditional informal messages, prefix '[elapsed_time] Info: '.