Since GLSL doesn't have an include-file option I'm trying to add this by using a "#pragma include" parser. (I want this because I have some generic methods I'd like to implement only once but might use in many different shaders, like Ken Perlin's smootherstep)
Parsing the shader 开发者_如何学Gofiles to get the included files works fine. But when setting the ShaderSource with the multiple source files I always run into problems; since my main shader normally starts with "#version 330" and the #version-line always has to be the first line in the shader, I can only add my main file as the first in the array of strings passed to glShadersource, and after that all the included files. But then my main file can't use any functions implemented in those included files, since they'll essentially be concatenated after my main file so the compiler complains that it doesn't know the functions my main file is using.
The only way I can think of to get it to work is to read the main file, parse the include pragma, and then replace that pragma line with the file-contents of the file to be included (recursively applying this same method to all included files that might include other files themselves) - but that would mean the linenumbers in compilation-errors would not match the real linenumbers of the main file anymore.
Has anybody set up some sort of "include" functionality for GLSL that works AND keeps the linenumbers ? And if so - how ?
What about parsing for the #version
tag and making this a seperate (and the first) source string? This way you may also have different version tags in the includes (depending on their functions requirements) and just reduce them to only one version tag (the one with the highest version number).
First all, there is the #line
preprocessor directive which set the current source line reported in compiler error messages. Using this preprocessor directive you can make it easy in including external source lines. This should solve your problem.
Additionally, I've read the shading_language_include extension, which should aid you to support "include" functionalities. If your driver has not implemeneted it, you could still support the syntax that extension introduce, so you can gracefully support shaders requiring that extension.
If your shaders are in files, you can use cpp (or gcc -E) to process them (and deal with any #include directives) before passing them to openGL. You can even something like popen("cpp -P main.glsl", "r")
to read and preprocess your shader...
精彩评论