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).
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.
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 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.
Haha, I even had a TODO here. An exception in this case is when the mesh
is already interleaved -- then the layout is kept intact and thus it's
not needed to know what vertex format sizes to repack.
The array size is always last, defaulting to 0. This makes it consistent
with the offset-only constructor and removes two unnecessary overloads.
It's a breaking change, but I don't think array attributes have many
users yet -- and better to do this now than later. In any case, sorry
about breaking your code.
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.
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
The point of this change is to allow greater flexibility and reduce
confusion.
When instanced meshes are implemented, MeshTools::interleave() can be
used for creating interleaved buffers with per-instance data and then
the call to Mesh::setCount() will be harmful and/or confusing, becuase
the user would in fact want to call Mesh::setInstanceCount() instead.
Similarly, MeshTools::compressIndices() can be used to create index
buffer for more than one mesh.
GL 4.4 has ARB_buffer_storage, which (in relatively distant future) will
mean that the current way of Buffer::setData() will be deprecated in
favor of Buffer::setStorage(), similarly as Texture::setStorage()
replaced Texture::setImage(). Thus any function which calls
Buffer::setData() internally is not future-proof.
The old MeshTools::compressIndices() and MeshTools::interleave()
overloads are marked as deprecated and will be removed in future
release.
Basically a version of interleave() which takes existing buffer instead
of creating new zero-initialized one. The last bit needed for real
runtime usage.
Everything are now pure functions, no shared state, no useless functor
class wrapping. Still needed to wrap attribute count and stride
computation functions in struct to make proper overload resolution
working without the need to deinline the functions (they have cyclic
dependencies).
The only places where they aren't absolute are:
- when header is included from corresponding source file
- when including headers which are not part of final installation (e.g.
test-specific configuration, headers from Implementation/)
Everything what was in src/ is now in src/Corrade, everything from
src/Plugins is now in src/MagnumPlugins, everything from external/ is in
src/MagnumExternal. Added new CMakeLists.txt file and updated the other
ones for the moves, no other change was made. If MAGNUM_BUILD_DEPRECATED
is set, everything compiles and installs like previously except for the
plugins, which are now in MagnumPlugins and not in Magnum/Plugins.
We have std::memset for that. What the hell I was thinking back then.
Found when trying to get rid of as many naked allocations and deletions
as possible. Also improved the test with some ASCII-art documentation.
Print expected and actual count to simplify debugging. Also the phrase
"nothing done." is useless, as nothing is _ever_ done after assertion
failure. Probably remains from the times where that wasn't assertion but
merely harmless warning.