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();