pub struct Texture2D { /* private fields */ }Expand description
Texture, data stored in GPU memory
Implementations§
Source§impl Texture2D
impl Texture2D
pub fn weak_clone(&self) -> Texture2D
Sourcepub fn from_file_with_format(
bytes: &[u8],
format: Option<ImageFormat>,
) -> Texture2D
pub fn from_file_with_format( bytes: &[u8], format: Option<ImageFormat>, ) -> Texture2D
Creates a Texture2D from a slice of bytes that contains an encoded image.
If format is None, it will make an educated guess on the
ImageFormat.
§Example
let texture = Texture2D::from_file_with_format(
include_bytes!("../examples/rust.png"),
None,
);Sourcepub fn from_image(image: &Image) -> Texture2D
pub fn from_image(image: &Image) -> Texture2D
Creates a Texture2D from an Image.
Examples found in repository?
28fn color_picker_texture(w: usize, h: usize) -> (Texture2D, Image) {
29 let ratio = 1.0 / h as f32;
30
31 let mut image = Image::gen_image_color(w as u16, h as u16, WHITE);
32 let image_data = image.get_image_data_mut();
33
34 for j in 0..h {
35 for i in 0..w {
36 let lightness = 1.0 - i as f32 * ratio;
37 let hue = j as f32 * ratio;
38
39 image_data[i + j * w] = color::hsl_to_rgb(hue, 1.0, lightness).into();
40 }
41 }
42
43 (Texture2D::from_image(&image), image)
44}More examples
10async fn main() {
11 let w = screen_width() as usize;
12 let h = screen_height() as usize;
13
14 let mut cells = vec![CellState::Dead; w * h];
15 let mut buffer = vec![CellState::Dead; w * h];
16
17 let mut image = Image::gen_image_color(w as u16, h as u16, WHITE);
18
19 for cell in cells.iter_mut() {
20 if rand::gen_range(0, 5) == 0 {
21 *cell = CellState::Alive;
22 }
23 }
24 let texture = Texture2D::from_image(&image);
25
26 loop {
27 clear_background(WHITE);
28
29 let w = image.width();
30 let h = image.height();
31
32 for y in 0..h as i32 {
33 for x in 0..w as i32 {
34 let mut neighbors_count = 0;
35
36 for j in -1i32..=1 {
37 for i in -1i32..=1 {
38 // out of bounds
39 if y + j < 0 || y + j >= h as i32 || x + i < 0 || x + i >= w as i32 {
40 continue;
41 }
42 // cell itself
43 if i == 0 && j == 0 {
44 continue;
45 }
46
47 let neighbor = cells[(y + j) as usize * w + (x + i) as usize];
48 if neighbor == CellState::Alive {
49 neighbors_count += 1;
50 }
51 }
52 }
53
54 let current_cell = cells[y as usize * w + x as usize];
55 buffer[y as usize * w + x as usize] = match (current_cell, neighbors_count) {
56 // Rule 1: Any live cell with fewer than two live neighbours
57 // dies, as if caused by underpopulation.
58 (CellState::Alive, x) if x < 2 => CellState::Dead,
59 // Rule 2: Any live cell with two or three live neighbours
60 // lives on to the next generation.
61 (CellState::Alive, 2) | (CellState::Alive, 3) => CellState::Alive,
62 // Rule 3: Any live cell with more than three live
63 // neighbours dies, as if by overpopulation.
64 (CellState::Alive, x) if x > 3 => CellState::Dead,
65 // Rule 4: Any dead cell with exactly three live neighbours
66 // becomes a live cell, as if by reproduction.
67 (CellState::Dead, 3) => CellState::Alive,
68 // All other cells remain in the same state.
69 (otherwise, _) => otherwise,
70 };
71 }
72 }
73
74 for i in 0..buffer.len() {
75 cells[i] = buffer[i];
76
77 image.set_pixel(
78 (i % w) as u32,
79 (i / w) as u32,
80 match buffer[i as usize] {
81 CellState::Alive => BLACK,
82 CellState::Dead => WHITE,
83 },
84 );
85 }
86
87 texture.update(&image);
88
89 draw_texture(&texture, 0., 0., WHITE);
90
91 next_frame().await
92 }
93}Sourcepub const fn from_miniquad_texture(texture: TextureId) -> Texture2D
pub const fn from_miniquad_texture(texture: TextureId) -> Texture2D
Creates a Texture2D from a miniquad Texture
Sourcepub fn from_rgba8(width: u16, height: u16, bytes: &[u8]) -> Texture2D
pub fn from_rgba8(width: u16, height: u16, bytes: &[u8]) -> Texture2D
Creates a Texture2D from a slice of bytes in an R,G,B,A sequence, with the given width and height.
§Example
// Create a 2x2 texture from a byte slice with 4 rgba pixels
let bytes: Vec<u8> = vec![255, 0, 0, 192, 0, 255, 0, 192, 0, 0, 255, 192, 255, 255, 255, 192];
let texture = Texture2D::from_rgba8(2, 2, &bytes);Sourcepub fn update(&self, image: &Image)
pub fn update(&self, image: &Image)
Uploads Image data to this texture.
Examples found in repository?
10async fn main() {
11 let w = screen_width() as usize;
12 let h = screen_height() as usize;
13
14 let mut cells = vec![CellState::Dead; w * h];
15 let mut buffer = vec![CellState::Dead; w * h];
16
17 let mut image = Image::gen_image_color(w as u16, h as u16, WHITE);
18
19 for cell in cells.iter_mut() {
20 if rand::gen_range(0, 5) == 0 {
21 *cell = CellState::Alive;
22 }
23 }
24 let texture = Texture2D::from_image(&image);
25
26 loop {
27 clear_background(WHITE);
28
29 let w = image.width();
30 let h = image.height();
31
32 for y in 0..h as i32 {
33 for x in 0..w as i32 {
34 let mut neighbors_count = 0;
35
36 for j in -1i32..=1 {
37 for i in -1i32..=1 {
38 // out of bounds
39 if y + j < 0 || y + j >= h as i32 || x + i < 0 || x + i >= w as i32 {
40 continue;
41 }
42 // cell itself
43 if i == 0 && j == 0 {
44 continue;
45 }
46
47 let neighbor = cells[(y + j) as usize * w + (x + i) as usize];
48 if neighbor == CellState::Alive {
49 neighbors_count += 1;
50 }
51 }
52 }
53
54 let current_cell = cells[y as usize * w + x as usize];
55 buffer[y as usize * w + x as usize] = match (current_cell, neighbors_count) {
56 // Rule 1: Any live cell with fewer than two live neighbours
57 // dies, as if caused by underpopulation.
58 (CellState::Alive, x) if x < 2 => CellState::Dead,
59 // Rule 2: Any live cell with two or three live neighbours
60 // lives on to the next generation.
61 (CellState::Alive, 2) | (CellState::Alive, 3) => CellState::Alive,
62 // Rule 3: Any live cell with more than three live
63 // neighbours dies, as if by overpopulation.
64 (CellState::Alive, x) if x > 3 => CellState::Dead,
65 // Rule 4: Any dead cell with exactly three live neighbours
66 // becomes a live cell, as if by reproduction.
67 (CellState::Dead, 3) => CellState::Alive,
68 // All other cells remain in the same state.
69 (otherwise, _) => otherwise,
70 };
71 }
72 }
73
74 for i in 0..buffer.len() {
75 cells[i] = buffer[i];
76
77 image.set_pixel(
78 (i % w) as u32,
79 (i / w) as u32,
80 match buffer[i as usize] {
81 CellState::Alive => BLACK,
82 CellState::Dead => WHITE,
83 },
84 );
85 }
86
87 texture.update(&image);
88
89 draw_texture(&texture, 0., 0., WHITE);
90
91 next_frame().await
92 }
93}pub fn update_from_bytes(&self, width: u32, height: u32, bytes: &[u8])
Sourcepub fn update_part(
&self,
image: &Image,
x_offset: i32,
y_offset: i32,
width: i32,
height: i32,
)
pub fn update_part( &self, image: &Image, x_offset: i32, y_offset: i32, width: i32, height: i32, )
Uploads Image data to part of this texture.
Sourcepub fn width(&self) -> f32
pub fn width(&self) -> f32
Returns the width of this texture.
Examples found in repository?
10async fn main() {
11 let mut rustaceanes: Vec<Rustaceane> = Vec::new();
12 let rustacean_tex = load_texture("examples/rustacean_happy.png").await.unwrap();
13 rustacean_tex.set_filter(FilterMode::Nearest);
14
15 loop {
16 clear_background(Color::default());
17
18 if macroquad::input::is_mouse_button_down(MouseButton::Left) {
19 for _i in 0..100 {
20 rustaceanes.push(Rustaceane {
21 pos: Vec2::from(macroquad::input::mouse_position()),
22 speed: Vec2::new(
23 rand::gen_range(-250., 250.) / 60.,
24 rand::gen_range(-250., 250.) / 60.,
25 ),
26 color: Color::from_rgba(
27 rand::gen_range(50, 240),
28 rand::gen_range(80, 240),
29 rand::gen_range(100, 240),
30 255,
31 ),
32 })
33 }
34 }
35
36 for rustaceane in &mut rustaceanes {
37 rustaceane.pos += rustaceane.speed;
38
39 if ((rustaceane.pos.x + rustacean_tex.width() / 2.) > screen_width())
40 || ((rustaceane.pos.x + rustacean_tex.width() / 2.) < 0.)
41 {
42 rustaceane.speed.x *= -1.;
43 }
44 if ((rustaceane.pos.y + rustacean_tex.height() / 2.) > screen_height())
45 || ((rustaceane.pos.y + rustacean_tex.height() / 2.) < 0.)
46 {
47 rustaceane.speed.y *= -1.;
48 }
49
50 draw_texture(
51 &rustacean_tex,
52 rustaceane.pos.x,
53 rustaceane.pos.y,
54 rustaceane.color,
55 );
56 }
57
58 draw_fps();
59 draw_text(
60 format!("Rustaceanes: {}", rustaceanes.len()).as_str(),
61 0.,
62 32.,
63 32.,
64 WHITE,
65 );
66
67 next_frame().await
68 }
69}Sourcepub fn height(&self) -> f32
pub fn height(&self) -> f32
Returns the height of this texture.
Examples found in repository?
10async fn main() {
11 let mut rustaceanes: Vec<Rustaceane> = Vec::new();
12 let rustacean_tex = load_texture("examples/rustacean_happy.png").await.unwrap();
13 rustacean_tex.set_filter(FilterMode::Nearest);
14
15 loop {
16 clear_background(Color::default());
17
18 if macroquad::input::is_mouse_button_down(MouseButton::Left) {
19 for _i in 0..100 {
20 rustaceanes.push(Rustaceane {
21 pos: Vec2::from(macroquad::input::mouse_position()),
22 speed: Vec2::new(
23 rand::gen_range(-250., 250.) / 60.,
24 rand::gen_range(-250., 250.) / 60.,
25 ),
26 color: Color::from_rgba(
27 rand::gen_range(50, 240),
28 rand::gen_range(80, 240),
29 rand::gen_range(100, 240),
30 255,
31 ),
32 })
33 }
34 }
35
36 for rustaceane in &mut rustaceanes {
37 rustaceane.pos += rustaceane.speed;
38
39 if ((rustaceane.pos.x + rustacean_tex.width() / 2.) > screen_width())
40 || ((rustaceane.pos.x + rustacean_tex.width() / 2.) < 0.)
41 {
42 rustaceane.speed.x *= -1.;
43 }
44 if ((rustaceane.pos.y + rustacean_tex.height() / 2.) > screen_height())
45 || ((rustaceane.pos.y + rustacean_tex.height() / 2.) < 0.)
46 {
47 rustaceane.speed.y *= -1.;
48 }
49
50 draw_texture(
51 &rustacean_tex,
52 rustaceane.pos.x,
53 rustaceane.pos.y,
54 rustaceane.color,
55 );
56 }
57
58 draw_fps();
59 draw_text(
60 format!("Rustaceanes: {}", rustaceanes.len()).as_str(),
61 0.,
62 32.,
63 32.,
64 WHITE,
65 );
66
67 next_frame().await
68 }
69}pub fn size(&self) -> Vec2
Sourcepub fn set_filter(&self, filter_mode: FilterMode)
pub fn set_filter(&self, filter_mode: FilterMode)
Sets the FilterMode of this texture.
Use Nearest if you need integer-ratio scaling for pixel art, for example.
§Example
let texture = Texture2D::empty();
texture.set_filter(FilterMode::Linear);Examples found in repository?
4async fn main() {
5 let render_target = render_target(320, 150);
6 render_target.texture.set_filter(FilterMode::Nearest);
7
8 let material = load_material(
9 ShaderSource::Glsl {
10 vertex: CRT_VERTEX_SHADER,
11 fragment: CRT_FRAGMENT_SHADER,
12 },
13 Default::default(),
14 )
15 .unwrap();
16
17 loop {
18 // drawing to the texture
19
20 // 0..100, 0..100 camera
21 set_camera(&Camera2D {
22 zoom: vec2(0.01, 0.01),
23 target: vec2(0.0, 0.0),
24 render_target: Some(render_target.clone()),
25 ..Default::default()
26 });
27
28 clear_background(LIGHTGRAY);
29 draw_line(-30.0, 45.0, 30.0, 45.0, 3.0, BLUE);
30 draw_circle(-45.0, -35.0, 20.0, YELLOW);
31 draw_circle(45.0, -35.0, 20.0, GREEN);
32
33 // drawing to the screen
34
35 set_default_camera();
36
37 clear_background(WHITE);
38 gl_use_material(&material);
39 draw_texture_ex(
40 &render_target.texture,
41 0.,
42 0.,
43 WHITE,
44 DrawTextureParams {
45 dest_size: Some(vec2(screen_width(), screen_height())),
46 ..Default::default()
47 },
48 );
49 gl_use_default_material();
50
51 next_frame().await;
52 }
53}More examples
10async fn main() {
11 let mut rustaceanes: Vec<Rustaceane> = Vec::new();
12 let rustacean_tex = load_texture("examples/rustacean_happy.png").await.unwrap();
13 rustacean_tex.set_filter(FilterMode::Nearest);
14
15 loop {
16 clear_background(Color::default());
17
18 if macroquad::input::is_mouse_button_down(MouseButton::Left) {
19 for _i in 0..100 {
20 rustaceanes.push(Rustaceane {
21 pos: Vec2::from(macroquad::input::mouse_position()),
22 speed: Vec2::new(
23 rand::gen_range(-250., 250.) / 60.,
24 rand::gen_range(-250., 250.) / 60.,
25 ),
26 color: Color::from_rgba(
27 rand::gen_range(50, 240),
28 rand::gen_range(80, 240),
29 rand::gen_range(100, 240),
30 255,
31 ),
32 })
33 }
34 }
35
36 for rustaceane in &mut rustaceanes {
37 rustaceane.pos += rustaceane.speed;
38
39 if ((rustaceane.pos.x + rustacean_tex.width() / 2.) > screen_width())
40 || ((rustaceane.pos.x + rustacean_tex.width() / 2.) < 0.)
41 {
42 rustaceane.speed.x *= -1.;
43 }
44 if ((rustaceane.pos.y + rustacean_tex.height() / 2.) > screen_height())
45 || ((rustaceane.pos.y + rustacean_tex.height() / 2.) < 0.)
46 {
47 rustaceane.speed.y *= -1.;
48 }
49
50 draw_texture(
51 &rustacean_tex,
52 rustaceane.pos.x,
53 rustaceane.pos.y,
54 rustaceane.color,
55 );
56 }
57
58 draw_fps();
59 draw_text(
60 format!("Rustaceanes: {}", rustaceanes.len()).as_str(),
61 0.,
62 32.,
63 32.,
64 WHITE,
65 );
66
67 next_frame().await
68 }
69}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}Sourcepub fn raw_miniquad_id(&self) -> TextureId
pub fn raw_miniquad_id(&self) -> TextureId
Returns the handle for this texture.
Sourcepub fn grab_screen(&self)
pub fn grab_screen(&self)
Updates this texture from the screen.
Sourcepub fn get_texture_data(&self) -> Image
pub fn get_texture_data(&self) -> Image
Returns an Image from the pixel data in this texture.
This operation can be expensive.