pub struct Material { /* private fields */ }Expand description
Material instance loaded on GPU.
Implementations§
Source§impl Material
impl Material
Sourcepub fn set_uniform<T>(&self, name: &str, uniform: T)
pub fn set_uniform<T>(&self, name: &str, uniform: T)
Set GPU uniform value for this material. “name” should be from “uniforms” list used for material creation. Otherwise uniform value would be silently ignored.
Examples found in repository?
examples/screen_texture.rs (line 34)
4async fn main() {
5 let texture: Texture2D = load_texture("examples/chess.png").await.unwrap();
6
7 let lens_material = load_material(
8 ShaderSource::Glsl {
9 vertex: LENS_VERTEX_SHADER,
10 fragment: LENS_FRAGMENT_SHADER,
11 },
12 MaterialParams {
13 uniforms: vec![UniformDesc::new("Center", UniformType::Float2)],
14 ..Default::default()
15 },
16 )
17 .unwrap();
18
19 loop {
20 clear_background(WHITE);
21 draw_texture_ex(
22 &texture,
23 0.0,
24 0.0,
25 WHITE,
26 DrawTextureParams {
27 dest_size: Some(vec2(screen_width(), screen_height())),
28 ..Default::default()
29 },
30 );
31
32 let lens_center = mouse_position();
33
34 lens_material.set_uniform("Center", lens_center);
35
36 gl_use_material(&lens_material);
37 draw_circle(lens_center.0, lens_center.1, 250.0, RED);
38 gl_use_default_material();
39
40 next_frame().await
41 }
42}More examples
examples/custom_material.rs (line 84)
40async fn main() {
41 let pipeline_params = PipelineParams {
42 color_blend: Some(BlendState::new(
43 Equation::Add,
44 BlendFactor::Value(BlendValue::SourceAlpha),
45 BlendFactor::OneMinusValue(BlendValue::SourceAlpha),
46 )),
47 ..Default::default()
48 };
49
50 let mat = load_material(
51 ShaderSource::Glsl {
52 vertex: VERTEX,
53 fragment: FRAGMENT,
54 },
55 MaterialParams {
56 uniforms: vec![UniformDesc::new("test_color", UniformType::Float4)],
57 pipeline_params,
58 ..Default::default()
59 },
60 )
61 .unwrap();
62
63 let mat_with_array = load_material(
64 ShaderSource::Glsl {
65 vertex: VERTEX,
66 fragment: FRAGMENT_WITH_ARRAY,
67 },
68 MaterialParams {
69 uniforms: vec![UniformDesc::array(
70 UniformDesc::new("test_color", UniformType::Float4),
71 10,
72 )],
73 pipeline_params,
74 ..Default::default()
75 },
76 )
77 .unwrap();
78
79 loop {
80 clear_background(GRAY);
81
82 gl_use_material(&mat);
83
84 mat.set_uniform("test_color", vec4(1., 0., 0., 1.));
85
86 draw_rectangle(50.0, 50.0, 100., 100., WHITE);
87
88 mat.set_uniform("test_color", vec4(0., 1., 0., 1.));
89 draw_rectangle(160.0, 50.0, 100., 100., WHITE);
90
91 mat.set_uniform("test_color", vec4(0., 0., 1., 1.));
92 draw_rectangle(270.0, 50.0, 100., 100., WHITE);
93
94 gl_use_material(&mat_with_array);
95 let mut colors: [Vec4; 10] = [vec4(0.0, 1.0, 0.0, 0.0); 10];
96 colors[5] = vec4(0.0, 1.0, 1.0, 1.0);
97 mat_with_array.set_uniform_array("test_color", &colors[..]);
98 draw_rectangle(50.0, 160.0, 100., 100., WHITE);
99
100 gl_use_default_material();
101
102 draw_rectangle(380.0, 50.0, 100., 100., YELLOW);
103
104 next_frame().await
105 }
106}examples/shadertoy.rs (line 159)
47async fn main() {
48 let ferris = load_texture("examples/rust.png").await.unwrap();
49 let (color_picker_texture, color_picker_image) = color_picker_texture(200, 200);
50
51 let mut fragment_shader = DEFAULT_FRAGMENT_SHADER.to_string();
52 let mut vertex_shader = DEFAULT_VERTEX_SHADER.to_string();
53
54 let pipeline_params = PipelineParams {
55 depth_write: true,
56 depth_test: Comparison::LessOrEqual,
57 ..Default::default()
58 };
59
60 let mut material = load_material(
61 ShaderSource::Glsl {
62 vertex: &vertex_shader,
63 fragment: &fragment_shader,
64 },
65 MaterialParams {
66 pipeline_params,
67 ..Default::default()
68 },
69 )
70 .unwrap();
71 let mut error: Option<String> = None;
72
73 enum Mesh {
74 Sphere,
75 Cube,
76 Plane,
77 }
78 let mut mesh = Mesh::Sphere;
79
80 let mut camera = Camera3D {
81 position: vec3(-15., 15., -5.),
82 up: vec3(0., 1., 0.),
83 target: vec3(0., 5., -5.),
84 ..Default::default()
85 };
86
87 let mut colorpicker_window = false;
88 let mut color_picking_uniform = None;
89
90 let mut new_uniform_window = false;
91 let mut new_uniform_name = String::new();
92 let mut uniforms: Vec<(String, Uniform)> = vec![];
93
94 loop {
95 clear_background(WHITE);
96
97 set_camera(&camera);
98
99 draw_grid(
100 20,
101 1.,
102 Color::new(0.55, 0.55, 0.55, 0.75),
103 Color::new(0.75, 0.75, 0.75, 0.75),
104 );
105
106 gl_use_material(&material);
107 match mesh {
108 Mesh::Plane => draw_plane(vec3(0., 2., 0.), vec2(5., 5.), Some(&ferris), WHITE),
109 Mesh::Sphere => draw_sphere(vec3(0., 6., 0.), 5., Some(&ferris), WHITE),
110 Mesh::Cube => draw_cube(vec3(0., 5., 0.), vec3(10., 10., 10.), Some(&ferris), WHITE),
111 }
112 gl_use_default_material();
113
114 set_default_camera();
115
116 let mut need_update = false;
117
118 widgets::Window::new(hash!(), vec2(20., 20.), vec2(470., 650.))
119 .label("Shader")
120 .ui(&mut *root_ui(), |ui| {
121 ui.label(None, "Camera: ");
122 ui.same_line(0.0);
123 if ui.button(None, "Ortho") {
124 camera.projection = Projection::Orthographics;
125 }
126 ui.same_line(0.0);
127 if ui.button(None, "Perspective") {
128 camera.projection = Projection::Perspective;
129 }
130 ui.label(None, "Mesh: ");
131 ui.same_line(0.0);
132 if ui.button(None, "Sphere") {
133 mesh = Mesh::Sphere;
134 }
135 ui.same_line(0.0);
136 if ui.button(None, "Cube") {
137 mesh = Mesh::Cube;
138 }
139 ui.same_line(0.0);
140 if ui.button(None, "Plane") {
141 mesh = Mesh::Plane;
142 }
143
144 ui.label(None, "Uniforms:");
145 ui.separator();
146
147 for (i, (name, uniform)) in uniforms.iter_mut().enumerate() {
148 ui.label(None, &format!("{name}"));
149 ui.same_line(120.0);
150
151 match uniform {
152 Uniform::Float1(x) => {
153 widgets::InputText::new(hash!(hash!(), i))
154 .size(vec2(200.0, 19.0))
155 .filter_numbers()
156 .ui(ui, x);
157
158 if let Ok(x) = x.parse::<f32>() {
159 material.set_uniform(name, x);
160 }
161 }
162 Uniform::Float2(x, y) => {
163 widgets::InputText::new(hash!(hash!(), i))
164 .size(vec2(99.0, 19.0))
165 .filter_numbers()
166 .ui(ui, x);
167
168 ui.same_line(0.0);
169
170 widgets::InputText::new(hash!(hash!(), i))
171 .size(vec2(99.0, 19.0))
172 .filter_numbers()
173 .ui(ui, y);
174
175 if let (Ok(x), Ok(y)) = (x.parse::<f32>(), y.parse::<f32>()) {
176 material.set_uniform(name, (x, y));
177 }
178 }
179 Uniform::Float3(x, y, z) => {
180 widgets::InputText::new(hash!(hash!(), i))
181 .size(vec2(65.0, 19.0))
182 .filter_numbers()
183 .ui(ui, x);
184
185 ui.same_line(0.0);
186
187 widgets::InputText::new(hash!(hash!(), i))
188 .size(vec2(65.0, 19.0))
189 .filter_numbers()
190 .ui(ui, y);
191
192 ui.same_line(0.0);
193
194 widgets::InputText::new(hash!(hash!(), i))
195 .size(vec2(65.0, 19.0))
196 .filter_numbers()
197 .ui(ui, z);
198
199 if let (Ok(x), Ok(y), Ok(z)) =
200 (x.parse::<f32>(), y.parse::<f32>(), z.parse::<f32>())
201 {
202 material.set_uniform(name, (x, y, z));
203 }
204 }
205
206 Uniform::Color(color) => {
207 let mut canvas = ui.canvas();
208
209 let cursor = canvas.cursor();
210
211 canvas.rect(
212 Rect::new(cursor.x + 20.0, cursor.y, 50.0, 18.0),
213 Color::new(0.2, 0.2, 0.2, 1.0),
214 Color::new(color.x, color.y, color.z, 1.0),
215 );
216
217 if ui.button(None, "change") {
218 colorpicker_window = true;
219 color_picking_uniform = Some(name.to_owned());
220 }
221 material.set_uniform(name, (color.x, color.y, color.z));
222 }
223 }
224 }
225 ui.separator();
226 if ui.button(None, "New uniform") {
227 new_uniform_window = true;
228 }
229 TreeNode::new(hash!(), "Fragment shader")
230 .init_unfolded()
231 .ui(ui, |ui| {
232 if ui.editbox(hash!(), vec2(440., 200.), &mut fragment_shader) {
233 need_update = true;
234 };
235 });
236 ui.tree_node(hash!(), "Vertex shader", |ui| {
237 if ui.editbox(hash!(), vec2(440., 300.), &mut vertex_shader) {
238 need_update = true;
239 };
240 });
241
242 if let Some(ref error) = error {
243 Label::new(error).multiline(14.0).ui(ui);
244 }
245 });
246
247 if new_uniform_window {
248 widgets::Window::new(hash!(), vec2(100., 100.), vec2(200., 80.))
249 .label("New uniform")
250 .ui(&mut *root_ui(), |ui| {
251 if ui.active_window_focused() == false {
252 new_uniform_window = false;
253 }
254 ui.input_text(hash!(), "Name", &mut new_uniform_name);
255 let uniform_type = ui.combo_box(
256 hash!(),
257 "Type",
258 &["Float1", "Float2", "Float3", "Color"],
259 None,
260 );
261
262 if ui.button(None, "Add") {
263 if new_uniform_name.is_empty() == false {
264 let uniform = match uniform_type {
265 0 => Uniform::Float1("0".to_string()),
266 1 => Uniform::Float2("0".to_string(), "0".to_string()),
267 2 => Uniform::Float3(
268 "0".to_string(),
269 "0".to_string(),
270 "0".to_string(),
271 ),
272 3 => Uniform::Color(vec3(0.0, 0.0, 0.0)),
273 _ => unreachable!(),
274 };
275 uniforms.push((new_uniform_name.clone(), uniform));
276 new_uniform_name.clear();
277 need_update = true;
278 }
279 new_uniform_window = false;
280 }
281
282 ui.same_line(0.0);
283 if ui.button(None, "Cancel") {
284 new_uniform_window = false;
285 }
286 });
287 }
288
289 if colorpicker_window {
290 colorpicker_window &= widgets::Window::new(hash!(), vec2(140., 100.), vec2(210., 240.))
291 .label("Colorpicker")
292 .ui(&mut *root_ui(), |ui| {
293 if ui.active_window_focused() == false {
294 colorpicker_window = false;
295 }
296
297 let mut canvas = ui.canvas();
298 let cursor = canvas.cursor();
299 let mouse = mouse_position();
300 let x = mouse.0 as i32 - cursor.x as i32;
301 let y = mouse.1 as i32 - (cursor.y as i32 + 20);
302
303 let color = color_picker_image
304 .get_pixel(x.max(0).min(199) as u32, y.max(0).min(199) as u32);
305
306 canvas.rect(
307 Rect::new(cursor.x, cursor.y, 200.0, 18.0),
308 Color::new(0.0, 0.0, 0.0, 1.0),
309 Color::new(color.r, color.g, color.b, 1.0),
310 );
311 canvas.image(
312 Rect::new(cursor.x, cursor.y + 20.0, 200.0, 200.0),
313 &color_picker_texture,
314 );
315
316 if x >= 0 && x < 200 && y >= 0 && y < 200 {
317 canvas.rect(
318 Rect::new(mouse.0 - 3.5, mouse.1 - 3.5, 7.0, 7.0),
319 Color::new(0.3, 0.3, 0.3, 1.0),
320 Color::new(1.0, 1.0, 1.0, 1.0),
321 );
322
323 if is_mouse_button_down(MouseButton::Left) {
324 colorpicker_window = false;
325 let uniform_name = color_picking_uniform.take().unwrap();
326
327 uniforms
328 .iter_mut()
329 .find(|(name, _)| name == &uniform_name)
330 .unwrap()
331 .1 = Uniform::Color(vec3(color.r, color.g, color.b));
332 }
333 }
334 });
335 }
336
337 if need_update {
338 let uniforms = uniforms
339 .iter()
340 .map(|(name, uniform)| UniformDesc::new(name, uniform.uniform_type()))
341 .collect::<Vec<_>>();
342
343 match load_material(
344 ShaderSource::Glsl {
345 vertex: &vertex_shader,
346 fragment: &fragment_shader,
347 },
348 MaterialParams {
349 pipeline_params,
350 uniforms,
351 textures: vec![],
352 },
353 ) {
354 Ok(new_material) => {
355 material = new_material;
356 error = None;
357 }
358 Err(err) => {
359 error = Some(format!("{err:#?}"));
360 }
361 }
362 }
363
364 next_frame().await
365 }
366}Sourcepub fn set_uniform_array<T: ToBytes>(&self, name: &str, uniform: &[T])
pub fn set_uniform_array<T: ToBytes>(&self, name: &str, uniform: &[T])
Examples found in repository?
examples/custom_material.rs (line 97)
40async fn main() {
41 let pipeline_params = PipelineParams {
42 color_blend: Some(BlendState::new(
43 Equation::Add,
44 BlendFactor::Value(BlendValue::SourceAlpha),
45 BlendFactor::OneMinusValue(BlendValue::SourceAlpha),
46 )),
47 ..Default::default()
48 };
49
50 let mat = load_material(
51 ShaderSource::Glsl {
52 vertex: VERTEX,
53 fragment: FRAGMENT,
54 },
55 MaterialParams {
56 uniforms: vec![UniformDesc::new("test_color", UniformType::Float4)],
57 pipeline_params,
58 ..Default::default()
59 },
60 )
61 .unwrap();
62
63 let mat_with_array = load_material(
64 ShaderSource::Glsl {
65 vertex: VERTEX,
66 fragment: FRAGMENT_WITH_ARRAY,
67 },
68 MaterialParams {
69 uniforms: vec![UniformDesc::array(
70 UniformDesc::new("test_color", UniformType::Float4),
71 10,
72 )],
73 pipeline_params,
74 ..Default::default()
75 },
76 )
77 .unwrap();
78
79 loop {
80 clear_background(GRAY);
81
82 gl_use_material(&mat);
83
84 mat.set_uniform("test_color", vec4(1., 0., 0., 1.));
85
86 draw_rectangle(50.0, 50.0, 100., 100., WHITE);
87
88 mat.set_uniform("test_color", vec4(0., 1., 0., 1.));
89 draw_rectangle(160.0, 50.0, 100., 100., WHITE);
90
91 mat.set_uniform("test_color", vec4(0., 0., 1., 1.));
92 draw_rectangle(270.0, 50.0, 100., 100., WHITE);
93
94 gl_use_material(&mat_with_array);
95 let mut colors: [Vec4; 10] = [vec4(0.0, 1.0, 0.0, 0.0); 10];
96 colors[5] = vec4(0.0, 1.0, 1.0, 1.0);
97 mat_with_array.set_uniform_array("test_color", &colors[..]);
98 draw_rectangle(50.0, 160.0, 100., 100., WHITE);
99
100 gl_use_default_material();
101
102 draw_rectangle(380.0, 50.0, 100., 100., YELLOW);
103
104 next_frame().await
105 }
106}pub fn set_texture(&self, name: &str, texture: Texture2D)
Trait Implementations§
impl StructuralPartialEq for Material
Auto Trait Implementations§
impl Freeze for Material
impl RefUnwindSafe for Material
impl Send for Material
impl Sync for Material
impl Unpin for Material
impl UnwindSafe for Material
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more