How to write cross GLProfile compatible shader using JOGL

From JogampWiki
Revision as of 03:54, 14 December 2013 by Sgothel (talk | contribs)
Jump to navigation Jump to search

Note: To be refined / edited!

In order to create cross platform GLSL shaders the following three points have to be taken into account:

GLSL Version Directive

Some OpenGL implementations require the GLSL version directive #version <number> to be explicitly included in the shader source as the first directive.

The GLSL version directive shall match the OpenGL version of the context, see GLContext's GLSLVersionNumber.

If any of above requirements are not fulfilled the shader code compilation might fail on certain platforms and OpenGL version.

Users may compose their shader at runtime to comply with the GLSL version directive utilizing JOGL's features:

GLSL Precision Directive

In case you target ES2, ES3 or >= GL3 OpenGL contexts one needs to add a precision qualifier to your variable declarations or use a shader wide default precision qualifier directive.

Users may either add such precision directive in their code in a fine grained manner adjusting precision to their tasks, or they may utilize a JOGL's feature:

GLSL Version & Default Precision Directive

The GLSL version and default precision directives maybe performed by the ShaderCode class, which can load your code from an input stream (URI source) or CharSequence array and customize it appropriately via defaultShaderCustomization(..).

ShaderCode also allows users to perform further custom editing on the fly.

Have a look at how GLSL shaders are loaded inside the jogamp jogl junit tests using ShaderCode for cross platform GLSL use: RedSquareES2.

final ShaderCode vp0 = ShaderCode.create(gl, GL2ES2.GL_VERTEX_SHADER, this.getClass(), "shader", "shader/bin", "RedSquareShader", true);
final ShaderCode fp0 = ShaderCode.create(gl, GL2ES2.GL_FRAGMENT_SHADER, this.getClass(), "shader", "shader/bin", "RedSquareShader", true);
vp0.defaultShaderCustomization(gl, true, true);
fp0.defaultShaderCustomization(gl, true, true);
final ShaderProgram sp0 = new ShaderProgram();
sp0.add(gl, vp0, System.err);
sp0.add(gl, fp0, System.err);

GLSL Version Compatibility

GLSL Version >= 130

GLSL version >= 130 uses in and out keywords instead of attributes and varying. it also requires the fragment shader to explicitly define the out variable. Compatibility with previous GLSL versions can be reached by adding some GLSL pre-processor defines at the beginning of the shaders.

Vertex shader:

#if __VERSION__ >= 130
   #define attribute in
   #define varying out
#endif

Fragment shader:

#if __VERSION__ >= 130
   #define varying in
   out vec4 mgl_FragColor;
 #else
   #define mgl_FragColor gl_FragColor  
#endif

Look at the Cross platform GLSL shaders used by the JogAmp JOGL junit tests how to add the pre-processor defines:

JOGL Unit Test Shader.