From 40f45d7b7e35dd4937abe6b5ce16b6256b4f1eeb Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 29 Sep 2022 10:52:58 -0700 Subject: Adds linear gradient support to 2D meshes in the canvas widget. --- glow/src/backend.rs | 7 +- glow/src/shader/common/gradient.frag | 48 ++++++++ glow/src/shader/common/triangle.frag | 4 +- glow/src/shader/common/triangle.vert | 6 +- glow/src/triangle.rs | 228 ++++++++++++++++++----------------- glow/src/triangle/gradient.rs | 189 +++++++++++++++++++++++++++++ glow/src/triangle/solid.rs | 67 ++++++++++ glow/src/window/compositor.rs | 3 +- 8 files changed, 429 insertions(+), 123 deletions(-) create mode 100644 glow/src/shader/common/gradient.frag create mode 100644 glow/src/triangle/gradient.rs create mode 100644 glow/src/triangle/solid.rs (limited to 'glow/src') diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 78d4229e..6fc4fb38 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -1,7 +1,6 @@ -use crate::program; +use crate::{program, triangle}; use crate::quad; use crate::text; -use crate::triangle; use crate::{Settings, Transformation, Viewport}; use iced_graphics::backend; @@ -100,16 +99,16 @@ impl Backend { ); } - if !layer.meshes.is_empty() { + if !layer.meshes.0.is_empty() { let scaled = transformation * Transformation::scale(scale_factor, scale_factor); self.triangle_pipeline.draw( + &layer.meshes, gl, target_height, scaled, scale_factor, - &layer.meshes, ); } diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag new file mode 100644 index 00000000..588f63e0 --- /dev/null +++ b/glow/src/shader/common/gradient.frag @@ -0,0 +1,48 @@ +// GLSL does not support dynamically sized arrays without SSBOs +#define MAX_STOPS 64 + +#ifdef GL_ES +#ifdef GL_FRAGMENT_PRECISION_HIGH +precision highp float; +#else +precision mediump float; +#endif +#endif + +#ifdef HIGHER_THAN_300 +layout (location = 0) out vec4 fragColor; +#define gl_FragColor fragColor +#endif + +in vec2 raw_position; + +uniform vec2 gradient_start; +uniform vec2 gradient_end; + +uniform uint color_stops_size; +uniform float color_stop_offsets[MAX_STOPS]; +uniform vec4 color_stop_colors[MAX_STOPS]; + +void main() { + vec2 gradient_vec = vec2(gradient_end - gradient_start); + vec2 current_vec = vec2(raw_position.xy - gradient_start); + vec2 unit = normalize(gradient_vec); + float coord_offset = dot(unit, current_vec) / length(gradient_vec); + + for (uint i = 0; i < color_stops_size - 1; i++) { + float stop_offset = color_stop_offsets[i]; + float next_stop_offset = color_stop_offsets[i + 1]; + + if (stop_offset <= coord_offset && coord_offset <= next_stop_offset) { + fragColor = mix(color_stop_colors[i], color_stop_colors[i+1], smoothstep( + stop_offset, + next_stop_offset, + coord_offset + )); + } else if (coord_offset < color_stop_offsets[0]) { + fragColor = color_stop_colors[0]; + } else if (coord_offset > color_stop_offsets[color_stops_size - 1]) { + fragColor = color_stop_colors[color_stops_size - 1]; + } + } +} \ No newline at end of file diff --git a/glow/src/shader/common/triangle.frag b/glow/src/shader/common/triangle.frag index e8689f2e..0ee65239 100644 --- a/glow/src/shader/common/triangle.frag +++ b/glow/src/shader/common/triangle.frag @@ -11,8 +11,8 @@ out vec4 fragColor; #define gl_FragColor fragColor #endif -in vec4 v_Color; +uniform vec4 color; void main() { - gl_FragColor = v_Color; + fragColor = color; } \ No newline at end of file diff --git a/glow/src/shader/common/triangle.vert b/glow/src/shader/common/triangle.vert index d0494a5f..09a4e324 100644 --- a/glow/src/shader/common/triangle.vert +++ b/glow/src/shader/common/triangle.vert @@ -1,11 +1,9 @@ uniform mat4 u_Transform; in vec2 i_Position; -in vec4 i_Color; - -out vec4 v_Color; +out vec2 raw_position; void main() { gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); - v_Color = i_Color; + raw_position = i_Position; } \ No newline at end of file diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index ae4f83ef..7d0e14c7 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,66 +1,41 @@ -//! Draw meshes of triangles. +//! Draw meshes of triangle. +mod gradient; +mod solid; + use crate::program::{self, Shader}; use crate::Transformation; use glow::HasContext; -use iced_graphics::layer; +use iced_graphics::layer::{Mesh, Meshes}; +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}; -const VERTEX_BUFFER_SIZE: usize = 10_000; -const INDEX_BUFFER_SIZE: usize = 10_000; - #[derive(Debug)] pub(crate) struct Pipeline { - program: ::Program, vertex_array: ::VertexArray, vertices: Buffer, indices: Buffer, - transform_location: ::UniformLocation, current_transform: Transformation, + programs: TrianglePrograms, } -impl Pipeline { - pub fn new( - gl: &glow::Context, - shader_version: &program::Version, - ) -> Pipeline { - let program = unsafe { - let vertex_shader = Shader::vertex( - gl, - shader_version, - include_str!("shader/common/triangle.vert"), - ); - let fragment_shader = Shader::fragment( - gl, - shader_version, - include_str!("shader/common/triangle.frag"), - ); - - program::create( - gl, - &[vertex_shader, fragment_shader], - &[(0, "i_Position"), (1, "i_Color")], - ) - }; - - let transform_location = - unsafe { gl.get_uniform_location(program, "u_Transform") } - .expect("Get transform location"); - - unsafe { - gl.use_program(Some(program)); - - let transform: [f32; 16] = Transformation::identity().into(); - gl.uniform_matrix_4_f32_slice( - Some(&transform_location), - false, - &transform, - ); +#[derive(Debug)] +struct TrianglePrograms { + solid: TriangleProgram, + gradient: TriangleProgram, +} - gl.use_program(None); - } +#[derive(Debug)] +enum TriangleProgram { + Solid(SolidProgram), + Gradient(GradientProgram), +} +impl Pipeline { + pub fn new(gl: &glow::Context, shader_version: &program::Version) -> Self { let vertex_array = unsafe { gl.create_vertex_array().expect("Create vertex array") }; @@ -73,7 +48,7 @@ impl Pipeline { gl, glow::ARRAY_BUFFER, glow::DYNAMIC_DRAW, - VERTEX_BUFFER_SIZE, + std::mem::size_of::() as usize, ) }; @@ -82,7 +57,7 @@ impl Pipeline { gl, glow::ELEMENT_ARRAY_BUFFER, glow::DYNAMIC_DRAW, - INDEX_BUFFER_SIZE, + std::mem::size_of::() as usize, ) }; @@ -92,58 +67,45 @@ impl Pipeline { gl.enable_vertex_attrib_array(0); gl.vertex_attrib_pointer_f32(0, 2, glow::FLOAT, false, stride, 0); - gl.enable_vertex_attrib_array(1); - gl.vertex_attrib_pointer_f32( - 1, - 4, - glow::FLOAT, - false, - stride, - 4 * 2, - ); - gl.bind_vertex_array(None); - } + }; - Pipeline { - program, + Self { vertex_array, vertices, indices, - transform_location, current_transform: Transformation::identity(), + programs: TrianglePrograms { + solid: TriangleProgram::Solid(SolidProgram::new( + gl, + shader_version, + )), + gradient: TriangleProgram::Gradient(GradientProgram::new( + gl, + shader_version, + )), + }, } } pub fn draw( &mut self, + meshes: &Meshes<'_>, gl: &glow::Context, target_height: u32, transformation: Transformation, scale_factor: f32, - meshes: &[layer::Mesh<'_>], ) { unsafe { gl.enable(glow::MULTISAMPLE); gl.enable(glow::SCISSOR_TEST); - gl.use_program(Some(self.program)); - gl.bind_vertex_array(Some(self.vertex_array)); + gl.bind_vertex_array(Some(self.vertex_array)) } - // This looks a bit crazy, but we are just counting how many vertices - // and indices we will need to handle. - // TODO: Improve readability - let (total_vertices, total_indices) = meshes - .iter() - .map(|layer::Mesh { buffers, .. }| { - (buffers.vertices.len(), buffers.indices.len()) - }) - .fold((0, 0), |(total_v, total_i), (v, i)| { - (total_v + v, total_i + i) - }); - - // Then we ensure the current buffers are big enough, resizing if - // necessary + //count the total number of vertices & indices we need to handle for all meshes + let (total_vertices, total_indices) = meshes.attribute_count(); + + // Then we ensure the current attribute buffers are big enough, resizing if necessary unsafe { self.vertices.bind(gl, total_vertices); self.indices.bind(gl, total_indices); @@ -153,7 +115,7 @@ impl Pipeline { let mut last_vertex = 0; let mut last_index = 0; - for layer::Mesh { buffers, .. } in meshes { + for Mesh { buffers, .. } in meshes.0.iter() { unsafe { gl.buffer_sub_data_u8_slice( glow::ARRAY_BUFFER, @@ -176,11 +138,12 @@ impl Pipeline { let mut last_vertex = 0; let mut last_index = 0; - for layer::Mesh { + for Mesh { buffers, origin, clip_bounds, - } in meshes + shader, + } in meshes.0.iter() { let transform = transformation * Transformation::translate(origin.x, origin.y); @@ -188,17 +151,6 @@ impl Pipeline { let clip_bounds = (*clip_bounds * scale_factor).snap(); unsafe { - if self.current_transform != transform { - let matrix: [f32; 16] = transform.into(); - gl.uniform_matrix_4_f32_slice( - Some(&self.transform_location), - false, - &matrix, - ); - - self.current_transform = transform; - } - gl.scissor( clip_bounds.x as i32, (target_height - (clip_bounds.y + clip_bounds.height)) @@ -207,6 +159,15 @@ 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); + gl.draw_elements_base_vertex( glow::TRIANGLES, buffers.indices.len() as i32, @@ -222,34 +183,79 @@ impl Pipeline { unsafe { gl.bind_vertex_array(None); - gl.use_program(None); gl.disable(glow::SCISSOR_TEST); gl.disable(glow::MULTISAMPLE); } } -} -#[repr(C)] -#[derive(Debug, Clone, Copy)] -struct Uniforms { - transform: [f32; 16], + fn use_with_shader( + &mut self, + gl: &glow::Context, + shader: &shader::Shader, + transform: Option, + ) { + match shader { + shader::Shader::Solid(color) => { + if let TriangleProgram::Solid(solid_program) = + &mut self.programs.solid + { + unsafe { gl.use_program(Some(solid_program.program)) } + solid_program.set_uniforms(gl, color, transform); + } + } + shader::Shader::Gradient(gradient) => { + if let TriangleProgram::Gradient(gradient_program) = + &mut self.programs.gradient + { + unsafe { gl.use_program(Some(gradient_program.program)) } + gradient_program.set_uniforms(gl, gradient, transform); + } + } + } + } } -unsafe impl bytemuck::Zeroable for Uniforms {} -unsafe impl bytemuck::Pod for Uniforms {} - -impl Default for Uniforms { - fn default() -> Self { - Self { - transform: *Transformation::identity().as_ref(), - } +/// A simple shader program. Uses [`triangle.vert`] for its vertex shader and only binds position +/// attribute location. +pub(super) fn simple_triangle_program( + gl: &glow::Context, + shader_version: &program::Version, + fragment_shader: &'static str, +) -> ::Program { + unsafe { + let vertex_shader = Shader::vertex( + gl, + shader_version, + include_str!("shader/common/triangle.vert"), + ); + + let fragment_shader = + Shader::fragment(gl, shader_version, fragment_shader); + + program::create( + gl, + &[vertex_shader, fragment_shader], + &[(0, "i_Position")], + ) } } -impl From for Uniforms { - fn from(transformation: Transformation) -> Uniforms { - Self { - transform: transformation.into(), +pub(super) fn update_transform( + gl: &glow::Context, + program: ::Program, + transform: Option +) { + 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(), + ); } } } diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs new file mode 100644 index 00000000..d1b10d77 --- /dev/null +++ b/glow/src/triangle/gradient.rs @@ -0,0 +1,189 @@ +use crate::program::Version; +use crate::triangle::{simple_triangle_program, update_transform}; +use glow::{Context, HasContext, NativeProgram}; +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: ::Program, + pub(super) uniform_data: GradientUniformData, +} + +impl GradientProgram { + pub(super) fn new(gl: &Context, shader_version: &Version) -> Self { + let program = simple_triangle_program( + gl, + shader_version, + include_str!("../shader/common/gradient.frag"), + ); + + Self { + program, + uniform_data: GradientUniformData::new(gl, program), + } + } + + pub(super) fn set_uniforms<'a>( + &mut self, + gl: &Context, + gradient: &Gradient, + transform: Option, + ) { + update_transform(gl, self.program, transform); + + if &self.uniform_data.current_gradient != gradient { + match gradient { + Gradient::Linear(linear) => { + let gradient_start: [f32; 2] = (linear.start).into(); + let gradient_end: [f32; 2] = (linear.end).into(); + + unsafe { + gl.uniform_2_f32( + Some( + &self + .uniform_data + .uniform_locations + .gradient_start_location, + ), + gradient_start[0], + gradient_start[1], + ); + + gl.uniform_2_f32( + Some( + &self + .uniform_data + .uniform_locations + .gradient_end_location, + ), + gradient_end[0], + gradient_end[1], + ); + + gl.uniform_1_u32( + Some( + &self + .uniform_data + .uniform_locations + .color_stops_size_location, + ), + linear.color_stops.len() as u32, + ); + + for (index, stop) in + linear.color_stops.iter().enumerate() + { + gl.uniform_1_f32( + Some( + &self + .uniform_data + .uniform_locations + .color_stops_locations[index] + .offset, + ), + stop.offset, + ); + + gl.uniform_4_f32( + Some( + &self + .uniform_data + .uniform_locations + .color_stops_locations[index] + .color, + ), + stop.color.r, + stop.color.g, + stop.color.b, + stop.color.a, + ); + } + } + } + } + + self.uniform_data.current_gradient = gradient.clone(); + } + } +} + +#[derive(Debug)] +pub(super) struct GradientUniformData { + current_gradient: Gradient, + uniform_locations: GradientUniformLocations, +} + +#[derive(Debug)] +struct GradientUniformLocations { + gradient_start_location: ::UniformLocation, + gradient_end_location: ::UniformLocation, + color_stops_size_location: ::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], +} + +#[derive(Copy, Debug, Clone)] +struct ColorStopLocation { + color: ::UniformLocation, + offset: ::UniformLocation, +} + +impl GradientUniformData { + fn new(gl: &Context, program: NativeProgram) -> Self { + let gradient_start_location = + unsafe { gl.get_uniform_location(program, "gradient_start") } + .expect("Gradient - Get gradient_start."); + + let gradient_end_location = + unsafe { gl.get_uniform_location(program, "gradient_end") } + .expect("Gradient - Get gradient_end."); + + let color_stops_size_location = + unsafe { gl.get_uniform_location(program, "color_stops_size") } + .expect("Gradient - Get color_stops_size."); + + let color_stops_locations: [ColorStopLocation; 64] = + core::array::from_fn(|index| { + let offset = unsafe { + gl.get_uniform_location( + program, + &format!("color_stop_offsets[{}]", index), + ) + } + .expect(&format!( + "Gradient - Color stop offset with index {}", + index + )); + + let color = unsafe { + gl.get_uniform_location( + program, + &format!("color_stop_colors[{}]", index), + ) + } + .expect(&format!( + "Gradient - Color stop colors with index {}", + index + )); + + ColorStopLocation { color, offset } + }); + + GradientUniformData { + current_gradient: Gradient::Linear(Linear { + start: Default::default(), + end: Default::default(), + color_stops: vec![], + }), + uniform_locations: GradientUniformLocations { + gradient_start_location, + gradient_end_location, + color_stops_size_location, + color_stops_locations, + }, + } + } +} diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs new file mode 100644 index 00000000..3a33cea8 --- /dev/null +++ b/glow/src/triangle/solid.rs @@ -0,0 +1,67 @@ +use crate::program::Version; +use crate::triangle::{simple_triangle_program, update_transform}; +use crate::Color; +use glow::{Context, HasContext, NativeProgram}; +use iced_graphics::Transformation; + +#[derive(Debug)] +pub struct SolidProgram { + pub(crate) program: ::Program, + pub(crate) uniform_data: SolidUniformData, +} + +impl SolidProgram { + pub fn new(gl: &Context, shader_version: &Version) -> Self { + let program = simple_triangle_program( + gl, + shader_version, + include_str!("../shader/common/triangle.frag"), + ); + + Self { + program, + uniform_data: SolidUniformData::new(gl, program), + } + } + + pub fn set_uniforms<'a>( + &mut self, + gl: &Context, + color: &Color, + transform: Option, + ) { + update_transform(gl, self.program, transform); + + if &self.uniform_data.color != color { + unsafe { + gl.uniform_4_f32( + Some(&self.uniform_data.color_location), + color.r, + color.g, + color.b, + color.a, + ); + } + + self.uniform_data.color = *color; + } + } +} + +#[derive(Debug)] +pub(crate) struct SolidUniformData { + pub color: Color, + pub color_location: ::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."), + } + } +} diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index f6afaa68..e9cf6015 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -26,8 +26,7 @@ impl iced_graphics::window::GLCompositor for Compositor { log::info!("{:#?}", settings); let version = gl.version(); - log::info!("Version: {:?}", version); - log::info!("Embedded: {}", version.is_embedded); + log::info!("OpenGL version: {:?} (Embedded: {}", version, version.is_embedded); let renderer = gl.get_parameter_string(glow::RENDERER); log::info!("Renderer: {}", renderer); -- cgit From e25f3d3dea2d2c1ba7d2778948443df2745084be Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 29 Sep 2022 17:13:32 -0700 Subject: Fixed issue where OpenGL would not render both shaders at once under certain circumstances. --- glow/src/triangle.rs | 52 ++++++++++++++++++++++------------------------------ 1 file changed, 22 insertions(+), 30 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 7d0e14c7..85d873fe 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -24,14 +24,8 @@ pub(crate) struct Pipeline { #[derive(Debug)] struct TrianglePrograms { - solid: TriangleProgram, - gradient: TriangleProgram, -} - -#[derive(Debug)] -enum TriangleProgram { - Solid(SolidProgram), - Gradient(GradientProgram), + solid: SolidProgram, + gradient: GradientProgram, } impl Pipeline { @@ -76,14 +70,8 @@ impl Pipeline { indices, current_transform: Transformation::identity(), programs: TrianglePrograms { - solid: TriangleProgram::Solid(SolidProgram::new( - gl, - shader_version, - )), - gradient: TriangleProgram::Gradient(GradientProgram::new( - gl, - shader_version, - )), + solid: SolidProgram::new(gl, shader_version), + gradient: GradientProgram::new(gl, shader_version), }, } } @@ -138,16 +126,21 @@ impl Pipeline { let mut last_vertex = 0; let mut last_index = 0; - for Mesh { + for (index, Mesh { buffers, origin, clip_bounds, shader, - } in meshes.0.iter() + }) 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); + } + let clip_bounds = (*clip_bounds * scale_factor).snap(); unsafe { @@ -196,25 +189,24 @@ impl Pipeline { ) { match shader { shader::Shader::Solid(color) => { - if let TriangleProgram::Solid(solid_program) = - &mut self.programs.solid - { - unsafe { gl.use_program(Some(solid_program.program)) } - solid_program.set_uniforms(gl, color, transform); - } + unsafe { gl.use_program(Some(self.programs.solid.program)) } + self.programs.solid.set_uniforms(gl, color, transform); } shader::Shader::Gradient(gradient) => { - if let TriangleProgram::Gradient(gradient_program) = - &mut self.programs.gradient - { - unsafe { gl.use_program(Some(gradient_program.program)) } - gradient_program.set_uniforms(gl, gradient, transform); - } + 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 /// attribute location. pub(super) fn simple_triangle_program( -- cgit From 6e7b3ced0b1daf368e44e181ecdb4ae529877eb6 Mon Sep 17 00:00:00 2001 From: shan Date: Tue, 4 Oct 2022 18:24:46 -0700 Subject: Reworked wgpu buffers, updated glow side to have proper transform location storage, attempting to fix visibility modifiers, implemented some of the feedback received in initial PR. --- glow/src/backend.rs | 2 +- glow/src/shader/common/gradient.frag | 1 + glow/src/triangle.rs | 126 ++++++++++++----------------------- glow/src/triangle/gradient.rs | 92 ++++++++++++++----------- glow/src/triangle/solid.rs | 62 ++++++++++------- 5 files changed, 134 insertions(+), 149 deletions(-) (limited to 'glow/src') 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: ::VertexArray, vertices: Buffer, indices: Buffer, - 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::()) as i32, - bytemuck::cast_slice(&buffers.vertices), + (vertex_offset * std::mem::size_of::()) as i32, + bytemuck::cast_slice(&mesh.buffers.vertices), ); gl.buffer_sub_data_u8_slice( glow::ELEMENT_ARRAY_BUFFER, - (last_index * std::mem::size_of::()) as i32, - bytemuck::cast_slice(&buffers.indices), + (index_offset * std::mem::size_of::()) 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::()) 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, - ) { - 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, ) -> ::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: ::Program, - transform: Option + location: ::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: ::Program, - pub(super) uniform_data: GradientUniformData, +pub struct GradientProgram { + pub program: ::Program, + pub uniform_data: GradientUniformData, +} + +#[derive(Debug)] +pub struct GradientUniformData { + gradient: Gradient, + transform: Transformation, + uniform_locations: GradientUniformLocations, +} + +#[derive(Debug)] +struct GradientUniformLocations { + gradient_start_location: ::UniformLocation, + gradient_end_location: ::UniformLocation, + color_stops_size_location: ::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: ::UniformLocation, +} + +#[derive(Copy, Debug, Clone)] +struct ColorStopLocation { + color: ::UniformLocation, + offset: ::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, + 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: ::UniformLocation, - gradient_end_location: ::UniformLocation, - color_stops_size_location: ::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: ::UniformLocation, - offset: ::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: ::Program, - pub(crate) uniform_data: SolidUniformData, + program: ::Program, + uniform_data: SolidUniformData, +} + +#[derive(Debug)] +pub(crate) struct SolidUniformData { + pub color: Color, + pub color_location: ::UniformLocation, + pub transform: Transformation, + pub transform_location: ::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, + 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: ::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 -- cgit From 30432cbade3d9b25c4df62656a7494db3f4ea82a Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 10:49:58 -0700 Subject: Readjusted namespaces, removed Geometry example as it's no longer relevant. --- glow/src/triangle.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f16f8af4..5e58f4e4 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -5,13 +5,13 @@ mod solid; use crate::{program, Transformation}; use glow::HasContext; use iced_graphics::layer::{attribute_count_of, Mesh}; -use iced_graphics::shader; use std::marker::PhantomData; +use iced_graphics::layer; use crate::triangle::gradient::GradientProgram; use crate::triangle::solid::SolidProgram; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; -use shader::Shader; +use layer::mesh; #[derive(Debug)] pub(crate) struct Pipeline { @@ -139,11 +139,11 @@ impl Pipeline { clip_bounds.height as i32, ); - match mesh.shader { - Shader::Solid(color) => { + match mesh.style { + mesh::Style::Solid(color) => { self.programs.solid.use_program(gl, &color, &transform); } - Shader::Gradient(gradient) => { + mesh::Style::Gradient(gradient) => { self.programs.gradient.use_program(gl, &gradient, &transform); } } -- cgit From 1eb8d972ba60592da7bfc27fe7ec80138e64dd7b Mon Sep 17 00:00:00 2001 From: shan Date: Wed, 5 Oct 2022 16:07:43 -0700 Subject: Reduced memory transfer of OpenGL gradient uniform upload. Rearranged gradient uniforms on OpenGL side to be more performant. --- glow/src/quad/compatibility.rs | 6 +- glow/src/quad/core.rs | 6 +- glow/src/shader/common/gradient.frag | 43 ++++++----- glow/src/triangle/gradient.rs | 143 +++++++++++++---------------------- 4 files changed, 77 insertions(+), 121 deletions(-) (limited to 'glow/src') diff --git a/glow/src/quad/compatibility.rs b/glow/src/quad/compatibility.rs index eb3fb7e0..28a5ea7c 100644 --- a/glow/src/quad/compatibility.rs +++ b/glow/src/quad/compatibility.rs @@ -70,11 +70,10 @@ impl Pipeline { unsafe { gl.use_program(Some(program)); - let matrix: [f32; 16] = Transformation::identity().into(); gl.uniform_matrix_4_f32_slice( Some(&transform_location), false, - &matrix, + Transformation::identity().as_ref(), ); gl.uniform_1_f32(Some(&scale_location), 1.0); @@ -139,11 +138,10 @@ impl Pipeline { if transformation != self.current_transform { unsafe { - let matrix: [f32; 16] = transformation.into(); gl.uniform_matrix_4_f32_slice( Some(&self.transform_location), false, - &matrix, + transformation.as_ref(), ); self.current_transform = transformation; diff --git a/glow/src/quad/core.rs b/glow/src/quad/core.rs index 3e51b1ca..16bec385 100644 --- a/glow/src/quad/core.rs +++ b/glow/src/quad/core.rs @@ -65,11 +65,10 @@ impl Pipeline { unsafe { gl.use_program(Some(program)); - let matrix: [f32; 16] = Transformation::identity().into(); gl.uniform_matrix_4_f32_slice( Some(&transform_location), false, - &matrix, + Transformation::identity().as_ref(), ); gl.uniform_1_f32(Some(&scale_location), 1.0); @@ -119,11 +118,10 @@ impl Pipeline { if transformation != self.current_transform { unsafe { - let matrix: [f32; 16] = transformation.into(); gl.uniform_matrix_4_f32_slice( Some(&self.transform_location), false, - &matrix, + transformation.as_ref(), ); self.current_transform = transformation; diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 1afb557d..89d2d398 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -1,6 +1,3 @@ -// GLSL does not support dynamically sized arrays without SSBOs -#define MAX_STOPS 64 - #ifdef GL_ES #ifdef GL_FRAGMENT_PRECISION_HIGH precision highp float; @@ -16,34 +13,38 @@ layout (location = 0) out vec4 fragColor; in vec2 raw_position; -uniform vec2 gradient_start; -uniform vec2 gradient_end; - +uniform vec4 gradient_direction; uniform uint color_stops_size; -uniform float color_stop_offsets[MAX_STOPS]; -uniform vec4 color_stop_colors[MAX_STOPS]; +// GLSL does not support dynamically sized arrays without SSBOs so this is capped to 16 stops +//stored as color(vec4) -> offset(vec4) sequentially; +uniform vec4 color_stops[32]; //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); + vec2 start = gradient_direction.xy; + vec2 end = gradient_direction.zw; + vec2 gradient_vec = vec2(end - start); + vec2 current_vec = vec2(raw_position.xy - start); vec2 unit = normalize(gradient_vec); float coord_offset = dot(unit, current_vec) / length(gradient_vec); - for (uint i = 0; i < color_stops_size - 1; i++) { - float stop_offset = color_stop_offsets[i]; - float next_stop_offset = color_stop_offsets[i + 1]; + for (uint i = 0; i < color_stops_size - 2; i += 2) { + vec4 color = color_stops[i]; + float offset = color_stops[i+1].x; + + vec4 next_color = color_stops[i+2]; + float next_offset = color_stops[i+3].x; - if (stop_offset <= coord_offset && coord_offset <= next_stop_offset) { - fragColor = mix(color_stop_colors[i], color_stop_colors[i+1], smoothstep( - stop_offset, - next_stop_offset, + if (offset <= coord_offset && coord_offset <= next_offset) { + fragColor = mix(color, next_color, smoothstep( + offset, + next_offset, coord_offset )); - } else if (coord_offset < color_stop_offsets[0]) { - fragColor = color_stop_colors[0]; - } else if (coord_offset > color_stop_offsets[color_stops_size - 1]) { - fragColor = color_stop_colors[color_stops_size - 1]; + } else if (coord_offset < color_stops[1].x) { + fragColor = color_stops[0]; + } else if (coord_offset > color_stops[color_stops_size - 1].x) { + fragColor = color_stops[color_stops_size - 2]; } } } \ No newline at end of file diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index 547871e2..4b157890 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -1,8 +1,8 @@ use crate::program::Version; -use crate::triangle::{simple_triangle_program, set_transform}; +use crate::triangle::{set_transform, simple_triangle_program}; use glow::{Context, HasContext, NativeProgram}; -use iced_graphics::gradient::Linear; use iced_graphics::gradient::Gradient; +use iced_graphics::gradient::Linear; use iced_graphics::Transformation; #[derive(Debug)] @@ -20,21 +20,14 @@ pub struct GradientUniformData { #[derive(Debug)] struct GradientUniformLocations { - gradient_start_location: ::UniformLocation, - gradient_end_location: ::UniformLocation, + gradient_direction_location: ::UniformLocation, color_stops_size_location: ::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], + color_stops_location: ::UniformLocation, transform_location: ::UniformLocation, } -#[derive(Copy, Debug, Clone)] -struct ColorStopLocation { - color: ::UniformLocation, - offset: ::UniformLocation, -} - impl GradientProgram { pub fn new(gl: &Context, shader_version: &Version) -> Self { let program = simple_triangle_program( @@ -56,76 +49,60 @@ impl GradientProgram { transform: &Transformation, ) { if transform != &self.uniform_data.transform { - set_transform(gl, self.uniform_data.uniform_locations.transform_location, *transform); + set_transform( + gl, + self.uniform_data.uniform_locations.transform_location, + *transform, + ); } if &self.uniform_data.gradient != gradient { match gradient { Gradient::Linear(linear) => { - let gradient_start: [f32; 2] = (linear.start).into(); - let gradient_end: [f32; 2] = (linear.end).into(); - unsafe { - gl.uniform_2_f32( + gl.uniform_4_f32( Some( - &self - .uniform_data - .uniform_locations - .gradient_start_location, + &self.uniform_data.uniform_locations.gradient_direction_location ), - gradient_start[0], - gradient_start[1], + linear.start.x, + linear.start.y, + linear.end.x, + linear.end.y ); - gl.uniform_2_f32( + gl.uniform_1_u32( Some( &self .uniform_data .uniform_locations - .gradient_end_location, + .color_stops_size_location, ), - gradient_end[0], - gradient_end[1], + (linear.color_stops.len() * 2) as u32, ); - gl.uniform_1_u32( + let mut stops = [0.0; 128]; + + for (index, stop) in linear.color_stops.iter().enumerate() { + if index == 16 { break; } + stops[index*8] = stop.color.r; + stops[(index*8)+1] = stop.color.g; + stops[(index*8)+2] = stop.color.b; + stops[(index*8)+3] = stop.color.a; + stops[(index*8)+4] = stop.offset; + stops[(index*8)+5] = 0.; + stops[(index*8)+6] = 0.; + stops[(index*8)+7] = 0.; + } + + gl.uniform_4_f32_slice( Some( &self .uniform_data .uniform_locations - .color_stops_size_location, + .color_stops_location, ), - linear.color_stops.len() as u32, + &stops, ); - - for (index, stop) in - linear.color_stops.iter().enumerate() - { - gl.uniform_1_f32( - Some( - &self - .uniform_data - .uniform_locations - .color_stops_locations[index] - .offset, - ), - stop.offset, - ); - - gl.uniform_4_f32( - Some( - &self - .uniform_data - .uniform_locations - .color_stops_locations[index] - .color, - ), - stop.color.r, - stop.color.g, - stop.color.b, - stop.color.a, - ); - } } } } @@ -134,10 +111,13 @@ impl GradientProgram { } } - pub fn use_program(&mut self, gl: &glow::Context, gradient: &Gradient, transform: &Transformation) { - unsafe { - gl.use_program(Some(self.program)) - } + pub fn use_program( + &mut self, + gl: &Context, + gradient: &Gradient, + transform: &Transformation, + ) { + unsafe { gl.use_program(Some(self.program)) } self.write_uniforms(gl, gradient, transform); } @@ -145,38 +125,18 @@ impl GradientProgram { impl GradientUniformData { fn new(gl: &Context, program: NativeProgram) -> Self { - let gradient_start_location = - unsafe { gl.get_uniform_location(program, "gradient_start") } - .expect("Gradient - Get gradient_start."); - - let gradient_end_location = - unsafe { gl.get_uniform_location(program, "gradient_end") } - .expect("Gradient - Get gradient_end."); + let gradient_direction_location = + unsafe { gl.get_uniform_location(program, "gradient_direction") } + .expect("Gradient - Get gradient_direction."); let color_stops_size_location = unsafe { gl.get_uniform_location(program, "color_stops_size") } .expect("Gradient - Get color_stops_size."); - let color_stops_locations: [ColorStopLocation; 64] = - core::array::from_fn(|index| { - let offset = unsafe { - gl.get_uniform_location( - program, - &format!("color_stop_offsets[{}]", index), - ) - } - .expect("Gradient - Color stop offset location."); - - let color = unsafe { - gl.get_uniform_location( - program, - &format!("color_stop_colors[{}]", index), - ) - } - .expect("Gradient - Color stop color location."); - - ColorStopLocation { color, offset } - }); + let color_stops_location = unsafe { + gl.get_uniform_location(program, "color_stops") + .expect("Gradient - Get color_stops.") + }; let transform_location = unsafe { gl.get_uniform_location(program, "u_Transform") } @@ -190,10 +150,9 @@ impl GradientUniformData { }), transform: Transformation::identity(), uniform_locations: GradientUniformLocations { - gradient_start_location, - gradient_end_location, + gradient_direction_location, color_stops_size_location, - color_stops_locations, + color_stops_location, transform_location, }, } -- cgit From cb7c4676543cd508dfae8d4dcbd9cc8b61b1a94e Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 6 Oct 2022 07:28:05 -0700 Subject: Fixed lint issues & cleaned up some documentation. --- glow/src/shader/common/gradient.frag | 2 +- glow/src/shader/common/triangle.frag | 2 +- glow/src/shader/common/triangle.vert | 2 +- glow/src/triangle.rs | 2 +- glow/src/triangle/solid.rs | 6 +++--- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'glow/src') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 89d2d398..ade9c4a1 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -47,4 +47,4 @@ void main() { fragColor = color_stops[color_stops_size - 2]; } } -} \ No newline at end of file +} diff --git a/glow/src/shader/common/triangle.frag b/glow/src/shader/common/triangle.frag index 0ee65239..ead40fe5 100644 --- a/glow/src/shader/common/triangle.frag +++ b/glow/src/shader/common/triangle.frag @@ -15,4 +15,4 @@ uniform vec4 color; void main() { fragColor = color; -} \ No newline at end of file +} diff --git a/glow/src/shader/common/triangle.vert b/glow/src/shader/common/triangle.vert index 09a4e324..fe505997 100644 --- a/glow/src/shader/common/triangle.vert +++ b/glow/src/shader/common/triangle.vert @@ -6,4 +6,4 @@ out vec2 raw_position; void main() { gl_Position = u_Transform * vec4(i_Position, 0.0, 1.0); raw_position = i_Position; -} \ No newline at end of file +} diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 5e58f4e4..f26d1cea 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,4 +1,4 @@ -//! Draw meshes of triangle. +//! Draw meshes of triangles. mod gradient; mod solid; diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs index d5b73eb9..3d4d1968 100644 --- a/glow/src/triangle/solid.rs +++ b/glow/src/triangle/solid.rs @@ -11,7 +11,7 @@ pub struct SolidProgram { } #[derive(Debug)] -pub(crate) struct SolidUniformData { +struct SolidUniformData { pub color: Color, pub color_location: ::UniformLocation, pub transform: Transformation, @@ -74,10 +74,10 @@ impl SolidProgram { } } - pub fn use_program(&mut self, gl: &glow::Context, color: &Color, transform: &Transformation) { + pub fn use_program(&mut self, gl: &Context, color: &Color, transform: &Transformation) { unsafe { gl.use_program(Some(self.program)) } self.write_uniforms(gl, color, transform) } -} \ No newline at end of file +} -- cgit From f9a6efcaa03728f43aaa105af8936c1ed4778388 Mon Sep 17 00:00:00 2001 From: shan Date: Thu, 6 Oct 2022 19:41:00 -0700 Subject: Fixed some more imports/documentation. --- glow/src/triangle/gradient.rs | 5 ++--- glow/src/triangle/solid.rs | 15 +++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index 4b157890..a8bb5ec5 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -22,8 +22,7 @@ pub struct GradientUniformData { struct GradientUniformLocations { gradient_direction_location: ::UniformLocation, color_stops_size_location: ::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 + //currently the maximum number of stops is 16 due to lack of SSBO in GL2.1 color_stops_location: ::UniformLocation, transform_location: ::UniformLocation, } @@ -140,7 +139,7 @@ impl GradientUniformData { let transform_location = unsafe { gl.get_uniform_location(program, "u_Transform") } - .expect("Get transform location."); + .expect("Gradient - Get u_Transform."); GradientUniformData { gradient: Gradient::Linear(Linear { diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs index 3d4d1968..5ba7f91c 100644 --- a/glow/src/triangle/solid.rs +++ b/glow/src/triangle/solid.rs @@ -25,12 +25,12 @@ impl SolidUniformData { color_location: unsafe { gl.get_uniform_location(program, "color") } - .expect("Solid - Color uniform location."), + .expect("Solid - Get color."), transform: Transformation::identity(), transform_location: unsafe { gl.get_uniform_location(program, "u_Transform") } - .expect("Get transform location."), + .expect("Solid - Get u_Transform."), } } } @@ -74,10 +74,13 @@ impl SolidProgram { } } - pub fn use_program(&mut self, gl: &Context, color: &Color, transform: &Transformation) { - unsafe { - gl.use_program(Some(self.program)) - } + pub fn use_program( + &mut self, + gl: &Context, + color: &Color, + transform: &Transformation, + ) { + unsafe { gl.use_program(Some(self.program)) } self.write_uniforms(gl, color, transform) } } -- cgit From 12a87c54eb68b992676060c80e518ffb29445cfc Mon Sep 17 00:00:00 2001 From: shan Date: Fri, 7 Oct 2022 11:41:50 -0700 Subject: Added support for relative positioning of gradient fills. Addressed some PR feedback. --- glow/src/shader/common/gradient.frag | 3 +++ 1 file changed, 3 insertions(+) (limited to 'glow/src') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index ade9c4a1..3c701af7 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -45,6 +45,9 @@ void main() { fragColor = color_stops[0]; } else if (coord_offset > color_stops[color_stops_size - 1].x) { fragColor = color_stops[color_stops_size - 2]; + } else { + //This use case can happen if a gradient's start & end position are the same + fragColor = vec4(0.0, 0.0, 0.0, 0.0); } } } -- cgit From 87371ce93411ba900c83cd8230a5814b59092c4b Mon Sep 17 00:00:00 2001 From: shan Date: Fri, 7 Oct 2022 13:06:06 -0700 Subject: Fixed an edge case where when gradient start/end are identical the GL fragment shader was not choosing the appropriate color. --- glow/src/shader/common/gradient.frag | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'glow/src') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 3c701af7..82c7e251 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -27,27 +27,33 @@ void main() { vec2 current_vec = vec2(raw_position.xy - start); vec2 unit = normalize(gradient_vec); float coord_offset = dot(unit, current_vec) / length(gradient_vec); + //if a gradient has a start/end stop that is identical, the mesh will have a transparent fill + fragColor = vec4(0.0, 0.0, 0.0, 0.0); - for (uint i = 0; i < color_stops_size - 2; i += 2) { - vec4 color = color_stops[i]; - float offset = color_stops[i+1].x; + float min_offset = color_stops[1].x; + float max_offset = color_stops[color_stops_size - 1].x; - vec4 next_color = color_stops[i+2]; + for (uint i = 0; i < color_stops_size - 2; i += 2) { + float curr_offset = color_stops[i+1].x; float next_offset = color_stops[i+3].x; - if (offset <= coord_offset && coord_offset <= next_offset) { - fragColor = mix(color, next_color, smoothstep( - offset, + if (coord_offset <= min_offset) { + //current coordinate is before the first defined offset, set it to the start color + fragColor = color_stops[0]; + } + + if (curr_offset <= coord_offset && coord_offset <= next_offset) { + //current fragment is between the current offset processing & the next one, interpolate colors + fragColor = mix(color_stops[i], color_stops[i+2], smoothstep( + curr_offset, next_offset, coord_offset )); - } else if (coord_offset < color_stops[1].x) { - fragColor = color_stops[0]; - } else if (coord_offset > color_stops[color_stops_size - 1].x) { + } + + if (coord_offset >= max_offset) { + //current coordinate is before the last defined offset, set it to the last color fragColor = color_stops[color_stops_size - 2]; - } else { - //This use case can happen if a gradient's start & end position are the same - fragColor = vec4(0.0, 0.0, 0.0, 0.0); } } } -- cgit From 215e6c95be7370bdd29c75b904463f06f942b7c0 Mon Sep 17 00:00:00 2001 From: shan Date: Fri, 7 Oct 2022 13:21:32 -0700 Subject: More import adjusting. --- glow/src/triangle.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f26d1cea..f7fe9235 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -4,14 +4,12 @@ mod solid; use crate::{program, Transformation}; use glow::HasContext; -use iced_graphics::layer::{attribute_count_of, Mesh}; +use iced_graphics::layer::{mesh, mesh::attribute_count_of, Mesh}; use std::marker::PhantomData; -use iced_graphics::layer; use crate::triangle::gradient::GradientProgram; use crate::triangle::solid::SolidProgram; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; -use layer::mesh; #[derive(Debug)] pub(crate) struct Pipeline { @@ -144,7 +142,9 @@ impl Pipeline { self.programs.solid.use_program(gl, &color, &transform); } mesh::Style::Gradient(gradient) => { - self.programs.gradient.use_program(gl, &gradient, &transform); + self.programs + .gradient + .use_program(gl, &gradient, &transform); } } @@ -203,7 +203,7 @@ pub fn set_transform( gl.uniform_matrix_4_f32_slice( Some(&location), false, - transform.as_ref() + transform.as_ref(), ); } } -- cgit From bb8d46a3fdf925b4b2fa9e7db76e48caf020b212 Mon Sep 17 00:00:00 2001 From: bungoboingo Date: Mon, 10 Oct 2022 20:55:43 -0700 Subject: Fixed fragment shader compatibility issues with GLES 3.0+ --- glow/src/shader/common/gradient.frag | 26 +++++++++++++------------- glow/src/window/compositor.rs | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) (limited to 'glow/src') diff --git a/glow/src/shader/common/gradient.frag b/glow/src/shader/common/gradient.frag index 82c7e251..42d0201f 100644 --- a/glow/src/shader/common/gradient.frag +++ b/glow/src/shader/common/gradient.frag @@ -1,14 +1,14 @@ #ifdef GL_ES -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif + #ifdef GL_FRAGMENT_PRECISION_HIGH + precision highp float; + #else + precision mediump float; + #endif #endif #ifdef HIGHER_THAN_300 -layout (location = 0) out vec4 fragColor; -#define gl_FragColor fragColor + layout (location = 0) out vec4 fragColor; + #define gl_FragColor fragColor #endif in vec2 raw_position; @@ -31,11 +31,11 @@ void main() { fragColor = vec4(0.0, 0.0, 0.0, 0.0); float min_offset = color_stops[1].x; - float max_offset = color_stops[color_stops_size - 1].x; + float max_offset = color_stops[color_stops_size - 1u].x; - for (uint i = 0; i < color_stops_size - 2; i += 2) { - float curr_offset = color_stops[i+1].x; - float next_offset = color_stops[i+3].x; + for (uint i = 0u; i < color_stops_size - 2u; i += 2u) { + float curr_offset = color_stops[i+1u].x; + float next_offset = color_stops[i+3u].x; if (coord_offset <= min_offset) { //current coordinate is before the first defined offset, set it to the start color @@ -44,7 +44,7 @@ void main() { if (curr_offset <= coord_offset && coord_offset <= next_offset) { //current fragment is between the current offset processing & the next one, interpolate colors - fragColor = mix(color_stops[i], color_stops[i+2], smoothstep( + fragColor = mix(color_stops[i], color_stops[i+2u], smoothstep( curr_offset, next_offset, coord_offset @@ -53,7 +53,7 @@ void main() { if (coord_offset >= max_offset) { //current coordinate is before the last defined offset, set it to the last color - fragColor = color_stops[color_stops_size - 2]; + fragColor = color_stops[color_stops_size - 2u]; } } } diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index e9cf6015..6459dbce 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -26,7 +26,7 @@ impl iced_graphics::window::GLCompositor for Compositor { log::info!("{:#?}", settings); let version = gl.version(); - log::info!("OpenGL version: {:?} (Embedded: {}", version, version.is_embedded); + log::info!("OpenGL version: {:?} (Embedded: {})", version, version.is_embedded); let renderer = gl.get_parameter_string(glow::RENDERER); log::info!("Renderer: {}", renderer); -- cgit From c4565759e4294540f54a81e4d91ddea7a769d3d4 Mon Sep 17 00:00:00 2001 From: bungoboingo Date: Tue, 18 Oct 2022 15:18:37 -0700 Subject: Cleaned up namespaces re: PR comments. --- glow/src/triangle.rs | 22 ++++++++++------------ glow/src/triangle/gradient.rs | 27 +++++++++++++-------------- glow/src/triangle/solid.rs | 23 +++++++++++++---------- 3 files changed, 36 insertions(+), 36 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f7fe9235..fff14910 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -4,11 +4,9 @@ mod solid; use crate::{program, Transformation}; use glow::HasContext; -use iced_graphics::layer::{mesh, mesh::attribute_count_of, Mesh}; +use iced_graphics::layer::{mesh, Mesh}; use std::marker::PhantomData; -use crate::triangle::gradient::GradientProgram; -use crate::triangle::solid::SolidProgram; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; #[derive(Debug)] @@ -16,13 +14,13 @@ pub(crate) struct Pipeline { vertex_array: ::VertexArray, vertices: Buffer, indices: Buffer, - programs: TrianglePrograms, + programs: ProgramList, } #[derive(Debug)] -struct TrianglePrograms { - solid: SolidProgram, - gradient: GradientProgram, +struct ProgramList { + solid: solid::Program, + gradient: gradient::Program, } impl Pipeline { @@ -65,9 +63,9 @@ impl Pipeline { vertex_array, vertices, indices, - programs: TrianglePrograms { - solid: SolidProgram::new(gl, shader_version), - gradient: GradientProgram::new(gl, shader_version), + programs: ProgramList { + solid: solid::Program::new(gl, shader_version), + gradient: gradient::Program::new(gl, shader_version), }, } } @@ -87,7 +85,7 @@ impl Pipeline { } //count the total amount of vertices & indices we need to handle - let (total_vertices, total_indices) = attribute_count_of(meshes); + let (total_vertices, total_indices) = mesh::attribute_count_of(meshes); // Then we ensure the current attribute buffers are big enough, resizing if necessary unsafe { @@ -171,7 +169,7 @@ impl Pipeline { /// A simple shader program. Uses [`triangle.vert`] for its vertex shader and only binds position /// attribute location. -pub(super) fn simple_triangle_program( +pub(super) fn program( gl: &glow::Context, shader_version: &program::Version, fragment_shader: &'static str, diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index a8bb5ec5..6bca44ee 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -1,25 +1,25 @@ use crate::program::Version; -use crate::triangle::{set_transform, simple_triangle_program}; +use crate::triangle; use glow::{Context, HasContext, NativeProgram}; use iced_graphics::gradient::Gradient; use iced_graphics::gradient::Linear; use iced_graphics::Transformation; #[derive(Debug)] -pub struct GradientProgram { +pub struct Program { pub program: ::Program, - pub uniform_data: GradientUniformData, + pub uniform_data: UniformData, } #[derive(Debug)] -pub struct GradientUniformData { +pub struct UniformData { gradient: Gradient, transform: Transformation, - uniform_locations: GradientUniformLocations, + uniform_locations: UniformLocations, } #[derive(Debug)] -struct GradientUniformLocations { +struct UniformLocations { gradient_direction_location: ::UniformLocation, color_stops_size_location: ::UniformLocation, //currently the maximum number of stops is 16 due to lack of SSBO in GL2.1 @@ -27,9 +27,9 @@ struct GradientUniformLocations { transform_location: ::UniformLocation, } -impl GradientProgram { +impl Program { pub fn new(gl: &Context, shader_version: &Version) -> Self { - let program = simple_triangle_program( + let program = triangle::program( gl, shader_version, include_str!("../shader/common/gradient.frag"), @@ -37,7 +37,7 @@ impl GradientProgram { Self { program, - uniform_data: GradientUniformData::new(gl, program), + uniform_data: UniformData::new(gl, program), } } @@ -48,7 +48,7 @@ impl GradientProgram { transform: &Transformation, ) { if transform != &self.uniform_data.transform { - set_transform( + triangle::set_transform( gl, self.uniform_data.uniform_locations.transform_location, *transform, @@ -117,12 +117,11 @@ impl GradientProgram { transform: &Transformation, ) { unsafe { gl.use_program(Some(self.program)) } - self.write_uniforms(gl, gradient, transform); } } -impl GradientUniformData { +impl UniformData { fn new(gl: &Context, program: NativeProgram) -> Self { let gradient_direction_location = unsafe { gl.get_uniform_location(program, "gradient_direction") } @@ -141,14 +140,14 @@ impl GradientUniformData { unsafe { gl.get_uniform_location(program, "u_Transform") } .expect("Gradient - Get u_Transform."); - GradientUniformData { + Self { gradient: Gradient::Linear(Linear { start: Default::default(), end: Default::default(), color_stops: vec![], }), transform: Transformation::identity(), - uniform_locations: GradientUniformLocations { + uniform_locations: UniformLocations { gradient_direction_location, color_stops_size_location, color_stops_location, diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs index 5ba7f91c..311e3704 100644 --- a/glow/src/triangle/solid.rs +++ b/glow/src/triangle/solid.rs @@ -1,24 +1,23 @@ use crate::program::Version; -use crate::triangle::{set_transform, simple_triangle_program}; -use crate::Color; +use crate::{triangle, Color}; use glow::{Context, HasContext, NativeProgram}; use iced_graphics::Transformation; #[derive(Debug)] -pub struct SolidProgram { +pub struct Program { program: ::Program, - uniform_data: SolidUniformData, + uniform_data: UniformData, } #[derive(Debug)] -struct SolidUniformData { +struct UniformData { pub color: Color, pub color_location: ::UniformLocation, pub transform: Transformation, pub transform_location: ::UniformLocation, } -impl SolidUniformData { +impl UniformData { fn new(gl: &Context, program: NativeProgram) -> Self { Self { color: Color::TRANSPARENT, @@ -35,9 +34,9 @@ impl SolidUniformData { } } -impl SolidProgram { +impl Program { pub fn new(gl: &Context, shader_version: &Version) -> Self { - let program = simple_triangle_program( + let program = triangle::program( gl, shader_version, include_str!("../shader/common/triangle.frag"), @@ -45,7 +44,7 @@ impl SolidProgram { Self { program, - uniform_data: SolidUniformData::new(gl, program), + uniform_data: UniformData::new(gl, program), } } @@ -56,7 +55,11 @@ impl SolidProgram { transform: &Transformation, ) { if transform != &self.uniform_data.transform { - set_transform(gl, self.uniform_data.transform_location, *transform) + triangle::set_transform( + gl, + self.uniform_data.transform_location, + *transform, + ) } if color != &self.uniform_data.color { -- cgit From 67ab4fd8c0ebd0e1e638307c6b303cce5cc13e9c Mon Sep 17 00:00:00 2001 From: bungoboingo Date: Tue, 18 Oct 2022 18:05:53 -0700 Subject: Updated syntax for color stop iteration re: PR comments. --- glow/src/triangle/gradient.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index 6bca44ee..36e434e3 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -81,8 +81,7 @@ impl Program { let mut stops = [0.0; 128]; - for (index, stop) in linear.color_stops.iter().enumerate() { - if index == 16 { break; } + for (index, stop) in linear.color_stops.iter().enumerate().take(16) { stops[index*8] = stop.color.r; stops[(index*8)+1] = stop.color.g; stops[(index*8)+2] = stop.color.b; -- cgit From b95745340441835bd25b5cadc2342254631f8c05 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 04:35:16 +0100 Subject: Run `cargo fmt` --- glow/src/backend.rs | 2 +- glow/src/triangle/gradient.rs | 93 ++++++++++++++++++++++--------------------- glow/src/window/compositor.rs | 6 ++- 3 files changed, 54 insertions(+), 47 deletions(-) (limited to 'glow/src') diff --git a/glow/src/backend.rs b/glow/src/backend.rs index 7333d513..21af2ecf 100644 --- a/glow/src/backend.rs +++ b/glow/src/backend.rs @@ -1,6 +1,6 @@ -use crate::{program, triangle}; use crate::quad; use crate::text; +use crate::{program, triangle}; use crate::{Settings, Transformation, Viewport}; use iced_graphics::backend; diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index 36e434e3..ad41dffd 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -57,52 +57,55 @@ impl Program { if &self.uniform_data.gradient != gradient { match gradient { - Gradient::Linear(linear) => { - unsafe { - gl.uniform_4_f32( - Some( - &self.uniform_data.uniform_locations.gradient_direction_location - ), - linear.start.x, - linear.start.y, - linear.end.x, - linear.end.y - ); - - gl.uniform_1_u32( - Some( - &self - .uniform_data - .uniform_locations - .color_stops_size_location, - ), - (linear.color_stops.len() * 2) as u32, - ); - - let mut stops = [0.0; 128]; - - for (index, stop) in linear.color_stops.iter().enumerate().take(16) { - stops[index*8] = stop.color.r; - stops[(index*8)+1] = stop.color.g; - stops[(index*8)+2] = stop.color.b; - stops[(index*8)+3] = stop.color.a; - stops[(index*8)+4] = stop.offset; - stops[(index*8)+5] = 0.; - stops[(index*8)+6] = 0.; - stops[(index*8)+7] = 0.; - } - - gl.uniform_4_f32_slice( - Some( - &self - .uniform_data - .uniform_locations - .color_stops_location, - ), - &stops, - ); + Gradient::Linear(linear) => unsafe { + gl.uniform_4_f32( + Some( + &self + .uniform_data + .uniform_locations + .gradient_direction_location, + ), + linear.start.x, + linear.start.y, + linear.end.x, + linear.end.y, + ); + + gl.uniform_1_u32( + Some( + &self + .uniform_data + .uniform_locations + .color_stops_size_location, + ), + (linear.color_stops.len() * 2) as u32, + ); + + let mut stops = [0.0; 128]; + + for (index, stop) in + linear.color_stops.iter().enumerate().take(16) + { + stops[index * 8] = stop.color.r; + stops[(index * 8) + 1] = stop.color.g; + stops[(index * 8) + 2] = stop.color.b; + stops[(index * 8) + 3] = stop.color.a; + stops[(index * 8) + 4] = stop.offset; + stops[(index * 8) + 5] = 0.; + stops[(index * 8) + 6] = 0.; + stops[(index * 8) + 7] = 0.; } - } + + gl.uniform_4_f32_slice( + Some( + &self + .uniform_data + .uniform_locations + .color_stops_location, + ), + &stops, + ); + }, } self.uniform_data.gradient = gradient.clone(); diff --git a/glow/src/window/compositor.rs b/glow/src/window/compositor.rs index 6459dbce..20756032 100644 --- a/glow/src/window/compositor.rs +++ b/glow/src/window/compositor.rs @@ -26,7 +26,11 @@ impl iced_graphics::window::GLCompositor for Compositor { log::info!("{:#?}", settings); let version = gl.version(); - log::info!("OpenGL version: {:?} (Embedded: {})", version, version.is_embedded); + log::info!( + "OpenGL version: {:?} (Embedded: {})", + version, + version.is_embedded + ); let renderer = gl.get_parameter_string(glow::RENDERER); log::info!("Renderer: {}", renderer); -- cgit From 62465842099908f9e50b8edabfec709b37b1ade3 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 04:37:23 +0100 Subject: Convert colors to linear RGB before uploading in `solid` pipelines --- glow/src/triangle/solid.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle/solid.rs b/glow/src/triangle/solid.rs index 311e3704..fb3d40c3 100644 --- a/glow/src/triangle/solid.rs +++ b/glow/src/triangle/solid.rs @@ -63,13 +63,15 @@ impl Program { } if color != &self.uniform_data.color { + let [r, g, b, a] = color.into_linear(); + unsafe { gl.uniform_4_f32( Some(&self.uniform_data.color_location), - color.r, - color.g, - color.b, - color.a, + r, + g, + b, + a, ); } -- cgit From 9a02d60ba51a91049466caa46db73d741520e051 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 04:41:27 +0100 Subject: Convert colors to linear RGB in `gradient` pipelines --- glow/src/triangle/gradient.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle/gradient.rs b/glow/src/triangle/gradient.rs index ad41dffd..5225612e 100644 --- a/glow/src/triangle/gradient.rs +++ b/glow/src/triangle/gradient.rs @@ -86,10 +86,12 @@ impl Program { for (index, stop) in linear.color_stops.iter().enumerate().take(16) { - stops[index * 8] = stop.color.r; - stops[(index * 8) + 1] = stop.color.g; - stops[(index * 8) + 2] = stop.color.b; - stops[(index * 8) + 3] = stop.color.a; + let [r, g, b, a] = stop.color.into_linear(); + + stops[index * 8] = r; + stops[(index * 8) + 1] = g; + stops[(index * 8) + 2] = b; + stops[(index * 8) + 3] = a; stops[(index * 8) + 4] = stop.offset; stops[(index * 8) + 5] = 0.; stops[(index * 8) + 6] = 0.; -- cgit From 7e22e2d45293c5916812be03dc7367134b69b3ad Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 04:53:27 +0100 Subject: Fix lints by `clippy` --- glow/src/triangle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index fff14910..68ebcb00 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -137,12 +137,12 @@ impl Pipeline { match mesh.style { mesh::Style::Solid(color) => { - self.programs.solid.use_program(gl, &color, &transform); + self.programs.solid.use_program(gl, color, &transform); } mesh::Style::Gradient(gradient) => { self.programs .gradient - .use_program(gl, &gradient, &transform); + .use_program(gl, gradient, &transform); } } -- cgit From 84d1b79fefc88534835fdfbe79bc0eb3b43627cf Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 05:50:53 +0100 Subject: Move `mesh::Style` to `triangle` and reuse it in `fill` and `stroke` --- glow/src/triangle.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 68ebcb00..5d14666c 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -3,8 +3,11 @@ mod gradient; mod solid; use crate::{program, Transformation}; + +use iced_graphics::layer::mesh::{self, Mesh}; +use iced_graphics::triangle; + use glow::HasContext; -use iced_graphics::layer::{mesh, Mesh}; use std::marker::PhantomData; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; @@ -136,10 +139,10 @@ impl Pipeline { ); match mesh.style { - mesh::Style::Solid(color) => { + triangle::Style::Solid(color) => { self.programs.solid.use_program(gl, color, &transform); } - mesh::Style::Gradient(gradient) => { + triangle::Style::Gradient(gradient) => { self.programs .gradient .use_program(gl, gradient, &transform); -- cgit From f31c8f2504ea7c004c5caed8913e5da28d2e50e2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 3 Nov 2022 06:05:23 +0100 Subject: Refactor imports of `triangle` modules in `iced_glow` and `iced_wgpu` --- glow/src/triangle.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'glow/src') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 5d14666c..0e27bcf2 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -2,16 +2,15 @@ mod gradient; mod solid; -use crate::{program, Transformation}; +use crate::program; +use crate::Transformation; use iced_graphics::layer::mesh::{self, Mesh}; -use iced_graphics::triangle; +use iced_graphics::triangle::{self, Vertex2D}; use glow::HasContext; use std::marker::PhantomData; -pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; - #[derive(Debug)] pub(crate) struct Pipeline { vertex_array: ::VertexArray, -- cgit