Consistently with checkLink(), this avoids having to explicitly include
both Iterable and Reference in shader code. Alsod allowing people to
have direct arrays of shaders, runtime-sized lists of shaders etc.
A compat include is provided on a deprecated build to avoid breaking
existing code.
The class is rather heavy (strings, STL vector) and it'll stay heavier
than strictly needed even after the planned STL cleanup -- shader users
should not bear the overhead of Array, StringView etc. that it needs in
order to compile the shader sources.
I might eventually come to a different conclusion (maybe separating
GL::Shader population and usage like doing in Vulkan with CreateInfos),
but right now this commit has the best available solution -- converting
the instance to a lightweight class containing just ID and type, and
then converting that back to a GL::Shader upon checking compilation/link
status.
While at it, also removed the not-strictly-needed Optional usage from
the header. It wouldn't work with forward-declared GL::Shader anyway.
The whole time I thought this class doesn't need such APIs due to being
rather short-lived. But now with async shader compilation it's no longer
so short-lived.
There's no reason for those to exist anymore -- origiinally they were
added in a hopeful attempt to make use of parallel shader compilation,
but in practice that meant compiling at most two or three shaders at
once and still stalling until that was done, so not that great at all.
The new APIs provide much better opportunities for parallelism.
Fun fact:
CORRADE_INTERNAL_ASSERT_OUTPUT(vert.compile() && frag.compile());
is actually one character shorter than
CORRADE_INTERNAL_ASSERT_OUTPUT(GL::Shader::compile({vert, frag}));
so not even typing convenience would be a reason to keep these.
The new async APIs were just checking the link status, and printing the
linker error. Because drivers commonly do all that in a single step,
without really separating compilation from linking (or at least that's
what I thought?), I assumed the linker error would contain *also* the
compilation error, if any.
But on a quick check with Mesa that's not the case, I only get "error:
linking with uncompiled/unspecialized shader", which is very useless.
Which means, to get proper error output, the checkLink() function now
explicitly takes a list of the input shaders. It will unconditionally go
through them at the beginning and call checkCompile() on each.
To further encourage the shaders to be passed, there's no default
argument -- so if the application calls checkCompile() on its own for
some reason, it has to pass an empty list to checkLink().
Until now it relied on the driver adding a \n after each message. Which
happened in 99% cases, but sometimes not, and it is really annoying in
that case. Right now I witnessed Mesa giving me a non-newlined message
if I call checkLink() and a shader compilation failed before, resulting
in nasty output like
error: linking with uncompiled/unspecialized shaderAssertion checkLink() failed at /home/mosra/Code/magnum/src/Magnum/Shaders/FlatGL.cpp:248
And I bet I encountered other weird cases, like there being two
newlines, or the message being just a newline without any other content,
thus spamming the output on every compilation. It's not practical to try
to find driver-specific workarounds here, so I'm just trimming always
and then rely on Debug adding its own newline after.
In particular:
- listing the *very important* stuff -- such as what macro to define to
make the library usable at all -- in the header
- mentioning what to do if cross-SO/DLL visibility is desired
The actual generated single-header file will be updated once I find more
time. Not now.
Marking it as having "some" caveats right now, will change it to none
once the remaining features like camera & light export are added and
once the mesh buffer views get more compact.
This happened because I made an early implementation of the batch
AbstractSceneConverter APIs, stashed it away, then implemented image
flags and then continued working on the stash, unaware that it's
outdated.
It makes no difference in this case, the State struct is not exported
even without the attribute. OTOH, it would need to have an EXPORT
attribute if it was desired to be exported, for example like done with
nested classes in GL::Framebuffer.
The enum-to-string conversion was just a private API and we need to use
it in various material filtering code. It was also a private class member
for some reason, even though it has no relation to / dependency on the
MaterialData class. So it's made a free function instead.
The MeshData and SceneData find APIs had the complexity documented, do
the same for MaterialData too. Plus cross-link this API from
hasAttribute() / hasField() so it's easier to find.
Unlike most other options, where a plugin can support 3D but not 2D or
compressed but not uncompressed data, the "levels" option is orthogonal
to the rest -- if a format supports multi-level data, it obviously also
supports a case where there is just a single level, and if it supports
multi-level images, then it likely supports them for 1D, 2D and 3D, not
just some.
I used the same reasoning for the new SceneConverterFeatures interfaces
already, just "backporting" it here as well.
The bit pattern actually followed this already, but for some reason I
still went ahead and stamped out all possible combinations. Because
of that, nothing really changes on the ABI side either and the
deprecated aliases are now exactly as they were before, so no need to
bump the plugin interface version.