pusher
This commit is contained in:
parent
f25ed801f5
commit
e8f3b2bc47
183
Cargo.lock
generated
183
Cargo.lock
generated
@ -282,6 +282,15 @@ version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-sys"
|
||||
version = "0.2.1"
|
||||
@ -452,7 +461,7 @@ dependencies = [
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"wasm-bindgen",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -550,6 +559,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
@ -590,12 +608,32 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cursor-icon"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96a6ac251f4a2aca6b3f91340350eab87ae57c3f127ffeb585e92bd336717991"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs"
|
||||
version = "5.0.1"
|
||||
@ -729,6 +767,12 @@ dependencies = [
|
||||
"zune-inflate",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.4"
|
||||
@ -840,6 +884,16 @@ dependencies = [
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "geo"
|
||||
version = "0.28.0"
|
||||
@ -1353,7 +1407,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c2a198fb6b0eada2a8df47933734e6d35d350665a33a3593d7164fa52c75c19"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1821,7 +1875,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall 0.5.1",
|
||||
"smallvec",
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -2015,8 +2069,10 @@ dependencies = [
|
||||
"pathfinder_geometry",
|
||||
"raw-window-handle 0.5.2",
|
||||
"regex",
|
||||
"rust-embed",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"tinyfiledialogs",
|
||||
"toml",
|
||||
@ -2234,6 +2290,40 @@ dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed"
|
||||
version = "8.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0"
|
||||
dependencies = [
|
||||
"rust-embed-impl",
|
||||
"rust-embed-utils",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-impl"
|
||||
version = "8.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"rust-embed-utils",
|
||||
"syn 2.0.66",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-embed-utils"
|
||||
version = "8.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d"
|
||||
dependencies = [
|
||||
"sha2",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.0"
|
||||
@ -2373,6 +2463,17 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simba"
|
||||
version = "0.8.1"
|
||||
@ -2557,6 +2658,19 @@ version = "0.12.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4873307b7c257eddcb50c9bedf158eb669578359fb28428bef438fec8e6ba7c2"
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"fastrand",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.61"
|
||||
@ -3051,7 +3165,7 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3078,7 +3192,16 @@ version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.5",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3113,18 +3236,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.5",
|
||||
"windows_aarch64_msvc 0.52.5",
|
||||
"windows_i686_gnu 0.52.5",
|
||||
"windows_aarch64_gnullvm 0.52.6",
|
||||
"windows_aarch64_msvc 0.52.6",
|
||||
"windows_i686_gnu 0.52.6",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc 0.52.5",
|
||||
"windows_x86_64_gnu 0.52.5",
|
||||
"windows_x86_64_gnullvm 0.52.5",
|
||||
"windows_x86_64_msvc 0.52.5",
|
||||
"windows_i686_msvc 0.52.6",
|
||||
"windows_x86_64_gnu 0.52.6",
|
||||
"windows_x86_64_gnullvm 0.52.6",
|
||||
"windows_x86_64_msvc 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3141,9 +3264,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
@ -3159,9 +3282,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
@ -3177,15 +3300,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
@ -3201,9 +3324,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
@ -3219,9 +3342,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
@ -3237,9 +3360,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
@ -3255,9 +3378,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "winit"
|
||||
|
||||
@ -47,6 +47,8 @@ glsl = "7.0.0"
|
||||
glsl-quasiquote = "7.0.0"
|
||||
toml = "0.8.19"
|
||||
femtovg = "0.9.2"
|
||||
rust-embed = "8.5.0"
|
||||
tempfile = "3.12.0"
|
||||
|
||||
[features]
|
||||
default = ["sdf_font"]
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::errors::*;
|
||||
use crate::{errors::*, Asset};
|
||||
use dirs::font_dir;
|
||||
use freetype::face::LoadFlag;
|
||||
use freetype::{Face, GlyphMetrics, Library};
|
||||
@ -7,26 +7,46 @@ use image::GrayImage;
|
||||
use image::ImageBuffer;
|
||||
use log::*;
|
||||
use std::collections::HashMap;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
use std::{env, fs};
|
||||
pub struct FontManager {
|
||||
library: Library,
|
||||
fonts: HashMap<String, Font>,
|
||||
}
|
||||
use tempfile::NamedTempFile;
|
||||
|
||||
impl FontManager {
|
||||
pub fn new() -> Result<Self> {
|
||||
// let source = fk::source::SystemSource::new();
|
||||
|
||||
let library = Library::init().map_err(|e| Error::InitError(e.into()))?;
|
||||
|
||||
let root_path = font_dir().map_or_else(
|
||||
|| {
|
||||
error!("Font dir not found");
|
||||
Err(Error::InitError(anyhow::anyhow!("Font dir not found")))
|
||||
},
|
||||
|font_dir| {
|
||||
info!("Font dir: {:?}", font_dir);
|
||||
Ok(font_dir)
|
||||
},
|
||||
)?;
|
||||
let root_path = font_dir().unwrap_or_else(|| {
|
||||
let default_font = Asset::get("Roboto-Regular.ttf").unwrap();
|
||||
let exe_path = env::current_exe().unwrap();
|
||||
let mut folder_path = exe_path.parent().unwrap().to_path_buf();
|
||||
folder_path.push("resources");
|
||||
|
||||
if folder_path.exists() {
|
||||
info!("Resources Folder exists");
|
||||
} else {
|
||||
fs::create_dir_all(&folder_path).unwrap();
|
||||
}
|
||||
|
||||
folder_path
|
||||
});
|
||||
|
||||
// let root_path = font_dir().map_or_else(
|
||||
// || {
|
||||
// error!("Font dir not found");
|
||||
// Err(Error::InitError(anyhow::anyhow!("Font dir not found")))
|
||||
// },
|
||||
// |font_dir| {
|
||||
// info!("Font dir: {:?}", font_dir);
|
||||
// Ok(font_dir)
|
||||
// },
|
||||
// )?;
|
||||
|
||||
Ok(Self {
|
||||
library,
|
||||
|
||||
@ -145,7 +145,6 @@ impl AttaWithBuffer for AggFastPath {
|
||||
sum += num;
|
||||
}
|
||||
|
||||
let point_lens = data.iter().map(|d| d.len()).collect::<Vec<_>>();
|
||||
let mut vbo = Vec::with_capacity(points.len() * 10);
|
||||
for p in points {
|
||||
vbo.extend_from_slice(&[
|
||||
@ -155,15 +154,9 @@ impl AttaWithBuffer for AggFastPath {
|
||||
}
|
||||
let mut ebo = vec![];
|
||||
for (idx, e) in data.iter().map(|v| &v.ebo).enumerate() {
|
||||
if idx > 0 {
|
||||
let len = lens[idx - 1] as u32;
|
||||
for e in e.iter() {
|
||||
ebo.extend_from_slice(&[e[0] + len, e[1] + len, e[2] + len]);
|
||||
}
|
||||
} else {
|
||||
for e in e.iter() {
|
||||
ebo.extend_from_slice(e);
|
||||
}
|
||||
let len = lens[idx] as u32;
|
||||
for e in e.iter() {
|
||||
ebo.extend_from_slice(&[e[0] + len, e[1] + len, e[2] + len]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -120,7 +120,7 @@ pub enum Config {
|
||||
|
||||
config_for_everyitem!({PPIConfig => PPI},{FontConfig => Font}, );
|
||||
|
||||
pub trait AttachWithMouse {
|
||||
pub trait AttachWithIO {
|
||||
type State: CameraOP;
|
||||
fn attach_with_mouse(
|
||||
&mut self,
|
||||
@ -141,3 +141,9 @@ pub enum MouseState {
|
||||
Wheel(f32),
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct MouseKeyboardState {
|
||||
pub mouse_state: MouseState,
|
||||
pub keyboard_state: [bool; 652],
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
use super::colormap::ColorMap;
|
||||
use super::transforms::viewport::Viewport;
|
||||
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics};
|
||||
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithIO, Config, Graphics};
|
||||
use crate::components::{CodeType, Program, Shader};
|
||||
use crate::data_loader::{CoordType, Data, DataType};
|
||||
use crate::errors::*;
|
||||
|
||||
@ -2,7 +2,7 @@ use std::rc::Rc;
|
||||
use tracker::track;
|
||||
|
||||
use super::transforms::{position::Position, trackball::TrackballModel};
|
||||
use super::{AttaWithProgram, AttachWithMouse};
|
||||
use super::{AttaWithProgram, AttachWithIO};
|
||||
use crate::camera::{self, Camera};
|
||||
use crate::errors::*;
|
||||
use crate::pg::layout_type::ViewPort;
|
||||
@ -17,7 +17,7 @@ pub struct Trackball {
|
||||
|
||||
impl Trackball {
|
||||
pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result<Self> {
|
||||
let trackball = TrackballModel::new(0.0, 90.0);
|
||||
let trackball = TrackballModel::new(0.0, 90.0, 20.0);
|
||||
|
||||
Ok(Self { trackball })
|
||||
}
|
||||
@ -40,7 +40,7 @@ impl AttaWithProgram for Trackball {
|
||||
}
|
||||
}
|
||||
|
||||
impl AttachWithMouse for Trackball {
|
||||
impl AttachWithIO for Trackball {
|
||||
type State = super::MouseState;
|
||||
fn attach_with_mouse(
|
||||
&mut self,
|
||||
|
||||
@ -1,17 +1,53 @@
|
||||
use crate::components::{CodeType, Program, Snippet};
|
||||
use crate::errors::Result;
|
||||
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
|
||||
use crate::graphics::{AttaWithProgram, AttachWithIO, MouseKeyboardState, MouseState};
|
||||
use crate::pg::layout_type::ViewPort;
|
||||
use crate::ui::operation::Projection;
|
||||
|
||||
use glow::HasContext;
|
||||
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
|
||||
use nalgebra_glm::vec3;
|
||||
use serde::de;
|
||||
|
||||
use super::trackball::{self, TrackballModel};
|
||||
use super::viewport;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct PlaneTrans {}
|
||||
pub struct PlaneTrans {
|
||||
trackball: TrackballModel,
|
||||
}
|
||||
|
||||
impl AttachWithMouse for PlaneTrans {
|
||||
type State = MouseState;
|
||||
impl PlaneTrans {
|
||||
fn translate(
|
||||
&self,
|
||||
projection: &Projection,
|
||||
camera: &mut crate::camera::Camera,
|
||||
delta: &[f32; 2],
|
||||
viewport_size: &[f32; 2],
|
||||
) {
|
||||
let watch_vec = camera.front();
|
||||
let fov = projection.fov().to_radians();
|
||||
let aspect = projection.aspect();
|
||||
|
||||
// Z_near
|
||||
let z_distance = camera.front().norm().abs();
|
||||
|
||||
let h = 2.0 * z_distance * (fov / 2.0).tan();
|
||||
let w = h * aspect;
|
||||
|
||||
let move_width = (delta[0] * w) / viewport_size[0];
|
||||
let move_height = (delta[1] * h) / viewport_size[1];
|
||||
|
||||
let up = camera.get_upward();
|
||||
let right = watch_vec.cross(&up).normalize();
|
||||
let _move = move_width * right + move_height * up;
|
||||
camera.set_position(camera.get_position() - _move);
|
||||
camera.set_center(camera.get_center() - _move);
|
||||
}
|
||||
}
|
||||
|
||||
impl AttachWithIO for PlaneTrans {
|
||||
type State = MouseKeyboardState;
|
||||
|
||||
fn attach_with_mouse(
|
||||
&mut self,
|
||||
@ -20,47 +56,50 @@ impl AttachWithMouse for PlaneTrans {
|
||||
projection: &mut crate::ui::operation::Projection,
|
||||
viewport: &ViewPort,
|
||||
) -> bool {
|
||||
let watch_vec = camera.front();
|
||||
let viewport_size = viewport.size();
|
||||
let if_vertical = true;
|
||||
let shift_key = state.keyboard_state[imgui::Key::LeftShift as usize];
|
||||
let ctrl_key = state.keyboard_state[imgui::Key::LeftCtrl as usize];
|
||||
|
||||
match state {
|
||||
match &state.mouse_state {
|
||||
MouseState::Drag { from, delta } => {
|
||||
if if_vertical {
|
||||
// Radian
|
||||
let fov = projection.fov().to_radians();
|
||||
let aspect = projection.aspect();
|
||||
|
||||
// Z_near
|
||||
let z_near = projection.z_near();
|
||||
|
||||
let h = 2.0 * z_near * (fov / 2.0).tan();
|
||||
let w = h * aspect;
|
||||
|
||||
let move_width = (delta[0] * w) / viewport_size[0];
|
||||
let move_height = (delta[1] * h) / viewport_size[1];
|
||||
|
||||
let up = camera.get_upward();
|
||||
let right = watch_vec.cross(&up).normalize();
|
||||
let _move = move_width * right + move_height * up;
|
||||
|
||||
camera.set_position(camera.get_position() + _move);
|
||||
camera.set_center(camera.get_center() + _move);
|
||||
if shift_key {
|
||||
self.trackball.drag_to(
|
||||
from[0] - viewport_size[0] / 2.0,
|
||||
from[1] - viewport_size[1] / 2.0,
|
||||
0.0,
|
||||
-delta[1],
|
||||
);
|
||||
} else if ctrl_key {
|
||||
self.trackball.drag_to(
|
||||
from[0] - viewport_size[0] / 2.0,
|
||||
from[1] - viewport_size[1] / 2.0,
|
||||
-delta[0],
|
||||
0.0,
|
||||
);
|
||||
} else if shift_key && ctrl_key {
|
||||
self.trackball.drag_to(
|
||||
from[0] - viewport_size[0] / 2.0,
|
||||
from[1] - viewport_size[1] / 2.0,
|
||||
-delta[0],
|
||||
-delta[1],
|
||||
)
|
||||
} else {
|
||||
self.translate(projection, camera, delta, &viewport_size);
|
||||
}
|
||||
true
|
||||
}
|
||||
MouseState::Wheel(delta) => {
|
||||
projection.set_fov((projection.fov() - delta).clamp(15.0, 120.0));
|
||||
true
|
||||
}
|
||||
_ => {}
|
||||
_ => false,
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn init_camera(&self) -> crate::camera::Camera {
|
||||
crate::camera::Camera::new(
|
||||
vec3(0.0, 20.0, 0.0),
|
||||
vec3(0.0, 0.0, 1.0),
|
||||
vec3(0.0, 0.0, 20.0),
|
||||
vec3(0.0, 1.0, 0.0),
|
||||
vec3(0.0, 0.0, 0.0),
|
||||
)
|
||||
}
|
||||
@ -72,10 +111,7 @@ impl AttaWithProgram for PlaneTrans {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
unsafe {
|
||||
let loc = program.get_uniform_location(gl, "trackball_model");
|
||||
|
||||
let trackball = nalgebra_glm::rotate_x(&nalgebra_glm::identity(), 90.0f32.to_radians());
|
||||
|
||||
gl.uniform_matrix_4_f32_slice(loc.as_ref(), false, trackball.as_slice());
|
||||
self.trackball.attach_with_program(gl, program)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@ -83,6 +119,7 @@ impl AttaWithProgram for PlaneTrans {
|
||||
|
||||
impl Default for PlaneTrans {
|
||||
fn default() -> Self {
|
||||
Self {}
|
||||
let trackball = TrackballModel::new(0.0, 0.0, 200.0);
|
||||
Self { trackball }
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,13 +19,13 @@ pub struct TrackballModel {
|
||||
}
|
||||
|
||||
impl TrackballModel {
|
||||
pub fn new(theta: f32, phi: f32) -> Self {
|
||||
pub fn new(phi: f32, theta: f32, range: f32) -> Self {
|
||||
let mut trackball = Self {
|
||||
rotation: UnitQuaternion::identity(),
|
||||
count: 0,
|
||||
model: Matrix4::identity(),
|
||||
renorm_count: 97,
|
||||
trackball_size: 20.0,
|
||||
trackball_size: range,
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
theta,
|
||||
@ -35,6 +35,17 @@ impl TrackballModel {
|
||||
trackball
|
||||
}
|
||||
|
||||
pub fn rotate_z(&mut self, angle: f32) {
|
||||
let q = UnitQuaternion::from_axis_angle(&Vector3::z_axis(), angle);
|
||||
self.rotation *= q;
|
||||
self.count += 1;
|
||||
if self.count > self.renorm_count {
|
||||
self.rotation = UnitQuaternion::new_normalize(*self.rotation.clone());
|
||||
self.count = 0;
|
||||
}
|
||||
self.model = self.rotation.to_homogeneous();
|
||||
}
|
||||
|
||||
pub fn drag_to(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
let q = self.rotate(x, y, dx, dy);
|
||||
self.rotation *= q;
|
||||
@ -159,7 +170,7 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_trackball() {
|
||||
let mut trackball = TrackballModel::new(45.0, 45.0);
|
||||
let mut trackball = TrackballModel::new(45.0, 45.0, 20.0);
|
||||
println!("{:?}", trackball.model());
|
||||
|
||||
trackball.drag_to(0.0, 10.0, 15.0, 30.0);
|
||||
|
||||
@ -15,6 +15,12 @@ mod utils;
|
||||
|
||||
use pg::App;
|
||||
use support::supporter::run;
|
||||
use rust_embed::RustEmbed;
|
||||
|
||||
|
||||
#[derive(RustEmbed)]
|
||||
#[folder = "resources/"]
|
||||
pub struct Asset;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
static SETTING: Lazy<setting::Setting> = Lazy::new(|| setting::Setting::new());
|
||||
|
||||
@ -13,7 +13,7 @@ use crate::graphics::ppi::PPI;
|
||||
use crate::graphics::threed::Trackball;
|
||||
use crate::graphics::transforms::plane::PlaneTrans;
|
||||
use crate::graphics::transforms::viewport;
|
||||
use crate::graphics::{AttaWithProgram, AttachWithMouse};
|
||||
use crate::graphics::{AttaWithProgram, AttachWithIO};
|
||||
use crate::ui::operation::Operation;
|
||||
use crate::ui::typ::LayoutAttach;
|
||||
use crate::utils::cache::CachedData;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
use crate::{
|
||||
graphics::AttachWithMouse,
|
||||
graphics::AttachWithIO,
|
||||
ui::{
|
||||
operation::{self, Operation},
|
||||
typ::CameraOP,
|
||||
@ -59,22 +59,19 @@ impl<'a> Attach<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn bind_data(&mut self, vbo: &Vec<f32>, ebo: Option<&Vec<u32>>, len: i32) {
|
||||
fn bind_data(&mut self, vbo: &Vec<f32>, ebo: Option<&Vec<u32>>, len: i32, usage: u32) {
|
||||
use bytemuck::cast_slice;
|
||||
self.vbo.bind(glow::ARRAY_BUFFER);
|
||||
unsafe {
|
||||
self.gl
|
||||
.buffer_data_u8_slice(glow::ARRAY_BUFFER, cast_slice(&vbo), glow::STATIC_DRAW);
|
||||
.buffer_data_u8_slice(glow::ARRAY_BUFFER, cast_slice(&vbo), usage);
|
||||
if let Some(ebo) = ebo {
|
||||
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
|
||||
.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, cast_slice(&ebo), usage);
|
||||
|
||||
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
||||
}
|
||||
@ -91,7 +88,7 @@ impl<'a> Attach<'a> {
|
||||
pub trait Module: Sized {
|
||||
type Cursor: ModuleCursor;
|
||||
type Data;
|
||||
type Operation: AttachWithMouse;
|
||||
type Operation: AttachWithIO;
|
||||
|
||||
fn render(
|
||||
&mut self,
|
||||
|
||||
@ -55,7 +55,7 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
config: &PPIModuleConfig,
|
||||
) -> Result<()> {
|
||||
let (vbo, ebo, len) = self.ppi_program.bake(data, &config.to_ppi_config())?;
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len);
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::DYNAMIC_DRAW);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -65,19 +65,25 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
data: &Data,
|
||||
config: &PPIModuleConfig,
|
||||
) -> Result<()> {
|
||||
let config = config.to_line_config();
|
||||
let raw_config = config.to_line_config();
|
||||
|
||||
// Will be changed in the future
|
||||
let outskirt = 10.0;
|
||||
|
||||
let mut paths = vec![];
|
||||
|
||||
for range in 1..=6 {
|
||||
let r = outskirt / 5.0 * range as f32;
|
||||
let range_line_num = config.range_line_num;
|
||||
let r = outskirt / range_line_num as f32;
|
||||
let seg_num = 200;
|
||||
let angle = 2f32 * f32::consts::PI / seg_num as f32;
|
||||
|
||||
for range in 1..=range_line_num {
|
||||
// Create the path
|
||||
let mut path = Path::new(true);
|
||||
let r = r * range as f32;
|
||||
// Draw the circle
|
||||
for seg in 0..200 {
|
||||
let angle = 2f32 * f32::consts::PI / 200.0 * seg as f32;
|
||||
for seg in 0..seg_num {
|
||||
let angle = angle * seg as f32;
|
||||
let x = (angle.cos() * r) as f32;
|
||||
let y = (angle.sin() * r) as f32;
|
||||
path.push([x, y, 0.01]);
|
||||
@ -86,9 +92,10 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
let a = 2.0 * f32::consts::PI / 6.0;
|
||||
let ath_lin_num = config.ath_line_num;
|
||||
|
||||
for _a in 0..7 {
|
||||
let a = 2.0 * f32::consts::PI / ath_lin_num as f32;
|
||||
for _a in 0..=ath_lin_num {
|
||||
let mut path = Path::new(false);
|
||||
let x = (a * _a as f32).cos() * outskirt;
|
||||
let y = (a * _a as f32).sin() * outskirt;
|
||||
@ -98,8 +105,16 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
let (vbo, ebo, len) = self.line_program.bake(&paths, &config)?;
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len);
|
||||
if config.vertical_axis {
|
||||
let mut path = Path::new(false);
|
||||
path.push([0.0, 0.0, 0.0]);
|
||||
path.push([0.0, 0.0, outskirt]);
|
||||
path.finish();
|
||||
paths.push(path);
|
||||
}
|
||||
|
||||
let (vbo, ebo, len) = self.line_program.bake(&paths, &raw_config)?;
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -113,7 +128,7 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
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);
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,6 +166,13 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
self.bind_ppi_pg(ppi_attach, data, config);
|
||||
}
|
||||
|
||||
if config.changed_range_line_num()
|
||||
|| config.changed_ath_line_num()
|
||||
|| config.changed_vertical_axis()
|
||||
{
|
||||
self.bind_line_pg(&mut cursor.line_attach, data, config)?;
|
||||
}
|
||||
|
||||
// PPI Draw
|
||||
ppi_attach.bind_self();
|
||||
self.ppi_program.draw(&self.gl, ppi_attach.len())?;
|
||||
@ -304,15 +326,27 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> {
|
||||
|
||||
let mut line_width = self.ppi_config.line_width;
|
||||
let mut line_antialias = self.ppi_config.line_antialias;
|
||||
let mut range_line_num = self.ppi_config.range_line_num;
|
||||
let mut ath_line_num = self.ppi_config.ath_line_num;
|
||||
|
||||
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);
|
||||
ui.slider("Range Line Num", 0, 10, &mut range_line_num);
|
||||
ui.slider("Ath Line Num", 0, 10, &mut ath_line_num);
|
||||
|
||||
ui.separator();
|
||||
|
||||
let mut value = self.ppi_config.vertical_axis;
|
||||
ui.checkbox("Axis?", &mut value);
|
||||
|
||||
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.set_range_line_num(range_line_num);
|
||||
self.ppi_config.set_ath_line_num(ath_line_num);
|
||||
self.ppi_config.set_vertical_axis(value);
|
||||
self.ppi_config.changed_any()
|
||||
}
|
||||
|
||||
@ -329,6 +363,9 @@ pub struct PPIModuleConfig {
|
||||
pub line_color: [f32; 4],
|
||||
pub line_width: f32,
|
||||
pub line_antialias: f32,
|
||||
pub range_line_num: usize,
|
||||
pub ath_line_num: usize,
|
||||
pub vertical_axis: bool,
|
||||
pub layer: usize,
|
||||
pub colors: Vec<[u8; 4]>,
|
||||
pub color_range: [f32; 2],
|
||||
@ -354,6 +391,9 @@ impl Default for PPIModuleConfig {
|
||||
line_width: 1.5,
|
||||
line_antialias: 0.5,
|
||||
layer: 0,
|
||||
vertical_axis: false,
|
||||
range_line_num: 5,
|
||||
ath_line_num: 6,
|
||||
colors: vec![],
|
||||
color_range: [0.0, 0.0],
|
||||
is_three_d: true,
|
||||
|
||||
17
src/ui/io.rs
17
src/ui/io.rs
@ -10,7 +10,7 @@ pub struct MouseIO {
|
||||
}
|
||||
|
||||
pub struct KeyboardIO {
|
||||
pub keys: [bool; 512], // 键盘按键状态
|
||||
pub keys: [bool; 652], // 键盘按键状态
|
||||
}
|
||||
|
||||
pub struct IO {
|
||||
@ -23,7 +23,8 @@ impl IO {
|
||||
let io = ui.io();
|
||||
|
||||
let delta = if ui.is_mouse_dragging(imgui::MouseButton::Left) {
|
||||
let delta = ui.mouse_drag_delta_with_threshold(imgui::MouseButton::Left, 5.0);
|
||||
// let delta = ui.mouse_drag_delta_with_threshold(imgui::MouseButton::Left, 5.0);
|
||||
let delta = ui.mouse_drag_delta_with_button(imgui::MouseButton::Left);
|
||||
ui.reset_mouse_drag_delta(imgui::MouseButton::Left);
|
||||
Some(delta)
|
||||
} else {
|
||||
@ -31,20 +32,22 @@ impl IO {
|
||||
};
|
||||
|
||||
let windows_position = ui.window_pos();
|
||||
let inner_pad = ui.window_content_region_min();
|
||||
let position = [
|
||||
io.mouse_pos[0] - windows_position[0] - inner_pad[0],
|
||||
io.mouse_pos[1] - windows_position[1] - inner_pad[1],
|
||||
];
|
||||
|
||||
IO {
|
||||
mouse: MouseIO {
|
||||
position: [
|
||||
io.mouse_pos[0] - windows_position[0],
|
||||
io.mouse_pos[1] - windows_position[1],
|
||||
],
|
||||
position: position,
|
||||
drag_delta: delta,
|
||||
is_dragging: ui.is_mouse_dragging(imgui::MouseButton::Left),
|
||||
left_button_pressed: io.mouse_down[0],
|
||||
right_button_pressed: io.mouse_down[1],
|
||||
wheel_delta: io.mouse_wheel,
|
||||
},
|
||||
keyboard: KeyboardIO { keys: [false; 512] },
|
||||
keyboard: KeyboardIO { keys: io.keys_down },
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,18 +2,18 @@ use super::typ::CameraOP;
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
components::Program,
|
||||
graphics::{AttaWithProgram, AttachWithMouse},
|
||||
graphics::{AttaWithProgram, AttachWithIO},
|
||||
pg::layout_type::ViewPort,
|
||||
};
|
||||
|
||||
pub struct Operation<T: AttachWithMouse> {
|
||||
pub struct Operation<T: AttachWithIO> {
|
||||
camera: Camera,
|
||||
projection: Projection,
|
||||
operation: T,
|
||||
need_update: bool,
|
||||
}
|
||||
|
||||
impl<T: AttachWithMouse + AttaWithProgram> Operation<T> {
|
||||
impl<T: AttachWithIO + AttaWithProgram> Operation<T> {
|
||||
pub fn new(operation: T, aspect: f32, fov: f32, z_near: f32, z_far: f32) -> Self {
|
||||
let projection = Projection::new(aspect, fov, z_near, z_far);
|
||||
Self {
|
||||
@ -58,11 +58,6 @@ impl<T: AttachWithMouse + AttaWithProgram> Operation<T> {
|
||||
self.operation.attach_with_program(gl, program);
|
||||
}
|
||||
|
||||
// pub fn attach_with_mouse(&mut self, camera_op: &T::State) -> bool {
|
||||
// self.operation
|
||||
// .attach_with_mouse(camera_op, &mut self.camera, &mut self.projection)
|
||||
// }
|
||||
|
||||
pub fn is_need_update(&self) -> bool {
|
||||
self.need_update
|
||||
}
|
||||
@ -71,6 +66,10 @@ impl<T: AttachWithMouse + AttaWithProgram> Operation<T> {
|
||||
self.operation.reset();
|
||||
self.need_update = true;
|
||||
}
|
||||
|
||||
pub fn clean(&mut self) {
|
||||
self.need_update = false;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Projection {
|
||||
|
||||
@ -4,7 +4,7 @@ use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size};
|
||||
use crate::camera::Camera;
|
||||
use crate::graphics::threed::Trackball;
|
||||
use crate::graphics::transforms::plane::PlaneTrans;
|
||||
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
|
||||
use crate::graphics::{AttaWithProgram, AttachWithIO, MouseKeyboardState, MouseState};
|
||||
use crate::pg::ModulePackage;
|
||||
use crate::pg::{_ModulePackage, layout_type::ViewPort};
|
||||
use crate::ui::helper::Helper;
|
||||
@ -182,6 +182,15 @@ impl CameraOP for MouseState {
|
||||
}
|
||||
}
|
||||
|
||||
impl CameraOP for MouseKeyboardState {
|
||||
fn from_context(context: &IO) -> Self {
|
||||
Self {
|
||||
mouse_state: MouseState::from_context(context),
|
||||
keyboard_state: context.keyboard.keys,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> {
|
||||
fn append(&mut self, package: ModulePackage<'gl>) {
|
||||
self.packages.push(package);
|
||||
@ -194,7 +203,10 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> {
|
||||
helper: &mut Helper,
|
||||
) -> crate::errors::Result<()> {
|
||||
// helper.draw_modules(gl, &self.packages);
|
||||
if self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update() {
|
||||
|
||||
let need_launch =
|
||||
self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update();
|
||||
if need_launch {
|
||||
// Helper task
|
||||
self.main_viewport.bind(gl);
|
||||
|
||||
@ -205,6 +217,8 @@ impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> {
|
||||
for package in self.packages.iter_mut() {
|
||||
programs.draw_modules(package, &self.operation, &self.main_viewport)?;
|
||||
}
|
||||
|
||||
self.operation.clean();
|
||||
}
|
||||
|
||||
if self.packages.is_empty() {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user