luminance has been having lots of activity lately. I’ve been working (hard) on making it to the
1.0
release for months now and came to a very important realization: lots of changes have been
done and I’m still not ready to release it. I’ve kind of lost myself in the process.
This article is about two main topics:
If you don’t care about the changes, feel free to go read this to know how you can learn about luminance and graphics programming in general.
Lately, luminance has received a wide range of feature additions, bug fixes and design ideas. I’ve
been wanting to release all those changes as part of the 1.0
release but the thing is: among all
the changes, some have been around on the master
branch for months without a proper release on
crates.io… because the 1.0
milestone was not reached. People have been moving towards luminance
more and more and some provided feedback about using luminance. Happy but indecisive about what to
do, I faced a dilemma:
1.0
but eventually block people from using all
the cool features of luminance because the last release on crates.io is months old.1.0
for everything and 0.31
for all the new
candies.I have decided to go with the second option.
Just before writing this article, the last luminance version was 0.30
— just for the record,
that version is eleven months old, ~200 commits behind master
. The new and most recent version is
thus 0.31
and crates got updated:
#[derive(..)]
construct.Lot of work has been accomplished and I received several contributions from people all around the globe, including PRs and issues. I’d like to remind that I appreciate both and you are really encouraged to contribute in any way you want to. Special thanks fly to:
About that last point, my Reddit and Twitter interactions about luminance have been very interesting because I got to test the water about how people feel about luminance, especially when compared to (not so) similar crates, such as [gfx], glium or even gl. I came to the realization, after reading people and what they would love to have as a graphics crate, that luminance can have the role of the easy crate, that is not necessarily the fastest but fast enough to be quickly productive. I cannot help it but keep thinking about a simple question: if some people can make games in Java or C# with a garbage collector or using old tech like OpenGL 2.1 (yes, some people still make pretty good games with that), why would one need a perfect zero-cost abstraction down-to-the-metal unsafe ultra-optimized crate to write something? See, I went round and squares about that topic, because I’ve already used luminance in several projects of mine (mostly demoscene purposes), and it just does the job. So, yes, luminance doesn’t have that cool, new and modern Vulkan-type API, I must confess. But it has its own API, which is very functional-based (see the History section of luminance for further details about that) and, to me, modern enough so that people don’t get frustrated with the overall design being too clunky.
So, yeah. I gave up on the idea of introducing backends in luminance. I really changed my mind several times about that topic and it’s actually when I read comments on Reddit about people getting confused about the direction of the crate that I made up my mind: luminance must remain simple. Having a system of backends that can be hot-switched, concurrent etc. is just going to make things hard for people to use it — and maintain it! It’s likely that I will introduce, however, feature-gates to allow to compile luminance on WebAssembly via WebGL, OpenGL ES or even Vulkan at some point, but the difference is that no backend will be implemented. That means that those feature-flags aren’t likely to be summable at first. But all of this will be done in future releases; stay tuned.
The current blog post brings a description of all the changes of luminance-0.31. It should be the
last 0.*.*
version before hitting the 1.0
release. To the question:
Why not releasing
1.0
directly?
I answer that the 1.0
milestone has a backlog with two major changes that will take time to
implement and I think it would be a pity to postpone a lot of great changes that are already
available because of two features that are yet to be implemented. The concept of versions is to
allow releasing features in a structured way without having to wait too much. So here we are.
This post also show cases a small tutorial about how to get started with luminance. The very first steps you should have would be to have a look at the examples/ directory and try to play with all of the samples.
Disclaimer: the following section of this article is based on luminance’s changelog.
panic!
and attributeless renders.Format::R
and Format::RG
when querying a texture’s texels.GTup
. No code was using it and it was not really elegant.uniform_interface!
macro and replace it with the UniformInterface
procedural
derive macro.mut
operation. That is required to lock-in the mapped slices
and prevent to generate new ones, which would be an undefined behavior in most graphics backends
such as OpenGL.Texture<..>
type anymore, as a type family is now used to ease the generation of
color and depth slots).Vertex
trait is implemented.
Vertex::vertex_format
method has been renamed Vertex::vertex_desc
.VertexFormat
, that method now returns a VertexDesc
. Where a
VertexFormat
was a set of VertexComponentFormat
, a VertexDesc
is a set of
VertexBufferDesc
.VertexBufferDesc
is a new type that didn’t exist back then in 0.30. It provides new data
and information about how a vertex attribute will be spread in a GPU buffer. Especially, it has:
VertexAttribDesc
, the new name of VertexComponentFormat
.VertexComponentFormat
was renamed VertexAttribDesc
.VertexAttribType
’s integral variants.VertexAttrib
. Such a trait is used to map a type to a
VertexAttribDesc
.Vertex
has zero implementor instead of several ones in 0.30. The reason for that is that
VertexBufferDesc
is application-driven and depends on the vertex semantics in place in the
application or library.Semantics
trait.
Implementing directly Semantics
is possible, even though not recommended. Basically,
Semantics
provides information such as the index and name of a given semantics as long
as the list of all possible semantics, encoded by SemanticsDesc
.Vertex
and Semantics
proc-macro derive in the
[luminance-derive] crate.Tess
type to make it easier to work with.
Tess::new
and Tess::attributeless
functions were removed.TessBuilder
type was added and replace both the above function.a ..= b
operator, allowing to slice a Tess
with inclusive closed bounds...= b
operator, allowing to slice a Tess
with inclusive bounds open on the left
side.Tess::new
associated function expected indices to be a slice of u32
. This
new release allows to use any type that implements the TessIndex
trait (mapping a type to a
TessIndexType
. Currently, you have u8
, u16
and u32
available.Tess::{as_index_slice,as_index_slice_mut}
. Those now enable you to conditionally slice-map
the index buffer of a Tess
, if it exists.SamplerType
trait, used as constraint on the
Pixel::SamplerType
associated type.Floating
texture without caring about the
actual type. That is especially true as you typically use sampler2D
in a shader and not
sampler2DRGB32F
.layout (location = _)
is
correctly set to the right value regarding what you have in your Tess
’ vertex buffers. That
was both unsafe and terribly misleading (and not very elegant). The new situation, which
relies on vertex semantics, completely gets rid of vertex locations worries, which get
overrided by luminance when a shader program gets linked.enum
s — such as DepthTest
— variants from Enabled
/ Disabled
to
On
/ Off
or Yes
/ No
, depending on the situation.swap_buffers
from GraphicsContext
to Surface
in [luminance-windowing].GenMipmaps
instead of bool
to encode whether mipmaps should be generated in
texture code. That change is a readability enhancement when facing texture creation code.Dimensionable::zero_offset()
a constant, Dimensionable::ZERO_OFFSET
.bool
to CursorMode
.unsafe
can be
implemented in a safe way with that crate, so you should definitely try to use it.#[derive(Vertex)]
: derive the Vertex
trait for a struct
.#[derive(Semantics)]
: derive the Semantics
trait for an enum
.#[derive(UniformInterface)]
: derive the UniformInterface
trait for a struct
.Program<_, _, ()>
and still set uniform values by querying the uniforms
dynamically. This feature also fully benefits from the strongly typed interface of Uniform<_>
,
so you will get TypeMismatch
runtime error if you try to trick the type system.std
feature gate, allowing to compile with the standard library – this is enabled by
default. The purpose of this feature is to allow people to use default-features = false
to
compile without the standard library. This feature is currently very experimental and shouldn’t
be used in any production releases so far – expect breakage / undefined behaviors as this
feature hasn’t been quite intensively tested yet.R11FG11FB10F
pixel format.WindowOpt
now has support for multisampling. See the WindowOpt::set_num_samples
for
further details.Norm
is a normalized pixel format. Such formats state that the
texels are encoded as integers but when fetched from a shader, they are turned into
floating-point number by normalizing them. For instance, when fetching pixels from a texture
encoded with R8UI
, you get integers ranging in [0; 255]
but when fetching pixels from a
texture encoded with NormR8UI
, even though texels are still stored as 8-bit unsigned integers,
when fetched, you get floating-point numbers comprised in [0; 1]
.std::mem::uninitialized
references, as it is now on deprecation path. Fortunately, the
codes that were using that function got patched with safe Rust (!) and/or simpler constructs.
It’s a win-win.#[repr(C)]
annotation on vertex types in examples. That is a bit unfortunate because
such an annotation is very likely to be mandatory when sending data to the GPU and it should be
done automatically instead of requiring the user to do it. That situation will be fixed in a
next release.cargo run --example
command. Read more
here.#![deny(missing_docs)]
. The situation is still
not perfect and patch versions will be released to fix and update the documentation. Step by
step.11-query-texture-texels
example, which showcases how to query a texture’s texels and
drop it on the filesystem.irc.freenode.net
#luminance
I also spent quite a lot of time and energy working on two ways to learn luminance:
So far, I’m writing articles and the wiki is going to be updated let’s say, every week, if I find enough spare time. You can also tell me what kind of stuff you’d like to learn and do.
The official documentation is up to date but is not as good as I expect it to be. I will be adding patches versions to 0.31 to update it.
I hope you like luminance and will make a good use of it. And of course, keep the vibes!