eclipse-efx / efxclipse-drift

Eclipse Public License 2.0
147 stars 17 forks source link

RuntimeException during swapchain creation on JavaFX 20 Windows #50

Open lenis0012 opened 1 year ago

lenis0012 commented 1 year ago

with DriftFX 1.0.0 I am getting a runtime exception on JavaFX 20 with JDK 20.

Exception in thread "Thread-4" java.lang.RuntimeException
    at org.eclipse.fx.drift.internal.frontend.FxImageFactory.createFxImage(FxImageFactory.java:37)
    at org.eclipse.fx.drift.internal.frontend.SimpleFrontSwapChain.<init>(SimpleFrontSwapChain.java:58)
    at org.eclipse.fx.drift.internal.frontend.FrontendImpl.doCreateSwapchain(FrontendImpl.java:99)
    at org.eclipse.fx.drift.internal.frontend.FrontendImpl.receiveCommand(FrontendImpl.java:137)
    at org.eclipse.fx.drift.internal.backend.BackendImpl.sendCommand(BackendImpl.java:85)
    at org.eclipse.fx.drift.internal.backend.BackendImpl.createSwapchain(BackendImpl.java:45)
    at org.eclipse.fx.drift.internal.RendererImpl.createSwapchain(RendererImpl.java:88)
    at com.lenis0012.oraksi.SceneExplorer.loop(SceneExplorer.java:74)
    at com.lenis0012.oraksi.SceneExplorer.run(SceneExplorer.java:37)

This error occurs in FxImageFactory when creating an image. I debugged the error and noticed that all Prism backends return false. So Prism.isES2(), Prism.isD3D() and Prism.isSW() are all false.

I am using the following code to set up an OpenGL context:

this.context = org.eclipse.fx.drift.internal.GL.createContext(0, 3, 3);
org.eclipse.fx.drift.internal.GL.makeContextCurrent(context);

and this is the code in my rendering loop:

Vec2i size = renderer.getSize();
if(swapchain == null || size.x != swapchain.getConfig().size.x || size.y != swapchain.getConfig().size.y) {
    if(swapchain != null) {
        swapchain.dispose();
    }
    swapchain = renderer.createSwapchain(new SwapchainConfig(size, 2, PresentationMode.MAILBOX, StandardTransferTypes.MainMemory));
}

RenderTarget renderTarget = swapchain.acquire();
int texId = GLRenderer.getGLTextureId(renderTarget);

glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0);
glViewport(0, 0, size.x, size.y);

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glBindFramebuffer(GL_FRAMEBUFFER, 0);
swapchain.present(renderTarget);

The initialization and loop happen on a separate thread started from the FXML controller using Platform.runLater to allow layout to complete first.