![]() |
ImFusion SDK 4.3
|
#include <ImFusion/Core/GL/Program.h>
OpenGL GLSL program with a fragment and optional vertex and geometry shader. More...
OpenGL GLSL program with a fragment and optional vertex and geometry shader.
The source code for the shaders is resolved by GL::Program in conjunction with the Resource System infrastructure. It will use Resource::query() to check whether any registered resource repository can provide the source code corresponding to the identifier (i.e. file name) passed during construction of the GL::Program. An optional path prefix will be interpreted as repository name to allow for more specific source code queries and resolve potential ambiguities, for instance the identifier MyPlugin/MyShader.frag
will first search to find the resource MyShader.frag
in a repository with the name MyPlugin
. Only if this can not be resolved, it will continue searching for a resource with the name MyPlugin/MyShader.frag
in any registered repository. If none of the resource repositories can resolve the given shader name, initialization of the GL::Program will fail.
When you're using OpenGL shaders in your own module, you should create a dedicated Resource::Repository in order to control the loading behavior for your shaders.
Similar to C++ headers, a GLSL program can include other GLSL headers. By convention, a GLSL header has the extension .glh and must not contain a main function. Otherwise, it can contain other function, struct, variable or uniform definitions like any normal shader. A GLSL header can be included in a shader using:
The code from the include file will be inserted (as in copied) right after the #pragma
.
To allow for using the same include in different shaders, the GL::Program shader preprocessor will define one of the following defines in the corresponding shader stages: IMFUSION_VERTEX_SHADER
, IMFUSION_GEOMETRY_SHADER
, IMFUSION_FRAGMENT_SHADER
, IMFUSION_COMPUTE_SHADER
, IMFUSION_TESSELATION_EVALUATION_SHADER
, or IMFUSION_TESSELATION_CONTROL_SHADER
.
In the case of an error, the resulting log will be reformatted and the line number is replaced with the line number and the filename where the line originates. Include file names are resolved the same way as normal shader file names (i.e. querying the Resource System infrastructure).
GL::Program will parse the version directive of each loaded shader/shader include. If there is no version directive present in a shader, it will assume GLSL 3.3. If a shader and its includes require different GLSL versions, GL::Program will use the maximum version.
varying
) to their modern GLSL counterpart. This compatibility mode may be dropped at future versions to only allow GLSL >= 3.3Example:
Classes | |
struct | AbstractIncludeStruct |
Struct for representing an abstract include object. More... | |
struct | BufferBinding |
Struct to keep track of GlBuffers bound shaders as SSBOs. More... | |
struct | ImageBinding |
struct | ShaderInfo |
Encapsulates information about each shader stage. More... | |
struct | TextureBinding |
Public Types | |
enum class | ImageAccess { ReadOnly = 0x88B8 , WriteOnly = 0x88B9 , ReadWrite = 0x88BA } |
Type of access that will be performed on a bound image. More... | |
enum class | Stage { Vertex = 0x8B31 , Geometry = 0x8DD9 , Fragment = 0x8B30 , Compute = 0x91B9 , TesselationEvaluation = 0x8E87 , TesselationControl = 0x8E88 } |
Enumeration of supported shader stages. More... | |
enum class | Cloning { Everything = 0 , NoDecorators = 1 << 0 , NoAbstractIncludes = 1 << 1 } |
Bitflag enumeration to configure Program::clone() More... | |
enum class | Compilation { Defer , Immediate , ImmediateThrowOnFailure } |
Describes how to deal with necessary (re-) compilation of the shader. More... | |
Public Member Functions | |
Program (std::vector< std::pair< Stage, const char * > > shaders, const std::string &defines="", Compilation compileBehavior=Compilation::ImmediateThrowOnFailure) | |
Instantiates a new OpenGL program consisting of one or multiple GLSL shaders. | |
virtual | ~Program () |
Destructor, deletes all allocated resources. | |
std::unique_ptr< Program > | clone (Flags< Cloning > cloneOptions, Compilation compileBehavior) const |
Performs a deep copy of the shader with its sources, defines, and optionally also decorators and abstract includes. | |
virtual bool | setDefines (const std::string &defines, Compilation compileBehavior=Compilation::Immediate) |
Sets the optional string of definitions that is pasted at the beginning of all shaders. | |
const std::string & | defines () const |
Returns the optional string of definitions that is pasted at the beginning of all shaders. | |
bool | setExpandDefines (bool expandDefines, Compilation compileBehavior=Compilation::Immediate) |
Sets the flag to optionally also expand (abstract) includes recursively found in defines. | |
bool | expandsDefines () const |
Returns the flag whether to also expand (abstract) includes recursively found in defines. | |
bool | addRequiredExtension (const std::string &extensionName, Compilation compileBehavior=Compilation::Immediate) |
Registers a GLSL extension as required so that the preprocessor adds the corresponding #extension directives. | |
const std::vector< std::string > & | requiredExtensions () const |
Returns all GLSL extensions that were registered as required through addRequiredExtension(). | |
template<typename T> | |
void | setArgument (const char *name, const T &val) |
Sets a shader argument (i.e., uniform), including images, matrices, vectors. | |
template<typename T> | |
void | setArgument (const std::string &name, const T &val) |
Sets a shader argument (i.e., uniform), including images, matrices, vectors. | |
void | setArgument (const char *name, const Texture &val, const Sampler &sampling) |
Sets a shader sampler with additional sampling parameters (temporarily overrides the parameters of the texture). | |
void | setArgument (const char *name, const std::vector< const Texture * > &val, const Sampler &sampling) |
Sets multiple shader samplers with additional sampling parameters (temporarily overrides the parameters of the texture). | |
bool | bindBuffer (const char *name, ShaderStorageBuffer &buffer) |
Binds the given SSBO to the interface block of the given name in the shader. | |
void | unbindBuffers () |
Unbinds all buffers from this shader. | |
bool | bindImage (const char *name, Texture &image, ImageAccess access) |
Binds the given texture as GLSL image variable to the given uniform name. | |
void | addDecorator (ProgramDecorator *dec) |
Add a decorator to apply upon enabling. | |
void | removeDecorator (ProgramDecorator *dec) |
Remove a decorator. | |
bool | addAbstractIncludeDefinition (const AbstractInclude *include, Compilation compileBehavior=Compilation::Immediate) |
Adds an abstract include to the shader source. | |
bool | removeAbstractIncludeDefinition (AbstractInclude *include, Compilation compileBehavior=Compilation::Immediate) |
Removes an abstract include definition. | |
bool | removeAbstractIncludeDefinition (const std::string &defineName, Compilation compileBehavior=Compilation::Immediate) |
Removes an abstract include definition. | |
void | enable () |
Enable the shader program now. | |
void | disable () |
Disable the shader program and set no active shader. | |
void | dispatchCompute (const vec3i &numWorkGroups) |
Launch a compute shader with the given number of work groups. | |
void | dispatchCompute (int numWorkGroupsX, int numWorkGroupsY=1, int numWorkGroupsZ=1) |
Launch a compute shader with the given number of work groups. | |
void | unbindImages (bool manipGlState=true) |
Unbind texture arguments that had been set before. | |
int | numImages () const |
Returns an upper bound of the number of images that have been set as arguments. | |
int | loc (const char *name) |
Returns GLSL uniform location. | |
uint32_t | id () const |
Returns the internal OpenGL id for this program. | |
bool | overrideShaderSource (Stage shaderStage, const std::string &shaderSource, Compilation compileBehavior) |
Set custom shader source to override source code from Resource infrastructure for the given shader stage. | |
bool | compile (Compilation compileBehavior=Compilation::Immediate) |
Immediately compiles the GLSL shaders and links them to the final program. | |
bool | isCompiled () const |
Returns whether the shader has been successfully compiled and is up-to-date or whether there are pending changes. | |
Static Public Member Functions | |
static std::unique_ptr< Program > | createVertexFragment (const std::string &vertexShaderName, const std::string &framentShaderName, const std::string &defines="", Compilation compileBehavior=Compilation::Immediate) |
Convenience function to instantiate a new OpenGL program consisting of a vertex and a fragment shader. | |
static std::unique_ptr< Program > | createVertexGeometryFragment (const std::string &vertexShaderName, const std::string &geometryShaderName, const std::string &framentShaderName, const std::string &defines="", Compilation compileBehavior=Compilation::Immediate) |
Convenience function to instantiate a new OpenGL program consisting of a vertex, geometry, and a fragment shader. | |
static std::unique_ptr< Program > | createCompute (const std::string &computeShaderName, const std::string &defines="", Compilation compileBehavior=Compilation::Immediate) |
Convenience function to instantiate a new OpenGL program consisting of a compute shader. | |
static std::string | determineVersion (int minVersion, int maxVersion, const std::string &filename) |
Returns a GLSL version string that accommodates the given version range. | |
Protected Member Functions | |
virtual Program * | cloneImpl () const |
Virtual helper function to actually clone this type, may throw on error. | |
int | checkForUnititializedUniforms () const |
Only in _DEBUG builds: Checks for active uniforms (GL_ACTIVE_UNIFORMS ) that were not initializes using GL::Program::setArgument(). | |
bool | initProgram (Compilation compileBehavior) |
Initializes or Reinitializes the program. | |
void | initShader (const ShaderInfo &si) |
Initialize a single shader. | |
int | bindSampler (const char *uniformName, const Texture &texture, const Sampler *sampler, bool setUniformAndRecycleUnit) |
void | unbindSamplers (const char *uniformName) |
std::string | joinShaderNames () const |
Static Protected Member Functions | |
static std::string | loadShaderSource (const ShaderInfo &si, bool expandDefines, const std::map< std::string, AbstractIncludeStruct > &abstractIncludes, const std::string &additionalDefines, const std::vector< std::string > &requiredExtensions={}) |
static std::string | expandInclude (const std::string &line, std::string &defines, int &minVersion, int &maxVersion, std::vector< std::string > &includeFilenames, const std::string &shaderName, const std::map< std::string, AbstractIncludeStruct > &abstractIncludes, const std::string &additionalDefines, const std::string &dependentIncludesPrefix="") |
Searches for #pragma include defines and returns the source of the include file expandInclude is called recursively by the include to expand includes inside the include. | |
static void | convertLegacyCodeToModernGlsl (std::string &lines, Stage shaderType) |
Converts selected legacy GLSL constructs to their modern GLSL > 3.3 counterpart using simple text replacement. | |
static void | gatherAbstractIncludesRecursively (const AbstractInclude *include, const std::map< std::string, AbstractIncludeStruct > &abstractIncludes, std::vector< AbstractIncludeStruct > &outIncludes, const std::string &dependentIncludesPrefix="") |
Protected Attributes | |
uint32_t | m_progID = 0 |
OpenGL program ID. | |
std::vector< ShaderInfo > | m_shaders |
List of all shader stages part of the program. | |
std::string | m_defines |
Optional string of definitions pasted to the beginning of each shader. | |
std::vector< TextureBinding > | m_textures |
All textures bound to the shader, index defines binding location. | |
std::vector< BufferBinding > | m_buffers |
All buffers bound to the shader, index defines binding location. | |
std::vector< ImageBinding > | m_images |
All images bound to the shader as images, index defines image unit. | |
std::vector< ProgramDecorator * > | m_dec |
The optional decorator instances. | |
bool | m_expandDefines = false |
Flag whether to optionally also expand includes found in defines. | |
std::unordered_set< std::string > | m_assignedUniforms |
Names of all uniforms that were set using setArgument() | |
std::map< std::string, AbstractIncludeStruct > | m_abstractIncludes |
Abstract include by define name. | |
std::vector< std::string > | m_requiredExtensions |
GLSL extensions that must be enabled. | |
|
strong |
Type of access that will be performed on a bound image.
|
strong |
Enumeration of supported shader stages.
|
strong |
Bitflag enumeration to configure Program::clone()
Enumerator | |
---|---|
Everything | Clone everything. |
NoDecorators | Do not copy GL::ProgramDecorator instances. |
NoAbstractIncludes | Do not copy AbstractInclude instances. |
|
strong |
Describes how to deal with necessary (re-) compilation of the shader.
Program | ( | std::vector< std::pair< Stage, const char * > > | shaders, |
const std::string & | defines = "", | ||
Compilation | compileBehavior = Compilation::ImmediateThrowOnFailure ) |
Instantiates a new OpenGL program consisting of one or multiple GLSL shaders.
shaders | List of pairs {shader stage, source code resource name} of all shaders that shall form the OpenGL program. The shaders' source code is resolved using the ImFusion::Resource infrastructure as described above. |
defines | List of optional definitions that are to be pasted at the beginning of the source code of each participating shader. |
compileBehavior | Flag whether the copied shader should be compiled immediately and how to handle compilation failure. |
std::runtime_error | Will always throw if the underlying OpenGL objects could not be created. Depending on compileBehavior this function may also throw if compilation of the shader fails (e.g. shader source could not be resolved, shader source contains invalid GLSL, ...). |
|
static |
Convenience function to instantiate a new OpenGL program consisting of a vertex and a fragment shader.
Depending on compileBehavior failure will be indicated either by returning a nullptr or by throwing. Failure can happen if the underlying OpenGL objects could not be created or if immediate compilation of the shader fails (e.g. shader source could not be resolved, shader source contains invalid GLSL, ...).
std::runtime_error | on failure if compileBehavior is ImmediateThrowOnFailure . |
|
static |
Convenience function to instantiate a new OpenGL program consisting of a vertex, geometry, and a fragment shader.
Depending on compileBehavior failure will be indicated either by returning a nullptr or by throwing. Failure can happen if the underlying OpenGL objects could not be created or if immediate compilation of the shader fails (e.g. shader source could not be resolved, shader source contains invalid GLSL, ...).
std::runtime_error | on failure if compileBehavior is ImmediateThrowOnFailure . |
|
static |
Convenience function to instantiate a new OpenGL program consisting of a compute shader.
Depending on compileBehavior failure will be indicated either by returning a nullptr or by throwing. Failure can happen if the underlying OpenGL objects could not be created or if immediate compilation of the shader fails (e.g. shader source could not be resolved, shader source contains invalid GLSL, ...).
std::runtime_error | on failure if compileBehavior is ImmediateThrowOnFailure . |
std::unique_ptr< Program > clone | ( | Flags< Cloning > | cloneOptions, |
Compilation | compileBehavior ) const |
Performs a deep copy of the shader with its sources, defines, and optionally also decorators and abstract includes.
GL::ProgramDecorator instances are not deep-copied, thus you must make sure that they remain valid throughout the lifetime of all clones. In contrast, GL::AbstractInclude instances are deep-copied.
cloneOptions | Bitflag mask describing what aspects of the program are to be cloned. |
compileBehavior | Flag whether the copied shader should be compiled immediately and how to handle compilation failure. |
|
virtual |
Sets the optional string of definitions that is pasted at the beginning of all shaders.
Changing the defines will require recompilation of the shader and invalidate all configured uniforms, buffers, and images.
Reimplemented in ImageProgram.
bool setExpandDefines | ( | bool | expandDefines, |
Compilation | compileBehavior = Compilation::Immediate ) |
Sets the flag to optionally also expand (abstract) includes recursively found in defines.
Changing this flag will require recompilation of the shader and invalidate all configured uniforms, buffers, and images.
bool addRequiredExtension | ( | const std::string & | extensionName, |
Compilation | compileBehavior = Compilation::Immediate ) |
Registers a GLSL extension as required so that the preprocessor adds the corresponding #extension
directives.
For every registered extensionName the preprocessor will put #extension <extensionName> : require
to the top of the source code.
void setArgument | ( | const char * | name, |
const T & | val ) |
Sets a shader argument (i.e., uniform), including images, matrices, vectors.
This template member function is implemented for the following types T
:
bool
int32_t
, uint32_t
, float
, as well as a std::vector
of these typesvec2i
, vec3i
, vec4i
, as well as a std::vector
of these typesvec2f
, vec3f
, vec4f
, as well as a std::vector
of these typesmat2f
, mat3f
, mat4f
, as well as a std::vector
of these typesGL::Texture
, and std::vector<const Gl::Texture*>
Furthermore, we implement the following convenience overloads for double-precision floating point values. Be advised that they are not supported by GLSL and a narrowing conversion to single-precision will take place:
double
, vec2
, vec3
, vec4
, mat2
, mat3
, mat4
|
inline |
Sets a shader argument (i.e., uniform), including images, matrices, vectors.
This template member function is implemented for the following types T
:
bool
int32_t
, uint32_t
, float
, as well as a std::vector
of these typesvec2i
, vec3i
, vec4i
, as well as a std::vector
of these typesvec2f
, vec3f
, vec4f
, as well as a std::vector
of these typesmat2f
, mat3f
, mat4f
, as well as a std::vector
of these typesGL::Texture
, and std::vector<const Gl::Texture*>
Furthermore, we implement the following convenience overloads for double-precision floating point values. Be advised that they are not supported by GLSL and a narrowing conversion to single-precision will take place:
double
, vec2
, vec3
, vec4
, mat2
, mat3
, mat4
bool bindBuffer | ( | const char * | name, |
ShaderStorageBuffer & | buffer ) |
Binds the given SSBO to the interface block of the given name in the shader.
The return value indicates whether the binding was successful
bool bindImage | ( | const char * | name, |
Texture & | image, | ||
ImageAccess | access ) |
Binds the given texture as GLSL image variable to the given uniform name.
bool addAbstractIncludeDefinition | ( | const AbstractInclude * | include, |
Compilation | compileBehavior = Compilation::Immediate ) |
Adds an abstract include to the shader source.
This method only extracts the define name and include path from the AbstractInclude, the pointer itself is not stored and only used in this method. Only one AbstractInclude can be set per define name. If an AbstractInclude with the same defineName is already set, it will be overridden in the case of non-matching fingerprints. Changing the defines will require recompilation of the shader and invalidate all configured uniforms, buffers, and images.
bool removeAbstractIncludeDefinition | ( | AbstractInclude * | include, |
Compilation | compileBehavior = Compilation::Immediate ) |
Removes an abstract include definition.
Changing the defines will require recompilation of the shader and invalidate all configured uniforms, buffers, and images.
bool removeAbstractIncludeDefinition | ( | const std::string & | defineName, |
Compilation | compileBehavior = Compilation::Immediate ) |
Removes an abstract include definition.
Changing the defines will require recompilation of the shader and invalidate all configured uniforms, buffers, and images.
void dispatchCompute | ( | const vec3i & | numWorkGroups | ) |
Launch a compute shader with the given number of work groups.
This function must only be called if this shader is a compute shader.
void dispatchCompute | ( | int | numWorkGroupsX, |
int | numWorkGroupsY = 1, | ||
int | numWorkGroupsZ = 1 ) |
Launch a compute shader with the given number of work groups.
This function must only be called if this shader is a compute shader.
void unbindImages | ( | bool | manipGlState = true | ) |
Unbind texture arguments that had been set before.
manipGlState | Flag whether to also manipulate OpenGL state. If false, will only update internal bookkeeping. |
int numImages | ( | ) | const |
Returns an upper bound of the number of images that have been set as arguments.
bool overrideShaderSource | ( | Stage | shaderStage, |
const std::string & | shaderSource, | ||
Compilation | compileBehavior ) |
Set custom shader source to override source code from Resource infrastructure for the given shader stage.
bool compile | ( | Compilation | compileBehavior = Compilation::Immediate | ) |
Immediately compiles the GLSL shaders and links them to the final program.
You do not need to call this function explicitly unless you used Compilation::Defer
previously.
compileBehavior | Defines how to indicate errors, must not be Defer . |
false
if compileBehavior is Compilation::Immediate
and compilation failed. true
in all other cases.
|
static |
Returns a GLSL version string that accommodates the given version range.
E.g. determineVersion(330, 450, "") would return "#version 450". The given filename is only used for logging purposes. This usually returns a version string containing maxVersion, except when IMFUSION_GLES is defined which always returns "#version 300 es". Returns an empty string if maxVersion is 0.
|
protectedvirtual |
Virtual helper function to actually clone this type, may throw on error.
Reimplemented in ImageProgram.
|
protected |
Only in _DEBUG
builds: Checks for active uniforms (GL_ACTIVE_UNIFORMS
) that were not initializes using GL::Program::setArgument().
Logs a warning for each uninitialized uniform and returns the count of those.
|
staticprotected |
Searches for #pragma include defines and returns the source of the include file expandInclude is called recursively by the include to expand includes inside the include.
line | the line to search for the pragma | |
[in,out] | defines | the current active defines, if the include is an abstract include its define will be appended |
[in,out] | minVersion | the current minimum GLSL version in the program, will be updated if the include has a lower version |
[in,out] | maxVersion | the current maximum GLSL version in the program, will be updated if the include has a higher version |
[in,out] | includeFilenames | list of all current includes, if an include is found it will be appended |
shaderName | m_shaderNames[num] for logging only | |
abstractIncludes | this is generally taken to be m_abstractIncludes | |
additionalDefines | this is generally taken to be m_defines |