pub const fn vec3(x: f32, y: f32, z: f32) -> Vec3
Expand description
Creates a 3-dimensional vector.
Examples found in repository?
examples/tree.rs (line 12)
3fn tree(gl: &mut QuadGl, time: f64, deep: u32, angle: f32, tall: f32) {
4 if deep >= 8 {
5 return;
6 }
7
8 // we can use normal macroquad drawing API here
9 draw_rectangle(-0.01 / 2., 0., 0.01, tall, DARKGRAY);
10
11 // and we can also modify internal macroquad render state with "gl" reference
12 gl.push_model_matrix(glam::Mat4::from_translation(glam::vec3(0., tall, 0.)));
13
14 // right leaf
15 gl.push_model_matrix(glam::Mat4::from_rotation_z(angle + time.sin() as f32 * 0.1));
16 tree(gl, time, deep + 1, angle * 0.7, tall * 0.8);
17 gl.pop_model_matrix();
18
19 // left leaf
20 gl.push_model_matrix(glam::Mat4::from_rotation_z(
21 -angle - time.cos() as f32 * 0.1,
22 ));
23 tree(gl, time, deep + 1, angle * 0.7, tall * 0.8);
24 gl.pop_model_matrix();
25
26 gl.pop_model_matrix();
27}
More examples
examples/3d.rs (line 14)
4async fn main() {
5 let rust_logo = load_texture("examples/rust.png").await.unwrap();
6 let ferris = load_texture("examples/ferris.png").await.unwrap();
7
8 loop {
9 clear_background(LIGHTGRAY);
10
11 // Going 3d!
12
13 set_camera(&Camera3D {
14 position: vec3(-20., 15., 0.),
15 up: vec3(0., 1., 0.),
16 target: vec3(0., 0., 0.),
17 ..Default::default()
18 });
19
20 draw_grid(20, 1., BLACK, GRAY);
21
22 draw_cube_wires(vec3(0., 1., -6.), vec3(2., 2., 2.), DARKGREEN);
23 draw_cube_wires(vec3(0., 1., 6.), vec3(2., 2., 2.), DARKBLUE);
24 draw_cube_wires(vec3(2., 1., 2.), vec3(2., 2., 2.), YELLOW);
25
26 draw_plane(vec3(-8., 0., -8.), vec2(5., 5.), Some(&ferris), WHITE);
27
28 draw_cube(
29 vec3(-5., 1., -2.),
30 vec3(2., 2., 2.),
31 Some(&rust_logo),
32 WHITE,
33 );
34 draw_cube(vec3(-5., 1., 2.), vec3(2., 2., 2.), Some(&ferris), WHITE);
35 draw_cube(vec3(2., 0., -2.), vec3(0.4, 0.4, 0.4), None, BLACK);
36
37 draw_sphere(vec3(-8., 0., 0.), 1., None, BLUE);
38
39 // Back to screen space, render some text
40
41 set_default_camera();
42 draw_text("WELCOME TO 3D WORLD", 10.0, 20.0, 30.0, BLACK);
43
44 next_frame().await
45 }
46}
examples/first_person.rs (line 23)
18async fn main() {
19 let mut x = 0.0;
20 let mut switch = false;
21 let bounds = 8.0;
22
23 let world_up = vec3(0.0, 1.0, 0.0);
24 let mut yaw: f32 = 1.18;
25 let mut pitch: f32 = 0.0;
26
27 let mut front = vec3(
28 yaw.cos() * pitch.cos(),
29 pitch.sin(),
30 yaw.sin() * pitch.cos(),
31 )
32 .normalize();
33 let mut right = front.cross(world_up).normalize();
34 let mut up = right.cross(front).normalize();
35
36 let mut position = vec3(0.0, 1.0, 0.0);
37 let mut last_mouse_position: Vec2 = mouse_position().into();
38
39 let mut grabbed = true;
40 set_cursor_grab(grabbed);
41 show_mouse(false);
42
43 loop {
44 let delta = get_frame_time();
45
46 if is_key_pressed(KeyCode::Escape) {
47 break;
48 }
49 if is_key_pressed(KeyCode::Tab) {
50 grabbed = !grabbed;
51 set_cursor_grab(grabbed);
52 show_mouse(!grabbed);
53 }
54
55 if is_key_down(KeyCode::Up) {
56 position += front * MOVE_SPEED;
57 }
58 if is_key_down(KeyCode::Down) {
59 position -= front * MOVE_SPEED;
60 }
61 if is_key_down(KeyCode::Left) {
62 position -= right * MOVE_SPEED;
63 }
64 if is_key_down(KeyCode::Right) {
65 position += right * MOVE_SPEED;
66 }
67
68 let mouse_position: Vec2 = mouse_position().into();
69 let mouse_delta = mouse_position - last_mouse_position;
70
71 last_mouse_position = mouse_position;
72
73 if grabbed {
74 yaw += mouse_delta.x * delta * LOOK_SPEED;
75 pitch += mouse_delta.y * delta * -LOOK_SPEED;
76
77 pitch = if pitch > 1.5 { 1.5 } else { pitch };
78 pitch = if pitch < -1.5 { -1.5 } else { pitch };
79
80 front = vec3(
81 yaw.cos() * pitch.cos(),
82 pitch.sin(),
83 yaw.sin() * pitch.cos(),
84 )
85 .normalize();
86
87 right = front.cross(world_up).normalize();
88 up = right.cross(front).normalize();
89
90 x += if switch { 0.04 } else { -0.04 };
91 if x >= bounds || x <= -bounds {
92 switch = !switch;
93 }
94 }
95
96 clear_background(LIGHTGRAY);
97
98 // Going 3d!
99
100 set_camera(&Camera3D {
101 position: position,
102 up: up,
103 target: position + front,
104 ..Default::default()
105 });
106
107 draw_grid(20, 1., BLACK, GRAY);
108
109 draw_line_3d(
110 vec3(x, 0.0, x),
111 vec3(5.0, 5.0, 5.0),
112 Color::new(1.0, 1.0, 0.0, 1.0),
113 );
114
115 draw_cube_wires(vec3(0., 1., -6.), vec3(2., 2., 2.), GREEN);
116 draw_cube_wires(vec3(0., 1., 6.), vec3(2., 2., 2.), BLUE);
117 draw_cube_wires(vec3(2., 1., 2.), vec3(2., 2., 2.), RED);
118
119 // Back to screen space, render some text
120
121 set_default_camera();
122 draw_text("First Person Camera", 10.0, 20.0, 30.0, BLACK);
123
124 draw_text(
125 format!("X: {} Y: {}", mouse_position.x, mouse_position.y).as_str(),
126 10.0,
127 48.0 + 18.0,
128 30.0,
129 BLACK,
130 );
131 draw_text(
132 format!("Press <TAB> to toggle mouse grab: {grabbed}").as_str(),
133 10.0,
134 48.0 + 42.0,
135 30.0,
136 BLACK,
137 );
138
139 next_frame().await
140 }
141}
examples/shadertoy.rs (line 81)
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}