diff --git a/src/Magnum/AbstractShaderProgram.cpp b/src/Magnum/AbstractShaderProgram.cpp index 5a5c6e8c5..9dbdd586b 100644 --- a/src/Magnum/AbstractShaderProgram.cpp +++ b/src/Magnum/AbstractShaderProgram.cpp @@ -1070,305 +1070,4 @@ void AbstractShaderProgram::uniformImplementationDSAEXT(const GLint location, co } #endif -namespace Implementation { - -UnsignedInt FloatAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -#ifndef MAGNUM_TARGET_GLES2 -UnsignedInt IntAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - return 4*components; - } - - CORRADE_ASSERT_UNREACHABLE(); -} -#endif - -#ifndef MAGNUM_TARGET_GLES -UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::Double: - return 8*components; - } - - CORRADE_ASSERT_UNREACHABLE(); -} -#endif - -UnsignedInt Attribute>::size(GLint components, DataType dataType) { - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - case DataType::UnsignedInt10f11f11fRev: - CORRADE_INTERNAL_ASSERT(components == 3); - return 4; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -UnsignedInt Attribute>::size(GLint components, DataType dataType) { - #ifndef MAGNUM_TARGET_GLES - if(components == GL_BGRA) components = 4; - #endif - - switch(dataType) { - case DataType::UnsignedByte: - case DataType::Byte: - return components; - case DataType::UnsignedShort: - case DataType::Short: - case DataType::HalfFloat: - return 2*components; - case DataType::UnsignedInt: - case DataType::Int: - case DataType::Float: - return 4*components; - #ifndef MAGNUM_TARGET_GLES - case DataType::Double: - return 8*components; - #endif - - #ifndef MAGNUM_TARGET_GLES2 - case DataType::UnsignedInt2101010Rev: - case DataType::Int2101010Rev: - CORRADE_INTERNAL_ASSERT(components == 4); - return 4; - #endif - } - - CORRADE_ASSERT_UNREACHABLE(); -} - -Debug operator<<(Debug debug, SizedAttribute<1, 1>::Components value) { - switch(value) { - case SizedAttribute<1, 1>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 2>::Components value) { - switch(value) { - case SizedAttribute<1, 2>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 2>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 3>::Components value) { - switch(value) { - case SizedAttribute<1, 3>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 3>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case SizedAttribute<1, 3>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedAttribute<1, 4>::Components value) { - switch(value) { - case SizedAttribute<1, 4>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case SizedAttribute<1, 4>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case SizedAttribute<1, 4>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - case SizedAttribute<1, 4>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<2>::Components value) { - switch(value) { - case SizedMatrixAttribute<2>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<3>::Components value) { - switch(value) { - case SizedMatrixAttribute<3>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, SizedMatrixAttribute<4>::Components value) { - switch(value) { - case SizedMatrixAttribute<4>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, Attribute>::Components value) { - switch(value) { - case Attribute>::Components::One: - return debug << "AbstractShaderProgram::Attribute::Components::One"; - case Attribute>::Components::Two: - return debug << "AbstractShaderProgram::Attribute::Components::Two"; - case Attribute>::Components::Three: - return debug << "AbstractShaderProgram::Attribute::Components::Three"; - case Attribute>::Components::Four: - return debug << "AbstractShaderProgram::Attribute::Components::Four"; - #ifndef MAGNUM_TARGET_GLES - case Attribute>::Components::BGRA: - return debug << "AbstractShaderProgram::Attribute::Components::BGRA"; - #endif - } - - return debug << "AbstractShaderProgram::Attribute::Components::(invalid)"; -} - -Debug operator<<(Debug debug, FloatAttribute::DataType value) { - switch(value) { - #define _c(value) case FloatAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -#ifndef MAGNUM_TARGET_GLES2 -Debug operator<<(Debug debug, IntAttribute::DataType value) { - switch(value) { - #define _c(value) case IntAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} -#endif - -#ifndef MAGNUM_TARGET_GLES -Debug operator<<(Debug debug, DoubleAttribute::DataType value) { - switch(value) { - #define _c(value) case DoubleAttribute::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(Double) - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} -#endif - -Debug operator<<(Debug debug, Attribute>::DataType value) { - switch(value) { - #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - _c(UnsignedInt10f11f11fRev) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -Debug operator<<(Debug debug, Attribute>::DataType value) { - switch(value) { - #define _c(value) case Attribute>::DataType::value: return debug << "AbstractShaderProgram::Attribute::DataType::" #value; - _c(UnsignedByte) - _c(Byte) - _c(UnsignedShort) - _c(Short) - _c(UnsignedInt) - _c(Int) - _c(HalfFloat) - _c(Float) - #ifndef MAGNUM_TARGET_GLES - _c(Double) - #endif - #ifndef MAGNUM_TARGET_GLES2 - _c(UnsignedInt2101010Rev) - _c(Int2101010Rev) - #endif - #undef _c - } - - return debug << "AbstractShaderProgram::Attribute::DataType::(invalid)"; -} - -} - } diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index 4d0ba00b5..134addeb4 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -32,17 +32,13 @@ #include #include #include -#include #include "Magnum/AbstractObject.h" -#include "Magnum/Magnum.h" +#include "Magnum/Attribute.h" namespace Magnum { -namespace Implementation { - template struct Attribute; - struct ShaderProgramState; -} +namespace Implementation { struct ShaderProgramState; } /** @brief Base for shader program implementations @@ -338,16 +334,13 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { friend struct Implementation::ShaderProgramState; public: - template class Attribute; - /** * @brief Max supported vertex attribute count * * The result is cached, repeated queries don't result in repeated * OpenGL calls. * @see @ref Mesh::maxVertexAttributes(), - * @ref AbstractShaderProgram::Attribute, @fn_gl{Get} with - * @def_gl{MAX_VERTEX_ATTRIBS} + * @ref Attribute, @fn_gl{Get} with @def_gl{MAX_VERTEX_ATTRIBS} */ static Int maxVertexAttributes(); @@ -1019,542 +1012,6 @@ class MAGNUM_EXPORT AbstractShaderProgram: public AbstractObject { GLuint _id; }; -/** -@brief Base struct for attribute location and type - -Template parameter @p location is vertex attribute location, number between `0` -and @ref maxVertexAttributes(). 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 Vector4i for `ivec4`. DataType is type of passed data when adding vertex -buffers to mesh. By default it is the same as type used in shader (e.g. -@ref DataType::Int for @ref Vector4i). It's also possible to pass integer data -to floating-point shader inputs. In this case you may want to normalize the -values (e.g. color components from 0-255 to 0.0f - 1.0f) -- see @ref DataOption::Normalized. - -Only some types are allowed as attribute types, see @ref AbstractShaderProgram-types -for more information. - -See @ref AbstractShaderProgram-subclassing for example usage in shaders and -@ref Mesh-configuration for example usage when adding vertex buffers to mesh. -*/ -template class AbstractShaderProgram::Attribute { - public: - enum: UnsignedInt { - Location = location, /**< Location to which the attribute is bound */ - - /** - * Count of vectors in this type - * - * @see @ref vectorSize() - */ - VectorCount = Implementation::Attribute::VectorCount - }; - - /** - * @brief Type - * - * Type used in shader code. - * @see @ref ScalarType, @ref DataType - */ - typedef T Type; - - /** - * @brief Scalar type - * - * The underlying scalar type of the attribute. - * @see @ref Type, @ref DataType - */ - typedef typename Implementation::Attribute::ScalarType ScalarType; - - /** - * @brief Component count - * - * Count of components passed to the shader. If passing smaller count - * of components than corresponding type has, unspecified components - * are set to default values (second and third to `0`, fourth to `1`). - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class Components: GLint { - /** - * Only first component is specified. Second, third and fourth - * component are set to `0`, `0`, `1`, respectively. Only for - * scalar and vector types, not matrices. - */ - One = 1, - - /** - * First two components are specified. Third and fourth component - * are set to `0`, `1`, respectively. Only for two, three and - * four-component vector types and 2x2, 3x2 and 4x2 matrix types. - */ - Two = 2, - - /** - * First three components are specified. Fourth component is set to - * `1`. Only for three and four-component vector types, 2x3, 3x3 - * and 4x3 matrix types. - */ - Three = 3, - - /** - * All four components are specified. Only for four-component - * vector types and 2x4, 3x4 and 4x4 matrix types. - */ - Four = 4, - - #ifndef MAGNUM_TARGET_GLES - /** - * Four components with BGRA ordering. Only for four-component - * float vector type. Must be used along with @ref DataType::UnsignedByte - * and @ref DataOption::Normalized. - * @requires_gl32 %Extension @extension{ARB,vertex_array_bgra} - * @requires_gl Only RGBA component ordering is supported in OpenGL - * ES. - */ - BGRA = GL_BGRA - #endif - }; - #else - typedef typename Implementation::Attribute::Components Components; - #endif - - /** - * @brief Data type - * - * Type of data passed to shader. - * @see @ref Type, @ref DataOptions, @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ - Byte = GL_BYTE, /**< Byte */ - UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */ - Short = GL_SHORT, /**< Short */ - UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ - Int = GL_INT, /**< Int */ - - /** - * Half float. Only for float attribute types. - * @requires_gl30 %Extension @extension{ARB,half_float_vertex} - * @requires_gles30 %Extension @es_extension{OES,vertex_half_float} - * in OpenGL ES 2.0 - */ - HalfFloat = GL_HALF_FLOAT, - - /** Float. Only for float attribute types. */ - Float = GL_FLOAT, - - #ifndef MAGNUM_TARGET_GLES - /** - * Double. Only for float and double attribute types. - * @requires_gl Only floats are available in OpenGL ES. - */ - Double = GL_DOUBLE, - - /** - * Unsigned 10.11.11 packed float. Only for three-component float - * vector attribute type. - * @requires_gl44 %Extension @extension{ARB,vertex_type_10f_11f_11f_rev} - * @requires_gl Packed float attributes are not available in OpenGL - * ES. - */ - UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, - #endif - - /* GL_FIXED not supported */ - - #ifndef MAGNUM_TARGET_GLES2 - /** - * Unsigned 2.10.10.10 packed integer. Only for four-component - * float vector attribute type. - * @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}? - * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} - * @requires_gles30 Packed attributes are not available in OpenGL - * ES 2.0 - */ - UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, - - /** - * Signed 2.10.10.10 packed integer. Only for four-component float - * vector attribute type. - * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} - * @requires_gles30 Packed attributes are not available in OpenGL - * ES 2.0 - */ - Int2101010Rev = GL_INT_2_10_10_10_REV - #endif - }; - #else - typedef typename Implementation::Attribute::DataType DataType; - #endif - - /** - * @brief Data option - * @see @ref DataOptions, @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - enum class DataOption: UnsignedByte { - /** - * Normalize integer components. Only for float attribute types. - * Default is to not normalize. - */ - Normalized = 1 << 0 - }; - #else - typedef typename Implementation::Attribute::DataOption DataOption; - #endif - - /** - * @brief Data options - * @see @ref Attribute() - */ - #ifdef DOXYGEN_GENERATING_OUTPUT - typedef typename Containers::EnumSet DataOptions; - #else - typedef typename Implementation::Attribute::DataOptions DataOptions; - #endif - - /** - * @brief Constructor - * @param components Component count - * @param dataType Type of passed data. Default is the same as - * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). - * @param dataOptions Data options. Default is no options. - */ - constexpr Attribute(Components components, DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {} - - /** - * @brief Constructor - * @param dataType Type of passed data. Default is the same as - * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). - * @param dataOptions Data options. Default is no options. - * - * Component count is set to the same value as in type used in shader - * (e.g. @ref Components::Three for @ref Vector3). - */ - constexpr Attribute(DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {} - - /** @brief Component count of passed data */ - constexpr Components components() const { return _components; } - - /** @brief Type of passed data */ - constexpr DataType dataType() const { return _dataType; } - - /** - * @brief Size of each vector in passed data - * - * @see @ref VectorCount - */ - UnsignedInt vectorSize() const { - return Implementation::Attribute::size(GLint(_components), _dataType); - } - - /** @brief Data options */ - constexpr DataOptions dataOptions() const { return _dataOptions; } - - private: - Components _components; - DataType _dataType; - DataOptions _dataOptions; -}; - -#ifdef DOXYGEN_GENERATING_OUTPUT -/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::Components} */ -template Debug operator<<(Debug debug, AbstractShaderProgram::Attribute::Components); - -/** @debugoperatorclassenum{Magnum::AbstractShaderProgram::Attribute,Magnum::AbstractShaderProgram::Attribute::DataType} */ -template Debug operator<<(Debug debug, AbstractShaderProgram::Attribute::DataType); -#endif - -namespace Implementation { - -/* Base for sized attributes */ -template struct SizedAttribute; - -/* Vector attribute sizes */ -template struct SizedVectorAttribute { - enum: UnsignedInt { VectorCount = UnsignedInt(cols) }; -}; -template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1 }; - constexpr static Components DefaultComponents = Components::One; -}; -template<> struct SizedAttribute<1, 2>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2 }; - constexpr static Components DefaultComponents = Components::Two; -}; -template<> struct SizedAttribute<1, 3>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2, Three = 3 }; - constexpr static Components DefaultComponents = Components::Three; -}; -template<> struct SizedAttribute<1, 4>: SizedVectorAttribute<1> { - enum class Components: GLint { One = 1, Two = 2, Three = 3, Four = 4 }; - constexpr static Components DefaultComponents = Components::Four; -}; -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 1>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 2>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 3>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 4>::Components value); - -/* Matrix attribute sizes */ -template struct SizedMatrixAttribute; -template<> struct SizedMatrixAttribute<2> { - enum class Components: GLint { Two = 2 }; - constexpr static Components DefaultComponents = Components::Two; -}; -template<> struct SizedMatrixAttribute<3> { - enum class Components: GLint { Three = 3 }; - constexpr static Components DefaultComponents = Components::Three; -}; -template<> struct SizedMatrixAttribute<4> { - enum class Components: GLint { Four = 4 }; - constexpr static Components DefaultComponents = Components::Four; -}; -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<2>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<3>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<4>::Components value); -template<> struct SizedAttribute<2, 2>: SizedVectorAttribute<2>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<3, 3>: SizedVectorAttribute<3>, SizedMatrixAttribute<3> {}; -template<> struct SizedAttribute<4, 4>: SizedVectorAttribute<4>, SizedMatrixAttribute<4> {}; -#ifndef MAGNUM_TARGET_GLES2 -template<> struct SizedAttribute<2, 3>: SizedVectorAttribute<2>, SizedMatrixAttribute<3> {}; -template<> struct SizedAttribute<3, 2>: SizedVectorAttribute<3>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<2, 4>: SizedVectorAttribute<2>, SizedMatrixAttribute<4> {}; -template<> struct SizedAttribute<4, 2>: SizedVectorAttribute<4>, SizedMatrixAttribute<2> {}; -template<> struct SizedAttribute<3, 4>: SizedVectorAttribute<3>, SizedMatrixAttribute<4> {}; -template<> struct SizedAttribute<4, 3>: SizedVectorAttribute<4>, SizedMatrixAttribute<3> {}; -#endif - -/* Base for attributes */ -template struct Attribute; - -/* Base for float attributes */ -struct FloatAttribute { - typedef Float ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE - #endif - }; - constexpr static DataType DefaultDataType = DataType::Float; - - enum class DataOption: UnsignedByte { - Normalized = 1 << 0 - }; - typedef Containers::EnumSet DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -CORRADE_ENUMSET_OPERATORS(FloatAttribute::DataOptions) - -Debug MAGNUM_EXPORT operator<<(Debug debug, FloatAttribute::DataType value); - -#ifndef MAGNUM_TARGET_GLES2 -/* Base for int attributes */ -struct IntAttribute { - typedef Int ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT - }; - constexpr static DataType DefaultDataType = DataType::Int; - - enum class DataOption: UnsignedByte {}; - typedef Containers::EnumSet DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -CORRADE_ENUMSET_OPERATORS(IntAttribute::DataOptions) - -Debug MAGNUM_EXPORT operator<<(Debug debug, IntAttribute::DataType value); - -/* Base for unsigned int attributes */ -struct UnsignedIntAttribute { - typedef UnsignedInt ScalarType; - - typedef IntAttribute::DataType DataType; - constexpr static DataType DefaultDataType = DataType::UnsignedInt; - - typedef IntAttribute::DataOption DataOption; - typedef IntAttribute::DataOptions DataOptions; - - static UnsignedInt size(GLint components, DataType dataType) { - return IntAttribute::size(components, dataType); - } -}; -#endif - -#ifndef MAGNUM_TARGET_GLES -/* Base for double attributes */ -struct DoubleAttribute { - typedef Double ScalarType; - - enum class DataType: GLenum { - Double = GL_DOUBLE - }; - constexpr static DataType DefaultDataType = DataType::Double; - - typedef IntAttribute::DataOption DataOption; - typedef IntAttribute::DataOptions DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value); -#endif - -/* Floating-point three-component vector has additional data type compared to - classic floats */ -template<> struct Attribute>: SizedAttribute<1, 3> { - typedef Float ScalarType; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE, - UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV - #endif - }; - constexpr static DataType DefaultDataType = DataType::Float; - - typedef FloatAttribute::DataOption DataOption; - typedef FloatAttribute::DataOptions DataOptions; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); - -/* Floating-point four-component vector is absolutely special case */ -template<> struct Attribute> { - typedef Float ScalarType; - - enum class Components: GLint { - One = 1, - Two = 2, - Three = 3, - Four = 4 - #ifndef MAGNUM_TARGET_GLES - , - BGRA = GL_BGRA - #endif - }; - constexpr static Components DefaultComponents = Components::Four; - - enum class DataType: GLenum { - UnsignedByte = GL_UNSIGNED_BYTE, - Byte = GL_BYTE, - UnsignedShort = GL_UNSIGNED_SHORT, - Short = GL_SHORT, - UnsignedInt = GL_UNSIGNED_INT, - Int = GL_INT, - #ifndef MAGNUM_TARGET_GLES2 - HalfFloat = GL_HALF_FLOAT, - #else - HalfFloat = GL_HALF_FLOAT_OES, - #endif - Float = GL_FLOAT - #ifndef MAGNUM_TARGET_GLES - , - Double = GL_DOUBLE - #endif - #ifndef MAGNUM_TARGET_GLES2 - , - UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, - Int2101010Rev = GL_INT_2_10_10_10_REV - #endif - }; - constexpr static DataType DefaultDataType = DataType::Float; - - typedef FloatAttribute::DataOption DataOption; - typedef FloatAttribute::DataOptions DataOptions; - - enum: UnsignedInt { VectorCount = 1 }; - - static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); -}; - -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::Components value); -Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); - -/* Common float, int, unsigned int and double scalar attributes */ -template<> struct Attribute: FloatAttribute, SizedAttribute<1, 1> {}; -#ifndef MAGNUM_TARGET_GLES2 -template<> struct Attribute: IntAttribute, SizedAttribute<1, 1> {}; -template<> struct Attribute: UnsignedIntAttribute, SizedAttribute<1, 1> {}; -#ifndef MAGNUM_TARGET_GLES -template<> struct Attribute: DoubleAttribute, SizedAttribute<1, 1> {}; -#endif -#endif - -/* Common float, int, unsigned int and double vector attributes */ -template struct Attribute>: FloatAttribute, SizedAttribute<1, size_> {}; -#ifndef MAGNUM_TARGET_GLES2 -template struct Attribute>: IntAttribute, SizedAttribute<1, size_> {}; -template struct Attribute>: UnsignedIntAttribute, SizedAttribute<1, size_> {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: DoubleAttribute, SizedAttribute<1, size_> {}; -#endif -#endif -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; - -/* Common float and double rectangular matrix attributes */ -template struct Attribute>: FloatAttribute, SizedAttribute {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: DoubleAttribute, SizedAttribute {}; -#endif - -/* Common float and double square matrix attributes */ -template struct Attribute>: Attribute> {}; -#ifndef MAGNUM_TARGET_GLES -template struct Attribute>: Attribute> {}; -#endif -template struct Attribute>: Attribute> {}; -template struct Attribute>: Attribute> {}; - -} - } #endif diff --git a/src/Magnum/Attribute.cpp b/src/Magnum/Attribute.cpp new file mode 100644 index 000000000..f4a410898 --- /dev/null +++ b/src/Magnum/Attribute.cpp @@ -0,0 +1,329 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "Attribute.h" + +#include + +namespace Magnum { namespace Implementation { + +UnsignedInt FloatAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +#ifndef MAGNUM_TARGET_GLES2 +UnsignedInt IntAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + return 4*components; + } + + CORRADE_ASSERT_UNREACHABLE(); +} +#endif + +#ifndef MAGNUM_TARGET_GLES +UnsignedInt DoubleAttribute::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::Double: + return 8*components; + } + + CORRADE_ASSERT_UNREACHABLE(); +} +#endif + +UnsignedInt Attribute>::size(GLint components, DataType dataType) { + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + case DataType::UnsignedInt10f11f11fRev: + CORRADE_INTERNAL_ASSERT(components == 3); + return 4; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +UnsignedInt Attribute>::size(GLint components, DataType dataType) { + #ifndef MAGNUM_TARGET_GLES + if(components == GL_BGRA) components = 4; + #endif + + switch(dataType) { + case DataType::UnsignedByte: + case DataType::Byte: + return components; + case DataType::UnsignedShort: + case DataType::Short: + case DataType::HalfFloat: + return 2*components; + case DataType::UnsignedInt: + case DataType::Int: + case DataType::Float: + return 4*components; + #ifndef MAGNUM_TARGET_GLES + case DataType::Double: + return 8*components; + #endif + + #ifndef MAGNUM_TARGET_GLES2 + case DataType::UnsignedInt2101010Rev: + case DataType::Int2101010Rev: + CORRADE_INTERNAL_ASSERT(components == 4); + return 4; + #endif + } + + CORRADE_ASSERT_UNREACHABLE(); +} + +Debug operator<<(Debug debug, SizedAttribute<1, 1>::Components value) { + switch(value) { + case SizedAttribute<1, 1>::Components::One: + return debug << "Attribute::Components::One"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 2>::Components value) { + switch(value) { + case SizedAttribute<1, 2>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 2>::Components::Two: + return debug << "Attribute::Components::Two"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 3>::Components value) { + switch(value) { + case SizedAttribute<1, 3>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 3>::Components::Two: + return debug << "Attribute::Components::Two"; + case SizedAttribute<1, 3>::Components::Three: + return debug << "Attribute::Components::Three"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedAttribute<1, 4>::Components value) { + switch(value) { + case SizedAttribute<1, 4>::Components::One: + return debug << "Attribute::Components::One"; + case SizedAttribute<1, 4>::Components::Two: + return debug << "Attribute::Components::Two"; + case SizedAttribute<1, 4>::Components::Three: + return debug << "Attribute::Components::Three"; + case SizedAttribute<1, 4>::Components::Four: + return debug << "Attribute::Components::Four"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<2>::Components value) { + switch(value) { + case SizedMatrixAttribute<2>::Components::Two: + return debug << "Attribute::Components::Two"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<3>::Components value) { + switch(value) { + case SizedMatrixAttribute<3>::Components::Three: + return debug << "Attribute::Components::Three"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, SizedMatrixAttribute<4>::Components value) { + switch(value) { + case SizedMatrixAttribute<4>::Components::Four: + return debug << "Attribute::Components::Four"; + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, Attribute>::Components value) { + switch(value) { + case Attribute>::Components::One: + return debug << "Attribute::Components::One"; + case Attribute>::Components::Two: + return debug << "Attribute::Components::Two"; + case Attribute>::Components::Three: + return debug << "Attribute::Components::Three"; + case Attribute>::Components::Four: + return debug << "Attribute::Components::Four"; + #ifndef MAGNUM_TARGET_GLES + case Attribute>::Components::BGRA: + return debug << "Attribute::Components::BGRA"; + #endif + } + + return debug << "Attribute::Components::(invalid)"; +} + +Debug operator<<(Debug debug, FloatAttribute::DataType value) { + switch(value) { + #define _c(value) case FloatAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +#ifndef MAGNUM_TARGET_GLES2 +Debug operator<<(Debug debug, IntAttribute::DataType value) { + switch(value) { + #define _c(value) case IntAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} +#endif + +#ifndef MAGNUM_TARGET_GLES +Debug operator<<(Debug debug, DoubleAttribute::DataType value) { + switch(value) { + #define _c(value) case DoubleAttribute::DataType::value: return debug << "Attribute::DataType::" #value; + _c(Double) + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} +#endif + +Debug operator<<(Debug debug, Attribute>::DataType value) { + switch(value) { + #define _c(value) case Attribute>::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + _c(UnsignedInt10f11f11fRev) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +Debug operator<<(Debug debug, Attribute>::DataType value) { + switch(value) { + #define _c(value) case Attribute>::DataType::value: return debug << "Attribute::DataType::" #value; + _c(UnsignedByte) + _c(Byte) + _c(UnsignedShort) + _c(Short) + _c(UnsignedInt) + _c(Int) + _c(HalfFloat) + _c(Float) + #ifndef MAGNUM_TARGET_GLES + _c(Double) + #endif + #ifndef MAGNUM_TARGET_GLES2 + _c(UnsignedInt2101010Rev) + _c(Int2101010Rev) + #endif + #undef _c + } + + return debug << "Attribute::DataType::(invalid)"; +} + +}} diff --git a/src/Magnum/Attribute.h b/src/Magnum/Attribute.h new file mode 100644 index 000000000..26deca2fc --- /dev/null +++ b/src/Magnum/Attribute.h @@ -0,0 +1,582 @@ +#ifndef Magnum_Attribute_h +#define Magnum_Attribute_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class @ref Magnum::Attribute + */ + +#include + +#include "Magnum/Magnum.h" +#include "Magnum/OpenGL.h" +#include "Magnum/visibility.h" + +namespace Magnum { + +namespace Implementation { template struct Attribute; } + +/** +@brief Base class for attribute location and type + +For use in @ref AbstractShaderProgram subclasses. Template parameter @p location +is vertex attribute location, number between `0` and @ref maxVertexAttributes(). +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 Vector4i for `ivec4`. DataType is type of passed data when adding vertex +buffers to mesh. By default it is the same as type used in shader (e.g. +@ref DataType::Int for @ref Vector4i). It's also possible to pass integer data +to floating-point shader inputs. In this case you may want to normalize the +values (e.g. color components from 0-255 to 0.0f - 1.0f) -- see +@ref DataOption::Normalized. + +Only some types are allowed as attribute types, see @ref AbstractShaderProgram-types +for more information. + +See @ref AbstractShaderProgram-subclassing for example usage in shaders and +@ref Mesh-configuration for example usage when adding vertex buffers to mesh. +*/ +template class Attribute { + public: + enum: UnsignedInt { + Location = location, /**< Location to which the attribute is bound */ + + /** + * Count of vectors in this type + * + * @see @ref vectorSize() + */ + VectorCount = Implementation::Attribute::VectorCount + }; + + /** + * @brief Type + * + * Type used in shader code. + * @see @ref ScalarType, @ref DataType + */ + typedef T Type; + + /** + * @brief Scalar type + * + * The underlying scalar type of the attribute. + * @see @ref Type, @ref DataType + */ + typedef typename Implementation::Attribute::ScalarType ScalarType; + + /** + * @brief Component count + * + * Count of components passed to the shader. If passing smaller count + * of components than corresponding type has, unspecified components + * are set to default values (second and third to `0`, fourth to `1`). + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class Components: GLint { + /** + * Only first component is specified. Second, third and fourth + * component are set to `0`, `0`, `1`, respectively. Only for + * scalar and vector types, not matrices. + */ + One = 1, + + /** + * First two components are specified. Third and fourth component + * are set to `0`, `1`, respectively. Only for two, three and + * four-component vector types and 2x2, 3x2 and 4x2 matrix types. + */ + Two = 2, + + /** + * First three components are specified. Fourth component is set to + * `1`. Only for three and four-component vector types, 2x3, 3x3 + * and 4x3 matrix types. + */ + Three = 3, + + /** + * All four components are specified. Only for four-component + * vector types and 2x4, 3x4 and 4x4 matrix types. + */ + Four = 4, + + #ifndef MAGNUM_TARGET_GLES + /** + * Four components with BGRA ordering. Only for four-component + * float vector type. Must be used along with @ref DataType::UnsignedByte + * and @ref DataOption::Normalized. + * @requires_gl32 %Extension @extension{ARB,vertex_array_bgra} + * @requires_gl Only RGBA component ordering is supported in OpenGL + * ES. + */ + BGRA = GL_BGRA + #endif + }; + #else + typedef typename Implementation::Attribute::Components Components; + #endif + + /** + * @brief Data type + * + * Type of data passed to shader. + * @see @ref Type, @ref DataOptions, @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, /**< Unsigned byte */ + Byte = GL_BYTE, /**< Byte */ + UnsignedShort = GL_UNSIGNED_SHORT, /**< Unsigned short */ + Short = GL_SHORT, /**< Short */ + UnsignedInt = GL_UNSIGNED_INT, /**< Unsigned int */ + Int = GL_INT, /**< Int */ + + /** + * Half float. Only for float attribute types. + * @requires_gl30 %Extension @extension{ARB,half_float_vertex} + * @requires_gles30 %Extension @es_extension{OES,vertex_half_float} + * in OpenGL ES 2.0 + */ + HalfFloat = GL_HALF_FLOAT, + + /** Float. Only for float attribute types. */ + Float = GL_FLOAT, + + #ifndef MAGNUM_TARGET_GLES + /** + * Double. Only for float and double attribute types. + * @requires_gl Only floats are available in OpenGL ES. + */ + Double = GL_DOUBLE, + + /** + * Unsigned 10.11.11 packed float. Only for three-component float + * vector attribute type. + * @requires_gl44 %Extension @extension{ARB,vertex_type_10f_11f_11f_rev} + * @requires_gl Packed float attributes are not available in OpenGL + * ES. + */ + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV, + #endif + + /* GL_FIXED not supported */ + + #ifndef MAGNUM_TARGET_GLES2 + /** + * Unsigned 2.10.10.10 packed integer. Only for four-component + * float vector attribute type. + * @todo How about (incompatible) @es_extension{OES,vertex_type_10_10_10_2}? + * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 Packed attributes are not available in OpenGL + * ES 2.0 + */ + UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, + + /** + * Signed 2.10.10.10 packed integer. Only for four-component float + * vector attribute type. + * @requires_gl33 %Extension @extension{ARB,vertex_type_2_10_10_10_rev} + * @requires_gles30 Packed attributes are not available in OpenGL + * ES 2.0 + */ + Int2101010Rev = GL_INT_2_10_10_10_REV + #endif + }; + #else + typedef typename Implementation::Attribute::DataType DataType; + #endif + + /** + * @brief Data option + * @see @ref DataOptions, @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + enum class DataOption: UnsignedByte { + /** + * Normalize integer components. Only for float attribute types. + * Default is to not normalize. + */ + Normalized = 1 << 0 + }; + #else + typedef typename Implementation::Attribute::DataOption DataOption; + #endif + + /** + * @brief Data options + * @see @ref Attribute() + */ + #ifdef DOXYGEN_GENERATING_OUTPUT + typedef typename Containers::EnumSet DataOptions; + #else + typedef typename Implementation::Attribute::DataOptions DataOptions; + #endif + + /** + * @brief Constructor + * @param components Component count + * @param dataType Type of passed data. Default is the same as + * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). + * @param dataOptions Data options. Default is no options. + */ + constexpr Attribute(Components components, DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(components), _dataType(dataType), _dataOptions(dataOptions) {} + + /** + * @brief Constructor + * @param dataType Type of passed data. Default is the same as + * type used in shader (e.g. @ref DataType::Int for @ref Vector4i). + * @param dataOptions Data options. Default is no options. + * + * Component count is set to the same value as in type used in shader + * (e.g. @ref Components::Three for @ref Vector3). + */ + constexpr Attribute(DataType dataType = Implementation::Attribute::DefaultDataType, DataOptions dataOptions = DataOptions()): _components(Implementation::Attribute::DefaultComponents), _dataType(dataType), _dataOptions(dataOptions) {} + + /** @brief Component count of passed data */ + constexpr Components components() const { return _components; } + + /** @brief Type of passed data */ + constexpr DataType dataType() const { return _dataType; } + + /** + * @brief Size of each vector in passed data + * + * @see @ref VectorCount + */ + UnsignedInt vectorSize() const { + return Implementation::Attribute::size(GLint(_components), _dataType); + } + + /** @brief Data options */ + constexpr DataOptions dataOptions() const { return _dataOptions; } + + private: + Components _components; + DataType _dataType; + DataOptions _dataOptions; +}; + +#ifdef DOXYGEN_GENERATING_OUTPUT +/** @debugoperatorclassenum{Magnum::Attribute,Magnum::Attribute::Components} */ +template Debug operator<<(Debug debug, Attribute::Components); + +/** @debugoperatorclassenum{Magnum::Attribute,Magnum::Attribute::DataType} */ +template Debug operator<<(Debug debug, Attribute::DataType); +#endif + +namespace Implementation { + +/* Base for sized attributes */ +template struct SizedAttribute; + +/* Vector attribute sizes */ +template struct SizedVectorAttribute { + enum: UnsignedInt { VectorCount = UnsignedInt(cols) }; +}; +template<> struct SizedAttribute<1, 1>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1 }; + constexpr static Components DefaultComponents = Components::One; +}; +template<> struct SizedAttribute<1, 2>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2 }; + constexpr static Components DefaultComponents = Components::Two; +}; +template<> struct SizedAttribute<1, 3>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2, Three = 3 }; + constexpr static Components DefaultComponents = Components::Three; +}; +template<> struct SizedAttribute<1, 4>: SizedVectorAttribute<1> { + enum class Components: GLint { One = 1, Two = 2, Three = 3, Four = 4 }; + constexpr static Components DefaultComponents = Components::Four; +}; +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 1>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 2>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 3>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedAttribute<1, 4>::Components value); + +/* Matrix attribute sizes */ +template struct SizedMatrixAttribute; +template<> struct SizedMatrixAttribute<2> { + enum class Components: GLint { Two = 2 }; + constexpr static Components DefaultComponents = Components::Two; +}; +template<> struct SizedMatrixAttribute<3> { + enum class Components: GLint { Three = 3 }; + constexpr static Components DefaultComponents = Components::Three; +}; +template<> struct SizedMatrixAttribute<4> { + enum class Components: GLint { Four = 4 }; + constexpr static Components DefaultComponents = Components::Four; +}; +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<2>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<3>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, SizedMatrixAttribute<4>::Components value); +template<> struct SizedAttribute<2, 2>: SizedVectorAttribute<2>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<3, 3>: SizedVectorAttribute<3>, SizedMatrixAttribute<3> {}; +template<> struct SizedAttribute<4, 4>: SizedVectorAttribute<4>, SizedMatrixAttribute<4> {}; +#ifndef MAGNUM_TARGET_GLES2 +template<> struct SizedAttribute<2, 3>: SizedVectorAttribute<2>, SizedMatrixAttribute<3> {}; +template<> struct SizedAttribute<3, 2>: SizedVectorAttribute<3>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<2, 4>: SizedVectorAttribute<2>, SizedMatrixAttribute<4> {}; +template<> struct SizedAttribute<4, 2>: SizedVectorAttribute<4>, SizedMatrixAttribute<2> {}; +template<> struct SizedAttribute<3, 4>: SizedVectorAttribute<3>, SizedMatrixAttribute<4> {}; +template<> struct SizedAttribute<4, 3>: SizedVectorAttribute<4>, SizedMatrixAttribute<3> {}; +#endif + +/* Base for attributes */ +template struct Attribute; + +/* Base for float attributes */ +struct FloatAttribute { + typedef Float ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE + #endif + }; + constexpr static DataType DefaultDataType = DataType::Float; + + enum class DataOption: UnsignedByte { + Normalized = 1 << 0 + }; + typedef Containers::EnumSet DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +CORRADE_ENUMSET_OPERATORS(FloatAttribute::DataOptions) + +Debug MAGNUM_EXPORT operator<<(Debug debug, FloatAttribute::DataType value); + +#ifndef MAGNUM_TARGET_GLES2 +/* Base for int attributes */ +struct IntAttribute { + typedef Int ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT + }; + constexpr static DataType DefaultDataType = DataType::Int; + + enum class DataOption: UnsignedByte {}; + typedef Containers::EnumSet DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +CORRADE_ENUMSET_OPERATORS(IntAttribute::DataOptions) + +Debug MAGNUM_EXPORT operator<<(Debug debug, IntAttribute::DataType value); + +/* Base for unsigned int attributes */ +struct UnsignedIntAttribute { + typedef UnsignedInt ScalarType; + + typedef IntAttribute::DataType DataType; + constexpr static DataType DefaultDataType = DataType::UnsignedInt; + + typedef IntAttribute::DataOption DataOption; + typedef IntAttribute::DataOptions DataOptions; + + static UnsignedInt size(GLint components, DataType dataType) { + return IntAttribute::size(components, dataType); + } +}; +#endif + +#ifndef MAGNUM_TARGET_GLES +/* Base for double attributes */ +struct DoubleAttribute { + typedef Double ScalarType; + + enum class DataType: GLenum { + Double = GL_DOUBLE + }; + constexpr static DataType DefaultDataType = DataType::Double; + + typedef IntAttribute::DataOption DataOption; + typedef IntAttribute::DataOptions DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, DoubleAttribute::DataType value); +#endif + +/* Floating-point three-component vector has additional data type compared to + classic floats */ +template<> struct Attribute>: SizedAttribute<1, 3> { + typedef Float ScalarType; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE, + UnsignedInt10f11f11fRev = GL_UNSIGNED_INT_10F_11F_11F_REV + #endif + }; + constexpr static DataType DefaultDataType = DataType::Float; + + typedef FloatAttribute::DataOption DataOption; + typedef FloatAttribute::DataOptions DataOptions; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); + +/* Floating-point four-component vector is absolutely special case */ +template<> struct Attribute> { + typedef Float ScalarType; + + enum class Components: GLint { + One = 1, + Two = 2, + Three = 3, + Four = 4 + #ifndef MAGNUM_TARGET_GLES + , + BGRA = GL_BGRA + #endif + }; + constexpr static Components DefaultComponents = Components::Four; + + enum class DataType: GLenum { + UnsignedByte = GL_UNSIGNED_BYTE, + Byte = GL_BYTE, + UnsignedShort = GL_UNSIGNED_SHORT, + Short = GL_SHORT, + UnsignedInt = GL_UNSIGNED_INT, + Int = GL_INT, + #ifndef MAGNUM_TARGET_GLES2 + HalfFloat = GL_HALF_FLOAT, + #else + HalfFloat = GL_HALF_FLOAT_OES, + #endif + Float = GL_FLOAT + #ifndef MAGNUM_TARGET_GLES + , + Double = GL_DOUBLE + #endif + #ifndef MAGNUM_TARGET_GLES2 + , + UnsignedInt2101010Rev = GL_UNSIGNED_INT_2_10_10_10_REV, + Int2101010Rev = GL_INT_2_10_10_10_REV + #endif + }; + constexpr static DataType DefaultDataType = DataType::Float; + + typedef FloatAttribute::DataOption DataOption; + typedef FloatAttribute::DataOptions DataOptions; + + enum: UnsignedInt { VectorCount = 1 }; + + static UnsignedInt MAGNUM_EXPORT size(GLint components, DataType dataType); +}; + +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::Components value); +Debug MAGNUM_EXPORT operator<<(Debug debug, Attribute>::DataType value); + +/* Common float, int, unsigned int and double scalar attributes */ +template<> struct Attribute: FloatAttribute, SizedAttribute<1, 1> {}; +#ifndef MAGNUM_TARGET_GLES2 +template<> struct Attribute: IntAttribute, SizedAttribute<1, 1> {}; +template<> struct Attribute: UnsignedIntAttribute, SizedAttribute<1, 1> {}; +#ifndef MAGNUM_TARGET_GLES +template<> struct Attribute: DoubleAttribute, SizedAttribute<1, 1> {}; +#endif +#endif + +/* Common float, int, unsigned int and double vector attributes */ +template struct Attribute>: FloatAttribute, SizedAttribute<1, size_> {}; +#ifndef MAGNUM_TARGET_GLES2 +template struct Attribute>: IntAttribute, SizedAttribute<1, size_> {}; +template struct Attribute>: UnsignedIntAttribute, SizedAttribute<1, size_> {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: DoubleAttribute, SizedAttribute<1, size_> {}; +#endif +#endif +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; + +/* Common float and double rectangular matrix attributes */ +template struct Attribute>: FloatAttribute, SizedAttribute {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: DoubleAttribute, SizedAttribute {}; +#endif + +/* Common float and double square matrix attributes */ +template struct Attribute>: Attribute> {}; +#ifndef MAGNUM_TARGET_GLES +template struct Attribute>: Attribute> {}; +#endif +template struct Attribute>: Attribute> {}; +template struct Attribute>: Attribute> {}; + +} + +} + +#endif diff --git a/src/Magnum/CMakeLists.txt b/src/Magnum/CMakeLists.txt index fd3306071..bee8b9878 100644 --- a/src/Magnum/CMakeLists.txt +++ b/src/Magnum/CMakeLists.txt @@ -34,6 +34,7 @@ set(Magnum_SRCS AbstractQuery.cpp AbstractTexture.cpp AbstractShaderProgram.cpp + Attribute.cpp Buffer.cpp ColorFormat.cpp CubeMapTexture.cpp @@ -89,6 +90,7 @@ set(Magnum_HEADERS AbstractShaderProgram.h AbstractTexture.h Array.h + Attribute.h Buffer.h Color.h ColorFormat.h diff --git a/src/Magnum/DebugTools/ResourceManager.cpp b/src/Magnum/DebugTools/ResourceManager.cpp index 0103133e5..bc21ef540 100644 --- a/src/Magnum/DebugTools/ResourceManager.cpp +++ b/src/Magnum/DebugTools/ResourceManager.cpp @@ -27,6 +27,7 @@ #include "ResourceManager.h" +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Mesh.h" #include "Magnum/MeshView.h" diff --git a/src/Magnum/Implementation/MeshState.h b/src/Magnum/Implementation/MeshState.h index 9095a6ff0..95b0bbc6c 100644 --- a/src/Magnum/Implementation/MeshState.h +++ b/src/Magnum/Implementation/MeshState.h @@ -39,7 +39,7 @@ struct MeshState { void(Mesh::*createImplementation)(); void(Mesh::*destroyImplementation)(); - void(Mesh::*attributePointerImplementation)(const Mesh::Attribute&); + void(Mesh::*attributePointerImplementation)(const Mesh::GenericAttribute&); #ifndef MAGNUM_TARGET_GLES2 void(Mesh::*attributeIPointerImplementation)(const Mesh::IntegerAttribute&); #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/Magnum.h b/src/Magnum/Magnum.h index 74380a20d..112937e3b 100644 --- a/src/Magnum/Magnum.h +++ b/src/Magnum/Magnum.h @@ -454,6 +454,8 @@ template class Array1D; template class Array2D; template class Array3D; +template class Attribute; + enum class BufferUsage: GLenum; class Buffer; diff --git a/src/Magnum/Mesh.cpp b/src/Magnum/Mesh.cpp index 0eb6a22a5..fd5756dab 100644 --- a/src/Magnum/Mesh.cpp +++ b/src/Magnum/Mesh.cpp @@ -27,6 +27,7 @@ #include +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Context.h" #include "Magnum/Extensions.h" @@ -207,6 +208,18 @@ Mesh& Mesh::setIndexBuffer(Buffer& buffer, GLintptr offset, IndexType type, Unsi return *this; } +void Mesh::draw(AbstractShaderProgram& shader) { + shader.use(); + + #ifndef MAGNUM_TARGET_GLES + drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd); + #elif !defined(MAGNUM_TARGET_GLES2) + drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd); + #else + drawInternal(_count, _baseVertex, _instanceCount, _indexOffset); + #endif +} + #ifndef MAGNUM_TARGET_GLES void Mesh::drawInternal(Int count, Int baseVertex, Int instanceCount, UnsignedInt baseInstance, GLintptr indexOffset, Int indexStart, Int indexEnd) #elif !defined(MAGNUM_TARGET_GLES2) @@ -365,11 +378,11 @@ void Mesh::destroyImplementationVAO() { #endif } -void Mesh::attributePointerInternal(const Attribute& attribute) { +void Mesh::attributePointerInternal(const GenericAttribute& attribute) { (this->*Context::current()->state().mesh->attributePointerImplementation)(attribute); } -void Mesh::attributePointerImplementationDefault(const Attribute& attribute) { +void Mesh::attributePointerImplementationDefault(const GenericAttribute& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -378,7 +391,7 @@ void Mesh::attributePointerImplementationDefault(const Attribute& attribute) { _attributes.push_back(attribute); } -void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { +void Mesh::attributePointerImplementationVAO(const GenericAttribute& attribute) { #if defined(CORRADE_TARGET_NACL) || defined(MAGNUM_TARGET_WEBGL) CORRADE_ASSERT(attribute.buffer->targetHint() == Buffer::TargetHint::Array, "Mesh::addVertexBuffer(): the buffer has unexpected target hint, expected" << Buffer::TargetHint::Array << "but got" << attribute.buffer->targetHint(), ); @@ -389,7 +402,7 @@ void Mesh::attributePointerImplementationVAO(const Attribute& attribute) { } #ifndef MAGNUM_TARGET_GLES -void Mesh::attributePointerImplementationDSAEXT(const Attribute& attribute) { +void Mesh::attributePointerImplementationDSAEXT(const GenericAttribute& attribute) { _created = true; glEnableVertexArrayAttribEXT(_id, attribute.location); glVertexArrayVertexAttribOffsetEXT(_id, attribute.buffer->id(), attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.offset); @@ -397,7 +410,7 @@ void Mesh::attributePointerImplementationDSAEXT(const Attribute& attribute) { } #endif -void Mesh::vertexAttribPointer(const Attribute& attribute) { +void Mesh::vertexAttribPointer(const GenericAttribute& attribute) { glEnableVertexAttribArray(attribute.location); attribute.buffer->bindInternal(Buffer::TargetHint::Array); glVertexAttribPointer(attribute.location, attribute.size, attribute.type, attribute.normalized, attribute.stride, reinterpret_cast(attribute.offset)); @@ -516,7 +529,7 @@ void Mesh::bindIndexBufferImplementationVAO(Buffer& buffer) { void Mesh::bindImplementationDefault() { /* Specify vertex attributes */ - for(const Attribute& attribute: _attributes) + for(const GenericAttribute& attribute: _attributes) vertexAttribPointer(attribute); #ifndef MAGNUM_TARGET_GLES2 @@ -538,7 +551,7 @@ void Mesh::bindImplementationVAO() { } void Mesh::unbindImplementationDefault() { - for(const Attribute& attribute: _attributes) + for(const GenericAttribute& attribute: _attributes) glDisableVertexAttribArray(attribute.location); #ifndef MAGNUM_TARGET_GLES2 diff --git a/src/Magnum/Mesh.h b/src/Magnum/Mesh.h index fbae5fe19..950fbac62 100644 --- a/src/Magnum/Mesh.h +++ b/src/Magnum/Mesh.h @@ -30,9 +30,11 @@ */ #include +#include #include -#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/AbstractObject.h" +#include "Magnum/Attribute.h" namespace Magnum { @@ -125,9 +127,8 @@ namespace Implementation { struct MeshState; } You have to specify at least primitive and vertex/index count using @ref setPrimitive() and @ref setCount(). Then fill your vertex buffers with -data, add them to the mesh and specify -@ref AbstractShaderProgram::Attribute "shader attribute" layout inside the -buffers using @ref addVertexBuffer(). You can also use +data, add them to the mesh and specify @ref Attribute "shader attribute" layout +inside the buffers using @ref addVertexBuffer(). You can also use @ref MeshTools::interleave() to conveniently interleave vertex data. If you want indexed mesh, fill your index buffer with data and specify its @@ -640,7 +641,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * @return Reference to self (for method chaining) * * Parameter @p offset is offset of the array from the beginning, - * attribute list is combination of @ref AbstractShaderProgram::Attribute "attribute definitions" + * attribute list is combination of @ref Attribute "attribute definitions" * (specified in implementation of given shader) and offsets between * interleaved attributes. * @@ -807,17 +808,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { * @fn_gl{DrawElementsInstancedBaseVertex}/ * @fn_gl{DrawElementsInstancedBaseVertexBaseInstance} */ - void draw(AbstractShaderProgram& shader) { - shader.use(); - - #ifndef MAGNUM_TARGET_GLES - drawInternal(_count, _baseVertex, _instanceCount, _baseInstance, _indexOffset, _indexStart, _indexEnd); - #elif !defined(MAGNUM_TARGET_GLES2) - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset, _indexStart, _indexEnd); - #else - drawInternal(_count, _baseVertex, _instanceCount, _indexOffset); - #endif - } + void draw(AbstractShaderProgram& shader); void draw(AbstractShaderProgram&& shader) { draw(shader); } /**< @overload */ @@ -840,7 +831,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { private: #ifndef DOXYGEN_GENERATING_OUTPUT - struct MAGNUM_LOCAL Attribute { + struct MAGNUM_LOCAL GenericAttribute { Buffer* buffer; GLuint location; GLint size; @@ -881,8 +872,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { Mesh& setLabelInternal(Containers::ArrayReference label); /* Computing stride of interleaved vertex attributes */ - template static GLsizei strideOfInterleaved(const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { - return attribute.vectorSize()*AbstractShaderProgram::Attribute::VectorCount + strideOfInterleaved(attributes...); + template static GLsizei strideOfInterleaved(const Attribute& attribute, const U&... attributes) { + return attribute.vectorSize()*Attribute::VectorCount + strideOfInterleaved(attributes...); } template static GLsizei strideOfInterleaved(GLintptr gap, const T&... attributes) { return gap + strideOfInterleaved(attributes...); @@ -890,11 +881,11 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { static GLsizei strideOfInterleaved() { return 0; } /* Adding interleaved vertex attributes */ - template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, const AbstractShaderProgram::Attribute& attribute, const U&... attributes) { + template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, const Attribute& attribute, const U&... attributes) { addVertexAttribute(buffer, attribute, offset, stride, divisor); /* Add size of this attribute to offset for next attribute */ - addVertexBufferInternal(buffer, offset+attribute.vectorSize()*AbstractShaderProgram::Attribute::VectorCount, stride, divisor, attributes...); + addVertexBufferInternal(buffer, offset+attribute.vectorSize()*Attribute::VectorCount, stride, divisor, attributes...); } template void addVertexBufferInternal(Buffer& buffer, GLintptr offset, GLsizei stride, GLuint divisor, GLintptr gap, const T&... attributes) { /* Add the gap to offset for next attribute */ @@ -902,14 +893,14 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } void addVertexBufferInternal(Buffer&, GLsizei, GLuint, GLintptr) {} - template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { - for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute::VectorCount; ++i) - attributePointerInternal(Attribute{ + template void addVertexAttribute(typename std::enable_if::ScalarType, Float>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) + attributePointerInternal(GenericAttribute{ &buffer, location+i, GLint(attribute.components()), GLenum(attribute.dataType()), - bool(attribute.dataOptions() & AbstractShaderProgram::Attribute::DataOption::Normalized), + bool(attribute.dataOptions() & Attribute::DataOption::Normalized), GLintptr(offset+i*attribute.vectorSize()), stride, divisor @@ -917,7 +908,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES2 - template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + template void addVertexAttribute(typename std::enable_if::ScalarType>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { attributePointerInternal(IntegerAttribute{ &buffer, location, @@ -930,8 +921,8 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { } #ifndef MAGNUM_TARGET_GLES - template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const AbstractShaderProgram::Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { - for(UnsignedInt i = 0; i != AbstractShaderProgram::Attribute::VectorCount; ++i) + template void addVertexAttribute(typename std::enable_if::ScalarType, Double>::value, Buffer&>::type buffer, const Attribute& attribute, GLintptr offset, GLsizei stride, GLuint divisor) { + for(UnsignedInt i = 0; i != Attribute::VectorCount; ++i) attributePointerInternal(LongAttribute{ &buffer, location+i, @@ -964,13 +955,13 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { void MAGNUM_LOCAL destroyImplementationDefault(); void MAGNUM_LOCAL destroyImplementationVAO(); - void attributePointerInternal(const Attribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationDefault(const Attribute& attribute); - void MAGNUM_LOCAL attributePointerImplementationVAO(const Attribute& attribute); + void attributePointerInternal(const GenericAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDefault(const GenericAttribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationVAO(const GenericAttribute& attribute); #ifndef MAGNUM_TARGET_GLES - void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const Attribute& attribute); + void MAGNUM_LOCAL attributePointerImplementationDSAEXT(const GenericAttribute& attribute); #endif - void MAGNUM_LOCAL vertexAttribPointer(const Attribute& attribute); + void MAGNUM_LOCAL vertexAttribPointer(const GenericAttribute& attribute); #ifndef MAGNUM_TARGET_GLES2 void attributePointerInternal(const IntegerAttribute& attribute); @@ -1029,7 +1020,7 @@ class MAGNUM_EXPORT Mesh: public AbstractObject { IndexType _indexType; Buffer* _indexBuffer; - std::vector _attributes; + std::vector _attributes; #ifndef MAGNUM_TARGET_GLES2 std::vector _integerAttributes; #ifndef MAGNUM_TARGET_GLES diff --git a/src/Magnum/MeshTools/FullScreenTriangle.cpp b/src/Magnum/MeshTools/FullScreenTriangle.cpp index b7ce1cc63..b218240d7 100644 --- a/src/Magnum/MeshTools/FullScreenTriangle.cpp +++ b/src/Magnum/MeshTools/FullScreenTriangle.cpp @@ -25,7 +25,7 @@ #include "FullScreenTriangle.h" -#include "Magnum/AbstractShaderProgram.h" +#include "Magnum/Attribute.h" #include "Magnum/Buffer.h" #include "Magnum/Context.h" #include "Magnum/Mesh.h" @@ -55,7 +55,7 @@ std::pair, Mesh> fullScreenTriangle(Version version) { buffer->setData(triangle, BufferUsage::StaticDraw); /** @todo Is it possible to attach moveable buffer here to avoid heap allocation? OTOH this is more effective in most (modern) cases */ - mesh.addVertexBuffer(*buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + mesh.addVertexBuffer(*buffer, 0, Attribute<0, Vector2>{}); } return {std::move(buffer), std::move(mesh)}; diff --git a/src/Magnum/MeshView.cpp b/src/Magnum/MeshView.cpp index 165edd4a3..bae0c4c9b 100644 --- a/src/Magnum/MeshView.cpp +++ b/src/Magnum/MeshView.cpp @@ -28,6 +28,7 @@ #include #include +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Context.h" #include "Magnum/Mesh.h" diff --git a/src/Magnum/Shaders/Generic.h b/src/Magnum/Shaders/Generic.h index 567fa6ab1..4b9ffc425 100644 --- a/src/Magnum/Shaders/Generic.h +++ b/src/Magnum/Shaders/Generic.h @@ -68,17 +68,17 @@ template struct Generic { * * Defined as @ref Vector2 in 2D and @ref Vector3 in 3D. */ - typedef AbstractShaderProgram::Attribute<0, T> Position; + typedef Attribute<0, T> Position; /** @brief 2D texture coordinates */ - typedef AbstractShaderProgram::Attribute<1, Vector2> TextureCoordinates; + typedef Attribute<1, Vector2> TextureCoordinates; /** * @brief Vertex normal * * Defined only in 3D. */ - typedef AbstractShaderProgram::Attribute<2, Vector3> Normal; + typedef Attribute<2, Vector3> Normal; }; #endif @@ -90,16 +90,16 @@ typedef Generic<3> Generic3D; #ifndef DOXYGEN_GENERATING_OUTPUT struct BaseGeneric { - typedef AbstractShaderProgram::Attribute<1, Vector2> TextureCoordinates; + typedef Attribute<1, Vector2> TextureCoordinates; }; template<> struct Generic<2>: BaseGeneric { - typedef AbstractShaderProgram::Attribute<0, Vector2> Position; + typedef Attribute<0, Vector2> Position; }; template<> struct Generic<3>: BaseGeneric { - typedef AbstractShaderProgram::Attribute<0, Vector3> Position; - typedef AbstractShaderProgram::Attribute<2, Vector3> Normal; + typedef Attribute<0, Vector3> Position; + typedef Attribute<2, Vector3> Normal; }; #endif diff --git a/src/Magnum/Test/AbstractShaderProgramTest.cpp b/src/Magnum/Test/AbstractShaderProgramTest.cpp index 77317bf1c..0aca06d57 100644 --- a/src/Magnum/Test/AbstractShaderProgramTest.cpp +++ b/src/Magnum/Test/AbstractShaderProgramTest.cpp @@ -75,7 +75,7 @@ AbstractShaderProgramTest::AbstractShaderProgramTest() { } void AbstractShaderProgramTest::attributeScalar() { - typedef AbstractShaderProgram::Attribute<3, Float> Attribute; + typedef Attribute<3, Float> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::Location, 3); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -95,7 +95,7 @@ void AbstractShaderProgramTest::attributeScalar() { void AbstractShaderProgramTest::attributeScalarInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Int> Attribute; + typedef Attribute<3, Int> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -113,7 +113,7 @@ void AbstractShaderProgramTest::attributeScalarInt() { void AbstractShaderProgramTest::attributeScalarUnsignedInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, UnsignedInt> Attribute; + typedef Attribute<3, UnsignedInt> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -131,7 +131,7 @@ void AbstractShaderProgramTest::attributeScalarUnsignedInt() { void AbstractShaderProgramTest::attributeScalarDouble() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Double> Attribute; + typedef Attribute<3, Double> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -144,7 +144,7 @@ void AbstractShaderProgramTest::attributeScalarDouble() { } void AbstractShaderProgramTest::attributeVector() { - typedef AbstractShaderProgram::Attribute<3, Vector3> Attribute; + typedef Attribute<3, Vector3> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -168,7 +168,7 @@ void AbstractShaderProgramTest::attributeVector() { void AbstractShaderProgramTest::attributeVectorInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Vector2i> Attribute; + typedef Attribute<3, Vector2i> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -188,7 +188,7 @@ void AbstractShaderProgramTest::attributeVectorInt() { void AbstractShaderProgramTest::attributeVectorUnsignedInt() { #ifndef MAGNUM_TARGET_GLES2 - typedef AbstractShaderProgram::Attribute<3, Vector4ui> Attribute; + typedef Attribute<3, Vector4ui> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -208,7 +208,7 @@ void AbstractShaderProgramTest::attributeVectorUnsignedInt() { void AbstractShaderProgramTest::attributeVectorDouble() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Vector2d> Attribute; + typedef Attribute<3, Vector2d> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -227,7 +227,7 @@ void AbstractShaderProgramTest::attributeVectorDouble() { } void AbstractShaderProgramTest::attributeVector4() { - typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute; + typedef Attribute<3, Vector4> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -243,7 +243,7 @@ void AbstractShaderProgramTest::attributeVector4() { void AbstractShaderProgramTest::attributeVectorBGRA() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Vector4> Attribute; + typedef Attribute<3, Vector4> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 1); @@ -256,7 +256,7 @@ void AbstractShaderProgramTest::attributeVectorBGRA() { } void AbstractShaderProgramTest::attributeMatrixNxN() { - typedef AbstractShaderProgram::Attribute<3, Matrix3> Attribute; + typedef Attribute<3, Matrix3> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 3); @@ -269,7 +269,7 @@ void AbstractShaderProgramTest::attributeMatrixNxN() { #ifndef MAGNUM_TARGET_GLES2 void AbstractShaderProgramTest::attributeMatrixMxN() { - typedef AbstractShaderProgram::Attribute<3, Matrix3x4> Attribute; + typedef Attribute<3, Matrix3x4> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 3); @@ -283,7 +283,7 @@ void AbstractShaderProgramTest::attributeMatrixMxN() { void AbstractShaderProgramTest::attributeMatrixNxNd() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Matrix4d> Attribute; + typedef Attribute<3, Matrix4d> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 4); @@ -299,7 +299,7 @@ void AbstractShaderProgramTest::attributeMatrixNxNd() { void AbstractShaderProgramTest::attributeMatrixMxNd() { #ifndef MAGNUM_TARGET_GLES - typedef AbstractShaderProgram::Attribute<3, Matrix4x2d> Attribute; + typedef Attribute<3, Matrix4x2d> Attribute; CORRADE_VERIFY((std::is_same{})); CORRADE_COMPARE(Attribute::VectorCount, 4); diff --git a/src/Magnum/Test/MeshGLTest.cpp b/src/Magnum/Test/MeshGLTest.cpp index a064dfe8b..dbea75921 100644 --- a/src/Magnum/Test/MeshGLTest.cpp +++ b/src/Magnum/Test/MeshGLTest.cpp @@ -23,6 +23,7 @@ DEALINGS IN THE SOFTWARE. */ +#include "Magnum/AbstractShaderProgram.h" #include "Magnum/Buffer.h" #include "Magnum/Color.h" #include "Magnum/ColorFormat.h" @@ -468,7 +469,7 @@ void MeshGLTest::addVertexBufferUnsignedInt() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedInt data[] = { 0, 157, 35681 }; Buffer buffer; @@ -493,7 +494,7 @@ void MeshGLTest::addVertexBufferInt() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr Int data[] = { 0, 457931, 27530 }; Buffer buffer; @@ -514,7 +515,7 @@ void MeshGLTest::addVertexBufferInt() { #endif void MeshGLTest::addVertexBufferFloat() { - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -543,7 +544,7 @@ void MeshGLTest::addVertexBufferDouble() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Double> Attribute; + typedef Attribute<0, Double> Attribute; const Double data[] = { 0.0, -0.7, Math::normalize(45828) }; Buffer buffer; @@ -570,7 +571,7 @@ void MeshGLTest::addVertexBufferVectorNui() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector3ui> Attribute; + typedef Attribute<0, Vector3ui> Attribute; constexpr Vector3ui data[] = { {}, {37448, 547686, 156}, {27592, 157, 25} }; Buffer buffer; @@ -595,7 +596,7 @@ void MeshGLTest::addVertexBufferVectorNi() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector2i> Attribute; + typedef Attribute<0, Vector2i> Attribute; constexpr Vector2i data[] = { {}, {-37448, 547686}, {27592, -157} }; Buffer buffer; @@ -616,7 +617,7 @@ void MeshGLTest::addVertexBufferVectorNi() { #endif void MeshGLTest::addVertexBufferVectorN() { - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; const Vector3 data[] = { {}, {0.0f, -0.9f, 1.0f}, Math::normalize(Color3ub(96, 24, 156)) }; Buffer buffer; @@ -645,7 +646,7 @@ void MeshGLTest::addVertexBufferVectorNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Vector4d> Attribute; + typedef Attribute<0, Vector4d> Attribute; const Vector4d data[] = { {}, {0.0, -0.9, 1.0, 1.25}, @@ -669,7 +670,7 @@ void MeshGLTest::addVertexBufferVectorNd() { #endif void MeshGLTest::addVertexBufferMatrixNxN() { - typedef AbstractShaderProgram::Attribute<0, Matrix3x3> Attribute; + typedef Attribute<0, Matrix3x3> Attribute; const Matrix3x3 data[] = { {}, @@ -698,7 +699,7 @@ void MeshGLTest::addVertexBufferMatrixNxNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Matrix3x3d> Attribute; + typedef Attribute<0, Matrix3x3d> Attribute; const Matrix3x3d data[] = { {}, @@ -731,7 +732,7 @@ void MeshGLTest::addVertexBufferMatrixNxNd() { #ifndef MAGNUM_TARGET_GLES2 void MeshGLTest::addVertexBufferMatrixMxN() { - typedef AbstractShaderProgram::Attribute<0, Matrix3x4> Attribute; + typedef Attribute<0, Matrix3x4> Attribute; const Matrix3x4 data[] = { {}, @@ -761,7 +762,7 @@ void MeshGLTest::addVertexBufferMatrixMxNd() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Matrix3x4d> Attribute; + typedef Attribute<0, Matrix3x4d> Attribute; const Matrix3x4d data[] = { {}, @@ -799,7 +800,7 @@ void MeshGLTest::addVertexBufferUnsignedIntWithUnsignedShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedShort data[] = { 0, 49563, 16583 }; Buffer buffer; @@ -824,7 +825,7 @@ void MeshGLTest::addVertexBufferUnsignedIntWithShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr Short data[] = { 0, 24563, 16583 }; Buffer buffer; @@ -849,7 +850,7 @@ void MeshGLTest::addVertexBufferIntWithUnsignedShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr UnsignedShort data[] = { 0, 49563, 16583 }; Buffer buffer; @@ -874,7 +875,7 @@ void MeshGLTest::addVertexBufferIntWithShort() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Int> Attribute; + typedef Attribute<0, Int> Attribute; constexpr Short data[] = { 0, 24563, -16583 }; Buffer buffer; @@ -903,7 +904,7 @@ void MeshGLTest::addVertexBufferFloatWithHalfFloat() { CORRADE_SKIP(Extensions::GL::OES::vertex_half_float::string() + std::string(" is not supported.")); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; Buffer buffer; buffer.setData({nullptr, 6}, BufferUsage::StaticDraw); @@ -918,7 +919,7 @@ void MeshGLTest::addVertexBufferFloatWithHalfFloat() { #ifndef MAGNUM_TARGET_GLES void MeshGLTest::addVertexBufferFloatWithDouble() { - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Double data[] = { 0.0, -0.7, Math::normalize(186) }; Buffer buffer; @@ -943,7 +944,7 @@ void MeshGLTest::addVertexBufferVector3WithUnsignedInt10f11f11fRev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_10f_11f_11f_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -964,7 +965,7 @@ void MeshGLTest::addVertexBufferVector4WithUnsignedInt2101010Rev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_2_10_10_10_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -983,7 +984,7 @@ void MeshGLTest::addVertexBufferVector4WithInt2101010Rev() { CORRADE_SKIP(Extensions::GL::ARB::vertex_type_2_10_10_10_rev::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; Buffer buffer; buffer.setData({nullptr, 12}, BufferUsage::StaticDraw); @@ -998,7 +999,7 @@ void MeshGLTest::addVertexBufferVector4WithInt2101010Rev() { #endif void MeshGLTest::addVertexBufferLessVectorComponents() { - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; const Vector3 data[] = { {}, {0.0f, -0.9f, 1.0f}, @@ -1026,7 +1027,7 @@ void MeshGLTest::addVertexBufferLessVectorComponents() { } void MeshGLTest::addVertexBufferNormalized() { - typedef AbstractShaderProgram::Attribute<0, Vector3> Attribute; + typedef Attribute<0, Vector3> Attribute; constexpr Color3ub data[] = { {}, {0, 128, 64}, {32, 156, 228} }; Buffer buffer; @@ -1057,7 +1058,7 @@ void MeshGLTest::addVertexBufferBGRA() { CORRADE_SKIP(Extensions::GL::ARB::vertex_array_bgra::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, Vector4> Attribute; + typedef Attribute<0, Vector4> Attribute; constexpr Color4ub data[] = { {}, {0, 128, 64, 161}, {96, 24, 156, 225} }; Buffer buffer; @@ -1385,7 +1386,7 @@ void MeshGLTest::setInstanceCount() { CORRADE_SKIP("Required extension is not available."); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -1463,7 +1464,7 @@ void MeshGLTest::setInstanceCountBaseInstance() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::base_instance::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; @@ -1604,7 +1605,7 @@ void MeshGLTest::addVertexBufferInstancedFloat() { CORRADE_SKIP("Required drawing extension is not available."); #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, /* Offset */ @@ -1645,7 +1646,7 @@ void MeshGLTest::addVertexBufferInstancedInteger() { CORRADE_SKIP(Extensions::GL::EXT::gpu_shader4::string() + std::string(" is not available.")); #endif - typedef AbstractShaderProgram::Attribute<0, UnsignedInt> Attribute; + typedef Attribute<0, UnsignedInt> Attribute; constexpr UnsignedInt data[] = { 0, /* Offset */ @@ -1680,7 +1681,7 @@ void MeshGLTest::addVertexBufferInstancedDouble() { if(!Context::current()->isExtensionSupported()) CORRADE_SKIP(Extensions::GL::ARB::vertex_attrib_64bit::string() + std::string(" is not available.")); - typedef AbstractShaderProgram::Attribute<0, Double> Attribute; + typedef Attribute<0, Double> Attribute; const Double data[] = { 0.0, /* Offset */ @@ -1760,7 +1761,7 @@ void MeshGLTest::multiDraw() { Debug() << Extensions::GL::EXT::multi_draw_arrays::string() << "not supported, using fallback implementation"; #endif - typedef AbstractShaderProgram::Attribute<0, Float> Attribute; + typedef Attribute<0, Float> Attribute; const Float data[] = { 0.0f, -0.7f, Math::normalize(96) }; Buffer buffer; diff --git a/src/Magnum/Test/SampleQueryGLTest.cpp b/src/Magnum/Test/SampleQueryGLTest.cpp index 6e87c9621..60b25c0f4 100644 --- a/src/Magnum/Test/SampleQueryGLTest.cpp +++ b/src/Magnum/Test/SampleQueryGLTest.cpp @@ -111,7 +111,7 @@ void SampleQueryGLTest::querySamplesPassed() { Mesh mesh; mesh.setPrimitive(MeshPrimitive::Triangles) .setCount(3) - .addVertexBuffer(buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + .addVertexBuffer(buffer, 0, Attribute<0, Vector2>{}); MyShader shader; @@ -160,7 +160,7 @@ void SampleQueryGLTest::conditionalRender() { Mesh mesh; mesh.setPrimitive(MeshPrimitive::Triangles) .setCount(3) - .addVertexBuffer(buffer, 0, AbstractShaderProgram::Attribute<0, Vector2>()); + .addVertexBuffer(buffer, 0, Attribute<0, Vector2>{}); MyShader shader; framebuffer.bind(FramebufferTarget::ReadDraw);