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

50
src/IndexedMesh.h

@ -20,7 +20,6 @@
*/ */
#include "Mesh.h" #include "Mesh.h"
#include "Buffer.h"
namespace Magnum { namespace Magnum {
@ -30,9 +29,15 @@ namespace Magnum {
@section IndexedMesh-configuration Indexed mesh configuration @section IndexedMesh-configuration Indexed mesh configuration
Next to @ref Mesh-configuration "everything needed for non-indexed mesh" you Next to @ref Mesh-configuration "everything needed for non-indexed mesh" you
have to call also setIndexCount() and setIndexType(). Then fill index buffer have to call also setIndexCount() and setIndexType(). Then create index buffer
or use MeshTools::compressIndices() to conveniently fill the index buffer and and assign it to the mesh using setIndexBuffer() or use
set index count and type. 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 @section IndexedMesh-drawing Rendering meshes
@ -53,12 +58,21 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
* @brief Constructor * @brief Constructor
* @param primitive Primitive type * @param primitive Primitive type
* *
* Creates indexed mesh with zero vertex count and zero index count. * Creates indexed mesh with no index buffer, zero vertex count and
* @see setPrimitive(), setVertexCount(), setIndexCount(), * zero index count.
* setIndexType(), @fn_gl{BindVertexArray} (if * @see setPrimitive(), setVertexCount(), setIndexBuffer(),
* @extension{APPLE,vertex_array_object} is available) * 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 */ /** @brief Index count */
inline GLsizei indexCount() const { return _indexCount; } inline GLsizei indexCount() const { return _indexCount; }
@ -88,14 +102,6 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
return this; 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 * @brief Draw the mesh
* *
@ -114,12 +120,12 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
void MAGNUM_LOCAL bind(); void MAGNUM_LOCAL bind();
typedef void(IndexedMesh::*CreateIndexedImplementation)(); typedef void(IndexedMesh::*BindIndexBufferImplementation)();
void MAGNUM_LOCAL createIndexedImplementationDefault(); void MAGNUM_LOCAL bindIndexBufferImplementationDefault();
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL createIndexedImplementationVAO(); void MAGNUM_LOCAL bindIndexBufferImplementationVAO();
#endif #endif
static MAGNUM_LOCAL CreateIndexedImplementation createIndexedImplementation; static MAGNUM_LOCAL BindIndexBufferImplementation bindIndexBufferImplementation;
typedef void(IndexedMesh::*BindIndexedImplementation)(); typedef void(IndexedMesh::*BindIndexedImplementation)();
void MAGNUM_LOCAL bindIndexedImplementationDefault(); void MAGNUM_LOCAL bindIndexedImplementationDefault();
@ -128,7 +134,7 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh {
#endif #endif
static MAGNUM_LOCAL BindIndexedImplementation bindIndexedImplementation; static MAGNUM_LOCAL BindIndexedImplementation bindIndexedImplementation;
Buffer _indexBuffer; Buffer* _indexBuffer;
GLsizei _indexCount; GLsizei _indexCount;
Type _indexType; 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); 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; size_t indexCount;
Type indexType; Type indexType;
char* data; char* data;
std::tie(indexCount, indexType, data) = operator()(); std::tie(indexCount, indexType, data) = operator()();
mesh->setIndexType(indexType); mesh->setIndexBuffer(buffer)
mesh->setIndexCount(indices.size()); ->setIndexType(indexType)
mesh->indexBuffer()->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage); ->setIndexCount(indices.size());
buffer->setData(indexCount*TypeInfo::sizeOf(indexType), data, usage);
delete[] data; delete[] data;
} }

12
src/MeshTools/CompressIndices.h

@ -41,7 +41,7 @@ class MESHTOOLS_EXPORT CompressIndices {
std::tuple<std::size_t, Type, char*> operator()() const; 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: private:
struct Compressor { 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 @brief Compress vertex indices and write them to index buffer
@param mesh Output mesh @param mesh Output mesh
@param buffer Index buffer
@param usage Index buffer usage @param usage Index buffer usage
@param indices Index array @param indices Index array
The same as compressIndices(const std::vector<std::uint32_t>&), but this 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 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() @see MeshTools::interleave()
*/ */
inline void compressIndices(IndexedMesh* mesh, Buffer::Usage usage, const std::vector<std::uint32_t>& indices) { inline void compressIndices(IndexedMesh* mesh, Buffer* buffer, Buffer::Usage usage, const std::vector<std::uint32_t>& indices) {
return Implementation::CompressIndices{indices}(mesh, usage); return Implementation::CompressIndices{indices}(mesh, buffer, usage);
} }
}} }}

Loading…
Cancel
Save