summaryrefslogtreecommitdiff
path: root/crates/renderer/src/overlay/asset.rs
blob: a616703ed18e4671a76a6e02374c09d62fc4bcf9 (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
114
115
116
117
118
119
120
use teleia::*;

use crate::overlay;

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum AssetSort {
    Texture,
    Mesh,
}
impl AssetSort {
    pub fn from_str(s: &str) -> Option<Self> {
        match s {
            "texture" => Some(Self::Texture),
            "mesh" => Some(Self::Mesh),
            _ => None,
        }
    }
}
#[derive(Clone, PartialEq, Eq)]
pub struct DisplayedAsset {
    sort: AssetSort,
    path: String,
}
pub struct Overlay {
    loaded: Option<DisplayedAsset>,
    displayed: Option<DisplayedAsset>,
    texture_placeholder: texture::Texture,
    texture: texture::Texture,
    mesh: mesh::Mesh,
}
impl Overlay {
    pub fn new(ctx: &context::Context) -> Self {
        Self {
            loaded: None,
            displayed: None,
            texture_placeholder: texture::Texture::new(ctx, include_bytes!("../assets/textures/placeholder.png")),
            texture: texture::Texture::new_empty(ctx),
            mesh: mesh::Mesh::new_empty(ctx, true, true),
        }
    }
    pub fn load_displayed(&mut self, ctx: &context::Context) -> Erm<()> {
        if let Some(d) = &self.displayed {
            match d.sort {
                AssetSort::Texture => {
                    let bs = std::fs::read(&d.path)?;
                    self.texture.upload(ctx, &bs);
                },
                AssetSort::Mesh => {
                    let bs = std::fs::read(&d.path)?;
                    self.mesh.upload_obj(ctx, &bs);
                },
            }
        }
        Ok(())
    }
}
impl overlay::Overlay for Overlay {
    fn handle_binary(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State, msg: &net::fig::BinaryMessage) -> Erm<()> {
        match &*msg.event {
            b"overlay asset display" => {
                let mut reader = std::io::Cursor::new(&msg.data);
                let ssort = net::fig::read_length_prefixed_utf8(&mut reader)?;
                let path = net::fig::read_length_prefixed_utf8(&mut reader)?;
                if let Some(sort) = AssetSort::from_str(&ssort) {
                    log::warn!("displaying {} asset at: {}", ssort, path);
                    let new = Some(DisplayedAsset {sort, path});
                    if new != self.displayed {
                        self.displayed = new.clone();
                        if self.displayed != self.loaded {
                            if let Err(e) = self.load_displayed(ctx) {
                                self.displayed = None;
                                log::warn!("error when loading asset: {}", e);
                            } else {
                                self.loaded = new;
                            }
                        }
                    }
                } else {
                    log::warn!("unknown asset sort: {}", ssort);
                }
            },
            b"overlay asset clear" => {
                self.displayed = None;
            },
            _ => {},
        }
        Ok(())
    }
    fn render(&mut self, ctx: &context::Context, st: &mut state::State, ost: &mut overlay::State) -> Erm<()> {
        if let Some(d) = &self.displayed {
            match d.sort {
                AssetSort::Texture => {
                    st.bind_2d(ctx, &ost.assets.shader_flat);
                    self.texture.bind(ctx);
                    ost.assets.shader_flat.set_position_2d(
                        ctx, st,
                        &glam::Vec2::new(ost.info.emacs_cursor.0, ost.info.emacs_cursor.1),
                        &glam::Vec2::new(self.texture.width as f32, self.texture.height as f32)
                    );
                    st.mesh_square.render(ctx);
                },
                AssetSort::Mesh => {
                    st.bind_3d(ctx, &ost.assets.shader_flat);
                    ost.assets.shader_flat.set_f32(ctx, "transparency", 0.0);
                    self.texture_placeholder.bind(ctx);
                    ost.assets.shader_flat.set_position_3d(
                        ctx, st,
                        &glam::Mat4::from_scale_rotation_translation(
                            glam::Vec3::new(1.0, 1.0, 1.0),
                            glam::Quat::from_rotation_y(st.tick as f32 / 75.0),
                            glam::Vec3::new(0.0, 0.0, -8.0)
                        ),
                    );
                    self.mesh.render(ctx);
                },
            }
        }
        Ok(())
    }
}