Using Containers::Pair allows me to make certain Range APIs constexpr
that weren't possible in C++11 before. Compared to std::pair it's also
trivially copyable, which is a nice property when storing it in various
growable containers.
As usual, the <Corrade/Containers/PairStl.h> include is in place to help
people with porting, although in many cases this change will be
breaking. I had to do it at some point anyway, so the earlier it is the
better.
A somewhat inverse / complementary utility for parentsBreadthFirst() --
while the former is useful mainly for convenient parent referencing,
this is for children and nested children. Currently the main use case is
extracting scene subtrees, which is also what the example snippet shows.
Getting a list of direct children is also possible, although for that
it's possible to use the parentsBreadthFirst() as well as the Parent
field directly, simply by scanning for all field entries with given
value.
This allows to filter individual field entries in the scene, such as
for example removing certain mesh assignments that were collapsed
together. A higher-level API that allows filtering all data belonging to
a certain set of objects will be then implemented on top of this one.
Same reasoning as before, the verb suggests it's transforming the
SceneData in some way, which isn't true, it just retrieves the data in a
certain way. And if an API that actually operates on SceneData got
added, it would be easily confused with this one.
Plus, the "order" isn't just one, this orders objects so they're grouped
with a common parent, but what if I wanted to instead order depth first?
Thus it's explicitly saying this is a breadth-first order.
The API got moved to the Hierarchy.h header, removing a need for a
dedicated file and test.
That's a second deprecation of this API in a short while, sorry. This
variant is hopefully the final one, with the previous one I still had
the problem that it contained a verb, which implied that it'd
*transform* the SceneData in some way which (unlike combineFields(),
filterFields() etc.) it didn't, it just extracts some data in a certain
way. This would all cause problems when there are APIs that actually do
perform hierarchy flattening.
It's also moved to a new, more general Hierarchy.h header which will
contain other hierarchy-related APIs. It doesn't make sense to have a
tiny header with just a single function, especially given it doesn't
depend on any heavy headers on its own.
Besides that it also makes the UnsignedInt overloads the main ones, and
the Trade::SceneField secondary, as is already done everywhere else (and
the opposite way was just bad inheritance from flattenMeshHierarchy()
it seems).
Especially the part about non-owned data was lacking, with basically no
information about what are offset-only attributes and fields actually
good for.
It looked like it was last touched in 2012. Not great. Also, with this I
can finally stop explaining the four-byte-aligned-row defaults to people
and can just point them to docs.
Useful for creating pixel formats with different channel count,
adding/removing the sRGB bit and such. Counterpart to
vertexFormat(VertexFormat, UnsignedInt, bool) that got added back in
2020.06 already.
This is unfortunately a breaking change to compileLines(), which now
takes the output of generateLines() instead of a line mesh. There's a
new assertion that'll blow up if the code is used the previous way,
sorry for the breakage.
What's however very useful about this change is that now it's possible
to take those generated line meshes and concatenate() them together,
achieving what's otherwise not implemented yet, such as drawing several
disconnected line strips or loops together.
It's all still partially private (the custom mesh attribute names are)
and I'm marking both APIs as experimental now to hint that it's not in
the final form/functionality yet. In particular, the data layout
optimizations described in the shader docs aren't used by these tools
yet, and if/once the line-specific vertex attributes become builtin,
compileLines() will not need to exist anymore as compile() will handle
that directly.
Took me a while to realize that tying this to a certain hardcoded field
isn't a good idea. The new variant is useful also for example for
getting absolute light positions or just whatever else. Besides taking a
SceneField there's now also an overload taking a field ID to avoid
double lookups. The only behavioral difference compared to the old API
is that the field is now required to exist, instead of the API being a
silent no-op if not present.
Eventually these APIs may get further extended to take a BitArrayView of
objects for which to calculate the transforms, for example to take only
meshes that are a part of the hierarchy, or meshes that satisfy an
arbitrary other condition. Which will also resolve the remaining
concerns with the API. I'm still keeping it marked as experimental tho,
the usefulness isn't set in stone yet.
The old APIs are marked as deprecated and implemented using the new
ones.
It's included in the MagnumGL library because it shouldn't be compiled
if MAGNUM_TARGET_GL is disabled. So, in other words, this was breaking
the GL-less build.
This means I (and people making their own plugins) don't need to go and
update each and every plugin once the version in the interface string
gets bumped after a (silent) ABI break. Such as when new virtual
functions get added, as those often lead to strange crashes if the
plugins don't get rebuilt after.
The plugins will now use this macro, which means they'll
automatically embed an interface string that was present in the base
class header at build time. However, when the base class updates, the
previous string is still embedded in the plugin binary, which will then
fail to load -- this being automatic doesn't mean the original purpose
is lost. Subsequently rebuilding the plugins from source will make them
pick up the updated interface string again.
The `Type` was suggesting it'd be some C++ type, definitely not values
like Scaling3D or Translation2D, resulting in a significant "brain
autocompletion error" every time I was using that type.
Unfortunately on AnimationData the trackTargetType() couldn't similarly
get renamed to trackTarget() as there's already trackTarget() that
contains the node ID the target points to, so it's trackTargetName()
instead. Renaming trackTarget() to trackTargetId() wasn't an option as
that would be inconsistent with everything else (TextureTools::image(),
MaterialAttribute::BaseColorTexture, SceneField::Mesh are all IDs but
they don't have an `Id` suffix); renaming to AnimationTrackTargetName
would keep it insanely long and wouldn't make it consistent either
(MeshAttribute, SceneFIeld, MaterialAttribute are all referred to as
"names" yet they don't have a `Name` suffix).
Currently just the bare minimum, more features such as handling
multiple contiguous strips and loops inside a single mesh or an
overlapping layout will come later.
The shader requires the input data to be laid out in a rather specific
way, and there will be a dedicated MeshTools utility for it in the
following commits. For independence though, the shader tests use a
custom helper.
The initial implementation has certain corner cases which will be
eventually resolved. For now they are pinned down with repro cases in
the test. But apart from that, it's pretty much usable in practice.
Remaining join styles (round and miter-clip) as well as stipple support
will eventually follow as well.
Having code snippets in docs compiled and checked for syntax and
outdated API errors is great. In theory. In practice the people reading
docs have NO IDEA how much needless suffering goes into making the
compiler collaborate with me on such a seemingly simple task. UGH.
Counterparts to the sRGB-converting APIs, for when one doesn't want to
perform sRGB conversion. Or for "wrong sRGB" workflows. Named like this
and not just `fromRgbInt()` to make the calls at least a bit suspicious.
I did that just to be sure that 3c8fd70c12
didn't break anything, but to my surprise arrived at a difference
somewhere completely different.
The problem is that the SVGs were generated before Math::pack() was
fixed in e62ce4faa6 (Feb 2019) to perform
correct rounding, and so most color values were off by one. Heh.
Same as in the previous commit, most cases are inputs so a StringStl.h
compatibility include will do, the only breaking change is
GL::Shader::sources() which now returns a StringIterable instead of a
std::vector<std::string> (ew).
Awesome about this whole thing is that The Shader API now allows
creating a shader from sources coming either from string view literals
or Utility::Resource completely without having to allocate any strings
internally, because all those can be just non-owning references wrapped
with String::nullTerminatedGlobalView(). The only parts which aren't
references are the #line markers, but (especially on 64bit) those can
easily fit into the 22-byte (or 10-byte on 32bit) SSO storage.
Also, various Shader constructors and assignment operators had to be
deinlined in order to avoid having to include the String header, which
would be needed for Array destruction during a move.
Co-authored-by: Hugo Amiard <hugo.amiard@wonderlandengine.com>
This is the first builtin array attribute, with one of the objectives
being an ability to support an arbitrary count of per-vertex weights in
a single contiguous attribute without the complexity of having to go
through several four-component attributes.
On the shader side it still needs to get cut into at most four
components per attribute, but there's no reason for such limitation to
get propagated here as well.
Co-authored-by: Vladimír Vondruš <mosra@centrum.cz>
Finally got an idea how to provide various options store these
efficiently, so it's implemented now. Five different storage variants
times four different type sizes.
What's especially nice is that the code snippets no longer need to
describe that there's "2 lights, 3 materials and 5 draws" because now
it's self-documenting.
A bunch of new GLES- and WebGL-specific draw() variants got added in
b30d313ecd over a year ago, but so far
they weren't exposed in any of the Shaders because it'd mean a lot of
nasty copypasting and I just didn't like that.
So instead, there's a new macro to handle this messy work, and also
tested in order to ensure everything is still as it should be and that
it works even outside the Magnum namespace. This makes it much easier to
add new draw() variants (such as indirect draws, *finally*), without
having to update every shader implementation under the sun.
One difference is that I'm now allowing drawTransformFeedback() always
-- because that makes sense. It *is* possible to use a regular shader to
draw a result of a XFB, so it doesn't make sense to attempt to block
that.
The change to Shaders will be done in the next commit.