Cross platform GLSL (ES)?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Cross platform GLSL (ES)?

lpvb
How can I use my x86-64 computer with intel integrated graphics to develop cross platform java opengl? I use the gl2es2 profile and then what do I do about the glsl shaders? Can I make ES shaders or do I have to change the version specifier when I load them or what? Thanks.
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

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

1. GLSL VERSION >= 130 uses in and out keywords instead of attributes and varying.  GLSL VERSION >= 130 also require the fragment shader to explicitly define the out variable. GLSL VERSION >= 130 compatibility can be handled 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:
http://jogamp.org/git/?p=jogl.git;a=tree;f=src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/shader;hb=HEAD


2. Some OpenGL contexts require the GLSL #version to be explicitly set at the start of the shader or else it will refuse to compile the shader. The GLSL #version must match a version that is compatible with the OpenGL context or else the shader will refuse to compile.

JogAmp JOGL can return the matching String containing the #version you need to add by analysing the context at runtime by using: gl.getContext().getGLSLVersionString()

http://jogamp.org/deployment/jogamp-current/javadoc/jogl/javadoc/com/jogamp/opengl/util/glsl/ShaderCode.html#addGLSLVersion%28javax.media.opengl.GL2ES2%29

3. You need to add a default precision qualifier if you target es2 es3 or gl3 opengl contexts.

You can use the com.jogamp.opengl.util.glsl.ShaderCode defaultShaderCustomization to add the GLSL shader customization required by your OpenGL context this will allow the shader to work on both desktop and mobile.
http://jogamp.org/deployment/jogamp-current/javadoc/jogl/javadoc/com/jogamp/opengl/util/glsl/ShaderCode.html#addDefaultShaderPrecision%28javax.media.opengl.GL2ES2,%20int%29


2 & 3 can be fixed in one go by using the com.jogamp.opengl.util.glsl.ShaderCode class to load your shaders from disk and customize them using defaultShaderCustomization

http://jogamp.org/deployment/jogamp-current/javadoc/jogl/javadoc/com/jogamp/opengl/util/glsl/ShaderCode.html#defaultShaderCustomization%28javax.media.opengl.GL2ES2,%20boolean,%20boolean%29

Look at how GLSL shaders are loaded inside the jogamp jogl junit tests using ShaderCode for cross platform GLSL use.
http://jogamp.org/git/?p=jogl.git;a=blob;f=src/test/com/jogamp/opengl/test/junit/jogl/demos/es2/RedSquareES2.java;hb=HEAD#l91

Cheers
Xerxes
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

io7m
Additionally, ES2 (GLSL ES 1.0) has restrictions on the types that can be used as attributes. Specifically:

"The attribute qualifier can be used only with the data types float, vec2, vec3, vec4, mat2, mat3, and
mat4. Attribute variables cannot be declared as arrays or structures."

From the GLSL ES 1.0 spec, section 4.3.3.

Also, GLSL ES 1.0 doesn't allow for multiple fragment shader outputs (specifically, it restricts the number of
possible framebuffer color attachments to 1), so any shaders that use multiple outputs
there have to be rewritten. In GLSL <= 1.20, writing to multiple fragment shader outputs meant writing
to gl_FragData[0 .. n]. This will still work in GLSL ES 1.0, but the gl_FragData array will consist of only one
element. In 1.30, outputs have to be declared as "out" parameters and then associated with
a specific "location" with glBindFragDataLocation. In GLSL 1.40 and above, "out" parameters can be assigned
specific locations with the location directive. For example: "layout(location = 0) out vec4 output". In ES3,
the situation is the same as GLSL 1.40 and above.
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

gouessej
Administrator
Maybe we should copy io7m's tips somewhere in the wiki. This is typically the kind of thing I don't want to forget.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

io7m
In reply to this post by lpvb
I'm not sure this really answered the original question, which was "How can I use my x86-64 computer with intel integrated graphics to develop cross platform java opengl?".

The actual answer is, assuming you're on a system that does support ES2/3 (which if you're on Linux on Intel
is a definite yes - everything newer than about 2008 can do ES2 with a reasonably recent version of Mesa, and
everything on Sandy Bridge and newer can do ES3):

1. Ask JOGL for a GLES2 (or GLES3) context, using a GLES2/GLES3 GLProfile.
2. Supply GLSL ES 1.0/3.0 shaders.
3. Try desperately to stick to the GL ES2/ES3 spec!

You'll find that ES2 is pretty crippled compared to ordinary desktop OpenGL, and it's incompatible in numerous
small ways. ES3 is much better, but I've no idea how much support it has on mobile platforms yet. It didn't come
out all that long ago.
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

io7m
In reply to this post by gouessej
The list of differences is long and frustrating! A *lot* of them are functions taking a subset of the available
GLEnum values (which is irritating, as they're not compile-time errors). Some functions are simply not present.
Some of it is just outright incompatible behaviour that doesn't match that of any other OpenGL version.

Off the top of my head:

glTexImage* requires that the "format" and "internalformat" parameters must match, and can only be one of
GL_ALPHA, GL_LUMINANCE, GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA. This is incompatible with every other
OpenGL version.

The restrictions on attribute types, as described earlier.

The restrictions on the number of framebuffer color attachments, as described earlier.

A complete lack of any concept of "read" framebuffers; the result is actually a subset of 3.0 and the four
framebuffer extensions JOGL uses to give equivalent behaviour on 2.1 (GL_ARB_framebuffer_object |  GL_EXT_framebuffer_object, GL_EXT_framebuffer_multisample, GL_EXT_framebuffer_blit, GL_EXT_packed_depth_stencil).

An amusing one is the stencil buffer: The majority of implementations don't support separate depth and stencil
framebuffer attachments, so you're required to use GL_OES_packed_depth_stencil to actually get a stencil buffer
at all (you're certainly not going to be doing any significant work rendering without a depth buffer).

I can't seem to remember any more. These are mostly things I've been working around for some eighteen
months in http://mvn.io7m.com/jcanephora...
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

Sven Gothel
Administrator
In reply to this post by Xerxes Rånby
On 12/13/2013 02:02 PM, Xerxes Rånby [via jogamp] wrote:
> In order to create cross platform GLSL shaders the following three points have
> to be taken into account:
>

Thank you Xerxes .. I went ahead and added it to our Wiki
and edited your text a bit:

https://jogamp.org/wiki/index.php/How_to_write_cross_GLProfile_compatible_shader_using_JOGL

Additions are very welcome!

~Sven


signature.asc (911 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Cross platform GLSL (ES)?

Sven Gothel
Administrator
In reply to this post by io7m
On 12/14/2013 01:27 AM, io7m [via jogamp] wrote:

https://jogamp.org/wiki/index.php/How_to_write_cross_GLProfile_compatible_shader_using_JOGL

.. added .. to be refined ..

~Sven


signature.asc (911 bytes) Download Attachment