summaryrefslogtreecommitdiffstats
path: root/glow/src/quad/compatibility.rs
diff options
context:
space:
mode:
Diffstat (limited to 'glow/src/quad/compatibility.rs')
-rw-r--r--glow/src/quad/compatibility.rs349
1 files changed, 0 insertions, 349 deletions
diff --git a/glow/src/quad/compatibility.rs b/glow/src/quad/compatibility.rs
deleted file mode 100644
index e909162c..00000000
--- a/glow/src/quad/compatibility.rs
+++ /dev/null
@@ -1,349 +0,0 @@
-use crate::program::{self, Shader};
-use crate::Transformation;
-use glow::HasContext;
-use iced_graphics::layer;
-use iced_native::Rectangle;
-
-// Only change `MAX_QUADS`, otherwise you could cause problems
-// by splitting a triangle into different render passes.
-const MAX_QUADS: usize = 100_000;
-const MAX_VERTICES: usize = MAX_QUADS * 4;
-const MAX_INDICES: usize = MAX_QUADS * 6;
-
-#[derive(Debug)]
-pub struct Pipeline {
- program: <glow::Context as HasContext>::Program,
- vertex_array: <glow::Context as HasContext>::VertexArray,
- vertex_buffer: <glow::Context as HasContext>::Buffer,
- index_buffer: <glow::Context as HasContext>::Buffer,
- transform_location: <glow::Context as HasContext>::UniformLocation,
- scale_location: <glow::Context as HasContext>::UniformLocation,
- screen_height_location: <glow::Context as HasContext>::UniformLocation,
- current_transform: Transformation,
- current_scale: f32,
- current_target_height: u32,
-}
-
-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/compatibility/quad.vert"),
- );
- let fragment_shader = Shader::fragment(
- gl,
- shader_version,
- include_str!("../shader/compatibility/quad.frag"),
- );
-
- program::create(
- gl,
- &[vertex_shader, fragment_shader],
- &[
- (0, "i_Pos"),
- (1, "i_Scale"),
- (2, "i_Color"),
- (3, "i_BorderColor"),
- (4, "i_BorderRadius"),
- (5, "i_BorderWidth"),
- ],
- )
- };
-
- let transform_location =
- unsafe { gl.get_uniform_location(program, "u_Transform") }
- .expect("Get transform location");
-
- let scale_location =
- unsafe { gl.get_uniform_location(program, "u_Scale") }
- .expect("Get scale location");
-
- let screen_height_location =
- unsafe { gl.get_uniform_location(program, "u_ScreenHeight") }
- .expect("Get target height location");
-
- unsafe {
- gl.use_program(Some(program));
-
- gl.uniform_matrix_4_f32_slice(
- Some(&transform_location),
- false,
- Transformation::identity().as_ref(),
- );
-
- gl.uniform_1_f32(Some(&scale_location), 1.0);
- gl.uniform_1_f32(Some(&screen_height_location), 0.0);
-
- gl.use_program(None);
- }
-
- let (vertex_array, vertex_buffer, index_buffer) =
- unsafe { create_buffers(gl, MAX_VERTICES) };
-
- Pipeline {
- program,
- vertex_array,
- vertex_buffer,
- index_buffer,
- transform_location,
- scale_location,
- screen_height_location,
- current_transform: Transformation::identity(),
- current_scale: 1.0,
- current_target_height: 0,
- }
- }
-
- pub fn draw(
- &mut self,
- gl: &glow::Context,
- target_height: u32,
- instances: &[layer::Quad],
- transformation: Transformation,
- scale: f32,
- bounds: Rectangle<u32>,
- ) {
- // TODO: Remove this allocation (probably by changing the shader and removing the need of two `position`)
- let vertices: Vec<Vertex> =
- instances.iter().flat_map(Vertex::from_quad).collect();
-
- // TODO: Remove this allocation (or allocate only when needed)
- let indices: Vec<i32> = (0..instances.len().min(MAX_QUADS) as i32)
- .flat_map(|i| {
- [i * 4, 1 + i * 4, 2 + i * 4, 2 + i * 4, 1 + i * 4, 3 + i * 4]
- })
- .cycle()
- .take(instances.len() * 6)
- .collect();
-
- unsafe {
- gl.enable(glow::SCISSOR_TEST);
- gl.scissor(
- bounds.x as i32,
- (target_height - (bounds.y + bounds.height)) as i32,
- bounds.width as i32,
- bounds.height as i32,
- );
-
- gl.use_program(Some(self.program));
- gl.bind_vertex_array(Some(self.vertex_array));
- gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vertex_buffer));
- gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.index_buffer));
- }
-
- if transformation != self.current_transform {
- unsafe {
- gl.uniform_matrix_4_f32_slice(
- Some(&self.transform_location),
- false,
- transformation.as_ref(),
- );
-
- self.current_transform = transformation;
- }
- }
-
- if scale != self.current_scale {
- unsafe {
- gl.uniform_1_f32(Some(&self.scale_location), scale);
- }
-
- self.current_scale = scale;
- }
-
- if target_height != self.current_target_height {
- unsafe {
- gl.uniform_1_f32(
- Some(&self.screen_height_location),
- target_height as f32,
- );
- }
-
- self.current_target_height = target_height;
- }
-
- let passes = vertices
- .chunks(MAX_VERTICES)
- .zip(indices.chunks(MAX_INDICES));
-
- for (vertices, indices) in passes {
- unsafe {
- gl.buffer_sub_data_u8_slice(
- glow::ARRAY_BUFFER,
- 0,
- bytemuck::cast_slice(vertices),
- );
-
- gl.buffer_sub_data_u8_slice(
- glow::ELEMENT_ARRAY_BUFFER,
- 0,
- bytemuck::cast_slice(indices),
- );
-
- gl.draw_elements(
- glow::TRIANGLES,
- indices.len() as i32,
- glow::UNSIGNED_INT,
- 0,
- );
- }
- }
-
- unsafe {
- gl.bind_vertex_array(None);
- gl.use_program(None);
- gl.disable(glow::SCISSOR_TEST);
- }
- }
-}
-
-unsafe fn create_buffers(
- gl: &glow::Context,
- size: usize,
-) -> (
- <glow::Context as HasContext>::VertexArray,
- <glow::Context as HasContext>::Buffer,
- <glow::Context as HasContext>::Buffer,
-) {
- let vertex_array = gl.create_vertex_array().expect("Create vertex array");
- let vertex_buffer = gl.create_buffer().expect("Create vertex buffer");
- let index_buffer = gl.create_buffer().expect("Create index buffer");
-
- gl.bind_vertex_array(Some(vertex_array));
-
- gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(index_buffer));
- gl.buffer_data_size(
- glow::ELEMENT_ARRAY_BUFFER,
- 12 * size as i32,
- glow::DYNAMIC_DRAW,
- );
-
- gl.bind_buffer(glow::ARRAY_BUFFER, Some(vertex_buffer));
- gl.buffer_data_size(
- glow::ARRAY_BUFFER,
- (size * Vertex::SIZE) as i32,
- glow::DYNAMIC_DRAW,
- );
-
- let stride = Vertex::SIZE 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, 2, glow::FLOAT, false, stride, 4 * 2);
-
- gl.enable_vertex_attrib_array(2);
- gl.vertex_attrib_pointer_f32(2, 4, glow::FLOAT, false, stride, 4 * (2 + 2));
-
- gl.enable_vertex_attrib_array(3);
- gl.vertex_attrib_pointer_f32(
- 3,
- 4,
- glow::FLOAT,
- false,
- stride,
- 4 * (2 + 2 + 4),
- );
-
- gl.enable_vertex_attrib_array(4);
- gl.vertex_attrib_pointer_f32(
- 4,
- 4,
- glow::FLOAT,
- false,
- stride,
- 4 * (2 + 2 + 4 + 4),
- );
-
- gl.enable_vertex_attrib_array(5);
- gl.vertex_attrib_pointer_f32(
- 5,
- 1,
- glow::FLOAT,
- false,
- stride,
- 4 * (2 + 2 + 4 + 4 + 4),
- );
-
- gl.enable_vertex_attrib_array(6);
- gl.vertex_attrib_pointer_f32(
- 6,
- 2,
- glow::FLOAT,
- false,
- stride,
- 4 * (2 + 2 + 4 + 4 + 4 + 1),
- );
-
- gl.bind_vertex_array(None);
- gl.bind_buffer(glow::ARRAY_BUFFER, None);
- gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
-
- (vertex_array, vertex_buffer, index_buffer)
-}
-
-/// The vertex of a colored rectangle with a border.
-///
-/// This type can be directly uploaded to GPU memory.
-#[derive(Debug, Clone, Copy, bytemuck::Pod, bytemuck::Zeroable)]
-#[repr(C)]
-pub struct Vertex {
- /// The position of the [`Vertex`].
- pub position: [f32; 2],
-
- /// The size of the [`Vertex`].
- pub size: [f32; 2],
-
- /// The color of the [`Vertex`], in __linear RGB__.
- pub color: [f32; 4],
-
- /// The border color of the [`Vertex`], in __linear RGB__.
- pub border_color: [f32; 4],
-
- /// The border radius of the [`Vertex`].
- pub border_radius: [f32; 4],
-
- /// The border width of the [`Vertex`].
- pub border_width: f32,
-
- /// The __quad__ position of the [`Vertex`].
- pub q_position: [f32; 2],
-}
-
-impl Vertex {
- const SIZE: usize = std::mem::size_of::<Self>();
-
- fn from_quad(quad: &layer::Quad) -> [Vertex; 4] {
- let base = Vertex {
- position: quad.position,
- size: quad.size,
- color: quad.color,
- border_color: quad.color,
- border_radius: quad.border_radius,
- border_width: quad.border_width,
- q_position: [0.0, 0.0],
- };
-
- [
- base,
- Self {
- q_position: [0.0, 1.0],
- ..base
- },
- Self {
- q_position: [1.0, 0.0],
- ..base
- },
- Self {
- q_position: [1.0, 1.0],
- ..base
- },
- ]
- }
-}