Browse Source

Trade: refresh MeshData docs slightly.

It was rather discouraging to start "Basic usage" with a boring-ass long
snippet. On the other hand showing just compile() first would lead
people to think it's all some opaque magic, so trying to balance that a
bit.

Also why the hell was the compile() snippet showing the horrendous GL
way of specifying attribute formats? This is not great either but at
least not redundant.
pull/525/head
Vladimír Vondruš 5 years ago
parent
commit
efa02d46df
  1. 11
      doc/snippets/MagnumMeshTools-gl.cpp
  2. 23
      doc/snippets/MagnumTrade.cpp
  3. 101
      src/Magnum/Trade/MeshData.h

11
doc/snippets/MagnumMeshTools-gl.cpp

@ -38,6 +38,8 @@
#include <vector>
#endif
#define DOXYGEN_IGNORE(...) __VA_ARGS__
using namespace Magnum;
int main() {
@ -55,8 +57,9 @@ GL::Mesh mesh = MeshTools::compile(meshData, indices, vertices);
{
Trade::MeshData meshData{MeshPrimitive::Lines, 5};
Trade::MeshAttribute myCustomAttribute{};
/* [compile-external-attributes] */
Trade::MeshAttribute myCustomAttribute = DOXYGEN_IGNORE({});
GL::Buffer indices, vertices;
indices.setData(meshData.indexData());
vertices.setData(meshData.vertexData());
@ -66,10 +69,8 @@ GL::Mesh mesh = MeshTools::compile(meshData, std::move(indices), vertices);
mesh.addVertexBuffer(std::move(vertices),
meshData.attributeOffset(myCustomAttribute),
meshData.attributeStride(myCustomAttribute),
GL::DynamicAttribute{
GL::DynamicAttribute::Kind::Generic, 7,
GL::DynamicAttribute::Components::One,
GL::DynamicAttribute::DataType::Float});
GL::DynamicAttribute{GL::DynamicAttribute::Kind::Generic, 7,
meshData.attributeFormat(myCustomAttribute)});
/* [compile-external-attributes] */
}

23
doc/snippets/MagnumTrade.cpp

@ -638,7 +638,7 @@ constexpr Trade::MeshAttributeData colors{Trade::MeshAttribute::Color,
/* Actual data populated later */
Containers::Array<char> vertexData{15*sizeof(Vertex)};
// ...
DOXYGEN_IGNORE()
Trade::MeshData{MeshPrimitive::Triangles, std::move(vertexData),
{positions, colors}};
/* [MeshAttributeData-usage-offset-only] */
@ -656,6 +656,14 @@ Trade::MeshAttributeData normals{Trade::MeshAttribute::Normal,
#endif
#ifdef MAGNUM_TARGET_GL
{
/* [MeshData-usage-compile] */
Trade::MeshData data = DOXYGEN_IGNORE(Trade::MeshData{MeshPrimitive::Points, 0});
GL::Mesh mesh = MeshTools::compile(data);
/* [MeshData-usage-compile] */
}
{
Trade::MeshData data{MeshPrimitive::Points, 0};
/* [MeshData-usage] */
@ -672,7 +680,7 @@ vertices.setData(MeshTools::interleave(data.positions3DAsArray(),
mesh.addVertexBuffer(std::move(vertices), 0,
Shaders::PhongGL::Position{}, Shaders::PhongGL::Normal{});
/* Set up an index buffer, if the mesh is indexed*/
/* Set up an index buffer, if the mesh is indexed */
if(data.isIndexed()) {
GL::Buffer indices;
indices.setData(data.indicesAsArray());
@ -702,8 +710,6 @@ mesh.addVertexBuffer(vertices,
GL::DynamicAttribute{Shaders::PhongGL::Normal{},
data.attributeFormat(Trade::MeshAttribute::Normal)});
// Set up other attributes ...
/* Upload the original packed index data */
if(data.isIndexed()) {
GL::Buffer indices;
@ -713,13 +719,6 @@ if(data.isIndexed()) {
} else mesh.setCount(data.vertexCount());
/* [MeshData-usage-advanced] */
}
{
Trade::MeshData data{MeshPrimitive::Points, 0};
/* [MeshData-usage-compile] */
GL::Mesh mesh = MeshTools::compile(data);
/* [MeshData-usage-compile] */
}
#endif
{
@ -747,7 +746,7 @@ struct Vertex {
Containers::Array<char> indexData{indexCount*sizeof(UnsignedShort)};
Containers::Array<char> vertexData{vertexCount*sizeof(Vertex)};
// …
DOXYGEN_IGNORE()
auto vertices = Containers::arrayCast<const Vertex>(vertexData);
auto indices = Containers::arrayCast<const UnsignedShort>(indexData);

101
src/Magnum/Trade/MeshData.h

@ -223,7 +223,7 @@ index array. The @ref MeshIndexType gets inferred from the view type:
Alternatively, you can pass a typeless @cpp const void @ce view and supply
@ref MeshIndexType explicitly, or a contiguous 2D view and let the class detect
the actual index type from second dimension size. Note that the class accepts
only contiguous views and not @ref Corrade::Containers::StridedArrayView,
only contiguous views and not @relativeref{Corrade,Containers::StridedArrayView},
following limitations of GPU index buffers that also have to be contiguous.
@see @ref MeshAttributeData
*/
@ -594,47 +594,60 @@ information such as primitive type. Populated instances of this class are
returned from @ref AbstractImporter::mesh() and from particular functions in
the @ref Primitives library.
@section Trade-MeshData-usage-compile Quick usage with MeshTools::compile()
If all you want is to create a @ref GL::Mesh that can be rendered by builtin
shaders, a simple yet efficient way is to use @ref MeshTools::compile():
@snippet MagnumTrade.cpp MeshData-usage-compile
This one-liner uploads the data and configures the mesh for all attributes
known by Magnum that are present in it. It's however rather opaque and doesn't
give you any opportunity to do anything with the mesh data before they get sent
to the GPU. It also won't be able to deal with any custom attributes that the
mesh contains. Continue below to see how to achieve a similar effect with
lower-level APIs.
@section Trade-MeshData-usage Basic usage
The simplest usage is through the convenience functions @ref positions2DAsArray(),
@ref positions3DAsArray(), @ref tangentsAsArray(), @ref bitangentsAsArray(),
@ref normalsAsArray(), @ref tangentsAsArray(), @ref textureCoordinates2DAsArray(),
@ref colorsAsArray() and @ref objectIdsAsArray(). Each of these takes an index
(as there can be multiple sets of texture coordinates, for example) and you're
expected to check for attribute presence first with either @ref hasAttribute()
or @ref attributeCount(MeshAttribute) const:
The second simplest usage is accessing attributes through the convenience
functions @ref positions2DAsArray(), @ref positions3DAsArray(),
@ref tangentsAsArray(), @ref bitangentsAsArray(), @ref normalsAsArray(),
@ref tangentsAsArray(), @ref textureCoordinates2DAsArray(),
@ref colorsAsArray() and @ref objectIdsAsArray(). You're expected to check for
attribute presence first with either @ref hasAttribute() (or
@ref attributeCount(MeshAttribute) const, as there can be multiple sets of
texture coordinates, for example). If you are creating a @ref GL::Mesh, the
usual path forward is then to @ref MeshTools::interleave() attributes of
interest, upload them to a @ref GL::Buffer and configure attribute binding for
the mesh.
The mesh can be also indexed, in which case the index buffer is exposed through
@ref indicesAsArray().
@snippet MagnumTrade.cpp MeshData-usage
@section Trade-MeshData-usage-advanced Advanced usage
The @ref positions2DAsArray(), ... functions shown above always return a
newly-allocated @ref Corrade::Containers::Array instance with a clearly defined
type that's large enough to represent most data. While that's fine for many use
cases, sometimes you may want to minimize the import time of a large model or
the imported data may be already in a well-optimized layout and format that you
want to preserve. The @ref MeshData class internally stores a contiguous blob
of data, which you can directly upload, and then use provided metadata to let
the GPU know of the format and layout. Because there's a lot of possible types
of each attribute (floats, packed integers, ...), the @ref GL::DynamicAttribute
can accept a pair of @ref GL::Attribute defined by the shader and the actual
@ref VertexFormat, figuring out all properties such as component count and
element data type without having to explicitly handle all relevant types:
newly-allocated @relativeref{Corrade,Containers::Array} instance of a type
that's large enough to represent most data. While that's fine for many use
cases, it can take significant amount of time for large models or maybe the
imported data is already in a well-optimized layout and format that you want to
preserve. The @ref MeshData class internally stores a contiguous blob of data,
which you can directly upload, and then use provided metadata to let the GPU
know of the format and layout. There's a lot of possible types of each
attribute (floats, packed integers, ...), so @ref GL::DynamicAttribute accepts
also a pair of @ref GL::Attribute defined by the shader and the actual
@ref VertexFormat, figuring out gthe GL-specific properties such as component
count or element data type for you:
@snippet MagnumTrade.cpp MeshData-usage-advanced
@section Trade-MeshData-usage-compile Using MeshTools::compile()
For a quick yet efficient way to upload all data and configure a mesh for all
known attributes that are present, @ref MeshTools::compile() can be used.
Compared to the above, it's just an oneliner:
@snippet MagnumTrade.cpp MeshData-usage-compile
Compared to configuring the mesh manually you may lose a bit of flexibility,
especially when you need to set up custom attributes or modify the data after.
See @ref MeshTools::compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&)
for a possible solution.
This approach is especially useful when dealing with custom attributes. See
also @ref MeshTools::compile(const Trade::MeshData&, GL::Buffer&, GL::Buffer&)
for a combined way that gives you both the flexibility needed for custom
attributes as well as the convenience for builtin attributes.
@section Trade-MeshData-usage-mutable Mutable data access
@ -658,21 +671,21 @@ to do a similar operation with normals and tangents as well.
@section Trade-MeshData-populating Populating an instance
A @ref MeshData instance by default takes over the ownership of an
@ref Corrade::Containers::Array containing the vertex / index data together
with a @ref MeshIndexData instance and a list of @ref MeshAttributeData
describing various index and vertex properties. For example, an interleaved
indexed mesh with 3D positions and RGBA colors would look like this ---
and variants with just vertex data or just index data or neither are possible
too:
@relativeref{Corrade,Containers::Array} containing the vertex / index data
together with a @ref MeshIndexData instance and a list of
@ref MeshAttributeData describing various index and vertex properties. For
example, an interleaved indexed mesh with 3D positions and RGBA colors would
look like this --- and variants with just vertex data or just index data or
neither are possible too:
@snippet MagnumTrade.cpp MeshData-populating
In cases where you want the @ref MeshData instance to only refer to external
data without taking ownership (for example in a memory-mapped file, constant
memory etc.). Instead of moving in an @ref Corrade::Containers::Array you pass
@ref DataFlags describing if the data is mutable or not together with an
@ref Corrade::Containers::ArrayView. A variant of the above where the index
data is constant and vertex data mutable, both referenced externally:
memory etc.). Instead of moving in an @relativeref{Corrade,Containers::Array}
you pass @ref DataFlags describing if the data is mutable or not together with
an @relativeref{Corrade,Containers::ArrayView}. A variant of the above where
the index data is constant and vertex data mutable, both referenced externally:
@snippet MagnumTrade.cpp MeshData-populating-non-owned
@ -1092,7 +1105,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
*
* Use the templated overload below to get the indices in a concrete
* type.
* @see @ref Corrade::Containers::StridedArrayView::isContiguous()
* @see @relativeref{Corrade,Containers::StridedArrayView::isContiguous()}
*/
Containers::StridedArrayView2D<const char> indices() const;
@ -1315,7 +1328,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
* implementation-specific values) and is guaranteed to be contiguous.
* Use the templated overload below to get the attribute in a concrete
* type.
* @see @ref Corrade::Containers::StridedArrayView::isContiguous(),
* @see @relativeref{Corrade,Containers::StridedArrayView::isContiguous()},
* @ref vertexFormatSize(),
* @ref isVertexFormatImplementationSpecific()
*/
@ -1398,7 +1411,7 @@ class MAGNUM_TRADE_EXPORT MeshData {
* type.
* @see @ref attribute(UnsignedInt) const,
* @ref mutableAttribute(MeshAttribute, UnsignedInt),
* @ref Corrade::Containers::StridedArrayView::isContiguous(),
* @relativeref{Corrade,Containers::StridedArrayView::isContiguous()},
* @ref isVertexFormatImplementationSpecific()
*/
Containers::StridedArrayView2D<const char> attribute(MeshAttribute name, UnsignedInt id = 0) const;

Loading…
Cancel
Save