diff options
| -rw-r--r-- | src/assets/shaders/bitmap/frag.glsl | 8 | ||||
| -rw-r--r-- | src/assets/shaders/bitmap/vert.glsl | 3 | ||||
| -rw-r--r-- | src/assets/shaders/truetype/frag.glsl | 17 | ||||
| -rw-r--r-- | src/assets/shaders/truetype/vert.glsl | 27 | ||||
| -rw-r--r-- | src/font.rs | 232 | ||||
| -rw-r--r-- | src/framebuffer.rs | 35 | ||||
| -rw-r--r-- | src/lib.rs | 25 | ||||
| -rw-r--r-- | src/mesh.rs | 1 | ||||
| -rw-r--r-- | src/shader.rs | 3 |
9 files changed, 243 insertions, 108 deletions
diff --git a/src/assets/shaders/bitmap/frag.glsl b/src/assets/shaders/bitmap/frag.glsl index 470a7b8..7df9a5c 100644 --- a/src/assets/shaders/bitmap/frag.glsl +++ b/src/assets/shaders/bitmap/frag.glsl @@ -2,16 +2,16 @@ precision highp float; uniform sampler2D texture_data; -uniform vec3 text_color; in vec2 vertex_texcoord; +in vec3 vertex_color; out vec4 frag_color; void main() { vec4 texel = texture(texture_data, vertex_texcoord); if (texel.rgb == vec3(0.0, 0.0, 0.0)) discard; - texel.r = text_color.r; - texel.g = text_color.g; - texel.b = text_color.b; + texel.r = vertex_color.r; + texel.g = vertex_color.g; + texel.b = vertex_color.b; frag_color = texel; } diff --git a/src/assets/shaders/bitmap/vert.glsl b/src/assets/shaders/bitmap/vert.glsl index 4ff9865..192d4b0 100644 --- a/src/assets/shaders/bitmap/vert.glsl +++ b/src/assets/shaders/bitmap/vert.glsl @@ -3,12 +3,15 @@ precision highp float; in vec2 vertex; in vec2 texcoord; +in vec3 color; uniform mat4 transform; out vec2 vertex_texcoord; +out vec3 vertex_color; void main() { vertex_texcoord = texcoord; + vertex_color = color; gl_Position = transform * vec4(vertex, 0.0, 1.0); } diff --git a/src/assets/shaders/truetype/frag.glsl b/src/assets/shaders/truetype/frag.glsl index b0e25bf..3f62e01 100644 --- a/src/assets/shaders/truetype/frag.glsl +++ b/src/assets/shaders/truetype/frag.glsl @@ -2,22 +2,15 @@ precision highp float; uniform sampler2D texture_data; -uniform int text[256]; -uniform int atlas_width; -uniform int cell_width; -uniform int text_width; in vec2 vertex_texcoord; +in vec3 vertex_color; out vec4 frag_color; void main() { - vec2 inverted_texcoord = vec2(vertex_texcoord.x, 1.0 - vertex_texcoord.y); - float texcoord_pixels_x = inverted_texcoord.x * float(text_width); - int char_idx = int(floor(texcoord_pixels_x)) / cell_width; - int offset = text[char_idx]; - float cbase = float(offset); - float coff = mod(texcoord_pixels_x, float(cell_width)); - float val = texture(texture_data, vec2((cbase + coff) / float(atlas_width), inverted_texcoord.y)).r; - frag_color = vec4(val, val, val, 1.0); + float val = texture(texture_data, vertex_texcoord).r; + if (val == 0.0) discard; + vec4 texel = vec4(vertex_color, val); + frag_color = texel; } diff --git a/src/assets/shaders/truetype/vert.glsl b/src/assets/shaders/truetype/vert.glsl index 4005d75..192d4b0 100644 --- a/src/assets/shaders/truetype/vert.glsl +++ b/src/assets/shaders/truetype/vert.glsl @@ -1,26 +1,17 @@ #version 300 es precision highp float; -uniform mat4 view; -uniform mat4 position; +in vec2 vertex; +in vec2 texcoord; +in vec3 color; + +uniform mat4 transform; out vec2 vertex_texcoord; +out vec3 vertex_color; void main() { - const vec2 positions[4] = vec2[]( - vec2(-1, -1), - vec2(+1, -1), - vec2(-1, +1), - vec2(+1, +1) - ); - const vec2 coords[4] = vec2[]( - vec2(0, 0), - vec2(1, 0), - vec2(0, 1), - vec2(1, 1) - ); - vec4 vertex = vec4(positions[gl_VertexID], 0.0, 1.0); - - vertex_texcoord = coords[gl_VertexID]; - gl_Position = view * position * vertex; + vertex_texcoord = texcoord; + vertex_color = color; + gl_Position = transform * vec4(vertex, 0.0, 1.0); } diff --git a/src/font.rs b/src/font.rs index 047e1f7..3074dff 100644 --- a/src/font.rs +++ b/src/font.rs @@ -3,73 +3,87 @@ use std::collections::HashMap; use crate::{context, mesh, shader, texture}; use glow::HasContext; -pub const CHAR_WIDTH: i32 = 7; -pub const CHAR_HEIGHT: i32 = 9; -pub const FONT_WIDTH: i32 = 112; -pub const FONT_HEIGHT: i32 = 54; - 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 new(ctx: &context::Context) -> Self { + 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, include_bytes!("assets/fonts/simple.png")); + 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 render_text_helper(&self, ctx: &context::Context, pos: &glam::Vec2, text: &str, color: &glam::Vec3) { + 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 = CHAR_WIDTH as f32 / FONT_WIDTH as f32; - let cheight = CHAR_HEIGHT as f32 / FONT_HEIGHT as f32; - let row_len = FONT_WIDTH as u32 / CHAR_WIDTH as u32; - for c in text.chars() { + 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 += CHAR_HEIGHT as f32; + cur.y -= self.char_height as f32; } else { let idx = vertices.len() as u32; vertices.push(cur); - vertices.push(cur + glam::Vec2::new(CHAR_WIDTH as f32, 0.0)); - vertices.push(cur + glam::Vec2::new(CHAR_WIDTH as f32, CHAR_HEIGHT as f32)); - vertices.push(cur + glam::Vec2::new(0.0, CHAR_HEIGHT as f32)); + 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; @@ -78,9 +92,15 @@ impl Bitmap { 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 += CHAR_WIDTH as f32; + cur.x += self.char_width as f32; } } let index_bytes: Vec<u8> = indices.iter().flat_map(|x| x.to_ne_bytes()).collect(); @@ -89,10 +109,9 @@ impl Bitmap { 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 - CHAR_HEIGHT as f32, + ctx.render_height / 2.0 - self.char_height as f32, ); let npos = (glam::Vec2::new(pos.x, -pos.y) + offset) * scale; - self.shader.set_vec3(ctx, "text_color", color as _); self.shader.set_mat4( ctx, "transform", &glam::Mat4::from_scale_rotation_translation( @@ -121,6 +140,15 @@ impl Bitmap { ), 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::<f32>() * 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, @@ -132,7 +160,7 @@ impl Bitmap { } pub fn render_text(&self, ctx: &context::Context, pos: &glam::Vec2, text: &str) { - self.render_text_helper(ctx, pos, text, &glam::Vec3::new(1.0, 1.0, 1.0)); + self.render_text_helper(ctx, pos, text, &[]); } } @@ -148,20 +176,22 @@ pub struct TrueType { pub cellwidth: usize, pub cellheight: usize, pub info: HashMap<char, AtlasInfo>, + 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) -> Self { + 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 size = 20.0; - let font = fontdue::Font::from_bytes( - include_bytes!("assets/fonts/ComicNeue-Regular.ttf") as &[u8], - fontdue::FontSettings::default(), - ).expect("failed to load font"); + 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) { @@ -213,51 +243,121 @@ impl TrueType { 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, + } } - Self { shader, font, atlas, atlaswidth, cellwidth, cellheight, info, } } - pub fn render_text(&self, ctx: &context::Context, pos: &glam::Vec2, text: &str) { - self.shader.bind(ctx); - unsafe { - ctx.gl.active_texture(glow::TEXTURE0); - ctx.gl.bind_texture(glow::TEXTURE_2D, Some(self.atlas.tex)); + 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; + } } - self.shader.set_mat4( - ctx, "view", - &glam::Mat4::from_scale( - glam::Vec3::new( - 2.0 / ctx.render_width, - 2.0 / ctx.render_height, - 1.0, - ), - ), + let index_bytes: Vec<u8> = 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 width = text.len() * self.cellwidth; + let npos = (glam::Vec2::new(pos.x, -pos.y) + offset) * scale; + self.shader.bind(ctx); self.shader.set_mat4( - ctx, "position", + ctx, "transform", &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(width as f32 / 2.0, self.cellheight as f32 / 2.0, 1.0), + glam::Vec3::new(scale.x, scale.y, 1.0), glam::Quat::IDENTITY, - glam::Vec3::new( - -ctx.render_width / 2.0 + pos.x + width as f32 / 2.0, - ctx.render_height / 2.0 - pos.y - self.cellheight as f32 / 2.0, - 0.0, - ), - ) + glam::Vec3::new(npos.x, npos.y, 0.0), + ), ); - let len = text.len().min(256); - let textvals: Vec<i32> = text.chars().take(len).map(|c| { - if let Some(i) = self.info.get(&c) { - i.pos as i32 - } else { - 0 - } - }).collect(); - self.shader.set_i32_array(ctx, "text[0]", &textvals); - self.shader.set_i32(ctx, "atlas_width", self.atlaswidth as i32); - self.shader.set_i32(ctx, "cell_width", self.cellwidth as i32); - self.shader.set_i32(ctx, "text_width", width as i32); - ctx.render_no_geometry(); + 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::<f32>() * 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::<f32>() * 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::<f32>() * 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); + } } } diff --git a/src/framebuffer.rs b/src/framebuffer.rs index ae96d6a..f97a967 100644 --- a/src/framebuffer.rs +++ b/src/framebuffer.rs @@ -102,4 +102,39 @@ impl Framebuffer { ); } } + + pub fn blit(&self, ctx: &context::Context, dest: &Self, pos: &glam::Vec2, scale: &glam::Vec2) { + unsafe { + ctx.gl.bind_framebuffer(glow::READ_FRAMEBUFFER, self.fbo); + ctx.gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, dest.fbo); + ctx.gl.blit_framebuffer( + 0, 0, self.dims.x as _, self.dims.y as _, + pos.x as _, pos.y as _, (pos.x + scale.x) as _, (pos.y + scale.y) as _, + glow::COLOR_BUFFER_BIT, glow::NEAREST + ); + } + } + + pub fn get_pixels(&self, ctx: &context::Context, buf: &mut [glam::Vec3]) { + let w = self.dims.x as usize; + let h = self.dims.y as usize; + let tmp = vec![glam::Vec3::default(); w * h]; + unsafe { + ctx.gl.bind_texture(glow::TEXTURE_2D, self.tex); + ctx.gl.get_tex_image( + glow::TEXTURE_2D, 0, glow::RGB, glow::FLOAT, + glow::PixelPackData::Slice( + std::slice::from_raw_parts_mut( + tmp.as_ptr() as *mut u8, + tmp.len() * std::mem::size_of::<glam::Vec3>() + ) + ), + ); + } + for y in 0..h { + for x in 0..w { + buf[x + (h - 1 - y) * w] = tmp[x + y * w]; + } + } + } } @@ -287,9 +287,10 @@ impl TestGame { pub async fn new(ctx: &context::Context) -> Self { Self { font: font::Bitmap::new(ctx), - tt: font::TrueType::new(ctx), + tt: font::TrueType::new(ctx, 12.0, include_bytes!("assets/fonts/ComicNeue-Regular.ttf")), cube: mesh::Mesh::from_obj(ctx, include_bytes!("assets/meshes/cube.obj")), - fox: scene::Scene::from_gltf(ctx, include_bytes!("assets/scenes/fox.glb")), + // fox: scene::Scene::from_gltf(ctx, include_bytes!("assets/scenes/fox.glb")), + fox: scene::Scene::from_gltf(ctx, include_bytes!("/home/llll/src/colonq/assets/lcolonq_flat.vrm")), tex: texture::Texture::new(ctx, include_bytes!("assets/textures/test.png")), shader: shader::Shader::new(ctx, include_str!("assets/shaders/scene/vert.glsl"), include_str!("assets/shaders/scene/frag.glsl")), } @@ -307,15 +308,16 @@ impl state::Game for TestGame { Some(()) } fn render(&mut self, ctx: &context::Context, st: &mut state::State) -> Option<()> { - // if let Some(n) = self.fox.nodes_by_name.get("J_Bip_C_Neck").and_then(|i| self.fox.nodes.get_mut(*i)) { - // n.transform *= glam::Mat4::from_rotation_z(0.05); - // } - self.fox.reflect_animation("Run", (st.tick as f32 / 60.0).rem(3.0)); + if let Some(n) = self.fox.nodes_by_name.get("J_Bip_C_Neck").and_then(|i| self.fox.nodes.get_mut(*i)) { + n.transform *= glam::Mat4::from_rotation_z(0.05); + } + // self.fox.reflect_animation("Run", (st.tick as f32 / 60.0).rem(3.0)); st.bind_3d(ctx, &self.shader); self.shader.set_position_3d( ctx, &glam::Mat4::from_scale_rotation_translation( - glam::Vec3::new(0.005, 0.005, 0.005), + // glam::Vec3::new(0.005, 0.005, 0.005), + glam::Vec3::new(1.0, 1.0, 1.0), glam::Quat::from_rotation_y(st.tick as f32 / 60.0), glam::Vec3::new(0.0, -0.2, 0.0), ), @@ -323,7 +325,14 @@ impl state::Game for TestGame { self.tex.bind(ctx); self.fox.render(ctx, &self.shader); self.font.render_text(ctx, &glam::Vec2::new(0.0, 10.0), "he's all FIXED up"); - // self.tt.render_text(ctx, &glam::Vec2::new(10.0, 10.0), "tESTge"); + self.tt.render_text_helper( + ctx, &glam::Vec2::new(10.0, 60.0), &glam::Vec2::new(20.0, 30.0), + "tESTge", + &[ + glam::Vec3::new(1.0, 0.0, 0.0), + glam::Vec3::new(0.0, 1.0, 0.0), + ], + ); Some(()) } } diff --git a/src/mesh.rs b/src/mesh.rs index 56d735f..7209de1 100644 --- a/src/mesh.rs +++ b/src/mesh.rs @@ -7,6 +7,7 @@ pub const ATTRIB_NORMAL: u32 = 1; pub const ATTRIB_TEXCOORD: u32 = 2; pub const ATTRIB_JOINT: u32 = 3; pub const ATTRIB_WEIGHT: u32 = 4; +pub const ATTRIB_COLOR: u32 = 5; pub struct Mesh { pub vao: glow::VertexArray, diff --git a/src/shader.rs b/src/shader.rs index cbaf3ee..408380d 100644 --- a/src/shader.rs +++ b/src/shader.rs @@ -46,6 +46,9 @@ impl Shader { ctx.gl.bind_attrib_location(program, mesh::ATTRIB_VERTEX, "vertex"); ctx.gl.bind_attrib_location(program, mesh::ATTRIB_NORMAL, "normal"); ctx.gl.bind_attrib_location(program, mesh::ATTRIB_TEXCOORD, "texcoord"); + ctx.gl.bind_attrib_location(program, mesh::ATTRIB_JOINT, "joint"); + ctx.gl.bind_attrib_location(program, mesh::ATTRIB_WEIGHT, "weight"); + ctx.gl.bind_attrib_location(program, mesh::ATTRIB_COLOR, "color"); ctx.gl.link_program(program); if !ctx.gl.get_program_link_status(program) { |
