Fix benchmarks for latest glium/glutin API
[mandelwow.git] / text.rs
diff --git a/text.rs b/text.rs
index c483846c0afe2ed05135234136d4c384f12228c8..e020156cd08956f226d9c36c0117dcaa24069452 100644 (file)
--- a/text.rs
+++ b/text.rs
@@ -1,9 +1,48 @@
 use cgmath::conv::array4x4;
-use cgmath::{Matrix4, One};
+use cgmath::Matrix4;
 use glium;
-use glium::{Surface, texture};
-use image;
-use std::io::Cursor;
+use glium::{Display, Program, Surface, implement_vertex, texture, uniform};
+use std;
+
+fn gamma<T>(x: T) -> f32
+where
+    f32: From<T>,
+    T: Copy,
+{
+    ((f32::from(x)) / 255.).powf(2.2)
+}
+
+fn srgb<T>(c: [T; 3]) -> [f32; 4]
+where
+    f32: From<T>,
+    T: Copy,
+{
+    [gamma(c[0]), gamma(c[1]), gamma(c[2]), 0.0]
+}
+
+#[cfg(feature = "image")]
+fn c64_font() -> (u32, u32, Vec<u8>) {
+    let image = image::load_from_memory_with_format(
+        &include_bytes!("textures/c64-font.png")[..],
+        image::PNG,
+    ).unwrap()
+        .to_luma();
+    let (w, h) = image.dimensions();
+    (w, h, image.into_raw())
+}
+
+#[cfg(not(feature = "image"))]
+fn c64_font() -> (u32, u32, Vec<u8>) {
+    let pixels = &include_bytes!("textures/c64-font.gray")[..];
+    (128, 128, Vec::from(pixels))
+}
+
+pub fn text_program(display: &Display) -> Program {
+    //load_program(display, "shaders/text.vert", "shaders/text.frag");
+    let vertex_shader_src = include_str!("shaders/text.vert");
+    let fragment_shader_src = include_str!("shaders/text.frag");
+    Program::from_source(display, vertex_shader_src, fragment_shader_src, None).unwrap()
+}
 
 #[derive(Copy, Clone)]
 struct Vertex {
@@ -12,24 +51,29 @@ struct Vertex {
 }
 implement_vertex!(Vertex, position, tex_coords);
 
-pub struct Text<'a> {
-    tex: texture::CompressedSrgbTexture2d,
+pub struct Text {
+    tex: texture::Texture2d,
     vertex_buffer: glium::VertexBuffer<Vertex>,
     index_buffer: glium::IndexBuffer<u16>,
     program: glium::Program,
-    params: glium::DrawParameters<'a>,
-    model: Matrix4<f32>,
+    params: glium::DrawParameters<'static>,
 }
 
-impl<'a> Text<'a> {
-    pub fn new(display: &glium::Display) -> Text {
-        let image = image::load(Cursor::new(&include_bytes!("c64-font.png")[..]), image::PNG)
-            .unwrap()
-            .to_rgba();
-        let dimensions = image.dimensions();
-        let image =
-            glium::texture::RawImage2d::from_raw_rgba_reversed(image.into_raw(), dimensions);
-        let tex = glium::texture::CompressedSrgbTexture2d::new(display, image).unwrap();
+impl Text {
+    pub fn new(display: &Display) -> Text {
+        let (w, h, pixels) = c64_font();
+        let image = glium::texture::RawImage2d {
+            data: std::borrow::Cow::from(pixels),
+            width: w,
+            height: h,
+            format: glium::texture::ClientFormat::U8,
+        };
+        let tex = glium::texture::Texture2d::with_format(
+            display,
+            image,
+            glium::texture::UncompressedFloatFormat::U8,
+            glium::texture::MipmapsOption::NoMipmap,
+        ).unwrap();
 
         // building the vertex buffer, which contains all the vertices that we will draw
         let vertex_buffer = {
@@ -37,21 +81,21 @@ impl<'a> Text<'a> {
                 display,
                 &[
                     Vertex {
-                        position: [-1.0, -1.0],
-                        tex_coords: [0.0, 0.0],
-                    },
-                    Vertex {
-                        position: [-1.0, 1.0],
+                        position: [-0.5, -0.5],
                         tex_coords: [0.0, 1.0],
                     },
                     Vertex {
-                        position: [1.0, 1.0],
-                        tex_coords: [1.0, 1.0],
+                        position: [-0.5, 0.5],
+                        tex_coords: [0.0, 0.0],
                     },
                     Vertex {
-                        position: [1.0, -1.0],
+                        position: [0.5, 0.5],
                         tex_coords: [1.0, 0.0],
                     },
+                    Vertex {
+                        position: [0.5, -0.5],
+                        tex_coords: [1.0, 1.0],
+                    },
                 ],
             ).unwrap()
         };
@@ -62,40 +106,6 @@ impl<'a> Text<'a> {
             &[1 as u16, 2, 0, 3],
         ).unwrap();
 
-        // compiling shaders and linking them together
-        let program = program!(display,
-        140 => {
-            vertex: "
-                #version 140
-
-                uniform mat4 model;
-                uniform mat4 perspview;
-
-                in vec2 position;
-                in vec2 tex_coords;
-
-                out vec2 v_tex_coords;
-
-                void main() {
-                    gl_Position = perspview * model * vec4(position, 0.0, 1.0);
-                    // Characters are arranged in a 16x16 square.
-                    // Texture oordinates originate in the bottom-left corner.
-                    v_tex_coords = (tex_coords) / 16.0 + vec2(0. / 16., 15. / 16.);
-                }
-            ",
-
-            fragment: "
-                #version 140
-                uniform sampler2D tex;
-                in vec2 v_tex_coords;
-                out vec4 f_color;
-
-                void main() {
-                    f_color = texture(tex, v_tex_coords);
-                }
-            "
-        }).unwrap();
-
         let params = glium::DrawParameters {
             depth: glium::Depth {
                 test: glium::draw_parameters::DepthTest::IfLess,
@@ -107,22 +117,25 @@ impl<'a> Text<'a> {
         };
 
         Text {
-            model: Matrix4::one(),
             tex: tex,
             vertex_buffer: vertex_buffer,
             index_buffer: index_buffer,
-            program: program,
+            program: text_program(display),
             params: params,
         }
     }
 
-    pub fn draw(&self, frame: &mut glium::Frame, perspview: &[[f32; 4]; 4]) {
-        let uniforms = uniform! {
-            model: array4x4(self.model),
+    pub fn draw(&self, frame: &mut glium::Frame, c: char, model: &Matrix4<f32>, perspview: &[[f32; 4]; 4]) {
+        let uniforms =
+            uniform! {
+            model: array4x4(*model),
             perspview: *perspview,
             tex: self.tex.sampled()
-                //.minify_filter(glium::uniforms::MinifySamplerFilter::Nearest)
                 .magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest),
+            index: c as i32,
+            // RGB values from http://unusedino.de/ec64/technical/misc/vic656x/colors/
+            bgcolor: srgb([ 64,  50, 133u8]),  //  6 - blue
+            fgcolor: srgb([120, 106, 189u8]),  // 14 - light blue
         };
         frame
             .draw(