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
use super::webgl::WebGl2;
use super::GraphicsApi;
use crate::communication::{RESOURCE_TABLE, SYNCHRONIZATION_MEMORY};
use crate::error::ClientError;
use rask_engine::resources::{GetTextures, Texture};
type RenderBackend = WebGl2;
static mut RENDERER: Option<Renderer<RenderBackend>> = None;
pub unsafe fn set_renderer(
renderer: Renderer<RenderBackend>,
) -> &'static mut Renderer<RenderBackend> {
RENDERER = Some(renderer);
RENDERER.as_mut().unwrap()
}
pub unsafe fn renderer_mut() -> Option<&'static mut Renderer<RenderBackend>> {
RENDERER.as_mut()
}
pub struct Renderer<T> {
graphics: T,
}
impl<T: GraphicsApi> Renderer<T> {
pub fn new() -> Result<Self, ClientError> {
log::debug!("Creating graphics buffer");
T::new(240, 135).map(|api| Self { graphics: api })
}
pub fn render(&mut self) -> Result<(), ClientError> {
#[cfg(debug_assertions)]
self.graphics
.ok()
.map_err(|e| ClientError::WebGlError(format!("WebGl2 error: {}", e)))?;
let size = unsafe { SYNCHRONIZATION_MEMORY.canvas_size };
log::trace!("canvas_size: {}px x {}px", size.0, size.1);
self.graphics.update_size(size.0, size.1);
self.draw_sprites()
}
pub fn draw_sprites(&mut self) -> Result<(), ClientError> {
let mut used_textures = crate::communication::TEXTURE_IDS.lock();
if used_textures.reset_notify > 0 {
log::debug!("Uploading new textures");
used_textures.reset_notify = 0;
self.graphics.remove_textures()?;
let guard = RESOURCE_TABLE.read();
let mut err = Ok(());
log::trace!("reading new textures");
let textures = used_textures
.ids
.iter()
.map(|&id| (id, guard.get_textures(id as usize)))
.flat_map(|(id, tex): (_, Result<Vec<(u64, &Texture)>, _>)| {
tex.map(|tex: Vec<(u64, &Texture)>| {
tex.iter()
.map(|(sid, t): &(u64, &Texture)| (id, *sid, *t))
.collect::<Vec<(u32, u64, &Texture)>>()
})
.unwrap_or_else(|e| -> Vec<(u32, u64, &Texture)> {
err = Err(e);
vec![]
})
})
.collect::<Vec<(u32, u64, &Texture)>>();
err?;
log::trace!("uploading new textures to gpu");
self.graphics.upload_textures(&textures)?;
}
let state = crate::communication::DOUBLE_BUFFER.lock();
self.graphics.update_sprite_vector(&state)?;
self.graphics.draw()
}
}