Add func to retrieve mesh names

main
_ 2020-03-07 02:23:23 +00:00
parent cd46a8dfcb
commit e5b6d7839a
3 changed files with 64 additions and 9 deletions

View File

@ -4,6 +4,7 @@ use sdl2::event::Event;
use sdl2::keyboard::{Keycode, Scancode}; use sdl2::keyboard::{Keycode, Scancode};
use std::collections::*; use std::collections::*;
use std::iter::FromIterator; use std::iter::FromIterator;
use std::str;
use std::time::{Duration}; use std::time::{Duration};
use opengl_rust::*; use opengl_rust::*;
@ -154,7 +155,7 @@ fn main () {
].into_iter () ].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 <u32, i32> = HashMap::from_iter ( let unis: HashMap <u32, i32> = HashMap::from_iter (
uni_lookup.iter () uni_lookup.iter ()
@ -171,15 +172,28 @@ fn main () {
texture.bind (); texture.bind ();
let model_data = load_small_file ("pumpking.iqm", 1024 * 1024); 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 renderable_model = RenderableModel::from_iqm (&model);
let sky_data = load_small_file ("sky-sphere.iqm", 1024 * 1024); 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_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 ["pos"]);
glezz::enable_vertex_attrib_array (attrs ["uv"]); glezz::enable_vertex_attrib_array (attrs ["uv"]);
glezz::enable_vertex_attrib_array (attrs ["normal"]); glezz::enable_vertex_attrib_array (attrs ["normal"]);
@ -251,17 +265,27 @@ fn main () {
{ {
use uniforms::*; use uniforms::*;
glezz::uniform_3fv (unis [&MIN_BRIGHT], &black); glezz::uniform_3fv (unis [&MIN_BRIGHT], &black);
glezz::uniform_3fv (unis [&MIN_ALBEDO], &white); glezz::uniform_3fv (unis [&MIN_ALBEDO], &white);
glezz::uniform_3fv (unis [&ALBEDO], &orange);
glezz::uniform_matrix_4fv (unis [&MVP], &mvp_mat); glezz::uniform_matrix_4fv (unis [&MVP], &mvp_mat);
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
{
glezz::uniform_3fv (unis [&ALBEDO], &orange);
renderable_model.draw (&attrs, 0); renderable_model.draw (&attrs, 0);
glezz::uniform_3fv (unis [&ALBEDO], &green); glezz::uniform_3fv (unis [&ALBEDO], &green);
renderable_model.draw (&attrs, 1); 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; let draw_sky = true;
if draw_sky { if draw_sky {

View File

@ -78,7 +78,7 @@ pub struct Mesh {
#[derive (Debug)] #[derive (Debug)]
pub struct Header { pub struct Header {
fields: [u32; 27], pub fields: [u32; 27],
} }
#[derive (Debug)] #[derive (Debug)]
@ -94,7 +94,7 @@ pub struct VertexArray {
pub struct Model <'a> { pub struct Model <'a> {
data: &'a [u8], data: &'a [u8],
header: Header, pub header: Header,
text: Vec <u8>, text: Vec <u8>,
pub meshes: Vec <Mesh>, pub meshes: Vec <Mesh>,
vertexarrays: Vec <VertexArray>, vertexarrays: Vec <VertexArray>,
@ -274,4 +274,25 @@ impl <'a> Model <'a> {
&self.data [offset..offset + num_bytes] &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]
}
} }

View File

@ -37,6 +37,8 @@ unsafe fn vertex_attrib_pointer (id: Option <u32>, num_coords: i32, float_offset
} }
impl RenderableModel { impl RenderableModel {
//pub fn from_
pub fn from_iqm (model: &iqm::Model) -> RenderableModel { pub fn from_iqm (model: &iqm::Model) -> RenderableModel {
let pos_bytes = model.get_vertex_slice (iqm::types::POSITION); let pos_bytes = model.get_vertex_slice (iqm::types::POSITION);
let uv_bytes = model.get_vertex_slice (iqm::types::TEXCOORD); 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_uv = uv_bytes.len () / 4;
let num_normal = normal_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]; 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 (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); 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 ()
}
} }