class SF::Shader

Overview

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:

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:

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:

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

Defined in:

graphics/graphics.cr
graphics/obj.cr

Constant Summary

CurrentTexture = CurrentTextureType.new

Represents the texture of the object being drawn

Constructors

Class Method Summary

Instance Method Summary

Macro Summary

Constructor Detail

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

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

Raises InitError on failure


[View source]
def self.from_memory(*args, **kwargs) : self #

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

Raises InitError on failure


[View source]
def self.from_stream(*args, **kwargs) : self #

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

Raises InitError on failure


[View source]
def self.new #

Default constructor

This constructor creates an invalid shader.


[View source]

Class Method Detail

def self.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]
def self.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]
def self.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]

Instance Method Detail

def finalize #

Destructor


[View source]
def 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]
def 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]
def 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]
def 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]
def 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]
def 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]
def 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]
def 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]
def 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]
def 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]
def set_parameter(name : String, x : Number, y : Number, z : Number, w : Number) #

Change a 4-components vector parameter of the shader


[View source]
def set_parameter(name : String, x : Number, y : Number, z : Number) #

Change a 3-components vector parameter of the shader


[View source]
def set_parameter(name : String, x : Number, y : Number) #

Change a 2-components vector parameter of the shader


[View source]
def set_parameter(name : String, x : Number) #

Change a float parameter of the shader


[View source]
def set_parameter(name : String, vector : Vector2 | Tuple) #

Change a 2-components vector parameter of the shader


[View source]
def set_parameter(name : String, vector : Vector3f) #

Change a 3-components vector parameter of the shader


[View source]
def set_parameter(name : String, color : Color) #

Change a color parameter of the shader


[View source]
def set_parameter(name : String, transform : Transform) #

Change a matrix parameter of the shader


[View source]
def set_parameter(name : String, texture : Texture) #

Change a texture parameter of the shader


[View source]
def set_parameter(name : String, p1 : CurrentTextureType) #

Change a texture parameter of the shader


[View source]

Macro Detail

macro method_missing(call) #

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


[View source]