From cb1c3f0b2b9ebc25f9924ab4a05952bdd2bcafe8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 26 Oct 2012 15:10:32 +0200 Subject: [PATCH] Preparation for type checked vertex attributes. Currently it was possible to pass e.g. five-component vector or 2x1 matrix to shader, we don't want that. --- src/AbstractShaderProgram.h | 47 +++++++++++++++ src/TypeTraits.h | 112 +++++++++++++++++++++++++++++++----- 2 files changed, 144 insertions(+), 15 deletions(-) diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index 41f05ac57..449afea09 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -203,6 +203,53 @@ specularTexture->bind(MyShader::SpecularTextureLayer); mesh.draw(); @endcode +@section AbstractShaderProgram-types Mapping between GLSL and Magnum types + +- `vec2`, `vec3` and `vec4` is @ref Math::Vector "Math::Vector<2, GLfloat>", + @ref Math::Vector "Math::Vector<3, GLfloat>" and + @ref Math::Vector "Math::Vector<4, GLfloat>". + +- `mat2`, `mat3` and `mat4` is @ref Math::Matrix "Math::Matrix<2, GLfloat>", + @ref Math::Matrix "Math::Matrix<3, GLfloat>" and + @ref Math::Matrix "Math::Matrix<4, GLfloat>". + +- `mat2x3`, `mat3x2`, `mat2x4`, `mat4x2`, `mat3x4`, `mat4x3` is + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLfloat>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLfloat>" and + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLfloat>". + +- `ivec2`, `ivec3` and `ivec4` is @ref Math::Vector "Math::Vector<2, GLint>", + @ref Math::Vector "Math::Vector<3, GLint>" and + @ref Math::Vector "Math::Vector<4, GLint>", `uvec2`, `uvec3` and `uvec4` is + @ref Math::Vector "Math::Vector<2, GLuint>", + @ref Math::Vector "Math::Vector<3, GLuint>" and + @ref Math::Vector "Math::Vector<4, GLuint>". + @requires_gl30 %Extension @extension{EXT,gpu_shader4} (for integer attributes) + @requires_gles30 Integer attributes are not supported in OpenGL ES 2.0. + +- `dvec2`, `dvec3` and `dvec4` is @ref Math::Vector "Math::Vector<2, GLdouble>", + @ref Math::Vector "Math::Vector<3, GLdouble>" and + @ref Math::Vector "Math::Vector<4, GLdouble>", `dmat2`, `dmat3` and `dmat4` + is @ref Math::Matrix "Math::Matrix<2, GLdouble>", + @ref Math::Matrix "Math::Matrix<3, GLdouble>" and + @ref Math::Matrix "Math::Matrix<4, GLdouble>", `dmat2x3`, `dmat3x2`, + `dmat2x4`, `dmat4x2`, `dmat3x4`, `dmat4x3` is + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 3, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 2, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<2, 4, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 2, GLdouble>", + @ref Math::RectangularMatrix "Math::RectangularMatrix<3, 4, GLdouble>" and + @ref Math::RectangularMatrix "Math::RectangularMatrix<4, 3, GLdouble>". + @requires_gl41 %Extension @extension{ARB,vertex_attrib_64bit} (for double attributes) + @requires_gl Double attributes are supported only on desktop OpenGL. + +Only types listed here (and their subclasses and specializations, such as +@ref Matrix3 or Color4) can be used for setting uniforms and specifying +vertex attributes. See also TypeTraits::AttributeType. + @section AbstractShaderProgram-performance-optimization Performance optimizations The engine tracks currently used shader program to avoid unnecessary calls to diff --git a/src/TypeTraits.h b/src/TypeTraits.h index 08da1bf09..ba53cb79b 100644 --- a/src/TypeTraits.h +++ b/src/TypeTraits.h @@ -25,8 +25,9 @@ namespace Magnum { namespace Math { - template class Vector; + template class RectangularMatrix; template class Matrix; + template class Vector; } template class Color3; @@ -42,6 +43,16 @@ OpenGL-specific traits. */ #ifdef DOXYGEN_GENERATING_OUTPUT template struct TypeTraits: public Math::MathTypeTraits { + /** + * @brief Corresponding type for vertex attributes + * + * Implemented only in types which can be used for vertex attributes. This + * function is not present for types unusable for vertex attributes, like + * five-component vectors or GLdouble in OpenGL ES. See also + * @ref AbstractShaderProgram-types. + */ + typedef U AttributeType; + /** * @brief OpenGL plain type ID * @@ -166,6 +177,7 @@ template<> struct TypeOf { typedef GLdouble Type; }; #endif template<> struct TypeTraits: public Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::UnsignedByte; } inline constexpr static Type indexType() { return Type::UnsignedByte; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedByte; } @@ -174,6 +186,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits }; template<> struct TypeTraits: public Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::Byte; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Byte; } @@ -182,6 +195,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits { }; template<> struct TypeTraits: public Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::UnsignedShort; } inline constexpr static Type indexType() { return Type::UnsignedShort; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedShort; } @@ -190,6 +204,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits struct TypeTraits: public Math::MathTypeTraits { + /* Can not be used for attributes */ inline constexpr static Type type() { return Type::Short; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Short; } @@ -198,6 +213,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits }; template<> struct TypeTraits: public Math::MathTypeTraits { + typedef GLuint AttributeType; inline constexpr static Type type() { return Type::UnsignedInt; } inline constexpr static Type indexType() { return Type::UnsignedInt; } inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::UnsignedInt; } @@ -206,6 +222,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits }; template<> struct TypeTraits: public Math::MathTypeTraits { + typedef GLint AttributeType; inline constexpr static Type type() { return Type::Int; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Int; } @@ -214,6 +231,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits { }; template<> struct TypeTraits: public Math::MathTypeTraits { + typedef GLfloat AttributeType; inline constexpr static Type type() { return Type::Float; } /* Can not be used for indices */ inline constexpr static AbstractImage::ComponentType imageType() { return AbstractImage::ComponentType::Float; } @@ -223,6 +241,7 @@ template<> struct TypeTraits: public Math::MathTypeTraits { #ifndef MAGNUM_TARGET_GLES template<> struct TypeTraits: public Math::MathTypeTraits { + typedef GLdouble AttributeType; inline constexpr static Type type() { return Type::Double; } /* Can not be used for indices */ /* Can not be used for images */ @@ -231,13 +250,45 @@ template<> struct TypeTraits: public Math::MathTypeTraits { }; #endif -template struct TypeTraits> { - inline constexpr static Type type() { return TypeTraits::type(); } - /* Can not be used for indices */ - /* Can not be used for images */ - inline constexpr static std::size_t size() { return sizeof(T); } - inline constexpr static std::size_t count() { return vectorSize; } -}; +namespace Implementation { + template struct VectorTypeTraits { + /* Might be used for attributes, see below */ + inline constexpr static Type type() { return TypeTraits::type(); } + /* Might be used for attributes, see below */ + /* Can not be used for indices */ + /* Can not be used for images */ + inline constexpr static std::size_t size() { return sizeof(T); } + inline constexpr static std::size_t count() { return vectorSize; } + }; + + template struct VectorAttributeType {}; + + template<> struct VectorAttributeType { + typedef GLuint AttributeType; + }; + + template<> struct VectorAttributeType { + typedef GLint AttributeType; + }; + + template<> struct VectorAttributeType { + typedef GLfloat AttributeType; + }; + + #ifndef MAGNUM_TARGET_GLES + template<> struct VectorAttributeType { + typedef GLdouble AttributeType; + }; + #endif +} + +template struct TypeTraits>: public Implementation::VectorTypeTraits {}; + +/* Only some vectors can be used as attributes */ +template struct TypeTraits>: Implementation::VectorTypeTraits<1, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<2, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<3, T>, Implementation::VectorAttributeType {}; +template struct TypeTraits>: Implementation::VectorTypeTraits<4, T>, Implementation::VectorAttributeType {}; template struct TypeTraits>: public TypeTraits> {}; template struct TypeTraits>: public TypeTraits> {}; @@ -247,13 +298,44 @@ template struct TypeTraits>: public TypeTraits struct TypeTraits>: public TypeTraits> {}; template struct TypeTraits>: public TypeTraits> {}; -template struct TypeTraits> { - inline constexpr static Type type() { return TypeTraits::type(); } - /* Can not be used for indices */ - /* Can not be used for images */ - inline constexpr static std::size_t size() { return sizeof(T); } - inline constexpr static std::size_t count() { return matrixSize*matrixSize; } -}; +namespace Implementation { + template struct MatrixTypeTraits { + inline constexpr static Type type() { return TypeTraits::type(); } + /* Might be used for attributes, see below */ + /* Can not be used for indices */ + /* Can not be used for images */ + inline constexpr static std::size_t size() { return sizeof(T); } + inline constexpr static std::size_t count() { return rows; } + inline constexpr static std::size_t vectors() { return cols; } + }; + + template struct MatrixAttributeType {}; + + template<> struct MatrixAttributeType { + typedef GLfloat AttributeType; + }; + + #ifndef MAGNUM_TARGET_GLES + template<> struct MatrixAttributeType { + typedef GLdouble AttributeType; + }; + #endif +} + +template struct TypeTraits>: public Implementation::MatrixTypeTraits {}; + +/* Only some floating-point matrices can be used as attributes */ +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 3, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 3, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<2, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 2, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<3, 4, T>, Implementation::MatrixAttributeType {}; +template struct TypeTraits>: Implementation::MatrixTypeTraits<4, 3, T>, Implementation::MatrixAttributeType {}; + +template struct TypeTraits>: TypeTraits> {}; template struct TypeTraits>: public TypeTraits> {}; template struct TypeTraits>: public TypeTraits> {};