Search code examples
opengl-es-2.0glslglsles

Does OpenGL (and OpenGL ES) support preprocessor "line continuation" characters?


I've got a macro in my OpenGL ES fragment shader that looks like this:

#define CHECK(x, DELTA, outColor, c1, c2) \
  if (x < (delta + (DELTA))) { \
    outColor = mix(c1, c2, smoothstep(delta, min(1.0, delta + (DELTA)), x)); \
    x = 10.0; /*skip all subsequent CHECKs */ \
  } \
  delta += DELTA; 

This works fine on my desktop, and on a variety of Android devices. (Yeah, I need to move away from the explicit flow control, but it gets the output I want for now.) The problem is that a few devices fail to compile this shader with errors like:

 0:257: L0002: Undeclared variable 'DELTA'
,0:260: L0001: Expected literal or '(', got '\'
,0:263: L0001: Expected literal or '('...

(Line 257 is the "if ( x" line, line 260 is the "} \" line, and 263 is not shown here, its the first use of the CHECK macro. There are no other instances of all-caps "DELTA" elsewhere in the shader.)

I think this error means they're tripping up on the line-continuation characters? Is this really something that only some GLSL compilers support?

I'm building my shaders with #version 100 to be as compatible as possible between desktop and Android.


Solution

  • OpenGL

    No

    The v1.20.8 OpenGL GLSL spec says "No". Section 3.1 "Basis. Character Set" contains:

    There is no line continuation character.

    See: http://www.opengl.org/registry/doc/GLSLangSpec.Full.1.20.8.pdf or http://www.opengl.org/registry/doc/GLSLangSpec.1.50.09.pdf

    Well, yes

    In a later version (v4.30.6) of the spec support for line-continuation characters was added. See: http://www.opengl.org/registry/doc/GLSLangSpec.4.30.6.pdf. I'm not clear when this was added.

    Older "#version" directives like (#version 100) do not seem to disable line continuations (at least on my Nvidia desktop driver).

    OpenGL ES

    No, maybe

    Section 1.5 "Compatibility" says:

    Support of line continuation and support of UTF-8 characters within comments is optional in GLSL ES 1.00 when used with the OpenGL ES 2.0 API. However, support is mandated for both of these when a GLSL ES 1.00 shader is used with the OpenGL ES 3.0 API.

    See http://www.khronos.org/registry/gles/specs/3.0/GLSL_ES_Specification_3.00.3.pdf

    Summary

    Newer GLSL specifications include support for line continuation characters, but in practice this support is not disabled for explicitly versioned shaders. Older GLSL compilers may not support line continuation characters, so for maximum compatibility they should be avoided.