From 7376e8f36d5e024ce99465f461c99e64eac2629c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 4 Feb 2014 16:07:00 +0100 Subject: [PATCH] Use functions to bind textures to shader rather than *Texture::bind(). Why did I do this: * It is more clean, shorter and nice looking with method chaining, i.e. instead of: shader.setColor(...) .setOtherParam(5); texture1.bind(MyShader::Texture1Layer); texture2.bind(MyShader::Texture2Layer); We now have this: shader.setColor(...) .setOtherParam(5) .setTexture1(texture1) .setTexture2(texture2); * It is now also clear which texture type is expected, the layer constant did not say anything about type. * Also it is possible to use new features (multi bind, bindless textures etc.) while preserving the same public API. The only potential disadvantage is that the textures don't stay bound like uniform values do, but this become a non-issue with bindless textures. As usual, the old way is now deprecated and will be removed in some future release. --- src/Magnum/AbstractShaderProgram.h | 36 ++++++++-------- src/Magnum/AbstractTexture.h | 11 +++-- src/Magnum/BufferTexture.h | 9 ++-- src/Magnum/CubeMapTexture.h | 11 +++-- src/Magnum/CubeMapTextureArray.h | 5 +-- src/Magnum/MultisampleTexture.h | 3 +- src/Magnum/RectangleTexture.h | 7 ++-- src/Magnum/ResourceManager.h | 2 +- src/Magnum/Shaders/AbstractVector.cpp | 43 +++++++++++++++++++ src/Magnum/Shaders/AbstractVector.h | 18 +++++++- src/Magnum/Shaders/CMakeLists.txt | 1 + src/Magnum/Shaders/DistanceFieldVector.h | 8 ++++ src/Magnum/Shaders/Flat.cpp | 8 ++++ src/Magnum/Shaders/Flat.h | 33 +++++++++------ src/Magnum/Shaders/Phong.cpp | 24 +++++++++++ src/Magnum/Shaders/Phong.h | 51 ++++++++++++++++++----- src/Magnum/Shaders/Vector.h | 8 ++++ src/Magnum/Text/Renderer.h | 12 +++--- src/Magnum/Texture.h | 3 +- src/Magnum/TextureArray.h | 3 +- src/Magnum/TextureTools/DistanceField.cpp | 16 +++---- 21 files changed, 230 insertions(+), 82 deletions(-) create mode 100644 src/Magnum/Shaders/AbstractVector.cpp diff --git a/src/Magnum/AbstractShaderProgram.h b/src/Magnum/AbstractShaderProgram.h index 7cdd763ae..925345bc0 100644 --- a/src/Magnum/AbstractShaderProgram.h +++ b/src/Magnum/AbstractShaderProgram.h @@ -63,14 +63,6 @@ enum: UnsignedInt { NormalOutput = 1 }; @endcode -- **Layers for texture uniforms** to which the textures will be bound before - rendering, for example: -@code -enum: Int { - DiffuseTextureLayer = 0, - SpecularTextureLayer = 1 -}; -@endcode - **Uniform locations** for setting uniform data (see below) (private variables), for example: @code @@ -111,6 +103,18 @@ MyShader& setProjection(const Matrix4& matrix) { return *this; } @endcode +- **Texture setting functions** in which you bind the textures to particular + layers using @ref AbstractTexture::bind() and equivalent, for example: +@code +MyShader& setDiffuseTexture(Texture2D& texture) { + texture->bind(0); + return *this; +} +MyShader& setSpecularTexture(Texture2D& texture) { + texture->bind(1); + return *this; +} +@endcode @subsection AbstractShaderProgram-attribute-location Binding attribute location @@ -230,8 +234,8 @@ uniform sampler2D diffuseTexture; uniform sampler2D specularTexture; @endcode @code -setUniform(DiffuseTextureUniform, DiffuseTextureLayer); -setUniform(SpecularTextureUniform, SpecularTextureLayer); +setUniform(DiffuseTextureUniform, 0); +setUniform(SpecularTextureUniform, 1); @endcode @see @ref Shader::maxTextureImageUnits() @@ -248,15 +252,13 @@ Basic workflow with %AbstractShaderProgram subclasses is: instance shader class, configure attribute binding in meshes (see @ref Mesh-configuration "Mesh documentation" for more information) and map shader outputs to framebuffer attachments if needed (see @ref Framebuffer-usage "Framebuffer documentation" for more -information). In each draw event set uniforms, bind specific framebuffer (if -needed) and bind required textures to their respective layers using -@ref AbstractTexture::bind(Int). Then call @ref Mesh::draw(). Example: +information). In each draw event set all required shader parameters, bind +specific framebuffer (if needed) and then call @ref Mesh::draw(). Example: @code shader.setTransformation(transformation) - .setProjection(projection); - -diffuseTexture.bind(MyShader::DiffuseTextureLayer); -specularTexture.bind(MyShader::SpecularTextureLayer); + .setProjection(projection) + .setDiffuseTexture(diffuseTexture) + .setSpecularTexture(specularTexture); mesh.draw(shader); @endcode diff --git a/src/Magnum/AbstractTexture.h b/src/Magnum/AbstractTexture.h index 5e41dc1d3..a13211979 100644 --- a/src/Magnum/AbstractTexture.h +++ b/src/Magnum/AbstractTexture.h @@ -208,10 +208,13 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject { /** * @brief Bind texture for rendering * - * Sets current texture as active in given layer. The layer must be - * between 0 and @ref maxLayers(). Note that only one texture can be - * bound to given layer. If @extension{EXT,direct_state_access} is not - * available, the layer is made active before binding the texture. + * Sets current texture as active in given layer. Note that only one + * texture can be bound to given layer. If @extension{EXT,direct_state_access} + * is not available, the layer is made active before binding the + * texture. + * @note This function is meant to be used only internally from + * @ref AbstractShaderProgram subclasses. See its documentation + * for more information. * @see @ref maxLayers(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} */ diff --git a/src/Magnum/BufferTexture.h b/src/Magnum/BufferTexture.h index d80dd0722..a8a891d26 100644 --- a/src/Magnum/BufferTexture.h +++ b/src/Magnum/BufferTexture.h @@ -181,11 +181,10 @@ constexpr static Vector3 data[] = { buffer.setData(data, BufferUsage::StaticDraw); @endcode -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `samplerBuffer`, `isamplerBuffer` or `usamplerBuffer`. -Unlike in classic textures, coordinates for buffer textures are integer -coordinates passed to `texelFetch()`. See also @ref AbstractShaderProgram -documentation for more information. +In shader, the texture is used via `samplerBuffer`, `isamplerBuffer` or +`usamplerBuffer`. Unlike in classic textures, coordinates for buffer textures +are integer coordinates passed to `texelFetch()`. See @ref AbstractShaderProgram +documentation for more information about usage in shaders. @section BufferTexture-performance-optimization Performance optimizations diff --git a/src/Magnum/CubeMapTexture.h b/src/Magnum/CubeMapTexture.h index 8db6acaf7..7b2ce1363 100644 --- a/src/Magnum/CubeMapTexture.h +++ b/src/Magnum/CubeMapTexture.h @@ -69,12 +69,11 @@ texture.setMagnificationFilter(Sampler::Filter::Linear) // ... @endcode -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `samplerCube`, `samplerCubeShadow`, `isamplerCube` or -`usamplerCube`. Unlike in classic textures, coordinates for cube map textures -is signed three-part vector from the center of the cube, which intersects one -of the six sides of the cube map. See also @ref AbstractShaderProgram for more -information about usage in shaders. +In shader, the texture is used via `samplerCube`, `samplerCubeShadow`, +`isamplerCube` or `usamplerCube`. Unlike in classic textures, coordinates for +cube map textures is signed three-part vector from the center of the cube, +which intersects one of the six sides of the cube map. See +@ref AbstractShaderProgram for more information about usage in shaders. @see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTextureArray, @ref Texture, @ref BufferTexture diff --git a/src/Magnum/CubeMapTextureArray.h b/src/Magnum/CubeMapTextureArray.h index a22b89ece..22cc837cc 100644 --- a/src/Magnum/CubeMapTextureArray.h +++ b/src/Magnum/CubeMapTextureArray.h @@ -67,12 +67,11 @@ for(std::size_t i = 0; i != 4; i += 6) { texture.generateMipmap(); @endcode -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `samplerCubeArray`, `samplerCubeArrayShadow`, +In shader, the texture is used via `samplerCubeArray`, `samplerCubeArrayShadow`, `isamplerCubeArray` or `usamplerCubeArray`. Unlike in classic textures, coordinates for cube map texture arrays is signed four-part vector. First three parts define vector from the center of the cube which intersects with one of -the six sides of the cube map, fourth part is layer in the array. See also +the six sides of the cube map, fourth part is layer in the array. See @ref AbstractShaderProgram for more information about usage in shaders. @see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTexture, diff --git a/src/Magnum/MultisampleTexture.h b/src/Magnum/MultisampleTexture.h index cff1c1d2b..97c986b6d 100644 --- a/src/Magnum/MultisampleTexture.h +++ b/src/Magnum/MultisampleTexture.h @@ -52,8 +52,7 @@ also @ref AbstractTexture documentation for more information. @todoc Finish when fully implemented -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `sampler2DMS`/`sampler2DMSArray`, +In shader, the texture is used via `sampler2DMS`/`sampler2DMSArray`, `isampler2DMS`/`isampler2DMSArray` or `usampler2DMS`/`usampler2DMSArray`. See @ref AbstractShaderProgram documentation for more information about usage in shaders. diff --git a/src/Magnum/RectangleTexture.h b/src/Magnum/RectangleTexture.h index d31f4d02f..2d8c76c6c 100644 --- a/src/Magnum/RectangleTexture.h +++ b/src/Magnum/RectangleTexture.h @@ -59,10 +59,9 @@ texture.setMagnificationFilter(Sampler::Filter::Linear) .setSubImage({}, image); @endcode -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via sampler2DRect`, `sampler2DRectShadow`, `isampler2DRect` -or `usampler2DRect`. See @ref AbstractShaderProgram documentation for more -information about usage in shaders. +In shader, the texture is used via sampler2DRect`, `sampler2DRectShadow`, +`isampler2DRect` or `usampler2DRect`. See @ref AbstractShaderProgram +documentation for more information about usage in shaders. @requires_gl31 %Extension @extension{ARB,texture_rectangle} @requires_gl Rectangle textures are not available in OpenGL ES. diff --git a/src/Magnum/ResourceManager.h b/src/Magnum/ResourceManager.h index 56e7479f4..1030abc0f 100644 --- a/src/Magnum/ResourceManager.h +++ b/src/Magnum/ResourceManager.h @@ -212,7 +212,7 @@ if(!cube) { @endcode - Using the resource data. @code -texture->bind(layer); +shader->setTexture(layer); cube->draw(*shader); @endcode - Destroying resource references and deleting manager instance when nothing diff --git a/src/Magnum/Shaders/AbstractVector.cpp b/src/Magnum/Shaders/AbstractVector.cpp new file mode 100644 index 000000000..e06d09cc9 --- /dev/null +++ b/src/Magnum/Shaders/AbstractVector.cpp @@ -0,0 +1,43 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013, 2014 + Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "AbstractVector.h" + +#include "Magnum/Texture.h" +#include "Magnum/Shaders/visibility.h" + +namespace Magnum { namespace Shaders { + +template AbstractVector& AbstractVector::setVectorTexture(Texture2D& texture) { + texture.bind(VectorTextureLayer); + return *this; +} + +#ifndef DOXYGEN_GENERATING_OUTPUT +template class MAGNUM_SHADERS_EXPORT AbstractVector<2>; +template class MAGNUM_SHADERS_EXPORT AbstractVector<3>; +#endif + +}} diff --git a/src/Magnum/Shaders/AbstractVector.h b/src/Magnum/Shaders/AbstractVector.h index b32be523b..fea2df38f 100644 --- a/src/Magnum/Shaders/AbstractVector.h +++ b/src/Magnum/Shaders/AbstractVector.h @@ -46,13 +46,29 @@ template class AbstractVector: public AbstractShaderProg /** @brief Texture coordinates */ typedef typename Generic::TextureCoordinates TextureCoordinates; + #ifdef MAGNUM_BUILD_DEPRECATED enum: Int { - VectorTextureLayer = 16 /**< Layer for vector texture */ + /** + * Layer for vector texture + * @deprecated Use @ref Magnum::Shaders::AbstractVector::setVectorTexture() "setVectorTexture()" instead. + */ + VectorTextureLayer = 16 }; + #endif + + /** + * @brief Set vector texture + * @return Reference to self (for method chaining) + */ + AbstractVector& setVectorTexture(Texture2D& texture); protected: explicit AbstractVector() = default; ~AbstractVector() = default; + + #ifndef MAGNUM_BUILD_DEPRECATED + enum: Int { VectorTextureLayer = 16 }; + #endif }; /** @brief Base for two-dimensional text shaders */ diff --git a/src/Magnum/Shaders/CMakeLists.txt b/src/Magnum/Shaders/CMakeLists.txt index 90714d0b4..0405f7529 100644 --- a/src/Magnum/Shaders/CMakeLists.txt +++ b/src/Magnum/Shaders/CMakeLists.txt @@ -26,6 +26,7 @@ corrade_add_resource(MagnumShaders_RCS resources.conf) set(MagnumShaders_SRCS + AbstractVector.cpp DistanceFieldVector.cpp Flat.cpp MeshVisualizer.cpp diff --git a/src/Magnum/Shaders/DistanceFieldVector.h b/src/Magnum/Shaders/DistanceFieldVector.h index de8316074..f81ce05b4 100644 --- a/src/Magnum/Shaders/DistanceFieldVector.h +++ b/src/Magnum/Shaders/DistanceFieldVector.h @@ -116,6 +116,14 @@ template class MAGNUM_SHADERS_EXPORT DistanceFieldVector return *this; } + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Overloads to remove WTF-factor from method chaining order */ + DistanceFieldVector& setVectorTexture(Texture2D& texture) { + AbstractVector::setVectorTexture(texture); + return *this; + } + #endif + private: Int transformationProjectionMatrixUniform, colorUniform, diff --git a/src/Magnum/Shaders/Flat.cpp b/src/Magnum/Shaders/Flat.cpp index 0fab460cb..b70085413 100644 --- a/src/Magnum/Shaders/Flat.cpp +++ b/src/Magnum/Shaders/Flat.cpp @@ -30,10 +30,13 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" #include "Magnum/Shader.h" +#include "Magnum/Texture.h" namespace Magnum { namespace Shaders { namespace { + enum: Int { TextureLayer = 0 }; + template constexpr const char* vertexShaderName(); template<> constexpr const char* vertexShaderName<2>() { return "Flat2D.vert"; } template<> constexpr const char* vertexShaderName<3>() { return "Flat3D.vert"; } @@ -96,6 +99,11 @@ template Flat::Flat(const Flags flags): tran #endif } +template Flat& Flat::setTexture(Texture2D& texture) { + if(_flags & Flag::Textured) texture.bind(TextureLayer); + return *this; +} + template class Flat<2>; template class Flat<3>; diff --git a/src/Magnum/Shaders/Flat.h b/src/Magnum/Shaders/Flat.h index ffbc7c4d6..e64afdd2a 100644 --- a/src/Magnum/Shaders/Flat.h +++ b/src/Magnum/Shaders/Flat.h @@ -52,15 +52,9 @@ need to provide @ref Position attribute in your triangle mesh and call at least If you want to use texture instead of color, you need to provide also @ref TextureCoordinates attribute. Pass @ref Flag::Textured to constructor and -then at render time bind the texture to its respective layer instead of calling -@ref setColor(). Example: -@code -Shaders::Flat2D shader(Shaders::Flat2D::Flag::Textured); - -// ... - -myTexture.bind(Shaders::Flat2D::TextureLayer); -@endcode +then at render time don't forget to set also the texture via @ref setTexture(). +The texture will be multiplied with the color (which is white by default, thus +it doesn't change texture color). For coloring the texture based on intensity you can use the @ref Vector shader. @see @ref Flat2D, @ref Flat3D @@ -77,10 +71,15 @@ template class MAGNUM_SHADERS_EXPORT Flat: public Abstra */ typedef typename Generic::TextureCoordinates TextureCoordinates; + #ifdef MAGNUM_BUILD_DEPRECATED enum: Int { - /** Layer for color texture. Used only if @ref Flag::Textured is set. */ + /** + * Layer for color texture. Used only if @ref Flag::Textured is set. + * @deprecated use @ref Magnum::Shaders::Flat::setTexture() "setTexture()" instead. + */ TextureLayer = 0 }; + #endif #ifdef DOXYGEN_GENERATING_OUTPUT /** @@ -125,11 +124,21 @@ template class MAGNUM_SHADERS_EXPORT Flat: public Abstra * @brief Set color * @return Reference to self (for method chaining) * - * Color will be multiplied with texture - * if @ref Flag::Textured is set. + * If not set, default value is fully opaque white. Color will be + * multiplied with texture if @ref Flag::Textured is set. + * @see @ref setTexture() */ Flat& setColor(const Color4& color); + /** + * @brief Set texture + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::Textured is set. + * @see @ref setColor() + */ + Flat& setTexture(Texture2D& texture); + private: Int transformationProjectionMatrixUniform, colorUniform; diff --git a/src/Magnum/Shaders/Phong.cpp b/src/Magnum/Shaders/Phong.cpp index feb810a6c..bb88002c3 100644 --- a/src/Magnum/Shaders/Phong.cpp +++ b/src/Magnum/Shaders/Phong.cpp @@ -30,9 +30,18 @@ #include "Magnum/Context.h" #include "Magnum/Extensions.h" #include "Magnum/Shader.h" +#include "Magnum/Texture.h" namespace Magnum { namespace Shaders { +namespace { + enum: Int { + AmbientTextureLayer = 0, + DiffuseTextureLayer = 1, + SpecularTextureLayer = 2 + }; +} + Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatrixUniform(1), normalMatrixUniform(2), lightUniform(3), diffuseColorUniform(4), ambientColorUniform(5), specularColorUniform(6), lightColorUniform(7), shininessUniform(8), _flags(flags) { Utility::Resource rs("MagnumShaders"); @@ -105,4 +114,19 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri #endif } +Phong& Phong::setAmbientTexture(Texture2D& texture) { + if(_flags & Flag::AmbientTexture) texture.bind(AmbientTextureLayer); + return *this; +} + +Phong& Phong::setDiffuseTexture(Texture2D& texture) { + if(_flags & Flag::DiffuseTexture) texture.bind(DiffuseTextureLayer); + return *this; +} + +Phong& Phong::setSpecularTexture(Texture2D& texture) { + if(_flags & Flag::SpecularTexture) texture.bind(SpecularTextureLayer); + return *this; +} + }} diff --git a/src/Magnum/Shaders/Phong.h b/src/Magnum/Shaders/Phong.h index 42bff2819..d864c2aad 100644 --- a/src/Magnum/Shaders/Phong.h +++ b/src/Magnum/Shaders/Phong.h @@ -46,15 +46,8 @@ call at least @ref setTransformationMatrix(), @ref setNormalMatrix(), If you want to use texture instead of color, you need to provide also @ref TextureCoordinates attribute. Pass appropriate flags to constructor and -then at render time bind the texture to its respective layer instead of setting -the color. Example: -@code -Shaders::Phong shader(Shaders::Phong::Flag::DiffuseTexture); - -// ... - -myDiffuseTexture.bind(Shaders::Phong::DiffuseTextureLayer); -@endcode +then at render time don't forget to also call appropriate subset of +@ref setAmbientTexture(), @ref setDiffuseTexture() and @ref setSpecularTexture(). */ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { public: @@ -69,25 +62,33 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { */ typedef Generic3D::TextureCoordinates TextureCoordinates; + #ifdef MAGNUM_BUILD_DEPRECATED enum: Int { /** * Layer for ambient texture. Used only if @ref Flag::AmbientTexture * is set. + * @deprecated Use @ref Magnum::Shaders::Phong::setAmbientTexture() "setAmbientTexture()" + * instead. */ AmbientTextureLayer = 0, /** * Layer for diffuse texture. Used only if @ref Flag::DiffuseTexture * is set. + * @deprecated Use @ref Magnum::Shaders::Phong::setDiffuseTexture() "setDiffuseTexture()" + * instead. */ DiffuseTextureLayer = 1, /** * Layer for specular texture. Used only if @ref Flag::SpecularTexture * is set. + * @deprecated Use @ref Magnum::Shaders::Phong::setSpecularTexture() "setSpecularTexture()" + * instead. */ SpecularTextureLayer = 2 }; + #endif /** * @brief Shader flag @@ -122,26 +123,56 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { * * If not set, default value is `(0.0f, 0.0f, 0.0f)`. Has no effect if * @ref Flag::AmbientTexture is set. + * @see @ref setAmbientTexture() */ Phong& setAmbientColor(const Color3& color); + /** + * @brief Set ambient texture + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::AmbientTexture is set. + * @see @ref setAmbientColor() + */ + Phong& setAmbientTexture(Texture2D& texture); + /** * @brief Set diffuse color * @return Reference to self (for method chaining) * - * Has no effect if @ref Flag::AmbientTexture is used. + * Has no effect if @ref Flag::DiffuseTexture is used. + * @see @ref setDiffuseTexture() */ Phong& setDiffuseColor(const Color3& color); + /** + * @brief Set diffuse texture + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::DiffuseTexture is set. + * @see @ref setDiffuseColor() + */ + Phong& setDiffuseTexture(Texture2D& texture); + /** * @brief Set specular color * @return Reference to self (for method chaining) * * If not set, default value is `(1.0f, 1.0f, 1.0f)`. Has no effect if * @ref Flag::SpecularTexture is set. + * @see @ref setSpecularTexture() */ Phong& setSpecularColor(const Color3& color); + /** + * @brief Set specular texture + * @return Reference to self (for method chaining) + * + * Has effect only if @ref Flag::SpecularTexture is set. + * @see @ref setSpecularColor() + */ + Phong& setSpecularTexture(Texture2D& texture); + /** * @brief Set shininess * @return Reference to self (for method chaining) diff --git a/src/Magnum/Shaders/Vector.h b/src/Magnum/Shaders/Vector.h index 72d934183..ae73cf8d0 100644 --- a/src/Magnum/Shaders/Vector.h +++ b/src/Magnum/Shaders/Vector.h @@ -82,6 +82,14 @@ template class MAGNUM_SHADERS_EXPORT Vector: public Abst return *this; } + #ifndef DOXYGEN_GENERATING_OUTPUT + /* Overloads to remove WTF-factor from method chaining order */ + Vector& setVectorTexture(Texture2D& texture) { + AbstractVector::setVectorTexture(texture); + return *this; + } + #endif + private: Int transformationProjectionMatrixUniform, backgroundColorUniform, diff --git a/src/Magnum/Text/Renderer.h b/src/Magnum/Text/Renderer.h index 58dad37ab..d9bdcc6ae 100644 --- a/src/Magnum/Text/Renderer.h +++ b/src/Magnum/Text/Renderer.h @@ -173,8 +173,8 @@ depends on features supported by particular font and its layouter. Immutable text (e.g. menu items, credits) can be simply rendered using static methods, returning result either as data arrays or as fully configured mesh. -The text can be then drawn by configuring text shader, binding font texture -and drawing the mesh: +The text can be then drawn as usual by configuring the shader and drawing the +mesh: @code Text::AbstractFont* font; Text::GlyphCache cache; @@ -190,8 +190,8 @@ std::tie(mesh, rectangle) = Text::Renderer2D::render(*font, cache, 0.15f, // Draw white text centered on the screen shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f)) - .setColor(Color3(1.0f)); -glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); + .setColor(Color3(1.0f)) + .setVectorTexture(glyphCache->texture()); mesh.draw(shader); @endcode See @ref render(AbstractFont&, const GlyphCache&, Float, const std::string&, Alignment) and @@ -215,8 +215,8 @@ renderer.render("Hello World Countdown: 10"); // Draw the text centered on the screen shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f)) - .setColor(Color3(1.0f)); -glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); + .setColor(Color3(1.0f)) + .setVectorTexture(glyphCache->texture()); renderer.mesh().draw(shader); @endcode diff --git a/src/Magnum/Texture.h b/src/Magnum/Texture.h index e4e5d8169..5551e8f88 100644 --- a/src/Magnum/Texture.h +++ b/src/Magnum/Texture.h @@ -82,8 +82,7 @@ texture.setMagnificationFilter(Sampler::Filter::Linear) @ref setMinificationFilter(), explicitly specify all mip levels with @ref setStorage() and @ref setImage() or call @ref generateMipmap(). -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `sampler1D`/`sampler2D`/`sampler3D`, +In shader, the texture is used via `sampler1D`/`sampler2D`/`sampler3D`, `sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`, `isampler1D`/`isampler2D`/`isampler3D` or `usampler1D`/`usampler2D`/`usampler3D`. See @ref AbstractShaderProgram documentation for more information about usage diff --git a/src/Magnum/TextureArray.h b/src/Magnum/TextureArray.h index e4653dae6..412bf6503 100644 --- a/src/Magnum/TextureArray.h +++ b/src/Magnum/TextureArray.h @@ -82,8 +82,7 @@ for(std::size_t i = 0; i != 16; ++i) { @ref setMinificationFilter(), explicitly specify all mip levels with @ref setStorage() and @ref setImage() or call @ref generateMipmap(). -The texture is bound to layer specified by shader via @ref bind(). In shader, -the texture is used via `sampler1DArray`/`sampler2DArray`, +In shader, the texture is used via `sampler1DArray`/`sampler2DArray`, `sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray` or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram documentation for more information about usage in shaders. diff --git a/src/Magnum/TextureTools/DistanceField.cpp b/src/Magnum/TextureTools/DistanceField.cpp index 21d9d247b..a68959db2 100644 --- a/src/Magnum/TextureTools/DistanceField.cpp +++ b/src/Magnum/TextureTools/DistanceField.cpp @@ -45,10 +45,6 @@ class DistanceFieldShader: public AbstractShaderProgram { public: typedef Attribute<0, Vector2> Position; - enum: Int { - TextureLayer = 8 - }; - explicit DistanceFieldShader(); DistanceFieldShader& setRadius(Int radius) { @@ -66,7 +62,14 @@ class DistanceFieldShader: public AbstractShaderProgram { return *this; } + DistanceFieldShader& setTexture(Texture2D& texture) { + texture.bind(TextureLayer); + return *this; + } + private: + enum: Int { TextureLayer = 8 }; + Int radiusUniform, scalingUniform, imageSizeInvertedUniform; @@ -162,9 +165,8 @@ void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangl DistanceFieldShader shader; shader.setRadius(radius) - .setScaling(Vector2(imageSize)/Vector2(rectangle.size())); - - input.bind(DistanceFieldShader::TextureLayer); + .setScaling(Vector2(imageSize)/Vector2(rectangle.size())) + .setTexture(input); #ifndef MAGNUM_TARGET_GLES if(!Context::current()->isVersionSupported(Version::GL300))