summaryrefslogtreecommitdiffstats
path: root/glow/src
diff options
context:
space:
mode:
Diffstat (limited to 'glow/src')
-rw-r--r--glow/src/backend.rs2
-rw-r--r--glow/src/shader/common/gradient.frag1
-rw-r--r--glow/src/triangle.rs126
-rw-r--r--glow/src/triangle/gradient.rs92
-rw-r--r--glow/src/triangle/solid.rs62
5 files changed, 134 insertions, 149 deletions
diff --git a/glow/src/backend.rs b/glow/src/backend.rs
index 6fc4fb38..7333d513 100644
--- a/glow/src/backend.rs
+++ b/glow/src/backend.rs
@@ -99,7 +99,7 @@ impl Backend {
);
}
- if !layer.meshes.0.is_empty() {
+ if !layer.meshes.is_empty() {
let scaled = transformation
* Transformation::scale(scale_factor, scale_factor);
diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag
index 588f63e0..1afb557d 100644
--- a/glow/src/shader/common/gradient.frag
+++ b/glow/src/shader/common/gradient.frag
@@ -23,6 +23,7 @@ uniform uint color_stops_size;
uniform float color_stop_offsets[MAX_STOPS];
uniform vec4 color_stop_colors[MAX_STOPS];
+//TODO: rewrite without branching to make ALUs happy
void main() {
vec2 gradient_vec = vec2(gradient_end - gradient_start);
vec2 current_vec = vec2(raw_position.xy - gradient_start);
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()
+ );
}
}
diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs
index d1b10d77..547871e2 100644
--- a/glow/src/triangle/gradient.rs
+++ b/glow/src/triangle/gradient.rs
@@ -1,18 +1,42 @@
use crate::program::Version;
-use crate::triangle::{simple_triangle_program, update_transform};
+use crate::triangle::{simple_triangle_program, set_transform};
use glow::{Context, HasContext, NativeProgram};
+use iced_graphics::gradient::Linear;
use iced_graphics::gradient::Gradient;
-use iced_graphics::widget::canvas::gradient::Linear;
use iced_graphics::Transformation;
#[derive(Debug)]
-pub(super) struct GradientProgram {
- pub(super) program: <Context as HasContext>::Program,
- pub(super) uniform_data: GradientUniformData,
+pub struct GradientProgram {
+ pub program: <Context as HasContext>::Program,
+ pub uniform_data: GradientUniformData,
+}
+
+#[derive(Debug)]
+pub struct GradientUniformData {
+ gradient: Gradient,
+ transform: Transformation,
+ uniform_locations: GradientUniformLocations,
+}
+
+#[derive(Debug)]
+struct GradientUniformLocations {
+ gradient_start_location: <Context as HasContext>::UniformLocation,
+ gradient_end_location: <Context as HasContext>::UniformLocation,
+ color_stops_size_location: <Context as HasContext>::UniformLocation,
+ //currently the maximum number of stops is 64 due to needing to allocate the
+ //memory for the array of stops with a const value in GLSL
+ color_stops_locations: [ColorStopLocation; 64],
+ transform_location: <Context as HasContext>::UniformLocation,
+}
+
+#[derive(Copy, Debug, Clone)]
+struct ColorStopLocation {
+ color: <Context as HasContext>::UniformLocation,
+ offset: <Context as HasContext>::UniformLocation,
}
impl GradientProgram {
- pub(super) fn new(gl: &Context, shader_version: &Version) -> Self {
+ pub fn new(gl: &Context, shader_version: &Version) -> Self {
let program = simple_triangle_program(
gl,
shader_version,
@@ -25,15 +49,17 @@ impl GradientProgram {
}
}
- pub(super) fn set_uniforms<'a>(
+ pub fn write_uniforms(
&mut self,
gl: &Context,
gradient: &Gradient,
- transform: Option<Transformation>,
+ transform: &Transformation,
) {
- update_transform(gl, self.program, transform);
+ if transform != &self.uniform_data.transform {
+ set_transform(gl, self.uniform_data.uniform_locations.transform_location, *transform);
+ }
- if &self.uniform_data.current_gradient != gradient {
+ if &self.uniform_data.gradient != gradient {
match gradient {
Gradient::Linear(linear) => {
let gradient_start: [f32; 2] = (linear.start).into();
@@ -104,31 +130,17 @@ impl GradientProgram {
}
}
- self.uniform_data.current_gradient = gradient.clone();
+ self.uniform_data.gradient = gradient.clone();
}
}
-}
-
-#[derive(Debug)]
-pub(super) struct GradientUniformData {
- current_gradient: Gradient,
- uniform_locations: GradientUniformLocations,
-}
-#[derive(Debug)]
-struct GradientUniformLocations {
- gradient_start_location: <Context as HasContext>::UniformLocation,
- gradient_end_location: <Context as HasContext>::UniformLocation,
- color_stops_size_location: <Context as HasContext>::UniformLocation,
- //currently the maximum number of stops is 64 due to needing to allocate the
- //memory for the array of stops with a const value in GLSL
- color_stops_locations: [ColorStopLocation; 64],
-}
+ pub fn use_program(&mut self, gl: &glow::Context, gradient: &Gradient, transform: &Transformation) {
+ unsafe {
+ gl.use_program(Some(self.program))
+ }
-#[derive(Copy, Debug, Clone)]
-struct ColorStopLocation {
- color: <Context as HasContext>::UniformLocation,
- offset: <Context as HasContext>::UniformLocation,
+ self.write_uniforms(gl, gradient, transform);
+ }
}
impl GradientUniformData {
@@ -153,10 +165,7 @@ impl GradientUniformData {
&format!("color_stop_offsets[{}]", index),
)
}
- .expect(&format!(
- "Gradient - Color stop offset with index {}",
- index
- ));
+ .expect("Gradient - Color stop offset location.");
let color = unsafe {
gl.get_uniform_location(
@@ -164,25 +173,28 @@ impl GradientUniformData {
&format!("color_stop_colors[{}]", index),
)
}
- .expect(&format!(
- "Gradient - Color stop colors with index {}",
- index
- ));
+ .expect("Gradient - Color stop color location.");
ColorStopLocation { color, offset }
});
+ let transform_location =
+ unsafe { gl.get_uniform_location(program, "u_Transform") }
+ .expect("Get transform location.");
+
GradientUniformData {
- current_gradient: Gradient::Linear(Linear {
+ gradient: Gradient::Linear(Linear {
start: Default::default(),
end: Default::default(),
color_stops: vec![],
}),
+ transform: Transformation::identity(),
uniform_locations: GradientUniformLocations {
gradient_start_location,
gradient_end_location,
color_stops_size_location,
color_stops_locations,
+ transform_location,
},
}
}
diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs
index 3a33cea8..d5b73eb9 100644
--- a/glow/src/triangle/solid.rs
+++ b/glow/src/triangle/solid.rs
@@ -1,13 +1,38 @@
use crate::program::Version;
-use crate::triangle::{simple_triangle_program, update_transform};
+use crate::triangle::{set_transform, simple_triangle_program};
use crate::Color;
use glow::{Context, HasContext, NativeProgram};
use iced_graphics::Transformation;
#[derive(Debug)]
pub struct SolidProgram {
- pub(crate) program: <Context as HasContext>::Program,
- pub(crate) uniform_data: SolidUniformData,
+ program: <Context as HasContext>::Program,
+ uniform_data: SolidUniformData,
+}
+
+#[derive(Debug)]
+pub(crate) struct SolidUniformData {
+ pub color: Color,
+ pub color_location: <Context as HasContext>::UniformLocation,
+ pub transform: Transformation,
+ pub transform_location: <Context as HasContext>::UniformLocation,
+}
+
+impl SolidUniformData {
+ fn new(gl: &Context, program: NativeProgram) -> Self {
+ Self {
+ color: Color::TRANSPARENT,
+ color_location: unsafe {
+ gl.get_uniform_location(program, "color")
+ }
+ .expect("Solid - Color uniform location."),
+ transform: Transformation::identity(),
+ transform_location: unsafe {
+ gl.get_uniform_location(program, "u_Transform")
+ }
+ .expect("Get transform location."),
+ }
+ }
}
impl SolidProgram {
@@ -24,15 +49,17 @@ impl SolidProgram {
}
}
- pub fn set_uniforms<'a>(
+ pub fn write_uniforms(
&mut self,
gl: &Context,
color: &Color,
- transform: Option<Transformation>,
+ transform: &Transformation,
) {
- update_transform(gl, self.program, transform);
+ if transform != &self.uniform_data.transform {
+ set_transform(gl, self.uniform_data.transform_location, *transform)
+ }
- if &self.uniform_data.color != color {
+ if color != &self.uniform_data.color {
unsafe {
gl.uniform_4_f32(
Some(&self.uniform_data.color_location),
@@ -46,22 +73,11 @@ impl SolidProgram {
self.uniform_data.color = *color;
}
}
-}
-
-#[derive(Debug)]
-pub(crate) struct SolidUniformData {
- pub color: Color,
- pub color_location: <Context as HasContext>::UniformLocation,
-}
-impl SolidUniformData {
- fn new(gl: &Context, program: NativeProgram) -> Self {
- Self {
- color: Color::TRANSPARENT,
- color_location: unsafe {
- gl.get_uniform_location(program, "color")
- }
- .expect("Solid - Color uniform location."),
+ pub fn use_program(&mut self, gl: &glow::Context, color: &Color, transform: &Transformation) {
+ unsafe {
+ gl.use_program(Some(self.program))
}
+ self.write_uniforms(gl, color, transform)
}
-}
+} \ No newline at end of file