{"id":13798545,"url":"https://github.com/husker-dev/openglfx","last_synced_at":"2026-01-12T14:57:54.595Z","repository":{"id":47769660,"uuid":"393363130","full_name":"husker-dev/openglfx","owner":"husker-dev","description":"OpenGL canvas for JavaFX","archived":false,"fork":false,"pushed_at":"2026-01-10T18:51:01.000Z","size":16068,"stargazers_count":133,"open_issues_count":6,"forks_count":16,"subscribers_count":5,"default_branch":"master","last_synced_at":"2026-01-11T03:38:17.908Z","etag":null,"topics":["java","javafx","jogl","kotlin","lwjgl","lwjgl2","lwjgl3","opengl"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/husker-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-08-06T11:58:47.000Z","updated_at":"2026-01-10T18:51:05.000Z","dependencies_parsed_at":"2023-02-18T06:01:21.957Z","dependency_job_id":"1d4eeb80-e3b8-4436-91d6-c134f0c8c8fc","html_url":"https://github.com/husker-dev/openglfx","commit_stats":null,"previous_names":[],"tags_count":72,"template":false,"template_full_name":null,"purl":"pkg:github/husker-dev/openglfx","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/husker-dev%2Fopenglfx","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/husker-dev%2Fopenglfx/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/husker-dev%2Fopenglfx/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/husker-dev%2Fopenglfx/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/husker-dev","download_url":"https://codeload.github.com/husker-dev/openglfx/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/husker-dev%2Fopenglfx/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28340414,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-12T12:22:26.515Z","status":"ssl_error","status_checked_at":"2026-01-12T12:22:10.856Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["java","javafx","jogl","kotlin","lwjgl","lwjgl2","lwjgl3","opengl"],"created_at":"2024-08-04T00:00:45.707Z","updated_at":"2026-01-12T14:57:54.590Z","avatar_url":"https://github.com/husker-dev.png","language":"C++","readme":"\u003cimg src=\"./.github/resources/logo.png\" alt=\"logo\"\u003e\n\n\u003ca href=\"https://boosty.to/husker-dev/donate\"\u003e\n    \u003cimg width=\"145\" src=\"./.github/resources/boosty.svg\" alt=\"boosty\"\u003e\n\u003c/a\u003e\n\n\u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/github/license/husker-dev/openglfx?style=flat-square\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/husker-dev/openglfx/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/husker-dev/openglfx?style=flat-square\"\u003e\u003c/a\u003e\n\n# About\n\nThis library adds a new element to the JavaFX for rendering OpenGL graphics using LWJGL, JOGL, LWJGL2 or LibGDX. It is optimized for each platform and includes some auxiliary functions for working with OpenGL from JavaFX.\n\n- [Dependency](#dependency)\n  - [JPMS](#jpms)\n- [Example](#example)\n- [Usage](#usage)\n  - [Rendering events](#rendering-events)\n  - [Antialiasing (MSAA)](#antialiasing-msaa)\n  - [Y-flipping](#y-flipping)\n  - [OpenGL profile](#opengl-profile)\n  - [FPS control](#fps-control)\n  - [Image transfering](#image-transfering)\n  - [RenderDoc](#renderdoc--nsight)\n  - [LibGDX](#libgdx)\n- [Under the hood](#under-the-hood)\n- [Thanks to](#thanks-to)\n\n\n\u003e **NOTE:** All examples are written in Kotlin + Gradle + LWJGL. If you want to use Java/JOGL/Maven, you can use [example code generator](https://husker-dev.github.io/husker-dev/?page=tools/openglfx).\n\n# Dependency\n```groovy\ndependencies {\n    // implementation JavaFX\n    // implementation LWJGL\n    // implementation ...\n\n    implementation 'com.huskerdev:openglfx-lwjgl:4.2.3'\n}\n```\n\nAvailable modules:\n  - ```openglfx-lwjgl```\n  - ```openglfx-lwjgl2```\n  - ```openglfx-jogl```\n  - ```openglfx-libgdx```\n\n## JPMS\nIf you are using JPMS (Java 9+ modules), then you need to add the following module in `module-info.java`:\n```java\nrequires openglfx.lwjgl;\n```\n`openglfx` adds exports for JavaFX at runtime, but if you experience issues with package access, then add following arguments to JVM:\n```\n-Dopenglfx.disable.exports=true\n```\nThen add `--add-exports` by hand:\n```\n--add-exports=javafx.graphics/com.sun.prism=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.javafx.scene.layout=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.javafx.scene=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.javafx.sg.prism=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.scenario=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.javafx.tk=ALL-UNNAMED\n--add-exports=javafx.graphics/com.sun.glass.ui=ALL-UNNAMED\n```\n\n# Example\nhttps://github.com/husker-dev/openglfx-example\n\n# Usage\n\nThis library adds only one component - ```GLCanvas```, that can be used like a regular element in JavaFX.\n\nAfter canvas is not needed anymore, call ```dispose()``` to free the allocated memory.\n\n```kotlin\nimport com.huskerdev.openglfx.canvas.GLCanvas\nimport com.huskerdev.openglfx.lwjgl.LWJGLExecutor.Companion.LWJGL_MODULE\n\nval canvas = GLCanvas(LWJGL_MODULE)\n```\n\nAvailable modules:\n  - ```LWJGL_MODULE```\n  - ```LWJGL2_MODULE```\n  - ```JOGL_MODULE```\n  - ```LIBGDX_MODULE```\n  \n\n### Rendering events\n\n```GLCanvas``` uses a logic similar to JOGL. The component has events where you can render the content.\n\n```kotlin\ncanvas.addOnInitEvent { event -\u003e\n    // Init some gl properties only once\n}\n\ncanvas.addOnRenderEvent { event -\u003e\n    // Render some content every frame\n}\n\ncanvas.addOnReshapeEvent { event -\u003e\n    // Change viewport matrices at resizing\n}\n\ncanvas.addOnDisposeEvent { event -\u003e\n    // Clear native data at disposing\n}\n```\n\n### Antialiasing (MSAA)\n```GLCanvas``` supports multi-sampling anti-aliasing. It can be enabled during creation.\nFor maximum possible MSAA level, specify -1.\n\n```kotlin\nGLCanvas(.., msaa = 4)\n```\n\n### Swap buffers\n```GLCanvas``` based on the swap chain system - you can think of it as \"double buffering\".\n\nThe best UI performance is achieved with `2` (default). The most responsive to resizing is `1`.\n\n```kotlin\nGLCanvas(.., swapBuffers = 1)\n```\n\n### Y-flipping\nBy default, OpenGL draws the image upside down. ```GLCanvas``` has the ability to flip it without loss of performance. To do this, specify the parameter at startup.\n\n```kotlin\nGLCanvas(.., flipY = true)\n```\n\n### OpenGL profile\n\nIn GLCanvas you can specify the desired profile. I advise you to always choose Core. \nTo do this, you need to specify a parameter in constructor.\n\n```kotlin\nGLCanvas(.., profile = GLProfile.CORE)\nGLCanvas(.., profile = GLProfile.COMPATIBILITY)\n```\n\n### FPS control\nIf you need to update content with a certain FPS, then you should use property ```fps```. Keep in mind that JavaFX can limits the refresh rate.\n\n| Value | Behavior                                                                                                                    |\n|-------|-----------------------------------------------------------------------------------------------------------------------------|\n| \u003c 0   | Monitor refresh rate                                                                                                        |\n| 0     | Do not updates automatically \u003cbr\u003e (Keep in mind that the update may be triggered by resizing or other commands from JavaFX) |\n| \\\u003e 0  | Update with desired FPS                                                                                                     |\n\n```kotlin\n// In constructor\nval canvas = GLCanvas(..., fps = 30)\n\n// Or at runtime\ncanvas.fps = 40\n```\n\nA draw call can also be \"requested\" by calling the `repaint()` method. \nIt won't force a draw immediately, but will tell the renderer to prepare a frame as soon as possible.\n\nDon't forget to disable VSync before JavaFX initialization if you want to get FPS more than monitor's frequency.\n```kotlin\nSystem.setProperty(\"prism.vsync\", \"false\")\n```\n\n### Image transfering\n```openglfx``` has the ability to move images from JavaFX to OpenGL textures and vice versa. A special class is used for this:\n```kotlin\nval fbo = GLImageManager.toGL(image)\n\nval image = GLImageManager.fromGL(fbo, width, height)\n```\n\n### RenderDoc \u0026 NSight\n```openglfx``` supports RenderDoc integration.\nTo use it, you need to set `externalWindow` in GLCanvas constructor to `true`. \n\nThis will create a separate window with the rendered image, which you can connect to via RenderDoc or NSight.\n\n### LibGDX\nTo use in LibGDX project, you should create new module.\n\nMinimal `build.gradle` example:\n```groovy\nplugins {\n    id(\"org.jetbrains.kotlin.jvm\")\n}\n\nsourceSets.main.resources.srcDirs += [ rootProject.file('assets').path ]\n\ndependencies {\n    implementation project(':core')\n    implementation \"com.badlogicgames.gdx:gdx-backend-lwjgl3:$gdxVersion\"\n    implementation \"com.badlogicgames.gdx:gdx-platform:$gdxVersion:natives-desktop\"\n\n    // openglfx\n    api(\"com.huskerdev:openglfx-libgdx:4.2.2\")\n  \n    // implementation(/* JavaFX */)\n    // implementation(/* LWJGL */)\n}\n```\nInstead of using GLCanvas, you should use `LibGDXCanvas`:\n```kotlin\nval canvas = LibGDXCanvas(Main()) // Main is ApplicationAdapter\n```\n\n# Under the hood\n\n- ### grapl\n  [husker-dev/grapl](https://github.com/husker-dev/offscreen-jgl) is used to create offscreen thread-independent GL context on Windows, MacOS and Linux.\n\n- ### GLExecutor\n  Executors are the bridges from OpenGLFX inner logic to outer libraries like LWJGL or JOGL.\n  \n  |          | LWJGL  | JOGL |\n  | -------- | ------ | ---- |\n  |  Class   | [LWJGLExecutor.kt](https://github.com/husker-dev/openglfx/blob/master/modules/lwjgl/kotlin/com/huskerdev/openglfx/lwjgl/LWJGLExecutor.kt)  | [JOGLFXExecutor.kt](https://github.com/husker-dev/openglfx/blob/master/modules/jogl/kotlin/com/huskerdev/openglfx/jogl/JOGLFXExecutor.kt)  |\n  | Instance | LWJGL_MODULE | JOGL_MODULE |\n\n  If you want to add new OpenGL library, just create your implementation of [GLExecutor](https://github.com/husker-dev/openglfx/blob/master/modules/core/kotlin/com/huskerdev/openglfx/GLExecutor.kt) and use it as existing one: ```GLCanvas.create(YOUR_EXECUTOR_INSTANCE)```.\n\n- ### Texture sharing\n\n  To efficiently connect OpenGL and JavaFX, OpenGLFX uses some techniques based on OS and supported extensions.\n  \n  [BlitCanvas]: https://github.com/husker-dev/openglfx/blob/master/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/BlitCanvas.kt\n  [ExternalObjectsCanvasES2Linux]: https://github.com/husker-dev/openglfx/blob/78a6cb174923605a6a0ffb70645134822a80a239/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/ExternalObjectsCanvasES2.kt#L49\n  [ExternalObjectsCanvasD3D]: https://github.com/husker-dev/openglfx/blob/master/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/ExternalObjectsCanvasD3D.kt\n  [ExternalObjectsCanvasES2Win]: https://github.com/husker-dev/openglfx/blob/78a6cb174923605a6a0ffb70645134822a80a239/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/ExternalObjectsCanvasES2.kt#L42\n  [IOSurfaceCanvas]: https://github.com/husker-dev/openglfx/blob/master/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/IOSurfaceCanvas.kt\n  [WGLDXInteropCanvas]: https://github.com/husker-dev/openglfx/blob/master/modules/core/kotlin/com/huskerdev/openglfx/internal/canvas/WGLDXInteropCanvas.kt\n\n  |                                                       | Description                                                                                                                                                                                    | Implementation                                                |\n  |-------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------|\n  | **Windows** \u003cbr\u003e (that supports EXT_external_objects) | [EXT_external_objects_win32](https://registry.khronos.org/OpenGL/extensions/EXT/EXT_external_objects_win32.txt) is used to create shared DXGI texture between DirectX 9 and OpenGL.            | [ExternalObjectsCanvasD3D.kt][ExternalObjectsCanvasD3D]       |\n  | **Windows** \u003cbr\u003e (that supports WGL_NV_DX_interop)    | [NV_DX_interop](https://www.khronos.org/registry/OpenGL/extensions/NV/WGL_NV_DX_interop.txt) is used to synchronize textures between DirectX 9 and OpenGL.                                     | [WGLDXInteropCanvas.kt][WGLDXInteropCanvas]                   |\n  | **Windows** \u003cbr\u003e (es2 pipeline)                       | [EXT_external_objects_win32](https://registry.khronos.org/OpenGL/extensions/EXT/EXT_external_objects_win32.txt) is used to create chain with shared texture: \u003cbr\u003e OpenGL ⟷ Vulkan ⟷ OpenGL   | [ExternalObjectsCanvasES2.Win.kt][ExternalObjectsCanvasES2Win]      |\n  | **Linux**                                             | [EXT_external_objects_fd](https://registry.khronos.org/OpenGL/extensions/EXT/EXT_external_objects_fd.txt) is used to create chain with shared texture: \u003cbr\u003e OpenGL ⟷ Vulkan ⟷ OpenGL         | [ExternalObjectsCanvasES2.Linux.kt][ExternalObjectsCanvasES2Linux]  |\n  | **macOS**                                             | IOSurface is used to create memory block in VRAM that can be used in different OpenGL contexts.                                                                                                | [IOSurfaceCanvas.kt][IOSurfaceCanvas]                         |\n  | *Other*                                               | Copies ByteBuffer from ```glReadPixels``` to JavaFX texture                                                                                                                                    | [BlitCanvas.kt][BlitCanvas]                                   |\n\n\n# Thanks to\n\n- [streamingdv](https://github.com/streamingdv) - big donation, debugging\n- [James H Ball](https://github.com/jameshball) - macOS tester\n- [Andrew Hamilton](https://github.com/orange451) - macOS tester, suggested new additions\n","funding_links":[],"categories":["Community"],"sub_categories":["Libraries"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhusker-dev%2Fopenglfx","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhusker-dev%2Fopenglfx","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhusker-dev%2Fopenglfx/lists"}