summaryrefslogtreecommitdiffstats
path: root/glow/src/triangle.rs
diff options
context:
space:
mode:
Diffstat (limited to 'glow/src/triangle.rs')
-rw-r--r--glow/src/triangle.rs126
1 files changed, 41 insertions, 85 deletions
diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs
index 85d873fe..f16f8af4 100644
--- a/glow/src/triangle.rs
+++ b/glow/src/triangle.rs
@@ -2,23 +2,22 @@
mod gradient;
mod solid;
-use crate::program::{self, Shader};
-use crate::Transformation;
+use crate::{program, Transformation};
use glow::HasContext;
-use iced_graphics::layer::{Mesh, Meshes};
+use iced_graphics::layer::{attribute_count_of, Mesh};
use iced_graphics::shader;
use std::marker::PhantomData;
use crate::triangle::gradient::GradientProgram;
use crate::triangle::solid::SolidProgram;
pub use iced_graphics::triangle::{Mesh2D, Vertex2D};
+use shader::Shader;
#[derive(Debug)]
pub(crate) struct Pipeline {
vertex_array: <glow::Context as HasContext>::VertexArray,
vertices: Buffer<Vertex2D>,
indices: Buffer<u32>,
- current_transform: Transformation,
programs: TrianglePrograms,
}
@@ -68,7 +67,6 @@ impl Pipeline {
vertex_array,
vertices,
indices,
- current_transform: Transformation::identity(),
programs: TrianglePrograms {
solid: SolidProgram::new(gl, shader_version),
gradient: GradientProgram::new(gl, shader_version),
@@ -78,7 +76,7 @@ impl Pipeline {
pub fn draw(
&mut self,
- meshes: &Meshes<'_>,
+ meshes: &[Mesh<'_>],
gl: &glow::Context,
target_height: u32,
transformation: Transformation,
@@ -90,8 +88,8 @@ impl Pipeline {
gl.bind_vertex_array(Some(self.vertex_array))
}
- //count the total number of vertices & indices we need to handle for all meshes
- let (total_vertices, total_indices) = meshes.attribute_count();
+ //count the total amount of vertices & indices we need to handle
+ let (total_vertices, total_indices) = attribute_count_of(meshes);
// Then we ensure the current attribute buffers are big enough, resizing if necessary
unsafe {
@@ -100,25 +98,25 @@ impl Pipeline {
}
// We upload all the vertices and indices upfront
- let mut last_vertex = 0;
- let mut last_index = 0;
+ let mut vertex_offset = 0;
+ let mut index_offset = 0;
- for Mesh { buffers, .. } in meshes.0.iter() {
+ for mesh in meshes {
unsafe {
gl.buffer_sub_data_u8_slice(
glow::ARRAY_BUFFER,
- (last_vertex * std::mem::size_of::<Vertex2D>()) as i32,
- bytemuck::cast_slice(&buffers.vertices),
+ (vertex_offset * std::mem::size_of::<Vertex2D>()) as i32,
+ bytemuck::cast_slice(&mesh.buffers.vertices),
);
gl.buffer_sub_data_u8_slice(
glow::ELEMENT_ARRAY_BUFFER,
- (last_index * std::mem::size_of::<u32>()) as i32,
- bytemuck::cast_slice(&buffers.indices),
+ (index_offset * std::mem::size_of::<u32>()) as i32,
+ bytemuck::cast_slice(&mesh.buffers.indices),
);
- last_vertex += buffers.vertices.len();
- last_index += buffers.indices.len();
+ vertex_offset += mesh.buffers.vertices.len();
+ index_offset += mesh.buffers.indices.len();
}
}
@@ -126,22 +124,11 @@ impl Pipeline {
let mut last_vertex = 0;
let mut last_index = 0;
- for (index, Mesh {
- buffers,
- origin,
- clip_bounds,
- shader,
- }) in meshes.0.iter().enumerate()
- {
- let transform =
- transformation * Transformation::translate(origin.x, origin.y);
-
- if index == 0 {
- //set initial transform uniform for both programs
- self.programs.set_transforms(gl, transform);
- }
+ for mesh in meshes {
+ let transform = transformation
+ * Transformation::translate(mesh.origin.x, mesh.origin.y);
- let clip_bounds = (*clip_bounds * scale_factor).snap();
+ let clip_bounds = (mesh.clip_bounds * scale_factor).snap();
unsafe {
gl.scissor(
@@ -152,25 +139,25 @@ impl Pipeline {
clip_bounds.height as i32,
);
- let t = if self.current_transform != transform {
- self.current_transform = transform;
- Some(transform)
- } else {
- None
- };
-
- self.use_with_shader(gl, shader, t);
+ match mesh.shader {
+ Shader::Solid(color) => {
+ self.programs.solid.use_program(gl, &color, &transform);
+ }
+ Shader::Gradient(gradient) => {
+ self.programs.gradient.use_program(gl, &gradient, &transform);
+ }
+ }
gl.draw_elements_base_vertex(
glow::TRIANGLES,
- buffers.indices.len() as i32,
+ mesh.buffers.indices.len() as i32,
glow::UNSIGNED_INT,
(last_index * std::mem::size_of::<u32>()) as i32,
last_vertex as i32,
);
- last_vertex += buffers.vertices.len();
- last_index += buffers.indices.len();
+ last_vertex += mesh.buffers.vertices.len();
+ last_index += mesh.buffers.indices.len();
}
}
@@ -180,31 +167,6 @@ impl Pipeline {
gl.disable(glow::MULTISAMPLE);
}
}
-
- fn use_with_shader(
- &mut self,
- gl: &glow::Context,
- shader: &shader::Shader,
- transform: Option<Transformation>,
- ) {
- match shader {
- shader::Shader::Solid(color) => {
- unsafe { gl.use_program(Some(self.programs.solid.program)) }
- self.programs.solid.set_uniforms(gl, color, transform);
- }
- shader::Shader::Gradient(gradient) => {
- unsafe { gl.use_program(Some(self.programs.gradient.program)) }
- self.programs.gradient.set_uniforms(gl, gradient, transform);
- }
- }
- }
-}
-
-impl TrianglePrograms {
- pub fn set_transforms(&self, gl: &glow::Context, transform: Transformation) {
- update_transform(gl, self.solid.program, Some(transform));
- update_transform(gl, self.gradient.program, Some(transform));
- }
}
/// A simple shader program. Uses [`triangle.vert`] for its vertex shader and only binds position
@@ -215,14 +177,14 @@ pub(super) fn simple_triangle_program(
fragment_shader: &'static str,
) -> <glow::Context as HasContext>::Program {
unsafe {
- let vertex_shader = Shader::vertex(
+ let vertex_shader = program::Shader::vertex(
gl,
shader_version,
include_str!("shader/common/triangle.vert"),
);
let fragment_shader =
- Shader::fragment(gl, shader_version, fragment_shader);
+ program::Shader::fragment(gl, shader_version, fragment_shader);
program::create(
gl,
@@ -232,23 +194,17 @@ pub(super) fn simple_triangle_program(
}
}
-pub(super) fn update_transform(
+pub fn set_transform(
gl: &glow::Context,
- program: <glow::Context as HasContext>::Program,
- transform: Option<Transformation>
+ location: <glow::Context as HasContext>::UniformLocation,
+ transform: Transformation,
) {
- if let Some(t) = transform {
- let transform_location =
- unsafe { gl.get_uniform_location(program, "u_Transform") }
- .expect("Get transform location.");
-
- unsafe {
- gl.uniform_matrix_4_f32_slice(
- Some(&transform_location),
- false,
- t.as_ref(),
- );
- }
+ unsafe {
+ gl.uniform_matrix_4_f32_slice(
+ Some(&location),
+ false,
+ transform.as_ref()
+ );
}
}