diff --git a/font.png b/font.png new file mode 100644 index 0000000..f8eb352 Binary files /dev/null and b/font.png differ diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index b2b452a..b941831 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -473,6 +473,7 @@ struct GameGraphics { texture_sky: Texture, texture_grass: Texture, + texture_font: Texture, pitch_colors: Vec , grass_index: usize, @@ -537,6 +538,7 @@ impl GameGraphics { let texture_sky = Texture::from_file ("sky.png"); let texture_grass = Texture::from_file ("grass.png"); + let texture_font = Texture::from_file ("font.png"); let (pitch_colors, grass_index) = { let silver = (255.0, 255.0, 255.0); @@ -582,7 +584,9 @@ impl GameGraphics { Pass { iso: IsoGlState { shader_id: None, - flags: hashmap! {}, + flags: hashmap! { + + }, front_face: None, stencil: None, depth_func: None, @@ -749,6 +753,37 @@ impl GameGraphics { stencil_mask: Some (0), }, }, + // Clear depth + Pass { + iso: IsoGlState { + shader_id: None, + flags: hashmap! {}, + front_face: None, + stencil: None, + depth_func: None, + color_mask: None, + depth_mask: Some (1), + stencil_mask: None, + }, + }, + // Draw UI + Pass { + iso: IsoGlState { + shader_id: Some (shaders [0].get_id ()), + flags: hashmap! { + gl::CULL_FACE => false, + gl::DEPTH_TEST => false, + gl::TEXTURE_2D => true, + gl::STENCIL_TEST => false, + }, + front_face: None, + stencil: None, + depth_func: Some (DepthFunc::Less), + color_mask: Some ((1, 1, 1, 1)), + depth_mask: Some (1), + stencil_mask: Some (0), + }, + }, ]; Self { @@ -763,6 +798,7 @@ impl GameGraphics { texture_sky, texture_grass, + texture_font, pitch_colors, grass_index, @@ -777,18 +813,11 @@ impl GameGraphics { ) { let magenta = color_from_255 ((255.0, 0.0, 255.0)); - let orange = color_from_255 ((210.0, 125.0, 44.0)); - let green = color_from_255 ((52.0, 101.0, 36.0)); let white = color_from_255 ((255.0, 255.0, 255.0)); let _off_white = color_from_255 ((222.0, 238.0, 214.0)); let black = color_from_255 ((0.0, 0.0, 0.0)); let _off_black = color_from_255 ((20.0, 12.0, 28.0)); - let pumpkin_colors = vec! [ - orange, - green, - ]; - let light = state.wind_tunnel.sunlight.to_vec3 (); let shadow_mat = { @@ -820,7 +849,9 @@ impl GameGraphics { }; let inverse_airplane = airplane_model_mat.inverse (); - let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), 1280.0 / 720.0, 0.125, 200.0); + let screen_size = (1280.0, 720.0); + + let proj_mat = Mat4::perspective_rh_gl (30.0f32.to_radians (), screen_size.0 / screen_size.1, 0.125, 200.0); let airplane_scale = 1.0 / 128.0; @@ -929,6 +960,8 @@ impl GameGraphics { } }); + self.texture_grass.bind (); + // Draw unlit ground passes.next ().unwrap ().with_shader (gl_state, self, |shader_vars| { @@ -943,20 +976,18 @@ impl GameGraphics { let mvp = view_mat * world_model_mat; glezz::uniform_matrix_4fv (unis [&MVP], &mvp); - glezz::uniform_3fv (unis [&ALBEDO], &self.pitch_colors [self.grass_index]); - + glezz::uniform_3fv (unis [&ALBEDO], &white); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &Vec3::from ((0.0, 0.0, 0.0))); self.mesh_pitch.draw (attrs, self.grass_index); }); - self.texture_grass.bind (); - // Draw lit ground passes.next ().unwrap ().with_shader (gl_state, self, |shader_vars| { let unis = shader_vars.unis; let attrs = shader_vars.attrs; + glezz::uniform_3fv (unis [&ALBEDO], &white); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &light); glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &Vec3::from ((0.0, 0.0, 1.0))); self.mesh_pitch.draw (attrs, self.grass_index); @@ -989,6 +1020,65 @@ impl GameGraphics { self.mesh_arrow.draw_all (shader_vars.attrs, |_| true); } }); + + // Clear depth + passes.next ().unwrap ().with (gl_state, || { + glezz::clear (gl::DEPTH_BUFFER_BIT); + }); + + // Draw UI + + self.texture_font.bind (); + if true { + passes.next ().unwrap ().with_shader (gl_state, self, + |shader_vars| { + let attrs = &shader_vars.attrs; + let unis = &shader_vars.unis; + + glezz::uniform_3fv (unis [&MIN_BRIGHT], &white); + glezz::uniform_3fv (unis [&MIN_ALBEDO], &black); + glezz::uniform_3fv (unis [&ALBEDO], &white); + + let font_size = (8.0, 18.0); + + let mvp = Mat4::from_scale ((2.0 * 256.0 / screen_size.0, 2.0 * 72.0 / screen_size.1, 1.0).into ()); + glezz::uniform_matrix_4fv (unis [&MVP], &mvp); + + let pos: Vec = vec! [ + 0.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 1.0, 1.0, 0.0, + 0.0, 1.0, 0.0, + ]; + + use std::convert::TryInto; + + let uv: Vec = vec! [ + 0.0, 1.0, + 1.0, 1.0, + 1.0, 0.0, + 0.0, 0.0, + ]; + + let indices: Vec = vec! [ + 0, 1, 2, + 0, 2, 3, + ]; + + unsafe { + use renderable_model::attributes::*; + use std::ffi::c_void; + + gl::BindBuffer (gl::ARRAY_BUFFER, 0); + gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, 0); + + gl::VertexAttribPointer (attrs [POS].unwrap (), 3, gl::FLOAT, 0u8, 4 * 3, &pos [0] as *const f32 as *const c_void); + gl::VertexAttribPointer (attrs [UV].unwrap (), 2, gl::FLOAT, 0u8, 4 * 2, &uv [0] as *const f32 as *const c_void); + + gl::DrawRangeElements (gl::TRIANGLES, 0, 6, 6, gl::UNSIGNED_INT, &indices [0] as *const u32 as *const c_void); + } + }); + } } } diff --git a/src/gl_state.rs b/src/gl_state.rs index 846dad7..8b2dfb3 100644 --- a/src/gl_state.rs +++ b/src/gl_state.rs @@ -206,6 +206,7 @@ impl Pass { for (flag, value) in state.flags.iter () { let old_entry = old_state.flags.entry (*flag); + if match &old_entry { hash_map::Entry::Vacant (_) => true, hash_map::Entry::Occupied (o) => o.get () != value, @@ -217,7 +218,7 @@ impl Pass { glezz::disable (*flag); } - old_entry.or_insert (*value); + (*old_entry.or_insert (*value)) = *value; } else { flag_elision_count += 1; @@ -326,6 +327,7 @@ impl Pass { { if let Some (s) = self.iso.shader_id { self.apply_diff (&mut gl_state.iso); + //self.apply_slow (); shader_component.lookup (s).with (gl_state.iso.shader_id, |shader_vars| { callback (shader_vars); }); diff --git a/src/texture.rs b/src/texture.rs index c7fd9aa..ad0888d 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -25,8 +25,17 @@ impl Texture { gl::GenTextures (1, &mut id); assert! (id != 0); + let width = info.width.try_into ().unwrap (); + let height = info.height.try_into ().unwrap (); + + let format = match info.color_type { + png::ColorType::RGB => gl::RGB, + png::ColorType::RGBA => gl::RGBA, + _ => panic! ("ColorType not implemented"), + }; + gl::BindTexture (gl::TEXTURE_2D, id); - gl::TexImage2D (gl::TEXTURE_2D, 0, gl::RGBA.try_into ().unwrap (), 1024, 1024, 0, gl::RGBA, gl::UNSIGNED_BYTE, &buf [0] as *const u8 as *const c_void); + gl::TexImage2D (gl::TEXTURE_2D, 0, format.try_into ().unwrap (), width, height, 0, format, gl::UNSIGNED_BYTE, &buf [0] as *const u8 as *const c_void); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_S, gl::CLAMP_TO_EDGE as i32); gl::TexParameteri (gl::TEXTURE_2D, gl::TEXTURE_WRAP_T, gl::CLAMP_TO_EDGE as i32);