The combineIndexArrays() and combineIndexedArrays() API is replaced with
a more generic combineIndexedAttributes(), and thanks to that we also
don't need STL-based duplicate() and removeDuplicates().
Similar to image mip level import, but this is largely left to be
importer-specific. For example PLY defines per-face data and sometimes
one might want to import them as-is, without them being turned into a
per-vertex property.
GL was missing a check whether given format is available on a target
(for example double types are not on ES), and for Vulkan we need something
similar to pixel format mapping as well.
Similarly to PixelFormat. Will be useful for Vulkan, unfortunately not
so much for GL because there the format is specified by three orthogonal
values and it's a terrible mess.
Originally this was done in order to make handling of deserialized data
much simpler (as for those attributes also need to only contain an
offset into some unknown data array), but seems this could be very
useful elsewhere as well -- for example when the layout is known
beforehand but the actual data not yet -- such as in the Line and
Gradient primitives (going to switch them to this in the next commit).
What still unfortunately has to be known in advance is the actual vertex
count (as supplying it directly to MeshData would mean adding 6 new
constructor overloads, and there's enough of those already). Might
revisit later.
Before it was a 32-byte structure with 3 bytes free (or a 20-byte
structure with 3 bytes free), now it's a 24-byte structure with 5 bytes
free. Exploiting the fact that strides can't be too high for a GPU
anyway (so 2 bytes is enough instead of 8), and vertex count is capped
to 32bit by MeshData anyway (so no need for 8 also), saving 10 bytes on
a 64-bit build.
The internals don't use any std::vector anymore, only the icosphere
needs an std::unordered_map to do duplicate removal. Additionally, the
most simple primitives are now simply views on constant data,
being completely zero-allocation.
On a Mac this resulted in the dylib going down from 1.5 MB to 418 kB in
Debug, and from 129 kB to 90 kB in Release. Quite nice.
The tests are not ported away from MeshDataXD yet as I want to ensure
the behavior is *exactly* as before.
For backwards compatibility these will delegate to the new MeshData
interfaces for 3D (and nothing for 2D, because so far there were no 2D
scene importers).
This was originally meant to be an interleave() that operates on
MeshData, but later I realized I need the same logic in duplicate(), so
turned it into a private function. Now I am pretty sure I'll be using
this function in *many* importer plugins :D
It only resets count of released thing to zero, not going all nuclear.
Otherwise it wouldn't be possible to release attribute data and then
vertex data as releasing one would wipe the other.
Allow to make:
- an indexed mesh with zero indices
- a mesh with non-zero attribute count but zero vertices
- a mesh with non-zero vertex count but zero attributes
All of these are valid use cases as explained in the tests, and will
also make the release*() behavior defined better.