Skip to content

class SF::Shader
inherits Reference #

Shader class (vertex, geometry and fragment)

Shaders are programs written using a specific language, executed directly by the graphics card and allowing 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

A SF::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 SFML.

Like any C/C++ program, a GLSL shader has its own variables called uniforms that you can set from your C++ application. SF::Shader handles different types of uniforms:

  • scalars: float, int, bool
  • vectors (2, 3 or 4 components)
  • matrices (3x3 or 4x4)
  • samplers (textures)

Some SFML-specific types can be converted:

Every uniform variable in a shader can be set through one of the set_parameter overloads, or through a shorthand. For example, if you have a shader with the following uniforms:

uniform float offset;
uniform vec3 point;
uniform vec4 color;
uniform mat4 matrix;
uniform sampler2D overlay;
uniform sampler2D current;

You can set their values from Crystal code as follows:

shader.offset 2.0
shader.point 0.5, 0.8, 0.3
shader.color color      # color is a SF::Color
shader.matrix transform # transform is a SF::Transform
shader.overlay texture  # texture is a SF::Texture
shader.current SF::Shader::CurrentTexture

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 an additional parameter to the Window.draw function:

states = SF::RenderStates.new(shader)
window.draw(sprite, states)

In the code above we pass a pointer 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 SF::Sprite 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 SF::Text: 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 SF::RenderTexture, then draw it to the main target using the shader
  • draw everything directly to the main target, then use SF::Texture.update(window) to copy its contents to a texture and draw it to the main target using the shader

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 SF::Texture that can be used as a raw OpenGL texture, SF::Shader can also be used directly as a raw shader for custom OpenGL geometry.

SF::Shader.bind shader
# ... render OpenGL geometry ...
SF::Shader.bind nil

Included modules

SF::GlResource SF::NonCopyable

Constants#

CurrentTexture = CurrentTextureType.new#

Represents the texture of the object being drawn

Constructors#

.from_file(*args, **kwargs) : self#

Shorthand for shader = Shader.new; shader.load_from_file(...); shader

Raises InitError on failure

View source

.from_memory(*args, **kwargs) : self#

Shorthand for shader = Shader.new; shader.load_from_memory(...); shader

Raises InitError on failure

View source

.from_stream(*args, **kwargs) : self#

Shorthand for shader = Shader.new; shader.load_from_stream(...); shader

Raises InitError on failure

View source

.new#

Default constructor

This constructor creates an invalid shader.

View source

Class methods#

.available? : Bool#

Tell whether or not the system supports shaders

This function should always be called before using the shader features. If it returns false, then any attempt to use SF::Shader will fail.

Returns: True if shaders are supported, false otherwise

View source

.bind(shader : Shader | Nil)#

Bind a shader for rendering

This function is not part of the graphics API, it mustn't be used when drawing SFML entities. It must be used only if you mix SF::Shader with OpenGL code.

s1 = SF::Shader.new
s2 = SF::Shader.new
# [...]
SF::Shader.bind s1
# draw OpenGL stuff that use s1...
SF::Shader.bind s2
# draw OpenGL stuff that use s2...
SF::Shader.bind nil
# draw OpenGL stuff that use no shader...
  • shader - Shader to bind, can be null to use no shader
View source

.geometry_available? : Bool#

Tell whether or not the system supports geometry shaders

This function should always be called before using the geometry shader features. If it returns false, then any attempt to use SF::Shader geometry shader features will fail.

This function can only return true if available?() would also return true, since shaders in general have to be supported in order for geometry shaders to be supported as well.

Note: The first call to this function, whether by your code or SFML will result in a context switch.

Returns: True if geometry shaders are supported, false otherwise

View source

Methods#

#finalize#

Destructor

View source

#load_from_file(vertex_shader_filename : String, geometry_shader_filename : String, fragment_shader_filename : String) : Bool#

Load the vertex, geometry and fragment shaders from files

This function loads the vertex, geometry and fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be text files containing valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader_filename - Path of the vertex shader file to load
  • geometry_shader_filename - Path of the geometry shader file to load
  • fragment_shader_filename - Path of the fragment shader file to load

Returns: True if loading succeeded, false if it failed

See also: load_from_memory, load_from_stream

View source

#load_from_file(filename : String, type : Shader::Type) : Bool#

Load the vertex, geometry or fragment shader from a file

This function loads a single shader, vertex, geometry or fragment, identified by the second argument. The source must be a text file containing a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders.

  • filename - Path of the vertex, geometry or fragment shader file to load
  • type - Type of shader (vertex, geometry or fragment)

Returns: True if loading succeeded, false if it failed

See also: load_from_memory, load_from_stream

View source

#load_from_file(vertex_shader_filename : String, fragment_shader_filename : String) : Bool#

Load both the vertex and fragment shaders from files

This function loads both the vertex and the fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be text files containing valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader_filename - Path of the vertex shader file to load
  • fragment_shader_filename - Path of the fragment shader file to load

Returns: True if loading succeeded, false if it failed

See also: load_from_memory, load_from_stream

View source

#load_from_memory(vertex_shader : String, geometry_shader : String, fragment_shader : String) : Bool#

Load the vertex, geometry and fragment shaders from source codes in memory

This function loads the vertex, geometry and fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader - String containing the source code of the vertex shader
  • geometry_shader - String containing the source code of the geometry shader
  • fragment_shader - String containing the source code of the fragment shader

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_stream

View source

#load_from_memory(shader : String, type : Shader::Type) : Bool#

Load the vertex, geometry or fragment shader from a source code in memory

This function loads a single shader, vertex, geometry or fragment, identified by the second argument. The source code must be a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders you'll probably need to read a good documentation for it before writing your own shaders.

  • shader - String containing the source code of the shader
  • type - Type of shader (vertex, geometry or fragment)

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_stream

View source

#load_from_memory(vertex_shader : String, fragment_shader : String) : Bool#

Load both the vertex and fragment shaders from source codes in memory

This function loads both the vertex and the fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The sources must be valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders; you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader - String containing the source code of the vertex shader
  • fragment_shader - String containing the source code of the fragment shader

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_stream

View source

#load_from_stream(vertex_shader_stream : InputStream, geometry_shader_stream : InputStream, fragment_shader_stream : InputStream) : Bool#

Load the vertex, geometry and fragment shaders from custom streams

This function loads the vertex, geometry and fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The source codes must be valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader_stream - Source stream to read the vertex shader from
  • geometry_shader_stream - Source stream to read the geometry shader from
  • fragment_shader_stream - Source stream to read the fragment shader from

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_memory

View source

#load_from_stream(stream : InputStream, type : Shader::Type) : Bool#

Load the vertex, geometry or fragment shader from a custom stream

This function loads a single shader, vertex, geometry or fragment, identified by the second argument. The source code must be a valid shader in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders you'll probably need to read a good documentation for it before writing your own shaders.

  • stream - Source stream to read from
  • type - Type of shader (vertex, geometry or fragment)

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_memory

View source

#load_from_stream(vertex_shader_stream : InputStream, fragment_shader_stream : InputStream) : Bool#

Load both the vertex and fragment shaders from custom streams

This function loads both the vertex and the fragment shaders. If one of them fails to load, the shader is left empty (the valid shader is unloaded). The source codes must be valid shaders in GLSL language. GLSL is a C-like language dedicated to OpenGL shaders you'll probably need to read a good documentation for it before writing your own shaders.

  • vertex_shader_stream - Source stream to read the vertex shader from
  • fragment_shader_stream - Source stream to read the fragment shader from

Returns: True if loading succeeded, false if it failed

See also: load_from_file, load_from_memory

View source

#native_handle : Int32#

Get the underlying OpenGL handle of the shader.

You shouldn't need to use this function, unless you have very specific stuff to implement that SFML doesn't support, or implement a temporary workaround until a bug is fixed.

Returns: OpenGL handle of the shader or 0 if not yet loaded

View source

#set_parameter(name : String, x : Number, y : Number, z : Number, w : Number)#

Change a 4-components vector parameter of the shader

View source

#set_parameter(name : String, x : Number, y : Number, z : Number)#

Change a 3-components vector parameter of the shader

View source

#set_parameter(name : String, x : Number, y : Number)#

Change a 2-components vector parameter of the shader

View source

#set_parameter(name : String, x : Number)#

Change a float parameter of the shader

View source

#set_parameter(name : String, vector : Vector2 | Tuple)#

Change a 2-components vector parameter of the shader

View source

#set_parameter(name : String, vector : Vector3f)#

Change a 3-components vector parameter of the shader

View source

#set_parameter(name : String, color : Color)#

Change a color parameter of the shader

View source

#set_parameter(name : String, transform : Transform)#

Change a matrix parameter of the shader

View source

#set_parameter(name : String, texture : Texture)#

Change a texture parameter of the shader

View source

#set_parameter(name : String, p1 : CurrentTextureType)#

Change a texture parameter of the shader

View source

Macros#

method_missing(call)#

Forwards calls like shader.param(arg1, arg2) to shader.set_parameter("param", arg1, arg2)

View source