♻️ 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_BRIGHT
, TEXTURE
, DITHER_PHASE
}
}
@ -182,7 +181,6 @@ fn main () {
(MIN_ALBEDO, "min_albedo"),
(MIN_BRIGHT, "min_bright"),
(TEXTURE, "texture"),
(DITHER_PHASE, "dither_phase"),
].into_iter ()
});
@ -225,6 +223,18 @@ fn main () {
let mesh_sky = renderable_from_iqm_file ("sky-sphere.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 silver = (255.0, 255.0, 255.0);
let wood = (133.0, 76.0, 48.0);
@ -297,7 +307,6 @@ fn main () {
}
window.gl_make_current (&gl_ctx).unwrap ();
let dither_phase = rand::thread_rng ().gen_range (0, 16);
let longitude = state.azimuth.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 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 (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_SKY], &object_space_sky);
{
glezz::uniform_3fv (unis [&ALBEDO], &orange);
mesh_pumpkin.draw (&attrs, 0);
glezz::uniform_3fv (unis [&ALBEDO], &green);
mesh_pumpkin.draw (&attrs, 1);
}
mesh_pumpkin.draw_all (&attrs, |i| {
glezz::uniform_3fv (unis [&ALBEDO], &pumpkin_colors [i]);
true
});
let mvp = view_mat * world_model_mat;
glezz::uniform_matrix_4fv (unis [&MVP], &mvp);
for (i, color) in pitch_colors.iter ().enumerate ().take (mesh_pitch.num_meshes ())
{
glezz::uniform_3fv (unis [&ALBEDO], color);
if i != grass_index {
mesh_pitch.draw (&attrs, i);
}
}
mesh_pitch.draw_all (&attrs, |i| {
glezz::uniform_3fv (unis [&ALBEDO], &pitch_colors [i]);
i != grass_index
});
let draw_sky = true;
if draw_sky {
@ -390,7 +385,7 @@ fn main () {
glezz::uniform_3fv (unis [&MIN_ALBEDO], &black);
glezz::uniform_1i (unis [&TEXTURE], 0);
mesh_sky.draw (&attrs, 0);
mesh_sky.draw_all (&attrs, |_| true);
}
glezz::enable (gl::STENCIL_TEST);
@ -409,19 +404,12 @@ fn main () {
let mvp = view_mat * pumpkin_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp);
{
mesh_pumpkin.draw (&shadow_attrs, 0);
mesh_pumpkin.draw (&shadow_attrs, 1);
}
mesh_pumpkin.draw_all (&shadow_attrs, |_| true);
let mvp = view_mat * world_model_mat;
glezz::uniform_matrix_4fv (shadow_unis [&MVP], &mvp);
for i in 0..mesh_pitch.num_meshes () {
if i != grass_index {
mesh_pitch.draw (&shadow_attrs, i);
}
}
mesh_pitch.draw_all (&shadow_attrs, |i| i != grass_index);
unsafe {
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 {
pub fn from_iqm (model: &iqm::Model) -> RenderableModel {
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.indexes.bind ();
@ -98,10 +102,31 @@ impl RenderableModel {
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);
}
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 {
self.meshes.len ()