[SOLVED] Android - SkyControl Exception

Hello @sgold ,
I tried using your SkyControl lib on Android device (both real & emulator) and I’m getting this exception:

2021-06-08 09:31:22.712 14103-14471/com.abware.scenemax3dgamehub E/AndroidRuntime: FATAL EXCEPTION: GLThread 660
    Process: com.abware.scenemax3dgamehub, PID: 14103
    java.lang.UnsupportedOperationException: No technique 'Default' on material 'dome20' is supported by the video hardware. The capabilities [GLSL110] are required.
        at com.jme3.material.Material.selectTechnique(Material.java:776)
        at com.jme3.material.Material.render(Material.java:1000)
        at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:634)
        at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
        at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
        at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:903)
        at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:799)
        at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1128)
        at com.jme3.renderer.RenderManager.render(RenderManager.java:1180)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:273)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
2021-06-08 09:31:22.712 14103-14471/com.abware.scenemax3dgamehub E/com.jme3.app.AndroidHarnessFragment: SEVERE Exception thrown in Thread[GLThread 660,5,main]
    java.lang.UnsupportedOperationException: No technique 'Default' on material 'dome20' is supported by the video hardware. The capabilities [GLSL110] are required.
        at com.jme3.material.Material.selectTechnique(Material.java:776)
        at com.jme3.material.Material.render(Material.java:1000)
        at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:634)
        at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
        at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
        at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:903)
        at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:799)
        at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1128)
        at com.jme3.renderer.RenderManager.render(RenderManager.java:1180)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:273)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

Is it a know limitation that SkyControl lib does not work on Android?

Thank you.

3 Likes

I am not good at shaders, but I think the problem may be as simple as adding GLSL300 or 310 like what PBR shaders does :

Notice : desktop uses GLSL110 as of minimum usage while android oGLES 1.0 was deprecated & not usable & doesn’t support shaders by any means(fixed pipeline), so the lowest version of possible glsl for embedded devices(android & Raspi) is glsl200, so as jme PBRLighting.j3md does, it declares a minimum of glsl300, you may try to do so at first then if it works, try downgrading to glsl200 which also supports shaders or add both.

So, at dome20.j3md at the Technique{} block add GLSL300, GLSL200, GLSL310 for both the FragmentShader & the VertexShader definitions, because there is no glsl110 on android devices, it was past when android was an emulator only (android 1.0 & even tho no shader support), but don’t remove glsl110 because its usable by desktop.

2 Likes

Thanks! I can try that but I consume JME via gradle build script. Does it mean that I must compile & use jars instead?

1 Like

Jars are compiled code too, you cannot edit jars code, the best thing to do is to either download a zip version of SkyControl code, do your changes & attach it as an android or java module, or clone the repo into intellij, do changes, build a snapshot & reuse the snapshot.

Ill try that and report if it succeed fixing the issue

1 Like

I have not used skycontrol before, just in case the dome20.j3md is accessible via java code like what jme3 does in Material loading, you can just download the dome20.j3md, add the modifications & use it directly through the java code.

OK. I have changed the j3md files for all domes and now I’m getting some kind of syntax error:

2021-06-09 08:58:54.096 24199-24248/com.abware.scenemax3dgamehub W/com.jme3.renderer.opengl.GLRenderer: WARNING Bad compile of:
    1	#version 300 es
    2	precision highp float;
    3	precision highp sampler2D;
    4	precision highp sampler3D;
    5	precision highp sampler2DShadow;
    6	precision highp sampler2DArray;
    7	#define FRAGMENT_SHADER 1
    8	#define HAS_OBJECT0 1
    9	#define HAS_OBJECT1 1
    10	#define HAS_HAZE 1
    11	/*
    12	 Copyright (c) 2014, Stephen Gold
    13	 All rights reserved.
    14	
    15	 Redistribution and use in source and binary forms, with or without
    16	 modification, are permitted provided that the following conditions are met:
    17	    * Redistributions of source code must retain the above copyright
    18	      notice, this list of conditions and the following disclaimer.
    19	    * Redistributions in binary form must reproduce the above copyright
    20	      notice, this list of conditions and the following disclaimer in the
    21	      documentation and/or other materials provided with the distribution.
    22	    * Neither the name of the copyright holder nor the names of its contributors
    23	      may be used to endorse or promote products derived from this software
    24	      without specific prior written permission.
    25	
    26	 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
    27	 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    28	 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    29	 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
    30	 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
    31	 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
    32	 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    33	 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
    34	 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    35	 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    36	 */
    37	
    38	/*
    39	 * fragment shader used by dome20.j3md
    40	 */
    41	uniform vec4 m_ClearColor;
    42	varying vec2 skyTexCoord;
    43	
    44	#ifdef HAS_STARS
    45	        uniform sampler2D m_StarsColorMap;
    46	#endif
    47	
    48	#ifdef HAS_OBJECT0
    49	        uniform vec4 m_Object0Color;
    50		uniform sampler2D m_Object0ColorMap;
    51		varying vec2 object0Coord;
    52	#endif
    53	
    54	#ifdef HAS_OBJECT1
    55	        uniform vec4 m_Object1Color;
    56		uniform sampler2D m_Object1ColorMap;
    57		varying vec2 object1Coord;
    58	#endif
    59	
    60	#ifdef HAS_HAZE
    61	        uniform sampler2D m_HazeAlphaMap;
    62	        uniform vec4 m_HazeColor;
    63	#endif
    64	
    65	vec4 mixColors(vec4 color0, vec4 color1) {
    66	        vec4 result;
    67	        float a0 = color0.a * (1.0 - color1.a);
    68	        result.a = a0 + color1.a;
    69	        if (result.a > 0.0) {
    70	                result.rgb = (a0 * color0.rgb + color1.a * color1.rgb)/result.a;
    71	        } else {
    72	                result.rgb = vec3(0.0);
    73	        }
    74	        return result;
    75	}
    76	
    77	void main() {
    78	        #ifdef HAS_STARS
    79	                vec4 stars = texture2D(m_StarsColorMap, skyTexCoord);
    80	        #else
    81	                vec4 stars = vec4(0.0);
    82	        #endif
    83	
    84	        vec4 objects = vec4(0.0);
    85	
    86	        #ifdef HAS_OBJECT0
    87	                if (floor(object0Coord.s) == 0.0 && 
    88	                    floor(object0Coord.t) == 0.0) {
    89	                        objects = m_Object0Color;
    90	                        objects *= texture2D(m_Object0ColorMap, object0Coord);
    91	                }
    92		#endif
    93	
    94	        #ifdef HAS_OBJECT1
    95	                if (floor(object1Coord.s) == 0.0 && 
    96	                    floor(object1Coord.t) == 0.0) {
    97	                        vec4 object1 = m_Object1Color;
    98	                        object1 *= texture2D(m_Object1ColorMap, object1Coord);
    99	                        objects = mixColors(objects, object1);
    100	                }
    101		#endif
    102	
    103	        vec4 color = mixColors(stars, objects);
    104	
    105	        vec4 clear = m_ClearColor;
    106		#ifdef HAS_HAZE
    107	                vec4 haze = m_HazeColor;
    108	                
2021-06-09 08:58:54.099 24199-24248/com.abware.scenemax3dgamehub E/AndroidRuntime: FATAL EXCEPTION: GLThread 770
    Process: com.abware.scenemax3dgamehub, PID: 24199
    com.jme3.renderer.RendererException: compile error in: ShaderSource[name=Shaders/skies/dome20/dome20.frag, defines, type=Fragment, language=GLSL300]
    ERROR: 0:42: 'varying' : Illegal use of reserved word 
    
        at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1516)
        at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1543)
        at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1608)
        at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:96)
        at com.jme3.material.Technique.render(Technique.java:167)
        at com.jme3.material.Material.render(Material.java:1033)
        at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:634)
        at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
        at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
        at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:903)
        at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:799)
        at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1128)
        at com.jme3.renderer.RenderManager.render(RenderManager.java:1180)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:273)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
2021-06-09 08:58:54.099 24199-24248/com.abware.scenemax3dgamehub E/com.jme3.app.AndroidHarnessFragment: SEVERE Exception thrown in Thread[GLThread 770,5,main]
    com.jme3.renderer.RendererException: compile error in: ShaderSource[name=Shaders/skies/dome20/dome20.frag, defines, type=Fragment, language=GLSL300]
    ERROR: 0:42: 'varying' : Illegal use of reserved word 
    
        at com.jme3.renderer.opengl.GLRenderer.updateShaderSourceData(GLRenderer.java:1516)
        at com.jme3.renderer.opengl.GLRenderer.updateShaderData(GLRenderer.java:1543)
        at com.jme3.renderer.opengl.GLRenderer.setShader(GLRenderer.java:1608)
        at com.jme3.material.logic.DefaultTechniqueDefLogic.render(DefaultTechniqueDefLogic.java:96)
        at com.jme3.material.Technique.render(Technique.java:167)
        at com.jme3.material.Material.render(Material.java:1033)
        at com.jme3.renderer.RenderManager.renderGeometry(RenderManager.java:634)
        at com.jme3.renderer.queue.RenderQueue.renderGeometryList(RenderQueue.java:273)
        at com.jme3.renderer.queue.RenderQueue.renderQueue(RenderQueue.java:315)
        at com.jme3.renderer.RenderManager.renderViewPortQueues(RenderManager.java:903)
        at com.jme3.renderer.RenderManager.flushQueue(RenderManager.java:799)
        at com.jme3.renderer.RenderManager.renderViewPort(RenderManager.java:1128)
        at com.jme3.renderer.RenderManager.render(RenderManager.java:1180)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:273)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

What do you think?

1 Like

I also tried changing to GLSL200 instead of GLSL300 and I’m getting this error:

2021-06-09 09:43:28.704 26114-26160/com.abware.scenemax3dgamehub E/AndroidRuntime: FATAL EXCEPTION: GLThread 781
    Process: com.abware.scenemax3dgamehub, PID: 26114
    java.lang.IllegalArgumentException: No enum constant com.jme3.renderer.Caps.GLSL200
        at java.lang.Enum.valueOf(Enum.java:257)
        at com.jme3.renderer.Caps.valueOf(Caps.java:49)
        at com.jme3.material.TechniqueDef.setShaderFile(TechniqueDef.java:552)
        at com.jme3.material.plugins.J3MLoader.readTechnique(J3MLoader.java:681)
        at com.jme3.material.plugins.J3MLoader.loadFromRoot(J3MLoader.java:779)
        at com.jme3.material.plugins.J3MLoader.load(J3MLoader.java:801)
        at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:272)
        at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:388)
        at com.jme3.material.Material.<init>(Material.java:104)
        at jme3utilities.sky.SkyMaterialCore.<init>(SkyMaterialCore.java:152)
        at jme3utilities.sky.SkyMaterial.<init>(SkyMaterial.java:138)
        at jme3utilities.sky.SkyControlCore.<init>(SkyControlCore.java:247)
        at jme3utilities.sky.SkyControl.<init>(SkyControl.java:202)
        at com.scenemaxeng.projector.SceneMaxApp.showSolarSystemSkyBox(SceneMaxApp.java:5295)
        at com.scenemaxeng.projector.SkyBoxActionController.run(SkyBoxActionController.java:28)
        at com.scenemaxeng.projector.CompositeController.run(CompositeController.java:80)
        at com.scenemaxeng.projector.SceneMaxApp.simpleUpdate(SceneMaxApp.java:2825)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:259)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)
2021-06-09 09:43:28.705 26114-26160/com.abware.scenemax3dgamehub E/com.jme3.app.AndroidHarnessFragment: SEVERE Exception thrown in Thread[GLThread 781,5,main]
    java.lang.IllegalArgumentException: No enum constant com.jme3.renderer.Caps.GLSL200
        at java.lang.Enum.valueOf(Enum.java:257)
        at com.jme3.renderer.Caps.valueOf(Caps.java:49)
        at com.jme3.material.TechniqueDef.setShaderFile(TechniqueDef.java:552)
        at com.jme3.material.plugins.J3MLoader.readTechnique(J3MLoader.java:681)
        at com.jme3.material.plugins.J3MLoader.loadFromRoot(J3MLoader.java:779)
        at com.jme3.material.plugins.J3MLoader.load(J3MLoader.java:801)
        at com.jme3.asset.DesktopAssetManager.loadLocatedAsset(DesktopAssetManager.java:272)
        at com.jme3.asset.DesktopAssetManager.loadAsset(DesktopAssetManager.java:388)
        at com.jme3.material.Material.<init>(Material.java:104)
        at jme3utilities.sky.SkyMaterialCore.<init>(SkyMaterialCore.java:152)
        at jme3utilities.sky.SkyMaterial.<init>(SkyMaterial.java:138)
        at jme3utilities.sky.SkyControlCore.<init>(SkyControlCore.java:247)
        at jme3utilities.sky.SkyControl.<init>(SkyControl.java:202)
        at com.scenemaxeng.projector.SceneMaxApp.showSolarSystemSkyBox(SceneMaxApp.java:5295)
        at com.scenemaxeng.projector.SkyBoxActionController.run(SkyBoxActionController.java:28)
        at com.scenemaxeng.projector.CompositeController.run(CompositeController.java:80)
        at com.scenemaxeng.projector.SceneMaxApp.simpleUpdate(SceneMaxApp.java:2825)
        at com.jme3.app.SimpleApplication.update(SimpleApplication.java:259)
        at com.jme3.app.AndroidHarnessFragment.update(AndroidHarnessFragment.java:576)
        at com.jme3.system.android.OGLESContext.onDrawFrame(OGLESContext.java:350)
        at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1571)
        at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1270)

1 Like

Could you change this definition to uniform & try again ?

1 Like

Sure. I’ll try and report

1 Like

Yeh, nice work, i was wrong about glsl200, there’s no glsl200, my reply was from memory :sweat_smile: lol broken memories, anyway versions are :

For OpenGLES :

For OpenGL :
image

but, i still wonder how glsl110 doesn’t work on android when its the actual ogles2.0, may be its written wrong in wikipedia & the actual glsl version is #150 !

1 Like

https://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/varying.php

Varying keyword makes the variables shareable by the Fragment & vertex shader of the same shader material, so we should find out if the dome20.vert is using skyTexCoord without redefining it, because i think if it’s changed to uniform, it may raise error of cannot find symbol or something…,

1 Like

Because glsl110 is a desktop version. If you want ogles20 the you specify it: Caps (jMonkeyEngine3)

Basically, these shaders were not written with Android in mind. In modern JME, you can actually cover most of your bases by adding GLSL100 to your j3md. In older JME, that would leave the #version line out altogether. In modern JME, it fills the appropriate minimum version in for desktop or android depending on environment.

1 Like

If you still having problems with the varying keyword, change this to 320 es & add GLSL320 Caps definition.

Thanks :slight_smile: I’ll get home in a few hours and try these options

1 Like

I see, the dome20.j3md has a default definition of GLSL100, but it doesn’t work on android & the device shader detects it as GLSL110 which is the desktop, so GLSL100 should go for desktop or android ?

1 Like

If it’s working right. The answer to your question is “yes”.

I don’t have the sky control source nor was a link to it provided or anything and I have nothing to do with that code… so I was only guessing from the error. Maybe the error is reporting wrong because there is a whole line of versions like the PBR shader or something so it picks the first one to report as the “technique”.

Someone would have to do some deeper digging into the technique selection code in this case.

I, too, thought it was weird that it was treating the device as “desktop”, though. I don’t really know anything else about Android development but maybe it would be useful to know more about what Android device/version/whatever was tried.

1 Like

There’s only one defined macro for GLSL100 inside that material definition.

The problem is with using varying keyword, despite pbr shaders are using it & everything is okay !

EDIT : from the last report of Adi, he has changed the macro to GLSL300 as pbr shaders does, & the exception is raised because of using varying.

Then it seems like JME somehow thinks it is on Desktop or OP is not using that version of the shader.

The original post had no such information. Once you started screwing with other stuff then all bets are off… because varying goes away in later versions as I understand. (versus varying in, varying out, etc.)

Edit: spending one more second poking in GIT from the link provided, it seems like GLSL100 was only added 9 months ago:

…so probably OP uses an older sky control is all.

This is why versions are important. Could have short-circuited this whole long thread to two posts.

2 Likes

I compiled SkyControl from the source code yesterday but included it in the project with the GLSL 300 change. I’ll revert to GLSL 100 and test again.

1 Like