Implement correct culling in the viewer

Using the DS's polygon attribute field.
This commit is contained in:
scurest 2018-03-10 11:04:32 -06:00
parent 962a16887e
commit c08f718d13
4 changed files with 39 additions and 23 deletions

View File

@ -64,6 +64,14 @@ fn model_info(db: &Database, model_id: usize) {
} }
} }
} }
println!(" Culling Mode: {}",
match (material.cull_backface, material.cull_frontface) {
(true, true) => "Cull All",
(true, false) => "Cull Backfacing",
(false, true) => "Cull Frontfacing",
(false, false) => "No Culling",
}
);
} }
println!(); println!();
} }

View File

@ -25,6 +25,8 @@ pub struct Material {
pub params: TextureParameters, pub params: TextureParameters,
pub width: u16, pub width: u16,
pub height: u16, pub height: u16,
pub cull_backface: bool,
pub cull_frontface: bool,
pub texture_mat: Matrix4<f64>, pub texture_mat: Matrix4<f64>,
} }
@ -176,6 +178,9 @@ fn read_material(cur: Cur, name: Name) -> Result<Material> {
let params = TextureParameters::from_u32(params); let params = TextureParameters::from_u32(params);
let cull_backface = polygon_attr.bits(6,7) == 0;
let cull_frontface = polygon_attr.bits(7,8) == 0;
// For now, use the section size to determine whether there // For now, use the section size to determine whether there
// is texture matrix data. // is texture matrix data.
let texture_mat = match section_size { let texture_mat = match section_size {
@ -196,6 +201,8 @@ fn read_material(cur: Cur, name: Name) -> Result<Material> {
params, params,
width, width,
height, height,
cull_backface,
cull_frontface,
texture_mat, texture_mat,
}) })
} }

View File

@ -1,9 +1,7 @@
use cgmath::Matrix4; use cgmath::Matrix4;
use errors::Result; use errors::Result;
use primitives::{Primitives, Vertex}; use primitives::{Primitives, Vertex};
use glium::{self, VertexBuffer, IndexBuffer, use glium::{self, VertexBuffer, IndexBuffer, Display, Frame, Surface};
Display, Frame, DrawParameters, Surface,
};
use glium::texture::Texture2d; use glium::texture::Texture2d;
use viewer::gl_context::GlContext; use viewer::gl_context::GlContext;
use viewer::state::ViewState; use viewer::state::ViewState;
@ -85,7 +83,6 @@ impl DrawingData {
db: &Database, db: &Database,
ctx: &GlContext, ctx: &GlContext,
target: &mut Frame, target: &mut Frame,
draw_params: &DrawParameters
) { ) {
if let Ok(ref gl_prims) = self.gl_prims { if let Ok(ref gl_prims) = self.gl_prims {
let model = &db.models[self.view_state.model_id]; let model = &db.models[self.view_state.model_id];
@ -93,6 +90,8 @@ impl DrawingData {
let mvp = self.view_state.eye.model_view_persp(); let mvp = self.view_state.eye.model_view_persp();
for call in &gl_prims.primitives.draw_calls { for call in &gl_prims.primitives.draw_calls {
let material = &model.materials[call.mat_id as usize];
let texture = let texture =
match self.textures[call.mat_id as usize] { match self.textures[call.mat_id as usize] {
Ok(Some(ref tex)) => tex, Ok(Some(ref tex)) => tex,
@ -116,7 +115,7 @@ impl DrawingData {
(true, true) => SamplerWrapFunction::Mirror, (true, true) => SamplerWrapFunction::Mirror,
} }
}; };
let params = &model.materials[call.mat_id as usize].params; let params = &material.params;
s.1.wrap_function.0 = wrap_fn(params.repeat_s, params.mirror_s); s.1.wrap_function.0 = wrap_fn(params.repeat_s, params.mirror_s);
s.1.wrap_function.1 = wrap_fn(params.repeat_t, params.mirror_t); s.1.wrap_function.1 = wrap_fn(params.repeat_t, params.mirror_t);
@ -136,12 +135,30 @@ impl DrawingData {
let indices = &gl_prims.index_buffer let indices = &gl_prims.index_buffer
.slice(call.index_range.clone()).unwrap(); .slice(call.index_range.clone()).unwrap();
let draw_params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::IfLess,
write: true,
.. Default::default()
},
backface_culling: {
use glium::draw_parameters::BackfaceCullingMode as Mode;
match (material.cull_backface, material.cull_frontface) {
(false, false) => Mode::CullingDisabled,
(true, false) => Mode::CullClockwise,
(false, true) => Mode::CullCounterClockwise,
(true, true) => continue,
}
},
.. Default::default()
};
target.draw( target.draw(
&gl_prims.vertex_buffer, &gl_prims.vertex_buffer,
indices, indices,
&ctx.program, &ctx.program,
&uniforms, &uniforms,
draw_params, &draw_params,
).unwrap(); ).unwrap();
} }
} }

View File

@ -286,23 +286,7 @@ impl Ui {
} else { } else {
let middle_grey = (0.4666, 0.4666, 0.4666, 1.0); let middle_grey = (0.4666, 0.4666, 0.4666, 1.0);
target.clear_color_srgb_and_depth(middle_grey, 1.0); target.clear_color_srgb_and_depth(middle_grey, 1.0);
self.drawing_data.draw(&self.db, &self.ctx, &mut target);
let draw_params = glium::DrawParameters {
depth: glium::Depth {
test: glium::draw_parameters::DepthTest::IfLess,
write: true,
.. Default::default()
},
backface_culling: glium::draw_parameters::BackfaceCullingMode::CullClockwise,
.. Default::default()
};
self.drawing_data.draw(
&self.db,
&self.ctx,
&mut target,
&draw_params,
);
} }
target.finish().unwrap(); target.finish().unwrap();