Browse Source

Deprecating AbstractShaderProgram::bind*Location().

Preferred workflow is to specify attribute location explicitly in the
shader. The functions remains here as some old Intel systems don't
support the required extension ARB_explicit_attrib_location (and it's
not in GL 3.0 either). Also updated and fixed the documentation.

Function bindAttribute() was renamed to bindAttributeLocation() to be
consistent with bindFragmentDataLocation().

PhongShader now uses explicit attribute location.
pull/279/head
Vladimír Vondruš 14 years ago
parent
commit
e868d8e03c
  1. 2
      src/AbstractShaderProgram.cpp
  2. 72
      src/AbstractShaderProgram.h
  3. 3
      src/Shaders/PhongShader.cpp
  4. 4
      src/Shaders/PhongShader.vert

2
src/AbstractShaderProgram.cpp

@ -38,7 +38,7 @@ bool AbstractShaderProgram::attachShader(Shader& shader) {
return true; return true;
} }
void AbstractShaderProgram::bindAttribute(GLuint location, const string& name) { void AbstractShaderProgram::bindAttributeLocation(GLuint location, const string& name) {
CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: attribute cannot be bound after linking.", ) CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: attribute cannot be bound after linking.", )
glBindAttribLocation(program, location, name.c_str()); glBindAttribLocation(program, location, name.c_str());

72
src/AbstractShaderProgram.h

@ -30,6 +30,8 @@ namespace Magnum {
/** /**
@brief Base class for shaders @brief Base class for shaders
@section AbstractShaderProgramSubclassing Subclassing workflow
This class is designed to be used via subclassing. Subclasses define these This class is designed to be used via subclassing. Subclasses define these
functions and properties: functions and properties:
- **Attribute location** typedefs defining locations and types for attribute - **Attribute location** typedefs defining locations and types for attribute
@ -39,19 +41,13 @@ typedef Attribute<0, Vector4> Vertex;
typedef Attribute<1, Vector3> Normal; typedef Attribute<1, Vector3> Normal;
typedef Attribute<2, Vector2> TextureCoords; typedef Attribute<2, Vector2> TextureCoords;
@endcode @endcode
See also bindAttribute(). - **Constructor**, which attaches particular shaders, links the program and
- **Constructor**, which attaches particular shaders, links the program, gets uniform locations, for example:
binds attribute locations and gets uniform locations, for example:
@code @code
// Load shaders from file and attach them to the program // Load shaders from file and attach them to the program
attachShader(Shader::fromFile(Shader::Vertex, "PhongShader.vert")); attachShader(Shader::fromFile(Shader::Vertex, "PhongShader.vert"));
attachShader(Shader::fromFile(Shader::Fragment, "PhongShader.frag")); attachShader(Shader::fromFile(Shader::Fragment, "PhongShader.frag"));
// Bind attribute names to IDs
bindAttribute(Vertex::Location, "vertex");
bindAttribute(Normal::Location, "normal");
bindAttribute(TextureCoords::Location, "textureCoords");
// Link // Link
link(); link();
@ -61,28 +57,43 @@ projectionMatrixUniform = uniformLocation("projectionMatrix");
// more uniforms like light location, colors etc. // more uniforms like light location, colors etc.
@endcode @endcode
- **Uniform binding functions**, which set shader uniforms using - **Uniform binding functions**, which set shader uniforms using
setUniform() and setUniformArray() functions. Example: setUniform() functions. Example:
@code @code
void setTransformationMatrixUniform(const Matrix4& matrix) { void setTransformationMatrixUniform(const Matrix4& matrix) {
setUniform(transformationMatrixUniform, matrix); setUniform(transformationMatrixUniform, matrix);
} }
@endcode @endcode
Basic workflow with AbstractShaderProgram subclasses is: instancing the class @subsection AbstractShaderProgramAttributeLocation Binding attribute location
(once at the beginning), then in every frame calling use(), setting uniforms The preferred workflow is to specify attribute location for vertex shader
and calling Mesh::draw() (see its documentation for more). input attributes and fragment shader output attributes explicitly in the
shader code, e.g.:
@code
layout(location = 0) in vec4 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec2 textureCoords;
@endcode
@requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for
explicit attribute location instead of using bindAttributeLocation())
@section MultipleFragmentOutputs Multiple fragment shader outputs If you don't have the required extension, you can use functions bindAttributeLocation()
If your shader uses multiple fragment outputs, you can use and bindFragmentDataLocation() between attaching of shaders and linking the
bindFragmentDataLocation() *before linking* to bind their names to desired program:
location, e.g.:
@code @code
bindFragmentDataLocation(0, "color"); // Shaders attached...
bindAttributeLocation(Vertex::Location, "vertex");
bindAttributeLocation(Normal::Location, "normal");
bindAttributeLocation(TextureCoords::Location, "textureCoords");
// Link...
@endcode @endcode
You should then clearly state in the documentation which output is on what @section AbstractShaderProgramRenderingWorkflow Rendering workflow
position, so the user can set framebuffer attachments for them using
Framebuffer::mapForDraw() or Framebuffer::mapDefaultForDraw(). Basic workflow with AbstractShaderProgram subclasses is: instancing the class
(once at the beginning), then in every frame calling use(), setting uniforms
and calling Mesh::draw() (see its documentation for more).
@todo Uniform arrays support @todo Uniform arrays support
@ -152,19 +163,27 @@ class MAGNUM_EXPORT AbstractShaderProgram {
* @param name Attribute name * @param name Attribute name
* *
* Binds attribute to location which is be used later for binding * Binds attribute to location which is be used later for binding
* vertex buffers. * vertex buffers. Preferred usage is to
* @note This function should be called between loadShader() calls * @note This function should be called between attachShader() calls
* and link(). * and link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgramAttributeLocation "class documentation"
* for more information.
*/ */
void bindAttribute(GLuint location, const std::string& name); void bindAttributeLocation(GLuint location, const std::string& name);
/** /**
* @brief Bind fragment data to given location * @brief Bind fragment data to given location
* @param location Location * @param location Location
* @param name Fragment output variable name * @param name Fragment output variable name
* *
* @note This function should be called between loadShader() calls * @note This function should be called between attachShader() calls
* and link(). * and link().
* @deprecated Preferred usage is to specify attribute location
* explicitly in the shader instead of using this function. See
* @ref AbstractShaderProgramAttributeLocation "class documentation"
* for more information.
* *
* @requires_gl30 Extension @extension{EXT,gpu_shader4} * @requires_gl30 Extension @extension{EXT,gpu_shader4}
*/ */
@ -212,7 +231,6 @@ class MAGNUM_EXPORT AbstractShaderProgram {
glUniform4fv(location, 1, value.data()); glUniform4fv(location, 1, value.data());
} }
/** @copydoc setUniform(GLint, GLfloat) */ /** @copydoc setUniform(GLint, GLfloat) */
inline void setUniform(GLint location, GLint value) { inline void setUniform(GLint location, GLint value) {
glUniform1i(location, value); glUniform1i(location, value);

3
src/Shaders/PhongShader.cpp

@ -24,9 +24,6 @@ PhongShader::PhongShader() {
attachShader(Shader::fromData(Shader::Type::Vertex, rs.get("PhongShader.vert"))); attachShader(Shader::fromData(Shader::Type::Vertex, rs.get("PhongShader.vert")));
attachShader(Shader::fromData(Shader::Type::Fragment, rs.get("PhongShader.frag"))); attachShader(Shader::fromData(Shader::Type::Fragment, rs.get("PhongShader.frag")));
bindAttribute(Vertex::Location, "vertex");
bindAttribute(Normal::Location, "normal");
link(); link();
ambientColorUniform = uniformLocation("ambientColor"); ambientColorUniform = uniformLocation("ambientColor");

4
src/Shaders/PhongShader.vert

@ -4,8 +4,8 @@ uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix; uniform mat4 projectionMatrix;
uniform vec3 light; uniform vec3 light;
in vec4 vertex; layout(location = 0) in vec4 vertex;
in vec3 normal; layout(location = 1) in vec3 normal;
out vec3 transformedNormal; out vec3 transformedNormal;
out vec3 lightDirection; out vec3 lightDirection;

Loading…
Cancel
Save