diff --git a/src/AbstractShaderProgram.cpp b/src/AbstractShaderProgram.cpp index 4fd606973..47ea3eeb4 100644 --- a/src/AbstractShaderProgram.cpp +++ b/src/AbstractShaderProgram.cpp @@ -50,6 +50,11 @@ void AbstractShaderProgram::bindFragmentDataLocation(GLuint location, const std: glBindFragDataLocation(program, location, name.c_str()); } +void AbstractShaderProgram::bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name) { + CORRADE_ASSERT(state == Initialized, "AbstractShaderProgram: fragment data location cannot be bound after linking.", ); + + glBindFragDataLocationIndexed(program, location, index, name.c_str()); +} #endif void AbstractShaderProgram::link() { diff --git a/src/AbstractShaderProgram.h b/src/AbstractShaderProgram.h index d15c2aeb9..d08447345 100644 --- a/src/AbstractShaderProgram.h +++ b/src/AbstractShaderProgram.h @@ -39,6 +39,8 @@ typedef Attribute<0, Vector4> Vertex; typedef Attribute<1, Vector3> Normal; typedef Attribute<2, Vector2> TextureCoords; @endcode + @todoc Output attribute location (for bindFragmentDataLocationIndexed(), + referenced also from Framebuffer::mapDefaultForDraw() / Framebuffer::mapForDraw()) - **Layers for texture uniforms** to which the textures will be bound before rendering, for example: @code @@ -82,18 +84,27 @@ layout(location = 0) in vec4 vertex; layout(location = 1) in vec3 normal; layout(location = 2) in vec2 textureCoords; @endcode +Similarly for ouput attributes, you can also specify blend equation color +index for them (see Framebuffer::BlendFunction for more information about +using color input index): +@code +layout(location = 0, index = 0) out vec4 color; +layout(location = 1, index = 1) out vec4 ambient; +@endcode @requires_gl (for explicit input attribute location instead of using bindAttributeLocation()) @requires_gl (for explicit output attribute location or using - bindFragmentDataLocation()) + bindFragmentDataLocation() / bindFragmentDataLocationIndexed()) @requires_gl30 Extension @extension{EXT,gpu_shader4} (for using bindFragmentDataLocation()) +@requires_gl33 Extension @extension{ARB,blend_func_extended} (for using + bindFragmentDataLocationIndexed()) @requires_gl33 Extension @extension{ARB,explicit_attrib_location} (for explicit attribute location instead of using bindAttributeLocation()) If you don't have the required extension, you can use functions bindAttributeLocation() -and bindFragmentDataLocation() between attaching of shaders and linking the -program: +and bindFragmentDataLocation() / bindFragmentDataLocationIndexed() between +attaching the shaders and linking the program: @code // Shaders attached... @@ -101,6 +112,9 @@ bindAttributeLocation(Vertex::Location, "vertex"); bindAttributeLocation(Normal::Location, "normal"); bindAttributeLocation(TextureCoords::Location, "textureCoords"); +bindFragmentDataLocationIndexed(0, 0, "color"); +bindFragmentDataLocationIndexed(1, 1, "ambient"); + // Link... @endcode @@ -249,16 +263,32 @@ class MAGNUM_EXPORT AbstractShaderProgram { #ifndef MAGNUM_TARGET_GLES /** - * @brief Bind fragment data to given location + * @brief Bind fragment data to given location and color input index * @param location Location * @param name Fragment output variable name + * @param index Blend equation color input index (`0` or `1`) * + * Binds fragment data to location which is used later for framebuffer + * operations. See also Framebuffer::BlendFunction for more + * information about using color input index. + * @requires_gl + * @requires_gl33 Extension @extension{ARB,blend_func_extended} * @note This function should be called after attachShader() calls and * before link(). * @deprecated Preferred usage is to specify attribute location * explicitly in the shader instead of using this function. See * @ref AbstractShaderProgram-attribute-location "class documentation" * for more information. + */ + void bindFragmentDataLocationIndexed(GLuint location, GLuint index, const std::string& name); + + /** + * @brief Bind fragment data to given location and first color input index + * @param location Location + * @param name Fragment output variable name + * + * The same as bindFragmentDataLocationIndexed(), but with `index` set + * to `0`. * @requires_gl * @requires_gl30 Extension @extension{EXT,gpu_shader4} */