1#![allow(dead_code)]
5#![allow(unused)]
6
7pub mod geometry;
8pub mod graphics;
9mod math;
10
11pub use math::*;
13
14pub use sokol::app::SAppDesc as KAppDesc;
16pub use sokol::app::SAppKeycode as Keycode;
17
18use sokol::app::*;
19use sokol::gfx::*;
20
21pub(crate) const MAX_QUADS: usize = 4000;
27pub(crate) const MAX_POINTS: usize = 15000;
28pub(crate) const MAX_LINES: usize = 1000;
29pub(crate) const MAX_IMAGES: usize = 100;
30pub(crate) const MAX_MESHES: usize = 200;
31
32#[derive(Default, Copy, Clone)]
33pub struct Texture {
34 pub id: usize,
35 pub w: u32,
36 pub h: u32,
37}
38
39#[derive(Default, Copy, Clone)]
41pub struct TextureFrameDesc {
42 pub x: u32,
43 pub y: u32,
44 pub w: u32,
45 pub h: u32,
46 pub offset: V2,
47}
48
49#[derive(Default, Clone, Copy)]
61pub struct Sprite {
62 pub(crate) img_id: usize,
63 pub(crate) corners: QuadCorners,
64}
65
66#[derive(Copy, Clone)]
74pub enum Pivot {
75 Center,
76 Px(V2),
77 Percent(V2),
78}
79
80#[derive(Default, Copy, Clone)]
81pub(crate) struct DrawPoint {
82 pub pos: V3,
83 pub color: V4,
84}
85
86impl DrawPoint {
87 pub fn new(x: f32, y: f32, z: f32, color: V4) -> DrawPoint {
88 let pos = V3 { x, y, z };
89 DrawPoint { pos, color }
90 }
91}
92
93#[derive(Default, Copy, Clone)]
94pub(crate) struct DrawLine {
95 pub point_a: V3,
96 pub color_a: V4,
97 pub point_b: V3,
98 pub color_b: V4, }
100
101#[derive(Default, Copy, Clone)]
102pub(crate) struct QuadVert {
103 pub pos: V3,
104 pub uv: V2,
105}
106
107impl QuadVert {
108 pub fn new(x: f32, y: f32, z: f32, uvx: f32, uvy: f32) -> QuadVert {
109 let pos = V3 { x, y, z };
110 let uv = V2 { x: uvx, y: uvy };
111 QuadVert { pos, uv }
112 }
113}
114
115pub(crate) type QuadCorners = [QuadVert; 4];
116
117#[derive(Default, Copy, Clone)]
118pub(crate) struct DrawQuad {
119 pub img_id: usize,
120 pub corners: QuadCorners,
121 pub transform: M4,
122}
123
124#[derive(Default, Clone, Copy)]
125pub(crate) struct DrawMesh {
126 pub mesh_i: usize,
127 pub transform: M4,
128}
129
130#[derive(Default)]
131pub(crate) struct GlShape {
132 pub pipeline: SgPipeline,
133 pub bindings: SgBindings,
134}
135
136#[derive(Default, Copy, Clone)]
137pub(crate) struct Image {
138 pub(crate) e: SgImage,
139 pub(crate) w: u32,
140 pub(crate) h: u32,
141}
142
143pub(crate) struct ImagesCtx {
144 e: [Image; MAX_IMAGES],
145 count: usize,
146}
147
148impl Default for ImagesCtx {
149 fn default() -> Self {
150 Self {
151 e: [Default::default(); MAX_IMAGES],
152 count: 0,
153 }
154 }
155}
156
157pub(crate) struct QuadsCtx {
158 pub(crate) shape: GlShape,
159 pub(crate) e: [DrawQuad; MAX_QUADS],
160 pub(crate) count: usize,
161}
162
163impl Default for QuadsCtx {
164 fn default() -> Self {
165 Self {
166 shape: Default::default(),
167 e: [Default::default(); MAX_QUADS],
168 count: Default::default(),
169 }
170 }
171}
172
173pub(crate) struct PointsCtx {
174 pub(crate) shape: GlShape,
175 pub(crate) e: [DrawPoint; MAX_POINTS],
176 pub(crate) count: usize,
177}
178
179impl Default for PointsCtx {
180 fn default() -> Self {
181 Self {
182 shape: Default::default(),
183 e: [Default::default(); MAX_POINTS],
184 count: Default::default(),
185 }
186 }
187}
188
189pub(crate) struct LinesCtx {
190 pub(crate) shape: GlShape,
191 pub(crate) e: [DrawLine; MAX_LINES],
192 pub(crate) count: usize,
193}
194
195impl Default for LinesCtx {
196 fn default() -> Self {
197 Self {
198 shape: Default::default(),
199 e: [Default::default(); MAX_LINES],
200 count: Default::default(),
201 }
202 }
203}
204
205pub(crate) struct MeshCtx {
206 pub(crate) shape: GlShape,
207 pub(crate) e: [DrawMesh; MAX_MESHES],
208 pub(crate) count: usize,
209}
210
211impl Default for MeshCtx {
212 fn default() -> Self {
213 Self {
214 shape: Default::default(),
215 e: [Default::default(); MAX_MESHES],
216 count: Default::default(),
217 }
218 }
219}
220
221#[derive(Default)]
222pub struct GraphicsCtx {
223 pub bg: V3,
224 pub proj: M4,
225 pub view: M4,
226 pub(crate) view_proj: M4,
227 pub(crate) quads: QuadsCtx,
229 pub(crate) points: PointsCtx,
230 pub(crate) lines: LinesCtx,
231 pub(crate) images: ImagesCtx,
232 pub(crate) mesh: MeshCtx,
233 pub(crate) pass_action: SgPassAction,
235}
236
237#[derive(Default)]
238pub struct InputCtx {
239 pub l_stick: V2,
240 pub r_stick: V2,
241 pub quit: bool,
242 pub dir_u: bool,
243 pub dir_d: bool,
244 pub dir_l: bool,
245 pub dir_r: bool,
246 pub action_pressed: bool,
247 pub action_released: bool,
248 pub mouse_wheel_y: f32,
249 pub mouse_pos: V2,
250 pub mouse_prev_pos: V2,
251}
252
253pub struct Ctx {
256 pub input: InputCtx,
257 pub gl: GraphicsCtx,
258}
259
260impl Default for Ctx {
261 fn default() -> Self {
262 Self {
263 input: Default::default(),
264 gl: Default::default(),
265 }
266 }
267}
268
269struct App<K: KApp> {
273 ctx: Ctx,
274 app: K,
275}
276
277pub trait KApp: 'static + Sized {
278 fn new() -> Self;
279 fn init(&mut self, ctx: &mut Ctx);
280 fn frame(&mut self, ctx: &mut Ctx);
281}
282
283impl<K: KApp> SApp for App<K> {
284 fn sapp_init(&mut self) {
285 let ctx = &mut self.ctx;
286 graphics::init(ctx);
287 self.app.init(ctx);
288 }
289
290 fn sapp_frame(&mut self) {
291 let ctx = &mut self.ctx;
292 ctx.gl.view_proj = ctx.gl.proj * ctx.gl.view;
293 self.app.frame(ctx);
294 ctx.input.mouse_wheel_y = 0.0;
295 ctx.input.mouse_prev_pos = ctx.input.mouse_pos;
296 graphics::present(ctx);
297 }
298
299 fn sapp_cleanup(&mut self) {
300 std::process::exit(0);
301 }
302
303 fn sapp_event(&mut self, event: SAppEvent) {
304 let ctx = &mut self.ctx;
305 if event.event_type == SAppEventType::KeyDown
307 && event.modifiers.contains(SAppModifier::SUPER)
308 && (event.key_code == SAppKeycode::KeyW || event.key_code == SAppKeycode::KeyQ)
309 {
310 std::process::exit(0)
311 }
312
313 match event.event_type {
315 SAppEventType::MouseMove => {
316 ctx.input.mouse_pos = v2(event.mouse_x, event.mouse_y);
317 }
318 SAppEventType::MouseScroll => {
319 ctx.input.mouse_wheel_y += event.scroll_y;
320 }
321 SAppEventType::KeyDown => match event.key_code {
322 SAppKeycode::KeyW => ctx.input.dir_u = true,
323 SAppKeycode::KeyA => ctx.input.dir_l = true,
324 SAppKeycode::KeyD => ctx.input.dir_r = true,
325 SAppKeycode::KeyS => ctx.input.dir_d = true,
326 _ => {}
327 },
328 SAppEventType::KeyUp => match event.key_code {
329 SAppKeycode::KeyW => ctx.input.dir_u = false,
330 SAppKeycode::KeyA => ctx.input.dir_l = false,
331 SAppKeycode::KeyD => ctx.input.dir_r = false,
332 SAppKeycode::KeyS => ctx.input.dir_d = false,
333 _ => {}
334 },
335
336 _ => {}
337 }
338 }
339}
340
341pub fn run<K: KApp>(desc: KAppDesc) {
342 let ctx: Ctx = Default::default();
343 let app: K = K::new();
344 sapp_run(App { ctx, app }, desc);
345}
346
347