Just a quick post to help people who might be having the same issues I was; using shaders written for OpenGL ES (or WebGL) in a non-embedded OpenGL environment.
Say you have a simple vertex shader:
If you try to compile this shader program on regular OpenGL you’ll get errors like these:
unrecognized profile specifier "mediump"
syntax error, unexpected identifier, expecting "::" at token "lowp"
That’s because OpenGL ES requires you to specify a default precision profile, and lets you specify per variable how high the precision is. The problem is, these keywords don’t exist in regular OpenGL and will cause errors if you try to compile them. Technically you’re supposed to have the shader language version as the first line of the shader, so the first thing I found out that adding #version 100
to the top of the file made this work on my computer. While I’m not 100% sure, I don’t think you can rely on this solution across hardware and driver combinations. So we need something better.
The second solution is to use preprocessor directives to test if we’re running GLES or not, like so:
Obviously, this solution works but is kind of too awful to express in words. Fortunately, there’s a better way. Because calls to glShaderSource
take a string, we can use a preprocessor outside of the shader to tack on a different shader header, assuming you only need one #version
in your non-embedded environment. Just insert the below depending on whether your project is compiled for OpenGL or OpenGL ES 2.0:
OpenGL:
OpenGL ES:
The macros will turn the precision keywords into blank space during the preprocessor phase, causing the shader to compile. You’ll also want to wrap the default precision statement with #ifdef GL_ES
and #endif
as shown above. Keep in mind that when I tried to do a multi-line string literal for the header in C# I got this error when trying to compile:
EOF/EOL inside preprocessor string
I’ve seen others who had similar issues with finicky linebreaks. Using Environment.NewLine
or simply \n
or a combination \r
and \n
fixed the issue. Finally if you’re wondering what that #version 110
is all about like I was, the version numbers don’t correspond to OpenGL versions, but to (the first three digits of) GLSL versions, with 100 having special significance to denote the GLSL version used for OpenGL ES 2.0.
Hope that was helpful, and happy coding!