use cgmath::conv::array4x4;
-use cgmath::{Matrix4, One};
+use cgmath::{Matrix4, Vector3};
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 {
implement_vertex!(Vertex, position, tex_coords);
pub struct Text<'a> {
- tex: texture::CompressedSrgbTexture2d,
+ tex: texture::Texture2d,
vertex_buffer: glium::VertexBuffer<Vertex>,
index_buffer: glium::IndexBuffer<u16>,
program: glium::Program,
params: glium::DrawParameters<'a>,
- model: Matrix4<f32>,
+ pub model: Matrix4<f32>,
+ pub character: char,
}
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();
+ pub fn new(display: &Display, character: char) -> 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 = {
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()
};
&[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,
};
Text {
- model: Matrix4::one(),
tex: tex,
vertex_buffer: vertex_buffer,
index_buffer: index_buffer,
- program: program,
+ program: text_program(display),
params: params,
+ model: Matrix4::from_translation(Vector3::unit_z() * (-1.0)),
+ character: character,
}
}
pub fn draw(&self, frame: &mut glium::Frame, perspview: &[[f32; 4]; 4]) {
- let uniforms = uniform! {
+ let uniforms =
+ uniform! {
model: array4x4(self.model),
perspview: *perspview,
tex: self.tex.sampled()
- //.minify_filter(glium::uniforms::MinifySamplerFilter::Nearest)
.magnify_filter(glium::uniforms::MagnifySamplerFilter::Nearest),
+ index: self.character 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(