ImFusion SDK 4.3
ImageProgram Class Reference

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

Convenience class to execute a GLSL fragment shader on an image or volume. More...

+ Inheritance diagram for ImageProgram:

Detailed Description

Convenience class to execute a GLSL fragment shader on an image or volume.

The fragment shader gets the voxel or pixel position of the fragment as input:

in vec3 in_texCoord;

The output can be defined arbitrary, e.g.:

layout (location = 0) out vec2 out_color;

The layout location corresponds to the list of texture passed to ImageProgram::compute, e.g. the location 0 will write to the first texture, the location 1 to the second texture and so on. The out type does not need to exactly match the corresponding texture because OpenGL automatically converts the values (check the OpenGL Specification for details).

A FBO is automatically created but can be replaced by a custom one.

Optionally, a geometry shader can be used to improve performance when computing 3D volumes. The performance gain depends on the use-case and the driver. In general the geometry shader overhead is too large for 2D processing (but works nonetheless). In 3D, using the geometry shader seems to be always faster on Nvidia and AMD. The geometry shader will only be used if all output volumes combined have less than GL_MAX_FRAMEBUFFER_LAYERS slices. Otherwise, the geometry shader stage will be active, but will add a slight overhead instead of improving the performance. Also consider that the geometry shader cannot be removed/added once a ImageProgram has been created.

Classes

class  Cuboid
 Utility class to specify the (sub-) region of the textures to execute the shader on. More...
 

Public Types

enum class  TexCoordMode { Image , Box }
 Applies if compute() is called with a Cuboid defining a ROI of the textures. More...
 
- Public Types inherited from Program
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

 ImageProgram (const std::string &fragmentShaderName, const std::string &defines="", bool useGeometryShader=false, TexCoordMode texCoordMode=TexCoordMode::Image, Compilation compileBehavior=Compilation::ImmediateThrowOnFailure)
 Creates a new ImageProgram for the given GLSL shader.
 
std::unique_ptr< ImageProgramclone (Flags< Cloning > cloneOptions, Compilation compileBehavior) const
 Performs a deep copy of the shader with its sources, defines, and optionally also decorators and abstract includes.
 
void setFBO (Framebuffer *fbo)
 Makes ImageProgram use fbo during computation instead of using an internal one.
 
Framebufferfbo () const
 Returns the currently used FBO.
 
void setClearOutputEnabled (bool enabled, const vec4f &clearColor=vec4f::Zero())
 Sets whether the output images are cleared before rendering to them (disabled by default).
 
const std::optional< vec4f > isClearOutputEnabled () const
 Returns whether the output images are cleared before rendering to them, and if yes with which color.
 
void compute (const std::vector< Texture * > &output, const Cuboid &box={})
 Executes the program on each pixel or voxel and writes the result in the given output textures.
 
void compute (Texture &output, const Cuboid &box={})
 Convenience overload to execute the program on a single texture.
 
void computeReduceZ (const std::vector< Texture * > &output, int numSlices=-1, int targetSlice=0, const Cuboid &box={})
 Executes the program on each pixel or voxel inside the box but writes only to a single slice.
 
void computeReduceZ (Texture &output, int numSlices=-1, int targetSlice=0, const Cuboid &box={})
 Convenience overload to execute a reduction the program on a single texture.
 
void setAvoidDriverTimeout (bool value)
 Sets the flag whether execute the shader in batches to avoid driver timeouts.
 
bool isAvoidingDriverTimeout () const
 Returns the flag whether execute the shader in batches to avoid driver timeouts.
 
bool setDefines (const std::string &defines, Compilation compileBehavior=Compilation::Immediate) override
 Sets the optional string of definitions that is pasted at the beginning of all shaders.
 
- Public Member Functions inherited from Program
 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< Programclone (Flags< Cloning > cloneOptions, Compilation compileBehavior) const
 Performs a deep copy of the shader with its sources, defines, and optionally also decorators and abstract includes.
 
const std::stringdefines () 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::string genericSamplerDefine (bool for3D)
 Returns a string with 3 GLSL defines to help writing shaders that support both 2D and 3D samplers.
 
- Static Public Member Functions inherited from Program
static std::unique_ptr< ProgramcreateVertexFragment (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< ProgramcreateVertexGeometryFragment (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< ProgramcreateCompute (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

ImageProgramcloneImpl () const override
 Virtual helper function to actually clone this type, may throw on error.
 
void ensureFboIsBound ()
 
- Protected Member Functions inherited from Program
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
 

Protected Attributes

std::unique_ptr< VertexBufferm_quad
 Full-screen quad used for rendering during compute()
 
Framebufferm_fbo = nullptr
 FBO used rendering to texture, ownership based on m_ownFbo
 
const TexCoordMode m_texCoordMode
 
std::optional< vec4f > m_clearColor
 Clear color for the output textures if enabled.
 
const bool m_useGS = false
 Flag whether to use a Geometry Shader for layered output textures.
 
bool m_externalFbo = false
 Flag whether m_fbo points to an externally providided FBO.
 
bool m_avoidTimeout = false
 Flag whether execute the shader in batches to avoid driver timeouts.
 
std::unique_ptr< Pimpl > m_pimpl
 
- Protected Attributes inherited from Program
uint32_t m_progID = 0
 OpenGL program ID.
 
std::vector< ShaderInfom_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< TextureBindingm_textures
 All textures bound to the shader, index defines binding location.
 
std::vector< BufferBindingm_buffers
 All buffers bound to the shader, index defines binding location.
 
std::vector< ImageBindingm_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::stringm_assignedUniforms
 Names of all uniforms that were set using setArgument()
 
std::map< std::string, AbstractIncludeStructm_abstractIncludes
 Abstract include by define name.
 
std::vector< std::stringm_requiredExtensions
 GLSL extensions that must be enabled.
 

Additional Inherited Members

- Static Protected Member Functions inherited from Program
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="")
 

Member Enumeration Documentation

◆ TexCoordMode

enum class TexCoordMode
strong

Applies if compute() is called with a Cuboid defining a ROI of the textures.

Enumerator
Image 

The texture coordinates will be computed relative to the image, i.e., the ROI also applies to input images.

Box 

The texture coordinates will be computed absolute wrt.

the box, i.e., the dimensions of the ROI will map to \([0,1]^3\).

Constructor & Destructor Documentation

◆ ImageProgram()

ImageProgram ( const std::string & fragmentShaderName,
const std::string & defines = "",
bool useGeometryShader = false,
TexCoordMode texCoordMode = TexCoordMode::Image,
Compilation compileBehavior = Compilation::ImmediateThrowOnFailure )
explicit

Creates a new ImageProgram for the given GLSL shader.

Parameters
fragmentShaderNameName of the GLSL fragment shader. The shader's source code is resolved using the ImFusion::Resource infrastructure as described in GL::Program.
definesList of optional definitions that are to be pasted at the beginning of the source code of each participating shader.
useGeometryShaderWhether to utilize the geometry shader. This can be faster on 3D volumes with Nvidia or AMD cards, but this depends on the workload. Settings this option to true does not require any changes to the fragment shader.
texCoordModeSee TexCoordMode
Exceptions
std::runtime_errorif the OpenGL program could not be created, either due to an OpenGL error or due to the Resource system not being able to resolve all of the shader sources.

Member Function Documentation

◆ clone()

std::unique_ptr< ImageProgram > 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.

Parameters
cloneOptionsBitflag mask describing what aspects of the program are to be cloned.
Note
This function does not copy any OpenGL state such as assigned uniform arguments/images/etc.
Exceptions
std::runtime_errorif the new OpenGL program could not be created

◆ setFBO()

void setFBO ( Framebuffer * fbo)

Makes ImageProgram use fbo during computation instead of using an internal one.

When a custom FBO is set the compute method will not automatically bind or unbind the FBO, however, it will still change the attachments and draw buffers. This may provide a performance benefit in hot sections of the code where you need to minimize the amount of GL state changes.

◆ fbo()

Framebuffer * fbo ( ) const

Returns the currently used FBO.

If no FBO was set explicitly, this returns the internal FBO generated by ImageProgram or nullptr in case no internal FBO was requested yet.

◆ compute() [1/2]

void compute ( const std::vector< Texture * > & output,
const Cuboid & box = {} )

Executes the program on each pixel or voxel and writes the result in the given output textures.

The viewport size (and the number of slices if 3D) is set to the size of the first non-zero texture.

Parameters
outputThe outputs are bound to the locations depending on their position in the vector. If an entry is null, nothing is bound to that attachment.
boxOptional ROI in terms of pixels to restrict the shader execution to.

◆ compute() [2/2]

void compute ( Texture & output,
const Cuboid & box = {} )

Convenience overload to execute the program on a single texture.

Executes the program on each pixel or voxel and writes the result in the given output textures.

The viewport size (and the number of slices if 3D) is set to the size of the first non-zero texture.

Parameters
outputThe outputs are bound to the locations depending on their position in the vector. If an entry is null, nothing is bound to that attachment.
boxOptional ROI in terms of pixels to restrict the shader execution to.

◆ computeReduceZ() [1/2]

void computeReduceZ ( const std::vector< Texture * > & output,
int numSlices = -1,
int targetSlice = 0,
const Cuboid & box = {} )

Executes the program on each pixel or voxel inside the box but writes only to a single slice.

The viewport size is set to the size of the first non-zero textures. The user has to setup the OpenGL state accordingly so that intended reduction takes place, e.g.

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
program.computeReduceZ(texOut, texIn.slices(), reduceTo);
Guard to easily save and restore critical (modern) OpenGL state.
Definition StateGuard.h:40
@ Blending
Save the GL_BLEND enable and glBlendFunc states.
Definition StateGuard.h:48
Parameters
outputThe outputs are bound to the locations depending on their position in the vector. If an entry is null, nothing is bound to that attachment.
numSlicesNumber of slices of the output textures. If negative, slices of the first non-zero output will be used. If output is a 2D textures, numSlices can be set to the number of slices of an input volume. This way, the computation will be performed on all voxel of the input volume but the results will be accumulated in the 2D textures.
targetSliceIndex of the slice to write to if output is a volume.
boxOptional ROI in terms of pixels to restrict the shader execution to.

◆ computeReduceZ() [2/2]

void computeReduceZ ( Texture & output,
int numSlices = -1,
int targetSlice = 0,
const Cuboid & box = {} )

Convenience overload to execute a reduction the program on a single texture.

Executes the program on each pixel or voxel inside the box but writes only to a single slice.

The viewport size is set to the size of the first non-zero textures. The user has to setup the OpenGL state accordingly so that intended reduction takes place, e.g.

glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE);
program.computeReduceZ(texOut, texIn.slices(), reduceTo);
Parameters
outputThe outputs are bound to the locations depending on their position in the vector. If an entry is null, nothing is bound to that attachment.
numSlicesNumber of slices of the output textures. If negative, slices of the first non-zero output will be used. If output is a 2D textures, numSlices can be set to the number of slices of an input volume. This way, the computation will be performed on all voxel of the input volume but the results will be accumulated in the 2D textures.
targetSliceIndex of the slice to write to if output is a volume.
boxOptional ROI in terms of pixels to restrict the shader execution to.

◆ setAvoidDriverTimeout()

void setAvoidDriverTimeout ( bool value)

Sets the flag whether execute the shader in batches to avoid driver timeouts.

If true, ImageProgram will perform a micro-benchmark and estimate the full computation time. If this would exceed the common hard limit on how long a single OpenGL call can take depending on the platform (e.g. TDR on Windows or the nVidia Linux OpenGL driver watchdog), the computation will be split into chunks.

◆ setDefines()

bool setDefines ( const std::string & defines,
Compilation compileBehavior = Compilation::Immediate )
overridevirtual

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 from Program.

◆ genericSamplerDefine()

static std::string genericSamplerDefine ( bool for3D)
static

Returns a string with 3 GLSL defines to help writing shaders that support both 2D and 3D samplers.

For 2D returns:

#define SAMPLER_TYPE sampler2D
#define SAMPLER_COORDS xy
#define SAMPLER_2D

And for 3D returns:

#define SAMPLER_TYPE sampler3D
#define SAMPLER_COORDS xyz
#define SAMPLER_3D

In a shader it can be used like this:

uniform SAMPLER_TYPE tex;
in vec3 texCoords;
void main()
{
vec4 color = texture(tex, texCoords.SAMPLER_COORDS);
}

◆ cloneImpl()

ImageProgram * cloneImpl ( ) const
overrideprotectedvirtual

Virtual helper function to actually clone this type, may throw on error.

Reimplemented from Program.

Member Data Documentation

◆ m_texCoordMode

const TexCoordMode m_texCoordMode
protected
See also
TexCoordMode

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