Apmong other things where it's useful for end users as a more convenient
alternative to recreating the MeshData by hand, I need to use this
inside the transform() utilities to preserve all index buffer properties
without copypasting nasty code everywhere.
As implementation-specific index types cause the index buffer to be
strided. which is not allowed by default, these work only if
InterleaveFlag::PreserveStridedIndices is set. Originally I thought
about straight-out disallowing implementation-specific types here,
unfortunately that broke some valid use cases so I backtracked on that
decision.
In the future I might change the default to preserve
implementation-specific indices with sane strides (i.e., positive powers
of 2), but that will only be done once similar treatment is finished for
attributes (currently zero and negative strides are just disallowed
completely).
The previous commits changed *nothing* related to this code, yet somehow
a Release build started warning about this variable maybe being used
uninitialized in the attribute checking loop even though it's *clearly*
not the case.
Tools are getting less useful and more annoying DAY BY DAY.
This mirrors what's done already for implementation-specific vertex
formats, thus:
* Ability to construct the classes without tripping up when trying to
check for type size in various asserts
* Providing a zero-size type-erased access in indices() and
mutableIndices()
* Disallowing typed and convenience access
The type is now extended to 32 bits. In the GL and Vk libraries it means
one can now do things like
MeshIndexType type = meshIndexTypeWrap(GL_UNSIGNED_BYTE);
and passing that to GL::Mesh or Vk::Mesh will cause it to use the value
directly, instead of doing a mapping from a generic type. The *real* use
case for this is however to allow custom index buffer representations in
Trade::MeshData. Support for that will be hooked up in the following
commit.
Otherwise it makes a tightly-packed copy. This also means that arbitrary
padding before/after the index buffer is preserved only in case it would
mean the data can be transferred without a copy -- otherwise it's faster
to just drop the padding and copy only the used part.
The reference() and mutableReference() utils preserve that implicitly as
MeshData::indices() now returns a strided array view containing all
needed information.
Also not something the classic GPU vertex pipeline can handle, but
useful for other scenarios. Subsequently a support for array indices
will be added, allowing to directly represent for example OBJ files,
where each attribute has its own index buffer.
I tried, I really did, but the downsides eventually just outweighed the
potential of this feature and I gave up. May try to tackle this again in
the future, but not now.
This is not something the classic GPU vertex pipeline can handle
(except maybe Vulkan, which can handle zero strides for instanced
attributes?), but useful for other scenarios. This means existing code
needs to be aware of and handle the new corner case.
Since the main speed advantage of the function is that it hashes a
*whole* vertex together instead of going through the attribute arrays
one by one, it can't really operate on whatever funny interleaved layout
it was given as there may be padding bytes with random content, breaking
the deduplication.
Since checking that a layout is really padding-less is rather complex,
the repacking is now performed always. This also means the && overload
makes no sense anymore and thus it was dropped.
This makes the test added in the previous commit not assert anymore, and
behave the same as the padding-less case.
Leads to an assertion inside StridedArrayView constructor, because I
just pass through the original attribute offsets/strides even though
interleavedMutableData() gives me a much smaller stride.
Moreover, because I just perform the deduplication on the original
vertex data *including* all random padding, the duplicate removal won't
always be able to find all duplicates. So test that case here as well --
turns out we just have to repack the data completely, after all.
This took me quite a while to realize -- not always it's desirable to
have the original layout unconditionally preserved, especially if for
example filtering a MeshData to just a subset of attributes.
TBF I have to thank CircleCI for sending me no less than three warning
e-mails about Xcode image deprecation. I just didn't bother
updating until it started actually failing.
Funny how even doing the *insanely complex* operation of extending a
MeshData with one extra attribute is still shorter than manually
populating the GL::Mesh.