Browse Source

Removed unneeded Mesh::add*VertexBuffer*().

It is possible to do everything with Mesh::addInterleavedVertexBuffer().
Moreover Mesh::addVertexBuffer() was dependent on vertex count, which
was counterintuitive and not always what the user wants. Also in many
times I mistakenly used Mesh::addVertexBuffer() instead of
Mesh::addInterleavedVertexBuffer() and then spent endless hours trying
to figure out what is wrong. This is now over. Thanks, brain!
pull/23/head
Vladimír Vondruš 13 years ago
parent
commit
7dd2bed63a
  1. 2
      src/DebugTools/ForceRenderer.cpp
  2. 4
      src/DebugTools/Implementation/AbstractShapeRenderer.cpp
  3. 213
      src/Mesh.h
  4. 2
      src/MeshTools/FullScreenTriangle.cpp
  5. 2
      src/TextureTools/DistanceField.cpp

2
src/DebugTools/ForceRenderer.cpp

@ -88,7 +88,7 @@ template<UnsignedInt dimensions> ForceRenderer<dimensions>::ForceRenderer(SceneG
Mesh* mesh = new Mesh;
mesh->setPrimitive(Mesh::Primitive::Lines)
.setIndexCount(indices.size())
.addVertexBuffer(*vertexBuffer, 0,
.addInterleavedVertexBuffer(*vertexBuffer, 0,
typename Shaders::Flat<dimensions>::Position(Shaders::Flat<dimensions>::Position::Components::Two))
.setIndexBuffer(*indexBuffer, 0, Mesh::IndexType::UnsignedByte, 0, positions.size());
ResourceManager::instance().set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);

4
src/DebugTools/Implementation/AbstractShapeRenderer.cpp

@ -53,7 +53,7 @@ template<> void create<2>(Trade::MeshData2D& data, Resource<Mesh>& meshResource,
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
.setVertexCount(data.positions(0).size())
.addVertexBuffer(*buffer, 0, Shaders::Flat2D::Position());
.addInterleavedVertexBuffer(*buffer, 0, Shaders::Flat2D::Position());
ResourceManager::instance().set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */
@ -75,7 +75,7 @@ template<> void create<3>(Trade::MeshData3D& data, Resource<Mesh>& meshResource,
Mesh* mesh = new Mesh;
mesh->setPrimitive(data.primitive())
.setVertexCount(data.positions(0).size())
.addVertexBuffer(*vertexBuffer, 0, Shaders::Flat3D::Position());
.addInterleavedVertexBuffer(*vertexBuffer, 0, Shaders::Flat3D::Position());
ResourceManager::instance().set(meshResource.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual);
/* Index buffer, if needed, if not, resource key doesn't have to be set */

213
src/Mesh.h

@ -29,7 +29,6 @@
*/
#include <vector>
#include <Utility/Assert.h>
#include <Utility/ConfigurationValue.h>
#include "AbstractShaderProgram.h"
@ -41,20 +40,19 @@ namespace Magnum {
@section Mesh-configuration Mesh configuration
You have to specify at least primitive and vertex count using setPrimitive()
and setVertexCount(). Then fill your vertex buffers with data, add them to the
mesh and specify @ref AbstractShaderProgram::Attribute "shader attribute" layout
inside the buffers using addVertexBuffer(), addInterleavedVertexBuffer() or
addVertexBufferStride(). You can also use MeshTools::interleave() in
combination with addInterleavedVertexBuffer() to conveniently fill interleaved
vertex buffer(s). The function itself calls setVertexCount(), so you don't
have to do it again.
If you have indexed mesh, you need to call setIndexCount() instead of
setVertexCount(). Then fill your index buffer with data and specify its layout
using setIndexBuffer(). You can also use MeshTools::compressIndices() to
conveniently compress the indices, fill the index buffer and configure the
mesh instead of calling setIndexCount() and setIndexBuffer() manually.
You have to specify at least primitive and vertex count using @ref setPrimitive()
and @ref setVertexCount(). Then fill your vertex buffers with data, add them to
the mesh and specify @ref AbstractShaderProgram::Attribute "shader attribute"
layout inside the buffers using @ref addInterleavedVertexBuffer(). You can also
use @ref MeshTools::interleave() conveniently fill interleaved vertex buffer.
The function itself calls @ref setVertexCount(), so you don't have to do it
again, but you still have to specify the layout using @ref addInterleavedVertexBuffer().
If you have indexed mesh, you need to call @ref setIndexCount() instead of
@ref setVertexCount(). Then 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 instead of calling @ref setIndexCount() and @ref setIndexBuffer() manually.
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
@ -64,7 +62,7 @@ different shader) or store data for more meshes in one buffer.
If the mesh has non-zero index count, it is treated as indexed mesh, otherwise
it is treated as non-indexed mesh. If both index and vertex count is zero, the
mesh is empty and no draw commands are issued when calling draw().
mesh is empty and no draw commands are issued when calling @ref draw().
@subsection Mesh-configuration-examples Example mesh configuration
@ -90,7 +88,7 @@ vertexBuffer.setData(positions, Buffer::Usage::StaticDraw);
// Set primitive and vertex count, add the buffer and specify its layout
mesh.setPrimitive(Mesh::Primitive::Triangles)
.setVertexCount(30)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position());
.addInterleavedVertexBuffer(vertexBuffer, 0, MyShader::Position());
@endcode
@subsubsection Mesh-configuration-examples-nonindexed-phong Interleaved vertex data
@ -108,9 +106,7 @@ MeshTools::interleave(mesh, buffer, Buffer::Usage::StaticDraw,
// Set primitive and specify layout of interleaved vertex buffer, vertex count
// has been already set by MeshTools::interleave()
mesh.setPrimitive(plane.primitive())
.addInterleavedVertexBuffer(buffer, 0,
Shaders::PhongShader::Position(),
Shaders::PhongShader::Normal());
.addInterleavedVertexBuffer(buffer, 0, Shaders::Phong::Position(), Shaders::Phong::Normal());
@endcode
@subsubsection Mesh-configuration-examples-indexed-phong Indexed mesh
@ -141,7 +137,7 @@ indexBuffer.setData(indices, Buffer::Usage::StaticDraw);
// Set primitive, index count, specify the buffers
mesh.setPrimitive(Mesh::Primitive::Triangles)
.setIndexCount(75)
.addVertexBuffer(vertexBuffer, 0, MyShader::Position())
.addInterleavedVertexBuffer(vertexBuffer, 0, MyShader::Position())
.setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte, 176, 229);
@endcode
@ -162,9 +158,7 @@ MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw,
// Set primitive and specify layout of interleaved vertex buffer. Index count
// and index buffer has been already specified by MeshTools::compressIndices().
mesh.setPrimitive(plane.primitive())
.addInterleavedVertexBuffer(vertexBuffer, 0,
Shaders::PhongShader::Position(),
Shaders::PhongShader::Normal());
.addInterleavedVertexBuffer(vertexBuffer, 0, Shaders::Phong::Position(), Shaders::Phong::Normal());
@endcode
@subsubsection Mesh-configuration-examples-data-options Specific formats of vertex data
@ -189,7 +183,7 @@ Vector2 positions[30] = {
// Specify layout of positions buffer -- only two components, unspecified Z
// component will be automatically set to 0
mesh.addVertexBuffer(positionBuffer, 0,
mesh.addInterleavedVertexBuffer(positionBuffer, 0,
MyShader::Position(MyShader::Position::Components::Two));
// Fill color buffer with colors specified as four-byte BGRA (e.g. directly
@ -202,7 +196,7 @@ colorBuffer.setData(colors, Buffer::Usage::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.addInterleavedVertexBuffer(colorBuffer, 0, MyShader::Color(
MyShader::Color::Components::BGRA,
MyShader::Color::DataType::UnsignedByte,
MyShader::Color::DataOption::Normalized));
@ -213,7 +207,7 @@ mesh.addVertexBuffer(colorBuffer, 0, MyShader::Color(
Basic workflow is: bind specific framebuffer for drawing (if needed), set up
respective shader, bind required textures (see
@ref AbstractShaderProgram-rendering-workflow "AbstractShaderProgram documentation"
for more infromation) and call Mesh::draw().
for more infromation) and call @ref Mesh::draw().
@section Mesh-performance-optimization Performance optimizations
@ -226,12 +220,11 @@ unnecessary calls to @fn_gl{BindVertexArray}.
If extension @extension{EXT,direct_state_access} and VAOs are available,
DSA functions are used for specifying attribute locations to avoid unnecessary
calls to @fn_gl{BindBuffer} and @fn_gl{BindVertexArray}. See documentation of
addVertexBuffer(), addInterleavedVertexBuffer(), addVertexBufferStride() for
more information.
@ref addInterleavedVertexBuffer() for more information.
If index range is specified in setIndexBuffer(), range-based version of
drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also draw()
for more information.
If index range is specified in @ref setIndexBuffer(), range-based version of
drawing commands are used on desktop OpenGL and OpenGL ES 3.0. See also
@ref draw() for more information.
@todo Support for indirect draw buffer (OpenGL 4.0, @extension{ARB,draw_indirect})
@todo Redo in a way that allows glMultiDrawArrays, glDrawArraysInstanced etc.
@ -385,8 +378,7 @@ class MAGNUM_EXPORT Mesh {
* @return Reference to self (for method chaining)
*
* Default is @ref Primitive::Triangles.
* @see @ref setVertexCount(), @ref addVertexBuffer(),
* @ref addInterleavedVertexBuffer(), @ref addVertexBufferStride()
* @see @ref setVertexCount(), @ref addInterleavedVertexBuffer()
*/
Mesh& setPrimitive(Primitive primitive) {
_primitive = primitive;
@ -401,8 +393,7 @@ class MAGNUM_EXPORT Mesh {
* @return Reference to self (for method chaining)
*
* Default is zero.
* @see setPrimitive(), addVertexBuffer(), addInterleavedVertexBuffer(),
* addVertexBufferStride(), MeshTools::interleave()
* @see setPrimitive(), addInterleavedVertexBuffer(), MeshTools::interleave()
*/
Mesh& setVertexCount(Int vertexCount) {
_vertexCount = vertexCount;
@ -425,130 +416,69 @@ class MAGNUM_EXPORT Mesh {
}
/**
* @brief Add buffer with non-interleaved vertex attributes for use with given shader
* @return Reference to self (for method chaining)
*
* Attribute list is combination of
* @ref AbstractShaderProgram::Attribute "attribute definitions"
* (specified in implementation of given shader) and gaps between
* attribute arrays.
*
* See @ref Mesh-configuration "class documentation" for simple usage
* example. For more involved example imagine that you have buffer
* with 35 bytes of some other data at the beginning (possibly material
* configuration), then position array, then texture coordinate array
* and then normal array. You want to draw it with Shaders::PhongShader,
* but it accepts only position and normal, so you have to skip the
* texture coordinate array:
* @code
* Buffer buffer;
* Mesh mesh;
* mesh.addVertexBuffer(buffer,
* 35, // offset of the data
* Shaders::PhongShader::Position(), // position array
* sizeof(Vector2)*mesh.vertexCount(), // skip texture coordinate array
* Shaders::PhongShader::Normal()); // normal array
* @endcode
*
* Vou can also achieve the same effect by calling this function more
* times with absolute offsets:
* @code
* mesh.addVertexBuffer(buffer, 35, Shaders::PhongShader::Position());
* .addVertexBuffer(buffer, 35 + (sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2))*
* mesh->vertexCount(), Shaders::PhongShader::Normal());
* @endcode
*
* @attention If specifying more than one attribute the actual vertex
* count must be set before calling this function. Otherwise
* vertex data positions in the buffer will be miscalculated.
* @attention The buffer passed as parameter is not managed by the
* mesh, you must ensure it will exist for whole lifetime of the
* mesh and delete it afterwards.
*
* @see addInterleavedVertexBuffer(), addVertexBufferStride(),
* setPrimitive(), setVertexCount(), @fn_gl{BindVertexArray},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer} or
* @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* if @extension{APPLE,vertex_array_object} is available
*/
template<class ...T> Mesh& addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes);
/**
* @brief Add buffer with interleaved vertex attributes for use with given shader
* @brief Add buffer with (interleaved) vertex attributes for use with given shader
* @return Reference to self (for method chaining)
*
* Parameter @p offset is offset of the interleaved array from the
* beginning, attribute list is combination of
* @ref AbstractShaderProgram::Attribute "attribute definitions"
* Parameter @p offset is offset of the array from the beginning,
* attribute list is combination of @ref AbstractShaderProgram::Attribute "attribute definitions"
* (specified in implementation of given shader) and offsets between
* attributes.
* interleaved attributes.
*
* See @ref Mesh-configuration "class documentation" for simple usage
* example. For more involved example imagine that you have buffer
* with 35 bytes of some other data at the beginning (possibly material
* with 76 bytes of some other data at the beginning (possibly material
* configuration) and then the interleaved vertex array. Each vertex
* consists of weight, position, texture coordinate and normal. You
* want to draw it with Shaders::PhongShader, but it accepts only
* want to draw it with @ref Shaders::Phong, but it accepts only
* position and normal, so you have to skip weight and texture
* coordinate in each vertex:
* @code
* Buffer buffer;
* Mesh mesh;
* mesh.addInterleavedVertexBuffer(buffer,
* 35, // skip other data
* sizeof(Float), // skip vertex weight
* Shaders::PhongShader::Position(), // vertex position
* sizeof(Vector2), // skip texture coordinates
* Shaders::PhongShader::Normal()); // vertex normal
* @endcode
Buffer buffer;
Mesh mesh;
mesh.addInterleavedVertexBuffer(buffer, 76, // initial array offset
4, // skip vertex weight (Float)
Shaders::Phong::Position(), // vertex position
8, // skip texture coordinates (Vector2)
Shaders::Phong::Normal()); // vertex normal
@endcode
*
* You can also achieve the same effect by calling addVertexBufferStride()
* more times with absolute offset from the beginning and stride
* between vertex attributes:
* @code
* GLsizei stride = // size of one vertex
* sizeof(Float) +
* sizeof(Shaders::PhongShader::Position::Type) +
* sizeof(Vector2) +
* sizeof(Shaders::PhongShader::Normal::Type);
* You can also achieve the same effect by calling @ref addInterleavedVertexBuffer()
* more times with explicitly specified gaps before and after the
* attributes. This can be used for e.g. runtime-dependent
* configuration, as it isn't dependent on the variadic template:
@code
mesh.addInterleavedVertexBuffer(buffer, 76, 4, Shaders::Phong::Position(), 20)
.addInterleavedVertexBuffer(buffer, 76, 24, Shaders::Phong::Normal(), 0);
@endcode
*
* mesh.addVertexBufferStride(buffer, 35 + sizeof(Float),
* stride, Shaders::PhongShader::Position());
* .addVertexBufferStride(buffer, 35 + sizeof(Float) +
* sizeof(Shaders::PhongShader::Position::Type) + sizeof(Vector2),
* stride, Shaders::PhongShader::Normal());
* @endcode
* If specifying more than one attribute, the function assumes that
* the array is interleaved. Adding non-interleaved vertex buffer can
* be done by specifying one attribute at a time with specific offset.
* Above example with weight, position, texture coordinate and normal
* arrays one after another (non-interleaved):
@code
Int vertexCount = 352;
mesh.addInterleavedVertexBuffer(buffer, 76 + 4*vertexCount, Shaders::Phong::Position())
.addInterleavedVertexBuffer(buffer, 76 + 24*vertexCount, Shaders::Phong::Normal());
@endcode
*
* @attention The buffer passed as parameter is not managed by the
* mesh, you must ensure it will exist for whole lifetime of the
* mesh and delete it afterwards.
*
* @see addVertexBufferStride(), addVertexBuffer(), setPrimitive(),
* setVertexCount(), @fn_gl{BindVertexArray},
* @see setPrimitive(), setVertexCount(), @fn_gl{BindVertexArray},
* @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer},
* @fn_gl{VertexAttribPointer} or
* @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access},
* @fn_gl_extension{VertexArrayVertexAttribOffset,EXT,direct_state_access}
* if @extension{APPLE,vertex_array_object} is available
* @todoc Add back the *s when Doxygen is sane again
*/
template<class ...T> inline Mesh& addInterleavedVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) {
addInterleavedVertexBufferInternal(buffer, offset, strideOfInterleaved(attributes...), attributes...);
return *this;
}
/**
* @brief Add buffer with interleaved vertex attributes for use with given shader
* @return Reference to self (for method chaining)
*
* See addInterleavedVertexBuffer() for more information.
*/
template<UnsignedInt location, class T> inline Mesh& addVertexBufferStride(Buffer& buffer, GLintptr offset, GLsizei stride, const AbstractShaderProgram::Attribute<location, T>& attribute) {
addInterleavedVertexBufferInternal(buffer, offset, stride, attribute);
return *this;
}
/**
* @brief Set index buffer
* @param buffer Index buffer
@ -644,19 +574,6 @@ class MAGNUM_EXPORT Mesh {
static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context& context);
/* Adding non-interleaved vertex attributes */
template<UnsignedInt location, class T, class ...U> inline void addVertexBufferInternal(Buffer& buffer, GLintptr offset, const AbstractShaderProgram::Attribute<location, T>& attribute, const U&... attributes) {
addVertexAttribute(buffer, attribute, offset, 0);
/* Add size of this attribute array to offset for next attribute */
addVertexBufferInternal(buffer, offset+attribute.dataSize()*_vertexCount, attributes...);
}
template<class ...T> inline void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLintptr gap, const T&... attributes) {
/* Add the gap to offset for next attribute */
addVertexBufferInternal(buffer, offset+gap, attributes...);
}
inline void addVertexBufferInternal(Buffer&, GLintptr) {}
/* Computing stride of interleaved vertex attributes */
template<UnsignedInt location, class T, class ...U> inline static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute<location, T>& attribute, const U&... attributes) {
return attribute.dataSize() + strideOfInterleaved(attributes...);
@ -811,14 +728,6 @@ Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::Primitive value);
/** @debugoperator{Magnum::Mesh} */
Debug MAGNUM_EXPORT operator<<(Debug debug, Mesh::IndexType value);
template<class ...T> inline Mesh& Mesh::addVertexBuffer(Buffer& buffer, GLintptr offset, const T&... attributes) {
CORRADE_ASSERT(sizeof...(attributes) == 1 || _vertexCount != 0,
"Mesh::addVertexBuffer(): vertex count must be set before binding attributes", *this);
addVertexBufferInternal(buffer, offset, attributes...);
return *this;
}
}
namespace Corrade { namespace Utility {

2
src/MeshTools/FullScreenTriangle.cpp

@ -53,7 +53,7 @@ std::pair<Buffer*, Mesh> fullScreenTriangle() {
buffer->setData(triangle, Buffer::Usage::StaticDraw);
/** @todo Is it possible to attach moveable buffer here to avoid heap
allocation? OTOH this is more effective in most (modern) cases */
mesh.addVertexBuffer(*buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>());
mesh.addInterleavedVertexBuffer(*buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>());
}
return {std::move(buffer), std::move(mesh)};

2
src/TextureTools/DistanceField.cpp

@ -190,7 +190,7 @@ void distanceField(Texture2D& input, Texture2D& output, const Rectanglei& rectan
Vector2( 3.0, 1.0)
};
buffer.setData(triangle, Buffer::Usage::StaticDraw);
mesh.addVertexBuffer(buffer, 0, DistanceFieldShader::Position());
mesh.addInterleavedVertexBuffer(buffer, 0, DistanceFieldShader::Position());
}
/* Draw the mesh */

Loading…
Cancel
Save