glium
Note to current and future Glium users:
Glium is no longer actively developed by its original
author. That said, PRs
are still welcome and maintenance is continued by the surrounding community.
Elegant and safe OpenGL wrapper.
Glium is an intermediate layer between OpenGL and your application. You still need to manually handle
the graphics pipeline, but without having to use OpenGL's old and error-prone API.
[dependencies]
glium = "*"
Its objectives:
- Be safe to use. Many aspects of OpenGL that can trigger a crash if misused are automatically handled by glium.
- Provide an API that enforces good practices such as RAII or stateless function calls.
- Be compatible with all OpenGL versions that support shaders, providing a unified API when things diverge.
- Avoid all OpenGL errors beforehand.
- Produce optimized OpenGL function calls, and allow the user to easily use modern OpenGL techniques.
Link to the documentation
If you have some knowledge of OpenGL, the documentation and the examples should get you easily started.
Link to a work-in-progress tutorial
Why should I use Glium instead of raw OpenGL calls?
Easy to use:
-
Functions are higher level in glium than in OpenGL. Glium's API tries to be as Rusty as
possible, and shouldn't be much different than using any other Rust library. Glium should
allow you to do everything that OpenGL allows you to do, just through high-level
functions. If something is missing, please open an issue. -
You can directly pass vectors, matrices and images to glium instead of manipulating low-level
data. -
Thanks to glutin, glium is very easy to setup compared to raw OpenGL.
-
Glium provides easier ways to do common tasks. For example the
VertexBuffer
struct
contains information about the vertex bindings, because you usually don't use several different
bindings with the same vertex buffer. This reduces the overall complexity of OpenGL. -
Glium handles framebuffer objects, samplers, and vertex array objects for you. You no longer
need to create them explicitly as they are automatically created when needed and destroyed
when their corresponding object is destroyed. -
Glium is stateless. There are no
set_something()
functions in the entire library, and
everything is done by parameter passing. The same set of function calls will always produce
the same results, which greatly reduces the number of potential problems.
Safety:
-
Glium detects what would normally be errors or undefined behaviors in OpenGL, and panics,
without callingglGetError
which would be too slow. Examples include requesting a depth test
when you don't have a depth buffer available, not binding any value to an attribute or uniform,
or binding multiple textures with different dimensions to the same framebuffer. -
If the OpenGL context triggers an error, then you have found a bug in glium. Please open
an issue. Just like Rust does everything it can to avoid crashes, glium does everything
it can to avoid OpenGL errors. -
The OpenGL context is automatically handled by glium. You don't need to worry about thread
safety, as it is forbidden to change the thread in which OpenGL objects operate. Glium also
allows you to safely replace the current OpenGL context with another one that shares the same
lists. -
Glium enforces RAII. Creating a
Texture2d
struct creates a texture, and destroying the struct
destroys the texture. It also uses Rust's borrow system to ensure that objects are still
alive and in the right state when you use them. Glium provides the same guarantees with OpenGL
objects that you have with regular objects in Rust. -
High-level functions are much easier to use and thus less error-prone. For example there is
no risk of making a mistake while specifying the names and offsets of your vertex attributes,
since Glium automatically generates this data for you. -
Robustness is automatically handled. If the OpenGL context is lost (because of a crash in the
driver for example) then swapping buffers will return an error.
Compatibility:
-
In its default mode, Glium should be compatible with both OpenGL and OpenGL ES. If something
doesn't work on OpenGL ES, please open an issue. -
During initialization, Glium detects whether the context provides all the required
functionality, and returns anErr
if the device is too old. Glium tries to be as tolerant
as possible, and should work with the majority of the OpenGL2-era devices. -
Glium will attempt to use the latest, optimized versions of OpenGL functions. This includes
buffer and texture immutable storage and direct state access. It will automatically fall back
to older functions if they are not available. -
Glium comes with a set of tests that you can run with
cargo test
. If your project/game
doesn't work on specific hardware, you can try running Glium's tests on it to see what is wrong.
Performances:
-
State changes are optimized. The OpenGL state is only modified if the state actually differs.
For example if you calldraw
with theIfLess
depth test twice in a row, then
glDepthFunc(GL_LESS)
andglEnable(GL_DEPTH_TEST)
will only be called the first time. If
you then calldraw
withIfGreater
, then onlyglDepthFunc(GL_GREATER)
will be called. -
Just like Rust is theoretically slower than C because of additional safety checks, glium is
theoretically slower than well-prepared and optimized raw OpenGL calls. However in practice
the difference is very low. -
Fully optimized OpenGL code uses advanced techniques such as persistent mapping or bindless
textures. These are hard to do and error-prone, but trivially easy to do with glium. You can
easily get a huge performance boost just by doing the right function calls. -
Since glium automatically avoids all OpenGL errors, you can safely use the
GL_KHR_no_error
extension when it is available. Using this extension should provide a good performance boost
(but it is also very recent and not available anywhere for the moment).
Limitations:
-
Robustness isn't supported everywhere yet, so you can still get crashes if you do incorrect
things in your shaders. -
Glium gives you access to all the tools but doesn't prevent you from doing horribly slow
things. Some knowledge of modern techniques is required if you want to reach maximum
performances. -
Glium pushes the Rust compiler to its limits. Stack overflows (inside the compiler),
internal compiler errors, one-hour compile time, etc. happen more often than in smaller
libraries. -
Macros are yet work-in-progress; see
glium-derive
for details.