From 365c664ef9076b026436de29ea3edf724ea725fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 22 Oct 2012 00:38:24 +0200 Subject: [PATCH] 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. --- src/IndexedMesh.cpp | 21 ++++++------- src/IndexedMesh.h | 50 +++++++++++++++++-------------- src/MeshTools/CompressIndices.cpp | 9 +++--- src/MeshTools/CompressIndices.h | 12 ++++---- 4 files changed, 51 insertions(+), 41 deletions(-) diff --git a/src/IndexedMesh.cpp b/src/IndexedMesh.cpp index 3bc9c8008..5b8b3433d 100644 --- a/src/IndexedMesh.cpp +++ b/src/IndexedMesh.cpp @@ -17,18 +17,19 @@ #include +#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 diff --git a/src/IndexedMesh.h b/src/IndexedMesh.h index ccb0ae104..1ee7d5d9e 100644 --- a/src/IndexedMesh.h +++ b/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; }; diff --git a/src/MeshTools/CompressIndices.cpp b/src/MeshTools/CompressIndices.cpp index fc028355b..e3e53b674 100644 --- a/src/MeshTools/CompressIndices.cpp +++ b/src/MeshTools/CompressIndices.cpp @@ -33,15 +33,16 @@ std::tuple CompressIndices::operator()() const { return SizeBasedCall(*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; } diff --git a/src/MeshTools/CompressIndices.h b/src/MeshTools/CompressIndices.h index ec6c88fb5..1ca638eba 100644 --- a/src/MeshTools/CompressIndices.h +++ b/src/MeshTools/CompressIndices.h @@ -41,7 +41,7 @@ class MESHTOOLS_EXPORT CompressIndices { std::tuple 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 compressIndices(const std::vector&), 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& indices) { - return Implementation::CompressIndices{indices}(mesh, usage); +inline void compressIndices(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage, const std::vector& indices) { + return Implementation::CompressIndices{indices}(mesh, buffer, usage); } }}