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

5
src/Magnum/GL/Mesh.h

@ -35,6 +35,7 @@
#include "Magnum/Tags.h" #include "Magnum/Tags.h"
#include "Magnum/GL/AbstractObject.h" #include "Magnum/GL/AbstractObject.h"
#include "Magnum/GL/Attribute.h" #include "Magnum/GL/Attribute.h"
#include "Magnum/GL/Buffer.h"
#include "Magnum/GL/GL.h" #include "Magnum/GL/GL.h"
namespace Magnum { namespace GL { namespace Magnum { namespace GL {
@ -489,7 +490,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
* *
* @see @ref setIndexBuffer(), @ref setCount() * @see @ref setIndexBuffer(), @ref setCount()
*/ */
bool isIndexed() const { return _indexBuffer; } bool isIndexed() const { return _indexBuffer.id(); }
/** /**
* @brief Index type * @brief Index type
@ -1052,7 +1053,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
#endif #endif
GLintptr _indexOffset{}; GLintptr _indexOffset{};
MeshIndexType _indexType{}; MeshIndexType _indexType{};
Buffer* _indexBuffer{}; Buffer _indexBuffer{NoCreate};
/* Storage for std::vector with attribute layout / attribute buffer /* Storage for std::vector with attribute layout / attribute buffer
instances. 4 pointers should be one pointer more than enough. */ 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 #ifndef MAGNUM_TARGET_GLES
hasBaseVertex = true; hasBaseVertex = true;
#else #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 #endif
} }
@ -92,7 +92,7 @@ void MeshView::multiDrawImplementationDefault(std::initializer_list<std::referen
(original.*state.bindImplementation)(); (original.*state.bindImplementation)();
/* Non-indexed meshes */ /* Non-indexed meshes */
if(!original._indexBuffer) { if(!original._indexBuffer.id()) {
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
glMultiDrawArrays(GLenum(original._primitive), baseVertex, count, meshes.size()); glMultiDrawArrays(GLenum(original._primitive), baseVertex, count, meshes.size());
#else #else
@ -140,7 +140,7 @@ void MeshView::multiDrawImplementationFallback(std::initializer_list<std::refere
#endif #endif
MeshView& MeshView::setIndexRange(Int first) { 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(); _indexOffset = _original.get()._indexOffset + first*_original.get().indexTypeSize();
return *this; return *this;
} }

Loading…
Cancel
Save