From 50a0e5558e5d5f9050dc5e194cbae10a401ab871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 2 Nov 2012 12:47:50 +0100 Subject: [PATCH] Updated OpenGL ES support in Mesh and IndexedMesh. VAOs could be supported with extensions, thus not disabling them for ES2. --- src/IndexedMesh.cpp | 11 ++++---- src/IndexedMesh.h | 4 --- src/Mesh.cpp | 67 ++++++++++++++++++++++++++++++++++----------- src/Mesh.h | 32 ++++++++++++++-------- 4 files changed, 76 insertions(+), 38 deletions(-) diff --git a/src/IndexedMesh.cpp b/src/IndexedMesh.cpp index 9a8d0daa0..e91453f74 100644 --- a/src/IndexedMesh.cpp +++ b/src/IndexedMesh.cpp @@ -49,31 +49,30 @@ void IndexedMesh::bind() { } void IndexedMesh::initializeContextBasedFunctionality(Context* context) { + /** @todo VAOs are in ES 3.0 and as extension in ES 2.0, enable them when some extension wrangler is available */ + #ifndef MAGNUM_TARGET_GLES if(context->isExtensionSupported()) { - #ifndef MAGNUM_TARGET_GLES Debug() << "IndexedMesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features"; bindIndexBufferImplementation = &IndexedMesh::bindIndexBufferImplementationVAO; bindIndexedImplementation = &IndexedMesh::bindIndexedImplementationVAO; - #endif } + #else + static_cast(context); + #endif } void IndexedMesh::bindIndexBufferImplementationDefault() {} -#ifndef MAGNUM_TARGET_GLES void IndexedMesh::bindIndexBufferImplementationVAO() { bindVAO(vao); _indexBuffer->bind(Buffer::Target::ElementArray); } -#endif void IndexedMesh::bindIndexedImplementationDefault() { _indexBuffer->bind(Buffer::Target::ElementArray); } -#ifndef MAGNUM_TARGET_GLES void IndexedMesh::bindIndexedImplementationVAO() {} -#endif } diff --git a/src/IndexedMesh.h b/src/IndexedMesh.h index 1ee7d5d9e..1a0b25e9f 100644 --- a/src/IndexedMesh.h +++ b/src/IndexedMesh.h @@ -122,16 +122,12 @@ class MAGNUM_EXPORT IndexedMesh: public Mesh { typedef void(IndexedMesh::*BindIndexBufferImplementation)(); void MAGNUM_LOCAL bindIndexBufferImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindIndexBufferImplementationVAO(); - #endif static MAGNUM_LOCAL BindIndexBufferImplementation bindIndexBufferImplementation; typedef void(IndexedMesh::*BindIndexedImplementation)(); void MAGNUM_LOCAL bindIndexedImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindIndexedImplementationVAO(); - #endif static MAGNUM_LOCAL BindIndexedImplementation bindIndexedImplementation; Buffer* _indexBuffer; diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 927d2c38e..f868c38be 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -30,8 +30,12 @@ namespace Magnum { Mesh::CreateImplementation Mesh::createImplementation = &Mesh::createImplementationDefault; Mesh::DestroyImplementation Mesh::destroyImplementation = &Mesh::destroyImplementationDefault; Mesh::AttributePointerImplementation Mesh::attributePointerImplementation = &Mesh::attributePointerImplementationDefault; +#ifndef MAGNUM_TARGET_GLES2 Mesh::AttributeIPointerImplementation Mesh::attributeIPointerImplementation = &Mesh::attributePointerImplementationDefault; +#ifndef MAGNUM_TARGET_GLES Mesh::AttributeLPointerImplementation Mesh::attributeLPointerImplementation = &Mesh::attributePointerImplementationDefault; +#endif +#endif Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault; Mesh::UnbindImplementation Mesh::unbindImplementation = &Mesh::unbindImplementationDefault; @@ -43,7 +47,14 @@ Mesh::~Mesh() { (this->*destroyImplementation)(); } -Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), attributes(std::move(other.attributes)), integerAttributes(std::move(other.integerAttributes)), longAttributes(std::move(other.longAttributes)) { +Mesh::Mesh(Mesh&& other): vao(other.vao), _primitive(other._primitive), _vertexCount(other._vertexCount), 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.vao = 0; } @@ -54,8 +65,12 @@ Mesh& Mesh::operator=(Mesh&& other) { _primitive = other._primitive; _vertexCount = other._vertexCount; 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.vao = 0; @@ -65,10 +80,12 @@ Mesh& Mesh::operator=(Mesh&& other) { Mesh* Mesh::setVertexCount(GLsizei vertexCount) { _vertexCount = vertexCount; attributes.clear(); - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 integerAttributes.clear(); + #ifndef MAGNUM_TARGET_GLES longAttributes.clear(); #endif + #endif return this; } @@ -82,8 +99,13 @@ void Mesh::draw() { } void Mesh::bindVAO(GLuint vao) { + /** @todo Get some extension wrangler instead to avoid linker errors to glBindVertexArray() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 GLuint& current = Context::current()->state()->mesh->currentVAO; if(current != vao) glBindVertexArray(current = vao); + #else + static_cast(vao); + #endif } void Mesh::bind() { @@ -98,23 +120,26 @@ void Mesh::vertexAttribPointer(const Attribute& attribute) { glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset)); } -#ifndef MAGNUM_TARGET_GLES +#ifndef MAGNUM_TARGET_GLES2 void Mesh::vertexAttribPointer(const IntegerAttribute& attribute) { glEnableVertexAttribArray(attribute.location); attribute.buffer->bind(Buffer::Target::Array); glVertexAttribIPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); } +#ifndef MAGNUM_TARGET_GLES void Mesh::vertexAttribPointer(const LongAttribute& attribute) { glEnableVertexAttribArray(attribute.location); attribute.buffer->bind(Buffer::Target::Array); glVertexAttribLPointer(attribute.location, attribute.size, attribute.type, attribute.stride, reinterpret_cast(attribute.offset)); } #endif +#endif void Mesh::initializeContextBasedFunctionality(Context* context) { + /** @todo VAOs are in ES 3.0 and as extension in ES 2.0, enable them when some extension wrangler is available */ + #ifndef MAGNUM_TARGET_GLES if(context->isExtensionSupported()) { - #ifndef MAGNUM_TARGET_GLES Debug() << "Mesh: using" << Extensions::GL::APPLE::vertex_array_object::string() << "features"; createImplementation = &Mesh::createImplementationVAO; @@ -134,39 +159,45 @@ void Mesh::initializeContextBasedFunctionality(Context* context) { bindImplementation = &Mesh::bindImplementationVAO; unbindImplementation = &Mesh::unbindImplementationVAO; - #endif } + #else + static_cast(context); + #endif } void Mesh::createImplementationDefault() {} -#ifndef MAGNUM_TARGET_GLES void Mesh::createImplementationVAO() { + /** @todo Get some extension wrangler instead to avoid linker errors to glGenVertexArrays() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 glGenVertexArrays(1, &vao); + #endif } -#endif void Mesh::destroyImplementationDefault() {} -#ifndef MAGNUM_TARGET_GLES void Mesh::destroyImplementationVAO() { + /** @todo Get some extension wrangler instead to avoid linker errors to glDeleteVertexArrays() on ES2 */ + #ifndef MAGNUM_TARGET_GLES2 glDeleteVertexArrays(1, &vao); + #endif } -#endif void Mesh::attributePointerImplementationDefault(const Attribute&) {} -#ifndef MAGNUM_TARGET_GLES void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { bindVAO(vao); vertexAttribPointer(attribute); } +#ifndef MAGNUM_TARGET_GLES void Mesh::attributePointerImplementationDSA(const Attribute& attribute) { glEnableVertexArrayAttribEXT(vao, attribute.location); glVertexArrayVertexAttribOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); } +#endif +#ifndef MAGNUM_TARGET_GLES2 void Mesh::attributePointerImplementationDefault(const IntegerAttribute&) {} void Mesh::attributePointerImplementationVAO(const IntegerAttribute& attribute) { @@ -174,11 +205,14 @@ void Mesh::attributePointerImplementationVAO(const IntegerAttribute& attribute) vertexAttribPointer(attribute); } +#ifndef MAGNUM_TARGET_GLES void Mesh::attributePointerImplementationDSA(const IntegerAttribute& attribute) { glEnableVertexArrayAttribEXT(vao, attribute.location); glVertexArrayVertexAttribIOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); } +#endif +#ifndef MAGNUM_TARGET_GLES void Mesh::attributePointerImplementationDefault(const LongAttribute&) {} void Mesh::attributePointerImplementationVAO(const LongAttribute& attribute) { @@ -191,41 +225,42 @@ void Mesh::attributePointerImplementationDSA(const LongAttribute& attribute) { glVertexArrayVertexAttribLOffsetEXT(vao, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); } #endif +#endif void Mesh::bindImplementationDefault() { for(const Attribute& attribute: attributes) vertexAttribPointer(attribute); - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 for(const IntegerAttribute& attribute: integerAttributes) vertexAttribPointer(attribute); + #ifndef MAGNUM_TARGET_GLES for(const LongAttribute& attribute: longAttributes) vertexAttribPointer(attribute); #endif + #endif } -#ifndef MAGNUM_TARGET_GLES void Mesh::bindImplementationVAO() { bindVAO(vao); } -#endif void Mesh::unbindImplementationDefault() { for(const Attribute& attribute: attributes) glDisableVertexAttribArray(attribute.location); - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 for(const IntegerAttribute& attribute: integerAttributes) glDisableVertexAttribArray(attribute.location); + #ifndef MAGNUM_TARGET_GLES for(const LongAttribute& attribute: longAttributes) glDisableVertexAttribArray(attribute.location); #endif + #endif } -#ifndef MAGNUM_TARGET_GLES void Mesh::unbindImplementationVAO() {} -#endif } diff --git a/src/Mesh.h b/src/Mesh.h index bdd430d70..78a1ee686 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -557,6 +557,7 @@ class MAGNUM_EXPORT Mesh { GLsizei stride; }; + #ifndef MAGNUM_TARGET_GLES2 struct MAGNUM_LOCAL IntegerAttribute { Buffer* buffer; GLuint location; @@ -566,6 +567,7 @@ class MAGNUM_EXPORT Mesh { GLsizei stride; }; + #ifndef MAGNUM_TARGET_GLES struct MAGNUM_LOCAL LongAttribute { Buffer* buffer; GLuint location; @@ -575,6 +577,8 @@ class MAGNUM_EXPORT Mesh { GLsizei stride; }; #endif + #endif + #endif static void MAGNUM_LOCAL initializeContextBasedFunctionality(Context* context); @@ -629,7 +633,7 @@ class MAGNUM_EXPORT Mesh { (this->*attributePointerImplementation)(attributes.back()); } - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 template inline void addVertexAttribute(typename std::enable_if::AttributeType>::value, Buffer*>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride) { integerAttributes.push_back({ buffer, @@ -643,6 +647,7 @@ class MAGNUM_EXPORT Mesh { (this->*attributeIPointerImplementation)(integerAttributes.back()); } + #ifndef MAGNUM_TARGET_GLES template inline void addVertexAttribute(typename std::enable_if::AttributeType, GLdouble>::value, Buffer*>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride) { for(GLuint i = 0; i != Implementation::Attribute::vectorCount(); ++i) { longAttributes.push_back({ @@ -658,6 +663,7 @@ class MAGNUM_EXPORT Mesh { } } #endif + #endif static void MAGNUM_LOCAL bindVAO(GLuint vao); @@ -668,59 +674,57 @@ class MAGNUM_EXPORT Mesh { } void MAGNUM_LOCAL vertexAttribPointer(const Attribute& attribute); - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 void MAGNUM_LOCAL vertexAttribPointer(const IntegerAttribute& attribute); + #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); #endif + #endif typedef void(Mesh::*CreateImplementation)(); void MAGNUM_LOCAL createImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL createImplementationVAO(); - #endif static CreateImplementation createImplementation; typedef void(Mesh::*DestroyImplementation)(); void MAGNUM_LOCAL destroyImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL destroyImplementationVAO(); - #endif static MAGNUM_LOCAL DestroyImplementation destroyImplementation; typedef void(Mesh::*AttributePointerImplementation)(const Attribute&); void MAGNUM_LOCAL attributePointerImplementationDefault(const Attribute& attribute); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL attributePointerImplementationVAO(const Attribute& attribute); + #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL attributePointerImplementationDSA(const Attribute& attribute); #endif static AttributePointerImplementation attributePointerImplementation; - #ifndef MAGNUM_TARGET_GLES + #ifndef MAGNUM_TARGET_GLES2 typedef void(Mesh::*AttributeIPointerImplementation)(const IntegerAttribute&); void MAGNUM_LOCAL attributePointerImplementationDefault(const IntegerAttribute& attribute); void MAGNUM_LOCAL attributePointerImplementationVAO(const IntegerAttribute& attribute); + #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL attributePointerImplementationDSA(const IntegerAttribute& attribute); + #endif static AttributeIPointerImplementation attributeIPointerImplementation; + #ifndef MAGNUM_TARGET_GLES typedef void(Mesh::*AttributeLPointerImplementation)(const LongAttribute&); void MAGNUM_LOCAL attributePointerImplementationDefault(const LongAttribute& attribute); void MAGNUM_LOCAL attributePointerImplementationVAO(const LongAttribute& attribute); void MAGNUM_LOCAL attributePointerImplementationDSA(const LongAttribute& attribute); static AttributeLPointerImplementation attributeLPointerImplementation; #endif + #endif typedef void(Mesh::*BindImplementation)(); void MAGNUM_LOCAL bindImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL bindImplementationVAO(); - #endif static MAGNUM_LOCAL BindImplementation bindImplementation; typedef void(Mesh::*UnbindImplementation)(); void MAGNUM_LOCAL unbindImplementationDefault(); - #ifndef MAGNUM_TARGET_GLES void MAGNUM_LOCAL unbindImplementationVAO(); - #endif static MAGNUM_LOCAL UnbindImplementation unbindImplementation; GLuint vao; @@ -728,8 +732,12 @@ class MAGNUM_EXPORT Mesh { GLsizei _vertexCount; std::vector attributes; + #ifndef MAGNUM_TARGET_GLES2 std::vector integerAttributes; + #ifndef MAGNUM_TARGET_GLES std::vector longAttributes; + #endif + #endif }; }