diff --git a/src/Magnum/Implementation/MeshState.cpp b/src/Magnum/Implementation/MeshState.cpp index b7ceea4d8..cbb48ea6c 100644 --- a/src/Magnum/Implementation/MeshState.cpp +++ b/src/Magnum/Implementation/MeshState.cpp @@ -61,18 +61,10 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu extensions.push_back(Extensions::GL::EXT::direct_state_access::string()); attributePointerImplementation = &Mesh::attributePointerImplementationDSAEXT; - attributeIPointerImplementation = &Mesh::attributePointerImplementationDSAEXT; - attributeLPointerImplementation = &Mesh::attributePointerImplementationDSAEXT; } else #endif { attributePointerImplementation = &Mesh::attributePointerImplementationVAO; - #ifndef MAGNUM_TARGET_GLES2 - attributeIPointerImplementation = &Mesh::attributePointerImplementationVAO; - #ifndef MAGNUM_TARGET_GLES - attributeLPointerImplementation = &Mesh::attributePointerImplementationVAO; - #endif - #endif } bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationVAO; @@ -84,12 +76,6 @@ MeshState::MeshState(Context& context, std::vector& extensions): cu createImplementation = &Mesh::createImplementationDefault; destroyImplementation = &Mesh::destroyImplementationDefault; attributePointerImplementation = &Mesh::attributePointerImplementationDefault; - #ifndef MAGNUM_TARGET_GLES2 - attributeIPointerImplementation = &Mesh::attributePointerImplementationDefault; - #ifndef MAGNUM_TARGET_GLES - attributeLPointerImplementation = &Mesh::attributePointerImplementationDefault; - #endif - #endif bindIndexBufferImplementation = &Mesh::bindIndexBufferImplementationDefault; bindImplementation = &Mesh::bindImplementationDefault; unbindImplementation = &Mesh::unbindImplementationDefault; diff --git a/src/Magnum/Implementation/MeshState.h b/src/Magnum/Implementation/MeshState.h index 835829257..2aec542b8 100644 --- a/src/Magnum/Implementation/MeshState.h +++ b/src/Magnum/Implementation/MeshState.h @@ -39,13 +39,7 @@ struct MeshState { void(Mesh::*createImplementation)(); void(Mesh::*destroyImplementation)(); - void(Mesh::*attributePointerImplementation)(const Mesh::GenericAttribute&); - #ifndef MAGNUM_TARGET_GLES2 - void(Mesh::*attributeIPointerImplementation)(const Mesh::IntegerAttribute&); - #ifndef MAGNUM_TARGET_GLES - void(Mesh::*attributeLPointerImplementation)(const Mesh::LongAttribute&); - #endif - #endif + void(Mesh::*attributePointerImplementation)(const Mesh::AttributeLayout&); #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2) void(Mesh::*vertexAttribDivisorImplementation)(GLuint, GLuint); #endif diff --git a/src/Magnum/Mesh.cpp b/src/Magnum/Mesh.cpp index 70ca9dc03..d70a751cf 100644 --- a/src/Magnum/Mesh.cpp +++ b/src/Magnum/Mesh.cpp @@ -138,12 +138,6 @@ Mesh::Mesh(Mesh&& other) noexcept: _id(other._id), _primitive(other._primitive), _indexStart(other._indexStart), _indexEnd(other._indexEnd), #endif _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 - , _longAttributes(std::move(other._longAttributes)) - #endif - #endif { other._id = 0; } @@ -167,12 +161,6 @@ Mesh& Mesh::operator=(Mesh&& other) noexcept { swap(_indexType, other._indexType); swap(_indexBuffer, other._indexBuffer); swap(_attributes, other._attributes); - #ifndef MAGNUM_TARGET_GLES2 - swap(_integerAttributes, other._integerAttributes); - #ifndef MAGNUM_TARGET_GLES - swap(_longAttributes, other._longAttributes); - #endif - #endif return *this; } @@ -400,11 +388,11 @@ void Mesh::destroyImplementationVAO() { #endif } -void Mesh::attributePointerInternal(const GenericAttribute& attribute) { +void Mesh::attributePointerInternal(const AttributeLayout& attribute) { (this->*Context::current()->state().mesh->attributePointerImplementation)(attribute); } -void Mesh::attributePointerImplementationDefault(const GenericAttribute& attribute) { +void Mesh::attributePointerImplementationDefault(const AttributeLayout& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -413,7 +401,7 @@ void Mesh::attributePointerImplementationDefault(const GenericAttribute& attribu _attributes.push_back(attribute); } -void Mesh::attributePointerImplementationVAO(const GenericAttribute& attribute) { +void Mesh::attributePointerImplementationVAO(const AttributeLayout& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -424,19 +412,45 @@ void Mesh::attributePointerImplementationVAO(const GenericAttribute& attribute) } #ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerImplementationDSAEXT(const GenericAttribute& attribute) { +void Mesh::attributePointerImplementationDSAEXT(const AttributeLayout& attribute) { _flags |= ObjectFlag::Created; glEnableVertexArrayAttribEXT(_id, attribute.location); - glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); + + #ifndef MAGNUM_TARGET_GLES2 + if(attribute.kind == AttributeLayout::Kind::Integral) + glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); + #ifndef MAGNUM_TARGET_GLES + else if(attribute.kind == AttributeLayout::Kind::Long) + glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); + #endif + else + #endif + { + glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.kind == AttributeLayout::Kind::GenericNormalized, attribute.stride, attribute.offset); + } + if(attribute.divisor) (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); } #endif -void Mesh::vertexAttribPointer(const GenericAttribute& attribute) { +void Mesh::vertexAttribPointer(const AttributeLayout& attribute) { glEnableVertexAttribArray(attribute.location); attribute.buffer->bindInternal(Buffer::TargetHint::Array); - glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset)); + + #ifndef MAGNUM_TARGET_GLES2 + if(attribute.kind == AttributeLayout::Kind::Integral) + glVertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); + #ifndef MAGNUM_TARGET_GLES + else if(attribute.kind == AttributeLayout::Kind::Long) + glVertexAttribLPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); + #endif + else + #endif + { + glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.kind == AttributeLayout::Kind::GenericNormalized, attribute.stride, reinterpret_cast(attribute.offset)); + } + if(attribute.divisor) { #ifndef MAGNUM_TARGET_GLES2 glVertexAttribDivisor(attribute.location, attribute.divisor); @@ -446,68 +460,6 @@ void Mesh::vertexAttribPointer(const GenericAttribute& attribute) { } } -#ifndef MAGNUM_TARGET_GLES2 -void Mesh::attributePointerInternal(const IntegerAttribute& attribute) { - (this->*Context::current()->state().mesh->attributeIPointerImplementation)(attribute); -} - -void Mesh::attributePointerImplementationDefault(const IntegerAttribute& attribute) { - _integerAttributes.push_back(attribute); -} - -void Mesh::attributePointerImplementationVAO(const IntegerAttribute& attribute) { - bindVAO(); - vertexAttribPointer(attribute); -} - -#ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerImplementationDSAEXT(const IntegerAttribute& attribute) { - _flags |= ObjectFlag::Created; - glEnableVertexArrayAttribEXT(_id, attribute.location); - glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) - (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); -} -#endif - -void Mesh::vertexAttribPointer(const IntegerAttribute& attribute) { - glEnableVertexAttribArray(attribute.location); - attribute.buffer->bindInternal(Buffer::TargetHint::Array); - glVertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); - if(attribute.divisor) glVertexAttribDivisor(attribute.location, attribute.divisor); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerInternal(const LongAttribute& attribute) { - (this->*Context::current()->state().mesh->attributeLPointerImplementation)(attribute); -} - -void Mesh::attributePointerImplementationDefault(const LongAttribute& attribute) { - _longAttributes.push_back(attribute); -} - -void Mesh::attributePointerImplementationVAO(const LongAttribute& attribute) { - bindVAO(); - vertexAttribPointer(attribute); -} - -void Mesh::attributePointerImplementationDSAEXT(const LongAttribute& attribute) { - _flags |= ObjectFlag::Created; - glEnableVertexArrayAttribEXT(_id, attribute.location); - glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); - if(attribute.divisor) - (this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor); -} - -void Mesh::vertexAttribPointer(const LongAttribute& attribute) { - glEnableVertexAttribArray(attribute.location); - attribute.buffer->bindInternal(Buffer::TargetHint::Array); - glVertexAttribLPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); - if(attribute.divisor) glVertexAttribDivisor(attribute.location, attribute.divisor); -} -#endif - #ifndef MAGNUM_TARGET_GLES void Mesh::vertexAttribDivisorImplementationVAO(const GLuint index, const GLuint divisor) { bindVAO(); @@ -562,18 +514,8 @@ void Mesh::bindIndexBufferImplementationVAO(Buffer& buffer) { void Mesh::bindImplementationDefault() { /* Specify vertex attributes */ - for(const GenericAttribute& attribute: _attributes) - vertexAttribPointer(attribute); - - #ifndef MAGNUM_TARGET_GLES2 - for(const IntegerAttribute& attribute: _integerAttributes) - vertexAttribPointer(attribute); - - #ifndef MAGNUM_TARGET_GLES - for(const LongAttribute& attribute: _longAttributes) + for(const AttributeLayout& attribute: _attributes) vertexAttribPointer(attribute); - #endif - #endif /* Bind index buffer, if the mesh is indexed */ if(_indexBuffer) _indexBuffer->bindInternal(Buffer::TargetHint::ElementArray); @@ -584,18 +526,8 @@ void Mesh::bindImplementationVAO() { } void Mesh::unbindImplementationDefault() { - for(const GenericAttribute& attribute: _attributes) - glDisableVertexAttribArray(attribute.location); - - #ifndef MAGNUM_TARGET_GLES2 - for(const IntegerAttribute& attribute: _integerAttributes) + for(const AttributeLayout& attribute: _attributes) glDisableVertexAttribArray(attribute.location); - - #ifndef MAGNUM_TARGET_GLES - for(const LongAttribute& attribute: _longAttributes) - glDisableVertexAttribArray(attribute.location); - #endif - #endif } void Mesh::unbindImplementationVAO() {} diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h index f401b741d..ac3ca38e8 100644 --- a/src/Magnum/Mesh.h +++ b/src/Magnum/Mesh.h @@ -842,42 +842,27 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void draw(AbstractShaderProgram&& shader) { draw(shader); } /**< @overload */ private: - #ifndef DOXYGEN_GENERATING_OUTPUT - struct MAGNUM_LOCAL GenericAttribute { - Buffer* buffer; - GLuint location; - GLint size; - GLenum type; - bool normalized; - GLintptr offset; - GLsizei stride; - GLuint divisor; - }; - - #ifndef MAGNUM_TARGET_GLES2 - struct MAGNUM_LOCAL IntegerAttribute { - Buffer* buffer; - GLuint location; - GLint size; - GLenum type; - GLintptr offset; - GLsizei stride; - GLuint divisor; - }; + struct MAGNUM_LOCAL AttributeLayout { + enum class Kind { + Generic, + GenericNormalized, + #ifndef MAGNUM_TARGET_GLES2 + Integral, + #ifndef MAGNUM_TARGET_GLES + Long + #endif + #endif + }; - #ifndef MAGNUM_TARGET_GLES - struct MAGNUM_LOCAL LongAttribute { Buffer* buffer; GLuint location; GLint size; GLenum type; + Kind kind; GLintptr offset; GLsizei stride; GLuint divisor; }; - #endif - #endif - #endif explicit Mesh(GLuint id, MeshPrimitive primitive, ObjectFlags flags): _id{id}, _primitive{primitive}, _flags{flags} {} @@ -911,12 +896,12 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) - attributePointerInternal(GenericAttribute{ + attributePointerInternal(AttributeLayout{ &buffer, location+i, GLint(attribute.components()), GLenum(attribute.dataType()), - bool(attribute.dataOptions() & Attribute::DataOption::Normalized), + attribute.dataOptions() & Attribute::DataOption::Normalized ? AttributeLayout::Kind::GenericNormalized : AttributeLayout::Kind::Generic, GLintptr(offset+i*attribute.vectorSize()), stride, divisor @@ -925,11 +910,12 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { #ifndef MAGNUM_TARGET_GLES2 template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { - attributePointerInternal(IntegerAttribute{ + attributePointerInternal(AttributeLayout{ &buffer, location, GLint(attribute.components()), GLenum(attribute.dataType()), + AttributeLayout::Kind::Integral, offset, stride, divisor @@ -939,11 +925,12 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { #ifndef MAGNUM_TARGET_GLES template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) - attributePointerInternal(LongAttribute{ + attributePointerInternal(AttributeLayout{ &buffer, location+i, GLint(attribute.components()), GLenum(attribute.dataType()), + AttributeLayout::Kind::Long, GLintptr(offset+i*attribute.vectorSize()), stride, divisor @@ -971,31 +958,13 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void MAGNUM_LOCAL destroyImplementationDefault(); void MAGNUM_LOCAL destroyImplementationVAO(); - void attributePointerInternal(const GenericAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDefault(const GenericAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationVAO(const GenericAttribute& attribute); + void attributePointerInternal(const AttributeLayout& attribute); + void MAGNUM_LOCAL attributePointerImplementationDefault(const AttributeLayout& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const AttributeLayout& attribute); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const GenericAttribute& attribute); - #endif - void MAGNUM_LOCAL vertexAttribPointer(const GenericAttribute& attribute); - - #ifndef MAGNUM_TARGET_GLES2 - void attributePointerInternal(const IntegerAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDefault(const IntegerAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationVAO(const IntegerAttribute& attribute); - #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const IntegerAttribute& attribute); - #endif - void MAGNUM_LOCAL vertexAttribPointer(const IntegerAttribute& attribute); - #endif - - #ifndef MAGNUM_TARGET_GLES - void attributePointerInternal(const LongAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDefault(const LongAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationVAO(const LongAttribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const LongAttribute& attribute); - void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const AttributeLayout& attribute); #endif + void MAGNUM_LOCAL vertexAttribPointer(const AttributeLayout& attribute); #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL vertexAttribDivisorImplementationVAO(GLuint index, GLuint divisor); @@ -1045,13 +1014,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { IndexType _indexType; Buffer* _indexBuffer; - std::vector _attributes; - #ifndef MAGNUM_TARGET_GLES2 - std::vector _integerAttributes; - #ifndef MAGNUM_TARGET_GLES - std::vector _longAttributes; - #endif - #endif + std::vector _attributes; }; /** @debugoperatorenum{Magnum::MeshPrimitive} */