Using #ifdef in OpenGL ES 2.0 shaders

It’s nice to use #ifdef’s in an OpenGL shader. This allows a shader file do things like contain a vertex shaders and pixel shaders in the same file. Or have different render paths selected at run time. Here is an example of a simple shader file:

To use a shader in OpenGL ES, the program will typically:
1. Load a file
2. Compile the shader
3. Link the shader

Before compiling the shader, the program calls glShaderSource to set the shader source. The real trick is with glShaderSource. This function can take multiple strings and combines them for compilation.

Here is a code sample that compiles a shader given a string (ShaderData) and the size of the string (Size). The function is passed a type (Type) which is defined as GL_VERTEX_SHADER or GL_FRAGMENT_SHADER. This function uses an #ifdef to compile the source as a vertex or pixel shader:

The documentation for glShaderSource says that the function can be called with string lengths of 0 for NULL terminated strings. However, for my implementation of OGLES 2 this did not work, so I had to specify the individual string lengths (as defined in ShaderStringLengths for this example).

With #ifdef’s, an application can modify a shader at runtime. It’s possible to enable/disable features like post processing effects, dynamic lighting, and more based on #defines. Best of luck!
For more complete information about compiler optimizations, see our Optimization Notice.