screen_texture/
screen_texture.rs

1use macroquad::prelude::*;
2
3#[macroquad::main("Texture")]
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}
43
44const LENS_FRAGMENT_SHADER: &'static str = r#"#version 100
45precision lowp float;
46
47varying vec2 uv;
48varying vec2 uv_screen;
49varying vec2 center;
50
51uniform sampler2D _ScreenTexture;
52
53void main() {
54    float gradient = length(uv);
55    vec2 uv_zoom = (uv_screen - center) * gradient + center;
56
57    gl_FragColor = texture2D(_ScreenTexture, uv_zoom);
58}
59"#;
60
61const LENS_VERTEX_SHADER: &'static str = "#version 100
62attribute vec3 position;
63attribute vec2 texcoord;
64
65varying lowp vec2 center;
66varying lowp vec2 uv;
67varying lowp vec2 uv_screen;
68
69uniform mat4 Model;
70uniform mat4 Projection;
71
72uniform vec2 Center;
73
74void main() {
75    vec4 res = Projection * Model * vec4(position, 1);
76    vec4 c = Projection * Model * vec4(Center, 0, 1);
77
78    uv_screen = res.xy / 2.0 + vec2(0.5, 0.5);
79    center = c.xy / 2.0 + vec2(0.5, 0.5);
80    uv = texcoord;
81
82    gl_Position = res;
83}
84";