From d4743183d40c6044ce6fa39e2a52919a32912cda Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 19 May 2020 14:23:28 +0200 Subject: Draft first working version of `iced_glow` :tada: --- glow/src/triangle.rs | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 glow/src/triangle.rs (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs new file mode 100644 index 00000000..f71022d0 --- /dev/null +++ b/glow/src/triangle.rs @@ -0,0 +1,84 @@ +//! Draw meshes of triangles. +use crate::{settings, Transformation}; +use iced_native::{Rectangle, Vector}; +use std::mem; + +const UNIFORM_BUFFER_SIZE: usize = 100; +const VERTEX_BUFFER_SIZE: usize = 10_000; +const INDEX_BUFFER_SIZE: usize = 10_000; + +#[derive(Debug)] +pub(crate) struct Pipeline {} + +impl Pipeline { + pub fn new( + gl: &glow::Context, + antialiasing: Option, + ) -> Pipeline { + Pipeline {} + } + + pub fn draw( + &mut self, + gl: &glow::Context, + target_width: u32, + target_height: u32, + transformation: Transformation, + scale_factor: f32, + meshes: &[(Vector, Rectangle, &Mesh2D)], + ) { + } +} + +#[repr(C)] +#[derive(Debug, Clone, Copy)] +struct Uniforms { + transform: [f32; 16], + // We need to align this to 256 bytes to please `wgpu`... + // TODO: Be smarter and stop wasting memory! + _padding_a: [f32; 32], + _padding_b: [f32; 16], +} + +impl Default for Uniforms { + fn default() -> Self { + Self { + transform: *Transformation::identity().as_ref(), + _padding_a: [0.0; 32], + _padding_b: [0.0; 16], + } + } +} + +impl From for Uniforms { + fn from(transformation: Transformation) -> Uniforms { + Self { + transform: transformation.into(), + _padding_a: [0.0; 32], + _padding_b: [0.0; 16], + } + } +} + +/// A two-dimensional vertex with some color in __linear__ RGBA. +#[repr(C)] +#[derive(Copy, Clone, Debug)] +pub struct Vertex2D { + /// The vertex position + pub position: [f32; 2], + /// The vertex color in __linear__ RGBA. + pub color: [f32; 4], +} + +/// A set of [`Vertex2D`] and indices representing a list of triangles. +/// +/// [`Vertex2D`]: struct.Vertex2D.html +#[derive(Clone, Debug)] +pub struct Mesh2D { + /// The vertices of the mesh + pub vertices: Vec, + /// The list of vertex indices that defines the triangles of the mesh. + /// + /// Therefore, this list should always have a length that is a multiple of 3. + pub indices: Vec, +} -- cgit From 05af8d00d4c0f7b8e0ece85224fd90a92da86da8 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 19 May 2020 17:15:44 +0200 Subject: Draft new `iced_graphics` crate :tada: --- glow/src/triangle.rs | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f71022d0..8b21c0a8 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -3,6 +3,8 @@ use crate::{settings, Transformation}; use iced_native::{Rectangle, Vector}; use std::mem; +pub use iced_graphics::triangle::Mesh2D; + const UNIFORM_BUFFER_SIZE: usize = 100; const VERTEX_BUFFER_SIZE: usize = 10_000; const INDEX_BUFFER_SIZE: usize = 10_000; @@ -59,26 +61,3 @@ impl From for Uniforms { } } } - -/// A two-dimensional vertex with some color in __linear__ RGBA. -#[repr(C)] -#[derive(Copy, Clone, Debug)] -pub struct Vertex2D { - /// The vertex position - pub position: [f32; 2], - /// The vertex color in __linear__ RGBA. - pub color: [f32; 4], -} - -/// A set of [`Vertex2D`] and indices representing a list of triangles. -/// -/// [`Vertex2D`]: struct.Vertex2D.html -#[derive(Clone, Debug)] -pub struct Mesh2D { - /// The vertices of the mesh - pub vertices: Vec, - /// The list of vertex indices that defines the triangles of the mesh. - /// - /// Therefore, this list should always have a length that is a multiple of 3. - pub indices: Vec, -} -- cgit From 720e7756f2afe30706b6b1a7fbde86b9f15e1d8c Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Tue, 19 May 2020 22:55:12 +0200 Subject: Move `Layer` to `iced_graphics` --- glow/src/triangle.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 8b21c0a8..5836f0cf 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,7 +1,6 @@ //! Draw meshes of triangles. use crate::{settings, Transformation}; -use iced_native::{Rectangle, Vector}; -use std::mem; +use iced_graphics::layer; pub use iced_graphics::triangle::Mesh2D; @@ -27,7 +26,7 @@ impl Pipeline { target_height: u32, transformation: Transformation, scale_factor: f32, - meshes: &[(Vector, Rectangle, &Mesh2D)], + meshes: &[layer::Mesh<'_>], ) { } } -- cgit From 60dcfc354e844757d2291bf44cb21c624bc270c2 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 May 2020 19:07:33 +0200 Subject: Draft `triangle` pipeline in `iced_glow` --- glow/src/triangle.rs | 251 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 238 insertions(+), 13 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 5836f0cf..3f4aaa1b 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,22 +1,106 @@ //! Draw meshes of triangles. -use crate::{settings, Transformation}; +use crate::program; +use crate::settings; +use crate::Transformation; +use glow::HasContext; use iced_graphics::layer; +use std::marker::PhantomData; -pub use iced_graphics::triangle::Mesh2D; +pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; -const UNIFORM_BUFFER_SIZE: usize = 100; const VERTEX_BUFFER_SIZE: usize = 10_000; const INDEX_BUFFER_SIZE: usize = 10_000; #[derive(Debug)] -pub(crate) struct Pipeline {} +pub(crate) struct Pipeline { + program: ::Program, + vertex_array: ::VertexArray, + vertices: Buffer, + indices: Buffer, + current_transform: Transformation, +} impl Pipeline { pub fn new( gl: &glow::Context, antialiasing: Option, ) -> Pipeline { - Pipeline {} + let program = unsafe { + program::create( + gl, + &[ + (glow::VERTEX_SHADER, include_str!("shader/triangle.vert")), + ( + glow::FRAGMENT_SHADER, + include_str!("shader/triangle.frag"), + ), + ], + ) + }; + + unsafe { + gl.use_program(Some(program)); + + gl.uniform_matrix_4_f32_slice( + Some(0), + false, + &Transformation::identity().into(), + ); + + gl.use_program(None); + } + + let vertex_array = + unsafe { gl.create_vertex_array().expect("Create vertex array") }; + + unsafe { + gl.bind_vertex_array(Some(vertex_array)); + } + + let vertices = unsafe { + Buffer::new( + gl, + glow::ARRAY_BUFFER, + glow::DYNAMIC_DRAW, + VERTEX_BUFFER_SIZE, + ) + }; + + let indices = unsafe { + Buffer::new( + gl, + glow::ELEMENT_ARRAY_BUFFER, + glow::DYNAMIC_DRAW, + INDEX_BUFFER_SIZE, + ) + }; + + unsafe { + let stride = std::mem::size_of::() as i32; + + 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, + vertex_array, + vertices, + indices, + current_transform: Transformation::identity(), + } } pub fn draw( @@ -28,6 +112,106 @@ impl Pipeline { scale_factor: f32, meshes: &[layer::Mesh<'_>], ) { + unsafe { + gl.enable(glow::SCISSOR_TEST); + gl.use_program(Some(self.program)); + 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 + unsafe { + self.vertices.bind(gl, total_vertices); + self.indices.bind(gl, total_indices); + } + + // We upload all the vertices and indices upfront + let mut last_vertex = 0; + let mut last_index = 0; + + for layer::Mesh { buffers, .. } 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), + ); + + gl.buffer_sub_data_u8_slice( + glow::ELEMENT_ARRAY_BUFFER, + (last_index * std::mem::size_of::()) as i32, + bytemuck::cast_slice(&buffers.indices), + ); + + last_vertex += buffers.vertices.len(); + last_index += buffers.indices.len(); + } + } + + // Then we draw each mesh using offsets + let mut last_vertex = 0; + let mut last_index = 0; + + for layer::Mesh { + buffers, + origin, + clip_bounds, + } in meshes + { + let transform = + transformation * Transformation::translate(origin.x, origin.y); + + let clip_bounds = (*clip_bounds * scale_factor).round(); + + unsafe { + if self.current_transform != transform { + gl.uniform_matrix_4_f32_slice( + Some(0), + false, + &transform.into(), + ); + + self.current_transform = transform; + } + + gl.scissor( + clip_bounds.x as i32, + (target_height - (clip_bounds.y + clip_bounds.height)) + as i32, + clip_bounds.width as i32, + clip_bounds.height as i32, + ); + + gl.draw_elements_base_vertex( + glow::TRIANGLES, + 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(); + } + } + + unsafe { + gl.bind_vertex_array(None); + gl.use_program(None); + gl.disable(glow::SCISSOR_TEST); + } } } @@ -35,18 +219,15 @@ impl Pipeline { #[derive(Debug, Clone, Copy)] struct Uniforms { transform: [f32; 16], - // We need to align this to 256 bytes to please `wgpu`... - // TODO: Be smarter and stop wasting memory! - _padding_a: [f32; 32], - _padding_b: [f32; 16], } +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(), - _padding_a: [0.0; 32], - _padding_b: [0.0; 16], } } } @@ -55,8 +236,52 @@ impl From for Uniforms { fn from(transformation: Transformation) -> Uniforms { Self { transform: transformation.into(), - _padding_a: [0.0; 32], - _padding_b: [0.0; 16], + } + } +} + +#[derive(Debug)] +struct Buffer { + raw: ::Buffer, + target: u32, + usage: u32, + size: usize, + phantom: PhantomData, +} + +impl Buffer { + pub unsafe fn new( + gl: &glow::Context, + target: u32, + usage: u32, + size: usize, + ) -> Self { + let raw = gl.create_buffer().expect("Create buffer"); + + let mut buffer = Buffer { + raw, + target, + usage, + size: 0, + phantom: PhantomData, + }; + + buffer.bind(gl, size); + + buffer + } + + pub unsafe fn bind(&mut self, gl: &glow::Context, size: usize) { + gl.bind_buffer(self.target, Some(self.raw)); + + if self.size < size { + gl.buffer_data_size( + self.target, + (size * std::mem::size_of::()) as i32, + self.usage, + ); + + self.size = size; } } } -- cgit From bbfb1c040c92e36b3d23a2167ad3432c819b9668 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Thu, 21 May 2020 19:50:53 +0200 Subject: Update to latest `glow` --- glow/src/triangle.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 3f4aaa1b..489ceaff 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -41,11 +41,8 @@ impl Pipeline { unsafe { gl.use_program(Some(program)); - gl.uniform_matrix_4_f32_slice( - Some(0), - false, - &Transformation::identity().into(), - ); + let transform: [f32; 16] = Transformation::identity().into(); + gl.uniform_matrix_4_f32_slice(Some(&0), false, &transform); gl.use_program(None); } @@ -177,11 +174,8 @@ impl Pipeline { unsafe { if self.current_transform != transform { - gl.uniform_matrix_4_f32_slice( - Some(0), - false, - &transform.into(), - ); + let matrix: [f32; 16] = transform.into(); + gl.uniform_matrix_4_f32_slice(Some(&0), false, &matrix); self.current_transform = transform; } -- cgit From c5545c7a7306b5312007ffa74a014db4992ff5f4 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 May 2020 01:14:31 +0200 Subject: Implement MSAA for triangle meshes in `iced_glow` --- glow/src/triangle.rs | 236 ++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 195 insertions(+), 41 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 489ceaff..f350db98 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -4,6 +4,7 @@ use crate::settings; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; +use iced_graphics::Size; use std::marker::PhantomData; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; @@ -18,6 +19,7 @@ pub(crate) struct Pipeline { vertices: Buffer, indices: Buffer, current_transform: Transformation, + antialias: Antialias, } impl Pipeline { @@ -97,6 +99,7 @@ impl Pipeline { vertices, indices, current_transform: Transformation::identity(), + antialias: Antialias::new(antialiasing), } } @@ -157,49 +160,57 @@ impl Pipeline { } } - // Then we draw each mesh using offsets - let mut last_vertex = 0; - let mut last_index = 0; - - for layer::Mesh { - buffers, - origin, - clip_bounds, - } in meshes - { - let transform = - transformation * Transformation::translate(origin.x, origin.y); - - let clip_bounds = (*clip_bounds * scale_factor).round(); - - unsafe { - if self.current_transform != transform { - let matrix: [f32; 16] = transform.into(); - gl.uniform_matrix_4_f32_slice(Some(&0), false, &matrix); - - self.current_transform = transform; + let Self { + antialias, + current_transform, + .. + } = self; + + // Then we draw each mesh using offsets with antialiasing + antialias.perform(gl, Size::new(target_width, target_height), |gl| { + let mut last_vertex = 0; + let mut last_index = 0; + + for layer::Mesh { + buffers, + origin, + clip_bounds, + } in meshes + { + let transform = transformation + * Transformation::translate(origin.x, origin.y); + + let clip_bounds = (*clip_bounds * scale_factor).round(); + + unsafe { + if *current_transform != transform { + let matrix: [f32; 16] = transform.into(); + gl.uniform_matrix_4_f32_slice(Some(&0), false, &matrix); + + *current_transform = transform; + } + + gl.scissor( + clip_bounds.x as i32, + (target_height - (clip_bounds.y + clip_bounds.height)) + as i32, + clip_bounds.width as i32, + clip_bounds.height as i32, + ); + + gl.draw_elements_base_vertex( + glow::TRIANGLES, + 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(); } - - gl.scissor( - clip_bounds.x as i32, - (target_height - (clip_bounds.y + clip_bounds.height)) - as i32, - clip_bounds.width as i32, - clip_bounds.height as i32, - ); - - gl.draw_elements_base_vertex( - glow::TRIANGLES, - 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(); } - } + }); unsafe { gl.bind_vertex_array(None); @@ -279,3 +290,146 @@ impl Buffer { } } } + +#[derive(Debug)] +pub struct Antialias { + renderbuffer: Option, + sample_count: u32, +} + +impl Antialias { + fn new(antialiasing: Option) -> Self { + Antialias { + renderbuffer: None, + sample_count: antialiasing + .map(settings::Antialiasing::sample_count) + .unwrap_or(1), + } + } + + fn perform( + &mut self, + gl: &glow::Context, + size: Size, + f: impl FnOnce(&glow::Context), + ) { + if self.sample_count == 1 { + return f(gl); + } + + let target = glow::DRAW_FRAMEBUFFER; + + let renderbuffer = if let Some(renderbuffer) = self.renderbuffer.take() + { + if size == renderbuffer.size { + renderbuffer + } else { + renderbuffer.destroy(gl); + + Renderbuffer::new(gl, target, self.sample_count, size) + } + } else { + Renderbuffer::new(gl, target, self.sample_count, size) + }; + + renderbuffer.bind(gl, target); + + unsafe { + gl.clear_color(0.0, 0.0, 0.0, 0.0); + gl.clear(glow::COLOR_BUFFER_BIT); + } + + f(gl); + + unsafe { + gl.bind_framebuffer(target, None); + gl.clear_color(1.0, 1.0, 1.0, 1.0); + } + + renderbuffer.blit(gl); + + self.renderbuffer = Some(renderbuffer); + } +} + +#[derive(Debug)] +pub struct Renderbuffer { + raw: ::Renderbuffer, + framebuffer: ::Framebuffer, + size: Size, +} + +impl Renderbuffer { + fn new( + gl: &glow::Context, + target: u32, + sample_count: u32, + size: Size, + ) -> Self { + let framebuffer = unsafe { + gl.create_framebuffer().expect("Create MSAA framebuffer") + }; + + let raw = unsafe { + gl.create_renderbuffer().expect("Create MSAA renderbuffer") + }; + + unsafe { + gl.bind_renderbuffer(glow::RENDERBUFFER, Some(raw)); + gl.renderbuffer_storage_multisample( + glow::RENDERBUFFER, + sample_count as i32, + glow::SRGB8_ALPHA8, + size.width as i32, + size.height as i32, + ); + + gl.bind_framebuffer(target, Some(framebuffer)); + gl.framebuffer_renderbuffer( + target, + glow::COLOR_ATTACHMENT0, + glow::RENDERBUFFER, + Some(raw), + ); + gl.bind_framebuffer(target, None); + } + + Self { + raw, + framebuffer, + size, + } + } + + fn bind(&self, gl: &glow::Context, target: u32) { + unsafe { + gl.bind_framebuffer(target, Some(self.framebuffer)); + } + } + + fn blit(&self, gl: &glow::Context) { + unsafe { + self.bind(gl, glow::READ_FRAMEBUFFER); + + gl.blit_framebuffer( + 0, + 0, + self.size.width as i32, + self.size.height as i32, + 0, + 0, + self.size.width as i32, + self.size.height as i32, + glow::COLOR_BUFFER_BIT, + glow::NEAREST, + ); + } + } + + fn destroy(self, gl: &glow::Context) { + unsafe { + gl.delete_renderbuffer(self.raw); + gl.delete_framebuffer(self.framebuffer); + } + } +} -- cgit From 6f71a8e3d5e47ab05653315b0d44b35af6a20338 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 May 2020 05:52:11 +0200 Subject: Use `get_uniform_location` for wider compatibility --- glow/src/triangle.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index f350db98..8bafa9c6 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -18,6 +18,7 @@ pub(crate) struct Pipeline { vertex_array: ::VertexArray, vertices: Buffer, indices: Buffer, + transform_location: ::UniformLocation, current_transform: Transformation, antialias: Antialias, } @@ -40,11 +41,19 @@ impl Pipeline { ) }; + 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(&0), false, &transform); + gl.uniform_matrix_4_f32_slice( + Some(&transform_location), + false, + &transform, + ); gl.use_program(None); } @@ -98,6 +107,7 @@ impl Pipeline { vertex_array, vertices, indices, + transform_location, current_transform: Transformation::identity(), antialias: Antialias::new(antialiasing), } @@ -163,6 +173,7 @@ impl Pipeline { let Self { antialias, current_transform, + transform_location, .. } = self; @@ -185,7 +196,11 @@ impl Pipeline { unsafe { if *current_transform != transform { let matrix: [f32; 16] = transform.into(); - gl.uniform_matrix_4_f32_slice(Some(&0), false, &matrix); + gl.uniform_matrix_4_f32_slice( + Some(transform_location), + false, + &matrix, + ); *current_transform = transform; } -- cgit From 1dd79c4697ce39589bea84142334b3cbd242fb59 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 May 2020 19:15:39 +0200 Subject: Use built-in OpenGL multisampling in `iced_glow` --- glow/src/triangle.rs | 248 ++++++++++----------------------------------------- 1 file changed, 45 insertions(+), 203 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 8bafa9c6..325359de 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -1,10 +1,8 @@ //! Draw meshes of triangles. use crate::program; -use crate::settings; use crate::Transformation; use glow::HasContext; use iced_graphics::layer; -use iced_graphics::Size; use std::marker::PhantomData; pub use iced_graphics::triangle::{Mesh2D, Vertex2D}; @@ -20,14 +18,10 @@ pub(crate) struct Pipeline { indices: Buffer, transform_location: ::UniformLocation, current_transform: Transformation, - antialias: Antialias, } impl Pipeline { - pub fn new( - gl: &glow::Context, - antialiasing: Option, - ) -> Pipeline { + pub fn new(gl: &glow::Context) -> Pipeline { let program = unsafe { program::create( gl, @@ -109,20 +103,19 @@ impl Pipeline { indices, transform_location, current_transform: Transformation::identity(), - antialias: Antialias::new(antialiasing), } } pub fn draw( &mut self, gl: &glow::Context, - target_width: u32, 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)); @@ -170,67 +163,59 @@ impl Pipeline { } } - let Self { - antialias, - current_transform, - transform_location, - .. - } = self; - - // Then we draw each mesh using offsets with antialiasing - antialias.perform(gl, Size::new(target_width, target_height), |gl| { - let mut last_vertex = 0; - let mut last_index = 0; - - for layer::Mesh { - buffers, - origin, - clip_bounds, - } in meshes - { - let transform = transformation - * Transformation::translate(origin.x, origin.y); - - let clip_bounds = (*clip_bounds * scale_factor).round(); - - unsafe { - if *current_transform != transform { - let matrix: [f32; 16] = transform.into(); - gl.uniform_matrix_4_f32_slice( - Some(transform_location), - false, - &matrix, - ); - - *current_transform = transform; - } - - gl.scissor( - clip_bounds.x as i32, - (target_height - (clip_bounds.y + clip_bounds.height)) - as i32, - clip_bounds.width as i32, - clip_bounds.height as i32, - ); + // Then we draw each mesh using offsets + let mut last_vertex = 0; + let mut last_index = 0; - gl.draw_elements_base_vertex( - glow::TRIANGLES, - buffers.indices.len() as i32, - glow::UNSIGNED_INT, - (last_index * std::mem::size_of::()) as i32, - last_vertex as i32, + for layer::Mesh { + buffers, + origin, + clip_bounds, + } in meshes + { + let transform = + transformation * Transformation::translate(origin.x, origin.y); + + let clip_bounds = (*clip_bounds * scale_factor).round(); + + unsafe { + if self.current_transform != transform { + let matrix: [f32; 16] = transform.into(); + gl.uniform_matrix_4_f32_slice( + Some(&self.transform_location), + false, + &matrix, ); - last_vertex += buffers.vertices.len(); - last_index += buffers.indices.len(); + self.current_transform = transform; } + + gl.scissor( + clip_bounds.x as i32, + (target_height - (clip_bounds.y + clip_bounds.height)) + as i32, + clip_bounds.width as i32, + clip_bounds.height as i32, + ); + + gl.draw_elements_base_vertex( + glow::TRIANGLES, + 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(); } - }); + } unsafe { gl.bind_vertex_array(None); gl.use_program(None); gl.disable(glow::SCISSOR_TEST); + gl.disable(glow::MULTISAMPLE); } } } @@ -305,146 +290,3 @@ impl Buffer { } } } - -#[derive(Debug)] -pub struct Antialias { - renderbuffer: Option, - sample_count: u32, -} - -impl Antialias { - fn new(antialiasing: Option) -> Self { - Antialias { - renderbuffer: None, - sample_count: antialiasing - .map(settings::Antialiasing::sample_count) - .unwrap_or(1), - } - } - - fn perform( - &mut self, - gl: &glow::Context, - size: Size, - f: impl FnOnce(&glow::Context), - ) { - if self.sample_count == 1 { - return f(gl); - } - - let target = glow::DRAW_FRAMEBUFFER; - - let renderbuffer = if let Some(renderbuffer) = self.renderbuffer.take() - { - if size == renderbuffer.size { - renderbuffer - } else { - renderbuffer.destroy(gl); - - Renderbuffer::new(gl, target, self.sample_count, size) - } - } else { - Renderbuffer::new(gl, target, self.sample_count, size) - }; - - renderbuffer.bind(gl, target); - - unsafe { - gl.clear_color(0.0, 0.0, 0.0, 0.0); - gl.clear(glow::COLOR_BUFFER_BIT); - } - - f(gl); - - unsafe { - gl.bind_framebuffer(target, None); - gl.clear_color(1.0, 1.0, 1.0, 1.0); - } - - renderbuffer.blit(gl); - - self.renderbuffer = Some(renderbuffer); - } -} - -#[derive(Debug)] -pub struct Renderbuffer { - raw: ::Renderbuffer, - framebuffer: ::Framebuffer, - size: Size, -} - -impl Renderbuffer { - fn new( - gl: &glow::Context, - target: u32, - sample_count: u32, - size: Size, - ) -> Self { - let framebuffer = unsafe { - gl.create_framebuffer().expect("Create MSAA framebuffer") - }; - - let raw = unsafe { - gl.create_renderbuffer().expect("Create MSAA renderbuffer") - }; - - unsafe { - gl.bind_renderbuffer(glow::RENDERBUFFER, Some(raw)); - gl.renderbuffer_storage_multisample( - glow::RENDERBUFFER, - sample_count as i32, - glow::SRGB8_ALPHA8, - size.width as i32, - size.height as i32, - ); - - gl.bind_framebuffer(target, Some(framebuffer)); - gl.framebuffer_renderbuffer( - target, - glow::COLOR_ATTACHMENT0, - glow::RENDERBUFFER, - Some(raw), - ); - gl.bind_framebuffer(target, None); - } - - Self { - raw, - framebuffer, - size, - } - } - - fn bind(&self, gl: &glow::Context, target: u32) { - unsafe { - gl.bind_framebuffer(target, Some(self.framebuffer)); - } - } - - fn blit(&self, gl: &glow::Context) { - unsafe { - self.bind(gl, glow::READ_FRAMEBUFFER); - - gl.blit_framebuffer( - 0, - 0, - self.size.width as i32, - self.size.height as i32, - 0, - 0, - self.size.width as i32, - self.size.height as i32, - glow::COLOR_BUFFER_BIT, - glow::NEAREST, - ); - } - } - - fn destroy(self, gl: &glow::Context) { - unsafe { - gl.delete_renderbuffer(self.raw); - gl.delete_framebuffer(self.framebuffer); - } - } -} -- cgit From d6bf8955dbca03898e379aae376d91677bb4d223 Mon Sep 17 00:00:00 2001 From: Héctor Ramón Jiménez Date: Fri, 22 May 2020 19:17:07 +0200 Subject: Use published `glow` and `glow_glyph` versions --- glow/src/triangle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'glow/src/triangle.rs') diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs index 325359de..ee7faf83 100644 --- a/glow/src/triangle.rs +++ b/glow/src/triangle.rs @@ -44,7 +44,7 @@ impl Pipeline { let transform: [f32; 16] = Transformation::identity().into(); gl.uniform_matrix_4_f32_slice( - Some(&transform_location), + Some(transform_location), false, &transform, ); @@ -182,7 +182,7 @@ impl Pipeline { if self.current_transform != transform { let matrix: [f32; 16] = transform.into(); gl.uniform_matrix_4_f32_slice( - Some(&self.transform_location), + Some(self.transform_location), false, &matrix, ); -- cgit