From 32ff6ce2d75e898cd350172916751ec13226d5f8 Mon Sep 17 00:00:00 2001 From: LLLL Colonq Date: Wed, 9 Apr 2025 03:13:42 -0400 Subject: Reorganize into workspace --- src/font.rs | 363 ------------------------------------------------------------ 1 file changed, 363 deletions(-) delete mode 100644 src/font.rs (limited to 'src/font.rs') diff --git a/src/font.rs b/src/font.rs deleted file mode 100644 index e431896..0000000 --- a/src/font.rs +++ /dev/null @@ -1,363 +0,0 @@ -use std::collections::HashMap; - -use crate::{context, mesh, shader, texture}; -use glow::HasContext; - -pub struct Bitmap { - pub char_width: i32, - pub char_height: i32, - pub font_width: i32, - pub font_height: i32, - pub shader: shader::Shader, - pub font: texture::Texture, - pub vao: glow::VertexArray, - pub vertex_buf: glow::Buffer, - pub texcoords_buf: glow::Buffer, - pub colors_buf: glow::Buffer, - pub index_buf: glow::Buffer, -} - -impl Bitmap { - pub fn from_image( - ctx: &context::Context, - char_width: i32, char_height: i32, - font_width: i32, font_height: i32, - data: &[u8], - ) -> Self { - let shader = shader::Shader::new_nolib( - &ctx, - include_str!("assets/shaders/bitmap/vert.glsl"), - include_str!("assets/shaders/bitmap/frag.glsl"), - ); - let font = texture::Texture::new(ctx, data); - unsafe { - let vao = ctx.gl.create_vertex_array().expect("failed to initialize vao"); - ctx.gl.bind_vertex_array(Some(vao)); - let vertex_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_VERTEX, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_VERTEX); - let texcoords_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(texcoords_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_TEXCOORD, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_TEXCOORD); - let colors_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(colors_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_COLOR, 3, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_COLOR); - let index_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buf)); - Self { - char_width, char_height, - font_width, font_height, - shader, - font, - vao, - vertex_buf, - texcoords_buf, - colors_buf, - index_buf, - } - } - } - - pub fn new(ctx: &context::Context) -> Self { - Self::from_image(ctx, 7, 9, 112, 54, include_bytes!("assets/fonts/simple.png")) - } - - pub fn render_text_helper(&self, ctx: &context::Context, pos: &glam::Vec2, text: &str, color: &[glam::Vec3]) { - let mut cur = glam::Vec2::new(0.0, 0.0); - let mut vertices = Vec::new(); - let mut texcoords = Vec::new(); - let mut colors = Vec::new(); - let mut indices = Vec::new(); - let cwidth = self.char_width as f32 / self.font_width as f32; - let cheight = self.char_height as f32 / self.font_height as f32; - let row_len = self.font_width as u32 / self.char_width as u32; - for (i, c) in text.chars().enumerate() { - if c == '\n' { - cur.x = 0.0; - cur.y -= self.char_height as f32; - } else { - let idx = vertices.len() as u32; - vertices.push(cur); - vertices.push(cur + glam::Vec2::new(self.char_width as f32, 0.0)); - vertices.push(cur + glam::Vec2::new(self.char_width as f32, self.char_height as f32)); - vertices.push(cur + glam::Vec2::new(0.0, self.char_height as f32)); - let cidx = c as u32 - ' ' as u32; - let col = cidx % row_len; - let row = cidx / row_len; - let tcbase = glam::Vec2::new(col as f32 * cwidth, row as f32 * cheight); - texcoords.push(tcbase + glam::Vec2::new(0.0, cheight)); - texcoords.push(tcbase + glam::Vec2::new(cwidth, cheight)); - texcoords.push(tcbase + glam::Vec2::new(cwidth, 0.0)); - texcoords.push(tcbase); - let c = if let Some(c) = color.get(if color.len() == 0 { 0 } else { i % color.len() }) { - *c - } else { - glam::Vec3::new(1.0, 1.0, 1.0) - }; - colors.push(c); colors.push(c); colors.push(c); colors.push(c); - indices.push(idx + 0); indices.push(idx + 1); indices.push(idx + 2); - indices.push(idx + 0); indices.push(idx + 3); indices.push(idx + 2); - cur.x += self.char_width as f32; - } - } - let index_bytes: Vec = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); - self.shader.bind(ctx); - self.font.bind(ctx); - let scale = glam::Vec2::new(2.0 / ctx.render_width, 2.0 / ctx.render_height); - let offset = glam::Vec2::new( - -ctx.render_width / 2.0, - ctx.render_height / 2.0 - self.char_height as f32, - ); - let npos = (glam::Vec2::new(pos.x, -pos.y) + offset) * scale; - self.shader.set_mat4( - ctx, "transform", - &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(scale.x, scale.y, 1.0), - glam::Quat::IDENTITY, - glam::Vec3::new(npos.x, npos.y, 0.0), - ), - ); - unsafe { - ctx.gl.bind_vertex_array(Some(self.vao)); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vertex_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - vertices.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.texcoords_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - texcoords.as_ptr() as _, - texcoords.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.colors_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - colors.as_ptr() as _, - colors.len() * std::mem::size_of::() * 3, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - &index_bytes, - glow::STATIC_DRAW, - ); - ctx.gl.draw_elements(glow::TRIANGLES, indices.len() as _, glow::UNSIGNED_INT, 0); - } - } - - pub fn render_text(&self, ctx: &context::Context, pos: &glam::Vec2, text: &str) { - self.render_text_helper(ctx, pos, text, &[]); - } -} - -pub struct AtlasInfo { - pub pos: usize, -} - -pub struct TrueType { - pub shader: shader::Shader, - pub font: fontdue::Font, - pub atlas: texture::Texture, - pub atlaswidth: usize, - pub cellwidth: usize, - pub cellheight: usize, - pub info: HashMap, - pub vao: glow::VertexArray, - pub vertex_buf: glow::Buffer, - pub texcoords_buf: glow::Buffer, - pub colors_buf: glow::Buffer, - pub index_buf: glow::Buffer, -} - -impl TrueType { - pub fn new(ctx: &context::Context, size: f32, data: &[u8]) -> Self { - let shader = shader::Shader::new_nolib( - &ctx, - include_str!("assets/shaders/truetype/vert.glsl"), - include_str!("assets/shaders/truetype/frag.glsl"), - ); - let font = fontdue::Font::from_bytes(data, fontdue::FontSettings::default()) - .expect("failed to load font"); - let mut chardata = HashMap::new(); - for ci in 0..128 { - if let Some(c) = char::from_u32(ci) { - if !c.is_ascii_graphic() { continue; } - let res = font.rasterize(c, size); - chardata.insert(c, res); - } - } - let mut cellwidth = 0; - let mut cellbase = 0; - let mut cellextra = 0; - for (_, (m, _)) in &chardata { - if m.width > cellwidth { cellwidth = m.width } - if m.height > cellbase { cellbase = m.height } - let extra = (-m.ymin.min(0)) as usize; - if extra > cellextra { cellextra = extra } - } - let mut cellheight = cellbase + cellextra; - cellwidth = cellwidth.next_power_of_two(); - cellheight = cellheight.next_power_of_two(); - let atlaswidth = (chardata.len() * cellwidth).next_power_of_two(); - let mut info = HashMap::new(); - let mut atlas_bmp: Vec = vec![0; atlaswidth * cellheight]; - for (i, (c, (m, bmp))) in chardata.iter().enumerate() { - let by = ((cellbase as i32) - (m.height as i32) - m.ymin) as usize; - let bx = cellwidth * i; - info.insert(*c, AtlasInfo { - pos: cellwidth * i, - }); - for x in 0..m.width { - for y in 0..m.height { - atlas_bmp[bx + x + (by + y) * atlaswidth] = bmp[x + y * m.width]; - } - } - } - let atlas = texture::Texture::new_empty(ctx); - unsafe { - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(atlas.tex)); - ctx.gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1); - ctx.gl.tex_image_2d( - glow::TEXTURE_2D, - 0, - glow::R8 as i32, - atlaswidth as i32, - cellheight as i32, - 0, - glow::RED, - glow::UNSIGNED_BYTE, - Some(&atlas_bmp), - ); - ctx.gl.generate_mipmap(glow::TEXTURE_2D); - let vao = ctx.gl.create_vertex_array().expect("failed to initialize vao"); - ctx.gl.bind_vertex_array(Some(vao)); - let vertex_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_VERTEX, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_VERTEX); - let texcoords_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(texcoords_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_TEXCOORD, 2, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_TEXCOORD); - let colors_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(colors_buf)); - ctx.gl.vertex_attrib_pointer_f32(mesh::ATTRIB_COLOR, 3, glow::FLOAT, false, 0, 0); - ctx.gl.enable_vertex_attrib_array(mesh::ATTRIB_COLOR); - let index_buf = ctx.gl.create_buffer().expect("failed to create buffer object"); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buf)); - Self { - shader, font, atlas, atlaswidth, cellwidth, cellheight, info, - vao, vertex_buf, texcoords_buf, colors_buf, index_buf, - } - } - } - - pub fn render_text_helper(&self, ctx: &context::Context, pos: &glam::Vec2, spacing: &glam::Vec2, text: &str, color: &[glam::Vec3]) { - let mut cur = glam::Vec2::new(0.0, 0.0); - let mut vertices = Vec::new(); - let mut texcoords = Vec::new(); - let mut colors = Vec::new(); - let mut indices = Vec::new(); - let cellwidth = self.cellwidth as f32; - let cellheight = self.cellheight as f32; - let cwidth = cellwidth / self.atlaswidth as f32; - let cheight = 1.0; - for (i, c) in text.chars().enumerate() { - if c == '\n' { - cur.x = 0.0; - cur.y -= spacing.y; - } else { - let idx = vertices.len() as u32; - if let Some(off) = self.info.get(&c) { - vertices.push(cur); - vertices.push(cur + glam::Vec2::new(cellwidth, 0.0)); - vertices.push(cur + glam::Vec2::new(cellwidth, cellheight)); - vertices.push(cur + glam::Vec2::new(0.0, cellheight)); - let tcbase = glam::Vec2::new(off.pos as f32 / self.atlaswidth as f32, 0.0); - texcoords.push(tcbase + glam::Vec2::new(0.0, cheight)); - texcoords.push(tcbase + glam::Vec2::new(cwidth, cheight)); - texcoords.push(tcbase + glam::Vec2::new(cwidth, 0.0)); - texcoords.push(tcbase); - let c = if let Some(c) = color.get(i) { - *c - } else { - glam::Vec3::new(1.0, 1.0, 1.0) - }; - colors.push(c); colors.push(c); colors.push(c); colors.push(c); - indices.push(idx + 0); indices.push(idx + 1); indices.push(idx + 2); - indices.push(idx + 0); indices.push(idx + 3); indices.push(idx + 2); - } - cur.x += spacing.x; - } - } - let index_bytes: Vec = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); - let scale = glam::Vec2::new(2.0 / ctx.render_width, 2.0 / ctx.render_height); - let offset = glam::Vec2::new( - -ctx.render_width / 2.0, - ctx.render_height / 2.0 - cellheight as f32, - ); - let npos = (glam::Vec2::new(pos.x, -pos.y) + offset) * scale; - self.shader.bind(ctx); - self.shader.set_mat4( - ctx, "transform", - &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(scale.x, scale.y, 1.0), - glam::Quat::IDENTITY, - glam::Vec3::new(npos.x, npos.y, 0.0), - ), - ); - unsafe { - ctx.gl.active_texture(glow::TEXTURE0); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.atlas.tex)); - ctx.gl.bind_vertex_array(Some(self.vao)); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vertex_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - vertices.as_ptr() as _, - vertices.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.texcoords_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - texcoords.as_ptr() as _, - texcoords.len() * std::mem::size_of::() * 2, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.colors_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - std::slice::from_raw_parts( - colors.as_ptr() as _, - colors.len() * std::mem::size_of::() * 3, - ), - glow::STATIC_DRAW, - ); - ctx.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buf)); - ctx.gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - &index_bytes, - glow::STATIC_DRAW, - ); - ctx.gl.draw_elements(glow::TRIANGLES, indices.len() as _, glow::UNSIGNED_INT, 0); - } - } -} -- cgit v1.2.3