While loops and dynamic branching in OpenGL ES 2.0 GLSL?


I’ve bought myself a Nexus 7 tablet and played a bit with the jME Android Deployment. Works really nice.

When enabling steep parallax mapping of the lighting shader, I get the following exception:


W/OGLESShaderRenderer( 3212): WARNING OGLESShaderRenderer 21:49:22 Bad compile of:

[…] // here comes parallax.glsllib code

E/AndroidHarness( 3212): com.jme3.renderer.RendererException: compile error in:ShaderSource[name=Common/MatDefs/Light/Lighting.frag, defines, type=Fragment, language=GLSL100] error:(267) : error C5011: profile does not support “while” statements and “while” could not be unrolled.


I’ve tried to alter GLSL100 to GLSL120 for the fragment shader in the Lighting.j3md, but that led to:


W/dalvikvm( 4192): threadid=11: thread exiting with uncaught exception (group=0x40b6c300)

E/AndroidHarness( 4192): Exception thrown in Thread[GLThread 807,5,main]

E/AndroidHarness( 4192): java.lang.IllegalStateException: Cannot render mesh without shader bound

E/AndroidHarness( 4192): at com.jme3.renderer.android.OGLESShaderRenderer.setVertexAttrib(OGLESShaderRenderer.java:1825)

E/AndroidHarness( 4192): at com.jme3.renderer.android.OGLESShaderRenderer.setVertexAttrib(OGLESShaderRenderer.java:1830)

E/AndroidHarness( 4192): at com.jme3.renderer.android.OGLESShaderRenderer.renderMeshDefault(OGLESShaderRenderer.java:2064)

E/AndroidHarness( 4192): at com.jme3.renderer.android.OGLESShaderRenderer.renderMesh(OGLESShaderRenderer.java:2096)

E/AndroidHarness( 4192): at com.jme3.material.Material.render(Material.java:1063)

E/AndroidHarness( 4192): at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:523)

E/AndroidHarness( 4192): at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:301)

E/AndroidHarness( 4192): at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:353)

E/AndroidHarness( 4192): at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:763)

E/AndroidHarness( 4192): at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:719)

E/AndroidHarness( 4192): at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:983)

E/AndroidHarness( 4192): at com.jme3.renderer.RenderManager.render(RenderManager.java:1029)

E/AndroidHarness( 4192): at com.jme3.app.SimpleApplication.update(SimpleApplication.java:251)

E/AndroidHarness( 4192): at com.jme3.app.AndroidHarness.update(AndroidHarness.java:485)

E/AndroidHarness( 4192): at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:332)

E/AndroidHarness( 4192): at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1516)

E/AndroidHarness( 4192): at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1240)


My question: Are loops with dynamic condition / dynamic branching possible on Android? Is it just my Tegra 3? Or do I have to select another “profile” (how?)?

Edit: I guess I found the answer in the OpenGL ES 2.0 spec…

Flow Control

In general, flow control is limited to forward branching and to loops that can be easily unrolled.
Forward branching is allowed, both for constant and non-constant conditions. Therefore if-then, if-thenelse,
break and continue statements are permitted.
Backward branching is only permitted for constant iteration loops as defined below.
In the following section, loop indices are defined as all the non-constant variables appearing in the branch
condition expression in a loop.

for loops are supported but with the following restrictions:
• There is one loop index.
• The loop index is initialized to a constant expression in the for_header
• The condition expression is of the form
loop_index relational_operator constant_expression
where relational_operator is one of: > >= < <= == or !=
The loop index is modified only in the for_header using one of the following forms:
loop_index += constant_expression
loop_index -= constant_expression
• Within the body of the loop, the loop index is not statically assigned to nor is it used as the
argument to a function out or inout parameter.

Support for while and do-while are not mandated.

Dynamic branching is not supported in OpenGL ES 2.0, this means advanced shader features like steep parallax won’t work on Android.