diff --git a/src/core/program.rs b/src/core/program.rs index 3ca6a5d6..4f6072de 100644 --- a/src/core/program.rs +++ b/src/core/program.rs @@ -430,23 +430,10 @@ impl Program { /// If you want to use an [ElementBuffer], see [Program::draw_elements]. /// pub fn draw_arrays(&self, render_states: RenderStates, viewport: Viewport, count: u32) { - self.context.set_viewport(viewport); - self.context.set_render_states(render_states); - self.use_program(); - unsafe { + self.draw_with(render_states, viewport, move || unsafe { self.context .draw_arrays(crate::context::TRIANGLES, 0, count as i32); - for location in self.attributes.values() { - self.context.disable_vertex_attrib_array(*location); - } - self.context.bind_vertex_array(None); - } - self.unuse_program(); - - #[cfg(debug_assertions)] - self.context - .error_check() - .expect("Unexpected rendering error occured") + }) } /// @@ -460,10 +447,7 @@ impl Program { count: u32, instance_count: u32, ) { - self.context.set_viewport(viewport); - self.context.set_render_states(render_states); - self.use_program(); - unsafe { + self.draw_with(render_states, viewport, move || unsafe { self.context.draw_arrays_instanced( crate::context::TRIANGLES, 0, @@ -472,17 +456,7 @@ impl Program { ); self.context .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None); - for location in self.attributes.values() { - self.context.disable_vertex_attrib_array(*location); - } - self.context.bind_vertex_array(None); - } - self.unuse_program(); - - #[cfg(debug_assertions)] - self.context - .error_check() - .expect("Unexpected rendering error occured") + }) } /// @@ -518,31 +492,14 @@ impl Program { first: u32, count: u32, ) { - self.context.set_viewport(viewport); - self.context.set_render_states(render_states); - self.use_program(); - element_buffer.bind(); - unsafe { + self.draw_elements_with(render_states, viewport, element_buffer, move || unsafe { self.context.draw_elements( crate::context::TRIANGLES, count as i32, T::data_type(), first as i32, ); - self.context - .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None); - - for location in self.attributes.values() { - self.context.disable_vertex_attrib_array(*location); - } - self.context.bind_vertex_array(None); - } - self.unuse_program(); - - #[cfg(debug_assertions)] - self.context - .error_check() - .expect("Unexpected rendering error occured") + }) } /// @@ -579,11 +536,7 @@ impl Program { count: u32, instance_count: u32, ) { - self.context.set_viewport(viewport); - self.context.set_render_states(render_states); - self.use_program(); - element_buffer.bind(); - unsafe { + self.draw_elements_with(render_states, viewport, element_buffer, move || unsafe { self.context.draw_elements_instanced( crate::context::TRIANGLES, count as i32, @@ -591,13 +544,27 @@ impl Program { first as i32, instance_count as i32, ); - self.context - .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None); + }) + } + + /// + /// Calls drawing callback `draw` after setting up rendering to use this shader program, cleaning up before return. + /// Requires that all attributes and uniforms have been defined using the [use_attribute] and [use_uniform] methods. + /// + pub fn draw_with(&self, render_states: RenderStates, viewport: Viewport, draw: impl FnOnce()) { + self.context.set_viewport(viewport); + self.context.set_render_states(render_states); + self.use_program(); + + draw(); + + unsafe { for location in self.attributes.values() { self.context.disable_vertex_attrib_array(*location); } self.context.bind_vertex_array(None); } + self.unuse_program(); #[cfg(debug_assertions)] @@ -606,6 +573,27 @@ impl Program { .expect("Unexpected rendering error occured") } + /// + /// Calls drawing callback `draw` after setting up rendering to use this shader program and element buffer `elements`, cleaning up before return. + /// Requires that all attributes and uniforms have been defined using the [use_attribute] and [use_uniform] methods. + /// + pub fn draw_elements_with( + &self, + render_states: RenderStates, + viewport: Viewport, + element_buffer: &ElementBuffer, + draw: impl FnOnce(), + ) { + self.draw_with(render_states, viewport, move || { + element_buffer.bind(); + draw(); + unsafe { + self.context + .bind_buffer(crate::context::ELEMENT_ARRAY_BUFFER, None); + } + }) + } + /// /// Returns true if this program uses the uniform with the given name. /// diff --git a/src/core/render_states.rs b/src/core/render_states.rs index faa3404a..f546d56d 100644 --- a/src/core/render_states.rs +++ b/src/core/render_states.rs @@ -36,9 +36,10 @@ pub struct RenderStates { /// /// Defines whether the triangles that are backfacing, frontfacing, both or none should be rendered in a render call. /// -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Default)] pub enum Cull { /// Render both front- and backfacing triangles. + #[default] None, /// Render only frontfacing triangles. Back, @@ -48,12 +49,6 @@ pub enum Cull { FrontAndBack, } -impl Default for Cull { - fn default() -> Self { - Self::None - } -} - /// /// Determines whether or not a fragment/pixel from the current render call should be discarded /// when comparing its depth with the depth of the current fragment/pixel. @@ -61,9 +56,10 @@ impl Default for Cull { /// **Note:** Depth test is disabled if the render call is not writing to a depth texture. /// #[allow(missing_docs)] -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Default)] pub enum DepthTest { Never, + #[default] Less, Equal, LessOrEqual, @@ -73,12 +69,6 @@ pub enum DepthTest { Always, } -impl Default for DepthTest { - fn default() -> Self { - Self::Less - } -} - /// /// Defines which channels (red, green, blue, alpha and depth) to write to in a render call. /// @@ -151,7 +141,7 @@ impl Default for WriteMask { /// This is usually used to simulate transparency. /// #[allow(missing_docs)] -#[derive(Debug, Copy, Clone, PartialEq)] +#[derive(Debug, Copy, Clone, PartialEq, Default)] pub enum Blend { Enabled { source_rgb_multiplier: BlendMultiplierType, @@ -161,6 +151,7 @@ pub enum Blend { rgb_equation: BlendEquationType, alpha_equation: BlendEquationType, }, + #[default] Disabled, } @@ -203,12 +194,6 @@ impl Blend { }; } -impl Default for Blend { - fn default() -> Self { - Self::Disabled - } -} - /// /// Value multiplied with the source or target color or alpha value in [Blend]. ///