summaryrefslogtreecommitdiffstats
path: root/glow/src/triangle.rs
diff options
context:
space:
mode:
Diffstat (limited to 'glow/src/triangle.rs')
-rw-r--r--glow/src/triangle.rs595
1 files changed, 0 insertions, 595 deletions
diff --git a/glow/src/triangle.rs b/glow/src/triangle.rs
deleted file mode 100644
index 42c88455..00000000
--- a/glow/src/triangle.rs
+++ /dev/null
@@ -1,595 +0,0 @@
-//! Draw meshes of triangles.
-use crate::program;
-use crate::Transformation;
-
-use iced_graphics::gradient::Gradient;
-use iced_graphics::layer::mesh::{self, Mesh};
-use iced_graphics::triangle::{ColoredVertex2D, Vertex2D};
-
-use glow::HasContext;
-use std::marker::PhantomData;
-
-#[cfg(feature = "tracing")]
-use tracing::info_span;
-
-const DEFAULT_VERTICES: usize = 1_000;
-const DEFAULT_INDICES: usize = 1_000;
-
-#[derive(Debug)]
-pub(crate) struct Pipeline {
- indices: Buffer<u32>,
- solid: solid::Program,
- gradient: gradient::Program,
-}
-
-impl Pipeline {
- pub fn new(gl: &glow::Context, shader_version: &program::Version) -> Self {
- let mut indices = unsafe {
- Buffer::new(
- gl,
- glow::ELEMENT_ARRAY_BUFFER,
- glow::DYNAMIC_DRAW,
- DEFAULT_INDICES,
- )
- };
-
- let solid = solid::Program::new(gl, shader_version);
- let gradient = gradient::Program::new(gl, shader_version);
-
- unsafe {
- gl.bind_vertex_array(Some(solid.vertex_array));
- indices.bind(gl, 0);
-
- gl.bind_vertex_array(Some(gradient.vertex_array));
- indices.bind(gl, 0);
-
- gl.bind_vertex_array(None);
- }
-
- Self {
- indices,
- solid,
- gradient,
- }
- }
-
- pub fn draw(
- &mut self,
- meshes: &[Mesh<'_>],
- gl: &glow::Context,
- target_height: u32,
- transformation: Transformation,
- scale_factor: f32,
- ) {
- #[cfg(feature = "tracing")]
- let _ = info_span!("Glow::Triangle", "DRAW").enter();
-
- unsafe {
- gl.enable(glow::MULTISAMPLE);
- gl.enable(glow::SCISSOR_TEST);
- }
-
- // Count the total amount of vertices & indices we need to handle
- let count = mesh::attribute_count_of(meshes);
-
- // Then we ensure the current attribute buffers are big enough, resizing if necessary
- unsafe {
- self.indices.bind(gl, count.indices);
- }
-
- // We upload all the vertices and indices upfront
- let mut solid_vertex_offset = 0;
- let mut gradient_vertex_offset = 0;
- let mut index_offset = 0;
-
- for mesh in meshes {
- let indices = mesh.indices();
-
- unsafe {
- gl.buffer_sub_data_u8_slice(
- glow::ELEMENT_ARRAY_BUFFER,
- (index_offset * std::mem::size_of::<u32>()) as i32,
- bytemuck::cast_slice(indices),
- );
-
- index_offset += indices.len();
- }
-
- match mesh {
- Mesh::Solid { buffers, .. } => {
- unsafe {
- self.solid.vertices.bind(gl, count.solid_vertices);
-
- gl.buffer_sub_data_u8_slice(
- glow::ARRAY_BUFFER,
- (solid_vertex_offset
- * std::mem::size_of::<ColoredVertex2D>())
- as i32,
- bytemuck::cast_slice(&buffers.vertices),
- );
- }
-
- solid_vertex_offset += buffers.vertices.len();
- }
- Mesh::Gradient { buffers, .. } => {
- unsafe {
- self.gradient
- .vertices
- .bind(gl, count.gradient_vertices);
-
- gl.buffer_sub_data_u8_slice(
- glow::ARRAY_BUFFER,
- (gradient_vertex_offset
- * std::mem::size_of::<Vertex2D>())
- as i32,
- bytemuck::cast_slice(&buffers.vertices),
- );
- }
-
- gradient_vertex_offset += buffers.vertices.len();
- }
- }
- }
-
- // Then we draw each mesh using offsets
- let mut last_solid_vertex = 0;
- let mut last_gradient_vertex = 0;
- let mut last_index = 0;
-
- for mesh in meshes {
- let indices = mesh.indices();
- let origin = mesh.origin();
-
- let transform =
- transformation * Transformation::translate(origin.x, origin.y);
-
- let clip_bounds = (mesh.clip_bounds() * scale_factor).snap();
-
- unsafe {
- 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,
- );
- }
-
- match mesh {
- Mesh::Solid { buffers, .. } => unsafe {
- gl.use_program(Some(self.solid.program));
- gl.bind_vertex_array(Some(self.solid.vertex_array));
-
- if transform != self.solid.uniforms.transform {
- gl.uniform_matrix_4_f32_slice(
- Some(&self.solid.uniforms.transform_location),
- false,
- transform.as_ref(),
- );
-
- self.solid.uniforms.transform = transform;
- }
-
- gl.draw_elements_base_vertex(
- glow::TRIANGLES,
- indices.len() as i32,
- glow::UNSIGNED_INT,
- (last_index * std::mem::size_of::<u32>()) as i32,
- last_solid_vertex as i32,
- );
-
- last_solid_vertex += buffers.vertices.len();
- },
- Mesh::Gradient {
- buffers, gradient, ..
- } => unsafe {
- gl.use_program(Some(self.gradient.program));
- gl.bind_vertex_array(Some(self.gradient.vertex_array));
-
- if transform != self.gradient.uniforms.transform {
- gl.uniform_matrix_4_f32_slice(
- Some(&self.gradient.uniforms.locations.transform),
- false,
- transform.as_ref(),
- );
-
- self.gradient.uniforms.transform = transform;
- }
-
- if &self.gradient.uniforms.gradient != *gradient {
- match gradient {
- Gradient::Linear(linear) => {
- gl.uniform_4_f32(
- Some(
- &self
- .gradient
- .uniforms
- .locations
- .gradient_direction,
- ),
- linear.start.x,
- linear.start.y,
- linear.end.x,
- linear.end.y,
- );
-
- gl.uniform_1_i32(
- Some(
- &self
- .gradient
- .uniforms
- .locations
- .color_stops_size,
- ),
- (linear.color_stops.len() * 2) as i32,
- );
-
- let mut stops = [0.0; 128];
-
- for (index, stop) in linear
- .color_stops
- .iter()
- .enumerate()
- .take(16)
- {
- 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.;
- stops[(index * 8) + 7] = 0.;
- }
-
- gl.uniform_4_f32_slice(
- Some(
- &self
- .gradient
- .uniforms
- .locations
- .color_stops,
- ),
- &stops,
- );
- }
- }
-
- self.gradient.uniforms.gradient = (*gradient).clone();
- }
-
- gl.draw_elements_base_vertex(
- glow::TRIANGLES,
- indices.len() as i32,
- glow::UNSIGNED_INT,
- (last_index * std::mem::size_of::<u32>()) as i32,
- last_gradient_vertex as i32,
- );
-
- last_gradient_vertex += buffers.vertices.len();
- },
- }
-
- last_index += indices.len();
- }
-
- unsafe {
- gl.bind_vertex_array(None);
- gl.disable(glow::SCISSOR_TEST);
- gl.disable(glow::MULTISAMPLE);
- }
- }
-}
-
-#[derive(Debug)]
-pub struct Buffer<T> {
- raw: <glow::Context as HasContext>::Buffer,
- target: u32,
- usage: u32,
- size: usize,
- phantom: PhantomData<T>,
-}
-
-impl<T> Buffer<T> {
- 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::<T>()) as i32,
- self.usage,
- );
-
- self.size = size;
- }
- }
-}
-
-mod solid {
- use crate::program;
- use crate::triangle;
- use glow::{Context, HasContext, NativeProgram};
- use iced_graphics::triangle::ColoredVertex2D;
- use iced_graphics::Transformation;
-
- #[derive(Debug)]
- pub struct Program {
- pub program: <Context as HasContext>::Program,
- pub vertex_array: <glow::Context as HasContext>::VertexArray,
- pub vertices: triangle::Buffer<ColoredVertex2D>,
- pub uniforms: Uniforms,
- }
-
- impl Program {
- pub fn new(gl: &Context, shader_version: &program::Version) -> Self {
- let program = unsafe {
- let vertex_shader = program::Shader::vertex(
- gl,
- shader_version,
- include_str!("shader/common/solid.vert"),
- );
-
- let fragment_shader = program::Shader::fragment(
- gl,
- shader_version,
- include_str!("shader/common/solid.frag"),
- );
-
- program::create(
- gl,
- &[vertex_shader, fragment_shader],
- &[(0, "i_Position"), (1, "i_Color")],
- )
- };
-
- let vertex_array = unsafe {
- gl.create_vertex_array().expect("Create vertex array")
- };
-
- let vertices = unsafe {
- triangle::Buffer::new(
- gl,
- glow::ARRAY_BUFFER,
- glow::DYNAMIC_DRAW,
- super::DEFAULT_VERTICES,
- )
- };
-
- unsafe {
- gl.bind_vertex_array(Some(vertex_array));
-
- let stride = std::mem::size_of::<ColoredVertex2D>() 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);
- };
-
- Self {
- program,
- vertex_array,
- vertices,
- uniforms: Uniforms::new(gl, program),
- }
- }
- }
-
- #[derive(Debug)]
- pub struct Uniforms {
- pub transform: Transformation,
- pub transform_location: <Context as HasContext>::UniformLocation,
- }
-
- impl Uniforms {
- fn new(gl: &Context, program: NativeProgram) -> Self {
- let transform = Transformation::identity();
- let transform_location =
- unsafe { gl.get_uniform_location(program, "u_Transform") }
- .expect("Solid - Get u_Transform.");
-
- unsafe {
- gl.use_program(Some(program));
-
- gl.uniform_matrix_4_f32_slice(
- Some(&transform_location),
- false,
- transform.as_ref(),
- );
-
- gl.use_program(None);
- }
-
- Self {
- transform,
- transform_location,
- }
- }
- }
-}
-
-mod gradient {
- use crate::program;
- use crate::triangle;
- use glow::{Context, HasContext, NativeProgram};
- use iced_graphics::gradient::{self, Gradient};
- use iced_graphics::triangle::Vertex2D;
- use iced_graphics::Transformation;
-
- #[derive(Debug)]
- pub struct Program {
- pub program: <Context as HasContext>::Program,
- pub vertex_array: <glow::Context as HasContext>::VertexArray,
- pub vertices: triangle::Buffer<Vertex2D>,
- pub uniforms: Uniforms,
- }
-
- impl Program {
- pub fn new(gl: &Context, shader_version: &program::Version) -> Self {
- let program = unsafe {
- let vertex_shader = program::Shader::vertex(
- gl,
- shader_version,
- include_str!("shader/common/gradient.vert"),
- );
-
- let fragment_shader = program::Shader::fragment(
- gl,
- shader_version,
- include_str!("shader/common/gradient.frag"),
- );
-
- program::create(
- gl,
- &[vertex_shader, fragment_shader],
- &[(0, "i_Position")],
- )
- };
-
- let vertex_array = unsafe {
- gl.create_vertex_array().expect("Create vertex array")
- };
-
- let vertices = unsafe {
- triangle::Buffer::new(
- gl,
- glow::ARRAY_BUFFER,
- glow::DYNAMIC_DRAW,
- super::DEFAULT_VERTICES,
- )
- };
-
- unsafe {
- gl.bind_vertex_array(Some(vertex_array));
-
- let stride = std::mem::size_of::<Vertex2D>() as i32;
-
- gl.enable_vertex_attrib_array(0);
- gl.vertex_attrib_pointer_f32(
- 0,
- 2,
- glow::FLOAT,
- false,
- stride,
- 0,
- );
-
- gl.bind_vertex_array(None);
- };
-
- Self {
- program,
- vertex_array,
- vertices,
- uniforms: Uniforms::new(gl, program),
- }
- }
- }
-
- #[derive(Debug)]
- pub struct Uniforms {
- pub gradient: Gradient,
- pub transform: Transformation,
- pub locations: Locations,
- }
-
- #[derive(Debug)]
- pub struct Locations {
- pub gradient_direction: <Context as HasContext>::UniformLocation,
- pub color_stops_size: <Context as HasContext>::UniformLocation,
- //currently the maximum number of stops is 16 due to lack of SSBO in GL2.1
- pub color_stops: <Context as HasContext>::UniformLocation,
- pub transform: <Context as HasContext>::UniformLocation,
- }
-
- impl Uniforms {
- fn new(gl: &Context, program: NativeProgram) -> Self {
- let gradient_direction = unsafe {
- gl.get_uniform_location(program, "gradient_direction")
- }
- .expect("Gradient - Get gradient_direction.");
-
- let color_stops_size =
- unsafe { gl.get_uniform_location(program, "color_stops_size") }
- .expect("Gradient - Get color_stops_size.");
-
- let color_stops = unsafe {
- gl.get_uniform_location(program, "color_stops")
- .expect("Gradient - Get color_stops.")
- };
-
- let transform = Transformation::identity();
- let transform_location =
- unsafe { gl.get_uniform_location(program, "u_Transform") }
- .expect("Solid - Get u_Transform.");
-
- unsafe {
- gl.use_program(Some(program));
-
- gl.uniform_matrix_4_f32_slice(
- Some(&transform_location),
- false,
- transform.as_ref(),
- );
-
- gl.use_program(None);
- }
-
- Self {
- gradient: Gradient::Linear(gradient::Linear {
- start: Default::default(),
- end: Default::default(),
- color_stops: vec![],
- }),
- transform: Transformation::identity(),
- locations: Locations {
- gradient_direction,
- color_stops_size,
- color_stops,
- transform: transform_location,
- },
- }
- }
- }
-}