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:

precision mediump float;

uniform mat4 matrixTransform;

attribute vec3 inputPosition;
attribute lowp vec4 inputColor;
attribute vec2 inputTexCoords;

varying lowp vec4 vColor;
varying vec2 vTexCoords;

void main() {
    gl_Position = matrixTransform * vec4(inputPosition, 1);
    vColor = inputColor;
    vTexCoords = inputTexCoords;
}

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:

#ifdef GL_ES
precision mediump float;
#endif

uniform mat4 matrixTransform;

attribute vec3 inputPosition;
#ifdef GL_ES
attribute lowp vec4 inputColor;
#else
attribute vec4 inputColor;
#endif
attribute vec2 inputTexCoords;

#ifdef GL_ES
varying lowp vec4 vColor;
#else
varying vec4 vColor;
#endif
varying vec2 vTexCoords;

void main() {
    gl_Position = matrixTransform * vec4(inputPosition, 1);
    vColor = inputColor;
    vTexCoords = inputTexCoords;
}

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:

#version 110
#define highp
#define mediump
#define lowp

OpenGL ES:

#version 100

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!