Browse Source

GL: store Mesh index buffer by value.

This allows moving Buffer instances without fear of breaking stuff. I
thought this was in since a long time, but doesn't seem so. This
reintroduces a header dependency, but until I have Containers::Storage
or something that *can* store forward-declared type safely, it's
inevitable.
pull/255/head
Vladimír Vondruš 8 years ago
parent
commit
7a0f1ef32d
  1. 14
      src/Magnum/GL/Mesh.cpp
  2. 5
      src/Magnum/GL/Mesh.h
  3. 6
      src/Magnum/GL/MeshView.cpp

14
src/Magnum/GL/Mesh.cpp

@ -228,7 +228,7 @@ Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _primitive(other._primitive),
#ifndef MAGNUM_TARGET_GLES2
_indexStart(other._indexStart), _indexEnd(other._indexEnd),
#endif
_indexOffset(other._indexOffset), _indexType(other._indexType), _indexBuffer(other._indexBuffer)
_indexOffset(other._indexOffset), _indexType(other._indexType), _indexBuffer{std::move(other._indexBuffer)}
{
(this->*Context::current().state().mesh->moveConstructImplementation)(std::move(other));
other._id = 0;
@ -294,12 +294,12 @@ Mesh& Mesh::setLabelInternal(const Containers::ArrayView<const char> label) {
#endif
MeshIndexType Mesh::indexType() const {
CORRADE_ASSERT(_indexBuffer, "Mesh::indexType(): mesh is not indexed", {});
CORRADE_ASSERT(_indexBuffer.id(), "Mesh::indexType(): mesh is not indexed", {});
return _indexType;
}
UnsignedInt Mesh::indexTypeSize() const {
CORRADE_ASSERT(_indexBuffer, "Mesh::indexTypeSize(): mesh is not indexed", {});
CORRADE_ASSERT(_indexBuffer.id(), "Mesh::indexTypeSize(): mesh is not indexed", {});
switch(_indexType) {
case MeshIndexType::UnsignedByte: return 1;
@ -331,7 +331,7 @@ Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, MeshIndexType type,
"GL::Mesh::setIndexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::ElementArray << "but got" << buffer.targetHint(), *this);
#endif
_indexBuffer = &buffer;
_indexBuffer = Buffer::wrap(buffer.id());
_indexOffset = offset;
_indexType = type;
#ifndef MAGNUM_TARGET_GLES2
@ -377,7 +377,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
/* Non-instanced mesh */
if(instanceCount == 1) {
/* Non-indexed mesh */
if(!_indexBuffer) {
if(!_indexBuffer.id()) {
glDrawArrays(GLenum(_primitive), baseVertex, count);
/* Indexed mesh with base vertex */
@ -415,7 +415,7 @@ void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, GLintptr i
/* Instanced mesh */
} else {
/* Non-indexed mesh */
if(!_indexBuffer) {
if(!_indexBuffer.id()) {
#ifndef MAGNUM_TARGET_GLES
/* Non-indexed mesh with base instance */
if(baseInstance) {
@ -698,7 +698,7 @@ void Mesh::bindImplementationDefault() {
vertexAttribPointer(attribute);
/* Bind index buffer, if the mesh is indexed */
if(_indexBuffer) _indexBuffer->bindInternal(Buffer::TargetHint::ElementArray);
if(_indexBuffer.id()) _indexBuffer.bindInternal(Buffer::TargetHint::ElementArray);
}
void Mesh::bindImplementationVAO() {

5
src/Magnum/GL/Mesh.h

@ -35,6 +35,7 @@
#include "Magnum/Tags.h"
#include "Magnum/GL/AbstractObject.h"
#include "Magnum/GL/Attribute.h"
#include "Magnum/GL/Buffer.h"
#include "Magnum/GL/GL.h"
namespace Magnum { namespace GL {
@ -489,7 +490,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
*
* @see @ref setIndexBuffer(), @ref setCount()
*/
bool isIndexed() const { return _indexBuffer; }
bool isIndexed() const { return _indexBuffer.id(); }
/**
* @brief Index type
@ -1052,7 +1053,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
#endif
GLintptr _indexOffset{};
MeshIndexType _indexType{};
Buffer* _indexBuffer{};
Buffer _indexBuffer{NoCreate};
/* Storage for std::vector with attribute layout / attribute buffer
instances. 4 pointers should be one pointer more than enough. */

6
src/Magnum/GL/MeshView.cpp

@ -82,7 +82,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
#ifndef MAGNUM_TARGET_GLES
hasBaseVertex = true;
#else
CORRADE_ASSERT(!original._indexBuffer, "GL::MeshView::draw(): desktop OpenGL is required for base vertex specification in indexed meshes", );
CORRADE_ASSERT(!original._indexBuffer.id(), "GL::MeshView::draw(): desktop OpenGL is required for base vertex specification in indexed meshes", );
#endif
}
@ -92,7 +92,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
(original.*state.bindImplementation)();
/* Non-indexed meshes */
if(!original._indexBuffer) {
if(!original._indexBuffer.id()) {
#ifndef MAGNUM_TARGET_GLES
glMultiDrawArrays(GLenum(original._primitive), baseVertex, count, meshes.size());
#else
@ -140,7 +140,7 @@ void MeshView::multiDrawImplementationFallback(std::initializer_list<std::refere
#endif
MeshView& MeshView::setIndexRange(Int first) {
CORRADE_ASSERT(_original.get()._indexBuffer, "MeshView::setIndexRange(): mesh is not indexed", *this);
CORRADE_ASSERT(_original.get()._indexBuffer.id(), "MeshView::setIndexRange(): mesh is not indexed", *this);
_indexOffset = _original.get()._indexOffset + first*_original.get().indexTypeSize();
return *this;
}

Loading…
Cancel
Save