pub struct Rect {
pub x: f32,
pub y: f32,
pub w: f32,
pub h: f32,
}
Expand description
A 2D rectangle, defined by its top-left corner, width and height.
Fields§
§x: f32
§y: f32
§w: f32
§h: f32
Implementations§
Source§impl Rect
impl Rect
Sourcepub const fn new(x: f32, y: f32, w: f32, h: f32) -> Rect
pub const fn new(x: f32, y: f32, w: f32, h: f32) -> Rect
Creates a new rectangle from its top-left corner, width and height.
§Arguments:
x
- x-coordinate of the top-left corner.y
- y-coordinate of the top-left corner.w
- width of theRect
, going to the right.h
- height of theRect
, going down.
Examples found in repository?
examples/letterbox.rs (line 14)
7async fn main() {
8 // Setup 'render_target', used to hold the rendering result so we can resize it
9 let render_target = render_target(VIRTUAL_WIDTH as u32, VIRTUAL_HEIGHT as u32);
10 render_target.texture.set_filter(FilterMode::Linear);
11
12 // Setup camera for the virtual screen, that will render to 'render_target'
13 let mut render_target_cam =
14 Camera2D::from_display_rect(Rect::new(0., 0., VIRTUAL_WIDTH, VIRTUAL_HEIGHT));
15 render_target_cam.render_target = Some(render_target.clone());
16
17 loop {
18 // Get required scaling value
19 let scale: f32 = f32::min(
20 screen_width() / VIRTUAL_WIDTH,
21 screen_height() / VIRTUAL_HEIGHT,
22 );
23
24 // Mouse position in the virtual screen
25 let virtual_mouse_pos = Vec2 {
26 x: (mouse_position().0 - (screen_width() - (VIRTUAL_WIDTH * scale)) * 0.5) / scale,
27 y: (mouse_position().1 - (screen_height() - (VIRTUAL_HEIGHT * scale)) * 0.5) / scale,
28 };
29
30 // ------------------------------------------------------------------------
31 // Begin drawing the virtual screen to 'render_target'
32 // ------------------------------------------------------------------------
33 set_camera(&render_target_cam);
34
35 clear_background(LIGHTGRAY);
36
37 draw_text("Hello Letterbox", 20.0, 20.0, 30.0, DARKGRAY);
38 draw_circle(VIRTUAL_WIDTH / 2.0 - 65.0, VIRTUAL_HEIGHT / 2.0, 35.0, RED);
39 draw_circle(VIRTUAL_WIDTH / 2.0 + 65.0, VIRTUAL_HEIGHT / 2.0, 35.0, BLUE);
40 draw_circle(
41 VIRTUAL_WIDTH / 2.0,
42 VIRTUAL_HEIGHT / 2.0 - 65.0,
43 35.0,
44 YELLOW,
45 );
46
47 draw_circle(virtual_mouse_pos.x, virtual_mouse_pos.y, 15.0, BLACK);
48
49 // ------------------------------------------------------------------------
50 // Begin drawing the window screen
51 // ------------------------------------------------------------------------
52 set_default_camera();
53
54 clear_background(BLACK); // Will be the letterbox color
55
56 // Draw 'render_target' to window screen, porperly scaled and letterboxed
57 draw_texture_ex(
58 &render_target.texture,
59 (screen_width() - (VIRTUAL_WIDTH * scale)) * 0.5,
60 (screen_height() - (VIRTUAL_HEIGHT * scale)) * 0.5,
61 WHITE,
62 DrawTextureParams {
63 dest_size: Some(vec2(VIRTUAL_WIDTH * scale, VIRTUAL_HEIGHT * scale)),
64 flip_y: true, // Must flip y otherwise 'render_target' will be upside down
65 ..Default::default()
66 },
67 );
68
69 next_frame().await;
70 }
71}
More examples
examples/shadertoy.rs (line 212)
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 scale(&mut self, sx: f32, sy: f32)
pub fn scale(&mut self, sx: f32, sy: f32)
Scales the Rect
by a factor of (sx, sy),
growing towards the bottom-left
Sourcepub fn combine_with(self, other: Rect) -> Rect
pub fn combine_with(self, other: Rect) -> Rect
Returns a new Rect
that includes all points of these two Rect
s.
Trait Implementations§
impl Copy for Rect
impl StructuralPartialEq for Rect
Auto Trait Implementations§
impl Freeze for Rect
impl RefUnwindSafe for Rect
impl Send for Rect
impl Sync for Rect
impl Unpin for Rect
impl UnwindSafe for Rect
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