diff --git a/src/Implementation/MeshState.h b/src/Implementation/MeshState.h index e7c79ca6c..e9b9f2dfb 100644 --- a/src/Implementation/MeshState.h +++ b/src/Implementation/MeshState.h @@ -29,9 +29,16 @@ namespace Magnum { namespace Implementation { struct MeshState { - constexpr MeshState(): currentVAO(0) {} + constexpr MeshState(): currentVAO(0) + #ifndef MAGNUM_TARGET_GLES2 + , maxElementsIndices(0), maxElementsVertices(0) + #endif + {} GLuint currentVAO; + #ifndef MAGNUM_TARGET_GLES2 + GLint maxElementsIndices, maxElementsVertices; + #endif }; }} diff --git a/src/Mesh.cpp b/src/Mesh.cpp index 4f8d8d963..6c715924f 100644 --- a/src/Mesh.cpp +++ b/src/Mesh.cpp @@ -48,6 +48,30 @@ Mesh::BindIndexBufferImplementation Mesh::bindIndexBufferImplementation = &Mesh: Mesh::BindImplementation Mesh::bindImplementation = &Mesh::bindImplementationDefault; Mesh::UnbindImplementation Mesh::unbindImplementation = &Mesh::unbindImplementationDefault; +Int Mesh::maxVertexAttributes() { return AbstractShaderProgram::maxVertexAttributes(); } + +#ifndef MAGNUM_TARGET_GLES2 +Int Mesh::maxElementsIndices() { + GLint& value = Context::current()->state().mesh->maxElementsIndices; + + /* Get the value, if not already cached */ + if(value == 0) + glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &value); + + return value; +} + +Int Mesh::maxElementsVertices() { + GLint& value = Context::current()->state().mesh->maxElementsVertices; + + /* Get the value, if not already cached */ + if(value == 0) + glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &value); + + return value; +} +#endif + std::size_t Mesh::indexSize(IndexType type) { switch(type) { case IndexType::UnsignedByte: return 1; diff --git a/src/Mesh.h b/src/Mesh.h index cfed7e82b..ddaf9827e 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -215,7 +215,9 @@ If @extension{APPLE,vertex_array_object}, OpenGL ES 3.0 or @es_extension{OES,vertex_array_object} on OpenGL ES 2.0 is supported, VAOs are used instead of binding the buffers and specifying vertex attribute pointers in each draw() call. The engine tracks currently bound VAO to avoid -unnecessary calls to @fn_gl{BindVertexArray}. +unnecessary calls to @fn_gl{BindVertexArray}. %Mesh limits and +implementation-defined values (such as @ref maxVertexAttributes()) are cached, +so repeated queries don't result in repeated @fn_gl{Get} calls. If extension @extension{EXT,direct_state_access} and VAOs are available, DSA functions are used for specifying attribute locations to avoid unnecessary @@ -326,6 +328,40 @@ class MAGNUM_EXPORT Mesh { UnsignedInt = GL_UNSIGNED_INT }; + /** + * @brief Max supported vertex attribute count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. This function is in fact alias to + * @ref AbstractShaderProgram::maxVertexAttributes(). + * @see @ref addVertexBuffer() + */ + static Int maxVertexAttributes(); + + #ifndef MAGNUM_TARGET_GLES2 + /** + * @brief Max recommended index count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENTS_INDICES} + * @requires_gles30 Ranged element draw is not supported in OpenGL ES + * 2.0. + */ + static Int maxElementsIndices(); + + /** + * @brief Max recommended vertex count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see @ref setIndexBuffer(), @fn_gl{Get} with @def_gl{MAX_ELEMENTS_VERTICES} + * @requires_gles30 Ranged element draw is not supported in OpenGL ES + * 2.0. + */ + static Int maxElementsVertices(); + #endif + /** * @brief Size of given index type * @@ -466,7 +502,8 @@ class MAGNUM_EXPORT Mesh { * mesh, you must ensure it will exist for whole lifetime of the * mesh and delete it afterwards. * - * @see setPrimitive(), setVertexCount(), @fn_gl{BindVertexArray}, + * @see @ref maxVertexAttributes(), @ref setPrimitive(), + * @ref setVertexCount(), @fn_gl{BindVertexArray}, * @fn_gl{EnableVertexAttribArray}, @fn_gl{BindBuffer}, * @fn_gl{VertexAttribPointer} or * @fn_gl_extension{EnableVertexArrayAttrib,EXT,direct_state_access}, @@ -495,7 +532,8 @@ class MAGNUM_EXPORT Mesh { * On OpenGL ES 2.0 this function behaves always as * setIndexBuffer(Buffer*, GLintptr, IndexType), as this functionality * is not available there. - * @see setIndexCount(), MeshTools::compressIndices(), + * @see @ref maxElementsIndices(), @ref maxElementsVertices(), + * @ref setIndexCount(), @ref MeshTools::compressIndices(), * @fn_gl{BindVertexArray}, @fn_gl{BindBuffer} (if * @extension{APPLE,vertex_array_object} is available) */ diff --git a/src/Platform/magnum-info.cpp b/src/Platform/magnum-info.cpp index 00be9155a..1d9c6a72c 100644 --- a/src/Platform/magnum-info.cpp +++ b/src/Platform/magnum-info.cpp @@ -32,6 +32,7 @@ #include "AbstractShaderProgram.h" #include "Context.h" #include "Extensions.h" +#include "Mesh.h" #include "Shader.h" #ifndef CORRADE_TARGET_NACL #include "Platform/WindowlessGlxApplication.h" @@ -178,6 +179,10 @@ MagnumInfo::MagnumInfo(const Arguments& arguments): Platform::WindowlessApplicat #define _l(val) Debug() << " " << #val << (sizeof(#val) > 64 ? "\n" + std::string(68, ' ') : std::string(64 - sizeof(#val), ' ')) << val; Debug() << "Limits and implementation-defined values:"; + #ifndef MAGNUM_TARGET_GLES2 + _l(Mesh::maxElementsIndices()) + _l(Mesh::maxElementsVertices()) + #endif _l(Shader::maxVertexOutputComponents()) _l(Shader::maxFragmentInputComponents()) _l(Shader::maxTextureImageUnits(Shader::Type::Vertex))