diff --git a/Cargo.lock b/Cargo.lock index 343010e..728b032 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -74,7 +74,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee91c0c2905bae44f84bfa4e044536541df26b7703fd0888deeb9060fcc44289" dependencies = [ "android-properties", - "bitflags 2.5.0", + "bitflags 2.6.0", "cc", "cesu8", "jni", @@ -266,9 +266,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "bitstream-io" @@ -357,7 +357,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fba7adb4dd5aa98e5553510223000e7148f621165ec5f9acd7113f6ca4995298" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "log", "polling", "rustix", @@ -738,6 +738,28 @@ dependencies = [ "simd-adler32", ] +[[package]] +name = "femtovg" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47921d14afc4daad9bedc926099bc6edcaa23e37a957448f86cdefcbafe2f632" +dependencies = [ + "bitflags 2.6.0", + "fnv", + "glow", + "image", + "imgref", + "log", + "lru", + "rgb", + "rustybuzz", + "slotmap", + "unicode-bidi", + "unicode-segmentation", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "flate2" version = "1.0.30" @@ -763,6 +785,12 @@ dependencies = [ "spin", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "foreign-types" version = "0.5.0" @@ -796,7 +824,7 @@ version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d1d1f81b925f09d7040682dbc91eb1b6ad43232f4bc6ee080f518001c05b5415" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "freetype-sys", "libc", ] @@ -931,7 +959,7 @@ version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18fcd4ae4e86d991ad1300b8f57166e5be0c95ef1f63f3f5b827f8a164548746" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cfg_aliases", "cgl", "core-foundation", @@ -1339,7 +1367,7 @@ version = "0.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3af92c55d7d839293953fcd0fda5ecfe93297cfde6ffbdec13b41d99c0ba6607" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", "redox_syscall 0.4.1", ] @@ -1350,7 +1378,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "libc", ] @@ -1541,7 +1569,7 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2076a31b7010b17a38c01907c45b945e8f11495ee4dd588309718901b1f7a5b7" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "jni-sys", "log", "ndk-sys", @@ -1961,6 +1989,7 @@ dependencies = [ "copypasta", "dirs", "env_logger", + "femtovg", "flate2", "freetype-rs", "geo", @@ -2135,7 +2164,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469052894dcb553421e483e4209ee581a45100d31b4018de03e5a7ad86374a7e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", ] [[package]] @@ -2219,7 +2248,7 @@ version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2232,6 +2261,22 @@ version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" +[[package]] +name = "rustybuzz" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfb9cf8877777222e4a3bc7eb247e398b56baba500c38c1c46842431adc8b55c" +dependencies = [ + "bitflags 2.6.0", + "bytemuck", + "smallvec", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-properties", + "unicode-script", +] + [[package]] name = "ryu" version = "1.0.18" @@ -2398,7 +2443,7 @@ version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "922fd3eeab3bd820d76537ce8f582b1cf951eceb5475c28500c7457d9d17f53a" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "calloop", "calloop-wayland-source", "cursor-icon", @@ -2670,12 +2715,42 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cb788ffebc92c5948d0e997106233eeb1d8b9512f93f41651f52b6c5f5af86" + +[[package]] +name = "unicode-ccc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df77b101bcc4ea3d78dafc5ad7e4f58ceffe0b2b16bf446aeb50b6cb4157656" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-properties" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4259d9d4425d9f0661581b804cb85fe66a4c631cadd8f490d1c13a35d5d9291" + +[[package]] +name = "unicode-script" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad8d71f5726e5f285a935e9fe8edfd53f0491eb6e9a5774097fdabee7cd8c9cd" + [[package]] name = "unicode-segmentation" version = "1.11.0" @@ -2813,7 +2888,7 @@ version = "0.31.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e321577a0a165911bdcfb39cf029302479d7527b517ee58ab0f6ad09edf0943" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "rustix", "wayland-backend", "wayland-scanner", @@ -2825,7 +2900,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "625c5029dbd43d25e6aa9615e88b829a5cad13b2819c4ae129fdbb7c31ab4c7e" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "cursor-icon", "wayland-backend", ] @@ -2847,7 +2922,7 @@ version = "0.31.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-scanner", @@ -2859,7 +2934,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -2872,7 +2947,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ad1f61b76b6c2d8742e10f9ba5c3737f6530b4c243132c2a2ccc8aa96fe25cd6" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "wayland-backend", "wayland-client", "wayland-protocols", @@ -3192,7 +3267,7 @@ dependencies = [ "ahash", "android-activity", "atomic-waker", - "bitflags 2.5.0", + "bitflags 2.6.0", "bytemuck", "calloop", "cfg_aliases", @@ -3304,7 +3379,7 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d039de8032a9a8856a6be89cea3e5d12fdd82306ab7c94d74e6deab2460651c5" dependencies = [ - "bitflags 2.5.0", + "bitflags 2.6.0", "dlib", "log", "once_cell", diff --git a/Cargo.toml b/Cargo.toml index 4ee2c99..3e6123c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,6 +46,7 @@ tracker = "0.2.2" glsl = "7.0.0" glsl-quasiquote = "7.0.0" toml = "0.8.19" +femtovg = "0.9.2" [features] default = ["sdf_font"] @@ -53,3 +54,4 @@ default = ["sdf_font"] normal_font = [] sdf_font = [] inparser = [] +femtovg = [] diff --git a/src/main.rs b/src/main.rs index 3fc940b..688aafd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,5 +21,5 @@ static SETTING: Lazy = Lazy::new(|| setting::Setting::new()); fn main() { env_logger::init(); - run(move |gl| App::new(gl).unwrap()); + run(move |gl, helper| App::new(gl, helper).unwrap()); } diff --git a/src/pg/app.rs b/src/pg/app.rs index df1dfd7..a15ec1e 100644 --- a/src/pg/app.rs +++ b/src/pg/app.rs @@ -8,7 +8,10 @@ use crate::{ colormap::linear::LinearColormap, ppi::PPI, threed::Trackball, AttaWithBuffer, AttaWithProgram, Graphics, }, - ui::{State, GUI}, + ui::{ + helper::{self, Helper}, + State, GUI, + }, utils::{ cache::{Cache, CachedData}, resources::{ @@ -32,12 +35,12 @@ pub struct App<'gl> { } impl<'gl> App<'gl> { - pub fn new(gl: &'gl GL) -> Result { + pub fn new(gl: &'gl GL, helper: Helper) -> Result { let programs = Programs::new(gl).unwrap(); let mut default_state = State::default(); let mut gui = GUI::new(State::default()); let layout = gui.layout(gl); - let context = Context::new(gl, Cache::new(), programs); + let context = Context::new(gl, Cache::new(), helper, programs); Ok(Self { gui, gl, @@ -78,6 +81,7 @@ impl<'gl> App<'gl> { pub struct Context<'gl> { pub gl: &'gl GL, + pub helper: Helper, pub programs: Programs<'gl>, pub datapool: Cache>, } @@ -86,9 +90,11 @@ impl<'gl> Context<'gl> { fn new( gl: &'gl GL, datapool: Cache>, + helper: Helper, programs: Programs<'gl>, ) -> Self { let context = Context { + helper, datapool, programs, gl, diff --git a/src/pg/layout_type.rs b/src/pg/layout_type.rs index 7d97138..d364517 100644 --- a/src/pg/layout_type.rs +++ b/src/pg/layout_type.rs @@ -1,12 +1,14 @@ use crate::graphics::ty; use crate::pg::{Context, ModulePackage}; use crate::ui::typ::{LayoutAttach, MainLoadAttach}; -use crate::utils::resources::{ManagedResource, RcGlRcFramebuffer, RcGlRcRenderbuffer, GL}; +use crate::utils::resources::{ + ManagedResource, RcGlRcFramebuffer, RcGlRcRenderbuffer, RcGlRcResource, Resource, GL, +}; use crate::{errors::*, main}; -use glow::HasContext; +use glow::{HasContext, NativeRenderbuffer, NativeTexture}; -const RBO_WIDTH: i32 = 1920; -const RBO_HEIGHT: i32 = 1080; +const RBO_WIDTH: i32 = 3840; +const RBO_HEIGHT: i32 = 2160; // App Layout Type macro_rules! impl_layout { @@ -22,11 +24,12 @@ macro_rules! impl_layout { { let programs = &mut context.programs; let gl = programs.gl; + let helper = &mut context.helper; match self { $( Self::$name(typ) => { - typ.render_task(gl, programs)?; + typ.render_task(gl, programs, helper)?; } )+ } @@ -47,69 +50,14 @@ macro_rules! impl_layout { }; } -pub struct ViewPort { +pub struct ViewPort { renderer_size: [f32; 2], main_fbo: RcGlRcFramebuffer, - _main_rbo: RcGlRcRenderbuffer, + _main_rbo: RcGlRcResource, _main_depth_rbo: RcGlRcRenderbuffer, } -impl ViewPort { - pub fn new(gl: &GL) -> Self { - let main_fbo: RcGlRcFramebuffer = gl.create_resource_rc(); - let main_rbo: RcGlRcRenderbuffer = gl.create_resource_rc(); - let main_depth_rbo: RcGlRcRenderbuffer = gl.create_resource_rc(); - - main_fbo.bind(glow::FRAMEBUFFER); - - unsafe { - // Color Attachment - main_rbo.bind(glow::RENDERBUFFER); - gl.renderbuffer_storage(glow::RENDERBUFFER, glow::RGBA8, RBO_WIDTH, RBO_HEIGHT); - gl.framebuffer_renderbuffer( - glow::FRAMEBUFFER, - glow::COLOR_ATTACHMENT0, - glow::RENDERBUFFER, - Some(main_rbo.native()), - ); - main_rbo.unbind(glow::RENDERBUFFER); - - // Depth Attachment - main_depth_rbo.bind(glow::RENDERBUFFER); - gl.renderbuffer_storage( - glow::RENDERBUFFER, - glow::DEPTH_COMPONENT24, - RBO_WIDTH, - RBO_HEIGHT, - ); - - gl.framebuffer_renderbuffer( - glow::FRAMEBUFFER, - glow::DEPTH_ATTACHMENT, - glow::RENDERBUFFER, - Some(main_depth_rbo.native()), - ); - main_depth_rbo.unbind(glow::RENDERBUFFER); - - // gl.clear_color(1.0, 0.0, 0.0, 1.0); - // gl.clear(glow::COLOR_BUFFER_BIT); - // 检查帧缓冲是否完整 - if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE { - panic!("Framebuffer is not complete!"); - } - - gl.enable(glow::DEPTH_TEST); - } - main_fbo.unbind(glow::FRAMEBUFFER); - - Self { - renderer_size: [0.0, 0.0], - main_fbo, - _main_rbo: main_rbo, - _main_depth_rbo: main_depth_rbo, - } - } - +impl ViewPort { pub fn bind(&self, gl: &glow::Context) { self.main_fbo.bind(glow::FRAMEBUFFER); unsafe { @@ -140,6 +88,150 @@ impl ViewPort { } } +impl ViewPort { + pub fn new(gl: &GL, depth: bool) -> Self { + let main_fbo: RcGlRcFramebuffer = gl.create_resource_rc(); + let main_rbo: RcGlRcResource = gl.create_resource_rc(); + let main_depth_rbo: RcGlRcRenderbuffer = gl.create_resource_rc(); + + main_fbo.bind(glow::FRAMEBUFFER); + + unsafe { + // Color Attachment + gl.active_texture(glow::TEXTURE0); + main_rbo.bind(glow::TEXTURE_2D); + gl.tex_image_2d( + glow::TEXTURE_2D, + 0, + glow::RGBA8 as i32, + RBO_WIDTH, + RBO_HEIGHT, + 0, + glow::RGBA, + glow::UNSIGNED_BYTE, + None, + ); + + gl.tex_parameter_i32( + glow::TEXTURE_2D, + glow::TEXTURE_MIN_FILTER, + glow::LINEAR as i32, + ); + gl.tex_parameter_i32( + glow::TEXTURE_2D, + glow::TEXTURE_MAG_FILTER, + glow::LINEAR as i32, + ); + + gl.framebuffer_texture_2d( + glow::FRAMEBUFFER, + glow::COLOR_ATTACHMENT0, + glow::TEXTURE_2D, + Some(main_rbo.native()), + 0, + ); + + if depth { + // Depth Attachment + main_depth_rbo.bind(glow::RENDERBUFFER); + gl.renderbuffer_storage( + glow::RENDERBUFFER, + glow::DEPTH_COMPONENT24, + RBO_WIDTH, + RBO_HEIGHT, + ); + + gl.framebuffer_renderbuffer( + glow::FRAMEBUFFER, + glow::DEPTH_ATTACHMENT, + glow::RENDERBUFFER, + Some(main_depth_rbo.native()), + ); + main_depth_rbo.unbind(glow::RENDERBUFFER); + gl.enable(glow::DEPTH_TEST); + } + + gl.clear_color(0.0, 0.0, 0.0, 0.0); + gl.clear(glow::COLOR_BUFFER_BIT); + // 检查帧缓冲是否完整 + if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE { + panic!("Framebuffer is not complete!"); + } + } + main_fbo.unbind(glow::FRAMEBUFFER); + + Self { + renderer_size: [0.0, 0.0], + main_fbo, + _main_rbo: main_rbo, + _main_depth_rbo: main_depth_rbo, + } + } + + pub fn texture(&self) -> &RcGlRcResource { + &self._main_rbo + } +} + +impl ViewPort { + pub fn new(gl: &GL, depth: bool) -> Self { + let main_fbo: RcGlRcFramebuffer = gl.create_resource_rc(); + let main_rbo: RcGlRcRenderbuffer = gl.create_resource_rc(); + let main_depth_rbo: RcGlRcRenderbuffer = gl.create_resource_rc(); + + main_fbo.bind(glow::FRAMEBUFFER); + + unsafe { + // Color Attachment + main_rbo.bind(glow::RENDERBUFFER); + gl.renderbuffer_storage(glow::RENDERBUFFER, glow::RGBA8, RBO_WIDTH, RBO_HEIGHT); + gl.framebuffer_renderbuffer( + glow::FRAMEBUFFER, + glow::COLOR_ATTACHMENT0, + glow::RENDERBUFFER, + Some(main_rbo.native()), + ); + main_rbo.unbind(glow::RENDERBUFFER); + + if depth { + // Depth Attachment + main_depth_rbo.bind(glow::RENDERBUFFER); + gl.renderbuffer_storage( + glow::RENDERBUFFER, + glow::DEPTH_COMPONENT24, + RBO_WIDTH, + RBO_HEIGHT, + ); + + gl.framebuffer_renderbuffer( + glow::FRAMEBUFFER, + glow::DEPTH_ATTACHMENT, + glow::RENDERBUFFER, + Some(main_depth_rbo.native()), + ); + main_depth_rbo.unbind(glow::RENDERBUFFER); + + gl.enable(glow::DEPTH_TEST); + } + + gl.clear_color(0.0, 0.0, 0.0, 0.0); + gl.clear(glow::COLOR_BUFFER_BIT); + // 检查帧缓冲是否完整 + if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE { + panic!("Framebuffer is not complete!"); + } + } + main_fbo.unbind(glow::FRAMEBUFFER); + + Self { + renderer_size: [0.0, 0.0], + main_fbo, + _main_rbo: main_rbo, + _main_depth_rbo: main_depth_rbo, + } + } +} + impl_layout!( {MainLoad => MainLoadAttach<'gl>}, ); diff --git a/src/pg/mod.rs b/src/pg/mod.rs index 1c82522..edbc27c 100644 --- a/src/pg/mod.rs +++ b/src/pg/mod.rs @@ -1,4 +1,6 @@ mod app; +use femtovg::renderer::OpenGl; +use femtovg::Canvas; use glow::HasContext; pub mod layout_type; mod modules; @@ -168,4 +170,10 @@ impl ModulePackage<'_> { pub fn dirty(&mut self) { self.need_update = true; } + + pub fn helper_task(&self, canvas: &mut Canvas) -> bool { + match &self.modules { + _ModulePackage::PPI(ppi) => ppi.helper_layer(canvas), + } + } } diff --git a/src/pg/modules/mod.rs b/src/pg/modules/mod.rs index fb22777..5db5ba0 100644 --- a/src/pg/modules/mod.rs +++ b/src/pg/modules/mod.rs @@ -9,6 +9,7 @@ use crate::{ resources::{ManagedResource, RcGlBuffer, RcGlVertexArray}, }, }; +use femtovg::{renderer::OpenGl, Canvas}; use glow::{HasContext, NativeBuffer, NativeVertexArray}; mod ppi; use crate::errors::*; @@ -100,4 +101,8 @@ pub trait ModuleCursor { F: FnOnce(&mut Self::Config); fn ui_build(&mut self, ui: &imgui::Ui) -> bool; + + fn helper_layer(&self, canvas: &mut Canvas) -> bool { + false + } } diff --git a/src/pg/modules/ppi.rs b/src/pg/modules/ppi.rs index 4b06891..e41c5d2 100644 --- a/src/pg/modules/ppi.rs +++ b/src/pg/modules/ppi.rs @@ -2,6 +2,7 @@ use std::rc::Rc; use tracker::track; use crate::graphics::{font::Text, *}; +use crate::ui::helper_components::colorbar::colorbar; use crate::ui::operation::{self, Operation}; use crate::SETTING; use crate::{ @@ -153,6 +154,7 @@ pub struct PPIModuleConfig { } pub struct PPIPackage<'gl> { + draw_helper: bool, ppi_config: PPIModuleConfig, ppi_attach: Attach<'gl>, ppi_data: CachedData, @@ -161,6 +163,7 @@ pub struct PPIPackage<'gl> { impl<'gl> PPIPackage<'gl> { fn new(ppi_config: PPIModuleConfig, ppi_attach: Attach<'gl>, data: &CachedData) -> Self { Self { + draw_helper: true, ppi_config, ppi_attach, ppi_data: Rc::clone(data), @@ -193,4 +196,9 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> { self.ppi_config.set_is_three_d(is_three_d); self.ppi_config.changed_any() } + + fn helper_layer(&self, canvas: &mut femtovg::Canvas) -> bool { + colorbar(canvas, &self.ppi_config.colors, &vec![]); + true + } } diff --git a/src/shaders/colormap.rs b/src/shaders/colormap.rs index 77c24cc..1dc7825 100644 --- a/src/shaders/colormap.rs +++ b/src/shaders/colormap.rs @@ -32,7 +32,7 @@ impl ColorMap { float invalid = colormap_conf.w; - if (value == invalid) { + if (abs(value - invalid) < 0.0001) { return vec4(0.0, 0.0, 0.0, 0.0); } diff --git a/src/support/supporter.rs b/src/support/supporter.rs index 5bb56ae..f2f97c3 100644 --- a/src/support/supporter.rs +++ b/src/support/supporter.rs @@ -1,5 +1,6 @@ -use crate::{graphics::font, pg::App, utils::resources::GL}; +use crate::{graphics::font, pg::App, ui::helper::Helper, utils::resources::GL}; +use femtovg::renderer::OpenGl; use glow::HasContext; use glutin::{ config::ConfigTemplateBuilder, @@ -22,7 +23,7 @@ use std::time::Instant; pub fn run(mut app: F) where - F: for<'b> FnMut(&'b GL) -> App<'b>, + F: for<'b> FnMut(&'b GL, Helper) -> App<'b>, { // Create Window let (event_loop, window, surface, context) = create_window(); @@ -39,8 +40,10 @@ where let gl_context = ig_renderer.gl_context().clone(); let gl = GL::new(gl_app); + let helper = helper(&gl, &context); + // App instance - let mut app = app(&gl); + let mut app = app(&gl, helper); let mut run = true; // Prepare @@ -183,6 +186,14 @@ fn glow_context(context: &PossiblyCurrentContext) -> glow::Context { } } +fn helper<'a>(gl: &'a GL, context: &PossiblyCurrentContext) -> Helper { + let renderer = unsafe { + OpenGl::new_from_function_cstr(|s| context.display().get_proc_address(s).cast()).unwrap() + }; + + Helper::new(gl, renderer) +} + fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) { let mut imgui_context = imgui::Context::create(); imgui_context.set_ini_filename(None); diff --git a/src/ui/helper.rs b/src/ui/helper.rs new file mode 100644 index 0000000..fd6b0dc --- /dev/null +++ b/src/ui/helper.rs @@ -0,0 +1,52 @@ +use crate::{ + pg::{layout_type::ViewPort, ModulePackage}, + utils::resources::GL, +}; +use femtovg::{renderer::OpenGl, Canvas}; +use glow::{NativeRenderbuffer, NativeTexture}; + +pub struct Helper { + canvas: Canvas, + viewport: ViewPort, +} + +impl Helper { + pub fn new(gl: &GL, mut renderer: OpenGl) -> Self { + let mut viewport = ViewPort::::new(gl, false); + renderer.set_screen_target(Some(viewport.fbo().native())); + let mut canvas = Canvas::new(renderer).expect("Cannot create canvas"); + + viewport.set_size([3840.0, 2160.0]); + canvas.set_size(3840, 2160, 1.0); + + Self { canvas, viewport } + } + + pub fn canvas(&mut self) -> &mut Canvas { + &mut self.canvas + } + + pub fn set_size(&mut self, size: [f32; 2], dpi: f32) { + self.viewport.set_size([size[0] * dpi, size[1] * dpi]); + self.canvas.set_size(size[0] as u32, size[1] as u32, dpi); + } + + pub fn render_task(&mut self, gl: &glow::Context, f: impl FnOnce(&mut Canvas)) { + self.viewport.bind(gl); + f(&mut self.canvas); + self.canvas.flush(); + self.viewport.unbind(); + } + + pub fn viewport(&self) -> &ViewPort { + &self.viewport + } + + pub fn draw_modules(&mut self, gl: &glow::Context, modules: &Vec) { + self.render_task(gl, |canvas| { + for module in modules { + module.helper_task(canvas); + } + }); + } +} diff --git a/src/ui/helper_components/colorbar.rs b/src/ui/helper_components/colorbar.rs new file mode 100644 index 0000000..8aa7c53 --- /dev/null +++ b/src/ui/helper_components/colorbar.rs @@ -0,0 +1,25 @@ +use femtovg::{renderer::OpenGl, Canvas, Color, Paint, Path}; + +pub fn colorbar(canvas: &mut Canvas, colors: &Vec<[u8; 4]>, ticks: &Vec) { + let width = canvas.width(); + let height = canvas.height(); + + let mut path = Path::new(); + + path.rect(0.0, 200.0, (width / 2) as f32, 200.0); + + let paint = Paint::color(femtovg::Color::from(Color::rgba(255, 0, 0, 255))); + canvas.fill_path(&mut path, &paint); + + // for (i, color) in colors.iter().enumerate() { + // let y = i as f32 * 100.0 / colors.len() as f32; + // let y1 = (i + 1) as f32 * 100.0 / colors.len() as f32; + + // let color = femtovg::Color::from(Color::rgba(color[0], color[1], color[2], color[3])); + // let paint = Paint::color(color); + + // path.rect(20.0, y1, 50.0, 100.0 / colors.len() as f32); + // let paint = Paint::color(color); + // canvas.fill_path(&mut path, &paint); + // } +} diff --git a/src/ui/helper_components/mod.rs b/src/ui/helper_components/mod.rs new file mode 100644 index 0000000..d5ee704 --- /dev/null +++ b/src/ui/helper_components/mod.rs @@ -0,0 +1 @@ +pub mod colorbar; diff --git a/src/ui/mod.rs b/src/ui/mod.rs index abd1d74..3052f47 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -13,11 +13,13 @@ use glow::{NativeFramebuffer, NativeRenderbuffer}; use imgui::*; #[macro_use] mod layout; +pub mod helper; pub mod io; mod state; pub mod typ; pub use layout::*; pub use state::State; +pub mod helper_components; pub mod operation; pub struct GUI { diff --git a/src/ui/typ/main_load.rs b/src/ui/typ/main_load.rs index daac37e..e669a64 100644 --- a/src/ui/typ/main_load.rs +++ b/src/ui/typ/main_load.rs @@ -6,11 +6,13 @@ use crate::graphics::threed::Trackball; use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState}; use crate::pg::ModulePackage; use crate::pg::{_ModulePackage, layout_type::ViewPort}; +use crate::ui::helper::Helper; use crate::ui::io::IO; use crate::ui::operation::Operation; use crate::utils::resources::GL; -use glow::HasContext; -use imgui::{Condition, Ui, WindowFlags}; +use bytemuck::Contiguous; +use glow::{HasContext, NativeRenderbuffer}; +use imgui::{Condition, TextureId, Ui, WindowFlags}; use nalgebra_glm::Vec3; pub struct MainLoad {} @@ -80,14 +82,14 @@ impl LayoutMod for MainLoad { let content_size = ui.content_region_avail(); apptyp.main_viewport.set_size(content_size); + // context.helper.set_size(content_size, scale[0]); - // ui.set_cursor_screen_pos([pos[0] + size[0], pos[1] + size[1]]); let draws = ui.get_window_draw_list(); draws.channels_split(2, |channels| { channels.set_current(0); let fbo = apptyp.main_viewport.fbo(); - let fbo = fbo.native(); + let main_fbo = fbo.native(); draws .add_callback({ @@ -95,9 +97,7 @@ impl LayoutMod for MainLoad { let x = pos[0] * scale[0]; let y = (dsp_size[1] - pos[1]) * scale[1]; - // gl.enable(glow::SCISSOR_TEST); - // gl.scissor(0, 0, size[0] as i32, size[1] as i32); - gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(fbo)); + gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(main_fbo)); gl.blit_framebuffer( 0, 0, @@ -116,20 +116,21 @@ impl LayoutMod for MainLoad { .build(); channels.set_current(1); - draws - .add_circle( - [pos[0] + 200.0, pos[1] + 200.0], - 50.0, - [1.0, 0.0, 0.0, 1.0], - ) - .filled(true) - .build(); - draws.add_text( - [pos[0] + 300.0, pos[1] + 300.0], - [1.0, 1.0, 1.0, 1.0], - "Hello World", - ); + let helper = context.helper.viewport(); + let texture = helper.texture().native(); + let gl = context.gl.gl_rc(); + + draws + .add_image( + TextureId::new(texture.0.into_integer() as usize), + pos, + [ + pos[0] + content_size[0] * scale[0], + pos[1] + content_size[1] * scale[1], + ], + ) + .build(); }); if ui.is_window_hovered() { @@ -142,7 +143,7 @@ impl LayoutMod for MainLoad { fn init<'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl> { let typ = MainLoadAttach { - main_viewport: ViewPort::new(gl), + main_viewport: ViewPort::::new(gl, true), packages: Vec::new(), operation: Operation::new(Trackball::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0), }; @@ -188,9 +189,13 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> { &mut self, gl: &glow::Context, programs: &mut crate::pg::Programs<'gl>, + helper: &mut Helper, ) -> crate::errors::Result<()> { - self.main_viewport.bind(gl); + 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); + unsafe { gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); } @@ -206,6 +211,7 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> { } } self.main_viewport.unbind(); + Ok(()) } } diff --git a/src/ui/typ/mod.rs b/src/ui/typ/mod.rs index eb41e2c..27cf9f0 100644 --- a/src/ui/typ/mod.rs +++ b/src/ui/typ/mod.rs @@ -1,5 +1,6 @@ use std::fmt::Debug; +use super::helper; use super::io::IO; use super::layout::{Layout, Size}; mod main_load; @@ -61,6 +62,7 @@ pub trait LayoutAttach<'gl> { &mut self, gl: &glow::Context, programs: &mut Programs<'gl>, + helper: &mut helper::Helper, ) -> crate::errors::Result<()>; } diff --git a/src/utils/resources.rs b/src/utils/resources.rs index 3950efa..7ccccb8 100644 --- a/src/utils/resources.rs +++ b/src/utils/resources.rs @@ -67,7 +67,7 @@ impl Deref for RcGlRcResource { } } -trait Resource: Clone + std::fmt::Debug { +pub trait Resource: Clone + std::fmt::Debug { fn drop_self(&self, gl: &glow::Context); fn create(gl: &glow::Context) -> Self;