use macroquad::prelude::*;
#[macroquad::main("Raw miniquad")]
async fn main() {
let stage = {
let InternalGlContext {
quad_context: ctx, ..
} = unsafe { get_internal_gl() };
raw_miniquad::Stage::new(ctx)
};
loop {
clear_background(LIGHTGRAY);
set_camera(&Camera2D {
zoom: vec2(1., screen_width() / screen_height()),
..Default::default()
});
draw_line(-0.4, 0.4, -0.8, 0.9, 0.05, BLUE);
draw_rectangle(-0.3, 0.3, 0.2, 0.2, GREEN);
draw_circle(0., 0., 0.1, YELLOW);
{
let mut gl = unsafe { get_internal_gl() };
gl.flush();
let t = get_time();
gl.quad_context.apply_pipeline(&stage.pipeline);
gl.quad_context
.begin_default_pass(miniquad::PassAction::Nothing);
gl.quad_context.apply_bindings(&stage.bindings);
for i in 0..10 {
let t = t + i as f64 * 0.3;
gl.quad_context
.apply_uniforms(miniquad::UniformsSource::table(
&raw_miniquad::shader::Uniforms {
offset: (t.sin() as f32 * 0.5, (t * 3.).cos() as f32 * 0.5),
},
));
gl.quad_context.draw(0, 6, 1);
}
gl.quad_context.end_render_pass();
}
set_default_camera();
draw_text("HELLO", 30.0, 200.0, 30.0, BLACK);
next_frame().await
}
}
mod raw_miniquad {
use miniquad::*;
#[repr(C)]
struct Vec2 {
x: f32,
y: f32,
}
#[repr(C)]
struct Vertex {
pos: Vec2,
uv: Vec2,
}
pub struct Stage {
pub pipeline: Pipeline,
pub bindings: Bindings,
}
impl Stage {
pub fn new(ctx: &mut dyn RenderingBackend) -> 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 = ctx.new_buffer(
BufferType::VertexBuffer,
BufferUsage::Immutable,
BufferSource::slice(&vertices),
);
let indices: [u16; 6] = [0, 1, 2, 0, 2, 3];
let index_buffer = ctx.new_buffer(
BufferType::IndexBuffer,
BufferUsage::Immutable,
BufferSource::slice(&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, 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,
];
let texture = ctx.new_texture_from_rgba8(4, 4, &pixels);
let bindings = Bindings {
vertex_buffers: vec![vertex_buffer],
index_buffer,
images: vec![texture],
};
let shader = ctx
.new_shader(
miniquad::ShaderSource::Glsl {
vertex: shader::VERTEX,
fragment: shader::FRAGMENT,
},
shader::meta(),
)
.unwrap();
let pipeline = ctx.new_pipeline(
&[BufferLayout::default()],
&[
VertexAttribute::new("pos", VertexFormat::Float2),
VertexAttribute::new("uv", VertexFormat::Float2),
],
shader,
Default::default(),
);
Stage { pipeline, bindings }
}
}
pub 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),
}
}
}