Texture2D

Struct Texture2D 

Source
pub struct Texture2D { /* private fields */ }
Expand description

Texture, data stored in GPU memory

Implementations§

Source§

impl Texture2D

Source

pub fn weak_clone(&self) -> Texture2D

Source

pub fn empty() -> Texture2D

Creates an empty Texture2D.

§Example
let texture = Texture2D::empty();
Source

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,
    );
Source

pub fn from_image(image: &Image) -> Texture2D

Creates a Texture2D from an Image.

Examples found in repository?
examples/shadertoy.rs (line 43)
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
Hide additional examples
examples/life.rs (line 24)
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}
Source

pub const fn from_miniquad_texture(texture: TextureId) -> Texture2D

Creates a Texture2D from a miniquad Texture

Source

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);
Source

pub fn update(&self, image: &Image)

Uploads Image data to this texture.

Examples found in repository?
examples/life.rs (line 87)
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}
Source

pub fn update_from_bytes(&self, width: u32, height: u32, bytes: &[u8])

Source

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.

Source

pub fn width(&self) -> f32

Returns the width of this texture.

Examples found in repository?
examples/rustaceanmark.rs (line 39)
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}
Source

pub fn height(&self) -> f32

Returns the height of this texture.

Examples found in repository?
examples/rustaceanmark.rs (line 44)
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}
Source

pub fn size(&self) -> Vec2

Source

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?
examples/post_processing.rs (line 6)
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
Hide additional examples
examples/rustaceanmark.rs (line 13)
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}
examples/letterbox.rs (line 10)
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}
Source

pub fn raw_miniquad_id(&self) -> TextureId

Returns the handle for this texture.

Source

pub fn grab_screen(&self)

Updates this texture from the screen.

Source

pub fn get_texture_data(&self) -> Image

Returns an Image from the pixel data in this texture.

This operation can be expensive.

Trait Implementations§

Source§

impl Clone for Texture2D

Source§

fn clone(&self) -> Texture2D

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Texture2D

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl From<Texture2D> for UiContent<'static>

Source§

fn from(data: Texture2D) -> UiContent<'static>

Converts to this type from the input type.
Source§

impl PartialEq for Texture2D

Source§

fn eq(&self, other: &Texture2D) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for Texture2D

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<S> FromSample<S> for S

Source§

fn from_sample_(s: S) -> S

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> ToSample<U> for T
where U: FromSample<T>,

Source§

fn to_sample_(self) -> U

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<S, T> Duplex<S> for T
where T: FromSample<S> + ToSample<S>,