Support Forum G3D Web Page |
Abstraction of the programmable hardware pipeline with G3D preprocessor extensions. More...
Inherits G3D::ReferenceCountedObject.
Classes | |
class | PreprocessedShaderSource |
A structure containing the individual parts of the code of a load-time preprocessed (by g3d, not the driver) shader. More... | |
class | ShaderProgram |
A wrapper around an actual openGL shader program object. More... | |
class | Source |
Stores either a filename or a shader source string (that has not gone through the g3d preprocessor) for a single shader stage. More... | |
class | Specification |
Consists of up to one Shader::Source per shader stage. More... | |
Public Types | |
enum | DomainType { STANDARD_INDEXED_RENDERING_MODE, STANDARD_NONINDEXED_RENDERING_MODE, MULTIDRAW_INDEXED_RENDERING_MODE, MULTIDRAW_NONINDEXED_RENDERING_MODE, INDIRECT_RENDERING_MODE, STANDARD_COMPUTE_MODE, INDIRECT_COMPUTE_MODE, RECT_MODE, ERROR_MODE } |
enum | FailureBehavior { EXCEPTION, PROMPT, SILENT } |
Determines the behavior upon a load-time or compile-time error for all shaders. More... | |
enum | RecoverableErrorType { LOAD_ERROR, COMPILATION_ERROR } |
enum | ShaderStage { VERTEX, TESSELLATION_CONTROL, TESSELLATION_EVAL, GEOMETRY, PIXEL, COMPUTE, STAGE_COUNT } |
enum | SourceType { FILE, STRING } |
Public Member Functions | |
void | bindG3DArgs (const shared_ptr< ShaderProgram > &p, RenderDevice *renderDevice, const Args &sourceArgs, int &maxModifiedTextureUnit) |
Sets the g3d uniform variables such as g3d_objectToWorldMatrix (using values from renderDevice) args. More... | |
void | bindStreamArg (const String &name, const AttributeArray &vertexRange, const ShaderProgram::AttributeDeclaration &decl) |
Bind a single vertex attribute. More... | |
void | bindStreamArgs (const shared_ptr< ShaderProgram > &program, const Args &args, RenderDevice *rd) |
Iterate over all formal parameters and bind all vertex attributes appropriately. More... | |
void | bindUniformArg (const Args::Arg &arg, const ShaderProgram::UniformDeclaration &decl, int &maxModifiedTextureUnit) |
Bind a single uniform variable. More... | |
void | bindUniformArgs (const shared_ptr< ShaderProgram > &program, const Args &args, bool allowG3DArgs, int &maxModifiedTextureUnit) |
Iterate over all formal parameters and bind all non-dummy variables appropriately. More... | |
shared_ptr< ShaderProgram > | compileAndBind (const Args &args, RenderDevice *rd, int &maxModifiedTextureUnit) |
Compile the shader and bind the arguments as necessary. More... | |
bool | g3dLoadTimePreprocessor (const String &dir, PreprocessedShaderSource &source, String &messages, GLuint stage, const Args &args) |
Execute all steps of the G3D load-time preprocessor engine. More... | |
bool | isCompute () const |
void | loadAndPreprocess (const Args &args, Array< PreprocessedShaderSource > &preprocessedSource) |
Load the shaders from files on disk, and run the preprocessor. More... | |
const String & | name () const |
A name for this shader. More... | |
bool | processIncludes (const String &dir, String &code, String &messages, const Args &args) |
Replaces all #includes in code with the contents of the appropriate files. More... | |
void | reload () |
Reload this shader from the files on disk, if it was loaded from disk. More... | |
shared_ptr< ShaderProgram > | retry (const Args &args) |
Reload from files on disk (if it was loaded from disk), run all steps of the g3d preprocessor and recompile. More... | |
void | setName (const String &n) |
void | unbindStreamArgs (const shared_ptr< ShaderProgram > &program, const Args &args, RenderDevice *rd) |
Counterpart to bindStreamArgs. More... | |
Static Public Member Functions | |
static GLenum | canonicalType (GLenum e) |
Converts texture types to their canonical value (anything that can be a sampler2D becomes GL_TEXTURE_2D, etc) all others are unmodified. More... | |
static shared_ptr< Shader > | create (const Specification &s) |
Creates a shader from the given specification, loads it from disk, and applies the g3d preprocessor. More... | |
static DomainType | domainType (const shared_ptr< Shader > &s, const Args &args) |
The mode to use when applying the shader and args. More... | |
static shared_ptr< Shader > | fromFiles (const String &f0, const String &f1="", const String &f2="", const String &f3="", const String &f4="") |
More... | |
static shared_ptr< Shader > | getShaderFromPattern (const String &pattern) |
Create a shader using all shaders specified by the given pattern. More... | |
static bool | isImageType (GLenum type) |
True if type corresponding to an OpenGL image type. More... | |
static bool | isSamplerType (GLenum type) |
True if type corresponding to an OpenGL sampler type. More... | |
static void | processExtensions (String &code, String &extensionLines) |
Reads the code looking for a #extension line (spaces allowed after "#"). More... | |
static bool | processVersion (String &code, String &versionLine) |
Reads the code looking for a #version line (spaces allowed after "#"). More... | |
static void | reloadAll () |
Reloads all shaders throughout G3D. More... | |
static void | setFailureBehavior (FailureBehavior f) |
Set the global failure behavior. More... | |
static GLuint | toGLEnum (ShaderStage s) |
static shared_ptr< Shader > | unlit () |
A shader that accepts color and textureMap arguments and applies them directly without lighting. More... | |
Static Public Attributes | |
static FailureBehavior | s_failureBehavior |
Protected Member Functions | |
Shader (const Specification &s) | |
No compilation, or even loading from files is performed at construction. More... | |
String | getLinePragma (int lineNumber, const String &filename) |
Returns a line directive in the format "#line X Y\n", where X is the lineNumber, and Y is an integer that maps to filename. More... | |
void | handleRecoverableError (RecoverableErrorType eType, const Args &args, const String &message, shared_ptr< ShaderProgram > &program) |
Handle a compilation or loading error as specified by s_failureBehavior. More... | |
shared_ptr< Shader::ShaderProgram > | shaderProgram (const Args &args, String &messages) |
Finds a shader program in the cache that matches the supplied args, recompiling if necessary. More... | |
Static Protected Member Functions | |
template<class T , class ... ArgTypes> | |
static shared_ptr< T > | createShared (ArgTypes &&... args) |
Like std::make_shared, but works for protected constructors. More... | |
static bool | expandExpectPragmas (String &source, const Table< int, String > &indexToNameTable, String &errorMessages) |
Expands G3D #expect preprocessor instructions. More... | |
static bool | expandForEachPragmas (String &processedSource, const Table< int, String > &indexToNameTable, String &errorMessages) |
Expands G3D #foreach pragmas found in processedSource into valid GLSL code. More... | |
static bool | expandForPragmas (String &processedSource, const Args &args, const Table< int, String > &indexToNameTable, String &errorMessages) |
Expands our #for pragmas found in processedSource into valid GLSL code. More... | |
static shared_ptr< Shader > | getShaderFromCacheOrCreate (const Specification &spec) |
If a shader of the given Specification exists, return it, otherwise create a new one. More... | |
static bool | sameSource (const Source &a, const Source &b) |
True iff a and b have the same SouceType and value. More... | |
static bool | sameSpec (const Specification &a, const Specification &b) |
True iff every stage of a and b satisfy sameSource. More... | |
static GLenum | toGLType (const String &s) |
Converts a type name to a GL enum. More... | |
Protected Attributes | |
Table< String, shared_ptr< ShaderProgram > > | m_compilationCache |
Maps preamble + macro definitions to compiled shaders. More... | |
Table< String, int > | m_fileNameToIndexTable |
Maps filenames to indices, so that we can correctly print #line directives. More... | |
Args | m_g3dUniformArgs |
A set of args solely for g3d uniforms. More... | |
Table< int, String > | m_indexToFilenameTable |
Maps indices to filenames, so that we can correctly output filenames when we get file indices back from the shader on error messages. More... | |
bool | m_isCompute |
String | m_name |
int | m_nextUnusedFileIndex |
The next index to be used by a previously unprocessed file when #including, so that we can produce proper #line directives. More... | |
Specification | m_specification |
Contains the filenames or hardcoded source strings this shader was constructed from. More... | |
Static Protected Attributes | |
static Array< weak_ptr< Shader > > | s_allShaders |
Array of all shaders ever created. More... | |
Friends | |
class | RenderDevice |
Abstraction of the programmable hardware pipeline with G3D preprocessor extensions.
Shaders are almost always invoked with the LAUNCH_SHADER macro, with arguments provided by the G3D::Args class. Many classes (including Framebuffer, ArticulatedModel::Pose, and LightingEnvironment) provide a UniformTable field that allows them to impose additional values on the Args used for shaders that incorporate them.
Shader supports macro arguments in addition to uniform and streaming (attribute, index) arguments. It caches all needed permutations of a shader that uses macros and then provides the correct instance at invokation time.
G3D introduces additional preprocessor commands GLSL:
The preprocessor automatically moves GLSL #version directives to the first line of a program before compilation.
The extended syntax "\#version v1 or v2 or ..." allows writing shaders that simultaneously target multiple GLSL versions. Shader will compie for the highest listed version number that the driver provides at runtime. Within the shader code, you can test against the VERSION macro to discover which version version is in use.
#include has three forms:
#include <filename.glsl>
Searches for the filename using G3D::System::findDataFile and inlines it.
#include "filename.glsl"
Loads the file relative to the including file.
#include MACRONAME
Loads the file specified by the fully qualified macro argument's value. The macro must be defined as a shader argument, not as a #define.
Every included file effectively has #pragma once
, which is done by the preprocessor to prevent infinitely recursive includes.
Shader expands
to
The upper bound cannot be a value set via #define...if it is a macro, then the macro must have been passed from C++ as an argument.
Example:
with NUM_LIGHTS
a macro arg with value "4", this code expands to:
The expression inside the $(...)
can also perform a single arithmetic expression of the form $(identifier operator number)
, where operator may be +, -, /, or *. If the number is an integer and the operator is /, then integer division is performed. Otherwise, the operation is performed at double precision.
The preprocessor inserts #line pragmas before each unrolled loop body, so errors will report correct line numbers.
The inner code then gets repeated for each value of field, and any occurence of in the inner code is replaced with the current value of field. Note that field can be replace with any string, and value* can be regular symbols or quoted strings.
Example:
becomes:
#eval(macroname)
is identical to just using macroname
if the macro contains no newlines and is a shader macro argument. It cannot be applied to macros that are defined in the shader using #define.
For shader macro arguments that contain newlines, #eval inserts their values with newlines and preserving surrounding line numbers for error reporting. Those macros are defined as blank for the regular preprocessor. This allows idioms such as:
G3D has two distinct preprocessing steps for shaders: load-time (e.g. include) and compile-time (for, foreach).
The load-time preprocessor is documented in Shader::g3dLoadTimePreprocessor().
The compile-time preprocessor currently only prepends Args::preambleAndMacroString() and evaluates the #for and #foreach commands ( Shader::expandForPragmas() )
Determines the behavior upon a load-time or compile-time error for all shaders.
Enumerator | |
---|---|
EXCEPTION | Throw an exception on load or compilation failure. |
PROMPT | Prompt the user to throw an exception, abort the program, or retry loading on load or compilation failure. (default) |
SILENT | ok() will be false if an error occurs |
|
protected |
No compilation, or even loading from files is performed at construction.
void G3D::Shader::bindG3DArgs | ( | const shared_ptr< ShaderProgram > & | p, |
RenderDevice * | renderDevice, | ||
const Args & | sourceArgs, | ||
int & | maxModifiedTextureUnit | ||
) |
Sets the g3d uniform variables such as g3d_objectToWorldMatrix (using values from renderDevice) args.
See Shader::g3dLoadTimePreprocessor for the declarations of all of the variables of this form that can be set by this function. Also binds them immediately, to avoid overhead of writing and reading into a datastructure
Also sets all uniforms of the form g3d_sz2D_textureName, where textureName is the name of any sampler type bound in sourceArgs. g3d_sz2D_textureName is a vec4 of the form (w, h, 1.0/w, 1.0/h), where w and h are the width and height of the texture named textureName.
void G3D::Shader::bindStreamArg | ( | const String & | name, |
const AttributeArray & | vertexRange, | ||
const ShaderProgram::AttributeDeclaration & | decl | ||
) |
Bind a single vertex attribute.
void G3D::Shader::bindStreamArgs | ( | const shared_ptr< ShaderProgram > & | program, |
const Args & | args, | ||
RenderDevice * | rd | ||
) |
Iterate over all formal parameters and bind all vertex attributes appropriately.
Also sets the glPatchParameter if the primitive type is patch.
void G3D::Shader::bindUniformArg | ( | const Args::Arg & | arg, |
const ShaderProgram::UniformDeclaration & | decl, | ||
int & | maxModifiedTextureUnit | ||
) |
Bind a single uniform variable.
void G3D::Shader::bindUniformArgs | ( | const shared_ptr< ShaderProgram > & | program, |
const Args & | args, | ||
bool | allowG3DArgs, | ||
int & | maxModifiedTextureUnit | ||
) |
Iterate over all formal parameters and bind all non-dummy variables appropriately.
Writes the maximum value of the texture unit that had a sampler bound to it to maxModifiedTextureUnit, so the caller can revert after the shading pass. (-1 if no samplers were bound).
|
static |
Converts texture types to their canonical value (anything that can be a sampler2D becomes GL_TEXTURE_2D, etc) all others are unmodified.
shared_ptr<ShaderProgram> G3D::Shader::compileAndBind | ( | const Args & | args, |
RenderDevice * | rd, | ||
int & | maxModifiedTextureUnit | ||
) |
Compile the shader and bind the arguments as necessary.
Adds the necessary g3d uniforms to args. Writes the maximum value of the texture unit that had a sampler bound to it to maxModifiedTextureUnit, so the caller can revert after the shading pass. (-1 if no samplers were bound).
|
static |
Creates a shader from the given specification, loads it from disk, and applies the g3d preprocessor.
|
inlinestaticprotectedinherited |
Like std::make_shared, but works for protected constructors.
Call as createShared<myclass>.
|
static |
The mode to use when applying the shader and args.
|
staticprotected |
Expands G3D #expect preprocessor instructions.
This is a load-time preprocessing step.
|
staticprotected |
Expands G3D #foreach pragmas found in processedSource into valid GLSL code.
Nested #foreach loops are processed from the outside in.
errorMessages is appended to if any errors are encountered with details.
The return value is true if not errors were encountered.
This is a load-time preprocessing step.
|
staticprotected |
Expands our #for pragmas found in processedSource into valid GLSL code.
Nested #for loops are processed from the outside in.
errorMessages is appended to if any errors are encountered with details.
The return value is true if no errors were encountered.
This is a load-time preprocessing step.
|
static |
bool G3D::Shader::g3dLoadTimePreprocessor | ( | const String & | dir, |
PreprocessedShaderSource & | source, | ||
String & | messages, | ||
GLuint | stage, | ||
const Args & | args | ||
) |
Execute all steps of the G3D load-time preprocessor engine.
Process Includes (adding #line directives where neccessary) Process Foreach macros (adding #line directives where neccessary) Process expect macros (adding #line directives where neccessary)
Process Version Line
messages | Any errors regarding inclusion of files are written here |
Returns a line directive in the format "#line X Y\n", where X is the lineNumber, and Y is an integer that maps to filename.
|
staticprotected |
If a shader of the given Specification exists, return it, otherwise create a new one.
Create a shader using all shaders specified by the given pattern.
Used to implement LAUNCH_SHADER.
|
protected |
Handle a compilation or loading error as specified by s_failureBehavior.
If this handles a compilation error, program can be overwritten with a correctly compiled shader (if s_failureBehaviord is PROMPT and the user reloads).
|
inline |
|
static |
True if type corresponding to an OpenGL image type.
|
static |
True if type corresponding to an OpenGL sampler type.
void G3D::Shader::loadAndPreprocess | ( | const Args & | args, |
Array< PreprocessedShaderSource > & | preprocessedSource | ||
) |
Load the shaders from files on disk, and run the preprocessor.
|
inline |
A name for this shader.
By default, this is the filename with a star instead of the extension, e.g., blur.*
Reads the code looking for a #extension line (spaces allowed after "#").
If one is found, remove it from code and put it in extensionLine.
bool G3D::Shader::processIncludes | ( | const String & | dir, |
String & | code, | ||
String & | messages, | ||
const Args & | args | ||
) |
Replaces all #includes in code with the contents of the appropriate files.
It is called recursively, so included files may have includes themselves. This is called automatically by the preprocessor, but is public so as to be accessible to code that directly manipulates source strings.
dir | The directory from which the parent was loaded. |
messages | Any errors regarding inclusion of files are written here |
Reads the code looking for a #version line (spaces allowed after "#").
If one is found, remove it from code and put it in versionLine, otherwise set versionLine to "#version 330\n".
void G3D::Shader::reload | ( | ) |
Reload this shader from the files on disk, if it was loaded from disk.
|
static |
Reloads all shaders throughout G3D.
shared_ptr<ShaderProgram> G3D::Shader::retry | ( | const Args & | args | ) |
Reload from files on disk (if it was loaded from disk), run all steps of the g3d preprocessor and recompile.
True iff a and b have the same SouceType and value.
|
staticprotected |
True iff every stage of a and b satisfy sameSource.
|
static |
Set the global failure behavior.
|
inline |
|
protected |
Finds a shader program in the cache that matches the supplied args, recompiling if necessary.
if compilation fails, returns nullptr and fills in messages with a report of what went wrong. Primarily intended for internal use by Shader; called from compileAndBind() and its variants.
|
static |
|
staticprotected |
Converts a type name to a GL enum.
void G3D::Shader::unbindStreamArgs | ( | const shared_ptr< ShaderProgram > & | program, |
const Args & | args, | ||
RenderDevice * | rd | ||
) |
Counterpart to bindStreamArgs.
Unbinds all vertex attributes that were set.
|
static |
A shader that accepts color and textureMap arguments and applies them directly without lighting.
This is like the old OpenGL fixed function, but supports colors and textures outside of the range [0, 1].
e.g., used by GFont and Draw::rect.
|
friend |
|
protected |
Maps preamble + macro definitions to compiled shaders.
Maps filenames to indices, so that we can correctly print #line directives.
|
protected |
A set of args solely for g3d uniforms.
We use this instead of modifying the args passed into compileAndBind(). This needs to be cleared every time we reload, or we will accidentally bind variables that don't exist in the compiled shader
Maps indices to filenames, so that we can correctly output filenames when we get file indices back from the shader on error messages.
|
protected |
Referenced by isCompute().
|
protected |
The next index to be used by a previously unprocessed file when #including, so that we can produce proper #line directives.
|
protected |
Contains the filenames or hardcoded source strings this shader was constructed from.
Array of all shaders ever created.
nullptr elements are flushed during reloadAll()
|
static |