Embed preprocessor definitions into GLSL source code.
This function generates and inserts #define
statements into existing
GLSL source code, allowing one to use GLSL preprocessor statements to alter
program source at compile time.
Passing {'MAX_LIGHTS': 8, 'NORMAL_MAP': False}
to defs will create and
insert the following #define
statements into shaderSrc:
#define MAX_LIGHTS 8
#define NORMAL_MAP 0
As per the GLSL specification, the #version
directive must be specified
at the top of the file before any other statement (with the exception of
comments). If a #version
directive is present, generated #define
statements will be inserted starting at the following line. If no
#version
directive is found in shaderSrc, the statements will be
prepended to shaderSrc.
Using preprocessor directives, multiple shader program routines can reside
in the same source text if enclosed by #ifdef
and #endif
statements
as shown here:
#ifdef VERTEX
// vertex shader code here ...
#endif
#ifdef FRAGMENT
// pixel shader code here ...
#endif
Both the vertex and fragment shader can be built from the same GLSL code
listing by setting either VERTEX
or FRAGMENT
as True:
vertexShader = gltools.compileShaderObjectARB(
gltools.embedShaderSourceDefs(glslSource, {'VERTEX': True}),
GL.GL_VERTEX_SHADER_ARB)
fragmentShader = gltools.compileShaderObjectARB(
gltools.embedShaderSourceDefs(glslSource, {'FRAGMENT': True}),
GL.GL_FRAGMENT_SHADER_ARB)
In addition, #ifdef
blocks can be used to prune render code paths. Here,
this GLSL snippet shows a shader having diffuse color sampled from a texture
is conditional on DIFFUSE_TEXTURE
being True, if not, the material
color is used instead:
#ifdef DIFFUSE_TEXTURE
uniform sampler2D diffuseTexture;
#endif
...
#ifdef DIFFUSE_TEXTURE
// sample color from texture
vec4 diffuseColor = texture2D(diffuseTexture, gl_TexCoord[0].st);
#else
// code path for no textures, just output material color
vec4 diffuseColor = gl_FrontMaterial.diffuse;
#endif
This avoids needing to provide two separate GLSL program sources to build shaders to handle cases where a diffuse texture is or isn’t used.
shaderSrc (str) – GLSL shader source code.
defs (dict) – Names and values to generate #define
statements. Keys must all be
valid GLSL preprocessor variable names of type str. Values can only be
int, float, str, bytes, or bool types. Boolean values True
and False are converted to integers 1 and 0, respectively.
GLSL source code with #define
statements inserted.
Examples
Defining MAX_LIGHTS
as 8 in a fragment shader program at runtime:
fragSrc = embedShaderSourceDefs(fragSrc, {'MAX_LIGHTS': 8})
fragShader = compileShaderObjectARB(fragSrc, GL_FRAGMENT_SHADER_ARB)