From 480888e8fc9f869d22c4e11d7b0b523daf43a585 Mon Sep 17 00:00:00 2001 From: Tsuki Date: Wed, 21 Aug 2024 00:03:35 +0800 Subject: [PATCH] pusher --- Cargo.lock | 1 + Cargo.toml | 2 +- src/graphics/collections/agg_fast_path.rs | 206 +++++--------- src/graphics/font/mod.rs | 111 +++++--- src/graphics/font/text_items.rs | 44 +-- src/graphics/ppi.rs | 3 +- src/pg/layout_type.rs | 4 + src/pg/mod.rs | 15 +- src/pg/modules/mod.rs | 36 ++- src/pg/modules/ppi.rs | 331 +++++++++++++++++----- src/shaders/agg_path.rs | 126 ++++++++ src/shaders/font.rs | 216 ++++++++++++++ src/shaders/mod.rs | 2 + src/shaders/trackball.rs | 40 +++ src/ui/typ/main_load.rs | 7 +- 15 files changed, 852 insertions(+), 292 deletions(-) create mode 100644 src/shaders/agg_path.rs create mode 100644 src/shaders/font.rs diff --git a/Cargo.lock b/Cargo.lock index 728b032..12bd831 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1182,6 +1182,7 @@ dependencies = [ "cfg-if", "chlorine", "mint", + "pkg-config", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 3e6123c..96f41eb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ glow = "0.13.1" glutin = "0.31.3" glutin-winit = "0.4.2" image = "0.25.2" -imgui = {version="0.12.0",features = ["tables-api"]} +imgui = {version="0.12.0",features = ["tables-api", "freetype"]} imgui-glow-renderer = "0.12.0" imgui-winit-support = "0.12.0" include_dir = "0.7.4" diff --git a/src/graphics/collections/agg_fast_path.rs b/src/graphics/collections/agg_fast_path.rs index 11e2f39..942283d 100644 --- a/src/graphics/collections/agg_fast_path.rs +++ b/src/graphics/collections/agg_fast_path.rs @@ -8,77 +8,42 @@ use crate::errors::*; use crate::graphics::transforms::viewport::Viewport; use crate::graphics::ty::Ty; use crate::graphics::{AttaWithBuffer, Config, Graphics}; +use crate::shaders::agg_path::{AggPathFragment, AggPathVertex}; use super::Colletion; pub struct AggFastPath { program: Program, - buffer: Vec, - indice: Vec<[u32; 3]>, +} - vao: Option, - vbo: Option, - ebo: Option, +pub struct AggFastPathConfig { + pub color: [f32; 4], + pub linewidth: f32, + pub antialias: f32, } impl AggFastPath { pub fn new() -> Result { let vertex = Shader::new( glow::VERTEX_SHADER, - CodeType::from_path("agg-fast-path.vert"), + CodeType::from_piece(AggPathVertex::new()), )?; let fragment = Shader::new( glow::FRAGMENT_SHADER, - CodeType::from_path("agg-fast-path.frag"), + CodeType::from_piece(AggPathFragment::new()), )?; - let input_snippet = Snippet::new( - "input", - CodeType::from_code( - " - layout(location = 0) in vec3 prev; - layout(location = 1) in vec3 curr; - layout(location = 2) in vec3 next; - layout(location = 3) in float id; - - uniform float linewidth; - - uniform float antialias; - - uniform vec4 color; - - ", - ), - false, - None, - )?; - - let vertex = vertex.add_snippet_before(input_snippet); - let program = Program::new(vertex, fragment, None, "330 core"); - // program.set_transform(transform); - // program.set_viewport(viewport); - - Ok(Self { - program, - buffer: Vec::with_capacity(128), - indice: Vec::with_capacity(128 * 2), - ebo: None, - vao: None, - vbo: None, - }) + Ok(Self { program }) } - #[cfg(feature = "inparser")] - pub fn set_transform(&mut self, transform: &T) { - self.program.set_transform(transform); - } - - #[cfg(feature = "inparser")] - pub fn set_viewport(&mut self, viewport: &Viewport) { - self.program.set_viewport(viewport); + pub fn set_viewport(&mut self, gl: &glow::Context, viewport: [f32; 2]) { + let loc = self.program.get_uniform_location(gl, "viewport"); + unsafe { + gl.uniform_2_f32(loc.as_ref(), viewport[0], viewport[1]); + } } pub fn set_linecolor(&mut self, gl: &glow::Context, color: [f32; 4]) { @@ -89,7 +54,7 @@ impl AggFastPath { } pub fn set_linewidth(&mut self, gl: &glow::Context, linewidth: f32) { - let loc = self.program.get_uniform_location(gl, "linewidth"); + let loc = self.program.get_uniform_location(gl, "thickness"); unsafe { gl.uniform_1_f32(loc.as_ref(), linewidth); } @@ -102,6 +67,12 @@ impl AggFastPath { } } + pub fn set_config(&mut self, gl: &glow::Context, config: &AggFastPathConfig) { + self.set_linecolor(gl, config.color); + self.set_linewidth(gl, config.linewidth); + self.set_anatialias(gl, config.antialias); + } + pub fn program(&mut self) -> &mut Program { &mut self.program } @@ -109,102 +80,24 @@ impl AggFastPath { pub fn program_ref(&self) -> &Program { &self.program } - - fn init(&mut self, gl: &glow::Context) { - self.set_anatialias(gl, 0.005); - self.set_linecolor(gl, [1.0, 1.0, 1.0, 1.0]); - self.set_linewidth(gl, 0.02); - } -} - -impl Colletion for AggFastPath { - type Item = Path; - - fn append(&mut self, item: Self::Item) { - self.buffer.extend(item.points); - self.indice.extend(item.ebo); - } } impl Graphics for AggFastPath { const id: &'static str = "AggPath"; - type Config = (); + type Config = AggFastPathConfig; fn compile(&mut self, gl: &glow::Context) -> Result<()> { - use bytemuck::cast_slice; - self.program.compile(gl)?; - - unsafe { - let vao = gl.create_vertex_array().unwrap(); - - gl.bind_vertex_array(Some(vao)); - for p in self.buffer.iter() { - println!("{}", p); - } - println!("{:?}", self.indice); - - let vbo = gl.create_buffer().unwrap(); - gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo)); - gl.buffer_data_u8_slice( - glow::ARRAY_BUFFER, - cast_slice(&self.buffer), - glow::STATIC_DRAW, - ); - - gl.enable_vertex_attrib_array(0); - gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 40, 0); - - gl.enable_vertex_attrib_array(1); - gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, 40, 12); - - gl.enable_vertex_attrib_array(2); - gl.vertex_attrib_pointer_f32(2, 3, glow::FLOAT, false, 40, 24); - - gl.enable_vertex_attrib_array(3); - gl.vertex_attrib_pointer_f32(3, 1, glow::FLOAT, false, 40, 36); - - let ebo = gl.create_buffer().unwrap(); - gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo)); - - gl.buffer_data_u8_slice( - glow::ELEMENT_ARRAY_BUFFER, - cast_slice(&self.indice), - glow::STATIC_DRAW, - ); - - self.vao = Some(vao); - self.vbo = Some(vbo); - self.ebo = Some(ebo); - - gl.bind_vertex_array(None); - } - - Ok(()) + self.program.compile(gl) } fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> { unsafe { - gl.bind_vertex_array(Some(self.vao.unwrap())); - gl.draw_elements( - glow::TRIANGLES, - (self.indice.len() * 3) as i32, - glow::UNSIGNED_INT, - 0, - ); - gl.bind_vertex_array(None); + gl.draw_elements(glow::TRIANGLES, count, glow::UNSIGNED_INT, 0); } - Ok(()) } fn destroy(&mut self, gl: &glow::Context) -> Result<()> { self.program.destroy(gl); - - unsafe { - self.ebo.map(|ebo| gl.delete_buffer(ebo)); - self.vao.map(|vao| gl.delete_vertex_array(vao)); - self.vbo.map(|vbo| gl.delete_buffer(vbo)); - } - Ok(()) } @@ -223,7 +116,6 @@ impl Graphics for AggFastPath { fn mount(&mut self, gl: &glow::Context) -> Result<()> { unsafe { gl.use_program(self.program.native_program); - self.init(gl); } Ok(()) } @@ -237,18 +129,57 @@ impl Graphics for AggFastPath { } impl AttaWithBuffer for AggFastPath { - type Data = (); + type Data = Vec; fn bake( &self, data: &Self::Data, config: &::Config, ) -> Result<(Vec, Option>, i32)> { - Ok((vec![], None, 0)) + let points = data.iter().map(|v| &v.points).flatten().collect::>(); + let mut vbo = Vec::with_capacity(points.len() * 10); + for p in points { + vbo.extend_from_slice(&[ + p.prev[0], p.prev[1], p.prev[2], p.curr[0], p.curr[1], p.curr[2], p.next[0], + p.next[1], p.next[2], p.id, + ]); + } + let mut ebo = vec![]; + for e in data.iter().map(|v| &v.ebo).flatten() { + ebo.extend_from_slice(e); + } + + let len = ebo.len() as i32; + + Ok((vbo, Some(ebo), len)) } fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option) { - (self.vao.unwrap(), self.vbo.unwrap(), self.ebo) + unsafe { + let vao = gl.create_vertex_array().unwrap(); + gl.bind_vertex_array(Some(vao)); + + let vbo = gl.create_buffer().unwrap(); + gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo)); + + gl.enable_vertex_attrib_array(0); + gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 40, 0); + + gl.enable_vertex_attrib_array(1); + gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, 40, 12); + + gl.enable_vertex_attrib_array(2); + gl.vertex_attrib_pointer_f32(2, 3, glow::FLOAT, false, 40, 24); + + gl.enable_vertex_attrib_array(3); + gl.vertex_attrib_pointer_f32(3, 1, glow::FLOAT, false, 40, 36); + let ebo = gl.create_buffer().unwrap(); + gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo)); + gl.bind_vertex_array(None); + + gl.bind_buffer(glow::ARRAY_BUFFER, None); + (vao, vbo, Some(ebo)) + } } } #[repr(C)] @@ -269,6 +200,11 @@ impl std::fmt::Display for Point { ) } } +impl Point { + fn f32_slice(&self) -> &[f32] { + unsafe { std::slice::from_raw_parts(self as *const Self as *const f32, 13) } + } +} impl Ty for Point {} diff --git a/src/graphics/font/mod.rs b/src/graphics/font/mod.rs index 787ccbd..a0a86a6 100644 --- a/src/graphics/font/mod.rs +++ b/src/graphics/font/mod.rs @@ -2,14 +2,15 @@ mod esdt; use esdt::{Image2d, Unorm8}; use glow::{HasContext, TEXTURE_2D}; use std::{cell::RefCell, collections::HashMap}; -use text_items::{LineStyle, Text as TextTrait}; +use text_items::Text as TextTrait; mod text_items; -pub use text_items::{Anchor, PositionText, TextLine}; +pub use text_items::{Anchor, LineStyle, PositionText, TextLine}; use crate::{ components::{CodeType, Program, Shader}, errors::*, font_manager::{FontManager, FontStyle}, + shaders::font::{FontFragment, FontGeometry, FontVertex}, utils::resources::RcGlTexture, }; @@ -18,14 +19,12 @@ pub struct Text<'a> { gl: &'a glow::Context, font_manager: RefCell, cache: RefCell>>, - items: Vec, program: Program, } pub struct Cache<'a> { gl: &'a glow::Context, cache: HashMap, - // cache_tex: Vec, width: usize, height: usize, last_pos: [usize; 2], @@ -115,14 +114,20 @@ impl<'a> Cache<'a> { self.cache.insert( c, TextVType { + // tex_coords: [ + // x as f32, + // (y + height - 1) as f32, + // (x + width - 1) as f32, + // (y + height - 1) as f32, + // (x + width - 1) as f32, + // y as f32, + // x as f32, + // y as f32, + // ], tex_coords: [ x as f32, (y + height - 1) as f32, (x + width - 1) as f32, - (y + height - 1) as f32, - (x + width - 1) as f32, - y as f32, - x as f32, y as f32, ], // tex_coords: [0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 0.0], @@ -146,34 +151,65 @@ impl<'a> Cache<'a> { #[derive(Clone)] pub struct TextVType { - tex_coords: [f32; 8], + tex_coords: [f32; 4], +} + +impl TextVType { + fn left_top(&self) -> [f32; 2] { + [self.tex_coords[0], self.tex_coords[1]] + } + + fn right_bottom(&self) -> [f32; 2] { + [self.tex_coords[2], self.tex_coords[3]] + } } impl<'a> Text<'a> { pub fn new(gl: &'a glow::Context, font_manager: FontManager) -> Result { let vertex = Shader::new( glow::VERTEX_SHADER, - crate::components::CodeType::from_path("font.vert"), + crate::components::CodeType::from_piece(FontVertex::new()), )?; - let fragment = Shader::new(glow::FRAGMENT_SHADER, CodeType::from_path("font.frag"))?; + let geom = Shader::new( + glow::GEOMETRY_SHADER, + crate::components::CodeType::from_piece(FontGeometry::new()), + )?; - let mut program = Program::new(vertex, fragment, None, "330 core"); - #[cfg(feature = "inparser")] - program.set_transform(&transform); + let fragment = Shader::new( + glow::FRAGMENT_SHADER, + CodeType::from_piece(FontFragment::new()), + )?; + + let mut program = Program::new(vertex, fragment, Some(geom), "330 core"); Ok(Self { gl, font_manager: RefCell::new(font_manager), cache: RefCell::new(HashMap::new()), - items: Vec::new(), program, }) } - #[cfg(feature = "inparser")] - pub fn set_viewport(&mut self, viewport: &Viewport) { - self.program.set_viewport(viewport); + pub fn set_viewport(&self, viewport: [f32; 2]) { + let loc = self.program.get_uniform_location(&self.gl, "viewport"); + unsafe { + self.gl + .uniform_2_f32(loc.as_ref(), viewport[0], viewport[1]); + } + } + + pub fn set_config(&self, config: FontConfig) { + match config { + FontConfig::Textline(style, font) => { + let loc = self.program.get_uniform_location(&self.gl, "location"); + let anchor = self.program.get_uniform_location(&self.gl, "anchor"); + unsafe { + self.gl.uniform_3_f32(loc.as_ref(), 0.0, 0.0, 1.0); + self.gl.uniform_3_f32(anchor.as_ref(), 0.0, 0.0, 0.0); + } + } + } } fn set_uniforms(&self) { @@ -207,9 +243,6 @@ impl<'a> Graphics for Text<'a> { fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> { unsafe { - gl.clear(glow::COLOR_BUFFER_BIT); - // gl.polygon_mode(glow::FRONT_AND_BACK, glow::LINE); - let loc = self.program.get_uniform_location(gl, "atlas_data"); gl.uniform_1_i32(loc.as_ref(), 0); @@ -227,7 +260,7 @@ impl<'a> Graphics for Text<'a> { self.set_uniforms(); - gl.draw_elements(glow::TRIANGLES, count / 2 * 3, glow::UNSIGNED_INT, 0); + gl.draw_arrays(glow::POINTS, 0, count); } Ok(()) } @@ -241,6 +274,16 @@ impl<'a> Graphics for Text<'a> { } fn set_config(&mut self, gl: &glow::Context, config: &Self::Config) -> Result<()> { + unsafe { + match config { + FontConfig::Textline(style, font) => { + let loc = self.program.get_uniform_location(gl, "location"); + let anchor = self.program.get_uniform_location(gl, "anchor"); + gl.uniform_3_f32(loc.as_ref(), 0.0, 0.0, 2.0); + gl.uniform_3_f32(anchor.as_ref(), 0.0, 0.0, 0.0); + } + } + } Ok(()) } } @@ -259,19 +302,7 @@ impl<'a> AttaWithBuffer for Text<'a> { &mut *self.cache.borrow_mut(), )?; - let mut ebos = Vec::with_capacity(v.len() / 2 * 3); - - for i in 0..v.len() / 4 { - let i = i as u32; - ebos.push(i * 4); - ebos.push(i * 4 + 1); - ebos.push(i * 4 + 3); - - ebos.push(i * 4 + 1); - ebos.push(i * 4 + 2); - ebos.push(i * 4 + 3); - } - Ok((v.vertex(), Some(ebos), v.len() as i32)) + Ok((v.vertex(), None, v.len() as i32)) } fn init( @@ -288,17 +319,15 @@ impl<'a> AttaWithBuffer for Text<'a> { let vbo = gl.create_buffer().unwrap(); gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo)); gl.enable_vertex_attrib_array(0); - gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 20, 0); + gl.vertex_attrib_pointer_f32(0, 4, glow::FLOAT, false, 32, 0); gl.enable_vertex_attrib_array(1); - gl.vertex_attrib_pointer_f32(1, 2, glow::FLOAT, false, 20, 12); - - let ebo = gl.create_buffer().unwrap(); - gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo)); + gl.vertex_attrib_pointer_f32(1, 4, glow::FLOAT, false, 32, 16); gl.bind_vertex_array(None); + gl.bind_buffer(glow::ARRAY_BUFFER, None); - (vao, vbo, Some(ebo)) + (vao, vbo, None) } } } diff --git a/src/graphics/font/text_items.rs b/src/graphics/font/text_items.rs index 64ec599..10a35b2 100644 --- a/src/graphics/font/text_items.rs +++ b/src/graphics/font/text_items.rs @@ -100,8 +100,8 @@ impl Default for TextAlign { #[repr(C)] #[derive(Clone, Copy, Zeroable, Pod)] pub struct TextVertexItem { - position: [f32; 3], - tex_coords: [f32; 2], + tex_coords: [f32; 4], + position: [f32; 4], } pub struct TextVertexArray { @@ -123,22 +123,25 @@ impl TextVertexArray { self.points.push(item); } - pub fn insert_text(&mut self, tex_coords: TextVType, positions: [[f32; 3]; 4]) { - for i in 0..4 { - self.push(TextVertexItem { - position: positions[i], - tex_coords: [ - tex_coords.tex_coords[i * 2], - tex_coords.tex_coords[i * 2 + 1], - ], - }); - } + pub fn insert_text(&mut self, tex_coords: TextVType, position: [f32; 2], size: [f32; 2]) { + let tex_left_top = tex_coords.left_top(); + let tex_right_bottom = tex_coords.right_bottom(); + + self.push(TextVertexItem { + position: [position[0], position[1], size[0], size[1]], + tex_coords: [ + tex_left_top[0], + tex_left_top[1], + tex_right_bottom[0], + tex_right_bottom[1], + ], + }); } pub fn vertex(&self) -> Vec { - let mut result = Vec::with_capacity(self.len() * 6); + let mut result = Vec::with_capacity(self.len() * 8); self.points.iter().for_each(|v| { - result.extend_from_slice(&v.position); result.extend_from_slice(&v.tex_coords); + result.extend_from_slice(&v.position); }); result } @@ -205,24 +208,25 @@ impl Text for TextLine { }); let metrics = font.get_metrics(char); - let bear_x = metrics.horiBearingX; - let bear_y = metrics.horiBearingY; + let width = (metrics.width >> 6) as f32; + let height = (metrics.height >> 6) as f32; + + let bear_x = (metrics.horiBearingX >> 6) as f32; + let bear_y = (metrics.horiBearingY >> 6) as f32; let x0 = pen[0] + bear_x as f32 + x_kerning; let y0 = pen[1] - bear_y as f32; let x1 = pen[0] + metrics.width as f32 + x_kerning; let y1 = pen[1] + metrics.height as f32; - let position = [[x0, y0, 0.0], [x1, y0, 0.0], [x1, y1, 0.0], [x1, y0, 0.0]]; - if let Some(cache) = cache.get(char) { - baked.insert_text(cache.to_owned(), position); + baked.insert_text(cache.to_owned(), [x0, y0], [width, height]); } else { let char_glyph = font.get_char(char, 64)?; let mut img = char_glyph.into(); let (result, _) = glyph_to_sdf(&mut img, SDF_PARAM, None); let b = cache.insert_glyph(result, char); - baked.insert_text(b.to_owned(), position); + baked.insert_text(b.to_owned(), [x0, y0], [width, height]); } pen[0] += x_advanced; diff --git a/src/graphics/ppi.rs b/src/graphics/ppi.rs index f757348..ff46dac 100644 --- a/src/graphics/ppi.rs +++ b/src/graphics/ppi.rs @@ -203,7 +203,7 @@ impl AttaWithBuffer for PPI { vertices.extend([r, *azi, *ele, *dt]); } } - let len = vertices.len() as i32 / 3; + let len = vertices.len() as i32 / 4; return Ok((vertices, None, len)); } else { return Err(Error::InvalidDataType); @@ -219,6 +219,7 @@ impl AttaWithBuffer for PPI { gl.enable_vertex_attrib_array(0); gl.vertex_attrib_pointer_f32(0, 4, glow::FLOAT, false, 16, 0); gl.bind_vertex_array(None); + gl.bind_buffer(glow::ARRAY_BUFFER, None); (vao, vbo, None) } diff --git a/src/pg/layout_type.rs b/src/pg/layout_type.rs index d364517..40f27f6 100644 --- a/src/pg/layout_type.rs +++ b/src/pg/layout_type.rs @@ -86,6 +86,10 @@ impl ViewPort { pub fn fbo(&self) -> &RcGlRcFramebuffer { &self.main_fbo } + + pub fn size(&self) -> [f32; 2] { + self.renderer_size + } } impl ViewPort { diff --git a/src/pg/mod.rs b/src/pg/mod.rs index edbc27c..177b334 100644 --- a/src/pg/mod.rs +++ b/src/pg/mod.rs @@ -2,13 +2,16 @@ mod app; use femtovg::renderer::OpenGl; use femtovg::Canvas; use glow::HasContext; +use layout_type::ViewPort; pub mod layout_type; mod modules; use crate::font_manager::FontManager; +use crate::graphics::collections::agg_fast_path::AggFastPath; use crate::graphics::font::Text; use crate::graphics::ppi::PPI; use crate::graphics::threed::Trackball; +use crate::graphics::transforms::viewport; use crate::graphics::{AttaWithProgram, AttachWithMouse}; use crate::ui::operation::Operation; use crate::ui::typ::LayoutAttach; @@ -25,6 +28,7 @@ pub(super) struct Programs<'gl> { gl: &'gl GL, _ppi: PPI, _text: Text<'gl>, + _line: AggFastPath, } impl<'gl> Programs<'gl> { @@ -35,21 +39,25 @@ impl<'gl> Programs<'gl> { gl, _ppi: PPI::new()?, _text: Text::new(gl, font_manager)?, + _line: AggFastPath::new()?, }) } pub fn prepare(&mut self) -> Result<()> { self._ppi.program().compile(&self.gl)?; + self._line.program().compile(&self.gl)?; + self._text.program_mut().compile(&self.gl)?; Ok(()) } pub fn ppi<'b>(&'b mut self) -> modules::PPIModule<'b, 'gl> { - modules::PPIModule::new(&self.gl, &mut self._ppi, &mut self._text).unwrap() + modules::PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line).unwrap() } pub fn destroy(&mut self) -> Result<()> { self._ppi.destroy(&self.gl)?; self._text.destroy(&self.gl)?; + self._line.destroy(&self.gl)?; Ok(()) } @@ -78,12 +86,11 @@ impl<'gl> Programs<'gl> { &mut self, modules: &mut ModulePackage<'gl>, operation: &Operation, + viewport: &ViewPort, ) -> Result<()> { match &mut modules.modules { _ModulePackage::PPI(ppi) => { - self.ppi().start(); - self.ppi().render(ppi, operation)?; - self.ppi().end(); + self.ppi().render(ppi, operation, viewport)?; } } modules.need_update = false; diff --git a/src/pg/modules/mod.rs b/src/pg/modules/mod.rs index 5db5ba0..2767e8f 100644 --- a/src/pg/modules/mod.rs +++ b/src/pg/modules/mod.rs @@ -15,7 +15,7 @@ mod ppi; use crate::errors::*; pub use ppi::{PPIModule, PPIPackage}; -use super::Data; +use super::{layout_type::ViewPort, Data}; #[derive(Debug, Clone)] struct Attach<'a> { @@ -43,23 +43,43 @@ impl<'a> Attach<'a> { } } + fn bind_self(&self) { + self.vao.bind(glow::VERTEX_ARRAY); + self.vbo.bind(glow::ARRAY_BUFFER); + if let Some(ebo) = self.ebo.as_ref() { + ebo.bind(glow::ELEMENT_ARRAY_BUFFER); + } + } + + fn unbind_self(&self) { + self.vao.unbind(glow::VERTEX_ARRAY); + self.vbo.unbind(glow::ARRAY_BUFFER); + if let Some(ebo) = self.ebo.as_ref() { + ebo.unbind(glow::ELEMENT_ARRAY_BUFFER); + } + } + fn bind_data(&mut self, vbo: &Vec, ebo: Option<&Vec>, len: i32) { use bytemuck::cast_slice; - self.vao.bind(glow::VERTEX_ARRAY); + self.vbo.bind(glow::ARRAY_BUFFER); unsafe { self.gl .buffer_data_u8_slice(glow::ARRAY_BUFFER, cast_slice(&vbo), glow::STATIC_DRAW); if let Some(ebo) = ebo { - self.ebo.as_ref().unwrap().bind(glow::ELEMENT_ARRAY_BUFFER); + self.gl.bind_buffer( + glow::ELEMENT_ARRAY_BUFFER, + Some(self.ebo.as_ref().unwrap().native()), + ); self.gl.buffer_data_u8_slice( glow::ELEMENT_ARRAY_BUFFER, cast_slice(&ebo), glow::STATIC_DRAW, ); + + self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None); } } - - self.vao.unbind(glow::VERTEX_ARRAY); + self.vbo.unbind(glow::ARRAY_BUFFER); self.len = len; } @@ -77,13 +97,9 @@ pub trait Module: Sized { &mut self, cursor: &mut Self::Cursor, operation: &Operation, + viewport: &ViewPort, ) -> Result<()>; - fn resize(&self, size: [f32; 2]); - fn destroy(&self); - fn start(&mut self); - // fn init(&mut self, info: &Operation) -> Result<()>; - fn end(&mut self); fn load_data<'dt>(&self, data: &CachedData) -> Result; } diff --git a/src/pg/modules/ppi.rs b/src/pg/modules/ppi.rs index e41c5d2..2b670ce 100644 --- a/src/pg/modules/ppi.rs +++ b/src/pg/modules/ppi.rs @@ -1,7 +1,14 @@ +use collections::agg_fast_path::{AggFastPath, AggFastPathConfig, Path}; +use core::f32; +use font::{FontConfig, LineStyle, PositionText, TextLine}; +use glow::HasContext; use std::rc::Rc; use tracker::track; +use transforms::viewport; +use crate::font_manager::{FontSize, FontStyle}; use crate::graphics::{font::Text, *}; +use crate::pg::layout_type::ViewPort; use crate::ui::helper_components::colorbar::colorbar; use crate::ui::operation::{self, Operation}; use crate::SETTING; @@ -20,35 +27,81 @@ use super::{Attach, Module, ModuleCursor}; pub struct PPIModule<'b, 'a: 'b> { gl: &'a glow::Context, ppi_program: &'b mut PPI, + line_program: &'b mut AggFastPath, text_program: &'b mut Text<'a>, } impl<'b, 'a: 'b> PPIModule<'b, 'a> { - pub fn new(gl: &'a glow::Context, ppi: &'b mut PPI, text: &'b mut Text<'a>) -> Result { + pub fn new( + gl: &'a glow::Context, + ppi: &'b mut PPI, + text: &'b mut Text<'a>, + line: &'b mut AggFastPath, + ) -> Result { let config = PPIConfig::default(); Ok(Self { gl, ppi_program: ppi, text_program: text, + line_program: line, }) } - fn rebind(&self, attach: &mut Attach, data: &Data, config: &PPIModuleConfig) -> Result<()> { - let (vbo, ebo, len) = self.ppi_program.bake( - data, - &PPIConfig { - unvalid_value: config.unvalid_value, - color_range: config.color_range, - colors: config.colors.clone(), - layer: config.layer, - rdpi: config.rdpi, - adpi: config.adpi, - three_d: config.is_three_d, - }, - )?; + fn bind_ppi_pg( + &self, + attach: &mut Attach, + data: &Data, + config: &PPIModuleConfig, + ) -> Result<()> { + let (vbo, ebo, len) = self.ppi_program.bake(data, &config.to_ppi_config())?; attach.bind_data(&vbo, ebo.as_ref(), len); Ok(()) } + + fn bind_line_pg( + &self, + attach: &mut Attach, + data: &Data, + config: &PPIModuleConfig, + ) -> Result<()> { + let config = config.to_line_config(); + // Create the path + let mut path = Path::new(true); + + // Will be changed in the future + let outskirt = 10.0; + + for seg in 0..500 { + let angle = 2f32 * f32::consts::PI / 500.0 * seg as f32; + let x = (angle.cos() * outskirt) as f32; + let y = (angle.sin() * outskirt) as f32; + path.push([x, y, 0.0]); + } + path.finish(); + + let (vbo, ebo, len) = self.line_program.bake(&vec![path], &config)?; + attach.bind_data(&vbo, ebo.as_ref(), len); + Ok(()) + } + + fn bind_tick(&self, attach: &mut Attach, data: &Data, config: &PPIModuleConfig) -> Result<()> { + let font_style = config.to_font_config(); + + match font_style { + FontConfig::Textline(line_style, font_style) => { + let new_text = TextLine::new("ABC", Some(font_style), None); + let position_text = + PositionText::new(new_text, [0.0, 0.0, 0.0], font::Anchor::BottomCenter); + + let text_pg_config = config.to_font_config(); + + let (vbo, ebo, len) = self.text_program.bake(&position_text, &text_pg_config)?; + attach.bind_data(&vbo, ebo.as_ref(), len); + } + } + + Ok(()) + } } impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> { @@ -56,116 +109,155 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> { type Data = Data; type Operation = Trackball; - fn start(&mut self) { - self.ppi_program.mount(&self.gl).unwrap(); - } - - fn end(&mut self) { - self.ppi_program.unmount(&self.gl).unwrap(); - } - fn render<'dt>( &mut self, cursor: &mut Self::Cursor, operation: &Operation, + viewport: &ViewPort, ) -> Result<()> { + // Mount PPI Program + self.ppi_program.mount(&self.gl)?; + // Deal with the operation operation.attach_with_program(&self.gl, self.ppi_program.program()); - let attach = &mut cursor.ppi_attach; + // PPI Program + let ppi_attach = &mut cursor.ppi_attach; let data = &cursor.ppi_data.borrow(); let config = &mut cursor.ppi_config; - self.ppi_program.set_config( - &self.gl, - &PPIConfig { - unvalid_value: config.unvalid_value, - color_range: config.color_range, - colors: config.colors.clone(), - layer: config.layer, - rdpi: config.rdpi, - adpi: config.adpi, - three_d: config.is_three_d, - }, - )?; + // Update the config + self.ppi_program + .set_config(&self.gl, &config.to_ppi_config())?; + // if the layer is changed, we need to rebind the data if config.changed_layer() { - self.rebind(attach, data, config); - config.reset(); + self.bind_ppi_pg(ppi_attach, data, config); } - attach.vao.bind(glow::VERTEX_ARRAY); - self.ppi_program.draw(&self.gl, attach.len())?; - attach.vao.unbind(glow::VERTEX_ARRAY); + + // PPI Draw + ppi_attach.bind_self(); + self.ppi_program.draw(&self.gl, ppi_attach.len())?; + ppi_attach.unbind_self(); + + // Unmount PPI Program + self.ppi_program.unmount(&self.gl)?; + + // Mount Line Program + self.line_program.mount(&self.gl)?; + + // Deal with the operation + operation.attach_with_program(&self.gl, self.line_program.program()); + + // Set the viewport, this is important + self.line_program.set_viewport(&self.gl, viewport.size()); + + // Update the config + self.line_program + .set_config(&self.gl, &config.to_line_config()); + + // PPI Tick Draw + let attach = &mut cursor.line_attach; + attach.bind_self(); + self.line_program.draw(&self.gl, attach.len())?; + attach.unbind_self(); + + self.line_program.unmount(&self.gl)?; + + self.text_program.mount(&self.gl); + + let tick_attach = &mut cursor.tick_attach; + // Deal with the operation + operation.attach_with_program(&self.gl, self.text_program.program_mut()); + self.text_program.set_viewport(viewport.size()); + self.text_program + .set_config(&self.gl, &config.to_font_config()); + + tick_attach.bind_self(); + self.text_program.draw(&self.gl, tick_attach.len())?; + tick_attach.unbind_self(); + + config.reset(); + Ok(()) } - fn resize(&self, size: [f32; 2]) {} - - fn destroy(&self) {} - fn load_data<'dt>(&self, data: &CachedData) -> Result { let _data = data.borrow(); + + // Check if the data is valid if _data.blocks.len() == 0 { return Err(Error::InvalidDataType); } + + // Init the memory let (vao, vbo, ebo) = self.ppi_program.init(&self.gl); - let mut attach = Attach::new(&self.gl, vao, vbo, ebo, None); + let mut ppi_attach = Attach::new(&self.gl, vao, vbo, ebo, None); + + // Get the data info let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&_data)?; + // Find the color map let cmap = SETTING.find(&t); + // Check if the color map is valid if cmap.is_none() { return Err(Error::InvalidDataType); } - let cmap = cmap.unwrap(); - let config = PPIModuleConfig { - color_range: cmap.value_range(), - colors: cmap.color()?, - layer: 0, - rdpi: r, - adpi: a, - max_layer, - unvalid_value: unvalid, - is_three_d: true, - tracker: 0, - }; + // Init the memory for the line program + let (vao, vbo, ebo) = self.line_program.init(&self.gl); + let mut line_attach = Attach::new(&self.gl, vao, vbo, ebo, None); - self.rebind(&mut attach, &data.borrow(), &config); + // Tick Label + let (vao, vbo, ebo) = self.text_program.init(&self.gl); + let mut tick_attach = Attach::new(&self.gl, vao, vbo, ebo, None); - Ok(PPIPackage::new(config, attach, data)) + let mut config = PPIModuleConfig::default(); + config.rdpi = r; + config.adpi = a; + config.max_layer = max_layer; + config.unvalid_value = unvalid; + config.colors = cmap.color()?; + config.color_range = cmap.value_range(); + + // Bind the data + self.bind_ppi_pg(&mut ppi_attach, &data.borrow(), &config); + self.bind_line_pg(&mut line_attach, &data.borrow(), &config); + self.bind_tick(&mut tick_attach, &data.borrow(), &config); + + Ok(PPIPackage::new( + config, + ppi_attach, + line_attach, + tick_attach, + data, + )) } } -#[track] -#[derive(PartialEq)] -pub struct PPIModuleConfig { - pub layer: usize, - pub colors: Vec<[u8; 4]>, - pub color_range: [f32; 2], - pub is_three_d: bool, - #[do_not_track] - pub unvalid_value: f32, - #[do_not_track] - pub max_layer: usize, - #[do_not_track] - pub rdpi: f32, - #[do_not_track] - pub adpi: f32, -} - pub struct PPIPackage<'gl> { draw_helper: bool, ppi_config: PPIModuleConfig, ppi_attach: Attach<'gl>, + line_attach: Attach<'gl>, + tick_attach: Attach<'gl>, ppi_data: CachedData, } impl<'gl> PPIPackage<'gl> { - fn new(ppi_config: PPIModuleConfig, ppi_attach: Attach<'gl>, data: &CachedData) -> Self { + fn new( + ppi_config: PPIModuleConfig, + ppi_attach: Attach<'gl>, + line_attach: Attach<'gl>, + tick_attach: Attach<'gl>, + data: &CachedData, + ) -> Self { Self { draw_helper: true, ppi_config, ppi_attach, + line_attach, + tick_attach, ppi_data: Rc::clone(data), } } @@ -192,8 +284,17 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> { ui.checkbox("three d?", &mut is_three_d); ui.separator(); + let mut line_width = self.ppi_config.line_width; + let mut line_antialias = self.ppi_config.line_antialias; + + ui.text("PPI Line Config"); + ui.slider("line width", 0.1, 10.0, &mut line_width); + ui.slider("line ana", 0.1, 10.0, &mut line_antialias); + self.ppi_config.set_layer(layer); self.ppi_config.set_is_three_d(is_three_d); + self.ppi_config.set_line_width(line_width); + self.ppi_config.set_line_antialias(line_antialias); self.ppi_config.changed_any() } @@ -202,3 +303,79 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> { true } } + +#[track] +#[derive(PartialEq)] +pub struct PPIModuleConfig { + pub ticks: bool, + pub line_color: [f32; 4], + pub line_width: f32, + pub line_antialias: f32, + pub layer: usize, + pub colors: Vec<[u8; 4]>, + pub color_range: [f32; 2], + pub is_three_d: bool, + + pub tick_label_color: [f32; 4], + pub tick_label_size: f32, + #[do_not_track] + pub unvalid_value: f32, + #[do_not_track] + pub max_layer: usize, + #[do_not_track] + pub rdpi: f32, + #[do_not_track] + pub adpi: f32, +} + +impl Default for PPIModuleConfig { + fn default() -> Self { + Self { + ticks: true, + line_color: [1.0, 1.0, 1.0, 1.0], + line_width: 2.0, + line_antialias: 2.0, + layer: 0, + colors: vec![], + color_range: [0.0, 0.0], + is_three_d: true, + unvalid_value: 0.0, + tick_label_color: [1.0, 1.0, 1.0, 1.0], + tick_label_size: 24.0, + max_layer: 0, + rdpi: 0.0, + adpi: 0.0, + tracker: 0, + } + } +} + +impl PPIModuleConfig { + fn to_ppi_config(&self) -> PPIConfig { + PPIConfig { + unvalid_value: self.unvalid_value, + color_range: self.color_range, + colors: self.colors.clone(), + layer: self.layer, + rdpi: self.rdpi, + adpi: self.adpi, + three_d: self.is_three_d, + } + } + + fn to_line_config(&self) -> AggFastPathConfig { + AggFastPathConfig { + color: self.line_color, + linewidth: self.line_width, + antialias: self.line_antialias, + } + } + + fn to_font_config(&self) -> FontConfig { + let line_style = LineStyle::default(); + let mut font_style = FontStyle::default(); + font_style.size = FontSize::Absolute(self.tick_label_size); + font_style.color = self.tick_label_color; + FontConfig::Textline(line_style, font_style) + } +} diff --git a/src/shaders/agg_path.rs b/src/shaders/agg_path.rs new file mode 100644 index 0000000..b683b97 --- /dev/null +++ b/src/shaders/agg_path.rs @@ -0,0 +1,126 @@ +use glsl::syntax::ShaderStage; +use glsl::syntax::TranslationUnit; +use glsl::transpiler::glsl::show_translation_unit; +use glsl_quasiquote::glsl; + +use crate::impl_code_piece; + +use super::{trackball::Trackball, CodePiece}; + +pub struct AggPathVertex(ShaderStage); + +pub struct AggPathFragment(ShaderStage); + +impl AggPathVertex { + pub fn new() -> Self { + let mut transform = Trackball::new().0; + let raw = glsl! { + + layout(location = 0) in vec3 prev; + layout(location = 1) in vec3 curr; + layout(location = 2) in vec3 next; + layout(location = 3) in float id; + + uniform float antialias; + uniform float thickness; + uniform vec2 viewport; + uniform vec4 color; + + out float v_distance; + out vec4 v_color; + + void main() { + vec4 ndc_prev = transform(position(prev)); + vec4 ndc_curr = transform(position(curr)); + vec4 ndc_next = transform(position(next)); + + // screen space + vec2 screen_prev = viewport * ((ndc_prev.xy/ndc_prev.w) + 1.0)/2.0; + vec2 screen_curr = viewport * ((ndc_curr.xy/ndc_curr.w) + 1.0)/2.0; + vec2 screen_next = viewport * ((ndc_next.xy/ndc_next.w) + 1.0)/2.0; + + + vec2 P; + float w = thickness/2.0 + antialias; + + if (prev.xy == curr.xy) { + vec2 v = normalize(screen_next.xy - screen_curr.xy); + vec2 normal = normalize(vec2(-v.y, v.x)); + P = screen_curr.xy + w*normal*id; + } else if (curr.xy == next.xy) { + vec2 v = normalize(screen_curr.xy - screen_prev.xy); + vec2 normal = normalize(vec2(-v.y, v.x)); + P = screen_curr.xy + w*normal*id; + } else { + + vec2 v0 = normalize(screen_curr.xy - screen_prev.xy); + vec2 v1 = normalize(screen_next.xy - screen_curr.xy); + vec2 normal = normalize(vec2(-v0.y, v0.x)); + vec2 tangent = normalize(v0 + v1); + + vec2 miter = vec2(-tangent.y, tangent.x); + + float l = abs(w/dot(miter,normal)); + P = screen_curr.xy + l*miter*sign(id); + } + + v_color = color; + + if (abs(id) > 1.5) v_color.a = 0.0; + v_distance = w * id; + + // Back to NDC coordinates + gl_Position = vec4(2.0*P/viewport-1.0, ndc_curr.z / ndc_curr.w, 1.0); + } + }; + + transform.extend(raw); + + Self(transform) + } +} + +impl AggPathFragment { + pub fn new() -> Self { + let raw = glsl! { + uniform float antialias; + uniform float thickness; + + in float v_distance; + in vec4 v_color; + out vec4 fragColor; + + + vec4 stroke(float distance, float linewidth, float antialias, vec4 fg_color) + { + vec4 frag_color; + float t = linewidth/2.0 - antialias; + float signed_distance = distance; + float border_distance = abs(signed_distance) - t; + float alpha = border_distance/antialias; + alpha = exp(-alpha*alpha); + + if( border_distance < 0.0 ) + frag_color = fg_color; + else + frag_color = vec4(fg_color.rgb, fg_color.a * alpha); + + return frag_color; + } + + vec4 stroke(float distance, float linewidth, float antialias, vec4 fg_color, vec4 bg_color) + { + return stroke(distance, linewidth, antialias, fg_color); + } + + void main() { + if (v_color.a == 0) {discard;} + fragColor = stroke(v_distance, thickness, antialias, v_color); + } + }; + Self(raw) + } +} + +impl_code_piece!(AggPathVertex, 0); +impl_code_piece!(AggPathFragment, 0); diff --git a/src/shaders/font.rs b/src/shaders/font.rs new file mode 100644 index 0000000..5e128fb --- /dev/null +++ b/src/shaders/font.rs @@ -0,0 +1,216 @@ +use super::trackball::Trackball; +use super::CodePiece; +use crate::impl_code_piece; +use glsl::syntax::ShaderStage; +use glsl::syntax::TranslationUnit; +use glsl::transpiler::glsl::show_translation_unit; +use glsl_quasiquote::glsl; + +pub struct FontVertex(pub ShaderStage); + +pub struct FontFragment(pub ShaderStage); + +pub struct FontGeometry(pub ShaderStage); + +impl FontVertex { + pub fn new() -> Self { + let raw = glsl! { + + // texcoord (left top, right bottom) + layout(location = 0) in vec4 texcoord; + + // Relative position (x, y, width, height) + layout(location = 1) in vec4 relative_position; + + out VS_OUT { + vec4 texcoord; + vec4 pos; + } vs_out; + + + void main() { + gl_Position = vec4(0.0, 0.0, 0.0, 1.0); + vs_out.texcoord = texcoord; + vs_out.pos = relative_position; + } + }; + + Self(raw) + } +} + +impl FontGeometry { + pub fn new() -> Self { + let mut transform = Trackball::new().0; + let raw = glsl! { + layout(points) in; + layout(triangle_strip, max_vertices = 4) out; + + // Uniforms + uniform vec3 location; + uniform vec3 anchor; + uniform vec2 viewport; + + // Texture Shape + uniform vec2 atlas_shape; + + out vec2 v_texCoord; + + in VS_OUT { + vec4 texcoord; + vec4 pos; + } gs_in[]; + + void main() { + + vec4 pos = gs_in[0].pos; + float x, y, width, hgt; + + // Char position and size + x = pos.x; + y = pos.y; + width = pos.z; + hgt = pos.w; + + // texcoord + vec2 tex_coord_lt = gs_in[0].texcoord.xy / atlas_shape; + vec2 tex_coord_rb = gs_in[0].texcoord.zw / atlas_shape; + + // Char Size + vec2 size = vec2(width, hgt); + + // Base Text Location + vec3 base_pos = location + anchor; + + // base_pos in NDC + vec4 ndc_base_pos = transform(position(base_pos)); + + // Screen Space + vec2 screen_base_pos = viewport * ((ndc_base_pos.xy / ndc_base_pos.w) + 1.0) / 2.0; + + // Billboard Type + vec2 left_top = screen_base_pos + vec2(x, y); + vec2 right_bottom = left_top + size; + + vec2 ndc_left_top = (2.0 * left_top / viewport - 1.0); + vec2 ndc_right_bottom = (2.0 * right_bottom / viewport - 1.0); + + // Emit vertices + gl_Position = vec4(ndc_left_top.x, ndc_right_bottom.y, ndc_base_pos.z / ndc_base_pos.w, 1.0); + v_texCoord = vec2(tex_coord_lt.x, tex_coord_lt.y); + EmitVertex(); + + gl_Position = vec4(ndc_right_bottom.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0); + v_texCoord = tex_coord_rb; + EmitVertex(); + + gl_Position = vec4(ndc_left_top.xy, ndc_base_pos.z / ndc_base_pos.w, 1.0); + v_texCoord = tex_coord_lt; + EmitVertex(); + + gl_Position = vec4(ndc_right_bottom.x, ndc_left_top.y, ndc_base_pos.z / ndc_base_pos.w, 1.0); + v_texCoord = vec2(tex_coord_rb.x, tex_coord_lt.y); + EmitVertex(); + + EndPrimitive(); + } + + }; + + transform.extend(raw); + + Self(transform) + } +} + +impl FontFragment { + pub fn new() -> Self { + let raw = glsl! { + uniform sampler2D atlas_data; + in vec2 v_texCoord; + + uniform vec4 uClipUV; + uniform vec4 uSdfConfig; + uniform int uMode; + uniform vec4 uBorder; + uniform vec4 uStroke; + uniform vec4 uFill; + + float getUVScale(vec2 sdfUV) { + float dx = dFdx(sdfUV.x); + float dy = dFdy(sdfUV.y); + return (sqrt(dx * dx + dy * dy) + sqrt(dy * dy + dx * dx)) * 0.5; + } + + struct SDF { + float outer; + float inner; + }; + + vec4 getTexture(vec2 uv) { + return texture(atlas_data, uv); + } + + vec4 getMask(vec4 color, vec2 uv, vec2 st) { + return color; // 默认不修改颜色 + } + + out vec4 fragColor; + + void main() { + vec4 fillColor = uFill; + vec4 strokeColor = uStroke; + + float scale = getUVScale(v_texCoord); + + vec4 texture = getTexture(v_texCoord); + + float dis = texture.r; + + if (dis<0.5) { + discard; + }else { + fragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + // float sdfRaw = 0.0; + // float mark = 0.0; + + // float sdf; + + // float sdfRadius = uSdfConfig.x; + // float expand = uBorder.x; + // float bleed = uBorder.y; + + // float d = (texture.r - 0.75) * sdfRadius; + // float s = (d + expand / uSdfConfig.y) / scale + 0.5 + bleed; + // sdf = s; // Assuming SDF returns a single float, adjust as necessary + + // if (uMode == -2) { + // fillColor = vec4(texture.rgb, fillColor.a); + // } + + // // if (gl_FragCoord.x < uClipUV.x || gl_FragCoord.y < uClipUV.y || gl_FragCoord.x > uClipUV.z || gl_FragCoord.y > uClipUV.w) { + // // discard; + // // } + // // Compute mask based on SDF + // float mask = clamp(sdf, 0.0, 1.0); + // // Final color blending logic here + + // if(mask < 0.5) { + // fragColor = vec4(0.0, 0.0, 0.0, 0.0); + // } else { + // fragColor = vec4(fillColor.rgb, 1.0); + // } + // fragColor = vec4(fillColor.rgb + mark, fillColor.a * mask + mark); + + // fragColor = vec4(1.0, 1.0, 1.0, 1.0); + } + }; + + Self(raw) + } +} + +impl_code_piece!(FontVertex, 0); +impl_code_piece!(FontGeometry, 0); +impl_code_piece!(FontFragment, 0); diff --git a/src/shaders/mod.rs b/src/shaders/mod.rs index 33ed41f..84ca983 100644 --- a/src/shaders/mod.rs +++ b/src/shaders/mod.rs @@ -1,4 +1,6 @@ +pub mod agg_path; pub mod colormap; +pub mod font; pub mod math; pub mod polar; pub mod ppi; diff --git a/src/shaders/trackball.rs b/src/shaders/trackball.rs index 57a9bfd..eb900af 100644 --- a/src/shaders/trackball.rs +++ b/src/shaders/trackball.rs @@ -21,6 +21,46 @@ impl Trackball { * trackball_model * position; } + + vec4 position(float x) + { + return vec4(x, 0.0, 0.0, 1.0); + } + + vec4 position(float x, float y) + { + return vec4(x, y, 0.0, 1.0); + } + + vec4 position(vec2 xy) + { + return vec4(xy, 0.0, 1.0); + } + + vec4 position(float x, float y, float z) + { + return vec4(x, y, z, 1.0); + } + + vec4 position(vec3 xyz) + { + return vec4(xyz, 1.0); + } + + vec4 position(vec4 xyzw) + { + return xyzw; + } + + vec4 position(vec2 xy, float z) + { + return vec4(xy, z, 1.0); + } + + vec4 position(float x, vec2 yz) + { + return vec4(x, yz, 1.0); + } }; Self(raw) diff --git a/src/ui/typ/main_load.rs b/src/ui/typ/main_load.rs index e669a64..a7e007a 100644 --- a/src/ui/typ/main_load.rs +++ b/src/ui/typ/main_load.rs @@ -81,11 +81,12 @@ impl LayoutMod for MainLoad { let dsp_size = ui.io().display_size; let content_size = ui.content_region_avail(); + + // Change the size of the viewport apptyp.main_viewport.set_size(content_size); // context.helper.set_size(content_size, scale[0]); let draws = ui.get_window_draw_list(); - draws.channels_split(2, |channels| { channels.set_current(0); let fbo = apptyp.main_viewport.fbo(); @@ -191,7 +192,7 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> { programs: &mut crate::pg::Programs<'gl>, helper: &mut Helper, ) -> crate::errors::Result<()> { - helper.draw_modules(gl, &self.packages); + // helper.draw_modules(gl, &self.packages); if self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update() { // Helper task self.main_viewport.bind(gl); @@ -201,7 +202,7 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> { } for package in self.packages.iter_mut() { - programs.draw_modules(package, &self.operation)?; + programs.draw_modules(package, &self.operation, &self.main_viewport)?; } }