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
114
#![deny(missing_docs)]
use lazy_static::lazy_static;
use sylasteven as engine;
use glutin::{GlContext, GlWindow};
use nanovg::{Font, Frame, Image};
pub use nanovg;
use std::collections::HashMap as Map;
use std::path::PathBuf;
struct Context(nanovg::Context);
unsafe impl Sync for Context {}
lazy_static! {
static ref NANOVG: Context = Context(
nanovg::ContextBuilder::new()
.stencil_strokes()
.build()
.expect("Initialization of NanoVG failed!")
);
}
pub struct RenderEvent {
pub frame: Frame<'static>,
pub default_font: Font<'static>,
}
pub struct Render {
default_font: Font<'static>,
pub images: Map<std::path::PathBuf, Image<'static>>,
gl_window: GlWindow,
}
impl Render {
pub fn new(gl_window: GlWindow) -> Render {
let default_font = Font::from_file(
&NANOVG.0,
"Default",
concat!(env!("CARGO_MANIFEST_DIR"), "/resources/FreeMono.ttf"),
)
.expect("Failed to load font 'FreeMono.ttf'");
Self {
default_font,
gl_window,
images: Map::new(),
}
}
pub fn add_image(&mut self, path: &PathBuf) -> Option<PathBuf> {
let context = &NANOVG.0;
if self.images.get(path).is_some() {
Some(path.clone())
} else if let Some(image) = Image::new(context).build_from_file(&path).ok() {
let result = Some(path.clone());
self.images.insert(path.to_path_buf(), image);
result
} else {
None
}
}
}
use crate::engine::{Handler, System};
impl<H: Handler> System<H> for Render
where
H::Event: From<RenderEvent>,
{
fn process(&mut self, handler: &mut H) {
let context = &NANOVG.0;
let Self {
gl_window,
default_font,
..
} = self;
let (width, height) = gl_window.get_inner_size().expect("Oh no");
let (width, height) = (width as i32, height as i32);
unsafe {
gl::Clear(gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
gl::Viewport(0, 0, width, height);
}
let (width, height) = (width as f32, height as f32);
context.frame((width, height), gl_window.hidpi_factor(), |frame| {
handler.handle(
RenderEvent {
frame,
default_font: *default_font,
}
.into(),
)
});
gl_window.swap_buffers().unwrap();
}
}