use macroquad::prelude::*;
#[macroquad::main("Texture")]
async fn main() {
let texture: Texture2D = load_texture("examples/chess.png").await.unwrap();
let lens_material = load_material(
ShaderSource::Glsl {
vertex: LENS_VERTEX_SHADER,
fragment: LENS_FRAGMENT_SHADER,
},
MaterialParams {
uniforms: vec![UniformDesc::new("Center", UniformType::Float2)],
..Default::default()
},
)
.unwrap();
loop {
clear_background(WHITE);
draw_texture_ex(
&texture,
0.0,
0.0,
WHITE,
DrawTextureParams {
dest_size: Some(vec2(screen_width(), screen_height())),
..Default::default()
},
);
let lens_center = mouse_position();
lens_material.set_uniform("Center", lens_center);
gl_use_material(&lens_material);
draw_circle(lens_center.0, lens_center.1, 250.0, RED);
gl_use_default_material();
next_frame().await
}
}
const LENS_FRAGMENT_SHADER: &'static str = r#"#version 100
precision lowp float;
varying vec2 uv;
varying vec2 uv_screen;
varying vec2 center;
uniform sampler2D _ScreenTexture;
void main() {
float gradient = length(uv);
vec2 uv_zoom = (uv_screen - center) * gradient + center;
gl_FragColor = texture2D(_ScreenTexture, uv_zoom);
}
"#;
const LENS_VERTEX_SHADER: &'static str = "#version 100
attribute vec3 position;
attribute vec2 texcoord;
varying lowp vec2 center;
varying lowp vec2 uv;
varying lowp vec2 uv_screen;
uniform mat4 Model;
uniform mat4 Projection;
uniform vec2 Center;
void main() {
vec4 res = Projection * Model * vec4(position, 1);
vec4 c = Projection * Model * vec4(Center, 0, 1);
uv_screen = res.xy / 2.0 + vec2(0.5, 0.5);
center = c.xy / 2.0 + vec2(0.5, 0.5);
uv = texcoord;
gl_Position = res;
}
";