Re-enable fullscreen toggling
[mandelwow.git] / text.rs
1 use cgmath::conv::array4x4;
2 use cgmath::Matrix4;
3 use glium;
4 use glium::{Display, Program, Surface, implement_vertex, texture, uniform};
5 use std;
6
7 fn gamma<T>(x: T) -> f32
8 where
9     f32: From<T>,
10     T: Copy,
11 {
12     ((f32::from(x)) / 255.).powf(2.2)
13 }
14
15 fn srgb<T>(c: [T; 3]) -> [f32; 4]
16 where
17     f32: From<T>,
18     T: Copy,
19 {
20     [gamma(c[0]), gamma(c[1]), gamma(c[2]), 0.0]
21 }
22
23 #[cfg(feature = "image")]
24 fn c64_font() -> (u32, u32, Vec<u8>) {
25     let image = image::load_from_memory_with_format(
26         &include_bytes!("textures/c64-font.png")[..],
27         image::PNG,
28     ).unwrap()
29         .to_luma();
30     let (w, h) = image.dimensions();
31     (w, h, image.into_raw())
32 }
33
34 #[cfg(not(feature = "image"))]
35 fn c64_font() -> (u32, u32, Vec<u8>) {
36     let pixels = &include_bytes!("textures/c64-font.gray")[..];
37     (128, 128, Vec::from(pixels))
38 }
39
40 pub fn text_program(display: &Display) -> Program {
41     //load_program(display, "shaders/text.vert", "shaders/text.frag");
42     let vertex_shader_src = include_str!("shaders/text.vert");
43     let fragment_shader_src = include_str!("shaders/text.frag");
44     Program::from_source(display, vertex_shader_src, fragment_shader_src, None).unwrap()
45 }
46
47 #[derive(Copy, Clone)]
48 struct Vertex {
49     position: [f32; 2],
50     tex_coords: [f32; 2],
51 }
52 implement_vertex!(Vertex, position, tex_coords);
53
54 pub struct Text {
55     tex: texture::Texture2d,
56     vertex_buffer: glium::VertexBuffer<Vertex>,
57     index_buffer: glium::IndexBuffer<u16>,
58     program: glium::Program,
59     params: glium::DrawParameters<'static>,
60 }
61
62 impl Text {
63     pub fn new(display: &Display) -> Text {
64         let (w, h, pixels) = c64_font();
65         let image = glium::texture::RawImage2d {
66             data: std::borrow::Cow::from(pixels),
67             width: w,
68             height: h,
69             format: glium::texture::ClientFormat::U8,
70         };
71         let tex = glium::texture::Texture2d::with_format(
72             display,
73             image,
74             glium::texture::UncompressedFloatFormat::U8,
75             glium::texture::MipmapsOption::NoMipmap,
76         ).unwrap();
77
78         // building the vertex buffer, which contains all the vertices that we will draw
79         let vertex_buffer = {
80             glium::VertexBuffer::new(
81                 display,
82                 &[
83                     Vertex {
84                         position: [-0.5, -0.5],
85                         tex_coords: [0.0, 1.0],
86                     },
87                     Vertex {
88                         position: [-0.5, 0.5],
89                         tex_coords: [0.0, 0.0],
90                     },
91                     Vertex {
92                         position: [0.5, 0.5],
93                         tex_coords: [1.0, 0.0],
94                     },
95                     Vertex {
96                         position: [0.5, -0.5],
97                         tex_coords: [1.0, 1.0],
98                     },
99                 ],
100             ).unwrap()
101         };
102
103         let index_buffer = glium::IndexBuffer::new(
104             display,
105             glium::index::PrimitiveType::TriangleStrip,
106             &[1 as u16, 2, 0, 3],
107         ).unwrap();
108
109         let params = glium::DrawParameters {
110             depth: glium::Depth {
111                 test: glium::draw_parameters::DepthTest::IfLess,
112                 write: true,
113                 ..Default::default()
114             },
115             multisampling: true,
116             ..Default::default()
117         };
118
119         Text {
120             tex: tex,
121             vertex_buffer: vertex_buffer,
122             index_buffer: index_buffer,
123             program: text_program(display),
124             params: params,
125         }
126     }
127
128     pub fn draw(&self, frame: &mut glium::Frame, c: char, model: &Matrix4<f32>, perspview: &[[f32; 4]; 4]) {
129         let uniforms =
130             uniform! {
131             model: array4x4(*model),
132             perspview: *perspview,
133             tex: self.tex.sampled()
134                 .magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest),
135             index: c as i32,
136             // RGB values from http://unusedino.de/ec64/technical/misc/vic656x/colors/
137             bgcolor: srgb([ 64,  50, 133u8]),  //  6 - blue
138             fgcolor: srgb([120, 106, 189u8]),  // 14 - light blue
139         };
140         frame
141             .draw(
142                 &self.vertex_buffer,
143                 &self.index_buffer,
144                 &self.program,
145                 &uniforms,
146                 &self.params,
147             )
148             .unwrap();
149     }
150 }