ImFusion SDK 4.3
MultiIncludable< BaseIncludeType, IncludeArgumentsTypes > Class Template Referenceabstract

#include <ImFusion/Core/GL/MultiAbstractInclude.h>

Multi-AbstractIncludes allow for using multiple instances of the same AbstractInclude type in one shader. More...

Detailed Description

template<typename BaseIncludeType, typename... IncludeArgumentsTypes>
class ImFusion::GL::MultiIncludable< BaseIncludeType, IncludeArgumentsTypes >

Multi-AbstractIncludes allow for using multiple instances of the same AbstractInclude type in one shader.

Inherit from this class to enable multiple instances of your AbstractIncludes in one shader. To avoid symbol conflicts this interface will perform a simple text replacement in the corresponding shader code: all occurrences of a baseToken will be replaced with a token specified by the user when instantiating the Multi-Include.

class Mask : public AbstractInclude, public MultiIncludable<Mask, Texture&>
{
Mask()
: AbstractInclude("IMAGE_MASK", "Mask.glh") // Mask is a regular AbstractInclude
// When requesting a Multi-include, all occurrences of `Mask` and `mask` will be replaced
{}
};
Base class for abstract GLSL includes.
Definition AbstractInclude.h:81
MultiIncludable(BaseIncludeType *crtpInstance, const std::string &baseToken, Flags< ShaderTextReplacement > replacementScheme)
Instantiate and configure the MultiIncludable interface.
Definition MultiAbstractInclude.h:152
Wrapper of an OpenGL Texture to store image data on the GPU.
Definition Texture.h:34
Base interface for implementing polymorphic image masks on the CPU.
Definition Mask.h:36
@ AllLowercase
Replace matches of toLower(baseToken) with the replacement token.
Definition MultiAbstractInclude.h:32
@ ExactMatch
Replace exact matches of the base token with the replacement token.
Definition MultiAbstractInclude.h:30

Since using multiple instances of the same include type in one shader requires having unique uniform names per multi-include and these uniform names need to be referenced from the C++ side, this interface provides the virtual setIncludeArguments() function: Its function arguments are defined by second variadic template argument IncludeArgumentsTypes of this class. Its final argument token references the unique per-multi-include token and will automatically be computed by the Multi-Include logic, so that you can use it to define uniform names:

// Note: the second function argument type matches the second MultiIncludable template type from above
int Mask::setIncludeArguments(Program& p, Texture& texture, const std::string& token = "mask") override
{
// token will automatically be set to `mask` or to it's replacement in case of a multi-include
p.setArgument("u_" + token + "Texture", texture);
return 1;
}
OpenGL GLSL program with a fragment and optional vertex and geometry shader.
Definition Program.h:99
void setArgument(const char *name, const T &val)
Sets a shader argument (i.e., uniform), including images, matrices, vectors.

A user can request a Multi-Include instance by calling createMultiInclude() and add those to the Program instead of the base include instance. This is the place where the user has to define a unique replacement token so that defines, uniforms, and functions of the multi-shader include instances are unique and the final shader does compile.

Program p = ...;
Mask m1, m2 = ...;
auto multiMask1 = m1.createMultiInclude("Mask1"); // all occurrences of `Mask` will be replaced with `Mask1`
auto multiMask2 = m2.createMultiInclude("Mask2"); // all occurrences of `Mask` will be replaced with `Mask2`
p.addAbstractInclude(m1.get());
p.addAbstractInclude(m2.get());
m1->setIncludeArguments(p, texture1); // automatically forwarded to Mask::setIncludeArguments(p, texture1, "Mask1");
m2->setIncludeArguments(p, texture2); // automatically forwarded to Mask::setIncludeArguments(p, texture2, "Mask2");

Given this original shader code:

[Mask.glh]
uniform sampler2D u_maskTexture;
float getMaskValue(in vec2 coord) {
return texture(u_maskTexture, coord).r;
}
[Program.frag]
#pragma abstract_include "MASK1"
#pragma abstract_include "MASK2"

adding the two multi-includes will expand it to:

uniform sampler2D u_mask1Texture;
float getMask1Value(in vec2 coord) {
return texture(u_mask1Texture, coord).r;
}
uniform sampler2D u_mask2Texture;
float getMask2Value(in vec2 coord) {
return texture(u_mask2Texture, coord).r;
}
Template Parameters
BaseIncludeTypeType of the concrete AbstractInclude that implements this interface (CRTP pattern), must also implement the AbstractInclude interface.
IncludeArgumentsTypesOptional Template pack describing the arguments that the user needs to pass to setIncludeArguments() in order to configure the include/corresponding shader.
See also
MultiAbstractInclude

Public Types

using MultiIncludeType = MultiAbstractInclude<BaseIncludeType, IncludeArgumentsTypes...>
 Alias for type of a multi-include instance of the original include.
 

Public Member Functions

std::shared_ptr< MultiIncludeTypecreateMultiInclude (const std::string &replacementToken)
 Instantiates a new AbstractInclude instance where all occurrences of baseToken provided during construction are replaces with replacementToken according to the specified replacementScheme.
 
virtual int setIncludeArguments (Program &prog, IncludeArgumentsTypes... includeArgs, const std::string &token) const =0
 Interface that multi includes should use to configure the shader include (such as setting uniforms, binding textures, etc).
 

Protected Member Functions

 MultiIncludable (BaseIncludeType *crtpInstance, const std::string &baseToken, Flags< ShaderTextReplacement > replacementScheme)
 Instantiate and configure the MultiIncludable interface.
 

Constructor & Destructor Documentation

◆ MultiIncludable()

template<typename BaseIncludeType, typename... IncludeArgumentsTypes>
MultiIncludable ( BaseIncludeType * crtpInstance,
const std::string & baseToken,
Flags< ShaderTextReplacement > replacementScheme )
inlineprotected

Instantiate and configure the MultiIncludable interface.

Parameters
crtpInstancePointer to the concrete instance implementing this interface (usually this)
baseTokenText fragment that will be replaced with the token specified in createMultiInclude() in order to generate unique shader code/variables. Make sure that the token is part of the base include's define name and to choose a sufficiently unique token to avoid replacing unwanted code.
replacementSchemeBitfield enumeration describing how to perform the text replacement in the include shader code. Text replacement of the include's define name is always performed using AllUppercase only.

Member Function Documentation

◆ setIncludeArguments()

template<typename BaseIncludeType, typename... IncludeArgumentsTypes>
virtual int setIncludeArguments ( Program & prog,
IncludeArgumentsTypes... includeArgs,
const std::string & token ) const
pure virtual

Interface that multi includes should use to configure the shader include (such as setting uniforms, binding textures, etc).

The return value shall indicate the number of textures bound to the program.

Parameters
progShader instance to configure
includeArgsList of custom arguments the user needs to provide in order to configure the include
tokenText fragment to distinguish multiple include instances: The MultiIncludable framework will ensure that this contains the replacement token of a concrete multi include instance.

The documentation for this class was generated from the following file:
Search Tab / S to search, Esc to close