Browse Source

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.
pull/51/head
Vladimír Vondruš 12 years ago
parent
commit
7376e8f36d
  1. 36
      src/Magnum/AbstractShaderProgram.h
  2. 11
      src/Magnum/AbstractTexture.h
  3. 9
      src/Magnum/BufferTexture.h
  4. 11
      src/Magnum/CubeMapTexture.h
  5. 5
      src/Magnum/CubeMapTextureArray.h
  6. 3
      src/Magnum/MultisampleTexture.h
  7. 7
      src/Magnum/RectangleTexture.h
  8. 2
      src/Magnum/ResourceManager.h
  9. 43
      src/Magnum/Shaders/AbstractVector.cpp
  10. 18
      src/Magnum/Shaders/AbstractVector.h
  11. 1
      src/Magnum/Shaders/CMakeLists.txt
  12. 8
      src/Magnum/Shaders/DistanceFieldVector.h
  13. 8
      src/Magnum/Shaders/Flat.cpp
  14. 33
      src/Magnum/Shaders/Flat.h
  15. 24
      src/Magnum/Shaders/Phong.cpp
  16. 51
      src/Magnum/Shaders/Phong.h
  17. 8
      src/Magnum/Shaders/Vector.h
  18. 12
      src/Magnum/Text/Renderer.h
  19. 3
      src/Magnum/Texture.h
  20. 3
      src/Magnum/TextureArray.h
  21. 16
      src/Magnum/TextureTools/DistanceField.cpp

36
src/Magnum/AbstractShaderProgram.h

@ -63,14 +63,6 @@ enum: UnsignedInt {
NormalOutput = 1 NormalOutput = 1
}; };
@endcode @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 - **Uniform locations** for setting uniform data (see below) (private
variables), for example: variables), for example:
@code @code
@ -111,6 +103,18 @@ MyShader& setProjection(const Matrix4& matrix) {
return *this; return *this;
} }
@endcode @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 @subsection AbstractShaderProgram-attribute-location Binding attribute location
@ -230,8 +234,8 @@ uniform sampler2D diffuseTexture;
uniform sampler2D specularTexture; uniform sampler2D specularTexture;
@endcode @endcode
@code @code
setUniform(DiffuseTextureUniform, DiffuseTextureLayer); setUniform(DiffuseTextureUniform, 0);
setUniform(SpecularTextureUniform, SpecularTextureLayer); setUniform(SpecularTextureUniform, 1);
@endcode @endcode
@see @ref Shader::maxTextureImageUnits() @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" class, configure attribute binding in meshes (see @ref Mesh-configuration "Mesh documentation"
for more information) and map shader outputs to framebuffer attachments if for more information) and map shader outputs to framebuffer attachments if
needed (see @ref Framebuffer-usage "Framebuffer documentation" for more needed (see @ref Framebuffer-usage "Framebuffer documentation" for more
information). In each draw event set uniforms, bind specific framebuffer (if information). In each draw event set all required shader parameters, bind
needed) and bind required textures to their respective layers using specific framebuffer (if needed) and then call @ref Mesh::draw(). Example:
@ref AbstractTexture::bind(Int). Then call @ref Mesh::draw(). Example:
@code @code
shader.setTransformation(transformation) shader.setTransformation(transformation)
.setProjection(projection); .setProjection(projection)
.setDiffuseTexture(diffuseTexture)
diffuseTexture.bind(MyShader::DiffuseTextureLayer); .setSpecularTexture(specularTexture);
specularTexture.bind(MyShader::SpecularTextureLayer);
mesh.draw(shader); mesh.draw(shader);
@endcode @endcode

11
src/Magnum/AbstractTexture.h

@ -208,10 +208,13 @@ class MAGNUM_EXPORT AbstractTexture: public AbstractObject {
/** /**
* @brief Bind texture for rendering * @brief Bind texture for rendering
* *
* Sets current texture as active in given layer. The layer must be * Sets current texture as active in given layer. Note that only one
* between 0 and @ref maxLayers(). Note that only one texture can be * texture can be bound to given layer. If @extension{EXT,direct_state_access}
* bound to given layer. If @extension{EXT,direct_state_access} is not * is not available, the layer is made active before binding the
* available, the layer is made active before binding the texture. * 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 * @see @ref maxLayers(), @fn_gl{ActiveTexture}, @fn_gl{BindTexture} or
* @fn_gl_extension{BindMultiTexture,EXT,direct_state_access} * @fn_gl_extension{BindMultiTexture,EXT,direct_state_access}
*/ */

9
src/Magnum/BufferTexture.h

@ -181,11 +181,10 @@ constexpr static Vector3 data[] = {
buffer.setData(data, BufferUsage::StaticDraw); buffer.setData(data, BufferUsage::StaticDraw);
@endcode @endcode
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `samplerBuffer`, `isamplerBuffer` or
the texture is used via `samplerBuffer`, `isamplerBuffer` or `usamplerBuffer`. `usamplerBuffer`. Unlike in classic textures, coordinates for buffer textures
Unlike in classic textures, coordinates for buffer textures are integer are integer coordinates passed to `texelFetch()`. See @ref AbstractShaderProgram
coordinates passed to `texelFetch()`. See also @ref AbstractShaderProgram documentation for more information about usage in shaders.
documentation for more information.
@section BufferTexture-performance-optimization Performance optimizations @section BufferTexture-performance-optimization Performance optimizations

11
src/Magnum/CubeMapTexture.h

@ -69,12 +69,11 @@ texture.setMagnificationFilter(Sampler::Filter::Linear)
// ... // ...
@endcode @endcode
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `samplerCube`, `samplerCubeShadow`,
the texture is used via `samplerCube`, `samplerCubeShadow`, `isamplerCube` or `isamplerCube` or `usamplerCube`. Unlike in classic textures, coordinates for
`usamplerCube`. Unlike in classic textures, coordinates for cube map textures cube map textures is signed three-part vector from the center of the cube,
is signed three-part vector from the center of the cube, which intersects one which intersects one of the six sides of the cube map. See
of the six sides of the cube map. See also @ref AbstractShaderProgram for more @ref AbstractShaderProgram for more information about usage in shaders.
information about usage in shaders.
@see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTextureArray, @see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTextureArray,
@ref Texture, @ref BufferTexture @ref Texture, @ref BufferTexture

5
src/Magnum/CubeMapTextureArray.h

@ -67,12 +67,11 @@ for(std::size_t i = 0; i != 4; i += 6) {
texture.generateMipmap(); texture.generateMipmap();
@endcode @endcode
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `samplerCubeArray`, `samplerCubeArrayShadow`,
the texture is used via `samplerCubeArray`, `samplerCubeArrayShadow`,
`isamplerCubeArray` or `usamplerCubeArray`. Unlike in classic textures, `isamplerCubeArray` or `usamplerCubeArray`. Unlike in classic textures,
coordinates for cube map texture arrays is signed four-part vector. First three 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 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. @ref AbstractShaderProgram for more information about usage in shaders.
@see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTexture, @see @ref Renderer::Feature::SeamlessCubeMapTexture, @ref CubeMapTexture,

3
src/Magnum/MultisampleTexture.h

@ -52,8 +52,7 @@ also @ref AbstractTexture documentation for more information.
@todoc Finish when fully implemented @todoc Finish when fully implemented
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `sampler2DMS`/`sampler2DMSArray`,
the texture is used via `sampler2DMS`/`sampler2DMSArray`,
`isampler2DMS`/`isampler2DMSArray` or `usampler2DMS`/`usampler2DMSArray`. See `isampler2DMS`/`isampler2DMSArray` or `usampler2DMS`/`usampler2DMSArray`. See
@ref AbstractShaderProgram documentation for more information about usage in @ref AbstractShaderProgram documentation for more information about usage in
shaders. shaders.

7
src/Magnum/RectangleTexture.h

@ -59,10 +59,9 @@ texture.setMagnificationFilter(Sampler::Filter::Linear)
.setSubImage({}, image); .setSubImage({}, image);
@endcode @endcode
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via sampler2DRect`, `sampler2DRectShadow`,
the texture is used via sampler2DRect`, `sampler2DRectShadow`, `isampler2DRect` `isampler2DRect` or `usampler2DRect`. See @ref AbstractShaderProgram
or `usampler2DRect`. See @ref AbstractShaderProgram documentation for more documentation for more information about usage in shaders.
information about usage in shaders.
@requires_gl31 %Extension @extension{ARB,texture_rectangle} @requires_gl31 %Extension @extension{ARB,texture_rectangle}
@requires_gl Rectangle textures are not available in OpenGL ES. @requires_gl Rectangle textures are not available in OpenGL ES.

2
src/Magnum/ResourceManager.h

@ -212,7 +212,7 @@ if(!cube) {
@endcode @endcode
- Using the resource data. - Using the resource data.
@code @code
texture->bind(layer); shader->setTexture(layer);
cube->draw(*shader); cube->draw(*shader);
@endcode @endcode
- Destroying resource references and deleting manager instance when nothing - Destroying resource references and deleting manager instance when nothing

43
src/Magnum/Shaders/AbstractVector.cpp

@ -0,0 +1,43 @@
/*
This file is part of Magnum.
Copyright © 2010, 2011, 2012, 2013, 2014
Vladimír Vondruš <mosra@centrum.cz>
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<UnsignedInt dimensions> AbstractVector<dimensions>& AbstractVector<dimensions>::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
}}

18
src/Magnum/Shaders/AbstractVector.h

@ -46,13 +46,29 @@ template<UnsignedInt dimensions> class AbstractVector: public AbstractShaderProg
/** @brief Texture coordinates */ /** @brief Texture coordinates */
typedef typename Generic<dimensions>::TextureCoordinates TextureCoordinates; typedef typename Generic<dimensions>::TextureCoordinates TextureCoordinates;
#ifdef MAGNUM_BUILD_DEPRECATED
enum: Int { 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<dimensions>& setVectorTexture(Texture2D& texture);
protected: protected:
explicit AbstractVector() = default; explicit AbstractVector() = default;
~AbstractVector() = default; ~AbstractVector() = default;
#ifndef MAGNUM_BUILD_DEPRECATED
enum: Int { VectorTextureLayer = 16 };
#endif
}; };
/** @brief Base for two-dimensional text shaders */ /** @brief Base for two-dimensional text shaders */

1
src/Magnum/Shaders/CMakeLists.txt

@ -26,6 +26,7 @@
corrade_add_resource(MagnumShaders_RCS resources.conf) corrade_add_resource(MagnumShaders_RCS resources.conf)
set(MagnumShaders_SRCS set(MagnumShaders_SRCS
AbstractVector.cpp
DistanceFieldVector.cpp DistanceFieldVector.cpp
Flat.cpp Flat.cpp
MeshVisualizer.cpp MeshVisualizer.cpp

8
src/Magnum/Shaders/DistanceFieldVector.h

@ -116,6 +116,14 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT DistanceFieldVector
return *this; return *this;
} }
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Overloads to remove WTF-factor from method chaining order */
DistanceFieldVector<dimensions>& setVectorTexture(Texture2D& texture) {
AbstractVector<dimensions>::setVectorTexture(texture);
return *this;
}
#endif
private: private:
Int transformationProjectionMatrixUniform, Int transformationProjectionMatrixUniform,
colorUniform, colorUniform,

8
src/Magnum/Shaders/Flat.cpp

@ -30,10 +30,13 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "Magnum/Shader.h" #include "Magnum/Shader.h"
#include "Magnum/Texture.h"
namespace Magnum { namespace Shaders { namespace Magnum { namespace Shaders {
namespace { namespace {
enum: Int { TextureLayer = 0 };
template<UnsignedInt> constexpr const char* vertexShaderName(); template<UnsignedInt> constexpr const char* vertexShaderName();
template<> constexpr const char* vertexShaderName<2>() { return "Flat2D.vert"; } template<> constexpr const char* vertexShaderName<2>() { return "Flat2D.vert"; }
template<> constexpr const char* vertexShaderName<3>() { return "Flat3D.vert"; } template<> constexpr const char* vertexShaderName<3>() { return "Flat3D.vert"; }
@ -96,6 +99,11 @@ template<UnsignedInt dimensions> Flat<dimensions>::Flat(const Flags flags): tran
#endif #endif
} }
template<UnsignedInt dimensions> Flat<dimensions>& Flat<dimensions>::setTexture(Texture2D& texture) {
if(_flags & Flag::Textured) texture.bind(TextureLayer);
return *this;
}
template class Flat<2>; template class Flat<2>;
template class Flat<3>; template class Flat<3>;

33
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 If you want to use texture instead of color, you need to provide also
@ref TextureCoordinates attribute. Pass @ref Flag::Textured to constructor and @ref TextureCoordinates attribute. Pass @ref Flag::Textured to constructor and
then at render time bind the texture to its respective layer instead of calling then at render time don't forget to set also the texture via @ref setTexture().
@ref setColor(). Example: The texture will be multiplied with the color (which is white by default, thus
@code it doesn't change texture color).
Shaders::Flat2D shader(Shaders::Flat2D::Flag::Textured);
// ...
myTexture.bind(Shaders::Flat2D::TextureLayer);
@endcode
For coloring the texture based on intensity you can use the @ref Vector shader. For coloring the texture based on intensity you can use the @ref Vector shader.
@see @ref Flat2D, @ref Flat3D @see @ref Flat2D, @ref Flat3D
@ -77,10 +71,15 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
*/ */
typedef typename Generic<dimensions>::TextureCoordinates TextureCoordinates; typedef typename Generic<dimensions>::TextureCoordinates TextureCoordinates;
#ifdef MAGNUM_BUILD_DEPRECATED
enum: Int { 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 TextureLayer = 0
}; };
#endif
#ifdef DOXYGEN_GENERATING_OUTPUT #ifdef DOXYGEN_GENERATING_OUTPUT
/** /**
@ -125,11 +124,21 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Flat: public Abstra
* @brief Set color * @brief Set color
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* Color will be multiplied with texture * If not set, default value is fully opaque white. Color will be
* if @ref Flag::Textured is set. * multiplied with texture if @ref Flag::Textured is set.
* @see @ref setTexture()
*/ */
Flat<dimensions>& setColor(const Color4& color); Flat<dimensions>& 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<dimensions>& setTexture(Texture2D& texture);
private: private:
Int transformationProjectionMatrixUniform, Int transformationProjectionMatrixUniform,
colorUniform; colorUniform;

24
src/Magnum/Shaders/Phong.cpp

@ -30,9 +30,18 @@
#include "Magnum/Context.h" #include "Magnum/Context.h"
#include "Magnum/Extensions.h" #include "Magnum/Extensions.h"
#include "Magnum/Shader.h" #include "Magnum/Shader.h"
#include "Magnum/Texture.h"
namespace Magnum { namespace Shaders { 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) { 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"); Utility::Resource rs("MagnumShaders");
@ -105,4 +114,19 @@ Phong::Phong(const Flags flags): transformationMatrixUniform(0), projectionMatri
#endif #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;
}
}} }}

51
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 If you want to use texture instead of color, you need to provide also
@ref TextureCoordinates attribute. Pass appropriate flags to constructor and @ref TextureCoordinates attribute. Pass appropriate flags to constructor and
then at render time bind the texture to its respective layer instead of setting then at render time don't forget to also call appropriate subset of
the color. Example: @ref setAmbientTexture(), @ref setDiffuseTexture() and @ref setSpecularTexture().
@code
Shaders::Phong shader(Shaders::Phong::Flag::DiffuseTexture);
// ...
myDiffuseTexture.bind(Shaders::Phong::DiffuseTextureLayer);
@endcode
*/ */
class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram { class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
public: public:
@ -69,25 +62,33 @@ class MAGNUM_SHADERS_EXPORT Phong: public AbstractShaderProgram {
*/ */
typedef Generic3D::TextureCoordinates TextureCoordinates; typedef Generic3D::TextureCoordinates TextureCoordinates;
#ifdef MAGNUM_BUILD_DEPRECATED
enum: Int { enum: Int {
/** /**
* Layer for ambient texture. Used only if @ref Flag::AmbientTexture * Layer for ambient texture. Used only if @ref Flag::AmbientTexture
* is set. * is set.
* @deprecated Use @ref Magnum::Shaders::Phong::setAmbientTexture() "setAmbientTexture()"
* instead.
*/ */
AmbientTextureLayer = 0, AmbientTextureLayer = 0,
/** /**
* Layer for diffuse texture. Used only if @ref Flag::DiffuseTexture * Layer for diffuse texture. Used only if @ref Flag::DiffuseTexture
* is set. * is set.
* @deprecated Use @ref Magnum::Shaders::Phong::setDiffuseTexture() "setDiffuseTexture()"
* instead.
*/ */
DiffuseTextureLayer = 1, DiffuseTextureLayer = 1,
/** /**
* Layer for specular texture. Used only if @ref Flag::SpecularTexture * Layer for specular texture. Used only if @ref Flag::SpecularTexture
* is set. * is set.
* @deprecated Use @ref Magnum::Shaders::Phong::setSpecularTexture() "setSpecularTexture()"
* instead.
*/ */
SpecularTextureLayer = 2 SpecularTextureLayer = 2
}; };
#endif
/** /**
* @brief Shader flag * @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 * If not set, default value is `(0.0f, 0.0f, 0.0f)`. Has no effect if
* @ref Flag::AmbientTexture is set. * @ref Flag::AmbientTexture is set.
* @see @ref setAmbientTexture()
*/ */
Phong& setAmbientColor(const Color3& color); 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 * @brief Set diffuse color
* @return Reference to self (for method chaining) * @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); 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 * @brief Set specular color
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)
* *
* If not set, default value is `(1.0f, 1.0f, 1.0f)`. Has no effect if * If not set, default value is `(1.0f, 1.0f, 1.0f)`. Has no effect if
* @ref Flag::SpecularTexture is set. * @ref Flag::SpecularTexture is set.
* @see @ref setSpecularTexture()
*/ */
Phong& setSpecularColor(const Color3& color); 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 * @brief Set shininess
* @return Reference to self (for method chaining) * @return Reference to self (for method chaining)

8
src/Magnum/Shaders/Vector.h

@ -82,6 +82,14 @@ template<UnsignedInt dimensions> class MAGNUM_SHADERS_EXPORT Vector: public Abst
return *this; return *this;
} }
#ifndef DOXYGEN_GENERATING_OUTPUT
/* Overloads to remove WTF-factor from method chaining order */
Vector<dimensions>& setVectorTexture(Texture2D& texture) {
AbstractVector<dimensions>::setVectorTexture(texture);
return *this;
}
#endif
private: private:
Int transformationProjectionMatrixUniform, Int transformationProjectionMatrixUniform,
backgroundColorUniform, backgroundColorUniform,

12
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 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. 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 The text can be then drawn as usual by configuring the shader and drawing the
and drawing the mesh: mesh:
@code @code
Text::AbstractFont* font; Text::AbstractFont* font;
Text::GlyphCache cache; 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 // Draw white text centered on the screen
shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f)) shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-rectangle.width()/2.0f))
.setColor(Color3(1.0f)); .setColor(Color3(1.0f))
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); .setVectorTexture(glyphCache->texture());
mesh.draw(shader); mesh.draw(shader);
@endcode @endcode
See @ref render(AbstractFont&, const GlyphCache&, Float, const std::string&, Alignment) and 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 // Draw the text centered on the screen
shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f)) shader.setTransformationProjectionMatrix(projection*Matrix3::translation(-renderer.rectangle().width()/2.0f))
.setColor(Color3(1.0f)); .setColor(Color3(1.0f))
glyphCache->texture()->bind(Shaders::VectorShader2D::FontTextureLayer); .setVectorTexture(glyphCache->texture());
renderer.mesh().draw(shader); renderer.mesh().draw(shader);
@endcode @endcode

3
src/Magnum/Texture.h

@ -82,8 +82,7 @@ texture.setMagnificationFilter(Sampler::Filter::Linear)
@ref setMinificationFilter(), explicitly specify all mip levels with @ref setMinificationFilter(), explicitly specify all mip levels with
@ref setStorage() and @ref setImage() or call @ref generateMipmap(). @ref setStorage() and @ref setImage() or call @ref generateMipmap().
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `sampler1D`/`sampler2D`/`sampler3D`,
the texture is used via `sampler1D`/`sampler2D`/`sampler3D`,
`sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`, `sampler1DShadow`/`sampler2DShadow`/`sampler3DShadow`,
`isampler1D`/`isampler2D`/`isampler3D` or `usampler1D`/`usampler2D`/`usampler3D`. `isampler1D`/`isampler2D`/`isampler3D` or `usampler1D`/`usampler2D`/`usampler3D`.
See @ref AbstractShaderProgram documentation for more information about usage See @ref AbstractShaderProgram documentation for more information about usage

3
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 setMinificationFilter(), explicitly specify all mip levels with
@ref setStorage() and @ref setImage() or call @ref generateMipmap(). @ref setStorage() and @ref setImage() or call @ref generateMipmap().
The texture is bound to layer specified by shader via @ref bind(). In shader, In shader, the texture is used via `sampler1DArray`/`sampler2DArray`,
the texture is used via `sampler1DArray`/`sampler2DArray`,
`sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray` `sampler1DArrayShadow`/`sampler1DArrayShadow`, `isampler1DArray`/`isampler2DArray`
or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram or `usampler1DArray`/`usampler2DArray`. See @ref AbstractShaderProgram
documentation for more information about usage in shaders. documentation for more information about usage in shaders.

16
src/Magnum/TextureTools/DistanceField.cpp

@ -45,10 +45,6 @@ class DistanceFieldShader: public AbstractShaderProgram {
public: public:
typedef Attribute<0, Vector2> Position; typedef Attribute<0, Vector2> Position;
enum: Int {
TextureLayer = 8
};
explicit DistanceFieldShader(); explicit DistanceFieldShader();
DistanceFieldShader& setRadius(Int radius) { DistanceFieldShader& setRadius(Int radius) {
@ -66,7 +62,14 @@ class DistanceFieldShader: public AbstractShaderProgram {
return *this; return *this;
} }
DistanceFieldShader& setTexture(Texture2D& texture) {
texture.bind(TextureLayer);
return *this;
}
private: private:
enum: Int { TextureLayer = 8 };
Int radiusUniform, Int radiusUniform,
scalingUniform, scalingUniform,
imageSizeInvertedUniform; imageSizeInvertedUniform;
@ -162,9 +165,8 @@ void distanceField(Texture2D& input, Texture2D& output, const Range2Di& rectangl
DistanceFieldShader shader; DistanceFieldShader shader;
shader.setRadius(radius) shader.setRadius(radius)
.setScaling(Vector2(imageSize)/Vector2(rectangle.size())); .setScaling(Vector2(imageSize)/Vector2(rectangle.size()))
.setTexture(input);
input.bind(DistanceFieldShader::TextureLayer);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
if(!Context::current()->isVersionSupported(Version::GL300)) if(!Context::current()->isVersionSupported(Version::GL300))

Loading…
Cancel
Save