♻️ Allow models to render all their meshes in a batch

main
_ 2020-03-08 01:59:44 +00:00
parent 04328b3564
commit e980599347
2 changed files with 53 additions and 40 deletions

View File

@ -109,7 +109,6 @@ iota! {
, MIN_ALBEDO , MIN_ALBEDO
, MIN_BRIGHT , MIN_BRIGHT
, TEXTURE , TEXTURE
, DITHER_PHASE
} }
} }
@ -182,7 +181,6 @@ fn main () {
(MIN_ALBEDO, "min_albedo"), (MIN_ALBEDO, "min_albedo"),
(MIN_BRIGHT, "min_bright"), (MIN_BRIGHT, "min_bright"),
(TEXTURE, "texture"), (TEXTURE, "texture"),
(DITHER_PHASE, "dither_phase"),
].into_iter () ].into_iter ()
}); });
@ -225,6 +223,18 @@ fn main () {
let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm"); let mesh_sky = renderable_from_iqm_file ("sky-sphere.iqm");
let mesh_pitch = renderable_from_iqm_file ("pitch.iqm"); let mesh_pitch = renderable_from_iqm_file ("pitch.iqm");
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 (pitch_colors, grass_index) = { let (pitch_colors, grass_index) = {
let silver = (255.0, 255.0, 255.0); let silver = (255.0, 255.0, 255.0);
let wood = (133.0, 76.0, 48.0); let wood = (133.0, 76.0, 48.0);
@ -297,7 +307,6 @@ fn main () {
} }
window.gl_make_current (&gl_ctx).unwrap (); window.gl_make_current (&gl_ctx).unwrap ();
let dither_phase = rand::thread_rng ().gen_range (0, 16);
let longitude = state.azimuth.to_radians (); let longitude = state.azimuth.to_radians ();
let latitude = (state.altitude - 90.0).to_radians (); let latitude = (state.altitude - 90.0).to_radians ();
@ -320,14 +329,6 @@ fn main () {
let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ()); let sky_mvp_mat = view_mat * Mat4::from_scale ((16.0, 16.0, 16.0).into ());
let light = Vec3::from ((2.0, 0.0, 5.0)).normalize (); let light = Vec3::from ((2.0, 0.0, 5.0)).normalize ();
//let light = Vec3::from ((0.0, 0.0, 0.0)).normalize ();
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));
glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32); glezz::clear_color (1.0f32, 0.0f32, 1.0f32, 1.0f32);
glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT); glezz::clear (gl::COLOR_BUFFER_BIT | gl::DEPTH_BUFFER_BIT | gl::STENCIL_BUFFER_BIT);
@ -362,24 +363,18 @@ fn main () {
glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light); glezz::uniform_3fv (unis [&OBJECT_SPACE_LIGHT], &object_space_light);
glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky); glezz::uniform_3fv (unis [&OBJECT_SPACE_SKY], &object_space_sky);
{ mesh_pumpkin.draw_all (&attrs, |i| {
glezz::uniform_3fv (unis [&ALBEDO], &orange); glezz::uniform_3fv (unis [&ALBEDO], &pumpkin_colors [i]);
mesh_pumpkin.draw (&attrs, 0); true
});
glezz::uniform_3fv (unis [&ALBEDO], &green);
mesh_pumpkin.draw (&attrs, 1);
}
let mvp = view_mat * world_model_mat; let mvp = view_mat * world_model_mat;
glezz::uniform_matrix_4fv (unis [&MVP], &mvp); glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
for (i, color) in pitch_colors.iter ().enumerate ().take (mesh_pitch.num_meshes ()) mesh_pitch.draw_all (&attrs, |i| {
{ glezz::uniform_3fv (unis [&ALBEDO], &pitch_colors [i]);
glezz::uniform_3fv (unis [&ALBEDO], color); i != grass_index
if i != grass_index { });
mesh_pitch.draw (&attrs, i);
}
}
let draw_sky = true; let draw_sky = true;
if draw_sky { if draw_sky {
@ -390,7 +385,7 @@ fn main () {
glezz::uniform_3fv (unis [&MIN_ALBEDO], &black); glezz::uniform_3fv (unis [&MIN_ALBEDO], &black);
glezz::uniform_1i (unis [&TEXTURE], 0); glezz::uniform_1i (unis [&TEXTURE], 0);
mesh_sky.draw (&attrs, 0); mesh_sky.draw_all (&attrs, |_| true);
} }
glezz::enable (gl::STENCIL_TEST); glezz::enable (gl::STENCIL_TEST);
@ -409,19 +404,12 @@ fn main () {
let mvp = view_mat * pumpkin_model_mat; let mvp = view_mat * pumpkin_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp); glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp);
{ mesh_pumpkin.draw_all (&shadow_attrs, |_| true);
mesh_pumpkin.draw (&shadow_attrs, 0);
mesh_pumpkin.draw (&shadow_attrs, 1);
}
let mvp = view_mat * world_model_mat; let mvp = view_mat * world_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp); glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp);
for i in 0..mesh_pitch.num_meshes () { mesh_pitch.draw_all (&shadow_attrs, |i| i != grass_index);
if i != grass_index {
mesh_pitch.draw (&shadow_attrs, i);
}
}
unsafe { unsafe {
gl::ColorMask (255, 255, 255, 255); gl::ColorMask (255, 255, 255, 255);

View File

@ -37,6 +37,8 @@ unsafe fn vertex_attrib_pointer (id: Option <u32>, num_coords: i32, float_offset
} }
} }
pub type AttrMap = HashMap <String, Option <u32>>;
impl RenderableModel { impl RenderableModel {
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);
@ -87,10 +89,12 @@ impl RenderableModel {
} }
} }
pub fn draw (&self, attrs: &HashMap <String, Option <u32>>, mesh_num: usize) pub fn draw_ranged <F> (&self,
attrs: &AttrMap, callback: F,
start: usize, end: usize
)
where F: Fn (usize) -> bool
{ {
let mesh = &self.meshes [mesh_num];
self.vertexes.bind (); self.vertexes.bind ();
self.indexes.bind (); self.indexes.bind ();
@ -98,9 +102,30 @@ impl RenderableModel {
vertex_attrib_pointer (attrs ["pos"], 3, 0); vertex_attrib_pointer (attrs ["pos"], 3, 0);
vertex_attrib_pointer (attrs ["uv"], 2, self.num_pos); vertex_attrib_pointer (attrs ["uv"], 2, self.num_pos);
vertex_attrib_pointer (attrs ["normal"], 3, self.num_pos + self.num_uv); vertex_attrib_pointer (attrs ["normal"], 3, self.num_pos + self.num_uv);
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);
} }
for mesh_num in start..end {
if ! callback (mesh_num) {
continue;
}
let mesh = &self.meshes [mesh_num];
unsafe {
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 draw_all <F> (&self, attrs: &AttrMap, callback: F)
where F: Fn (usize) -> bool
{
self.draw_ranged (attrs, callback, 0, self.meshes.len ());
}
pub fn draw (&self, attrs: &AttrMap, mesh_num: usize)
{
self.draw_ranged (attrs, |_| true, mesh_num, mesh_num + 1);
} }
pub fn num_meshes (&self) -> usize { pub fn num_meshes (&self) -> usize {