diff --git a/src/bin/pumpkin.rs b/src/bin/pumpkin.rs index ef7e432..cf3d77d 100644 --- a/src/bin/pumpkin.rs +++ b/src/bin/pumpkin.rs @@ -82,24 +82,6 @@ void main (void) { } "; -unsafe fn vertex_attrib_pointer (id: Option , num_coords: i32, slice: &[u8]) { - const FALSE_U8: u8 = 0; - const FLOAT_SIZE: i32 = 4; - - if let Some (id) = id { - gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, &slice [0] as *const u8 as *const c_void); - } -} - -unsafe fn point_to_model ( - attrs: &HashMap >, - model: &Model -) { - vertex_attrib_pointer (attrs ["pos"], 3, model.get_vertex_slice (0)); - vertex_attrib_pointer (attrs ["uv"], 2, model.get_vertex_slice (1)); - vertex_attrib_pointer (attrs ["normal"], 3, model.get_vertex_slice (2)); -} - const KEY_LEFT: usize = 0; const KEY_RIGHT: usize = KEY_LEFT + 1; const KEY_UP: usize = KEY_RIGHT + 1; @@ -232,6 +214,8 @@ fn main () { let sky_data = load_small_file ("sky-sphere.iqm", 1024 * 1024); let sky_model = Model::from_slice (&sky_data [..]); + let renderable_sky = glezz::RenderableModel::from_iqm (&sky_model); + const FALSE_U8: u8 = 0; glezz::enable_vertex_attrib_array (attrs ["pos"]); @@ -239,7 +223,7 @@ fn main () { glezz::enable_vertex_attrib_array (attrs ["normal"]); glezz::enable (gl::DEPTH_TEST); - glezz::enable (gl::TEXTURE); + glezz::enable (gl::TEXTURE_2D); let mut time_step = TimeStep::new (60, 1000); let mut state = WorldState::new (); @@ -317,22 +301,13 @@ fn main () { let draw_sky = true; if draw_sky { - unsafe { - gl::BindBuffer (gl::ARRAY_BUFFER, 0); - gl::BindBuffer (gl::ELEMENT_ARRAY_BUFFER, 0); - } - glezz::uniform_matrix_4fv (unis ["mvp"], &sky_mvp_mat); glezz::uniform_3fv (unis ["albedo"], &white); glezz::uniform_3fv (unis ["min_bright"], &white); glezz::uniform_3fv (unis ["min_albedo"], &black); glezz::uniform_1i (unis ["texture"], 0); - unsafe { - point_to_model (&attrs, &sky_model); - - gl::DrawElements (gl::TRIANGLES, (sky_model.meshes [0].num_triangles * 3) as i32, gl::UNSIGNED_INT, &sky_model.get_index_slice (0) [0] as *const u8 as *const c_void); - } + renderable_sky.draw (&attrs, 0); } window.gl_swap_window (); diff --git a/src/glezz.rs b/src/glezz.rs index 0733d42..af04d0a 100644 --- a/src/glezz.rs +++ b/src/glezz.rs @@ -77,24 +77,19 @@ pub struct VertexBuffer { id: u32, // Not bytes. len: usize, - // Assuming arrays are packed, not interleaved - // Typically 3, or 2 for UV. - num_coords: i32, } impl VertexBuffer { - pub fn from_slice (slice: &[u8], num_coords: i32) -> Self { + pub fn from_slice (slice: &[f32]) -> Self { const FLOAT_SIZE: usize = 4; - assert_eq! (slice.len () % (FLOAT_SIZE * (num_coords as usize)), 0); - let id = { let mut id = 0; unsafe { gl::GenBuffers (1, &mut id); gl::BindBuffer (gl::ARRAY_BUFFER, id); - gl::BufferData (gl::ARRAY_BUFFER, slice.len ().try_into ().unwrap (), &slice [0] as *const u8 as *const c_void, gl::STATIC_DRAW); + gl::BufferData (gl::ARRAY_BUFFER, (slice.len () * 4).try_into ().unwrap (), &slice [0] as *const f32 as *const c_void, gl::STATIC_DRAW); } assert! (id != 0); id @@ -103,7 +98,6 @@ impl VertexBuffer { Self { id, len: slice.len (), - num_coords, } } @@ -131,7 +125,6 @@ struct IndexBuffer { id: u32, // Not bytes. Number of indexes. len: usize, - min: u32, max: u32, } @@ -139,7 +132,6 @@ impl IndexBuffer { pub fn from_slice (slice: &[u8]) -> Self { let mut rdr = Cursor::new (slice); - let mut min = None; let mut max = None; const IDX_SIZE: usize = 4; @@ -149,11 +141,6 @@ impl IndexBuffer { for _ in 0..slice.len () / IDX_SIZE { let idx = rdr.read_u32:: ().unwrap (); - min = match min { - None => Some (idx), - Some (min) => Some (cmp::min (min, idx)), - }; - max = match max { None => Some (idx), Some (max) => Some (cmp::max (max, idx)), @@ -175,7 +162,6 @@ impl IndexBuffer { Self { id, len: slice.len () / IDX_SIZE, - min: min.unwrap (), max: max.unwrap (), } } @@ -211,46 +197,51 @@ struct RenderableMesh { } pub struct RenderableModel { - pos: Vec , - uv: Vec , - normals: Vec , + num_pos: usize, + num_uv: usize, + num_normal: usize, + vertexes: VertexBuffer, indexes: IndexBuffer, meshes: Vec , } -unsafe fn vertex_attrib_pointer (id: Option , num_coords: i32, slice: &[f32]) { +unsafe fn vertex_attrib_pointer (id: Option , num_coords: i32, float_offset: usize) { const FALSE_U8: u8 = 0; const FLOAT_SIZE: i32 = 4; if let Some (id) = id { - gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, &slice [0] as *const f32 as *const c_void); + gl::VertexAttribPointer (id, num_coords, gl::FLOAT, FALSE_U8, FLOAT_SIZE * num_coords, (float_offset * 4) as *const u8 as *const c_void); } } impl RenderableModel { pub fn from_iqm (model: &iqm::Model) -> RenderableModel { let pos_bytes = model.get_vertex_slice (iqm::types::POSITION); - let mut pos_vec = vec! [0.0; pos_bytes.len () / 4]; - LittleEndian::read_f32_into (pos_bytes, &mut pos_vec [..]); - let uv_bytes = model.get_vertex_slice (iqm::types::TEXCOORD); - let mut uv_vec = vec! [0.0; uv_bytes.len () / 4]; - LittleEndian::read_f32_into (uv_bytes, &mut uv_vec [..]); - let normal_bytes = model.get_vertex_slice (iqm::types::NORMAL); - let mut normal_vec = vec! [0.0; normal_bytes.len () / 4]; - LittleEndian::read_f32_into (normal_bytes, &mut normal_vec [..]); + + let num_pos = pos_bytes.len () / 4; + let num_uv = uv_bytes.len () / 4; + let num_normal = normal_bytes.len () / 4; + + 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]); + LittleEndian::read_f32_into (uv_bytes, &mut vertex_vec [num_pos..num_pos + num_uv]); + LittleEndian::read_f32_into (normal_bytes, &mut vertex_vec [num_pos + num_uv..num_pos + num_uv + num_normal]); + + let vertexes = VertexBuffer::from_slice (&vertex_vec); let index_slice = model.get_all_indexes (); let indexes = IndexBuffer::from_slice (index_slice); let max_index: usize = indexes.max.try_into ().unwrap (); - assert! (max_index * 3 < pos_vec.len ()); - assert! (max_index * 2 < uv_vec.len ()); - assert! (max_index * 3 < normal_vec.len ()); + assert! (max_index * 3 < num_pos); + assert! (max_index * 2 < num_uv); + assert! (max_index * 3 < num_normal); let meshes = model.meshes.iter () .map (|mesh| RenderableMesh { @@ -260,10 +251,11 @@ impl RenderableModel { .collect (); Self { - pos: pos_vec, - uv: uv_vec, - normals: normal_vec, + num_pos, + num_uv, + num_normal, + vertexes, indexes, meshes, } @@ -273,13 +265,13 @@ impl RenderableModel { { let mesh = &self.meshes [mesh_num]; + self.vertexes.bind (); + self.indexes.bind (); + unsafe { - gl::BindBuffer (gl::ARRAY_BUFFER, 0); - self.indexes.bind (); - - vertex_attrib_pointer (attrs ["pos"], 3, &self.pos); - vertex_attrib_pointer (attrs ["uv"], 2, &self.uv); - vertex_attrib_pointer (attrs ["normal"], 3, &self.normals); + vertex_attrib_pointer (attrs ["pos"], 3, 0); + vertex_attrib_pointer (attrs ["uv"], 2, self.num_pos); + vertex_attrib_pointer (attrs ["normal"], 3, self.num_pos + self.num_uv); gl::DrawElements (gl::TRIANGLES, mesh.num_triangles * 3, gl::UNSIGNED_INT, (mesh.first_triangle * 3 * 4) as *const u8 as *const c_void); }