Browse Source

Mesh rework, part 4: don't manage index buffer in IndexedMesh.

The user now has to manage the buffer, similarly to vertex buffers
in Mesh itself.
pull/7/head
Vladimír Vondruš 14 years ago
parent
commit
365c664ef9
  1. 21
      src/IndexedMesh.cpp
  2. 50
      src/IndexedMesh.h
  3. 9
      src/MeshTools/CompressIndices.cpp
  4. 12
      src/MeshTools/CompressIndices.h

21
src/IndexedMesh.cpp

@ -17,18 +17,19 @@
#include <Utility/Debug.h>
#include "Buffer.h"
#include "Context.h"
#include "Extensions.h"
namespace Magnum {
IndexedMesh::CreateIndexedImplementation IndexedMesh::createIndexedImplementation = &IndexedMesh::createIndexedImplementationDefault;
IndexedMesh::BindIndexBufferImplementation IndexedMesh::bindIndexBufferImplementation = &IndexedMesh::bindIndexBufferImplementationDefault;
IndexedMesh::BindIndexedImplementation IndexedMesh::bindIndexedImplementation = &IndexedMesh::bindIndexedImplementationDefault;
IndexedMesh::IndexedMesh(Mesh::Primitive primitive): Mesh(primitive), _indexCount(0), _indexType(Type::UnsignedShort) {
_indexBuffer.setTargetHint(Buffer::Target::ElementArray);
(this->*createIndexedImplementation)();
IndexedMesh* IndexedMesh::setIndexBuffer(Buffer* buffer) {
_indexBuffer = buffer;
(this->*bindIndexBufferImplementation)();
return this;
}
void IndexedMesh::draw() {
@ -52,24 +53,24 @@ void IndexedMesh::initializeContextBasedFunctionality(Context* context) {
#ifndef MAGNUM_TARGET_GLES
Debug() << "IndexedMesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features";
createIndexedImplementation = &IndexedMesh::createIndexedImplementationVAO;
bindIndexBufferImplementation = &IndexedMesh::bindIndexBufferImplementationVAO;
bindIndexedImplementation = &IndexedMesh::bindIndexedImplementationVAO;
#endif
}
}
void IndexedMesh::createIndexedImplementationDefault() {}
void IndexedMesh::bindIndexBufferImplementationDefault() {}
#ifndef MAGNUM_TARGET_GLES
void IndexedMesh::createIndexedImplementationVAO() {
void IndexedMesh::bindIndexBufferImplementationVAO() {
glBindVertexArray(vao);
_indexBuffer.bind(Buffer::Target::ElementArray);
_indexBuffer->bind(Buffer::Target::ElementArray);
}
#endif
void IndexedMesh::bindIndexedImplementationDefault() {
_indexBuffer.bind(Buffer::Target::ElementArray);
_indexBuffer->bind(Buffer::Target::ElementArray);
}
#ifndef MAGNUM_TARGET_GLES

50
src/IndexedMesh.h

@ -20,7 +20,6 @@
*/
#include "Mesh.h"
#include "Buffer.h"
namespace Magnum {
@ -30,9 +29,15 @@ namespace Magnum {
@section IndexedMesh-configuration Indexed mesh configuration
Next to @ref Mesh-configuration "everything needed for non-indexed mesh" you
have to call also setIndexCount() and setIndexType(). Then fill index buffer
or use MeshTools::compressIndices() to conveniently fill the index buffer and
set index count and type.
have to call also setIndexCount() and setIndexType(). Then create index buffer
and assign it to the mesh using setIndexBuffer() or use
MeshTools::compressIndices() to conveniently fill the index buffer and set
index count and type.
Similarly as in Mesh itself the index buffer is not managed by the mesh, so
you have to manage it on your own. On the other hand it allows you to use
one index buffer for more meshes (with different vertex data in each mesh, for
example) or store more than only index data in one buffer.
@section IndexedMesh-drawing Rendering meshes
@ -53,12 +58,21 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
* @brief Constructor
* @param primitive Primitive type
*
* Creates indexed mesh with zero vertex count and zero index count.
* @see setPrimitive(), setVertexCount(), setIndexCount(),
* setIndexType(), @fn_gl{BindVertexArray} (if
* @extension{APPLE,vertex_array_object} is available)
* Creates indexed mesh with no index buffer, zero vertex count and
* zero index count.
* @see setPrimitive(), setVertexCount(), setIndexBuffer(),
* setIndexCount(), setIndexType()
*/
inline IndexedMesh(Primitive primitive = Primitive::Triangles): Mesh(primitive), _indexBuffer(nullptr), _indexCount(0), _indexType(Type::UnsignedShort) {}
/**
* @brief Set index buffer
*
* @see MeshTools::compressIndices(), @fn_gl{BindVertexArray},
* @fn_gl{BindBuffer} (if @extension{APPLE,vertex_array_object}
* is available)
*/
IndexedMesh(Primitive primitive = Primitive::Triangles);
IndexedMesh* setIndexBuffer(Buffer* buffer);
/** @brief Index count */
inline GLsizei indexCount() const { return _indexCount; }
@ -88,14 +102,6 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
return this;
}
/**
* @brief Index buffer
*
* Returns pointer to index buffer, which should be then filled with
* indices (of type specified in constructor).
*/
inline Buffer* indexBuffer() { return &_indexBuffer; }
/**
* @brief Draw the mesh
*
@ -114,12 +120,12 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
void MAGNUM_LOCAL bind();
typedef void(IndexedMesh::*CreateIndexedImplementation)();
void MAGNUM_LOCAL createIndexedImplementationDefault();
typedef void(IndexedMesh::*BindIndexBufferImplementation)();
void MAGNUM_LOCAL bindIndexBufferImplementationDefault();
#ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL createIndexedImplementationVAO();
void MAGNUM_LOCAL bindIndexBufferImplementationVAO();
#endif
static MAGNUM_LOCAL CreateIndexedImplementation createIndexedImplementation;
static MAGNUM_LOCAL BindIndexBufferImplementation bindIndexBufferImplementation;
typedef void(IndexedMesh::*BindIndexedImplementation)();
void MAGNUM_LOCAL bindIndexedImplementationDefault();
@ -128,7 +134,7 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
#endif
static MAGNUM_LOCAL BindIndexedImplementation bindIndexedImplementation;
Buffer _indexBuffer;
Buffer* _indexBuffer;
GLsizei _indexCount;
Type _indexType;
};

9
src/MeshTools/CompressIndices.cpp

@ -33,15 +33,16 @@ std::tuple<size_t, Type, char* > CompressIndices::operator()() const {
return SizeBasedCall<Compressor>(*std::max_element(indices.begin(), indices.end()))(indices);
}
void CompressIndices::operator()(IndexedMesh* mesh, Buffer::Usage usage) const {
void CompressIndices::operator()(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage) const {
size_t indexCount;
Type indexType;
char* data;
std::tie(indexCount, indexType, data) = operator()();
mesh->setIndexType(indexType);
mesh->setIndexCount(indices.size());
mesh->indexBuffer()->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage);
mesh->setIndexBuffer(buffer)
->setIndexType(indexType)
->setIndexCount(indices.size());
buffer->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage);
delete[] data;
}

12
src/MeshTools/CompressIndices.h

@ -41,7 +41,7 @@ class MESHTOOLS_EXPORT CompressIndices {
std::tuple<std::size_t, Type, char*> operator()() const;
void operator()(IndexedMesh* mesh, Buffer::Usage usage) const;
void operator()(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage) const;
private:
struct Compressor {
@ -85,18 +85,20 @@ inline std::tuple<std::size_t, Type, char*> compressIndices(const std::vector<st
/**
@brief Compress vertex indices and write them to index buffer
@param mesh Output mesh
@param buffer Index buffer
@param usage Index buffer usage
@param indices Index array
The same as compressIndices(const std::vector<std::uint32_t>&), but this
function writes the output to mesh's index buffer and updates index count and
function writes the output to given index buffer and updates index count and
type in the mesh accordingly, so you don't have to call
IndexedMesh::setIndexCount() and IndexedMesh::setIndexType() on your own.
IndexedMesh::setIndexBuffer(), IndexedMesh::setIndexCount() and
IndexedMesh::setIndexType() on your own.
@see MeshTools::interleave()
*/
inline void compressIndices(IndexedMesh* mesh, Buffer::Usage usage, const std::vector<std::uint32_t>& indices) {
return Implementation::CompressIndices{indices}(mesh, usage);
inline void compressIndices(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage, const std::vector<std::uint32_t>& indices) {
return Implementation::CompressIndices{indices}(mesh, buffer, usage);
}
}}

Loading…
Cancel
Save