aboutsummaryrefslogtreecommitdiff
path: root/examples/render-quad/src/main.rs
blob: 1955b5154a7133da2fd3ab313f37a876b263a11c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//! Renders ./example.bsp geometry: (), texture_idx: ()  geometry: (), texture_idx: ()

extern crate gfx_hal as hal;

#[macro_use]
extern crate legion;

use anyhow::{Context, Result};
use log::warn;
use stockton_skeleton::{error::full_error_display, Renderer, Session};
use winit::{
    event::{Event, WindowEvent},
    event_loop::{ControlFlow, EventLoop},
    window::WindowBuilder,
};

mod draw_pass;
mod system;
use draw_pass::*;
use system::*;

/// Alias for our drawpass
type Dp<'a> = ExampleDrawPass<'a>;

fn main() {
    // Wrap for full error display
    if let Err(err) = try_main() {
        eprintln!("{}", full_error_display(err));
    }
}

fn try_main() -> Result<()> {
    // Initialise logger
    simplelog::TermLogger::init(
        log::LevelFilter::Debug,
        simplelog::ConfigBuilder::new()
            .set_max_level(log::LevelFilter::Debug)
            .set_thread_mode(simplelog::ThreadLogMode::Names)
            .build(),
        simplelog::TerminalMode::Stderr,
        simplelog::ColorChoice::Auto,
    )
    .context("Error initialising logger")?;

    // Make a window
    let event_loop = EventLoop::new();
    let window = WindowBuilder::new()
        .build(&event_loop)
        .context("Error creating window")?;

    // Grab cursor
    window.set_cursor_visible(false);
    if window.set_cursor_grab(true).is_err() {
        warn!("warning: cursor not grabbed");
    }

    // Our game world
    let mut session = Session::new(move |schedule| {
        schedule.add_system(mutate_state_system());
    });

    // An entity to keep track of our state
    let state_ent = session.world.push((ExampleState::default(),));

    // Create the renderer
    let renderer =
        Renderer::<Dp<'static>>::new(&window, &mut session, ExampleDrawPassConfig { state_ent })?;

    // We'll be moving it in/out of here, so we need an Option for safety.
    let mut renderer = Some(renderer);

    // Done loading - This is our main loop.
    // It just communicates events to the session and continuously ticks
    event_loop.run(move |event, _, flow| match event {
        Event::MainEventsCleared => {
            window.request_redraw();
        }
        Event::RedrawRequested(_) => {
            session.do_update();

            // Render
            let r = renderer.take().unwrap();
            match r.render(&session) {
                Ok(r) => {
                    renderer = Some(r);
                }
                Err(e) => {
                    println!("Error drawing: {}", full_error_display(e));

                    *flow = ControlFlow::Exit;
                }
            }
        }
        Event::WindowEvent {
            window_id: _,
            event: WindowEvent::Resized(_),
        } => {
            // (Attempt) resize
            let r = renderer.take().unwrap();
            match r.recreate_surface(&session) {
                Ok(r) => {
                    renderer = Some(r);
                }
                Err(e) => {
                    println!("Error resizing: {}", full_error_display(e));

                    *flow = ControlFlow::Exit;
                }
            }
        }
        _ => (),
    });
}