#![windows_subsystem = "windows"] use miniquad::*; #[repr(C)] struct Vec2 { x: f32, y: f32, } #[repr(C)] struct Vertex { pos: Vec2, uv: Vec2, } struct Stage { pipeline: Pipeline, bindings: Bindings, } impl Stage { pub fn new(ctx: &mut Context) -> Stage { #[rustfmt::skip] let vertices: [Vertex; 4] = [ Vertex { pos : Vec2 { x: -0.5, y: -0.5 }, uv: Vec2 { x: 0., y: 0. } }, Vertex { pos : Vec2 { x: 0.5, y: -0.5 }, uv: Vec2 { x: 1., y: 0. } }, Vertex { pos : Vec2 { x: 0.5, y: 0.5 }, uv: Vec2 { x: 1., y: 1. } }, Vertex { pos : Vec2 { x: -0.5, y: 0.5 }, uv: Vec2 { x: 0., y: 1. } }, ]; let vertex_buffer = Buffer::immutable(ctx, BufferType::VertexBuffer, &vertices); let indices: [u16; 6] = [0, 1, 2, 0, 2, 3]; let index_buffer = Buffer::immutable(ctx, BufferType::IndexBuffer, &indices); let pixels: [u8; 4 * 4 * 4] = [ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ]; let texture = Texture::from_rgba8(ctx, 4, 4, &pixels); let bindings = Bindings { vertex_buffers: vec![vertex_buffer], index_buffer: index_buffer, images: vec![texture], }; let shader = Shader::new(ctx, shader::VERTEX, shader::FRAGMENT, shader::meta()).unwrap(); let pipeline = Pipeline::new( ctx, &[BufferLayout::default()], &[ VertexAttribute::new("pos", VertexFormat::Float2), VertexAttribute::new("uv", VertexFormat::Float2), ], shader, ); Stage { pipeline, bindings } } } impl EventHandler for Stage { fn update(&mut self, _ctx: &mut Context) {} fn draw(&mut self, ctx: &mut Context) { let t = date::now(); ctx.begin_default_pass(Default::default()); ctx.apply_pipeline(&self.pipeline); ctx.apply_bindings(&self.bindings); for i in 0..10 { let t = t + i as f64 * 0.3; ctx.apply_uniforms(&shader::Uniforms { offset: (t.sin() as f32 * 0.5, (t * 3.).cos() as f32 * 0.5), }); ctx.draw(0, 6, 1); } ctx.end_render_pass(); ctx.commit_frame(); } fn char_event(&mut self, ctx: &mut Context, character: char, _: KeyMods, _: bool) { match character { 'z' => ctx.show_mouse(false), 'x' => ctx.show_mouse(true), _ => (), } let icon = match character { '1' => CursorIcon::Default, '2' => CursorIcon::Help, '3' => CursorIcon::Pointer, '4' => CursorIcon::Wait, '5' => CursorIcon::Crosshair, '6' => CursorIcon::Text, '7' => CursorIcon::Move, '8' => CursorIcon::NotAllowed, '9' => CursorIcon::EWResize, '0' => CursorIcon::NSResize, 'q' => CursorIcon::NESWResize, 'w' => CursorIcon::NWSEResize, _ => return, }; ctx.set_mouse_cursor(icon); } } fn main() { miniquad::start(conf::Conf::default(), |mut ctx| { Box::new(Stage::new(&mut ctx)) }); } mod shader { use miniquad::*; pub const VERTEX: &str = r#"#version 100 attribute vec2 pos; attribute vec2 uv; uniform vec2 offset; varying lowp vec2 texcoord; void main() { gl_Position = vec4(pos + offset, 0, 1); texcoord = uv; }"#; pub const FRAGMENT: &str = r#"#version 100 varying lowp vec2 texcoord; uniform sampler2D tex; void main() { gl_FragColor = texture2D(tex, texcoord); }"#; pub fn meta() -> ShaderMeta { ShaderMeta { images: vec!["tex".to_string()], uniforms: UniformBlockLayout { uniforms: vec![UniformDesc::new("offset", UniformType::Float2)], }, } } #[repr(C)] pub struct Uniforms { pub offset: (f32, f32), } }