diff --git a/doc/changelog.dox b/doc/changelog.dox index 0f2145430..4b0dea925 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -85,6 +85,7 @@ See also: more information. - New @ref GL::Buffer::Buffer(Containers::ArrayView, BufferUsage) constructor for directly creating buffers filled with data. +- New @ref GL::Mesh::maxVertexAttributeStride() limit query @subsubsection changelog-latest-new-math Math library diff --git a/doc/opengl-mapping.dox b/doc/opengl-mapping.dox index bc485cc18..c606102f7 100644 --- a/doc/opengl-mapping.dox +++ b/doc/opengl-mapping.dox @@ -523,7 +523,7 @@ glGet() parameter | Matching API @def_gl{MAX_UNIFORM_BUFFER_BINDINGS} | @ref GL::Buffer::maxUniformBindings() @def_gl{MAX_UNIFORM_LOCATIONS} | @ref GL::AbstractShaderProgram::maxUniformLocations() @def_gl{MAX_VERTEX_ATTRIBS} | @ref GL::AbstractShaderProgram::maxVertexAttributes() -@def_gl{MAX_VERTEX_ATTRIB_STRIDE} | | +@def_gl{MAX_VERTEX_ATTRIB_STRIDE} | @ref GL::Mesh::maxVertexAttributeStride() @def_gl{MAX_VERTEX_ATTRIB_BINDINGS} | | @def_gl{MAX_VERTEX_ATTRIB_RELATIVE_OFFSET} | | @def_gl{MAX_VERTEX_STREAMS} | @ref GL::TransformFeedback::maxVertexStreams() diff --git a/src/Magnum/GL/Implementation/MeshState.h b/src/Magnum/GL/Implementation/MeshState.h index 9c362b70b..509f38721 100644 --- a/src/Magnum/GL/Implementation/MeshState.h +++ b/src/Magnum/GL/Implementation/MeshState.h @@ -72,6 +72,9 @@ struct MeshState { #endif GLuint currentVAO; + #if !defined(MAGNUM_TARGET_WEBGL) && !defined(MAGNUM_TARGET_GLES2) + GLint maxVertexAttributeStride{}; + #endif #ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_WEBGL GLint64 maxElementIndex; diff --git a/src/Magnum/GL/Mesh.cpp b/src/Magnum/GL/Mesh.cpp index de8e1a3fb..438a21820 100644 --- a/src/Magnum/GL/Mesh.cpp +++ b/src/Magnum/GL/Mesh.cpp @@ -142,6 +142,35 @@ struct Mesh::AttributeLayout { GLuint divisor; }; +UnsignedInt Mesh::maxVertexAttributeStride() { + #ifdef MAGNUM_TARGET_WEBGL + /* Defined for WebGL 1 and for the new vertexAttribIPointer in WebGL 2 too: + https://www.khronos.org/registry/webgl/specs/latest/1.0/index.html#5.14.10 + https://www.khronos.org/registry/webgl/specs/latest/2.0/#3.7.8 + */ + return 255; + #else + #ifndef MAGNUM_TARGET_GLES + if(!Context::current().isVersionSupported(Version::GL440)) + #elif !defined(MAGNUM_TARGET_GLES2) + if(!Context::current().isVersionSupported(Version::GLES310)) + #endif + { + return 0xffffffffu; + } + + #ifndef MAGNUM_TARGET_GLES2 + GLint& value = Context::current().state().mesh->maxVertexAttributeStride; + + /* Get the value, if not already cached */ + if(value == 0) + glGetIntegerv(GL_MAX_VERTEX_ATTRIB_STRIDE, &value); + + return value; + #endif + #endif +} + #ifndef MAGNUM_TARGET_GLES2 #ifndef MAGNUM_TARGET_WEBGL Long Mesh::maxElementIndex() diff --git a/src/Magnum/GL/Mesh.h b/src/Magnum/GL/Mesh.h index 27042152a..ba6aac1ef 100644 --- a/src/Magnum/GL/Mesh.h +++ b/src/Magnum/GL/Mesh.h @@ -301,6 +301,19 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { friend Implementation::MeshState; public: + /** + * @brief Max vertex attribute stride + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. If OpenGL 4.4 or OpenGL 3.1 supporting this query + * isn't available, returns max representable 32-bit value + * (@cpp 0xffffffffu @ce). On WebGL 1 and 2 the max stride is specified + * to be @cpp 255 @ce with no corresponding limit query. + * @see @ref addVertexBuffer(), @fn_gl{Get} with + * @def_gl_keyword{MAX_VERTEX_ATTRIB_STRIDE} + */ + static UnsignedInt maxVertexAttributeStride(); + #ifndef MAGNUM_TARGET_GLES2 /** * @brief Max supported index value @@ -682,7 +695,8 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * mesh and delete it afterwards. * * @see @ref addVertexBufferInstanced(), @ref setPrimitive(), - * @ref setCount(), @fn_gl_keyword{BindVertexArray}, + * @ref setCount(), @ref maxVertexAttributeStride(), + * @fn_gl_keyword{BindVertexArray}, * @fn_gl_keyword{EnableVertexAttribArray}, @fn_gl{BindBuffer}, * @fn_gl_keyword{VertexAttribPointer} or * @fn_gl2{EnableVertexArrayAttrib,EnableVertexAttribArray}, @@ -720,7 +734,7 @@ class MAGNUM_GL_EXPORT Mesh: public AbstractObject { * available, the vertex array object is used to hold the parameters. * * @see @ref setPrimitive(), @ref setCount(), @ref setInstanceCount(), - * @ref setBaseInstance(), + * @ref setBaseInstance(), @ref maxVertexAttributeStride(), * @fn_gl{BindVertexArray}, @fn_gl_keyword{EnableVertexAttribArray}, * @fn_gl{BindBuffer}, @fn_gl_keyword{VertexAttribPointer}, * @fn_gl_keyword{VertexAttribDivisor} or diff --git a/src/Magnum/Platform/gl-info.cpp b/src/Magnum/Platform/gl-info.cpp index f1dc1e2d0..c7920d1c2 100644 --- a/src/Magnum/Platform/gl-info.cpp +++ b/src/Magnum/Platform/gl-info.cpp @@ -410,6 +410,7 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat _lvec(GL::AbstractFramebuffer::maxViewportSize()) _l(GL::AbstractFramebuffer::maxDrawBuffers()) _l(GL::Framebuffer::maxColorAttachments()) + _l(GL::Mesh::maxVertexAttributeStride()) #ifndef MAGNUM_TARGET_GLES2 _l(GL::Mesh::maxElementIndex()) _l(GL::Mesh::maxElementsIndices())