Rendering mesh
parent
5687dff5db
commit
9e03a9cbec
151
src/main.rs
151
src/main.rs
|
@ -45,6 +45,29 @@ mod iqm_consts {
|
||||||
pub const OFS_EXTENSIONS: usize = 26;
|
pub const OFS_EXTENSIONS: usize = 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod iqm_types {
|
||||||
|
pub const POSITION: u32 = 0;
|
||||||
|
pub const TEXCOORD: u32 = 1;
|
||||||
|
pub const NORMAL: u32 = 2;
|
||||||
|
pub const TANGENT: u32 = 3;
|
||||||
|
pub const BLENDINDEXES: u32 = 4;
|
||||||
|
pub const BLENDWEIGHTS: u32 = 5;
|
||||||
|
pub const COLOR: u32 = 6;
|
||||||
|
pub const CUSTOM: u32 = 0x10;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod iqm_formats {
|
||||||
|
pub const BYTE: u32 = 0;
|
||||||
|
pub const UBYTE: u32 = 1;
|
||||||
|
pub const SHORT: u32 = 2;
|
||||||
|
pub const USHORT: u32 = 3;
|
||||||
|
pub const INT: u32 = 4;
|
||||||
|
pub const UINT: u32 = 5;
|
||||||
|
pub const HALF: u32 = 6;
|
||||||
|
pub const FLOAT: u32 = 7;
|
||||||
|
pub const DOUBLE: u32 = 8;
|
||||||
|
}
|
||||||
|
|
||||||
#[derive (Debug)]
|
#[derive (Debug)]
|
||||||
pub struct IqmMesh {
|
pub struct IqmMesh {
|
||||||
name: u32,
|
name: u32,
|
||||||
|
@ -61,10 +84,22 @@ pub struct IqmHeader {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive (Debug)]
|
#[derive (Debug)]
|
||||||
pub struct IqmModel {
|
pub struct IqmVertexArray {
|
||||||
|
va_type: u32,
|
||||||
|
va_flags: u32,
|
||||||
|
va_format: u32,
|
||||||
|
va_size: u32,
|
||||||
|
va_offset: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive (Debug)]
|
||||||
|
pub struct IqmModel <'a> {
|
||||||
|
data: &'a [u8],
|
||||||
|
|
||||||
header: IqmHeader,
|
header: IqmHeader,
|
||||||
text: Vec <u8>,
|
text: Vec <u8>,
|
||||||
meshes: Vec <IqmMesh>,
|
meshes: Vec <IqmMesh>,
|
||||||
|
vertexarrays: Vec <IqmVertexArray>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IqmHeader {
|
impl IqmHeader {
|
||||||
|
@ -120,38 +155,111 @@ impl IqmMesh {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IqmModel {
|
impl IqmVertexArray {
|
||||||
pub fn from_slice (input: &[u8]) -> IqmModel {
|
pub fn from_slice (input: &[u8]) -> IResult <&[u8], IqmVertexArray> {
|
||||||
let header = IqmHeader::from_slice (input).unwrap ().1;
|
let mut result = IqmVertexArray {
|
||||||
|
va_type: 0,
|
||||||
|
va_flags: 0,
|
||||||
|
va_format: 0,
|
||||||
|
va_size: 0,
|
||||||
|
va_offset: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut input = input;
|
||||||
|
for field in [
|
||||||
|
&mut result.va_type,
|
||||||
|
&mut result.va_flags,
|
||||||
|
&mut result.va_format,
|
||||||
|
&mut result.va_size,
|
||||||
|
&mut result.va_offset,
|
||||||
|
].iter_mut () {
|
||||||
|
let (i, f) = le_u32 (input)?;
|
||||||
|
input = i;
|
||||||
|
**field = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok ((input, result))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl <'a> IqmModel <'a> {
|
||||||
|
pub fn from_slice (data: &'a [u8]) -> IqmModel <'a> {
|
||||||
|
let header = IqmHeader::from_slice (data).unwrap ().1;
|
||||||
|
|
||||||
let text = {
|
let text = {
|
||||||
let offset: usize = header.fields [iqm_consts::OFS_TEXT].try_into ().unwrap ();
|
let offset: usize = header.fields [iqm_consts::OFS_TEXT].try_into ().unwrap ();
|
||||||
let num: usize = header.fields [iqm_consts::NUM_TEXT].try_into ().unwrap ();
|
let num: usize = header.fields [iqm_consts::NUM_TEXT].try_into ().unwrap ();
|
||||||
Vec::from (&input [offset..offset + num])
|
Vec::from (&data [offset..offset + num])
|
||||||
};
|
};
|
||||||
|
|
||||||
let meshes = {
|
let meshes = {
|
||||||
let mut meshes = vec! [];
|
let num: usize = header.fields [iqm_consts::NUM_MESHES].try_into ().unwrap ();
|
||||||
|
let mut meshes = Vec::with_capacity (num);
|
||||||
let mesh_size = 6 * 4;
|
let mesh_size = 6 * 4;
|
||||||
let meshes_offset: usize = header.fields [iqm_consts::OFS_MESHES].try_into ().unwrap ();
|
let meshes_offset: usize = header.fields [iqm_consts::OFS_MESHES].try_into ().unwrap ();
|
||||||
|
|
||||||
for i in 0..header.fields [iqm_consts::NUM_MESHES] {
|
for i in 0..num {
|
||||||
let i: usize = i.try_into ().unwrap ();
|
|
||||||
|
|
||||||
let offset = meshes_offset + i * mesh_size;
|
let offset = meshes_offset + i * mesh_size;
|
||||||
let mesh_slice = &input [offset..offset + mesh_size];
|
let mesh_slice = &data [offset..offset + mesh_size];
|
||||||
|
|
||||||
meshes.push (IqmMesh::from_slice (mesh_slice).unwrap ().1);
|
meshes.push (IqmMesh::from_slice (mesh_slice).unwrap ().1);
|
||||||
}
|
}
|
||||||
meshes
|
meshes
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let vertexarrays = {
|
||||||
|
let num: usize = header.fields [iqm_consts::NUM_VERTEXARRAYS].try_into ().unwrap ();
|
||||||
|
let mut vertexarrays = Vec::with_capacity (num);
|
||||||
|
let vertexarray_size = 5 * 4;
|
||||||
|
let vertexarrays_offset: usize = header.fields [iqm_consts::OFS_VERTEXARRAYS].try_into ().unwrap ();
|
||||||
|
|
||||||
|
for i in 0..num {
|
||||||
|
let offset = vertexarrays_offset + i * vertexarray_size;
|
||||||
|
let vertexarray_slice = &data [offset..offset + vertexarray_size];
|
||||||
|
|
||||||
|
vertexarrays.push (IqmVertexArray::from_slice (vertexarray_slice).unwrap ().1);
|
||||||
|
}
|
||||||
|
|
||||||
|
vertexarrays
|
||||||
|
};
|
||||||
|
|
||||||
IqmModel {
|
IqmModel {
|
||||||
|
data,
|
||||||
|
|
||||||
header,
|
header,
|
||||||
text,
|
text,
|
||||||
meshes,
|
meshes,
|
||||||
|
vertexarrays,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_vertex_slice (&self,
|
||||||
|
mesh_index: usize, vertexarray_index: usize
|
||||||
|
) -> &[u8]
|
||||||
|
{
|
||||||
|
let vertexarray = &self.vertexarrays [vertexarray_index];
|
||||||
|
let bytes_per_float = 4;
|
||||||
|
let stride = bytes_per_float * vertexarray.va_size;
|
||||||
|
|
||||||
|
let mesh = &self.meshes [mesh_index];
|
||||||
|
let offset: usize = (vertexarray.va_offset + stride * mesh.first_vertex).try_into ().unwrap ();
|
||||||
|
let num_bytes: usize = (stride * mesh.num_vertexes).try_into ().unwrap ();
|
||||||
|
|
||||||
|
&self.data [offset..offset + num_bytes]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_index_slice (&self, mesh_index: usize) -> &[u8] {
|
||||||
|
let mesh = &self.meshes [mesh_index];
|
||||||
|
let bytes_per_u32 = 4;
|
||||||
|
let indexes_per_tri = 3;
|
||||||
|
let stride = bytes_per_u32 * indexes_per_tri;
|
||||||
|
|
||||||
|
let offset: usize = (self.header.fields [iqm_consts::OFS_TRIANGLES] + stride * mesh.first_triangle).try_into ().unwrap ();
|
||||||
|
|
||||||
|
let num_bytes: usize = (stride * mesh.num_triangles).try_into ().unwrap ();
|
||||||
|
|
||||||
|
&self.data [offset..offset + num_bytes]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_small_file <P> (name: P) -> Vec <u8>
|
pub fn load_small_file <P> (name: P) -> Vec <u8>
|
||||||
|
@ -424,23 +532,36 @@ fn main () {
|
||||||
1.0, 1.0,
|
1.0, 1.0,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
let model_data = load_small_file ("pumpking.iqm");
|
||||||
|
let model = IqmModel::from_slice (&model_data [..]);
|
||||||
|
let vertex_slice = model.get_vertex_slice (0, 0);
|
||||||
|
let index_slice = model.get_index_slice (0);
|
||||||
|
|
||||||
let id_mat: Vec <f32> = vec! [
|
let id_mat: Vec <f32> = vec! [
|
||||||
1.0, 0.0, 0.0, 0.0,
|
1.0, 0.0, 0.0, 0.0,
|
||||||
0.0, 1.0, 0.0, 0.0,
|
0.0, 1.0, 0.0, 0.0,
|
||||||
0.0, 0.0, 1.0, 0.0,
|
0.0, 0.0, 1.0, 0.0,
|
||||||
0.0, 0.0, 0.0, 1.0,
|
0.0, 0.0, 0.0, 1.0,
|
||||||
];
|
];
|
||||||
|
let view_mat: Vec <f32> = vec! [
|
||||||
|
0.3125, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.5, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 0.0,
|
||||||
|
0.0, 0.0, 0.0, 1.0,
|
||||||
|
];
|
||||||
let indexes: Vec <u16> = vec! [0, 1, 2];
|
let indexes: Vec <u16> = vec! [0, 1, 2];
|
||||||
|
|
||||||
const FALSE_U8: u8 = 0;
|
const FALSE_U8: u8 = 0;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::EnableVertexAttribArray (attrs ["pos"]);
|
gl::EnableVertexAttribArray (attrs ["pos"]);
|
||||||
let stride = 4 * 2;
|
|
||||||
|
|
||||||
gl::VertexAttribPointer (attrs ["pos"], 2, gl::FLOAT, FALSE_U8, stride, &tri_mesh [0] as *const f32 as *const c_void);
|
let num_coords = 3;
|
||||||
|
let stride = 4 * num_coords;
|
||||||
|
|
||||||
gl::UniformMatrix4fv (unis ["viewproj"], 1, FALSE_U8, &id_mat [0]);
|
gl::VertexAttribPointer (attrs ["pos"], num_coords, gl::FLOAT, FALSE_U8, stride, &vertex_slice [0] as *const u8 as *const c_void);
|
||||||
|
|
||||||
|
gl::UniformMatrix4fv (unis ["viewproj"], 1, FALSE_U8, &view_mat [0]);
|
||||||
gl::UniformMatrix4fv (unis ["model"], 1, FALSE_U8, &id_mat [0]);
|
gl::UniformMatrix4fv (unis ["model"], 1, FALSE_U8, &id_mat [0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -463,8 +584,9 @@ fn main () {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl::ClearColor (1.0f32, 0.0f32, 1.0f32, 1.0f32);
|
gl::ClearColor (1.0f32, 0.0f32, 1.0f32, 1.0f32);
|
||||||
gl::Clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
|
gl::Clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT);
|
||||||
|
gl::Disable (gl::CULL_FACE);
|
||||||
|
|
||||||
gl::DrawElements (gl::TRIANGLES, 3, gl::UNSIGNED_SHORT, &indexes [0] as *const u16 as *const c_void);
|
gl::DrawElements (gl::TRIANGLES, (model.meshes [0].num_triangles * 3) as i32, gl::UNSIGNED_INT, &index_slice [0] as *const u8 as *const c_void);
|
||||||
}
|
}
|
||||||
|
|
||||||
window.gl_swap_window ();
|
window.gl_swap_window ();
|
||||||
|
@ -493,6 +615,7 @@ mod tests {
|
||||||
let model = IqmModel::from_slice (&data [..]);
|
let model = IqmModel::from_slice (&data [..]);
|
||||||
|
|
||||||
println! ("{:?}", model.meshes);
|
println! ("{:?}", model.meshes);
|
||||||
|
println! ("{:?}", model.vertexarrays);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue