diff --git a/src/DebugTools/ObjectRenderer.cpp b/src/DebugTools/ObjectRenderer.cpp index 5285f15e4..f0a98e9a4 100644 --- a/src/DebugTools/ObjectRenderer.cpp +++ b/src/DebugTools/ObjectRenderer.cpp @@ -158,11 +158,10 @@ template ObjectRenderer::ObjectRenderer(Sce mesh->setPrimitive(Mesh::Primitive::Lines) ->setIndexCount(Renderer::indices.size()) - ->setIndexType(Mesh::IndexType::UnsignedByte) ->addInterleavedVertexBuffer(vertexBuffer, 0, typename Shaders::VertexColorShader::Position(), typename Shaders::VertexColorShader::Color()) - ->setIndexBuffer(indexBuffer); + ->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte); ResourceManager::instance()->set(this->mesh.key(), mesh, ResourceDataState::Final, ResourcePolicy::Manual); } diff --git a/src/Mesh.cpp b/src/Mesh.cpp index e23f5418b..4cc89e5f2 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -49,7 +49,7 @@ std::size_t Mesh::indexSize(IndexType type) { CORRADE_INTERNAL_ASSERT(false); } -Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexBuffer(nullptr), _indexCount(0), _indexType(IndexType::UnsignedInt) { +Mesh::Mesh(Primitive primitive): _primitive(primitive), _vertexCount(0), _indexCount(0), indexOffset(0), indexType(IndexType::UnsignedInt), indexBuffer(nullptr) { (this->*createImplementation)(); } @@ -61,7 +61,7 @@ Mesh::~Mesh() { (this->*destroyImplementation)(); } -Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), _indexBuffer(other._indexBuffer), _indexCount(other._indexCount), _indexType(other._indexType), attributes(std::move(other.attributes)) +Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), _indexCount(other._indexCount), indexOffset(other.indexOffset), indexType(other.indexType), indexBuffer(other.indexBuffer), attributes(std::move(other.attributes)) #ifndef MAGNUM_TARGET_GLES2 , integerAttributes(std::move(other.integerAttributes)) #ifndef MAGNUM_TARGET_GLES @@ -78,9 +78,10 @@ Mesh& Mesh::operator=(Mesh&& other) { vao = other.vao; _primitive = other._primitive; _vertexCount = other._vertexCount; - _indexBuffer = other._indexBuffer; _indexCount = other._indexCount; - _indexType = other._indexType; + indexOffset = other.indexOffset; + indexType = other.indexType; + indexBuffer = other.indexBuffer; attributes = std::move(other.attributes); #ifndef MAGNUM_TARGET_GLES2 integerAttributes = std::move(other.integerAttributes); @@ -94,6 +95,13 @@ Mesh& Mesh::operator=(Mesh&& other) { return *this; } +Mesh* Mesh::setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type) { + indexOffset = offset; + indexType = type; + (this->*bindIndexBufferImplementation)(buffer); + return this; +} + void Mesh::draw() { /* Nothing to draw */ if(!_vertexCount && !_indexCount) return; @@ -104,7 +112,7 @@ void Mesh::draw() { if(!_indexCount) glDrawArrays(static_cast(_primitive), 0, _vertexCount); /* Indexed mesh */ - else glDrawElements(static_cast(_primitive), _indexCount, static_cast(_indexType), nullptr); + else glDrawElements(static_cast(_primitive), _indexCount, static_cast(indexType), reinterpret_cast(indexOffset)); (this->*unbindImplementation)(); } @@ -240,7 +248,7 @@ void Mesh::attributePointerImplementationDSA(const LongAttribute& attribute) { #endif void Mesh::bindIndexBufferImplementationDefault(Buffer* buffer) { - _indexBuffer = buffer; + indexBuffer = buffer; } void Mesh::bindIndexBufferImplementationVAO(Buffer* buffer) { diff --git a/src/Mesh.h b/src/Mesh.h index ca5f37bd2..f98b13c79 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -42,12 +42,10 @@ 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() and additionaly specify also index type using setIndexType(). -Then fill your index buffer with data and add it to the mesh using -setIndexBuffer(). You can also use MeshTools::compressIndices() to +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(), setIndexType() and setIndexBuffer() -manually. +mesh instead of calling setIndexCount() and 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. On the other @@ -130,12 +128,11 @@ static constexpr GLubyte indices[75] = { }; indexBuffer->setData(indices, Buffer::Usage::StaticDraw); -// Set primitive, index count and type, add the buffers +// Set primitive, index count, add the buffers mesh->setPrimitive(Mesh::Primitive::Triangles) ->setIndexCount(75) - ->setIndexType(Mesh::IndexType::UnsignedByte) ->addVertexBuffer(vertexBuffer, 0, MyShader::Position()) - ->setIndexBuffer(indexBuffer); + ->setIndexBuffer(indexBuffer, 0, Mesh::IndexType::UnsignedByte); @endcode @code @@ -152,8 +149,8 @@ MeshTools::interleave(mesh, vertexBuffer, Buffer::Usage::StaticDraw, MeshTools::compressIndices(mesh, indexBuffer, Buffer::Usage::StaticDraw, *cube.indices()); -// Set primitive and specify layout of interleaved vertex buffer. Index count, -// type and index buffer has been already set by MeshTools::compressIndices(). +// 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(), @@ -452,7 +449,7 @@ class MAGNUM_EXPORT Mesh { /** * @brief Index type * - * @see setIndexType(), indexSize() + * @see setIndexBuffer(), indexSize() */ enum class IndexType: GLenum { UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ @@ -532,28 +529,13 @@ class MAGNUM_EXPORT Mesh { * @return Pointer to self (for method chaining) * * Default is zero. - * @see setIndexBuffer(), setIndexType(), MeshTools::compressIndices() + * @see setIndexBuffer(), MeshTools::compressIndices() */ inline Mesh* setIndexCount(GLsizei count) { _indexCount = count; return this; } - /** @brief Index type */ - inline IndexType indexType() const { return _indexType; } - - /** - * @brief Set index type - * @return Pointer to self (for method chaining) - * - * Default is @ref IndexType "IndexType::UnsignedInt". - * @see setIndexBuffer(), setIndexCount(), MeshTools::compressIndices() - */ - inline Mesh* setIndexType(IndexType type) { - _indexType = type; - return this; - } - /** * @brief Add buffer with non-interleaved vertex attributes for use with given shader * @return Pointer to self (for method chaining) @@ -686,16 +668,16 @@ class MAGNUM_EXPORT Mesh { /** * @brief Set index buffer + * @param buffer Index buffer + * @param offset Offset into the buffer + * @param type Index data type * @return Pointer to self (for method chaining) * - * @see setIndexCount(), setIndexType(), MeshTools::compressIndices(), + * @see setIndexCount(), MeshTools::compressIndices(), * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if * @extension{APPLE,vertex_array_object} is available) */ - inline Mesh* setIndexBuffer(Buffer* buffer) { - (this->*bindIndexBufferImplementation)(buffer); - return this; - } + Mesh* setIndexBuffer(Buffer* buffer, GLintptr offset, IndexType type); /** * @brief Draw the mesh @@ -871,7 +853,7 @@ class MAGNUM_EXPORT Mesh { typedef void(Mesh::*BindIndexBufferImplementation)(Buffer*); void MAGNUM_LOCAL bindIndexBufferImplementationDefault(Buffer* buffer); void MAGNUM_LOCAL bindIndexBufferImplementationVAO(Buffer* buffer); - static BindIndexBufferImplementation bindIndexBufferImplementation; + static MAGNUM_LOCAL BindIndexBufferImplementation bindIndexBufferImplementation; typedef void(Mesh::*BindImplementation)(); void MAGNUM_LOCAL bindImplementationDefault(); @@ -885,10 +867,10 @@ class MAGNUM_EXPORT Mesh { GLuint vao; Primitive _primitive; - GLsizei _vertexCount; - Buffer* _indexBuffer; - GLsizei _indexCount; - IndexType _indexType; + GLsizei _vertexCount, _indexCount; + GLintptr indexOffset; + IndexType indexType; + Buffer* indexBuffer; std::vector attributes; #ifndef MAGNUM_TARGET_GLES2 diff --git a/src/MeshTools/CompressIndices.cpp b/src/MeshTools/CompressIndices.cpp index 7d3890517..60ce595be 100644 --- a/src/MeshTools/CompressIndices.cpp +++ b/src/MeshTools/CompressIndices.cpp @@ -66,9 +66,8 @@ void compressIndices(Mesh* mesh, Buffer* buffer, Buffer::Usage usage, const std: char* data; std::tie(indexCount, indexType, data) = compressIndices(indices); - mesh->setIndexBuffer(buffer) - ->setIndexType(indexType) - ->setIndexCount(indices.size()); + mesh->setIndexCount(indices.size()) + ->setIndexBuffer(buffer, 0, indexType); buffer->setData(indexCount*Mesh::indexSize(indexType), data, usage); delete[] data; diff --git a/src/MeshTools/CompressIndices.h b/src/MeshTools/CompressIndices.h index c68b991e6..a0ee59b1e 100644 --- a/src/MeshTools/CompressIndices.h +++ b/src/MeshTools/CompressIndices.h @@ -62,9 +62,9 @@ std::tuple MAGNUM_MESHTOOLS_EXPORT compress @param indices Index array The same as compressIndices(const std::vector&), but this -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 Mesh::setIndexBuffer(), -Mesh::setIndexCount() and Mesh::setIndexType() on your own. +function writes the output to given buffer, updates index count and specifies +index buffer in the mesh, so you don't have to call Mesh::setIndexCount() +and Mesh::setIndexBuffer() on your own. @see MeshTools::interleave() */