From 8c92224ff8d34503b0924a009afc516965143d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 3 Mar 2012 04:03:41 +0100 Subject: [PATCH] Type-safe shader attributes. Now the data type is part of attribute definition, so user doesn't have to guess / look up what data should be there when binding with Mesh::bindAttribute(). --- src/AbstractShaderProgram.h | 29 +++++++++++++++++++---------- src/Mesh.h | 6 +++--- src/Shaders/PhongShader.cpp | 4 ++-- src/Shaders/PhongShader.h | 7 ++----- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index b993db513..32c54e49d 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -31,14 +31,12 @@ namespace Magnum { This class is designed to be used via subclassing. Subclasses define these functions and properties: - - Attribute location enum with indexes where the particular - attribute is bound, for example: + - Attribute location typedefs defining locations and types + for attribute binding with Mesh::bindAttribute(), for example: @code -enum Attribute { - Vertex = 0, - Normal = 1, - TextureCoords = 2 -}; +typedef Attribute<0, Vector4> Vertex; +typedef Attribute<1, Vector3> Normal; +typedef Attribute<2, Vector2> TextureCoords; @endcode See also bindAttribute(). - @b Constructor, which attaches particular shaders, links the program, binds @@ -51,9 +49,9 @@ enum Attribute { attachShader(fragmentShader); // Bind attribute names to IDs - bindAttribute(Vertex, "vertex"); - bindAttribute(Normal, "normal"); - bindAttribute(TextureCoords, "textureCoords"); + bindAttribute(Vertex::Location, "vertex"); + bindAttribute(Normal::Location, "normal"); + bindAttribute(TextureCoords::Location, "textureCoords"); // Link, then delete now uneeded shaders link(); @@ -84,6 +82,17 @@ class MAGNUM_EXPORT AbstractShaderProgram { AbstractShaderProgram& operator=(AbstractShaderProgram&& other) = delete; public: + /** + * @brief Base struct for attribute location and type + * + * See AbstractShaderProgram documentation or Mesh::bindAttribute() + * for an example. + */ + template struct Attribute { + static const size_t Location = i; /**< Location to which the attribute is bound */ + typedef T Type; /**< Attribute type */ + }; + /** @brief Default constructor */ AbstractShaderProgram(); diff --git a/src/Mesh.h b/src/Mesh.h index 1af71fc1d..7745b617a 100644 --- a/src/Mesh.h +++ b/src/Mesh.h @@ -162,17 +162,17 @@ class MAGNUM_EXPORT Mesh { /** * @brief Bind attribute + * @tparam attribute Attribute, defined in the shader * @param buffer Buffer where bind the attribute to (pointer * returned by addBuffer()) - * @param attribute Attribute * * Binds attribute of given type with given buffer. If the attribute is * already bound, given buffer isn't managed with this mesh (wasn't * initialized with addBuffer) or the mesh was already drawn, the * function does nothing. */ - template inline void bindAttribute(Buffer* buffer, GLuint attribute) { - bindAttribute(buffer, attribute, TypeTraits::count(), TypeTraits::glType()); + template inline void bindAttribute(Buffer* buffer) { + bindAttribute(buffer, Attribute::Location, TypeTraits::count(), TypeTraits::glType()); } /** diff --git a/src/Shaders/PhongShader.cpp b/src/Shaders/PhongShader.cpp index ebec7e61d..299f1bc4b 100644 --- a/src/Shaders/PhongShader.cpp +++ b/src/Shaders/PhongShader.cpp @@ -28,8 +28,8 @@ PhongShader::PhongShader() { attachShader(vertexShader); attachShader(fragmentShader); - bindAttribute(Vertex, "vertex"); - bindAttribute(Normal, "normal"); + bindAttribute(Vertex::Location, "vertex"); + bindAttribute(Normal::Location, "normal"); link(); delete vertexShader; diff --git a/src/Shaders/PhongShader.h b/src/Shaders/PhongShader.h index 2e347b26a..7c3f5331e 100644 --- a/src/Shaders/PhongShader.h +++ b/src/Shaders/PhongShader.h @@ -26,11 +26,8 @@ namespace Magnum { namespace Shaders { /** @brief Phong shader */ class PhongShader: public AbstractShaderProgram { public: - /** @brief Attribute */ - enum Attribute { - Vertex = 0, /**< @brief Vertex position (four-component vector) */ - Normal = 1 /**< @brief Normal direction (three-component vector) */ - }; + typedef Attribute<0, Vector4> Vertex; /**< @brief Vertex position */ + typedef Attribute<1, Vector3> Normal; /**< @brief Normal direction */ /** @brief Constructor */ PhongShader();