GLES and GL classes can't be used together with LWJGL 3.3.3 anymore
Berstanio opened this issue · 7 comments
Version
3.3.3
Platform
Windows x64
JDK
all
Module
core/OpenGL(ES)
Bug description
In LWJGL 3.3.3 ThreadLocalUtil#setFunctionMissingAddresses can't be called multiple times anymore.
However, both the GL and GLES classes call that method in their static initializer:
Therefor utlizing both classes in any way together is now not possible anymore. This used to work in LWJGL 3.3.2.
I'm not fully sure whether this can/should be considered a bug, but I thought I should open a issue just in case.
Stacktrace or crash log output
This is a stacktrace from a libGDX application.
Exception in thread "main" java.lang.ExceptionInInitializerError
at org.lwjgl.opengl.GL11.<clinit>(GL11.java:38)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createWindow(Lwjgl3Application.java:467)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.createWindow(Lwjgl3Application.java:448)
at com.badlogic.gdx.backends.lwjgl3.Lwjgl3Application.<init>(Lwjgl3Application.java:162)
at com.badlogic.gdx.tests.lwjgl3.Lwjgl3TestStarter.main(Lwjgl3TestStarter.java:91)
Caused by: java.lang.IllegalStateException: setFunctionMissingAddresses has been called already
at org.lwjgl.system.ThreadLocalUtil.setFunctionMissingAddresses(ThreadLocalUtil.java:202)
at org.lwjgl.opengl.GL.create(GL.java:182)
at org.lwjgl.opengl.GL.create(GL.java:126)
at org.lwjgl.opengl.GL.create(GL.java:112)
at org.lwjgl.opengl.GL.<clinit>(GL.java:85)
... 5 more
Hey @Berstanio,
What's the use-case for using GL and GLES at the same time?
As a disclaimer, I'm not really a expert with the libGDX rendering stack, this is just how I understand it.
OpenGL calls happen usually through the GL classes, because by default the OpenGL driver are used, e.g. here: https://github.com/libgdx/libgdx/blob/6b419518b029aad223f14515ccb9d26ca22fbfd6/backends/gdx-backend-lwjgl3/src/com/badlogic/gdx/backends/lwjgl3/Lwjgl3Application.java#L467
However, libGDX also supports rendering through ANGLE which is an OpenGL ES implementation. This is why I think the OpenGL ES class is needed for, to properly create the capability array.
https://github.com/libgdx/libgdx/blob/6b419518b029aad223f14515ccb9d26ca22fbfd6/backends/gdx-backend-lwjgl3/src/com/badlogic/gdx/backends/lwjgl3/Lwjgl3Application.java#L561-L570
As I said, I sadly can't give you more details on the "why" if you need them, I would have to ask others that are more familiar with ANGLE.
Hey @Berstanio,
I had some time to look into this today. Cloned libGDX, built it and ran the tests (gradlew launchTestsLwjgl3
, let me know if there's something else I could try).
Afaict, libGDX working with the Angle backend on LWJGL 3.3.2 and 3.3.3 with your fix is a happy accident. It is not a supported way to use the LWJGL bindings. In fact, the GL11.glClearColor
and GL11.glClear
calls in createWindow
do not even work, since GL.createCapabilities
is never called. With the way the LWJGL bindings are implemented (specifically, the "special" thread-local handling of GL & GLES calls), libGDX actually ends up calling GLES20.glBufferData
and GLES20.glCheckFramebufferStatus
respectively. It's a miracle that the JVM doesn't crash, because the corresponding function signatures are close enough.
libGDX should replace the two direct GL11
calls in createWindow
with an if/else block that calls the corresponding GLES20
functions when Angle is enabled. I tried it (used reflection, like in initiateGL
) and all demos worked just fine.
In general, when Angle is enabled, libGDX should only make EGL & GLES calls. There's no reason to touch the GL
class and load the standard OpenGL library (Angle uses it internally).
Thank you very much on the insights!
As I understand it, the issue also applies to com.badlogic.gdx.backends.lwjgl.LwjglGL20/LwjglGL30
classes, since they too call GLXX functions directly, right? So they should be all guarded too, I would assume?
No, with the Angle backend enabled OpenGL calls go through com.badlogic.gdx.backends.lwjgl3.angle.Lwjgl3GLES20
. This is already abstracted away nicely and demos work correctly.
The only demos that do not work are those using GL 3.0-3.2 features. LWJGL has GLES 3.0-3.2 bindings and I don't think there's any functionality missing, so libGDX should be able to support these versions too.
See the com.badlogic.gdx.backends.lwjgl3.Lwjgl3Graphics
constructor for details.
No, with the Angle backend enabled OpenGL calls go through
com.badlogic.gdx.backends.lwjgl3.angle.Lwjgl3GLES20
. This is already abstracted away nicely and demos work correctly.
You are correct, I oversaw that.
I will move forward and try to fix the outstanding two GL calls, thank you!
The only demos that do not work are those using GL 3.0-3.2 features. LWJGL has GLES 3.0-3.2 bindings and I don't think there's any functionality missing, so libGDX should be able to support these versions too.
I don't know why it is missing, I wasn't involved in the development of this. I guess at the time GLES was added to libGDX, ANGLE didn't supported GLES 3
Your suggested fix works great, thank you!
Closing this as completed.