فهرست منبع

add font rendering code

narodnik 5 سال پیش
والد
کامیت
8fa893712f
2فایلهای تغییر یافته به همراه90 افزوده شده و 0 حذف شده
  1. BIN
      res/font/PressStart2P-Regular.ttf
  2. 90 0
      src/bin/dfg.rs

BIN
res/font/PressStart2P-Regular.ttf


+ 90 - 0
src/bin/dfg.rs

@@ -25,6 +25,8 @@ fn get_time() -> f32 {
     START.elapsed().as_secs_f32()
 }
 
+const FONT_BYTES: &[u8] = include_bytes!("../../res/font/PressStart2P-Regular.ttf");
+
 #[rustfmt::skip]
 pub const OPENGL_TO_WGPU_MATRIX: cgmath::Matrix4<f32> = cgmath::Matrix4::new(
     1.0, 0.0, 0.0, 0.0,
@@ -248,6 +250,35 @@ struct Light {
     color: [f32; 3],
 }
 
+pub const UNBOUNDED_F32: f32 = std::f32::INFINITY;
+
+#[derive(Debug)]
+pub struct Text {
+    pub position: cgmath::Vector2<f32>,
+    pub bounds: cgmath::Vector2<f32>,
+    pub color: cgmath::Vector4<f32>,
+    pub text: String,
+    pub size: f32,
+    pub visible: bool,
+    pub focused: bool,
+    pub centered: bool,
+}
+
+impl Default for Text {
+    fn default() -> Self {
+        Self {
+            position: (0.0, 0.0).into(),
+            bounds: (UNBOUNDED_F32, UNBOUNDED_F32).into(),
+            color: (1.0, 1.0, 1.0, 1.0).into(),
+            text: String::new(),
+            size: 16.0,
+            visible: false,
+            focused: false,
+            centered: false,
+        }
+    }
+}
+
 const VERTEX_Z: f32 = 0.0;
 //  (-1, 1)                  (1, 1)
 //     +-----------------------+
@@ -320,6 +351,9 @@ struct State {
     cartoon_texture: texture::Texture,
     cartoon_bind_group: wgpu::BindGroup,
 
+    glyph_brush: wgpu_glyph::GlyphBrush<()>,
+    staging_belt: wgpu::util::StagingBelt,
+
     is_space_pressed: bool,
 }
 
@@ -749,6 +783,11 @@ impl State {
         });
         let num_indices = INDICES.len() as u32;
 
+        let font = wgpu_glyph::ab_glyph::FontArc::try_from_slice(FONT_BYTES).unwrap();
+        let glyph_brush =
+            wgpu_glyph::GlyphBrushBuilder::using_font(font).build(&device, sc_desc.format);
+        let staging_belt = wgpu::util::StagingBelt::new(1024);
+
         Self {
             surface,
             device,
@@ -780,6 +819,9 @@ impl State {
             cartoon_texture,
             cartoon_bind_group,
 
+            glyph_brush,
+            staging_belt,
+
             is_space_pressed: true,
         }
     }
@@ -912,12 +954,60 @@ impl State {
             render_pass.draw_indexed(0..self.num_indices, 0, 0..1);
         }
 
+        let play_text = Text {
+            position: (40.0, 40.0).into(),
+            color: (1.0, 1.0, 1.0, 1.0).into(),
+            text: String::from("Absolutely Proprietary"),
+            size: 32.0,
+            centered: false,
+            ..Default::default()
+        };
+        draw_text(&play_text, &mut self.glyph_brush);
+
+                self.glyph_brush
+                    .draw_queued(
+                        &self.device,
+                        &mut self.staging_belt,
+                        &mut encoder,
+                        &frame.view,
+                        self.sc_desc.width,
+                        self.sc_desc.height,
+                    )
+                    .unwrap();
+
+                self.staging_belt.finish();
+
         self.queue.submit(iter::once(encoder.finish()));
 
         Ok(())
     }
 }
 
+fn draw_text(text: &Text, glyph_brush: &mut wgpu_glyph::GlyphBrush<()>) {
+    let layout = wgpu_glyph::Layout::default().h_align(if text.centered {
+        wgpu_glyph::HorizontalAlign::Center
+    } else {
+        wgpu_glyph::HorizontalAlign::Left
+    });
+
+    let section =
+        wgpu_glyph::Section {
+            screen_position: text.position.into(),
+            bounds: text.bounds.into(),
+            layout,
+            ..Default::default()
+        }
+        .add_text(wgpu_glyph::Text::new(&text.text).with_color(text.color).with_scale(
+            if text.focused {
+                text.size + 8.0
+            } else {
+                text.size
+            },
+        ));
+
+    glyph_brush.queue(section);
+}
+
 fn main() {
     env_logger::init();
     let event_loop = EventLoop::new();