Browse Source

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().
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
8c92224ff8
  1. 29
      src/AbstractShaderProgram.h
  2. 6
      src/Mesh.h
  3. 4
      src/Shaders/PhongShader.cpp
  4. 7
      src/Shaders/PhongShader.h

29
src/AbstractShaderProgram.h

@ -31,14 +31,12 @@ namespace Magnum {
This class is designed to be used via subclassing. Subclasses define these
functions and properties:
- <strong>Attribute location</strong> enum with indexes where the particular
attribute is bound, for example:
- <strong>Attribute location</strong> 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<size_t i, class T> struct Attribute {
static const size_t Location = i; /**< Location to which the attribute is bound */
typedef T Type; /**< Attribute type */
};
/** @brief Default constructor */
AbstractShaderProgram();

6
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<class T> inline void bindAttribute(Buffer* buffer, GLuint attribute) {
bindAttribute(buffer, attribute, TypeTraits<T>::count(), TypeTraits<T>::glType());
template<class Attribute> inline void bindAttribute(Buffer* buffer) {
bindAttribute(buffer, Attribute::Location, TypeTraits<typename Attribute::Type>::count(), TypeTraits<typename Attribute::Type>::glType());
}
/**

4
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;

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

Loading…
Cancel
Save