diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index e02831f1a..cb181b9b4 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -73,6 +73,16 @@ AbstractShaderProgram::UniformMatrix3x4dvImplementation AbstractShaderProgram::u AbstractShaderProgram::UniformMatrix4x3dvImplementation AbstractShaderProgram::uniformMatrix4x3dvImplementation = &AbstractShaderProgram::uniformImplementationDefault; #endif +GLint AbstractShaderProgram::maxSupportedVertexAttributeCount() { + GLint& value = Context::current()->state()->shaderProgram->maxSupportedVertexAttributeCount; + + /* Get the value, if not already cached */ + if(value == 0) + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value); + + return value; +} + AbstractShaderProgram::~AbstractShaderProgram() { /* Remove current usage from the state */ GLuint& current = Context::current()->state()->shaderProgram->current; diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 7f85beeaf..28b3a63b1 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -273,7 +273,8 @@ vertex attributes. See also TypeTraits::AttributeType. @section AbstractShaderProgram-performance-optimization Performance optimizations The engine tracks currently used shader program to avoid unnecessary calls to -@fn_gl{UseProgram}. +@fn_gl{UseProgram}. %Shader limits (such as maxSupportedVertexAttributeCount()) +are cached, so repeated queries don't result in repeated @fn_gl{Get} calls. If extension @extension{ARB,separate_shader_objects} or @extension{EXT,direct_state_access} is available, uniform setting functions @@ -297,6 +298,11 @@ class MAGNUM_EXPORT AbstractShaderProgram { /** * @brief Base struct for attribute location and type * + * Template parameter @p location is vertex attribute location, number + * between `0` and maxSupportedVertexAttributeCount(). To ensure + * compatibility, you should always have vertex attribute with + * location `0`. + * * Template parameter @p T is the type which is used for shader * attribute, e.g. @ref Math::Vector4 "Vector4" for `ivec4`. * DataType is type of passed data when adding vertex buffers to mesh. @@ -315,10 +321,10 @@ class MAGNUM_EXPORT AbstractShaderProgram { * shaders and @ref Mesh-configuration for example usage when adding * vertex buffers to mesh. */ - template class Attribute { + template class Attribute { public: /** @brief Location to which the attribute is bound */ - static const GLuint Location = i; + static const GLuint Location = location; /** * @brief Type @@ -441,6 +447,15 @@ class MAGNUM_EXPORT AbstractShaderProgram { const DataOptions _dataOptions; }; + /** + * @brief Max supported vertex attribute count + * + * The result is cached, repeated queries don't result in repeated + * OpenGL calls. + * @see Attribute, @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIBS} + */ + static GLint maxSupportedVertexAttributeCount(); + /** * @brief Constructor * diff --git a/src/Implementation/ShaderProgramState.h b/src/Implementation/ShaderProgramState.h index d81af0aca..3aeb48310 100644 --- a/src/Implementation/ShaderProgramState.h +++ b/src/Implementation/ShaderProgramState.h @@ -20,10 +20,11 @@ namespace Magnum { namespace Implementation { struct ShaderProgramState { - inline constexpr ShaderProgramState(): current(0) {} + inline constexpr ShaderProgramState(): current(0), maxSupportedVertexAttributeCount(0) {} /* Currently used program */ GLuint current; + GLint maxSupportedVertexAttributeCount; }; }}