Amazing, I haven't been in this corner of the codebase for over six
months but the test setup and code coverage still makes it quite
straightforward to add a rather complex new feature without breaking
unrelated cases or leaving certain areas completely untested.
To be used with the recently added MaterialTools::removeDuplicates() for
example, or internally by other upcoming scene tools such as importer
filtering.
Usage pattern is very similar to the duplicate removal utilities in
MeshTools, except that here the process is a simple O(n^2 m) operation,
without any hashing. Turned out to be good enough, in the initial tests
at least.
This "type erased std::vector member" was done in the times before
growable arrays were a thing, and kind of made sense to go the extra way
to avoid a <vector> include in the header. Except that it made rather
unportable assumptions about std::vector size, which weren't correct for
example with _GLIBXX_ASSERTIONS set.
But what was *completely* unacceptable was that the vector was of one or
another type depending on the GL feature set present in the current
context. Apart from adding a lot of extra *nasty* logic to construction,
moves and destruction, this approach led to the mesh instance asking the
current context on destruction in order to know whether a destructor
should be called on std::vector<Buffer> or std::vector<AttributeLayout>.
Ugh.
Now it's a regular Array member (which isn't *that* heavy to need such
type-erased treatment, although it eventually could be), and thanks to
the AttributeLayout packing improvements in previous commits it's no
longer prohibitively wasteful to just abuse AttributeLayout instances to
store just owning Buffer instances alone -- doing so now wastes only 16
bytes per buffer, compared to 36 before. Given there's usually just one
or two vertex buffers per mesh (compared to attributes, which are
usually 4 or more), it should be fine.
The MeshGLTest::destructMovedOutInstance() test added few commits back
also no longer asserts on no GL context being present.
Saves 8 bytes (104 -> 96 bytes), which were before wasted on 4
byte padding before the 8-byte _indexBufferOffset member and 4 bytes
after the _indexBuffer, which is new there due to the Buffer being 8
instead of 12 bytes now.
On ES2 there's three 32-bit members less, which means this change only
moved the 4-byte after _indexBuffer to after _indexType, i.e. 88 bytes
before and 88 now as well.
Which, thanks to a 3-byte padding being now just 1 byte, makes the
Buffer class 8 bytes large instead of 12. And in turn, the internal
Mesh::AttributeLayout struct is now 40 bytes instead of 48 as there's no
longer an extra 4 bytes of padding to satisfy 8-byte alignment of the
offset member. Still can go lower than that.
Want to construct them without a GL context present, and Optional is too
wasteful. Also adding it to the AbstractGlyphCache base, where it skips
also allocating the internal PIMPL state, because it's not going to get
used for anything in a NoCreate'd instance anyway.
The test added in previous commit now passes. Besides the behavior being
different for single- and multi-bind calls, an additional "interesting"
behavior is that the glBindBufferBase() / glBindBufferRange()
apparently also creates the GL object, if not already (in contrast to
the multi-bind APIs which *require* the GL objects to be created
before).
Gotta admit I wasn't aware of this side effect, at all. Once I realized
that, a fix seemed simple at first, only to make a second (re)discovery,
where glBindBuffersRange() / glBindBuffersBase() does *not* have this
side effect.
I get that it's all a shaky pile building on top of a long legacy, but
still, it never ceases to amaze.
Need them for the UI. Will eventually need the sRGB literals too, not
sure what to do there yet, std::pow() is only constexpr in C++26. I'll
be probably long retired when *that* version becomes the min spec for
Magnum.
If Magnum and Corrade get installed into the same directory,
target_include_directories() or target_link_libraries() with Corrade
before Magnum will result in the (usually stale) installed Magnum
headers being picked over the local ones. Which is unwanted, so try to
always put the local Magnum include path first.
Tested manually by installing to an arbitrary location and editing
configure.h to contain an #error. That failed for the Text library, and
with these changes it now doesn't fail anymore, but that's not a
guarantee that I managed to fix all such cases.
Especially given that nullptr causes an assert. All call sites basically
ended up passing a &font and all that extra annoyance just doesn't make
sense.
Given this API is still relatively recent, I'm not bothering with
backwards compatibility.
Which also allows the internals to be a bit simpler / potentially more
efficient, as the implementation can now access the glyph cache contents
directly, without a getter.
The new API makes it possible to alias storage for the glyph offsets,
advances and IDs (20 bytes per glyph) directly with the output positions
+ texcoords (16 bytes per glyph, times four) by splitting the retrieval
in two steps.
I wonder how long will it take before this bites back, heh.
In basically all cases it's two independent operations so forcing them
to be done together doesn't really bring any potential efficiency
advantages. On the other hand, splitting them allows allows the caller
to better make use of available memory, as the new
renderGlyphQuadsInto() allows the input and output arrays to be aliased.
Bumping AbstractFont plugin interface versions as this is a breaking
change.
The awful original STL-heavy public API is kept the same for now, it's
just the internals being now implemented using brand new APIs that are
actually usable with multiple fonts, font sizes and runs with different
scripts/languages/directions. There's also preparation for configurable
vertical text layouting, although for now the functionality asserts that
horizontal text is used.
This also makes Renderer.h header available on non-GL builds, as the new
APIs don't rely on a class full of GL objects anymore. The class will
get eventually renamed and moved to a dedicated RendererGL.h header, but
for now this partial update has to suffice.
To be used as a placeholder argument in the reworked renderer APIs. No
intention to deal with the complexities of this right now, just taking
it to not have to deprecate & replace the API when this feature actually
gets implemented.
So it's possible to shape the text even before having all glyphs ready.
That's one reason, second reason is that this is a more common behavior
-- it usually doesn't make sense to make the text jump based on whether
it's "zaxaca", "KEKEKE" or "yqpyq".
The original alignment based on glyph bounds is now moved into dedicated
`*GlyphBounds` variants. Additionally the `*LeftGlyphBounds` were
changed to subtract the initial glyph offset as well, `*Integer` now
rounds only in the direction where it's needed because a division by 2
happened, and there's a set of `*Bottom*` values that somehow weren't
there before.