This commit is contained in:
Tsuki 2024-07-25 11:58:15 +08:00
parent 2638243856
commit 5a28820b5e
17 changed files with 640 additions and 403 deletions

212
Cargo.lock generated
View File

@ -18,6 +18,15 @@ version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046" checksum = "c71b1793ee61086797f5c80b6efa2b8ffa6d5dd703f118545808a7f2e27f7046"
[[package]]
name = "addr2line"
version = "0.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
dependencies = [
"gimli",
]
[[package]] [[package]]
name = "adler" name = "adler"
version = "1.0.2" version = "1.0.2"
@ -206,6 +215,21 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
[[package]]
name = "backtrace"
version = "0.3.73"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
dependencies = [
"addr2line",
"cc",
"cfg-if",
"libc",
"miniz_oxide",
"object",
"rustc-demangle",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.3.2" version = "1.3.2"
@ -375,6 +399,46 @@ dependencies = [
"windows-targets 0.52.5", "windows-targets 0.52.5",
] ]
[[package]]
name = "clap"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64acc1846d54c1fe936a78dc189c34e28d3f5afc348403f28ecf53660b9b8462"
dependencies = [
"clap_builder",
"clap_derive",
]
[[package]]
name = "clap_builder"
version = "4.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fb8393d67ba2e7bfaf28a23458e4e2b543cc73a99595511eb207fdb8aede942"
dependencies = [
"anstream",
"anstyle",
"clap_lex",
"strsim",
]
[[package]]
name = "clap_derive"
version = "4.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2bac35c6dafb060fd4d275d9a4ffae97917c13a6327903a8be2153cd964f7085"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.66",
]
[[package]]
name = "clap_lex"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b82cf0babdbd58558212896d1a4272303a57bdb245c2bf1147185fb45640e70"
[[package]] [[package]]
name = "clipboard-win" name = "clipboard-win"
version = "3.1.1" version = "3.1.1"
@ -385,6 +449,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "color_quant"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]] [[package]]
name = "colorchoice" name = "colorchoice"
version = "1.0.1" version = "1.0.1"
@ -516,6 +586,16 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "easy-signed-distance-field"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1df5b74971df6cfd9ce883fd96cbe5d6ae46868d681870d72fa518f2184472f"
dependencies = [
"image",
"ttf-parser 0.15.2",
]
[[package]] [[package]]
name = "either" name = "either"
version = "1.13.0" version = "1.13.0"
@ -581,6 +661,15 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "fdeflate"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645"
dependencies = [
"simd-adler32",
]
[[package]] [[package]]
name = "flate2" name = "flate2"
version = "1.0.30" version = "1.0.30"
@ -683,6 +772,12 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gimli"
version = "0.29.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
[[package]] [[package]]
name = "gl_generator" name = "gl_generator"
version = "0.14.0" version = "0.14.0"
@ -800,6 +895,12 @@ dependencies = [
"stable_deref_trait", "stable_deref_trait",
] ]
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.9" version = "0.3.9"
@ -846,6 +947,19 @@ dependencies = [
"objc2", "objc2",
] ]
[[package]]
name = "image"
version = "0.24.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5690139d2f55868e080017335e4b94cb7414274c74f1669c84fb5feba2c9f69d"
dependencies = [
"bytemuck",
"byteorder",
"color_quant",
"num-traits",
"png",
]
[[package]] [[package]]
name = "imgui" name = "imgui"
version = "0.12.0" version = "0.12.0"
@ -1105,6 +1219,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
dependencies = [ dependencies = [
"adler", "adler",
"simd-adler32",
] ]
[[package]] [[package]]
@ -1292,6 +1407,16 @@ dependencies = [
"libm", "libm",
] ]
[[package]]
name = "num_cpus"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "num_enum" name = "num_enum"
version = "0.7.2" version = "0.7.2"
@ -1364,6 +1489,15 @@ dependencies = [
"objc", "objc",
] ]
[[package]]
name = "object"
version = "0.36.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.19.0" version = "1.19.0"
@ -1385,7 +1519,7 @@ version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b41438d2fc63c46c74a2203bf5ccd82c41ba04347b2fcf5754f230b167067d5" checksum = "6b41438d2fc63c46c74a2203bf5ccd82c41ba04347b2fcf5754f230b167067d5"
dependencies = [ dependencies = [
"ttf-parser", "ttf-parser 0.21.1",
] ]
[[package]] [[package]]
@ -1435,6 +1569,19 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "png"
version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06e4b0d3d1312775e782c86c91a111aa1f910cbb65e1337f9975b5f9a554b5e1"
dependencies = [
"bitflags 1.3.2",
"crc32fast",
"fdeflate",
"flate2",
"miniz_oxide",
]
[[package]] [[package]]
name = "polling" name = "polling"
version = "3.7.1" version = "3.7.1"
@ -1497,6 +1644,7 @@ dependencies = [
"cgmath", "cgmath",
"chrono", "chrono",
"copypasta", "copypasta",
"easy-signed-distance-field",
"env_logger", "env_logger",
"flate2", "flate2",
"geo", "geo",
@ -1516,6 +1664,7 @@ dependencies = [
"once_cell", "once_cell",
"raw-window-handle 0.5.2", "raw-window-handle 0.5.2",
"regex", "regex",
"sdf_glyph_renderer",
"serde", "serde",
"serde_json", "serde_json",
"thiserror", "thiserror",
@ -1613,6 +1762,12 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "rustc-demangle"
version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "0.38.34" version = "0.38.34"
@ -1681,6 +1836,26 @@ dependencies = [
"tiny-skia", "tiny-skia",
] ]
[[package]]
name = "sdf_font"
version = "0.1.0"
dependencies = [
"clap",
"easy-signed-distance-field",
"num_cpus",
"spmc",
"tokio",
]
[[package]]
name = "sdf_glyph_renderer"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef220f6a4fff0c984e9fb3ab12cb5c86960b5bb6ec3b30dd7173e3bf603d94f"
dependencies = [
"thiserror",
]
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.204" version = "1.0.204"
@ -1738,6 +1913,12 @@ dependencies = [
"wide", "wide",
] ]
[[package]]
name = "simd-adler32"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
[[package]] [[package]]
name = "slab" name = "slab"
version = "0.4.9" version = "0.4.9"
@ -1819,6 +2000,12 @@ dependencies = [
"smallvec", "smallvec",
] ]
[[package]]
name = "spmc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5"
[[package]] [[package]]
name = "stable_deref_trait" name = "stable_deref_trait"
version = "1.2.0" version = "1.2.0"
@ -1831,6 +2018,12 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731" checksum = "6637bab7722d379c8b41ba849228d680cc12d0a45ba1fa2b48f2a30577a06731"
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@ -1898,6 +2091,17 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tokio"
version = "1.38.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df"
dependencies = [
"backtrace",
"num_cpus",
"pin-project-lite",
]
[[package]] [[package]]
name = "toml_datetime" name = "toml_datetime"
version = "0.6.6" version = "0.6.6"
@ -1931,6 +2135,12 @@ version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
[[package]]
name = "ttf-parser"
version = "0.15.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b3e06c9b9d80ed6b745c7159c40b311ad2916abb34a49e9be2653b90db0d8dd"
[[package]] [[package]]
name = "ttf-parser" name = "ttf-parser"
version = "0.21.1" version = "0.21.1"

View File

@ -1,37 +1,44 @@
[package] [package]
edition = "2021"
name = "radar-g" name = "radar-g"
version = "0.1.0" version = "0.1.0"
edition = "2021"
[dependencies] [dependencies]
imgui = "0.12.0" aligned-vec = "0.6.0"
anyhow = "1.0.86"
bytemuck = {version = "1.16.1", features = ["derive"]}
byteorder = "1.5.0"
cgmath = "0.18.0"
chrono = "0.4.38"
copypasta = "0.10.1"
easy-signed-distance-field = "0.1.1"
env_logger = "0.11.3"
flate2 = "1.0.30"
geo = "0.28.0"
glow = "0.13.1" glow = "0.13.1"
imgui-glow-renderer = "0.12.0"
imgui-winit-support = "0.12.0"
glutin = "0.31.3" glutin = "0.31.3"
glutin-winit = "0.4.2" glutin-winit = "0.4.2"
copypasta = "0.10.1" imgui = "0.12.0"
raw-window-handle = "0.5.2" imgui-glow-renderer = "0.12.0"
winit = "0.29.3" imgui-winit-support = "0.12.0"
cgmath = "0.18.0"
nalgebra-glm = "0.18.0"
regex = "1.10.5"
once_cell = "1.19.0"
include_dir = "0.7.4" include_dir = "0.7.4"
nom = "7.1.3"
thiserror = "1.0.61"
log = "0.4.22" log = "0.4.22"
env_logger = "0.11.3"
bytemuck = { version = "1.16.1", features = ["derive"] }
nalgebra = "0.33.0" nalgebra = "0.33.0"
nom-derive = "0.10.1" nalgebra-glm = "0.18.0"
serde = { version = "1.0.204", features = ["derive"] }
byteorder = "1.5.0"
chrono = "0.4.38"
flate2 = "1.0.30"
anyhow = "1.0.86"
serde_json = "1.0.120"
geo = "0.28.0"
ndarray = "0.15.6" ndarray = "0.15.6"
aligned-vec = "0.6.0" nom = "7.1.3"
nom-derive = "0.10.1"
once_cell = "1.19.0"
raw-window-handle = "0.5.2"
regex = "1.10.5"
sdf_glyph_renderer = "1.0.1"
serde = {version = "1.0.204", features = ["derive"]}
serde_json = "1.0.120"
thiserror = "1.0.61"
winit = "0.29.3"
[workspace]
members = [
"sdf_font",
]

5
check_sdf.py Normal file
View File

@ -0,0 +1,5 @@
import os
with open("resources/Dokdo-Regular/0-255.pbf","rb") as f:
pass

11
sdf_font/Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
edition = "2021"
name = "sdf_font"
version = "0.1.0"
[dependencies]
clap = { version = "4.5.9", features = ["derive"] }
easy-signed-distance-field = {version = "0.1.1", features = ["font", "ttf-parser", "export", "render"]}
num_cpus = "1.16.0"
spmc = "0.3.0"
tokio = { version = "1.38.1", features = ["fs","rt-multi-thread","sync"] }

4
sdf_font/src/check.rs Normal file
View File

@ -0,0 +1,4 @@
use std::{fs::File, io::Read};
#[test]
fn test() {}

72
sdf_font/src/main.rs Normal file
View File

@ -0,0 +1,72 @@
mod check;
use clap::{command, Parser};
use easy_signed_distance_field as sdf;
use std::fs::{self, create_dir_all, File};
use std::path::{Path, PathBuf};
use std::sync::atomic::{AtomicUsize, Ordering};
static TOTAL_GLYPHS_RENDERED: AtomicUsize = AtomicUsize::new(0);
const CHARACTERS: &'static str = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789\
,.!?@#$%^&*()";
#[derive(Parser, Debug)]
#[command(version, author, about)]
struct Args {
/// Sets the source directory to be scanned for fonts.
font_dir: PathBuf,
// / Sets the output directory in which the PBF glyphs will be placed (each font will be placed in a new subdirectory with appropriately named PBF files).
// out_dir: PathBuf,
}
fn render_worker(path: &PathBuf, output: &PathBuf) {
let mut file = fs::read(path).unwrap();
let font = sdf::Font::from_bytes(file.as_slice(), Default::default()).unwrap();
let px = 64.0;
let padding = 2;
let spread = 6.0;
for c in CHARACTERS.chars() {
if let Some((metrics, glyph_sdf)) = font.sdf_generate(px, padding, spread, c) {
let mut output = output.join(format!("{}.png", c));
output.parent().map(|p| create_dir_all(p).unwrap());
sdf::sdf_to_file(output.as_os_str().to_str().unwrap(), &glyph_sdf).unwrap();
output.set_file_name(format!("fuck_{}.png", c));
sdf::sdf_render_to_file(
output.as_os_str().to_str().unwrap(),
0.5,
0.5,
0.02,
&glyph_sdf,
)
.unwrap();
}
}
}
fn main() {
let args = Args::parse();
let font_dir = &args.font_dir;
let num_threads = num_cpus::get();
println!("Starting {num_threads} worker threads...");
for dir_entry in font_dir
.read_dir()
.expect("Unable to open font directory")
.flatten()
{
let path = dir_entry.path();
if let (Some(stem), Some(extension)) = (path.file_stem(), path.extension()) {
if path.is_file() && (["otf", "ttf"].contains(&extension.to_str().unwrap())) {
println!("Rendering glyphs for font: {}", path.to_str().unwrap());
let filename = PathBuf::from(format!("test/{}", stem.to_str().unwrap()));
render_worker(&path, &filename)
}
}
}
}

View File

@ -5,6 +5,6 @@ layout(location = 0) in vec3 position;
out float in_value; out float in_value;
void main() { void main() {
gl_Position = vec4(position.x, position.y, 0.0, 1.0); gl_Position = vec4(position.x, position.y, 0.5, 1.0);
in_value = position.z; in_value = position.z;
} }

View File

@ -47,6 +47,16 @@ impl Camera {
pub fn get_view_matrix(&self) -> Mat4x4 { pub fn get_view_matrix(&self) -> Mat4x4 {
let l = self.pos + self.front; let l = self.pos + self.front;
look_at(&self.pos, &l, &self.upward) look_at(&l, &self.pos, &self.upward)
}
}
impl Default for Camera {
fn default() -> Self {
Self {
pos: Vec3::new(0.0, 0.0, 0.0),
upward: Vec3::new(0.0, 1.0, 0.0),
front: Vec3::new(0.0, 0.0, -1.0),
}
} }
} }

View File

@ -1,6 +1,6 @@
use thiserror::Error; use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>; pub type Result<T = ()> = std::result::Result<T, Error>;
#[derive(Error, Debug)] #[derive(Error, Debug)]
pub enum Error { pub enum Error {

15
src/graphics/font/mod.rs Normal file
View File

@ -0,0 +1,15 @@
pub struct FontManager {
fonts: Vec<Font>,
}
impl FontManager {
pub fn new() -> Self {
Self { fonts: Vec::new() }
}
pub fn add_font(&mut self, font: Font) {
self.fonts.push(font);
}
}
pub struct Font {}

View File

@ -1,6 +1,7 @@
pub mod collections; pub mod collections;
pub mod colormap; pub mod colormap;
mod colormesh; mod colormesh;
pub mod font;
pub mod hello; pub mod hello;
pub mod ppi; pub mod ppi;
pub mod threed; pub mod threed;
@ -54,14 +55,14 @@ macro_rules! config_for_everyitem {
}; };
} }
#[derive(Clone)] #[derive(Debug, Clone)]
pub enum Config { pub enum Config {
PPI(PPIConfig), PPI(PPIConfig),
} }
config_for_everyitem!({PPIConfig => PPI},); config_for_everyitem!({PPIConfig => PPI},);
pub trait AttachWithMouse: AttaWithProgram { pub trait AttachWithMouse {
fn attach_with_mouse(&mut self, state: &MouseState); fn attach_with_mouse(&mut self, state: &MouseState);
} }

View File

@ -3,9 +3,11 @@ use glow::{HasContext, NativeBuffer, NativeVertexArray};
use crate::components::{CodeType, Program, Shader}; use crate::components::{CodeType, Program, Shader};
use crate::data_loader::{CoordType, Data, DataType}; use crate::data_loader::{CoordType, Data, DataType};
use crate::errors::*; use crate::errors::*;
use crate::graphics::transforms::Transform;
use super::colormap::ColorMap; use super::colormap::ColorMap;
use super::threed::ThreeD; use super::threed::ThreeD;
use super::transforms::position::Position;
use super::transforms::viewport::Viewport; use super::transforms::viewport::Viewport;
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics}; use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics};
@ -32,7 +34,11 @@ impl PPI {
CodeType::<String>::Path("ppi.frag".into()), CodeType::<String>::Path("ppi.frag".into()),
)?; )?;
let transform = ThreeD::new(1.0, 2.0, 1000.0, 45.0)?; let transform = ThreeD::new(1.0, 0.1, 100.0, 45.0)?;
println!("{}", transform.snippet().call(&vec![]).unwrap());
// let transform = Position::new()?;
let mut program = Program::new(vertex, fragment, Some(geom), "330 core"); let mut program = Program::new(vertex, fragment, Some(geom), "330 core");
program.set_transform(&transform); program.set_transform(&transform);
@ -245,7 +251,7 @@ impl AttaWithBuffer for PPI {
} }
} }
#[derive(Default, Clone)] #[derive(Default, Clone, Debug)]
pub struct PPIConfig { pub struct PPIConfig {
pub layer: usize, pub layer: usize,
pub rdpi: f32, pub rdpi: f32,

View File

@ -17,17 +17,17 @@ pub struct ThreeD {
} }
impl ThreeD { impl ThreeD {
pub fn new(aspect: f32, z_far: f32, z_near: f32, fov: f32) -> Result<Self> { pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result<Self> {
let trackball = Trackball::new()?; let trackball = Trackball::new()?;
let transform = ChainedTransform::from(&trackball).chain(&Position::new()?); let transform = ChainedTransform::from(&trackball).chain(&Position::new()?);
let camera = Camera::new( let camera = Camera::new(
Vec3::new(0.0, 0.0, 0.0), Vec3::new(0.0, -1.0, 0.0),
Vec3::new(0.0, 0.0, -1.0), Vec3::new(0.0, 1.0, 0.0),
Vec3::new(0.0, 1.0, 0.0), Vec3::new(0.0, 1.0, 0.0),
); );
let projection = nalgebra_glm::perspective(aspect, fov, z_near, z_far); let projection = nalgebra_glm::perspective(aspect, fov.to_radians(), z_near, z_far);
Ok(Self { Ok(Self {
transform: Rc::new(transform), transform: Rc::new(transform),
@ -53,14 +53,42 @@ impl AttaWithProgram for ThreeD {
unsafe { unsafe {
let view = program.get_uniform_location(gl, "trackball_view"); let view = program.get_uniform_location(gl, "trackball_view");
let projection = program.get_uniform_location(gl, "trackball_projection"); let projection = program.get_uniform_location(gl, "trackball_projection");
self.trackball.attach_with_program(gl, program)?;
let model = program.get_uniform_location(gl, "trackball_model");
// self.trackball.attach_with_program(gl, program)?;
let view_mat = nalgebra_glm::translation(&nalgebra_glm::vec3(0.0, 0.0, -3.0));
gl.uniform_matrix_4_f32_slice( gl.uniform_matrix_4_f32_slice(
view.as_ref(), view.as_ref(),
false, false,
self.camera.get_view_matrix().as_slice(), // nalgebra::Matrix4::identity().as_slice(),
view_mat.as_slice(),
// self.camera.get_view_matrix().as_slice(),
); );
println!("projection: {:?}", self.projection);
let id: nalgebra_glm::Mat4 = nalgebra_glm::identity();
let scale_factor = nalgebra_glm::vec3(1.5, 1.5, 1.0);
let res = nalgebra_glm::scaling(&scale_factor);
let rotate =
nalgebra_glm::rotation(45.0f32.to_radians(), &nalgebra_glm::vec3(1.0, 0.0, 0.0));
gl.uniform_matrix_4_f32_slice(
model.as_ref(),
false,
res.as_slice(), // nalgebra::Matrix4::identity().as_slice(),
);
gl.uniform_matrix_4_f32_slice(projection.as_ref(), false, self.projection.as_slice()); gl.uniform_matrix_4_f32_slice(projection.as_ref(), false, self.projection.as_slice());
// gl.uniform_matrix_4_f32_slice(
// projection.as_ref(),
// false,
// nalgebra::Matrix4::identity().as_slice(),
// );
} }
Ok(()) Ok(())
} }

View File

@ -14,7 +14,7 @@ impl Position {
let snippets = Snippet::new( let snippets = Snippet::new(
"position", "position",
CodeType::<&'static str>::Path("transform/position.glsl".into()), CodeType::<&'static str>::Path("transform/position.glsl".into()),
true, false,
None, None,
)?; )?;

View File

@ -140,7 +140,7 @@ impl Trackball {
let snippets = Snippet::new( let snippets = Snippet::new(
"trackball", "trackball",
CodeType::<&'static str>::Path("transform/trackball.glsl".into()), CodeType::<&'static str>::Path("transform/trackball.glsl".into()),
true, false,
None, None,
)?; )?;
@ -170,8 +170,7 @@ impl Transform for Trackball {
impl AttaWithProgram for Trackball { impl AttaWithProgram for Trackball {
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> { fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
unsafe { unsafe {
let model = self.snippet.find_symbol("trackball_model").unwrap(); let l = program.get_uniform_location(gl, "trackball_model");
let l = program.get_uniform_location(gl, &model);
gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice()); gl.uniform_matrix_4_f32_slice(l.as_ref(), false, self.model.model().as_slice());
} }

541
src/pg.rs
View File

@ -3,19 +3,16 @@ use crate::data_loader::Data;
use crate::graphics::colormap::linear::LinearColormap; use crate::graphics::colormap::linear::LinearColormap;
use crate::graphics::ppi::PPIConfig; use crate::graphics::ppi::PPIConfig;
use crate::graphics::threed::ThreeD; use crate::graphics::threed::ThreeD;
use crate::graphics::transforms::position::Position;
use crate::graphics::transforms::viewport::Viewport; use crate::graphics::transforms::viewport::Viewport;
use crate::graphics::transforms::ChainedTransform;
use crate::graphics::{ppi::PPI, Graphics}; use crate::graphics::{ppi::PPI, Graphics};
use crate::graphics::{AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, MouseState}; use crate::graphics::{AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, MouseState};
use crate::{errors::*, ui::base}; use crate::{errors::*, ui::base};
use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray}; use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray};
use imgui::{ImStr, ImString, Textures, Ui}; use imgui::{ImStr, ImString, Textures, Ui};
use log::info; use log::info;
use serde::de; use std::hash::Hash;
use std::collections::HashSet; use std::ops::Deref;
use std::{cell::RefCell, collections::HashMap, rc::Rc}; use std::{cell::RefCell, collections::HashMap, rc::Rc};
use winit::window;
pub type Graphic<Data> = Rc<RefCell<dyn Graphics<Data = Data>>>; pub type Graphic<Data> = Rc<RefCell<dyn Graphics<Data = Data>>>;
type RcGraphic<T> = Rc<RefCell<T>>; type RcGraphic<T> = Rc<RefCell<T>>;
@ -23,15 +20,10 @@ pub struct App<'a> {
pub ui_state: State, pub ui_state: State,
gl: &'a glow::Context, gl: &'a glow::Context,
viewport: Viewport, viewport: Viewport,
windows: HashMap<ImString, WindowData>, windows: HashMap<ImString, WindowData<'a>>,
programs: [Graphic<Data>; 1], programs: [Graphic<Data>; 1],
pub ppi_module: RcGraphic<PPI>, pub ppi_module: RcGraphic<PPI>,
program_with_window: HashMap<usize, Vec<ImString>>, program_with_window: HashMap<usize, Vec<ImString>>,
// Auto clean up
all_vaos: HashMap<NativeVertexArray, usize>,
all_other_buffers: HashMap<NativeBuffer, usize>,
all_framebuffers: HashMap<NativeFramebuffer, usize>,
all_frametextures: HashMap<NativeTexture, usize>,
} }
impl<'a> App<'a> { impl<'a> App<'a> {
@ -69,14 +61,10 @@ impl<'a> App<'a> {
ui_state: State {}, ui_state: State {},
viewport, viewport,
programs, programs,
windows: HashMap::new(), windows: HashMap::with_capacity(30),
ppi_module: ppi, ppi_module: ppi,
gl, gl,
program_with_window: HashMap::new(), program_with_window: HashMap::with_capacity(5),
all_vaos: HashMap::with_capacity(30),
all_other_buffers: HashMap::with_capacity(30),
all_framebuffers: HashMap::with_capacity(30),
all_frametextures: HashMap::with_capacity(30),
}) })
} }
@ -93,38 +81,50 @@ impl<'a> App<'a> {
self.program_with_window.get(&id).map(|windows| { self.program_with_window.get(&id).map(|windows| {
for window in windows.iter() { for window in windows.iter() {
let window_info = self.windows.get_mut(window).unwrap(); let window_info = self.windows.get_mut(window).unwrap();
// Skip the window if it doesn't need to be redrawn
if !window_info.need_redraw { if !window_info.need_redraw {
continue; continue;
} }
// If the window needs to be reinitialized, set the config
{
let conf = if window_info.re_init { let conf = if window_info.re_init {
window_info.config.as_ref() window_info.config.as_ref()
} else { } else {
None None
}; };
{
p.set_config(self.gl, conf).unwrap(); p.set_config(self.gl, conf).unwrap();
window_info.re_init = false; window_info.re_init = false;
} }
// Attach the modifer to the program
if let Some(motion) = window_info.modifer.as_ref() { if let Some(motion) = window_info.modifer.as_ref() {
motion.attach_with_program(&self.gl, p.program_ref()).unwrap(); motion
.attach_with_program(&self.gl, p.program_ref())
.unwrap();
} }
// Attach the data to the program
unsafe { unsafe {
self.gl let framebuffer = window_info.gl_fb_resources.as_ref().map(|v| v.native());
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer);
let attach = window_info.attach.as_ref(); // Skip the window if the framebuffer is None
if framebuffer.is_none() {
continue;
}
self.gl.bind_framebuffer(glow::FRAMEBUFFER, framebuffer);
let attach = window_info.attach.get(&id);
if attach.is_some() { if attach.is_some() {
self.gl.bind_vertex_array(Some(attach.unwrap().vao)); let vao = attach.unwrap().vao.native();
self.gl.bind_vertex_array(Some(vao));
} }
if attach.is_some() { if attach.is_some() {
let window_size = window_info.size; let window_size = window_info.size;
self.gl self.gl
.viewport(0, 0, window_size[0] as i32, window_size[1] as i32); .viewport(0, 0, window_size[0] as i32, window_size[1] as i32);
p.draw(&self.gl, attach.as_ref().unwrap().len).unwrap(); p.draw(&self.gl, attach.as_ref().unwrap().len).unwrap();
@ -139,11 +139,9 @@ impl<'a> App<'a> {
} }
} }
}); });
p.unmount(&self.gl).unwrap();
}
if need_clean { // Unmount the program
self.clean(); p.unmount(&self.gl).unwrap();
} }
} }
@ -154,21 +152,22 @@ impl<'a> App<'a> {
pub fn create_framebuffer( pub fn create_framebuffer(
&mut self, &mut self,
id: &str, id: &str,
size: (i32, i32), size: [i32; 2],
) -> Result<(NativeFramebuffer, NativeTexture)> { ) -> Result<(RcGlFramebuffer<'a>, RcGlTexture<'a>)> {
let id = &ImString::new(id); let id = &ImString::new(id);
let gl = self.gl;
let tex = unsafe {
let already = self.windows.contains_key(id)
&& self.windows.get(id).unwrap().framebuffer.is_some();
if already { if self.windows.contains_key(id) {
let info = self.windows.get(id).unwrap();
if info.gl_fb_resources.is_some() && info.gl_tex_resources.is_some() {
return Ok(( return Ok((
self.windows[id].framebuffer.unwrap(), info.gl_fb_resources.as_ref().unwrap().clone(),
self.windows[id].frametexture.unwrap(), info.gl_tex_resources.as_ref().unwrap().clone(),
)); ));
} }
}
let gl = self.gl;
let tex = unsafe {
let framebuffer = gl.create_framebuffer().unwrap(); let framebuffer = gl.create_framebuffer().unwrap();
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer)); gl.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer));
@ -178,8 +177,8 @@ impl<'a> App<'a> {
glow::TEXTURE_2D, glow::TEXTURE_2D,
0, 0,
glow::RGB8 as i32, glow::RGB8 as i32,
size.0, size[0],
size.1, size[1],
0, 0,
glow::RGB, glow::RGB,
glow::UNSIGNED_BYTE, glow::UNSIGNED_BYTE,
@ -211,10 +210,10 @@ impl<'a> App<'a> {
gl.bind_framebuffer(glow::FRAMEBUFFER, None); gl.bind_framebuffer(glow::FRAMEBUFFER, None);
gl.bind_texture(glow::TEXTURE_2D, None); gl.bind_texture(glow::TEXTURE_2D, None);
(
self.all_framebuffers_add(&framebuffer); RcGlResource::new(&self.gl, framebuffer),
self.all_frametextures_add(&texture); RcGlResource::new(&self.gl, texture),
(framebuffer, texture) )
}; };
Ok(tex) Ok(tex)
@ -225,6 +224,9 @@ impl<'a> App<'a> {
let mut p = program.borrow_mut(); let mut p = program.borrow_mut();
p.compile(&self.gl).unwrap(); p.compile(&self.gl).unwrap();
} }
unsafe {
self.gl.enable(glow::DEPTH_TEST);
}
} }
pub fn destroy(&mut self) { pub fn destroy(&mut self) {
@ -233,38 +235,21 @@ impl<'a> App<'a> {
p.unmount(&self.gl).unwrap(); p.unmount(&self.gl).unwrap();
p.destroy(&self.gl).unwrap(); p.destroy(&self.gl).unwrap();
} }
info!("Cleaning up all resources");
unsafe {
for vao in self.all_vaos.keys() {
self.gl.delete_vertex_array(*vao);
}
for vbo in self.all_other_buffers.keys() {
self.gl.delete_buffer(*vbo);
}
for framebuffer in self.all_framebuffers.keys() {
self.gl.delete_framebuffer(*framebuffer);
}
for texture in self.all_frametextures.keys() {
self.gl.delete_texture(*texture);
}
}
} }
pub fn create_ppi_render(&mut self, id: &str, config: Option<PPIConfig>) { pub fn create_ppi_render(&mut self, id: &str, config: Option<PPIConfig>) {
let id = &ImString::new(id); let id = &ImString::new(id);
let (vao, vbo, ebo) = self.ppi_module.borrow().init(&self.gl); let (vao, vbo, ebo) = self.ppi_module.borrow().init(&self.gl);
self.windows.get_mut(id).map(|w| { self.windows.get_mut(id).map(|w| {
w.attach = Some(Attach { w.attach.insert(
vao, 0,
vbo, Attach {
ebo, vao: RcGlResource::new(&self.gl, vao),
vbo: RcGlResource::new(&self.gl, vbo),
ebo: ebo.map(|ebo| RcGlResource::new(&self.gl, ebo)),
len: 0, len: 0,
}); },
);
w.need_redraw = true; w.need_redraw = true;
w.program = 0; w.program = 0;
w.config = Some(config.unwrap_or_default().into()); w.config = Some(config.unwrap_or_default().into());
@ -272,37 +257,32 @@ impl<'a> App<'a> {
let v = self.program_with_window.entry(0).or_insert(vec![]); let v = self.program_with_window.entry(0).or_insert(vec![]);
v.push(id.clone()); v.push(id.clone());
self.all_vaos_add(&vao);
self.all_other_buffers_add(&vbo);
ebo.map(|ebo| self.all_other_buffers_add(&ebo));
} }
pub fn bind_data(&mut self, id: &str, data: &Data) -> Result<()> { pub fn bind_data(&mut self, program_idx: usize, id: &str, data: &Data) -> Result {
let id = &ImString::new(id); let id = &ImString::new(id);
use bytemuck::cast_slice; use bytemuck::cast_slice;
let window = self.windows.get_mut(id).unwrap(); let window = self.windows.get_mut(id).unwrap();
let program = window.program; let program = window.program;
let program = self.programs[program].borrow(); let program = self.programs[program].borrow();
let data = program.bake(data)?; let data = program.bake(data)?;
assert!(window.attach.is_some()); let attach = window.attach.get_mut(&program_idx).unwrap();
let attach = window.attach.as_mut().unwrap();
attach.len = data.2; attach.len = data.2;
unsafe { unsafe {
self.gl.bind_buffer(glow::VERTEX_ARRAY, Some(attach.vbo)); self.gl
.bind_buffer(glow::VERTEX_ARRAY, Some(attach.vbo.native()));
self.gl.buffer_data_u8_slice( self.gl.buffer_data_u8_slice(
glow::ARRAY_BUFFER, glow::ARRAY_BUFFER,
cast_slice(data.0.as_slice()), cast_slice(data.0.as_slice()),
glow::STATIC_DRAW, glow::STATIC_DRAW,
); );
if let Some(ebo) = attach.ebo { if let Some(ebo) = attach.ebo.as_ref() {
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, attach.ebo); self.gl
.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ebo.native()));
self.gl.buffer_data_u8_slice( self.gl.buffer_data_u8_slice(
glow::ELEMENT_ARRAY_BUFFER, glow::ELEMENT_ARRAY_BUFFER,
cast_slice(&data.1.as_ref().unwrap()), cast_slice(&data.1.as_ref().unwrap()),
@ -317,90 +297,6 @@ impl<'a> App<'a> {
Ok(()) Ok(())
} }
fn all_framebuffers_add(&mut self, framebuffer: &NativeFramebuffer) {
self.all_framebuffers
.entry(*framebuffer)
.and_modify(|v| *v += 1)
.or_insert(1);
info!(
"Framebuffer: {:?} + 1, Framebuffer {:?}: {}",
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
);
}
fn all_framebuffers_minus(&mut self, framebuffer: &NativeFramebuffer) {
self.all_framebuffers
.entry(*framebuffer)
.and_modify(|v| *v -= 1);
info!(
"Framebuffer: {:?} - 1, Framebuffer {:?}: {}",
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
);
}
fn all_frametextures_add(&mut self, texture: &NativeTexture) {
self.all_frametextures
.entry(*texture)
.and_modify(|v| *v += 1)
.or_insert(1);
info!(
"Texture: {:?} + 1, Frametexture {:?}: {}",
texture, texture, self.all_frametextures[texture]
);
}
fn all_frametextures_minus(&mut self, texture: &NativeTexture) {
self.all_frametextures
.entry(*texture)
.and_modify(|v| *v -= 1);
info!(
"Texture: {:?} - 1, Frametexture {:?}: {}",
texture, texture, self.all_frametextures[texture]
);
}
fn all_vaos_add(&mut self, vao: &NativeVertexArray) {
self.all_vaos
.entry(*vao)
.and_modify(|v| *v += 1)
.or_insert(1);
info!("Vao: {:?} + 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
}
fn all_vaos_minus(&mut self, vao: &NativeVertexArray) {
self.all_vaos.entry(*vao).and_modify(|v| *v -= 1);
info!("Vao: {:?} - 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
}
fn all_other_buffers_add(&mut self, buffer: &NativeBuffer) {
self.all_other_buffers
.entry(*buffer)
.and_modify(|v| *v += 1)
.or_insert(1);
info!(
"Buffer: {:?} + 1, Buffer {:?}: {}",
buffer, buffer, self.all_other_buffers[buffer]
);
}
fn all_other_buffers_minus(&mut self, buffer: &NativeBuffer) {
self.all_other_buffers
.entry(*buffer)
.and_modify(|v| *v -= 1);
info!(
"Buffer: {:?} - 1, Buffer {:?}: {}",
buffer, buffer, self.all_other_buffers[buffer]
);
}
pub fn show_window(&mut self, ui: &Ui) { pub fn show_window(&mut self, ui: &Ui) {
let mut need_resize = vec![]; let mut need_resize = vec![];
@ -413,10 +309,14 @@ impl<'a> App<'a> {
if ui.is_mouse_clicked(imgui::MouseButton::Left) { if ui.is_mouse_clicked(imgui::MouseButton::Left) {
let io = ui.io(); let io = ui.io();
let pos = io.mouse_pos; let pos = io.mouse_pos;
window.last_mouse_position = pos;
let window_pos = ui.window_pos();
window.last_mouse_position =
[pos[0] - window_pos[0], pos[1] - window_pos[1]];
} }
if ui.is_mouse_dragging(imgui::MouseButton::Left) { if ui.is_mouse_dragging(imgui::MouseButton::Left) {
if ui.is_window_hovered() {
let delta = ui.mouse_drag_delta(); let delta = ui.mouse_drag_delta();
window.last_mouse_delta = delta; window.last_mouse_delta = delta;
window.accmulate_mouse_delta = [ window.accmulate_mouse_delta = [
@ -427,11 +327,18 @@ impl<'a> App<'a> {
from: window.last_mouse_position, from: window.last_mouse_position,
delta: delta, delta: delta,
}); });
println!(
"Dragging: {:?} {:?}",
window.last_mouse_position, window.accmulate_mouse_delta
);
window.modifer.as_mut().map(|v| { window.modifer.as_mut().map(|v| {
v.exec(window.motion.as_ref().unwrap()); v.exec(window.motion.as_ref().unwrap());
}); });
window.need_redraw = true; window.need_redraw = true;
} }
}
if ui.is_mouse_released(imgui::MouseButton::Left) { if ui.is_mouse_released(imgui::MouseButton::Left) {
if window.size != ui.window_size() { if window.size != ui.window_size() {
window.size = ui.window_size(); window.size = ui.window_size();
@ -440,13 +347,9 @@ impl<'a> App<'a> {
} }
} }
if let Some(texture) = window.frametexture { if let Some(texture) = window.gl_tex_resources.as_ref() {
let cursor = ui.cursor_pos(); let cursor = ui.cursor_pos();
imgui::Image::new( imgui::Image::new(texture.native2imguiid(), ui.window_size()).build(ui);
imgui::TextureId::new(texture.0.get() as usize),
ui.window_size(),
)
.build(ui);
ui.set_cursor_pos(cursor); ui.set_cursor_pos(cursor);
if ui.invisible_button(&window.title, ui.window_size()) { if ui.invisible_button(&window.title, ui.window_size()) {
let io = ui.io(); let io = ui.io();
@ -463,91 +366,25 @@ impl<'a> App<'a> {
} }
} }
// pub fn copy_window_resource( pub fn create_render_window(&mut self, title: &str, size: [f32; 2]) -> Result {
// &mut self,
// src: &str,
// dst: &str,
// stick: bool,
// ) -> Option<NativeTexture> {
// let src = &ImString::new(src);
// let window_info = self.windows.get(src).unwrap();
// let new_texture = if stick {
// let new_framebuffer_tex = self.create_framebuffer(dst, (300, 300)).unwrap();
// unsafe {
// self.gl
// .bind_framebuffer(glow::READ_FRAMEBUFFER, window_info.framebuffer);
// self.gl
// .bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.framebuffers[dst].0));
// self.gl.blit_framebuffer(
// 0,
// 0,
// 300,
// 300,
// 0,
// 0,
// 300,
// 300,
// glow::COLOR_BUFFER_BIT,
// glow::NEAREST,
// );
// self.gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
// self.gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
// }
// self.framebuffers
// .get_mut(dst)
// .map(|(_, redraw, program, atta)| {
// *atta = new_framebuffer.as_ref().map(|v| v.3.clone()).flatten();
// *redraw = true;
// *program = new_framebuffer.as_ref().map(|v| v.2).unwrap();
// });
// Some(new_framebuffer_tex)
// } else {
// let texture = self.frametextures.get(src).map(|texture| *texture);
// if let Some(ref framebuffer) = new_framebuffer {
// if let Some(ref texture) = texture {
// self.all_framebuffers_add(&framebuffer.0);
// self.all_frametextures_add(&texture);
// self.framebuffers
// .insert(ImString::new(dst), framebuffer.clone());
// self.frametextures
// .insert(ImString::new(dst), texture.clone());
// }
// }
// texture
// };
// new_framebuffer.map(|framebuffer| {
// new_texture.map(|_| {
// self.all_vaos_add(&framebuffer.3.as_ref().unwrap().vao);
// self.all_other_buffers_add(&framebuffer.3.as_ref().unwrap().vbo);
// framebuffer.3.as_ref().unwrap().ebo.map(|ebo| {
// self.all_other_buffers_add(&ebo);
// });
// self.program_with_window.get_mut(&framebuffer.2).map(|v| {
// v.push(ImString::new(dst));
// });
// });
// });
// new_texture
// }
pub fn create_render_window(&mut self, title: &str, size: [f32; 2]) -> Result<()> {
// Insert the window data into the windows hashmap // Insert the window data into the windows hashmap
let id = ImString::new(title); let id = ImString::new(title);
let mut data = WindowData::new(id.clone(), size, None); let mut data = WindowData::new(id.clone(), size, None);
let (fb, tex) = let (fb, tex) =
self.create_framebuffer(title, (size[0].floor() as i32, size[1].floor() as i32))?; self.create_framebuffer(title, [size[0].floor() as i32, size[1].floor() as i32])?;
data.gl_fb_resources = Some(fb);
data.framebuffer = Some(fb); data.gl_tex_resources = Some(tex);
data.frametexture = Some(tex);
self.windows.insert(id, data); self.windows.insert(id, data);
Ok(()) Ok(())
} }
pub fn set_window_modifer(&mut self, id: &str, modifer: Option<ModiferType>) {
let id = &ImString::new(id);
self.windows.get_mut(id).map(|v| {
v.modifer = modifer;
});
}
pub fn set_config(&mut self, id: &str) -> Option<&mut Config> { pub fn set_config(&mut self, id: &str) -> Option<&mut Config> {
let id = &ImString::new(id); let id = &ImString::new(id);
self.windows self.windows
@ -563,8 +400,10 @@ impl<'a> App<'a> {
let window_info = self.windows.get_mut(id).unwrap(); let window_info = self.windows.get_mut(id).unwrap();
window_info.need_redraw = true; window_info.need_redraw = true;
let tex = unsafe { let tex = unsafe {
self.gl self.gl.bind_framebuffer(
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer); glow::FRAMEBUFFER,
window_info.gl_fb_resources.as_ref().map(|v| v.native()),
);
let texture = self.gl.create_texture().unwrap(); let texture = self.gl.create_texture().unwrap();
self.gl.bind_texture(glow::TEXTURE_2D, Some(texture)); self.gl.bind_texture(glow::TEXTURE_2D, Some(texture));
self.gl.tex_image_2d( self.gl.tex_image_2d(
@ -607,102 +446,42 @@ impl<'a> App<'a> {
texture texture
}; };
let raw_tex = window_info.frametexture.as_ref().unwrap().to_owned();
self.all_frametextures_minus(&raw_tex); window_info.gl_tex_resources = Some(RcGlResource::new(self.gl, tex));
self.all_frametextures_add(&tex);
} }
pub fn destroy_window(&mut self) { pub fn destroy_window(&mut self) {
let ids: Vec<_> = self for (id, window) in self.windows.iter() {
.windows if !window.open {
.iter() self.program_with_window.get_mut(&window.program).map(|v| {
.filter(|v| v.1.open == false) v.retain(|k| k != id);
.map(|v| v.0.clone())
.collect();
for id in ids.iter() {
let window = self.windows.remove(id).unwrap();
window.framebuffer.map(|framebuffer| {
self.all_framebuffers_minus(&framebuffer);
});
window.frametexture.map(|texture| {
self.all_frametextures_minus(&texture);
});
if let Some(atta) = window.attach {
self.all_vaos_minus(&atta.vao);
self.all_other_buffers_minus(&atta.vbo);
atta.ebo.map(|ebo| {
self.all_other_buffers_minus(&ebo);
}); });
} }
} }
} self.windows.retain(|k, v| v.open == true);
fn clean(&mut self) {
info!("Cleaning up unused resources");
unsafe {
self.all_framebuffers
.iter()
.filter(|v| *v.1 == 0)
.for_each(|(bf, _)| {
info!("Deleting framebuffer: {:?}", bf);
self.gl.delete_framebuffer(*bf);
});
self.all_frametextures
.iter()
.filter(|v| *v.1 == 0)
.for_each(|(bf, _)| {
info!("Deleting texture: {:?}", bf);
self.gl.delete_texture(*bf);
});
self.all_vaos
.iter()
.filter(|v| *v.1 == 0)
.for_each(|(bf, _)| {
info!("Deleting vao: {:?}", bf);
self.gl.delete_vertex_array(*bf);
});
self.all_other_buffers
.iter()
.filter(|v| *v.1 == 0)
.for_each(|(bf, _)| {
info!("Deleting buffer: {:?}", bf);
self.gl.delete_buffer(*bf);
});
}
self.all_framebuffers.retain(|_, v| *v > 0);
self.all_frametextures.retain(|_, v| *v > 0);
self.all_vaos.retain(|_, v| *v > 0);
self.all_other_buffers.retain(|_, v| *v > 0);
} }
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Attach { pub struct Attach<'a> {
pub vao: NativeVertexArray, pub vao: RcGlResource<'a, NativeVertexArray>,
pub vbo: NativeBuffer, pub vbo: RcGlResource<'a, NativeBuffer>,
pub ebo: Option<NativeBuffer>, pub ebo: Option<RcGlResource<'a, NativeBuffer>>,
pub len: i32, pub len: i32,
} }
pub struct State {} pub struct State {}
pub struct WindowData { pub struct WindowData<'a> {
pub title: ImString, pub title: ImString,
pub open: bool, pub open: bool,
pub copy_from: Option<ImString>, pub copy_from: Option<ImString>,
pub size: [f32; 2], pub size: [f32; 2],
framebuffer: Option<NativeFramebuffer>, gl_fb_resources: Option<RcGlResource<'a, NativeFramebuffer>>,
frametexture: Option<NativeTexture>, gl_tex_resources: Option<RcGlResource<'a, NativeTexture>>,
need_redraw: bool, need_redraw: bool,
program: usize, program: usize,
attach: Option<Attach>, attach: HashMap<usize, Attach<'a>>,
re_init: bool, re_init: bool,
last_mouse_position: [f32; 2], last_mouse_position: [f32; 2],
@ -714,7 +493,7 @@ pub struct WindowData {
modifer: Option<ModiferType>, modifer: Option<ModiferType>,
} }
impl WindowData { impl<'a> WindowData<'a> {
pub fn new(title: ImString, size: [f32; 2], modifer: Option<ModiferType>) -> Self { pub fn new(title: ImString, size: [f32; 2], modifer: Option<ModiferType>) -> Self {
Self { Self {
title, title,
@ -727,11 +506,11 @@ impl WindowData {
mouse_position: [0.0, 0.0], mouse_position: [0.0, 0.0],
motion: None, motion: None,
framebuffer: None, gl_fb_resources: None,
frametexture: None, gl_tex_resources: None,
need_redraw: false, need_redraw: false,
program: 0, program: 0,
attach: None, attach: HashMap::with_capacity(10),
re_init: false, re_init: false,
config: None, config: None,
modifer, modifer,
@ -785,21 +564,17 @@ macro_rules! modifer_exec {
pub fn exec(&mut self, motion: &MouseState) { pub fn exec(&mut self, motion: &MouseState) {
match self { match self {
$( $(
ModiferType::$b(b) => { ModiferType::$b(b) => {
b.attach_with_mouse(motion); b.attach_with_mouse(motion);
} }
)+ )+
_ => {} _ => {}
} }
} }
} }
impl AttaWithProgram for ModiferType { impl AttaWithProgram for ModiferType {
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> { fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result {
match self { match self {
$( $(
@ -811,9 +586,7 @@ macro_rules! modifer_exec {
_ => { _ => {
} }
} }
Ok(()) Ok(())
} }
} }
@ -825,8 +598,6 @@ macro_rules! modifer_exec {
} }
} }
)+ )+
} }
} }
@ -837,3 +608,97 @@ pub enum ModiferType {
} }
modifer_exec!((ThreeD => ThreeD),); modifer_exec!((ThreeD => ThreeD),);
pub type RcGlFramebuffer<'a> = RcGlResource<'a, NativeFramebuffer>;
pub type RcGlTexture<'a> = RcGlResource<'a, NativeTexture>;
pub type RcGlVertexArray<'a> = RcGlResource<'a, NativeVertexArray>;
pub type RcGlBuffer<'a> = RcGlResource<'a, NativeBuffer>;
// pub type RcGlResource<'a, T> = Rc<GlResource<'a, T>>;
#[derive(Debug, Clone)]
pub struct RcGlResource<'a, T: Resource>(Rc<GlResource<'a, T>>);
impl<'a, T: Resource> RcGlResource<'a, T> {
pub fn new(gl: &'a glow::Context, resource: T) -> Self {
Self(Rc::new(GlResource::new(resource, gl)))
}
pub fn native(&self) -> T {
self.0.resource.clone()
}
}
impl<'a, T: Resource> Deref for RcGlResource<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.0.deref()
}
}
trait Resource: Clone + std::fmt::Debug {
fn drop_self(&self, gl: &glow::Context);
}
impl Resource for NativeVertexArray {
fn drop_self(&self, gl: &glow::Context) {
unsafe {
gl.delete_vertex_array(*self);
}
}
}
impl Resource for NativeBuffer {
fn drop_self(&self, gl: &glow::Context) {
unsafe {
gl.delete_buffer(*self);
}
}
}
impl Resource for NativeFramebuffer {
fn drop_self(&self, gl: &glow::Context) {
unsafe {
gl.delete_framebuffer(*self);
}
}
}
impl Resource for NativeTexture {
fn drop_self(&self, gl: &glow::Context) {
unsafe {
gl.delete_texture(*self);
}
}
}
#[derive(Debug)]
struct GlResource<'a, T: Resource> {
gl: &'a glow::Context,
resource: T,
}
impl<T: Resource> Deref for GlResource<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.resource
}
}
impl<'a, T: Resource> GlResource<'a, T> {
pub fn new(resource: T, gl: &'a glow::Context) -> Self {
Self { resource, gl }
}
}
impl<T: Resource> Drop for GlResource<'_, T> {
fn drop(&mut self) {
self.resource.drop_self(self.gl);
info!("Dropping resource: {:?}", self.resource);
}
}
impl<'a> RcGlResource<'a, NativeTexture> {
fn native2imguiid(&self) -> imgui::TextureId {
imgui::TextureId::new(self.native().0.get() as usize)
}
}

View File

@ -12,10 +12,14 @@ pub fn base(ui: &Ui, window: &winit::window::Window, run: &mut bool, app: &mut A
.build(|| { .build(|| {
if ui.button("PPI") { if ui.button("PPI") {
let data = let data =
load_data(r#"C:\Users\qwin7\Downloads\ZJSXAA_20230113070200_R.dat.gz"#).unwrap(); load_data(r#"/Users/tsuki/Desktop/ZJSXAA_20230113070200_R.dat.gz"#).unwrap();
app.create_render_window("ppi", [300.0, 300.0]).unwrap(); app.create_render_window("ppi", [300.0, 300.0]).unwrap();
app.create_ppi_render("ppi", None); app.create_ppi_render("ppi", None);
app.bind_data("ppi", &data).unwrap(); app.set_window_modifer(
"ppi",
Some(ThreeD::new(1.0, 0.1, 100.0, 45.0).unwrap().into()),
);
app.bind_data(0, "ppi", &data).unwrap();
let (rdpi, adpi, _) = { let (rdpi, adpi, _) = {
let ppi = app.ppi_module.borrow_mut(); let ppi = app.ppi_module.borrow_mut();