Skip to content

Commit

Permalink
MeshTools: deprecate mesh/buffer-modifying vertex/index tools.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mosra committed Apr 27, 2014
1 parent 2834e60 commit 51a14b9
Show file tree
Hide file tree
Showing 9 changed files with 216 additions and 163 deletions.
22 changes: 20 additions & 2 deletions src/Magnum/DebugTools/Implementation/AbstractShapeRenderer.cpp
Expand Up @@ -59,8 +59,17 @@ template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource,
/* Index buffer, if needed, if not, resource key doesn't have to be set */
if(data.isIndexed()) {
CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());

Containers::Array<char> indexData;
Mesh::IndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(data.indices());

Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
MeshTools::compressIndices(*mesh, *indexBuffer, BufferUsage::StaticDraw, data.indices());
indexBuffer->setData(indexData, BufferUsage::StaticDraw);
mesh->setCount(data.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);

ResourceManager::instance().set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);

/* The mesh is not indexed, set proper vertex count */
Expand All @@ -82,8 +91,17 @@ template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource,
/* Index buffer, if needed, if not, resource key doesn't have to be set */
if(data.isIndexed()) {
CORRADE_INTERNAL_ASSERT(indexBufferResource.key() != ResourceKey());

Containers::Array<char> indexData;
Mesh::IndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(data.indices());

Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
MeshTools::compressIndices(*mesh, *indexBuffer, BufferUsage::StaticDraw, data.indices());
indexBuffer->setData(indexData, BufferUsage::StaticDraw);
mesh->setCount(data.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);

ResourceManager::instance().set(indexBufferResource.key(), indexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);

/* The mesh is not indexed, set proper vertex count */
Expand Down
3 changes: 2 additions & 1 deletion src/Magnum/DebugTools/ObjectRenderer.cpp
Expand Up @@ -26,6 +26,7 @@
#include "ObjectRenderer.h"

#include "Magnum/Buffer.h"
#include "Magnum/Mesh.h"
#include "Magnum/DebugTools/ResourceManager.h"
#include "Magnum/MeshTools/Interleave.h"
#include "Magnum/SceneGraph/AbstractCamera.h"
Expand Down Expand Up @@ -159,7 +160,7 @@ template<UnsignedInt dimensions> ObjectRenderer<dimensions>::ObjectRenderer(Scen
Buffer* indexBuffer = new Buffer(Buffer::Target::ElementArray);
Mesh* mesh = new Mesh;

MeshTools::interleave(*mesh, *vertexBuffer, BufferUsage::StaticDraw, Renderer<dimensions>::positions, Renderer<dimensions>::colors);
vertexBuffer->setData(MeshTools::interleave(Renderer<dimensions>::positions, Renderer<dimensions>::colors), BufferUsage::StaticDraw);
ResourceManager::instance().set(this->vertexBuffer.key(), vertexBuffer, ResourceDataState::Final, ResourcePolicy::Manual);

indexBuffer->setData(Renderer<dimensions>::indices, BufferUsage::StaticDraw);
Expand Down
89 changes: 52 additions & 37 deletions src/Magnum/Mesh.h
Expand Up @@ -127,16 +127,15 @@ You have to specify at least primitive and vertex/index count using
data, add them to the mesh and specify
@ref AbstractShaderProgram::Attribute "shader attribute" layout inside the
buffers using @ref addVertexBuffer(). You can also use
@ref MeshTools::interleave() conveniently fill interleaved vertex buffer.
The function itself calls @ref setCount(), so you don't have to, but you still
have to specify the primitive using @ref setPrimitive() and the layout using
@ref addVertexBuffer().
@ref MeshTools::interleave() to conveniently interleave vertex data.
If you want indexed mesh, fill your index buffer with data and specify its
layout using @ref setIndexBuffer(). You can also use @ref MeshTools::compressIndices()
to conveniently compress the indices, fill the index buffer and configure the
mesh. It will call @ref setCount() and @ref setIndexBuffer(), so you don't have
to do anything else.
to conveniently compress the indices based on the range used.
There is also @ref MeshTools::compile() function which operates directly on
@ref Trade::MeshData2D / @ref Trade::MeshData3D and returns fully configured
mesh and vertex/index buffers for use with stock shaders.
Note that neither vertex buffers nor index buffer is managed (e.g. deleted on
destruction) by the mesh, so you have to manage them on your own and ensure
Expand All @@ -159,37 +158,36 @@ class MyShader: public AbstractShaderProgram {
// ...
};
Buffer vertexBuffer;
Mesh mesh;
// Fill vertex buffer with position data
static constexpr Vector3 positions[30] = {
// ...
};
Buffer vertexBuffer;
vertexBuffer.setData(positions, BufferUsage::StaticDraw);
// Set primitive and vertex count, add the buffer and specify its layout
// Configure the mesh, add vertex buffer
Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
.setCount(30)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position());
.addVertexBuffer(vertexBuffer, 0, MyShader::Position{});
@endcode
@subsubsection Mesh-configuration-examples-nonindexed-phong Interleaved vertex data
@code
// Non-indexed primitive with positions and normals
Trade::MeshData3D plane = Primitives::Plane::solid();
Buffer vertexBuffer;
Mesh mesh;
// Fill vertex buffer with interleaved position and normal data
MeshTools::interleave(mesh, buffer, BufferUsage::StaticDraw,
plane.positions(0), plane.normals(0));
Buffer vertexBuffer;
vertexBuffer.setData(MeshTools::interleave(plane.positions(0), plane.normals(0)), BufferUsage::StaticDraw);
// Set primitive and specify layout of interleaved vertex buffer, vertex count
// has been already set by MeshTools::interleave()
// Configure the mesh, add vertex buffer
Mesh mesh;
mesh.setPrimitive(plane.primitive())
.addVertexBuffer(buffer, 0, Shaders::Phong::Position(), Shaders::Phong::Normal());
.setCount(plane.positions(0).size())
.addVertexBuffer(buffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{});
@endcode
@subsubsection Mesh-configuration-examples-indexed-phong Indexed mesh
Expand All @@ -202,48 +200,60 @@ class MyShader: public AbstractShaderProgram {
// ...
};
Buffer vertexBuffer, indexBuffer;
Mesh mesh;
// Fill vertex buffer with position data
static constexpr Vector3 positions[300] = {
// ...
};
Buffer vertexBuffer;
vertexBuffer.setData(positions, BufferUsage::StaticDraw);
// Fill index buffer with index data
static constexpr GLubyte indices[75] = {
// ...
};
Buffer indexBuffer;
indexBuffer.setData(indices, BufferUsage::StaticDraw);
// Set primitive, index count, specify the buffers
// Configure the mesh, add both vertex and index buffer
Mesh mesh;
mesh.setPrimitive(MeshPrimitive::Triangles)
.setCount(75)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position())
.addVertexBuffer(vertexBuffer, 0, MyShader::Position{})
.setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229);
@endcode
Or using @ref MeshTools::interleave() and @ref MeshTools::compressIndices():
@code
// Indexed primitive
Trade::MeshData3D cube = Primitives::Cube::solid();
Buffer vertexBuffer, indexBuffer;
Mesh mesh;
// Fill vertex buffer with interleaved position and normal data
MeshTools::interleave(mesh, vertexBuffer, BufferUsage::StaticDraw,
cube.positions(0), cube.normals(0));
Buffer vertexBuffer;
vertexBuffer.setData(MeshTools::interleave(cube.positions(0), cube.normals(0)), BufferUsage::StaticDraw);
// Fill index buffer with compressed index data
MeshTools::compressIndices(mesh, indexBuffer, BufferUsage::StaticDraw,
cube.indices());
// Compress index data
Containers::Array<char> indexData;
Mesh::IndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(cube.indices());
// Set primitive and specify layout of interleaved vertex buffer. Index count
// and index buffer has been already specified by MeshTools::compressIndices().
// Fill index buffer
Buffer indexBuffer;
indexBuffer.setData(data);
// Configure the mesh, add both vertex and index buffer
Mesh mesh;
mesh.setPrimitive(plane.primitive())
.addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position(), Shaders::Phong::Normal());
.setCount(cube.indices().size())
.addVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position{}, Shaders::Phong::Normal{})
.setIndexBuffer(indexBuffer, 0, indexType, indexStart, indexEnd);
@endcode
Or, if you plan to use the mesh with stock shaders, you can just use
@ref MeshTools::compile().
@subsubsection Mesh-configuration-examples-data-options Specific formats of vertex data
@code
Expand All @@ -255,34 +265,39 @@ class MyShader: public AbstractShaderProgram {
// ...
};
// Initial mesh configuration
Mesh mesh;
mesh.setPrimitive(...)
.setCount(30);
// Fill position buffer with positions specified as two-component XY (i.e.,
// no Z component, which is meant to be always 0)
Buffer positionBuffer;
Vector2 positions[30] = {
// ...
};
Buffer positionBuffer;
positionBuffer.setData(positions, BufferUsage::StaticDraw);
// Specify layout of positions buffer -- only two components, unspecified Z
// component will be automatically set to 0
mesh.addVertexBuffer(positionBuffer, 0,
MyShader::Position(MyShader::Position::Components::Two));
MyShader::Position{MyShader::Position::Components::Two});
// Fill color buffer with colors specified as four-byte BGRA (e.g. directly
// from TGA file)
Buffer colorBuffer;
GLubyte colors[4*30] = {
// ...
};
Buffer colorBuffer;
colorBuffer.setData(colors, BufferUsage::StaticDraw);
// Specify layout of color buffer -- BGRA, each component unsigned byte and we
// want to normalize them from [0, 255] to [0.0f, 1.0f]
mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color(
mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color{
MyShader::Color::Components::BGRA,
MyShader::Color::DataType::UnsignedByte,
MyShader::Color::DataOption::Normalized));
MyShader::Color::DataOption::Normalized});
@endcode
@section Mesh-drawing Rendering meshes
Expand Down
43 changes: 27 additions & 16 deletions src/Magnum/MeshTools/Compile.cpp
Expand Up @@ -25,6 +25,7 @@

#include "Compile.h"

#include "Magnum/Buffer.h"
#include "Magnum/Math/Vector3.h"
#include "Magnum/MeshTools/CompressIndices.h"
#include "Magnum/MeshTools/Interleave.h"
Expand All @@ -51,9 +52,7 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::Target::Array}};

/* Interleave positions */
std::size_t vertexCount;
Containers::Array<char> data;
std::tie(vertexCount, std::ignore, data) = MeshTools::interleave(
Containers::Array<char> data = MeshTools::interleave(
meshData.positions(0),
stride - sizeof(Shaders::Generic2D::Position::Type));
mesh.addVertexBuffer(*vertexBuffer, 0,
Expand All @@ -73,16 +72,23 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
}

/* Fill vertex buffer with interleaved data */
vertexBuffer->setData(data, BufferUsage::StaticDraw);
vertexBuffer->setData(data, usage);

/* Fill index buffer */
/* If indexed, fill index buffer and configure indexed mesh */
std::unique_ptr<Buffer> indexBuffer;
if(meshData.isIndexed()) {
Containers::Array<char> indexData;
Mesh::IndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(meshData.indices());

indexBuffer.reset(new Buffer{Buffer::Target::ElementArray});
MeshTools::compressIndices(mesh, *indexBuffer, usage, meshData.indices());
indexBuffer->setData(data, usage);
mesh.setCount(meshData.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);

/* Else set proper vertex count */
} else mesh.setCount(vertexCount);
/* Else set vertex count */
} else mesh.setCount(meshData.positions(0).size());

return std::make_tuple(std::move(mesh), std::move(vertexBuffer), std::move(indexBuffer));
}
Expand All @@ -106,9 +112,7 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
std::unique_ptr<Buffer> vertexBuffer{new Buffer{Buffer::Target::Array}};

/* Interleave positions */
std::size_t vertexCount;
Containers::Array<char> data;
std::tie(vertexCount, std::ignore, data) = MeshTools::interleave(
Containers::Array<char> data = MeshTools::interleave(
meshData.positions(0),
stride - sizeof(Shaders::Generic3D::Position::Type));
mesh.addVertexBuffer(*vertexBuffer, 0,
Expand Down Expand Up @@ -140,16 +144,23 @@ std::tuple<Mesh, std::unique_ptr<Buffer>, std::unique_ptr<Buffer>> compile(const
}

/* Fill vertex buffer with interleaved data */
vertexBuffer->setData(data, BufferUsage::StaticDraw);
vertexBuffer->setData(data, usage);

/* Fill index buffer */
/* If indexed, fill index buffer and configure indexed mesh */
std::unique_ptr<Buffer> indexBuffer;
if(meshData.isIndexed()) {
Containers::Array<char> indexData;
Mesh::IndexType indexType;
UnsignedInt indexStart, indexEnd;
std::tie(indexData, indexType, indexStart, indexEnd) = MeshTools::compressIndices(meshData.indices());

indexBuffer.reset(new Buffer{Buffer::Target::ElementArray});
MeshTools::compressIndices(mesh, *indexBuffer, usage, meshData.indices());
indexBuffer->setData(data, usage);
mesh.setCount(meshData.indices().size())
.setIndexBuffer(*indexBuffer, 0, indexType, indexStart, indexEnd);

/* Else set proper vertex count */
} mesh.setCount(vertexCount);
/* Else set vertex count */
} mesh.setCount(meshData.positions(0).size());

return std::make_tuple(std::move(mesh), std::move(vertexBuffer), std::move(indexBuffer));
}
Expand Down

0 comments on commit 51a14b9

Please sign in to comment.