I want to be able to do these things:
- Write GLSL shaders
- Separate my sources for reusability purposes
- Validate all my sources before building the main application, and exit if anything fails
The GLSL standard is written so that you can specify multiple source strings to a single shader, and it will combine them. Shaders will also pass verification with C-style prototype-and implementation structure. For example, the following pseudocode shader:
#version 460
out vec4 color;
vec4 getColor() {
return vec4(0.0, 1.0, 0.0, 0.0);
}
void main() {
color = getColor();
}
Could be separated into this string:
#version 460
out vec4 color;
vec4 getColor();
void main() {
color = getColor();
}
and this string:
vec4 getColor() {
return vec4(0.0, 1.0, 0.0, 0.0);
}
By putting each in its own file to pass to glslangvalidator, I would hope you could validate them separately.
But there's a problem, and that problem is the #version directive. If I specify #version 460 at the start of all my sources, then when OpenGL combines them, the #version will be defined twice, which is not allowed. But if I don't, glslangvalidator will assume version 100, and the sources will not validate properly.
I've considered a few options:
- Dynamically remove the #version directive using string manipulation function when I read the source files to embed the sources in the application. This sounds like it could work, but it also feels like a hacky workaround.
- Dynamically add the #version directive to a duplicate file and run glslangvalidator against that instead. This also sounds like it could work, but it raises doubt about the validity of the validation (it validated against a slightly different source, after all).
- Specify the GLSL version at command line. For some reason, the tool only seems to accept version 100 at command line, when I need version 460.
- #ifndef gates. The validator raises an error with this because #version has to be the very first thing in the source, without even an exception allowed for preprocessor ifs.
Is there a canonical solution to this? Perhaps something I've overlooked in the GLSL spec, or an additional flag for the validator, or even an alternate tool I can use?