#[repr(C)]pub struct Shader<'texture> { /* private fields */ }
Expand description
Shader type (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 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 Rust program, a GLSL shader has its own variables called uniforms that you can set
from your Rust application. 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_uniform_*()
or set_uniform_array_*()
methods.
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 Rust code as follows,
using the types defined in the glsl
module:
let texture: FBox<Texture> = unimplemented!();
let mut shader: &Shader = unimplemented!();
let color: Color = unimplemented!();
let transform: Transform = unimplemented!();
shader.set_uniform_float("offset", 2.);
shader.set_uniform_vec3("point", Vector3f::new(0.5, 0.8, 0.3));
shader.set_uniform_vec4("color", color);
shader.set_uniform_mat4("matrix", transform);
shader.set_uniform_texture("overlay", &texture);
shader.set_uniform_current_texture("current");
To apply a shader to a drawable,
you must set the shader
field of a RenderStates
instance, and use
RenderTarget::draw_with_renderstates
. Example:
let mut states = RenderStates::default();;
states.shader = Some(shader);
window.draw_with_renderstates(&sprite, &states);
Shaders can be used on any drawable, but some combinations are not interesting.
For example, using a vertex shader on a 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 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 (like the old sf::PostFx
class in SFML 1). This can be done in two different ways:
-
draw everything to a
RenderTexture
, then draw it to the main target using the shader -
draw everything directly to the main target, then use
Texture::update_from_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 Texture
that can be used as a raw OpenGL texture, Shader
can also be used
directly as a raw shader for custom OpenGL geometry.
use sfml::graphics::*;
Shader::bind(Some(&shader));
// ... render OpenGL geometry ...
Shader::bind(None);
Implementations§
Source§impl<'texture> Shader<'texture>
impl<'texture> Shader<'texture>
Sourcepub fn from_file(path: &str, type_: ShaderType) -> SfResult<FBox<Self>>
pub fn from_file(path: &str, type_: ShaderType) -> SfResult<FBox<Self>>
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.
Examples found in repository?
26 fn new(texture: &'t Texture) -> SfResult<Self> {
27 let mut sprite = Sprite::new();
28 sprite.set_texture(texture, false);
29 Ok(Self {
30 sprite,
31 shader: Shader::from_file("pixelate.frag", ShaderType::Fragment)?,
32 })
33 }
34}
35
36impl Drawable for Pixelate<'_> {
37 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
38 &'a self,
39 target: &mut dyn RenderTarget,
40 states: &RenderStates<'texture, 'shader, 'shader_texture>,
41 ) {
42 let mut states = *states;
43 states.shader = Some(&self.shader);
44 target.draw_with_renderstates(&self.sprite, &states);
45 }
46}
47
48impl Effect for Pixelate<'_> {
49 fn update(&mut self, _t: f32, x: f32, y: f32) -> SfResult<()> {
50 self.shader
51 .set_uniform_float("pixel_threshold", (x + y) / 30.0)
52 }
53 fn name(&self) -> &str {
54 "pixelate"
55 }
56 fn as_drawable(&self) -> &dyn Drawable {
57 self
58 }
59}
60
61struct WaveBlur<'fo> {
62 text: Text<'fo>,
63 shader: FBox<Shader<'static>>,
64}
65
66const WAVEBLUR_TEXT: &str = "\
67Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.
68Mauris mi odio, bibendum quis fringilla a, laoreet vel orci. Proin vitae vulputate tortor.
69Praesent cursus ultrices justo, ut feugiat ante vehicula quis.
70Donec fringilla scelerisque mauris et viverra.
71Maecenas adipiscing ornare scelerisque. Nullam at libero elit.
72Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
73Nullam leo urna, tincidunt id semper eget, ultricies sed mi.
74Morbi mauris massa, commodo id dignissim vel, lobortis et elit.
75Fusce vel libero sed neque scelerisque venenatis.
76Integer mattis tincidunt quam vitae iaculis.
77Vivamus fringilla sem non velit venenatis fermentum.
78Vivamus varius tincidunt nisi id vehicula.
79Integer ullamcorper, enim vitae euismod rutrum, massa nisl semper ipsum,
80vestibulum sodales sem ante in massa.
81Vestibulum in augue non felis convallis viverra.
82Mauris ultricies dolor sed massa convallis sed aliquet augue fringilla.
83Duis erat eros, porta in accumsan in, blandit quis sem.
84In hac habitasse platea dictumst. Etiam fringilla est id odio dapibus sit amet semper dui laoreet.";
85
86impl<'fo> WaveBlur<'fo> {
87 fn new(font: &'fo Font) -> SfResult<Self> {
88 let mut text = Text::new(WAVEBLUR_TEXT, font, 22);
89 text.set_position((30., 20.));
90 Ok(Self {
91 text,
92 shader: Shader::from_file_vert_frag("wave.vert", "blur.frag")?,
93 })
94 }
95}
96
97impl Drawable for WaveBlur<'_> {
98 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
99 &'a self,
100 target: &mut dyn RenderTarget,
101 states: &RenderStates<'texture, 'shader, 'shader_texture>,
102 ) {
103 let mut states = *states;
104 states.shader = Some(&self.shader);
105 target.draw_with_renderstates(&self.text, &states);
106 }
107}
108
109impl Effect for WaveBlur<'_> {
110 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111 self.shader.set_uniform_float("wave_phase", t)?;
112 self.shader
113 .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114 self.shader
115 .set_uniform_float("blur_radius", (x + y) * 0.008)
116 }
117 fn name(&self) -> &str {
118 "wave + blur"
119 }
120 fn as_drawable(&self) -> &dyn Drawable {
121 self
122 }
123}
124
125struct StormBlink {
126 points: Vec<Vertex>,
127 shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131 fn new() -> SfResult<Self> {
132 use rand::{thread_rng, Rng};
133 let mut rng = thread_rng();
134
135 let mut points = Vec::new();
136 for _ in 0..40_000 {
137 let x = rng.gen_range(0.0..800.);
138 let y = rng.gen_range(0.0..600.);
139 let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140 points.push(Vertex::with_pos_color(
141 Vector2f::new(x, y),
142 Color::rgb(red, green, blue),
143 ));
144 }
145
146 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147 Ok(Self { points, shader })
148 }
149}
150
151impl Drawable for StormBlink {
152 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
153 &'a self,
154 target: &mut dyn RenderTarget,
155 states: &RenderStates<'texture, 'shader, 'shader_texture>,
156 ) {
157 let mut states = *states;
158 states.shader = Some(&self.shader);
159 target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
160 }
161}
162
163impl Effect for StormBlink {
164 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
165 let radius = 200. + t.cos() * 150.;
166 self.shader
167 .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
168 self.shader
169 .set_uniform_float("storm_inner_radius", radius / 3.)?;
170 self.shader
171 .set_uniform_float("storm_total_radius", radius)?;
172 self.shader
173 .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
174 }
175 fn name(&self) -> &str {
176 "storm + blink"
177 }
178 fn as_drawable(&self) -> &dyn Drawable {
179 self
180 }
181}
182
183struct Edge<'t> {
184 surface: FBox<RenderTexture>,
185 bg_sprite: Sprite<'t>,
186 entities: Vec<Sprite<'t>>,
187 shader: FBox<Shader<'static>>,
188}
189
190impl<'t> Edge<'t> {
191 fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
192 let mut surface = RenderTexture::new(800, 600)?;
193 surface.set_smooth(true);
194 let mut bg_sprite = Sprite::with_texture(bg_texture);
195 bg_sprite.set_position((135., 100.));
196 let mut entities = Vec::new();
197
198 for i in 0..6 {
199 entities.push(Sprite::with_texture_and_rect(
200 entity_texture,
201 IntRect::new(96 * i, 0, 96, 96),
202 ));
203 }
204
205 let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
206 shader.set_uniform_current_texture("texture")?;
207
208 Ok(Self {
209 surface,
210 bg_sprite,
211 entities,
212 shader,
213 })
214 }
Sourcepub fn from_file_vert_frag(vert: &str, frag: &str) -> SfResult<FBox<Self>>
pub fn from_file_vert_frag(vert: &str, frag: &str) -> SfResult<FBox<Self>>
Load both the vertex and fragment shaders from files.
This function loads both the vertex and the fragment shaders. 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.
Examples found in repository?
87 fn new(font: &'fo Font) -> SfResult<Self> {
88 let mut text = Text::new(WAVEBLUR_TEXT, font, 22);
89 text.set_position((30., 20.));
90 Ok(Self {
91 text,
92 shader: Shader::from_file_vert_frag("wave.vert", "blur.frag")?,
93 })
94 }
95}
96
97impl Drawable for WaveBlur<'_> {
98 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
99 &'a self,
100 target: &mut dyn RenderTarget,
101 states: &RenderStates<'texture, 'shader, 'shader_texture>,
102 ) {
103 let mut states = *states;
104 states.shader = Some(&self.shader);
105 target.draw_with_renderstates(&self.text, &states);
106 }
107}
108
109impl Effect for WaveBlur<'_> {
110 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111 self.shader.set_uniform_float("wave_phase", t)?;
112 self.shader
113 .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114 self.shader
115 .set_uniform_float("blur_radius", (x + y) * 0.008)
116 }
117 fn name(&self) -> &str {
118 "wave + blur"
119 }
120 fn as_drawable(&self) -> &dyn Drawable {
121 self
122 }
123}
124
125struct StormBlink {
126 points: Vec<Vertex>,
127 shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131 fn new() -> SfResult<Self> {
132 use rand::{thread_rng, Rng};
133 let mut rng = thread_rng();
134
135 let mut points = Vec::new();
136 for _ in 0..40_000 {
137 let x = rng.gen_range(0.0..800.);
138 let y = rng.gen_range(0.0..600.);
139 let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140 points.push(Vertex::with_pos_color(
141 Vector2f::new(x, y),
142 Color::rgb(red, green, blue),
143 ));
144 }
145
146 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147 Ok(Self { points, shader })
148 }
Sourcepub fn from_file_all(vert: &str, geom: &str, frag: &str) -> SfResult<FBox<Self>>
pub fn from_file_all(vert: &str, geom: &str, frag: &str) -> SfResult<FBox<Self>>
Load the vertex, geometry and fragment shaders from files.
This function loads the vertex, geometry and fragment shaders. 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.
Sourcepub fn from_memory(contents: &str, type_: ShaderType) -> SfResult<FBox<Self>>
pub fn from_memory(contents: &str, type_: ShaderType) -> SfResult<FBox<Self>>
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.
Sourcepub fn from_memory_vert_frag(vert: &str, frag: &str) -> SfResult<FBox<Self>>
pub fn from_memory_vert_frag(vert: &str, frag: &str) -> SfResult<FBox<Self>>
Load both the vertex and fragment shaders from source codes in memory.
This function loads both the vertex and the fragment shaders. 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.
Sourcepub fn from_memory_all(
vert: &str,
geom: &str,
frag: &str,
) -> SfResult<FBox<Self>>
pub fn from_memory_all( vert: &str, geom: &str, frag: &str, ) -> SfResult<FBox<Self>>
Load the vertex, geometry and fragment shaders from source codes in memory.
This function loads the vertex, geometry and fragment shaders. 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.
Sourcepub fn from_stream<T: Read + Seek>(
source: T,
type_: ShaderType,
) -> SfResult<FBox<Self>>
pub fn from_stream<T: Read + Seek>( source: T, type_: ShaderType, ) -> SfResult<FBox<Self>>
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.
Sourcepub fn from_stream_vert_frag<T, U>(vert: T, frag: U) -> SfResult<FBox<Self>>
pub fn from_stream_vert_frag<T, U>(vert: T, frag: U) -> SfResult<FBox<Self>>
Load both the vertex and fragment shaders from custom streams.
This function loads both the vertex and the fragment shaders. 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.
Sourcepub fn from_stream_all<T, U, V>(
vert: T,
geom: U,
frag: V,
) -> SfResult<FBox<Self>>
pub fn from_stream_all<T, U, V>( vert: T, geom: U, frag: V, ) -> SfResult<FBox<Self>>
Load the vertex, geometry and fragment shaders from custom streams.
This function loads the vertex, geometry and fragment shaders. 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.
Sourcepub fn bind(shader: Option<&Self>)
pub fn bind(shader: Option<&Self>)
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 Shader
with OpenGL code.
Sourcepub fn is_available() -> bool
pub fn is_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 Shader
will fail.
Sourcepub fn is_geometry_available() -> bool
pub fn is_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 Shader
geometry shader features will fail.
This function can only return true if Shader::is_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.
Sourcepub fn set_uniform_float(&mut self, name: &str, value: f32) -> SfResult<()>
pub fn set_uniform_float(&mut self, name: &str, value: f32) -> SfResult<()>
Specify value for float
uniform.
Examples found in repository?
49 fn update(&mut self, _t: f32, x: f32, y: f32) -> SfResult<()> {
50 self.shader
51 .set_uniform_float("pixel_threshold", (x + y) / 30.0)
52 }
53 fn name(&self) -> &str {
54 "pixelate"
55 }
56 fn as_drawable(&self) -> &dyn Drawable {
57 self
58 }
59}
60
61struct WaveBlur<'fo> {
62 text: Text<'fo>,
63 shader: FBox<Shader<'static>>,
64}
65
66const WAVEBLUR_TEXT: &str = "\
67Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.
68Mauris mi odio, bibendum quis fringilla a, laoreet vel orci. Proin vitae vulputate tortor.
69Praesent cursus ultrices justo, ut feugiat ante vehicula quis.
70Donec fringilla scelerisque mauris et viverra.
71Maecenas adipiscing ornare scelerisque. Nullam at libero elit.
72Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
73Nullam leo urna, tincidunt id semper eget, ultricies sed mi.
74Morbi mauris massa, commodo id dignissim vel, lobortis et elit.
75Fusce vel libero sed neque scelerisque venenatis.
76Integer mattis tincidunt quam vitae iaculis.
77Vivamus fringilla sem non velit venenatis fermentum.
78Vivamus varius tincidunt nisi id vehicula.
79Integer ullamcorper, enim vitae euismod rutrum, massa nisl semper ipsum,
80vestibulum sodales sem ante in massa.
81Vestibulum in augue non felis convallis viverra.
82Mauris ultricies dolor sed massa convallis sed aliquet augue fringilla.
83Duis erat eros, porta in accumsan in, blandit quis sem.
84In hac habitasse platea dictumst. Etiam fringilla est id odio dapibus sit amet semper dui laoreet.";
85
86impl<'fo> WaveBlur<'fo> {
87 fn new(font: &'fo Font) -> SfResult<Self> {
88 let mut text = Text::new(WAVEBLUR_TEXT, font, 22);
89 text.set_position((30., 20.));
90 Ok(Self {
91 text,
92 shader: Shader::from_file_vert_frag("wave.vert", "blur.frag")?,
93 })
94 }
95}
96
97impl Drawable for WaveBlur<'_> {
98 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
99 &'a self,
100 target: &mut dyn RenderTarget,
101 states: &RenderStates<'texture, 'shader, 'shader_texture>,
102 ) {
103 let mut states = *states;
104 states.shader = Some(&self.shader);
105 target.draw_with_renderstates(&self.text, &states);
106 }
107}
108
109impl Effect for WaveBlur<'_> {
110 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111 self.shader.set_uniform_float("wave_phase", t)?;
112 self.shader
113 .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114 self.shader
115 .set_uniform_float("blur_radius", (x + y) * 0.008)
116 }
117 fn name(&self) -> &str {
118 "wave + blur"
119 }
120 fn as_drawable(&self) -> &dyn Drawable {
121 self
122 }
123}
124
125struct StormBlink {
126 points: Vec<Vertex>,
127 shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131 fn new() -> SfResult<Self> {
132 use rand::{thread_rng, Rng};
133 let mut rng = thread_rng();
134
135 let mut points = Vec::new();
136 for _ in 0..40_000 {
137 let x = rng.gen_range(0.0..800.);
138 let y = rng.gen_range(0.0..600.);
139 let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140 points.push(Vertex::with_pos_color(
141 Vector2f::new(x, y),
142 Color::rgb(red, green, blue),
143 ));
144 }
145
146 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147 Ok(Self { points, shader })
148 }
149}
150
151impl Drawable for StormBlink {
152 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
153 &'a self,
154 target: &mut dyn RenderTarget,
155 states: &RenderStates<'texture, 'shader, 'shader_texture>,
156 ) {
157 let mut states = *states;
158 states.shader = Some(&self.shader);
159 target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
160 }
161}
162
163impl Effect for StormBlink {
164 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
165 let radius = 200. + t.cos() * 150.;
166 self.shader
167 .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
168 self.shader
169 .set_uniform_float("storm_inner_radius", radius / 3.)?;
170 self.shader
171 .set_uniform_float("storm_total_radius", radius)?;
172 self.shader
173 .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
174 }
175 fn name(&self) -> &str {
176 "storm + blink"
177 }
178 fn as_drawable(&self) -> &dyn Drawable {
179 self
180 }
181}
182
183struct Edge<'t> {
184 surface: FBox<RenderTexture>,
185 bg_sprite: Sprite<'t>,
186 entities: Vec<Sprite<'t>>,
187 shader: FBox<Shader<'static>>,
188}
189
190impl<'t> Edge<'t> {
191 fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
192 let mut surface = RenderTexture::new(800, 600)?;
193 surface.set_smooth(true);
194 let mut bg_sprite = Sprite::with_texture(bg_texture);
195 bg_sprite.set_position((135., 100.));
196 let mut entities = Vec::new();
197
198 for i in 0..6 {
199 entities.push(Sprite::with_texture_and_rect(
200 entity_texture,
201 IntRect::new(96 * i, 0, 96, 96),
202 ));
203 }
204
205 let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
206 shader.set_uniform_current_texture("texture")?;
207
208 Ok(Self {
209 surface,
210 bg_sprite,
211 entities,
212 shader,
213 })
214 }
215}
216
217impl Drawable for Edge<'_> {
218 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
219 &'a self,
220 target: &mut dyn RenderTarget,
221 states: &RenderStates<'texture, 'shader, 'shader_texture>,
222 ) {
223 let mut states = *states;
224 states.shader = Some(&self.shader);
225 target.draw_with_renderstates(&Sprite::with_texture(self.surface.texture()), &states);
226 }
227}
228
229impl Effect for Edge<'_> {
230 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
231 self.shader
232 .set_uniform_float("edge_threshold", 1. - (x + y) / 2.)?;
233 let entities_len = self.entities.len() as f32;
234
235 for (i, en) in self.entities.iter_mut().enumerate() {
236 let pos = (
237 (0.25 * (t * i as f32 + (entities_len - i as f32))).cos() * 300. + 350.,
238 (0.25 * (t * (entities_len - i as f32) + i as f32)).cos() * 200. + 250.,
239 );
240 en.set_position(pos);
241 }
242 self.surface.clear(Color::WHITE);
243 self.surface.draw(&self.bg_sprite);
244 for en in &self.entities {
245 self.surface.draw(en);
246 }
247 self.surface.display();
248 Ok(())
249 }
Sourcepub fn set_uniform_vec2(&mut self, name: &str, value: Vec2) -> SfResult<()>
pub fn set_uniform_vec2(&mut self, name: &str, value: Vec2) -> SfResult<()>
Specify value for vec2
uniform.
Examples found in repository?
110 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
111 self.shader.set_uniform_float("wave_phase", t)?;
112 self.shader
113 .set_uniform_vec2("wave_amplitude", Vector2f::new(x * 40., y * 40.))?;
114 self.shader
115 .set_uniform_float("blur_radius", (x + y) * 0.008)
116 }
117 fn name(&self) -> &str {
118 "wave + blur"
119 }
120 fn as_drawable(&self) -> &dyn Drawable {
121 self
122 }
123}
124
125struct StormBlink {
126 points: Vec<Vertex>,
127 shader: FBox<Shader<'static>>,
128}
129
130impl StormBlink {
131 fn new() -> SfResult<Self> {
132 use rand::{thread_rng, Rng};
133 let mut rng = thread_rng();
134
135 let mut points = Vec::new();
136 for _ in 0..40_000 {
137 let x = rng.gen_range(0.0..800.);
138 let y = rng.gen_range(0.0..600.);
139 let (red, green, blue) = (rng.r#gen(), rng.r#gen(), rng.r#gen());
140 points.push(Vertex::with_pos_color(
141 Vector2f::new(x, y),
142 Color::rgb(red, green, blue),
143 ));
144 }
145
146 let shader = Shader::from_file_vert_frag("storm.vert", "blink.frag")?;
147 Ok(Self { points, shader })
148 }
149}
150
151impl Drawable for StormBlink {
152 fn draw<'a: 'shader, 'texture, 'shader, 'shader_texture>(
153 &'a self,
154 target: &mut dyn RenderTarget,
155 states: &RenderStates<'texture, 'shader, 'shader_texture>,
156 ) {
157 let mut states = *states;
158 states.shader = Some(&self.shader);
159 target.draw_primitives(&self.points, PrimitiveType::POINTS, &states);
160 }
161}
162
163impl Effect for StormBlink {
164 fn update(&mut self, t: f32, x: f32, y: f32) -> SfResult<()> {
165 let radius = 200. + t.cos() * 150.;
166 self.shader
167 .set_uniform_vec2("storm_position", Vector2f::new(x * 800., y * 600.))?;
168 self.shader
169 .set_uniform_float("storm_inner_radius", radius / 3.)?;
170 self.shader
171 .set_uniform_float("storm_total_radius", radius)?;
172 self.shader
173 .set_uniform_float("blink_alpha", 0.5 + (t * 3.).cos() * 0.25)
174 }
Sourcepub fn set_uniform_vec3(&mut self, name: &str, value: Vec3) -> SfResult<()>
pub fn set_uniform_vec3(&mut self, name: &str, value: Vec3) -> SfResult<()>
Specify value for vec3
uniform.
Sourcepub fn set_uniform_vec4<V>(&mut self, name: &str, value: V) -> SfResult<()>
pub fn set_uniform_vec4<V>(&mut self, name: &str, value: V) -> SfResult<()>
Specify value for vec4 uniform.
This function can also be called with Color
objects that are converted to
glsl::Vec4
.
It is important to note that the components of the color are normalized before being
passed to the shader. Therefore, they are converted from range [0 .. 255]
to range
[0 .. 1]
. For example, a Color{r: 255, g: 127, b: 0, a: 255}
will be transformed to a Vec4{x: 1.0, y: 0.5, z: 0.0, w: 1.0}
in the shader.
Sourcepub fn set_uniform_int(&mut self, name: &str, value: i32) -> SfResult<()>
pub fn set_uniform_int(&mut self, name: &str, value: i32) -> SfResult<()>
Specify value for int
uniform.
Sourcepub fn set_uniform_ivec2(&mut self, name: &str, value: IVec2) -> SfResult<()>
pub fn set_uniform_ivec2(&mut self, name: &str, value: IVec2) -> SfResult<()>
Specify value for ivec2
uniform.
Sourcepub fn set_uniform_ivec3(&mut self, name: &str, value: IVec3) -> SfResult<()>
pub fn set_uniform_ivec3(&mut self, name: &str, value: IVec3) -> SfResult<()>
Specify value for ivec3
uniform.
Sourcepub fn set_uniform_ivec4<V>(&mut self, name: &str, value: V) -> SfResult<()>
pub fn set_uniform_ivec4<V>(&mut self, name: &str, value: V) -> SfResult<()>
Specify value for ivec4
uniform.
This overload can also be called with Color
objects that are
converted to glsl::IVec4
.
If color conversions are used, the ivec4
uniform in GLSL will hold the same values
as the original Color
instance. For example, Color{r: 255, g: 127, b: 0, a: 255}
is mapped to IVec4{x: 255, y: 127, z: 0, w: 255}
.
Sourcepub fn set_uniform_bool(&mut self, name: &str, value: bool) -> SfResult<()>
pub fn set_uniform_bool(&mut self, name: &str, value: bool) -> SfResult<()>
Specify value for bool
uniform.
Sourcepub fn set_uniform_bvec2(&mut self, name: &str, value: BVec2) -> SfResult<()>
pub fn set_uniform_bvec2(&mut self, name: &str, value: BVec2) -> SfResult<()>
Specify value for bvec2
uniform.
Sourcepub fn set_uniform_bvec3(&mut self, name: &str, value: BVec3) -> SfResult<()>
pub fn set_uniform_bvec3(&mut self, name: &str, value: BVec3) -> SfResult<()>
Specify value for bvec3
uniform.
Sourcepub fn set_uniform_bvec4(&mut self, name: &str, value: BVec4) -> SfResult<()>
pub fn set_uniform_bvec4(&mut self, name: &str, value: BVec4) -> SfResult<()>
Specify value for bvec4
uniform.
Sourcepub fn set_uniform_mat3<V>(&mut self, name: &str, value: V) -> SfResult<()>
pub fn set_uniform_mat3<V>(&mut self, name: &str, value: V) -> SfResult<()>
Specify value for mat3
matrix.
Sourcepub fn set_uniform_mat4<V>(&mut self, name: &str, value: V) -> SfResult<()>
pub fn set_uniform_mat4<V>(&mut self, name: &str, value: V) -> SfResult<()>
Specify value for mat4
matrix.
Sourcepub fn set_uniform_texture(
&mut self,
name: &str,
value: &'texture Texture,
) -> SfResult<()>
pub fn set_uniform_texture( &mut self, name: &str, value: &'texture Texture, ) -> SfResult<()>
Specify a texture as sampler2D
uniform.
name
is the name of the variable to change in the shader.
The corresponding parameter in the shader must be a 2D texture (sampler2D
GLSL type).
To use the texture of the object being drawn, which cannot be known in advance,
use Shader::set_uniform_current_texture
.
Sourcepub fn set_uniform_current_texture(&mut self, name: &str) -> SfResult<()>
pub fn set_uniform_current_texture(&mut self, name: &str) -> SfResult<()>
Specify current texture as sampler2D
uniform.
This function maps a shader texture variable to the texture of the object being drawn,
which cannot be known in advance.
The corresponding parameter in the shader must be a 2D texture (sampler2D
GLSL type).
Examples found in repository?
191 fn new(bg_texture: &'t Texture, entity_texture: &'t Texture) -> SfResult<Self> {
192 let mut surface = RenderTexture::new(800, 600)?;
193 surface.set_smooth(true);
194 let mut bg_sprite = Sprite::with_texture(bg_texture);
195 bg_sprite.set_position((135., 100.));
196 let mut entities = Vec::new();
197
198 for i in 0..6 {
199 entities.push(Sprite::with_texture_and_rect(
200 entity_texture,
201 IntRect::new(96 * i, 0, 96, 96),
202 ));
203 }
204
205 let mut shader = Shader::from_file("edge.frag", ShaderType::Fragment)?;
206 shader.set_uniform_current_texture("texture")?;
207
208 Ok(Self {
209 surface,
210 bg_sprite,
211 entities,
212 shader,
213 })
214 }
Sourcepub fn set_uniform_array_float(
&mut self,
name: &str,
array: &[f32],
) -> SfResult<()>
pub fn set_uniform_array_float( &mut self, name: &str, array: &[f32], ) -> SfResult<()>
Specify values for float[]
array uniform.
Sourcepub fn set_uniform_array_vec2(
&mut self,
name: &str,
array: &[Vec2],
) -> SfResult<()>
pub fn set_uniform_array_vec2( &mut self, name: &str, array: &[Vec2], ) -> SfResult<()>
Specify values for vec2[]
array uniform.
Sourcepub fn set_uniform_array_vec3(
&mut self,
name: &str,
array: &[Vec3],
) -> SfResult<()>
pub fn set_uniform_array_vec3( &mut self, name: &str, array: &[Vec3], ) -> SfResult<()>
Specify values for vec3[]
array uniform.
Sourcepub fn set_uniform_array_vec4(
&mut self,
name: &str,
array: &[Vec4],
) -> SfResult<()>
pub fn set_uniform_array_vec4( &mut self, name: &str, array: &[Vec4], ) -> SfResult<()>
Specify values for vec4[]
array uniform.
Sourcepub fn set_uniform_array_mat3(
&mut self,
name: &str,
array: &[Mat3],
) -> SfResult<()>
pub fn set_uniform_array_mat3( &mut self, name: &str, array: &[Mat3], ) -> SfResult<()>
Specify values for mat3[]
array uniform.
Sourcepub fn set_uniform_array_mat4(
&mut self,
name: &str,
array: &[Mat4],
) -> SfResult<()>
pub fn set_uniform_array_mat4( &mut self, name: &str, array: &[Mat4], ) -> SfResult<()>
Specify values for mat4[]
array uniform.
Sourcepub fn native_handle(&self) -> u32
pub fn native_handle(&self) -> u32
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.