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.
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.
It made testing and everything harder than strictly necessary. OTOH
still keeping MeshData as a friend and accessing members directly since
those are heavily interconnected anyway.
This makes it possible to have fully allocation-less MeshData, with
statically defined indices and attributes. Only the final MeshData
construction needs to be done at runtime because Array is not constexpr,
but that isn't anything heavy anyway.
With API analogous to the (relatively) new AnimationData -- with one
buffer containing all index data and one buffer containing all vertex
data, both meant to be uploaded as-is to the GPU.
This will eventually replace MeshData2D and MeshData3D, backwards
compatibility and wiring up to other APIs will be done in follow-up
commits.