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?
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.
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.
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)
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)
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 !
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…,
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.
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 ?
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.
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.