Browse Source

GL: get rid of std::vector in Mesh header.

This is actually a preparation to make buffer-owning meshes a
possibility (where I would need an union of vectors otherwise),
nevertheless it removes the dependency on a vector.
pull/255/head
Vladimír Vondruš 8 years ago
parent
commit
680144f1c5
  1. 4
      src/Magnum/GL/Implementation/MeshState.cpp
  2. 2
      src/Magnum/GL/Implementation/MeshState.h
  3. 33
      src/Magnum/GL/Mesh.cpp
  4. 10
      src/Magnum/GL/Mesh.h
  5. 42
      src/Magnum/GL/Test/MeshGLTest.cpp

4
src/Magnum/GL/Implementation/MeshState.cpp

@ -54,6 +54,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#endif #endif
createImplementation = &Mesh::createImplementationVAO; createImplementation = &Mesh::createImplementationVAO;
moveConstructImplementation = &Mesh::moveConstructImplementationVAO;
moveAssignImplementation = &Mesh::moveAssignImplementationVAO;
destroyImplementation = &Mesh::destroyImplementationVAO; destroyImplementation = &Mesh::destroyImplementationVAO;
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
@ -75,6 +77,8 @@ MeshState::MeshState(Context& context, ContextState& contextState, std::vector<s
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
else { else {
createImplementation = &Mesh::createImplementationDefault; createImplementation = &Mesh::createImplementationDefault;
moveConstructImplementation = &Mesh::moveConstructImplementationDefault;
moveAssignImplementation = &Mesh::moveAssignImplementationDefault;
destroyImplementation = &Mesh::destroyImplementationDefault; destroyImplementation = &Mesh::destroyImplementationDefault;
attributePointerImplementation = &Mesh::attributePointerImplementationDefault; attributePointerImplementation = &Mesh::attributePointerImplementationDefault;
bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationDefault; bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationDefault;

2
src/Magnum/GL/Implementation/MeshState.h

@ -41,6 +41,8 @@ struct MeshState {
void reset(); void reset();
void(Mesh::*createImplementation)(); void(Mesh::*createImplementation)();
void(Mesh::*moveConstructImplementation)(Mesh&&);
void(Mesh::*moveAssignImplementation)(Mesh&&);
void(Mesh::*destroyImplementation)(); void(Mesh::*destroyImplementation)();
void(Mesh::*attributePointerImplementation)(Mesh::AttributeLayout&); void(Mesh::*attributePointerImplementation)(Mesh::AttributeLayout&);
#if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)

33
src/Magnum/GL/Mesh.cpp

@ -25,6 +25,7 @@
#include "Mesh.h" #include "Mesh.h"
#include <vector>
#include <Corrade/Utility/Debug.h> #include <Corrade/Utility/Debug.h>
#include "Magnum/Mesh.h" #include "Magnum/Mesh.h"
@ -242,8 +243,9 @@ 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), _attributes(std::move(other._attributes)) _indexOffset(other._indexOffset), _indexType(other._indexType), _indexBuffer(other._indexBuffer)
{ {
(this->*Context::current().state().mesh->moveConstructImplementation)(std::move(other));
other._id = 0; other._id = 0;
} }
@ -265,7 +267,7 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept {
swap(_indexOffset, other._indexOffset); swap(_indexOffset, other._indexOffset);
swap(_indexType, other._indexType); swap(_indexType, other._indexType);
swap(_indexBuffer, other._indexBuffer); swap(_indexBuffer, other._indexBuffer);
swap(_attributes, other._attributes); (this->*Context::current().state().mesh->moveAssignImplementation)(std::move(other));
return *this; return *this;
} }
@ -540,6 +542,10 @@ void Mesh::bindVAO() {
void Mesh::createImplementationDefault() { void Mesh::createImplementationDefault() {
_id = 0; _id = 0;
_flags |= ObjectFlag::Created; _flags |= ObjectFlag::Created;
static_assert(sizeof(_attributes) >= sizeof(std::vector<AttributeLayout>),
"attribute storage buffer size too small");
new(&_attributes) std::vector<AttributeLayout>;
} }
void Mesh::createImplementationVAO() { void Mesh::createImplementationVAO() {
@ -558,7 +564,22 @@ void Mesh::createImplementationVAODSA() {
} }
#endif #endif
void Mesh::destroyImplementationDefault() {} void Mesh::moveConstructImplementationDefault(Mesh&& other) {
new(&_attributes) std::vector<AttributeLayout>{std::move(*reinterpret_cast<std::vector<AttributeLayout>*>(&other._attributes))};
}
void Mesh::moveConstructImplementationVAO(Mesh&&) {}
void Mesh::moveAssignImplementationDefault(Mesh&& other) {
std::swap(*reinterpret_cast<std::vector<AttributeLayout>*>(&_attributes),
*reinterpret_cast<std::vector<AttributeLayout>*>(&other._attributes));
}
void Mesh::moveAssignImplementationVAO(Mesh&&) {}
void Mesh::destroyImplementationDefault() {
reinterpret_cast<std::vector<AttributeLayout>*>(&_attributes)->~vector();
}
void Mesh::destroyImplementationVAO() { void Mesh::destroyImplementationVAO() {
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
@ -583,7 +604,7 @@ void Mesh::attributePointerImplementationDefault(AttributeLayout& attribute) {
"GL::Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer.targetHint(), ); "GL::Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer.targetHint(), );
#endif #endif
_attributes.push_back(attribute); reinterpret_cast<std::vector<AttributeLayout>*>(&_attributes)->push_back(attribute);
} }
void Mesh::attributePointerImplementationVAO(AttributeLayout& attribute) { void Mesh::attributePointerImplementationVAO(AttributeLayout& attribute) {
@ -681,7 +702,7 @@ void Mesh::bindIndexBufferImplementationVAO(Buffer& buffer) {
void Mesh::bindImplementationDefault() { void Mesh::bindImplementationDefault() {
/* Specify vertex attributes */ /* Specify vertex attributes */
for(AttributeLayout& attribute: _attributes) for(AttributeLayout& attribute: *reinterpret_cast<std::vector<AttributeLayout>*>(&_attributes))
vertexAttribPointer(attribute); vertexAttribPointer(attribute);
/* Bind index buffer, if the mesh is indexed */ /* Bind index buffer, if the mesh is indexed */
@ -693,7 +714,7 @@ void Mesh::bindImplementationVAO() {
} }
void Mesh::unbindImplementationDefault() { void Mesh::unbindImplementationDefault() {
for(const AttributeLayout& attribute: _attributes) for(const AttributeLayout& attribute: *reinterpret_cast<std::vector<AttributeLayout>*>(&_attributes))
glDisableVertexAttribArray(attribute.location); glDisableVertexAttribArray(attribute.location);
} }

10
src/Magnum/GL/Mesh.h

@ -29,7 +29,6 @@
* @brief Class @ref Magnum::GL::Mesh, enum @ref Magnum::GL::MeshPrimitive, @ref Magnum::GL::MeshIndexType, function @ref Magnum::GL::meshPrimitive(), @ref Magnum::GL::meshIndexType() * @brief Class @ref Magnum::GL::Mesh, enum @ref Magnum::GL::MeshPrimitive, @ref Magnum::GL::MeshIndexType, function @ref Magnum::GL::meshPrimitive(), @ref Magnum::GL::meshIndexType()
*/ */
#include <vector>
#include <Corrade/Containers/ArrayView.h> #include <Corrade/Containers/ArrayView.h>
#include <Corrade/Utility/ConfigurationValue.h> #include <Corrade/Utility/ConfigurationValue.h>
@ -981,6 +980,11 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
void MAGNUM_GL_LOCAL createImplementationVAODSA(); void MAGNUM_GL_LOCAL createImplementationVAODSA();
#endif #endif
void MAGNUM_GL_LOCAL moveConstructImplementationDefault(Mesh&& other);
void MAGNUM_GL_LOCAL moveConstructImplementationVAO(Mesh&& other);
void MAGNUM_GL_LOCAL moveAssignImplementationDefault(Mesh&& other);
void MAGNUM_GL_LOCAL moveAssignImplementationVAO(Mesh&& other);
void MAGNUM_GL_LOCAL destroyImplementationDefault(); void MAGNUM_GL_LOCAL destroyImplementationDefault();
void MAGNUM_GL_LOCAL destroyImplementationVAO(); void MAGNUM_GL_LOCAL destroyImplementationVAO();
@ -1041,7 +1045,9 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject {
MeshIndexType _indexType; MeshIndexType _indexType;
Buffer* _indexBuffer; Buffer* _indexBuffer;
std::vector<AttributeLayout> _attributes; /* Storage for std::vector with attribute layout / attribute buffer
instances. 4 pointers should be one pointer more than enough. */
struct { std::intptr_t data[4]; } _attributes;
}; };
/** @debugoperatorenum{MeshPrimitive} */ /** @debugoperatorenum{MeshPrimitive} */

42
src/Magnum/GL/Test/MeshGLTest.cpp

@ -285,8 +285,19 @@ void MeshGLTest::constructCopy() {
CORRADE_VERIFY(!(std::is_assignable<Mesh, const Mesh&>{})); CORRADE_VERIFY(!(std::is_assignable<Mesh, const Mesh&>{}));
} }
namespace {
struct FloatShader: AbstractShaderProgram {
explicit FloatShader(const std::string& type, const std::string& conversion);
};
}
void MeshGLTest::constructMove() { void MeshGLTest::constructMove() {
const Float data = Math::unpack<Float, UnsignedByte>(96);
Buffer buffer1, buffer2;
buffer1.setData({&data, 1}, BufferUsage::StaticDraw);
Mesh a; Mesh a;
a.addVertexBuffer(buffer1, 0, Attribute<0, Float>{});
const Int id = a.id(); const Int id = a.id();
MAGNUM_VERIFY_NO_GL_ERROR(); MAGNUM_VERIFY_NO_GL_ERROR();
@ -306,6 +317,7 @@ void MeshGLTest::constructMove() {
CORRADE_COMPARE(b.id(), id); CORRADE_COMPARE(b.id(), id);
Mesh c; Mesh c;
c.addVertexBuffer(buffer2, 1, Attribute<1, Float>{});
const Int cId = c.id(); const Int cId = c.id();
c = std::move(b); c = std::move(b);
@ -322,6 +334,32 @@ void MeshGLTest::constructMove() {
CORRADE_COMPARE(b.id(), cId); CORRADE_COMPARE(b.id(), cId);
CORRADE_COMPARE(c.id(), id); CORRADE_COMPARE(c.id(), id);
/* Test that drawing still works properly */
{
MAGNUM_VERIFY_NO_GL_ERROR();
Renderbuffer renderbuffer;
renderbuffer.setStorage(
#ifndef MAGNUM_TARGET_GLES2
RenderbufferFormat::RGBA8,
#else
RenderbufferFormat::RGBA4,
#endif
Vector2i(1));
Framebuffer framebuffer{{{}, Vector2i(1)}};
framebuffer.attachRenderbuffer(Framebuffer::ColorAttachment(0), renderbuffer)
.bind();
FloatShader shader{"float", "vec4(valueInterpolated, 0.0, 0.0, 0.0)"};
c.setPrimitive(MeshPrimitive::Points)
.setCount(1)
.draw(shader);
MAGNUM_VERIFY_NO_GL_ERROR();
CORRADE_COMPARE(framebuffer.read({{}, Vector2i{1}}, {PixelFormat::RGBA, PixelType::UnsignedByte}).data<UnsignedByte>()[0], 96);
}
} }
void MeshGLTest::wrap() { void MeshGLTest::wrap() {
@ -390,10 +428,6 @@ void MeshGLTest::label() {
#endif #endif
namespace { namespace {
struct FloatShader: AbstractShaderProgram {
explicit FloatShader(const std::string& type, const std::string& conversion);
};
#ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES2
struct IntegerShader: AbstractShaderProgram { struct IntegerShader: AbstractShaderProgram {
explicit IntegerShader(const std::string& type); explicit IntegerShader(const std::string& type);

Loading…
Cancel
Save