openglfx

repository·master·Indexed 40 days ago

https://github.com/husker-dev/openglfx

A library for rendering OpenGL graphics within JavaFX applications. It supports multiple backends including LWJGL, JOGL, LWJGL2, and LibGDX, providing the GLCanvas component for rendering, GLImageManager for texture sharing between JavaFX and OpenGL, and optimized event handling for the OpenGL lifecycle.

Tokens
1.6K
Snippets
6
Records
8
Agent score
50%

What's inside openglfx

  1. Configure JPMS for openglfx

    master

    If you are using Java 9+ modules (JPMS), add the following requirement to your module-info.java:

    requires openglfx.lwjgl;

    If you encounter package access issues at runtime, you can disable the library's automatic exports by setting the JVM argument -Dopenglfx.disable.exports=true. You must then manually add the following exports via --add-exports:

    --add-exports=javafx.graphics/com.sun.prism=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.javafx.scene.layout=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.scenario=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED
    --add-exports=javafx.graphics/com.sun.glass.ui=ALL-UNNAMED
  2. Install openglfx via Gradle

    master

    To use openglfx in your project, add the appropriate module to your dependencies block. You must also include your primary OpenGL provider (e.g., LWJGL or JOGL) and JavaFX.

    dependencies {
        // implementation JavaFX
        // implementation LWJGL
        // implementation ...
    
        implementation 'com.huskerdev:openglfx-lwjgl:4.2.3'
    }
  3. Integrate with LibGDX

    master

    To use openglfx in a LibGDX project, you should create a new module and use LibGDXCanvas instead of the standard GLCanvas. LibGDXCanvas takes an ApplicationAdapter (or similar) as its argument.

    Minimal build.gradle for a LibGDX module:

    plugins {
        id("org.jetbrains.kotlin.jvm")
    }
    
    sourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ]
    
    dependencies {
        implementation project(':core')
        implementation "com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion"
        implementation "com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop"
    
        // openglfx
        api("com.huskerdev:openglfx-libgdx:4.2.2")
    
        // implementation(/* JavaFX */)
        // implementation(/* LWJGL */)
    }

    Usage:

    val canvas = LibGDXCanvas(Main()) // Main is your ApplicationAdapter
  4. Use the GLCanvas component

    master

    The primary way to use this library is through the GLCanvas component. It acts as a regular JavaFX element.

    Important: You must call dispose() when the canvas is no longer needed to free allocated native memory.

    Available modules for initialization:

    • LWJGL_MODULE
    • LWJGL2_MODULE
    • JOGL_MODULE
    • LIBGDX_MODULE
    import com.huskerdev.openglfx.canvas.GLCanvas
    import com.huskerdev.openglfx.lwjgl.LWJGLExecutor.Companion.LWJGL_MODULE
    
    val canvas = GLCanvas(LWJGL_MODULE)
    
    // When finished:
    canvas.dispose()
  5. Handle GLCanvas rendering events

    master

    The GLCanvas uses an event-based system (similar to JOGL) to manage the OpenGL lifecycle. You can register listeners for initialization, rendering, resizing, and disposal.

    canvas.addOnInitEvent { event ->
        // Init some gl properties only once
    }
    
    canvas.addOnRenderEvent { event ->
        // Render some content every frame
    }
    
    canvas.addOnReshapeEvent { event ->
        // Change viewport matrices at resizing
    }
    
    canvas.addOnDisposeEvent { event ->
        // Clear native data at disposing
    }
  6. Control FPS and VSync

    master

    You can control the update frequency using the fps property. Note that JavaFX may limit the refresh rate.

    ValueBehavior
    < 0Monitor refresh rate
    0No automatic updates (updates only on resize/JavaFX commands)
    > 0Update with desired FPS

    To achieve FPS higher than the monitor's frequency, you must disable VSync before JavaFX initialization by setting the system property prism.vsync to false.

    You can also manually request a frame by calling repaint(), which tells the renderer to prepare a frame as soon as possible.

    // Set in constructor
    val canvas = GLCanvas(..., fps = 30)
    
    // Or update at runtime
    canvas.fps = 40
    
    // Request a frame
    canvas.repaint()
    
    // Disable VSync (must be done before JavaFX init)
    System.setProperty("prism.vsync", "false")
  7. Configure GLCanvas rendering options

    master

    When instantiating GLCanvas, you can customize several rendering behaviors:

    • Antialiasing (MSAA): Set msaa to a value (e.g., 4) for specific levels, or -1 for the maximum possible level.
    • Swap Buffers: Set swapBuffers to 2 (default) for best UI performance, or 1 for the most responsive resizing.
    • Y-flipping: Set flipY = true to automatically flip the image (OpenGL draws upside down by default).
    • OpenGL Profile: Specify the profile using GLProfile.CORE (recommended) or GLProfile.COMPATIBILITY.
    • RenderDoc/NSight Integration: Set externalWindow = true in the constructor to create a separate window that can be captured by external debuggers.
    // Example with multiple configurations
    val canvas = GLCanvas(
        LWJGL_MODULE, 
        msaa = 4, 
        swapBuffers = 2, 
        flipY = true, 
        profile = GLProfile.CORE,
        externalWindow = true
    )
  8. Transfer images between JavaFX and OpenGL

    master

    Use the GLImageManager class to move images between the JavaFX and OpenGL domains.

    • JavaFX $\rightarrow$ OpenGL: Use GLImageManager.toGL(image) to create an OpenGL texture from a JavaFX image.
    • OpenGL $\rightarrow$ JavaFX: Use GLImageManager.fromGL(fbo, width, height) to retrieve a JavaFX image from an FBO.
    // JavaFX to OpenGL
    val fbo = GLImageManager.toGL(image)
    
    // OpenGL to JavaFX
    val image = GLImageManager.fromGL(fbo, width, height)