Hi everyone.
I’m developing a cross platform engine which works with both the Core profile and OpenGL ES 2.0 (iPhone). I’ve encountered a problem with the #version preprocessor directive.
For OpenGL >= 3.3 (core profile), the value of #version is 330. This will reject all deprecated GLSL commands (this is what I want). However, for OpenGL ES 2.0, #version is set to 100.
How does one use the same shader source for both code bases? I can get around the issue by dynamically modifying the shader source before compilation (replacing #version with platform definition), but then I’m not using the same shader source anymore.
Edit: OK, I found the answer I was looking for. OpenGL ES 2.0 has a new preprocessor definition called GL_ES. Now I can do #version checks. Leaving this post here in case someone else runs into the same problem.
‘The #version directive must occur in a shader before anything else, except for comments and white space.’
#ifndef GL_ES
#version 330
#endif
appears to be illegal.
NVIDIA doesnt care, ATI does however and on my driver fails compilation.
Yes, I’ve read about that clause and had concerns (since I dynamically add preprocessor defintions at the beginning of the shader file), but experienced no issues on nVidia 250 hardware (Windows and Linux). Since my engine knows which code path to use, I guess that I have no choice but to manually prepend the correct version info when constructing the shader. It’s a shame I cannot rely on #ifdef GL_ES on AMD hardware.
Just use another shader string. It doesn’t have to be the first thing in a shader string; just the first thing in the first shader string. Remember: the way multiple strings works is that they are concatenated together to form the input before compilation. So just have the first string be “#version 330” for OpenGL, and whatever other version you need for GL ES.
You can do that, but I think what Alfonse was referring to is that glShaderSource takes an “array of strings”, not just a single string. Make the first string in the array just a “#version …” string. Nets you the same thing as the above, but selection could depend on a run-time sensed setting as well.