Embedded OpenGL node for rendering using LWJGL and JOGL with the best performance available.
Written on Kotlin with Java compatibility.
NOTE: All examples are written in Kotlin, Gradle and LWJGL. If you want to use Java/JOGL/Maven, you can use example code generator.
repositories {
// ...
maven { url 'https://jitpack.io' }
}
dependencies {
// ...JavaFX and LWJGL libraries...
implementation 'com.github.husker-dev.openglfx:core:3.0.5'
implementation 'com.github.husker-dev.openglfx:lwjgl:3.0.5'
}
This library adds only one component - OpenGLCanvas
, that can be used like a regular element in JavaFX.
import com.huskerdev.openglfx.OpenGLCanvas
import com.huskerdev.openglfx.lwjgl.LWJGLExecutor.Companion.LWJGL_MODULE
val canvas = OpenGLCanvas.create(LWJGL_MODULE)
// or
val canvas = OpenGLCanvas.create(LWJGL_MODULE, CORE_PROFILE) // For Core OpenGL profile
OpenGLCanvas
uses a logic similar to JOGL. The component has events where you can render content.
// JOGL only: Use the following code in each event to get the GL object
// val gl = (event as JOGLEvent).gl
canvas.addOnInitEvent { event ->
// Init some gl properties only at start
}
canvas.addOnRenderEvent { event ->
val fps = event.fps
val delta = event.delta
val width = event.width
val height = event.height
// Render some content
}
canvas.addOnReshapeEvent { event ->
val width = event.width
val height = event.height
// Changing viewport and matrices
}
canvas.addOnDisposeEvent { event ->
// Clear some native data
}
If you need to update content with a certain FPS, then you should use GLCanvasAnimator
. Keep in mind that JavaFX can limits the refresh rate.
import com.huskerdev.openglfx.GLCanvasAnimator
canvas.animator = GLCanvasAnimator(60.0)
canvas.animator = GLCanvasAnimator(GLCanvasAnimator.UNLIMITED_FPS) // For maximum available FPS
canvas.animator = null // To remove animator
Don't forget to disable VSync before JavaFX initialization if you want to get FPS more than monitor's frequency.
System.setProperty("prism.vsync", "false")
- JOGL can't initialize on macOS (#22)
If you know how to fix that problem I would be very happy
--add-opens javafx.base/com.sun.javafx=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.prism=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.prism.d3d=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.scene.layout=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED
--add-opens javafx.graphics/com.sun.javafx.geom=ALL-UNNAMED
--add-opens javafx.graphics/javafx.scene.image=ALL-UNNAMED
-
husker-dev/offscreen-jgl is used to create offscreen thread-independent GL context on Windows, MacOS and Linux.
-
Executors are the bridges from OpenGLFX inner logic to outer libraries like LWJGL or JOGL.
LWJGL JOGL Class LWJGLExecutor.kt JOGLFXExecutor.kt Instance LWJGL_MODULE JOGL_MODULE If you want to add new OpenGL library, just create your implementation of GLExecutor and use it as existing one:
OpenGLCanvas.create(YOUR_EXECUTOR_INSTANCE)
. -
To efficiently connect OpenGL and JavaFX, OpenGLFX uses some techniques based on OS.
Description Implementation Windows NV_DX_interop is used to synchronize textures between DirectX from JavaFX and OpenGL. InteropImpl.kt Linux/MacOS Creates a new GL context, that is shared with the JavaFX's one. Then renders to a JavaFX texture. SharedImpl.kt Other Copies PixelBuffer from glReadPixels
to JavaFX ImageUniversalImpl.kt
- James H Ball - macOS tester
- Andrew Hamilton - macOS tester, suggested new additions