+
Skip to content

erlangsters/egl-1.5

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

69 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EGL 1.5 binding for the BEAM

🚧 It's still in development and a first beta version will be available shortly. The master branch will be rewound!

Erlangsters Repository Supported Erlang/OTP Versions Current Version License Build Status Documentation Link

The binding of EGL 1.5 for the Erlang and Elixir programming language. It comes with a set of OpenGL bindings which are designed to work with it.

Unlike the OpenGL bindings, this binding is not generated and written by hand instead. The OpenGL bindings are generated by the OpenGL binding generator.

Note that EGL version 1.5 is the last and final version. It's the reason why the 1.5 suffix is added to the repository name. In fact, no binding for version 1.4 and earlier ever existed. The API of this binding is set in stone.

Any OpenGL developer knows that the API is not thread-safe and an active OpenGL context must be active. Given the BEAM executes code on arbitrary OS threads, read how the EGL binding solves thread safety.

Also, you will typically use ANGLE on macOS and Windows.

Written by the Erlangsters community and released under the MIT license.

Getting started

It would not make sense to use EGL without OpenGL, therefore, first pick an OpenGL binding to work with, and update rebar.config accordingly.

{deps, [
  {egl, {git, "https://github.com/erlangsters/egl-1.5.git", {tag, "master"}}}
  {gl, {git, "https://github.com/erlangsters/opengl-4.6.git", {tag, "master"}}}
]}.

Note that it will trigger the compilation of NIF modules which requires you to have a compiler and the EGL and OpenGL libraries installed on your system. It's heavily platform-dependent and therefore instructions cannot be provided easily, however, the Github workflow should be a good starting point.

If you're using macOS or Windows, you will want to use ANGLE which you're placing in discoverable paths. XXX: Update Makefile to use env vars.

Then use the following snippet of code to get you started.

Display = egl:get_display(default_display),
{ok, _} = egl:initialize(Display),

egl:bind_api(opengl_api).

ConfigAttribs = [
    {surface_type, [window_bit]},
    {renderable_type, [opengl_bit]}
],
{ok, Configs} = egl:choose_config(Display, ConfigAttribs),

ContextAttribs = [
    {context_major_version, 3}
],
{ok, Context} = egl:create_context(Display, Config, no_context, ContextAttribs),

egl:make_current(Display, no_surface, no_surface, Context),

{ok, Version} = gl:get_string(version).
io:format("OpenGL version: ~s~n", [Version]).

The API is unsafe meaning that it does not guard against mis-use of the EGL API. For instance, each EGL context that are created should be destroyed only once.

From there, you will need two things. First, understanding the API mapping (to know how a piece of C code using EGL translates to Erlang or Elixir), then understanding thread-safety (how the concept of OpenGL contexts apply at the BEAM level).

Additionally, for much more advanced use, you may want to learn how to interpolate with the binding to provide a native window handle, or execute batches of OpenGL commands more efficiently.

API mapping

This is a binding to a C API that has been slightly adapted to feel more natural when used in Erlang and Elixir.

However, rest assured, your existing EGL knowledge applies entirely because the changes are minor and trivial. With the API reference, you should have everything you need.

If you run into difficulties, check the API mapping document for details on how functions and types are mapped.

Additionally, the test suite in this repository serves as a useful reference for practical examples of EGL functions in action.

Threads safety

If you're an OpenGL developer, it should come without a surprise that all OpenGL commands operate in a context. The OpenGL context must be bound (or active) in the current OS thread before a command can be executed. Furthermore, you also know that there can only be one active context per OS thread at a time, and conversely, binding a context can potentially make an active context on another OS thread inactive.

The key word is OS thread.

Now, as an Erlang or Elixir developer, you also know that the BEAM does not expose OS threads directly and instead layer on top of it. At the BEAM level we work with a higher-level concept called BEAM processes, and all code is executed on whichever OS thread the BEAM deems appropriate.

The key word is BEAM process.

It's a conundrum that seems to make working with OpenGL in the BEAM impossible.

Fortunately, there is a solution. To solve this problem, the EGL binding spawns an additional OS thread per BEAM process that has an active OpenGL context. The OpenGL commands are then scheduled to run on those OS threads.

Because it effectively map BEAM processes to OS threads, the result is that you can work exactly like if a BEAM process was equal to a OS thread.

It's as simple as that.

It also means that there is no magic. All thread-safety concerns (and their associated complexity) still apply in your code. The only difference is that it's easier to write concurrent code in Erlang and Elixir.

For a more comprehensive explanation of the employed technique to solve the thread-safety, consult this document.

NIF interpolation

The EGL binding is responsible for re-arranging the execution of OpenGL commands in correct OS threads in order to make OpenGL on the BEAM even possible. In fact, the OpenGL bindings rely directly on the EGL binding to do that job.

However, if you need to execute OpenGL commands yourself, perhaps for optimization purpose, such as sending them in batches, you can use the C API of the EGL binding to do it. Just like the OpenGL bindings do. This document should tell you everything you need to know.

Also, if you happen to be writing some sort of low-level platform-specific NIF modules that need to work with the EGL binding, this document will teach you how to do it.

点击 这是indexloc提供的php浏览器服务,不要输入任何密码和下载