Not only the implementation is a template hell full of its own problems,
the internals are also just wrapping trivial bits of STL without adding
anything of value on top, so ultimately any code that actually used this
thing ended up being slower to build, more verbose, harder to reason
about and with thousands of tiny little inefficiencies all over the
place. So let's just finally say no to this idea from 2012.
"These seemed like a good idea at the time." But that was in 2013 and
while that might have been acceptable back then, it's not anymore, it's
all just a complex abstraction that prevents any reasonable resource
reuse and forces a dedicated draw call for each use.
Just do this directly from the corresponding Primitives instead.
Deprecating those allows me to eventually deprecate the (also
overengineered) ResourceManager class, at which point Magnum should be
finally free from the worst design decisions from 15 years ago.
Unfortunately several examples still rely on it (while it only makes
them more complex, not better), have to wait until those are cleaned up
first.
I'm going to deprecate the (awfully inefficient)
DebugTools::ForceRenderer and ObjectRenderer, and need at least
something else to direct the users to. This should suffice.
This was done back in October 2024 for all plugins in the magnum-plugins
repository, here it was blocked by usage in (now deprecated) MagnumFont.
In comparison the AnyImageImporter etc. plugins *are* meant to be
constructed directly by plugins that depend on them, so for those
nothing changes.
With StbTrueTypeFont no longer being embarrassingly slow due to a stupid
error, the MagnumFont plugin doesn't really provide any advantage
anymore. Originally I thought I'd update it to not be forcibly relying
on a TGA format and maybe add kerning support, but the image + text
format is extremely inefficient compared to basically anything else and
so I don't see a point in supporting it further. Marking it as
deprecated should also hint to people that using this thing is not a
good idea.
The MagnumFontConverter plugin was also the only user of the
AbstractFontConverter APIs, which right now are the last that didn't go
through a STL cleanup process. I plan to make a converter plugin for
font "minification" using HarfBuzz subsetting functionality, and not
having to support anything else that relies on the outdated APIs will
make the font converter API updates a bit easier.
Finally, the MagnumFont plugin was also the last one that directly
instantiated the TgaImporter plugin, instead of going through
AnyImageConverter. Marking it deprecated allows me to deprecate direct
instatiation in the remaining plugins as well.
Because MeshTools::removeDuplicates() uses a STL hashmap, it's quite
bad. So bad that on the Rungholt scene it takes 4 seconds out of 7.3 for
the whole import process.
Now I'm able to measure -- with the Rungholt scene from McGuire
archives, it takes it a whooping 7.3 seconds, measured with
magnum-sceneconverter --info-meshes --profile rungholt.obj
Compared to that, AssimpImporter in the default configuration takes 10.3
seconds, but with
magnum-sceneconverter --info-meshes --profile -I AssimpImporter \
-i postprocess/JoinIdenticalVertices=false,postprocess/SortByPType=false \
rungholt.obj
it takes just 4.3 seconds. And has the same vertex data size in total,
so that should probably be the default. I got some work to do, then.
The AbstractFont::openFile() and openData() now get an additional
argument specifying a font index to allow picking a concrete font index
for example in a TTC collection.
This index has to be specified upfront with no possibility to change it
afterwards, because that's how both FreeType and stb_truetype work. Thus
there are also new fileFontCount() and dataFontCount() APIs taking a
filename / data argument, instead of this being a fontCount() query on
an opened file. The implication from this is that -- unlike basically
all other APIs in Trade and elsewhere -- specifying an out-of-bounds
font index isn't an assertion (i.e., a programmer error) but rather a
graceful failure, because requireing the user to first call
fileFontCount() and then openFile() would mean having to open and
parse the same file twice, which is undesirable overhead.
While this isn't breaking for end users, as it's just a new optional
argument to openFile() and openData(), it's a breaking change for plugin
interfaces. The old doOpenFile() and doOpenData() interfaces are still
there to help transitioning existing plugins, but are marked as
deprecated. Delegating to those turned out to be quite involved, so
there are many new tests verifying this compatibility code path.
The plugin interface string version is bumped but in the next commits
I'm making use of the doOpenData() / doOpenFile() API breakage to do
more changes. Those won't result in further plugin interface changes, so
this set of commits should be treated as a single indivisible change to
the plugin interface. For this reason, uses of AbstractFont outside of
AbstractFontTest (including the MagnumFont plugin) aren't adapted yet
-- they pass tests as before, but compile only with deprecated APIs
enabled.
Co-authored-by: Andrew Snyder <asnyder@minitab.com>
Somehow I overlooked this extension back when implementing multidraw, or
maybe it was intentional because ANGLE supported multidraw but not this
extension.
Causes the following warning on GCC on a static build if user code isn't
compiled with -fvisibility=hidden:
warning: ‘Magnum::GL::Mesh’ declared with greater visibility than
the type of its field ‘Magnum::GL::Mesh::_attributes’ [-Wattributes]
According to quick testing, given that the struct definition isn't
public, presence of the MAGNUM_GL_LOCAL has no effect on the symbol
being exported. On the contrary, inner classes that are meant to be
exported (such as the ones in GL::Framebuffer) have to contain
MAGNUM_GL_EXPORT, otherwise it leads to linker errors. Furthermore, all
other inner structs with local definitions holding PIMPL state and such
don't have a MAGNUM_*_LOCAL macro applied anywhere
Thus the macro was likely redundant, and is removed.
I need this to sample a color map for debug visualization in the UI
library. Thus so far it's just 1D, and with 8-bit input. Other variants
might get added in the future if needed.
Yet another broken behavior with compressed textures on NVidia unearthed
by the recent changes with compressed block properties being set almost
always.
Text only, SDL3 has support for arbitrary mime types so the API is named
clipboardText() and not just clipboar(). Wanted to add this for
Emscripten as well, but after looking around a bit, I don't think I want
to deal with that until someone actually wants clipboard support
somewhere.
Is critically needed for the GltfImporter now, as the per-data importer
state is not useful on its own anymore and needs the Utility::Json
instance as well. And doing the same for AnyImageImporter as well for
feature parity.
And also immediately document it's not recommended to be used if it's
important to not miss any events, so basically next to useless. Yet some
projects implement their own key state caching on top of
Platform::Application, so it's better to give them the builtin thing
than suffer needless wheel reinvention.
Unlike _rgb and _rgbf these are not constexpr, but I'll eventually add
table-based constexpr variants into a new ConstexprLiterals namespace
for all sRGB and half-float variants.
This means I don't get the parsed number as an integer but have to parse
it myself from individual chars, on the other hand it allows me to check
that it's indeed hexadecimal and has correct length, because writing a
24-bit color literal with _rgbaf, or forgetting one digit, etc. was a
common source of accidental bugs.
The new code is larger and more complex, so I verified that it doesn't
have too large effect on compile times. On GCC the MathColorTest built
in ~1.20 seconds before and ~1.25 after, on Clang it was 1.24 vs 1.26.
So there's a minor increase, but it's small enough to warrant the
increased robustness. In total, the whole codebase with tests builds in
~120 seconds both before and after, so I suppose unless the codebase
consists of just color literals alone (which could be the case for e.g.
some stylesheets), it's completely fine.
And it found bugs in some test code already. Fix for those is in next
commit.
The original behavior was extremely imprecise. I remember hitting this
in the UI library, where it was happily telling me that a vector is
zero, and I spent ages debugging only to replace it with an equality
comparison that behaved correctly. Let's fix that properly.
Not file contents yet because the file can start with a XML preamble,
seven megabytes of comments and only then there's <svg. I'm not in a
mood for that today.
Counterpart to GlyphCacheArrayGL. At first I expected that it'd need
TextureTools::DistanceFieldGL to be expanded with texture array support
but after enough massaging of brain matter I realized that not really,
since the procesing has to be done slice by slice anyway, and having to
upload the whole array just to have a temporary input for processing
would be a waste of memory.
It just binds a layer of it to a framebuffer internally so no shader
changes or extra construction flags are needed. Originally I thought
about making the input an array as well, but ultimately that just
doesn't make sense -- the processing would need to be done slice by
slice anyway and you don't want to allocate the whole excessively sized
texture just for it to be used once, and only a part of it every time.
Wanted to add a proper variant that reads all layers at once into an
Image3D, but that requires the Image APIs to be made less crappy first.
So it's just this for noew because now I badly need it for
Text::DistanceFieldGlyphCacheArrayGL tests.
This was quite nasty, a multi-day effort to trim this down and then
increasingly growing disappointment as I discovered it was affecting
basically any use of the API.
Am I overdoing it? Most unpremultiplication code I found doesn't even
deal with treating alpha being zero correctly, while here I'm handling
also the cases of RGB channels going over alpha, and for packed
formats trying to match precision of the same done with pack()/unpack().
So far it contains just the uniform definitions and utilities related
to line drawing, nothing else, but especially the line utilities were
needed to be able to build MeshTools tests on a GL-less build.
The tests all pass exactly as they did before, apart from slightly
different assertion messages. I moved the guts from Renderer.cpp to
RendererGL.cpp as the code relies on both GL and STL, to not have it
spread over too many places.
I'm going to make a new Renderer class that's unlike the old one, and
isn't templated anymore either, so gotta make room for it first. I assume
that all existing code used the Renderer2D / Renderer3D typedefs so this
should be pretty much painless.
Ultimately this class will be gone, with only (then deprecated)
AbstractRenderer left, and Renderer2D / Renderer3D being aliases to it
-- internally it doesn't actually do anything dfferent, even the
positions are two-component in both cases.
As the time goes, I have less and less patience trying to figure these
things out. It's likely my fault for using the not-well-tested DSA APIs
or something.
For integer attributes, that is. This never worked and the MeshGLTest
even had an explicit test case for this, but it took me until now to
realize that this would be best caught at compile time. So now it is.
But since this functionality dates back to 2010, just removing the
values would likely break a lot of code (well, broken code, but still),
so the disallowed values are now deprecated, giving a compile time
warning when used, and are removed only on non-deprecated builds.