diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index ec14959..a89f471 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -4,6 +4,7 @@ use sdl2::event::Event; use sdl2::keyboard::{Keycode, Scancode}; use std::collections::*; use std::iter::FromIterator; +use std::str; use std::time::{Duration}; use opengl_rust::*; @@ -154,7 +155,7 @@ fn main () { ].into_iter () }); - let unis = shader_program.get_uniform_locations (uni_lookup.values ().map (|s| *s)); + let unis = shader_program.get_uniform_locations (uni_lookup.values ().copied ()); let unis: HashMap = HashMap::from_iter ( uni_lookup.iter () @@ -171,15 +172,28 @@ fn main () { texture.bind (); let model_data = load_small_file ("pumpking.iqm", 1024 * 1024); - let model = Model::from_slice (&model_data [..]); + let model = Model::from_slice (&model_data); let renderable_model = RenderableModel::from_iqm (&model); let sky_data = load_small_file ("sky-sphere.iqm", 1024 * 1024); - let sky_model = Model::from_slice (&sky_data [..]); + let sky_model = Model::from_slice (&sky_data); let renderable_sky = RenderableModel::from_iqm (&sky_model); + let renderable_pitch = { + let data = load_small_file ("pitch.iqm", 1024 * 1024); + let model = Model::from_slice (&data); + + for i in 0..model.meshes.len () { + let name = str::from_utf8 (model.get_mesh_name (i)).unwrap (); + + println! ("{} {}", i, name); + } + + RenderableModel::from_iqm (&model) + }; + glezz::enable_vertex_attrib_array (attrs ["pos"]); glezz::enable_vertex_attrib_array (attrs ["uv"]); glezz::enable_vertex_attrib_array (attrs ["normal"]); @@ -251,17 +265,27 @@ fn main () { { use uniforms::*; + glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); - glezz::uniform_3fv (unis [&ALBEDO], &orange); glezz::uniform_matrix_4fv (unis [&MVP], &mvp_mat); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); - renderable_model.draw (&attrs, 0); + { + glezz::uniform_3fv (unis [&ALBEDO], &orange); + renderable_model.draw (&attrs, 0); + + glezz::uniform_3fv (unis [&ALBEDO], &green); + renderable_model.draw (&attrs, 1); + } - glezz::uniform_3fv (unis [&ALBEDO], &green); - renderable_model.draw (&attrs, 1); + { + for i in 0..renderable_pitch.num_meshes () { + glezz::uniform_3fv (unis [&ALBEDO], &green); + renderable_pitch.draw (&attrs, i); + } + } let draw_sky = true; if draw_sky { diff --git a/src/iqm.rs b/src/iqm.rs index 35b0c0f..8ccfb84 100644 --- a/src/iqm.rs +++ b/src/iqm.rs @@ -78,7 +78,7 @@ pub struct Mesh { #[derive (Debug)] pub struct Header { - fields: [u32; 27], + pub fields: [u32; 27], } #[derive (Debug)] @@ -94,7 +94,7 @@ pub struct VertexArray { pub struct Model <'a> { data: &'a [u8], - header: Header, + pub header: Header, text: Vec , pub meshes: Vec , vertexarrays: Vec , @@ -274,4 +274,25 @@ impl <'a> Model <'a> { &self.data [offset..offset + num_bytes] } + + // I don't think IQM makes any guarantees about UTF-8 + // so I will only say that the slice has no NULs + + pub fn get_mesh_name (&self, index: usize) -> &[u8] { + let mesh = &self.meshes [index]; + + let ofs: usize = (self.header.fields [consts::OFS_TEXT] + mesh.name).try_into ().unwrap (); + + // There should be an easy way to do this with CString? + let mut nul_index = None; + for (j, c) in self.data [ofs..].iter ().enumerate () { + if *c == 0 { + nul_index = Some (j); + break; + } + } + let nul_index = nul_index.unwrap (); + + &self.data [ofs..ofs + nul_index] + } } diff --git a/src/renderable_model.rs b/src/renderable_model.rs index 116b315..5bfe8bb 100644 --- a/src/renderable_model.rs +++ b/src/renderable_model.rs @@ -37,6 +37,8 @@ unsafe fn vertex_attrib_pointer (id: Option , num_coords: i32, float_offset } impl RenderableModel { + //pub fn from_ + pub fn from_iqm (model: &iqm::Model) -> RenderableModel { let pos_bytes = model.get_vertex_slice (iqm::types::POSITION); let uv_bytes = model.get_vertex_slice (iqm::types::TEXCOORD); @@ -46,6 +48,10 @@ impl RenderableModel { let num_uv = uv_bytes.len () / 4; let num_normal = normal_bytes.len () / 4; + let num_vertexes = num_pos / 3; + assert_eq! (num_vertexes * 2, num_uv); + assert_eq! (num_vertexes * 3, num_normal); + let mut vertex_vec = vec! [0.0; num_pos + num_uv + num_normal]; LittleEndian::read_f32_into (pos_bytes, &mut vertex_vec [0..num_pos]); @@ -96,4 +102,8 @@ impl RenderableModel { gl::DrawRangeElements (gl::TRIANGLES, 0, self.indexes.max (), mesh.num_triangles * 3, gl::UNSIGNED_INT, (mesh.first_triangle * 3 * 4) as *const u8 as *const c_void); } } + + pub fn num_meshes (&self) -> usize { + self.meshes.len () + } }