Shaders are programs written using a specific language, executed directly by
the graphics card and allowing one to apply real-time operations to the
rendered entities.
There are three kinds of shaders:
Vertex shaders, that process vertices
Geometry shaders, that process primitives
Fragment (pixel) shaders, that process pixels
$(PARA
A $(U Shader) can be composed of either a vertex shader alone, a geometry
shader alone, a fragment shader alone, or any combination of them. (see the
variants of the load functions).
Shaders are written in GLSL, which is a C-like language dedicated to OpenGL
shaders. You'll probably need to learn its basics before writing your own
shaders for DSFML.
Like any D/C/C++ program, a GLSL shader has its own variables called uniforms
that you can set from your D application. $(U Shader) handles different types
of uniforms:)
scalars: float, int, bool
vectors (2, 3 or 4 components)
matrices (3x3 or 4x4)
samplers (textures)
$(PARA Some DSFML-specific types can be converted:)
$(COLOR_LINK) as a 4D vector (vec4)
$(TRANSFORM_LINK) as matrices (mat3 or mat4)
$(PARA Every uniform variable in a shader can be set through one of the
`setUniform()` or `setUniformArray()` overloads. For example, if you have a
shader with the following uniforms:)
$(PARA The old `setParameter()` overloads are deprecated and will be removed
in a future version. You should use their `setUniform()` equivalents instead.
It is also worth noting that DSFML supports index overloads for
setting uniforms:)
$(PARA The special `Shader.CurrentTexture` argument maps the given
`sampler2D` uniform to the current texture of the object being drawn (which
cannot be known in advance).
To apply a shader to a drawable, you must pass it as part of an additional
parameter to the `Window.draw()` function:)
$(PARA In the code above we pass a reference to the shader, because it may be
null (which means "no shader").
Shaders can be used on any drawable, but some combinations are not
interesting. For example, using a vertex shader on a $(SPRITE_LINK) is
limited because there are only 4 vertices, the sprite would have to be
subdivided in order to apply wave effects.
Another bad example is a fragment shader with $(TEXT_LINK): the texture of
the text is not the actual text that you see on screen, it is a big texture
containing all the characters of the font in an arbitrary order; thus,
texture lookups on pixels other than the current one may not give you the
expected result.
Shaders can also be used to apply global post-effects to the current contents
of the target. This can be done in two different ways:)
draw everything to a $(RENDERTEXTURE_LINK), then draw it to the main
target using the shader
draw everything directly to the main target, then use Texture.update
to copy its contents to a texture and draw it to the main target using
the shader
$(PARA The first technique is more optimized because it doesn't involve
retrieving the target's pixels to system memory, but the second one doesn't
impact the rendering process and can be easily inserted anywhere without
impacting all the code.
Like $(TEXTURE_LINK) that can be used as a raw OpenGL texture, $(U Shader)
can also be used directly as a raw shader for custom OpenGL geometry.)
Shaders are programs written using a specific language, executed directly by the graphics card and allowing one to apply real-time operations to the rendered entities.
There are three kinds of shaders:
$(PARA A $(U Shader) can be composed of either a vertex shader alone, a geometry shader alone, a fragment shader alone, or any combination of them. (see the variants of the load functions). Shaders are written in GLSL, which is a C-like language dedicated to OpenGL shaders. You'll probably need to learn its basics before writing your own shaders for DSFML. Like any D/C/C++ program, a GLSL shader has its own variables called uniforms that you can set from your D application. $(U Shader) handles different types of uniforms:)
$(PARA Some DSFML-specific types can be converted:)
$(PARA Every uniform variable in a shader can be set through one of the `setUniform()` or `setUniformArray()` overloads. For example, if you have a shader with the following uniforms:)
$(PARA You can set their values from D code as follows, using the types defined in the `dsfml.graphics.glsl` module:)
$(PARA The old `setParameter()` overloads are deprecated and will be removed in a future version. You should use their `setUniform()` equivalents instead. It is also worth noting that DSFML supports index overloads for setting uniforms:)
$(PARA The special `Shader.CurrentTexture` argument maps the given `sampler2D` uniform to the current texture of the object being drawn (which cannot be known in advance). To apply a shader to a drawable, you must pass it as part of an additional parameter to the `Window.draw()` function:)
$(PARA In the code above we pass a reference to the shader, because it may be null (which means "no shader"). Shaders can be used on any drawable, but some combinations are not interesting. For example, using a vertex shader on a $(SPRITE_LINK) is limited because there are only 4 vertices, the sprite would have to be subdivided in order to apply wave effects. Another bad example is a fragment shader with $(TEXT_LINK): the texture of the text is not the actual text that you see on screen, it is a big texture containing all the characters of the font in an arbitrary order; thus, texture lookups on pixels other than the current one may not give you the expected result. Shaders can also be used to apply global post-effects to the current contents of the target. This can be done in two different ways:)
$(PARA The first technique is more optimized because it doesn't involve retrieving the target's pixels to system memory, but the second one doesn't impact the rendering process and can be easily inserted anywhere without impacting all the code. Like $(TEXTURE_LINK) that can be used as a raw OpenGL texture, $(U Shader) can also be used directly as a raw shader for custom OpenGL geometry.)