Browse Source

Account for missing glVertexArrayVertexAttribDivisorEXT.

This function was added to ARB_instanced_arrays spec very late and thus
some implementations don't provide it (one case being AMD drivers on
Linux). If that function is not available, the non-DSA VAO specification
is used instead.
pull/87/head
Vladimír Vondruš 12 years ago
parent
commit
8446186a4e
  1. 9
      src/Magnum/Implementation/MeshState.cpp
  2. 2
      src/Magnum/Implementation/MeshState.h
  3. 21
      src/Magnum/Mesh.cpp
  4. 5
      src/Magnum/Mesh.h

9
src/Magnum/Implementation/MeshState.cpp

@ -137,7 +137,16 @@ MeshState::MeshState(Context& context, std::vector<std::string>& extensions): cu
drawArraysInstancedImplementation = nullptr; drawArraysInstancedImplementation = nullptr;
drawElementsInstancedImplementation = nullptr; drawElementsInstancedImplementation = nullptr;
} }
#endif
#ifndef MAGNUM_TARGET_GLES
/* Partial EXT_DSA implementation of vertex attrib divisor */
if(context.isExtensionSupported<Extensions::GL::EXT::direct_state_access>()) {
if(glVertexArrayVertexAttribDivisorEXT)
vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationDSAEXT;
else vertexAttribDivisorImplementation = &Mesh::vertexAttribDivisorImplementationVAO;
} else vertexAttribDivisorImplementation = nullptr;
#elif defined(MAGNUM_TARGET_GLES2)
/* Instanced arrays implementation on ES2 */ /* Instanced arrays implementation on ES2 */
if(context.isExtensionSupported<Extensions::GL::ANGLE::instanced_arrays>()) { if(context.isExtensionSupported<Extensions::GL::ANGLE::instanced_arrays>()) {
/* Extension added above */ /* Extension added above */

2
src/Magnum/Implementation/MeshState.h

@ -46,7 +46,7 @@ struct MeshState {
void(Mesh::*attributeLPointerImplementation)(const Mesh::LongAttribute&); void(Mesh::*attributeLPointerImplementation)(const Mesh::LongAttribute&);
#endif #endif
#endif #endif
#ifdef MAGNUM_TARGET_GLES2 #if !defined(MAGNUM_TARGET_GLES) || defined(MAGNUM_TARGET_GLES2)
void(Mesh::*vertexAttribDivisorImplementation)(GLuint, GLuint); void(Mesh::*vertexAttribDivisorImplementation)(GLuint, GLuint);
#endif #endif
void(Mesh::*bindIndexBufferImplementation)(Buffer&); void(Mesh::*bindIndexBufferImplementation)(Buffer&);

21
src/Magnum/Mesh.cpp

@ -406,7 +406,8 @@ void Mesh::attributePointerImplementationDSAEXT(const GenericAttribute& attribut
_created = true; _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location); glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); if(attribute.divisor)
(this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor);
} }
#endif #endif
@ -442,7 +443,8 @@ void Mesh::attributePointerImplementationDSAEXT(const IntegerAttribute& attribut
_created = true; _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location); glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); glVertexArrayVertexAttribIOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); if(attribute.divisor)
(this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor);
} }
#endif #endif
@ -472,7 +474,8 @@ void Mesh::attributePointerImplementationDSAEXT(const LongAttribute& attribute)
_created = true; _created = true;
glEnableVertexArrayAttribEXT(_id, attribute.location); glEnableVertexArrayAttribEXT(_id, attribute.location);
glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset); glVertexArrayVertexAttribLOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.stride, attribute.offset);
if(attribute.divisor) glVertexArrayVertexAttribDivisorEXT(_id, attribute.location, attribute.divisor); if(attribute.divisor)
(this->*Context::current()->state().mesh->vertexAttribDivisorImplementation)(attribute.location, attribute.divisor);
} }
void Mesh::vertexAttribPointer(const LongAttribute& attribute) { void Mesh::vertexAttribPointer(const LongAttribute& attribute) {
@ -483,7 +486,15 @@ void Mesh::vertexAttribPointer(const LongAttribute& attribute) {
} }
#endif #endif
#ifdef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES
void Mesh::vertexAttribDivisorImplementationVAO(const GLuint index, const GLuint divisor) {
bindVAO();
glVertexAttribDivisor(index, divisor);
}
void Mesh::vertexAttribDivisorImplementationDSAEXT(const GLuint index, const GLuint divisor) {
glVertexArrayVertexAttribDivisorEXT(_id, index, divisor);
}
#elif defined(MAGNUM_TARGET_GLES2)
void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLuint divisor) { void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glVertexAttribDivisorANGLE(index, divisor); glVertexAttribDivisorANGLE(index, divisor);
@ -493,7 +504,6 @@ void Mesh::vertexAttribDivisorImplementationANGLE(const GLuint index, const GLui
CORRADE_ASSERT_UNREACHABLE(); CORRADE_ASSERT_UNREACHABLE();
#endif #endif
} }
void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint divisor) { void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glVertexAttribDivisorEXT(index, divisor); glVertexAttribDivisorEXT(index, divisor);
@ -503,7 +513,6 @@ void Mesh::vertexAttribDivisorImplementationEXT(const GLuint index, const GLuint
CORRADE_ASSERT_UNREACHABLE(); CORRADE_ASSERT_UNREACHABLE();
#endif #endif
} }
void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint divisor) { void Mesh::vertexAttribDivisorImplementationNV(const GLuint index, const GLuint divisor) {
#if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL) #if !defined(CORRADE_TARGET_EMSCRIPTEN) && !defined(CORRADE_TARGET_NACL)
glVertexAttribDivisorNV(index, divisor); glVertexAttribDivisorNV(index, divisor);

5
src/Magnum/Mesh.h

@ -981,7 +981,10 @@ class MAGNUM_EXPORT Mesh: public AbstractObject {
void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute); void MAGNUM_LOCAL vertexAttribPointer(const LongAttribute& attribute);
#endif #endif
#ifdef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_GLES
void MAGNUM_LOCAL vertexAttribDivisorImplementationVAO(GLuint index, GLuint divisor);
void MAGNUM_LOCAL vertexAttribDivisorImplementationDSAEXT(GLuint index, GLuint divisor);
#elif defined(MAGNUM_TARGET_GLES2)
void MAGNUM_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationANGLE(GLuint index, GLuint divisor);
void MAGNUM_LOCAL vertexAttribDivisorImplementationEXT(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationEXT(GLuint index, GLuint divisor);
void MAGNUM_LOCAL vertexAttribDivisorImplementationNV(GLuint index, GLuint divisor); void MAGNUM_LOCAL vertexAttribDivisorImplementationNV(GLuint index, GLuint divisor);

Loading…
Cancel
Save