{"id":28652363,"url":"https://github.com/erlangsters/egl-1.5","last_synced_at":"2026-04-30T02:37:39.721Z","repository":{"id":298267436,"uuid":"862463761","full_name":"erlangsters/egl-1.5","owner":"erlangsters","description":"EGL 1.5 binding for the BEAM (Erlang and Elixir).","archived":false,"fork":false,"pushed_at":"2025-08-20T09:35:29.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-20T11:30:49.385Z","etag":null,"topics":["beam","binding","egl","elixir","erlang","erlangsters"],"latest_commit_sha":null,"homepage":"https://about.erlangsters.org","language":"Erlang","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/erlangsters.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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}},"created_at":"2024-09-24T16:35:23.000Z","updated_at":"2025-08-20T09:35:32.000Z","dependencies_parsed_at":"2025-08-20T11:18:43.952Z","dependency_job_id":"ef6277f8-a3da-4146-99ca-e7fd0ec61cb8","html_url":"https://github.com/erlangsters/egl-1.5","commit_stats":null,"previous_names":["erlangsters/egl-1.5"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/erlangsters/egl-1.5","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fegl-1.5","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fegl-1.5/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fegl-1.5/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fegl-1.5/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erlangsters","download_url":"https://codeload.github.com/erlangsters/egl-1.5/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erlangsters%2Fegl-1.5/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32452741,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["beam","binding","egl","elixir","erlang","erlangsters"],"created_at":"2025-06-13T06:12:55.873Z","updated_at":"2026-04-30T02:37:39.716Z","avatar_url":"https://github.com/erlangsters.png","language":"Erlang","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EGL 1.5 binding for the BEAM\n\n:construction: It's still in development and a first beta version will be\navailable shortly. The master branch will be rewound!\n\n[![Erlangsters Repository](https://img.shields.io/badge/erlangsters-egl--1.5-%23a90432)](https://github.com/erlangsters/egl-1.5)\n![Supported Erlang/OTP Versions](https://img.shields.io/badge/erlang%2Fotp-28-%23a90432)\n![Current Version](https://img.shields.io/badge/version-1.0.0-%23354052)\n![License](https://img.shields.io/github/license/erlangsters/egl-1.5)\n[![Build Status](https://img.shields.io/github/actions/workflow/status/erlangsters/egl-1.5/workflow.yml)](https://github.com/erlangsters/egl-1.5/actions/workflows/workflow.yml)\n[![Documentation Link](https://img.shields.io/badge/documentation-available-yellow)](http://erlangsters.github.io/egl-1.5/)\n\nThe binding of [EGL 1.5](https://registry.khronos.org/EGL/sdk/docs/man/) for the\nErlang and Elixir programming language. It comes with a set of OpenGL bindings\nwhich are designed to work with it.\n\n- OpenGL: [3.3](https://github.com/erlangsters/opengl-3.3) |\n  [4.1](https://github.com/erlangsters/opengl-4.1) |\n  [4.6](https://github.com/erlangsters/opengl-4.6)\n- OpenGL ES: [2.0](https://github.com/erlangsters/opengl-es-2.0) |\n  [3.0](https://github.com/erlangsters/opengl-es-3.0) |\n  [3.1](https://github.com/erlangsters/opengl-es-3.1) |\n  [3.2](https://github.com/erlangsters/opengl-es-3.2)\n\nUnlike the OpenGL bindings, this binding is not generated and written by hand\ninstead. The OpenGL bindings are generated by the OpenGL binding\n[generator](https://github.com/erlangsters/opengl-x.y-generator).\n\n\u003e Note that EGL version 1.5 is the last and final version. It's the reason why\n\u003e the 1.5 suffix is added to the repository name. In fact, no binding for\n\u003e version 1.4 and earlier ever existed. The API of this binding is set in\n\u003e stone.\n\nAny OpenGL developer knows that the API is not thread-safe and an active OpenGL\ncontext must be active. Given the BEAM executes code on arbitrary OS threads,\nread how the EGL binding solves [thread safety](#threads-safety).\n\nAlso, you will typically use ANGLE on macOS and Windows.\n\nWritten by the Erlangsters [community](https://about.erlangsters.org/) and\nreleased under the MIT [license](https://opensource.org/license/mit).\n\n## Getting started\n\nIt would not make sense to use EGL without OpenGL, therefore, first pick an\nOpenGL binding to work with, and update `rebar.config` accordingly.\n\n```erlang\n{deps, [\n  {egl, {git, \"https://github.com/erlangsters/egl-1.5.git\", {tag, \"master\"}}}\n  {gl, {git, \"https://github.com/erlangsters/opengl-4.6.git\", {tag, \"master\"}}}\n]}.\n```\n\n\u003e Note that it will trigger the compilation of NIF modules which requires you\n\u003e to have a compiler and the EGL and OpenGL libraries installed on your system.\n\u003e It's heavily platform-dependent and therefore instructions cannot be provided\n\u003e easily, however, the [Github workflow](.github/workflows/workflow.yml) should\n\u003e be a good starting point.\n\n\u003e If you're using macOS or Windows, you will want to use [ANGLE](https://github.com/google/angle) which you're placing in discoverable paths. XXX: Update Makefile to use env vars.\n\nThen use the following snippet of code to get you started.\n\n```erlang\nDisplay = egl:get_display(default_display),\n{ok, _} = egl:initialize(Display),\n\negl:bind_api(opengl_api).\n\nConfigAttribs = [\n    {surface_type, [window_bit]},\n    {renderable_type, [opengl_bit]}\n],\n{ok, Configs} = egl:choose_config(Display, ConfigAttribs),\n\nContextAttribs = [\n    {context_major_version, 3}\n],\n{ok, Context} = egl:create_context(Display, Config, no_context, ContextAttribs),\n\negl:make_current(Display, no_surface, no_surface, Context),\n\n{ok, Version} = gl:get_string(version).\nio:format(\"OpenGL version: ~s~n\", [Version]).\n```\n\n\u003e The API is unsafe meaning that it does not guard against mis-use of the EGL\n\u003e API. For instance, each EGL context that are created should be destroyed\n\u003e only once.\n\nFrom there, you will need two things. First, understanding the\n[API mapping](#api-mapping) (to know how a piece of C code using EGL translates\nto Erlang or Elixir), then understanding [thread-safety](#threads-safety) (how\nthe concept of OpenGL contexts apply at the BEAM level).\n\nAdditionally, for much more advanced use, you may want to learn how to\n[interpolate](#interpolation) with the binding to provide a native window\nhandle, or execute batches of OpenGL commands more efficiently.\n\n## API mapping\n\nThis is a binding to a C API that has been slightly adapted to feel more\nnatural when used in Erlang and Elixir.\n\nHowever, rest assured, your existing EGL knowledge applies entirely because the\nchanges are minor and trivial. With the API reference, you should have\neverything you need.\n\nIf you run into difficulties, check the API mapping document for details on how\nfunctions and types are mapped.\n\nAdditionally, the test suite in this repository serves as a useful reference\nfor practical examples of EGL functions in action.\n\n## Threads safety\n\nIf you're an OpenGL developer, it should come without a surprise that all\nOpenGL commands operate in a context. The OpenGL context must be bound (or\nactive) in the current OS thread before a command can be executed. Furthermore,\nyou also know that there can only be one active context per OS thread at a\ntime, and conversely, binding a context can potentially make an active context\non another OS thread inactive.\n\nThe key word is **OS thread**.\n\nNow, as an Erlang or Elixir developer, you also know that the BEAM does not\nexpose OS threads directly and instead layer on top of it. At the BEAM level we\nwork with a higher-level concept called BEAM processes, and all code is\nexecuted on whichever OS thread the BEAM deems appropriate.\n\nThe key word is **BEAM process**.\n\nIt's a conundrum that seems to make working with OpenGL in the BEAM impossible.\n\nFortunately, there is a solution. To solve this problem, the EGL binding spawns\nan additional OS thread per BEAM process that has an active OpenGL context. The\nOpenGL commands are then scheduled to run on those OS threads.\n\nBecause it effectively map BEAM processes to OS threads, the result is that you\ncan work **exactly** like if a BEAM process was equal to a OS thread.\n\nIt's as simple as that.\n\nIt also means that there is no magic. All thread-safety concerns (and their\nassociated complexity) still apply in your code. The only difference is that\nit's easier to write concurrent code in Erlang and Elixir.\n\nFor a more comprehensive explanation of the employed technique to solve the\nthread-safety, consult this [document](/docs/thread-safety.md).\n\n## NIF interpolation\n\nThe EGL binding is responsible for re-arranging the execution of OpenGL\ncommands in correct OS threads in order to make OpenGL on the BEAM even\npossible. In fact, the OpenGL bindings rely directly on the EGL binding to do\nthat job.\n\nHowever, if you need to execute OpenGL commands yourself, perhaps for\noptimization purpose, such as sending them in batches, you can use the C API of\nthe EGL binding to do it. Just like the OpenGL bindings do. This [document](/docs/native-window-handle.md)\nshould tell you everything you need to know.\n\nAlso, if you happen to be writing some sort of low-level platform-specific\nNIF modules that need to work with the EGL binding, this\n[document](/docs/opengl-context-executor.md) will teach you how to do it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlangsters%2Fegl-1.5","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferlangsters%2Fegl-1.5","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferlangsters%2Fegl-1.5/lists"}