#[macro_use] extern crate shadiertoy; use shadiertoy::{Window, Game, Shader, Texture}; use shadiertoy::image; use shadiertoy::glutin::{Event, WindowEvent}; use std::time::Instant; pipeline!(globals { resolution: Global<[f32; 2]>, time: Global, image: TextureSampler<[f32; 4]>, cursor: Global<[f32; 2]>, color: RenderTarget, }); struct Textured { start: Instant, shader: Shader, cursor: [f32; 2], image: Texture, } impl Game for Textured { fn new(window: &mut Window) -> Self { let shader = window.shader(globals::new(), b" #version 130 uniform vec2 resolution; uniform float time; uniform sampler2D image; uniform vec2 cursor; out vec4 color; void main() { float s = min(resolution.x, resolution.y); vec2 uv = (gl_FragCoord.xy + (s - resolution) / 2) / s; float st = sin(time); float ct = cos(time); uv = uv - (cursor - resolution / 2) / s; uv = mat2(ct, -st, st, ct) * (uv - 0.5) + 0.5; color = texture(image, vec2(uv.x, uv.y)); } ").unwrap(); Textured { start: Instant::now(), cursor: [0.0; 2], image: window.texture( image::load_from_memory(include_bytes!("texture.png")) .unwrap() .to_rgba(), ), shader, } } fn draw(&mut self, window: &mut Window) { let time = self.start.elapsed(); let time = time.as_secs() as f32 + time.subsec_nanos() as f32 * 1e-9; let resolution = window.size() .map(|(w, h)| [w as f32, h as f32]) .unwrap_or([0.0; 2]); window.draw(&self.shader, |color, _| globals::Data { resolution: &resolution, time: &time, image: &self.image, cursor: &self.cursor, color, }); } fn event(&mut self, window: &mut Window, event: Event) { if let Event::WindowEvent { event: WindowEvent::CursorMoved { position: (x, y), .. }, .. } = event { let (_, h) = window.size().unwrap_or((0, 0)); self.cursor = [x as f32, h as f32 - y as f32]; } } } pub fn main() { Textured::run() }