ppi module
This commit is contained in:
parent
91f67b395f
commit
9aab1b5304
54
Cargo.lock
generated
54
Cargo.lock
generated
@ -904,6 +904,27 @@ dependencies = [
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glsl"
|
||||
version = "7.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "577ac945ce66a4b7004c6e2807f517f94ef027dda89df578abe1fbb979d22f49"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glsl-quasiquote"
|
||||
version = "7.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "165f0276eb5b572678e2658b357d669aa08eca35032ca20381c24d58b46cca62"
|
||||
dependencies = [
|
||||
"glsl",
|
||||
"proc-macro-faithful-display",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "glutin"
|
||||
version = "0.31.3"
|
||||
@ -1860,6 +1881,12 @@ dependencies = [
|
||||
"toml_edit 0.21.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-faithful-display"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5bdf93a22e0e7b3d52e42837f111845a69957294d23671efeeb8d1baef4773a"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.85"
|
||||
@ -1938,6 +1965,8 @@ dependencies = [
|
||||
"freetype-rs",
|
||||
"geo",
|
||||
"glow",
|
||||
"glsl",
|
||||
"glsl-quasiquote",
|
||||
"glutin",
|
||||
"glutin-winit",
|
||||
"image",
|
||||
@ -1960,6 +1989,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
"tinyfiledialogs",
|
||||
"toml",
|
||||
"tracker",
|
||||
"winit",
|
||||
]
|
||||
@ -2290,9 +2320,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.6"
|
||||
version = "0.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
||||
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -2549,21 +2579,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.15"
|
||||
version = "0.8.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
|
||||
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.16",
|
||||
"toml_edit 0.22.20",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
version = "0.6.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@ -2581,15 +2611,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.16"
|
||||
version = "0.22.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
||||
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.15",
|
||||
"winnow 0.6.18",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -3213,9 +3243,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.15"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0"
|
||||
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
@ -16,7 +16,7 @@ dirs = "5.0.1"
|
||||
env_logger = "0.11.3"
|
||||
flate2 = "1.0.30"
|
||||
# font-kit = {version = "0.14.1"}
|
||||
freetype-rs = "0.37.0"
|
||||
freetype-rs = {version="0.37.0",features = ["bundled"]}
|
||||
geo = "0.28.0"
|
||||
glow = "0.13.1"
|
||||
glutin = "0.31.3"
|
||||
@ -43,9 +43,13 @@ thiserror = "1.0.61"
|
||||
winit = "0.29.3"
|
||||
tinyfiledialogs = "3.0"
|
||||
tracker = "0.2.2"
|
||||
glsl = "7.0.0"
|
||||
glsl-quasiquote = "7.0.0"
|
||||
toml = "0.8.19"
|
||||
|
||||
[features]
|
||||
default = ["sdf_font"]
|
||||
|
||||
normal_font = []
|
||||
sdf_font = []
|
||||
inparser = []
|
||||
|
||||
30
radar.toml
Normal file
30
radar.toml
Normal file
@ -0,0 +1,30 @@
|
||||
[[cmap]]
|
||||
type="DBZ"
|
||||
levels = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75]
|
||||
colors = ["#aaaaaa", "#0022ff", "#01a0f6", "#00ecec", "#00d800", "#019000", "#ffff00", "#e7c000", "#ff9000", "#ff0000", "#d60000",
|
||||
"#c00000", "#ff00f0", "#9600b4", "#ad90f0"]
|
||||
|
||||
[[cmap]]
|
||||
type="VEL"
|
||||
levels = [-90,-45, -35, -27, -20, -15, -10, -5, -1, 0, 1, 5, 10, 15, 20, 27, 1000]
|
||||
colors = ["#9fffff", "#00e0ff", "#0080ff", "#320096", "#00fb90", "#00bb90", "#008f00", "#cdc09f","#000000", "#f88700", "#ffcf00", "#ffff00", "#ae0000", "#d07000", "#dd0000", "#ff0000"]
|
||||
|
||||
[[cmap]]
|
||||
type="SW"
|
||||
colors=["#E0E0E0", "#7CE0E0", "#00E0E0", "#00B0B0", "#00FEFE", "#00C400", "#008000", "#FEFE00", "#FED200", "#FE7C00", "#FEB0B0", "#FE5858", "#FE0000", "#FEFEFE"]
|
||||
levels=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
|
||||
|
||||
[[cmap]]
|
||||
type="CC"
|
||||
colors=["#003CFF", "#00EFEF", "#00BABF", "#00837D", "#008938", "#00B729", "#00DA0D", "#00FF00", "#FFFF3B", "#FFF000", "#FFC600", "#FFA500", "#FF7200", "#FF1F00", "#C10000", "#D400AA"]
|
||||
levels=[0, 0.1, 0.3, 0.5, 0.6, 0.7, 0.8, 0.85, 0.9, 0.92, 0.94, 0.95, 0.96, 0.97, 0.98, 0.99]
|
||||
|
||||
[[cmap]]
|
||||
type="KDP"
|
||||
colors=["#00FFFF", "#00EFEF", "#00A8AC", "#B4B4B4", "#B4B4B4", "#00C027", "#00E80A", "#24FF24", "#FFFF1E", "#FFE600", "#FFBC00", "#FF9800", "#FF5E00", "#F20F00", "#BB003A", "#DD009C", "#FF00FF"]
|
||||
levels=[-0.8, -0.4, -0.2, -0.1, 0.1, 0.15, 0.22, 0.33, 0.5, 0.75, 1.1, 1.7, 2.4, 3.1, 7, 20]
|
||||
|
||||
[[cmap]]
|
||||
type="ZDR"
|
||||
colors=["#464646", "#505050", "#5A5A5A", "#646464", "#6E6E6E", "#787878", "#828282", "#8C8C8C", "#969696", "#AFAFAF", "#C8C8C8", "#DCF0DC", "#00C027", "#00E80A", "#24FF24", "#FFFF1E", "#FFF20F", "#FFE600", "#FFBC00", "#FF9800", "#FF5E00", "#FFFF00", "#F20F00", "#BB003A", "#DD009C", "#FF00FF"]
|
||||
levels=[-5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 6, 6.5, 7]
|
||||
@ -7,17 +7,17 @@ use std::num::NonZeroU32;
|
||||
pub(crate) struct Camera {
|
||||
pos: Vec3,
|
||||
upward: Vec3,
|
||||
front: Vec3,
|
||||
center: Vec3,
|
||||
}
|
||||
|
||||
pub type CameraPositon = Vec3;
|
||||
|
||||
impl Camera {
|
||||
pub(crate) fn new(world_loc: CameraPositon, upward: Vec3, front: Vec3) -> Self {
|
||||
pub(crate) fn new(world_loc: CameraPositon, upward: Vec3, center: Vec3) -> Self {
|
||||
Self {
|
||||
pos: world_loc,
|
||||
upward,
|
||||
front,
|
||||
center,
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,14 +29,6 @@ impl Camera {
|
||||
self.pos = pos;
|
||||
}
|
||||
|
||||
pub fn get_front(&self) -> Vec3 {
|
||||
self.front
|
||||
}
|
||||
|
||||
pub fn set_front(&mut self, front: Vec3) {
|
||||
self.front = front;
|
||||
}
|
||||
|
||||
pub fn get_upward(&self) -> Vec3 {
|
||||
self.upward
|
||||
}
|
||||
@ -46,8 +38,8 @@ impl Camera {
|
||||
}
|
||||
|
||||
pub fn get_view_matrix(&self) -> Mat4x4 {
|
||||
let l = self.pos + self.front;
|
||||
look_at(&l, &self.pos, &self.upward)
|
||||
let l = self.center;
|
||||
look_at(&self.pos, &l, &self.upward)
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,7 +48,7 @@ impl Default for Camera {
|
||||
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),
|
||||
center: Vec3::new(0.0, 0.0, -1.0),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ use glow::{HasContext, NativeUniformLocation};
|
||||
use super::shader::Shader;
|
||||
use super::snippets::{CodeType, Snippet};
|
||||
use crate::components::CodeComponent;
|
||||
use crate::graphics::transforms::{viewport::Viewport, Transform};
|
||||
use crate::graphics::transforms::viewport::Viewport;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Program {
|
||||
@ -45,16 +45,19 @@ impl Program {
|
||||
self.geometry.as_ref()
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
||||
self.vertex.set_hook(hook, code);
|
||||
self.fragment.set_hook(hook, code);
|
||||
self.geometry.as_mut().map(|g| g.set_hook(hook, code));
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_transform<T: Transform>(&mut self, value: &T) {
|
||||
self.set_hook("transform", value.snippet());
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||
self.set_hook("viewport", viewport.snippet());
|
||||
}
|
||||
@ -62,8 +65,11 @@ impl Program {
|
||||
pub fn compile(&mut self, gl: &glow::Context) -> crate::errors::Result<()> {
|
||||
use crate::errors::Error;
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
{
|
||||
self.vertex.define("_GLUMPY__VERTEX_SHADER__");
|
||||
self.fragment.define("_GLUMPY__FRAGMENT_SHADER__");
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let program = gl.create_program().map_err(|e| Error::InvalidProgram(e))?;
|
||||
@ -76,6 +82,7 @@ impl Program {
|
||||
|
||||
// Geom Shader
|
||||
let geom_shader = if let Some(geometry) = self.geometry.as_mut() {
|
||||
#[cfg(feature = "inparser")]
|
||||
geometry.define("_GLUMPY__GEOMETRY_SHADER__");
|
||||
let geometry_shader = geometry.compile(&self.version, gl);
|
||||
|
||||
@ -138,13 +145,13 @@ mod test {
|
||||
fn test_program() {
|
||||
let vertex = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
CodeType::<&'static str>::Path("agg-fast-path.vert".into()),
|
||||
CodeType::from_path("agg-fast-path.vert"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let fragment = Shader::new(
|
||||
glow::FRAGMENT_SHADER,
|
||||
CodeType::<&'static str>::Path("agg-fast-path.frag".into()),
|
||||
CodeType::from_path("agg-fast-path.frag"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@ -15,7 +15,10 @@ pub type ShaderType = u32;
|
||||
#[derive(Debug)]
|
||||
pub struct Shader {
|
||||
target: u32,
|
||||
#[cfg(feature = "inparser")]
|
||||
parsed: CodeBlock,
|
||||
parsed: String,
|
||||
#[cfg(feature = "inparser")]
|
||||
pub hooks: Vec<String>,
|
||||
}
|
||||
|
||||
@ -26,25 +29,34 @@ impl std::fmt::Display for Shader {
|
||||
}
|
||||
|
||||
impl Shader {
|
||||
pub fn new<S: Borrow<str>>(target: ShaderType, code: CodeType<S>) -> Result<Self> {
|
||||
pub fn new(target: ShaderType, code: CodeType) -> Result<Self> {
|
||||
let code = match code {
|
||||
CodeType::Code(code) => code.borrow().to_string(),
|
||||
CodeType::Code(code) => code,
|
||||
CodeType::Path(path) => {
|
||||
let code = find_file(path).expect(&format!("Failed to find file {}", path));
|
||||
let code = find_file(&path).expect(&format!(
|
||||
"Failed to find file {}",
|
||||
&path.as_os_str().to_str().unwrap()
|
||||
));
|
||||
code
|
||||
}
|
||||
};
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
{
|
||||
let code = merge_includes(code).map_err(|e| Error::InvalidSnippet(e.to_string()))?;
|
||||
let parsed = CodeBlock::new(&code)?;
|
||||
|
||||
let hooks = parsed.all_hooks().iter().map(|h| h.name.clone()).collect();
|
||||
info!("Shader:{} Hooks: {:?}", target, hooks);
|
||||
|
||||
Ok(Self {
|
||||
return Ok(Self {
|
||||
target,
|
||||
parsed,
|
||||
hooks,
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
target,
|
||||
parsed: code,
|
||||
})
|
||||
}
|
||||
|
||||
@ -68,11 +80,13 @@ impl Shader {
|
||||
shader
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn define(&mut self, s: &str) {
|
||||
self.parsed
|
||||
.insert(Code::new(&format!("#define {}\n", s)), 0);
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
||||
self.parsed.set_hook(hook, code);
|
||||
}
|
||||
@ -217,13 +231,8 @@ mod utils {
|
||||
body.push_str("}\n\n");
|
||||
let input = header + &body;
|
||||
|
||||
let result = Snippet::new(
|
||||
"fetch_uniform",
|
||||
CodeType::<String>::Code(input),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap();
|
||||
let result =
|
||||
Snippet::new("fetch_uniform", CodeType::from_code(input), false, None).unwrap();
|
||||
|
||||
result
|
||||
}
|
||||
@ -237,7 +246,7 @@ mod test {
|
||||
fn test_shader() {
|
||||
let shader = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
CodeType::<&'static str>::Path("agg-fast-path.vert".into()),
|
||||
CodeType::from_path("agg-fast-path.vert"),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ use std::{
|
||||
cell::{Ref, RefCell},
|
||||
collections::{HashMap, HashSet},
|
||||
ops::Add,
|
||||
path::Path,
|
||||
path::{Path, PathBuf},
|
||||
rc::Rc,
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
@ -11,6 +11,7 @@ pub use util::Variable;
|
||||
|
||||
use crate::{
|
||||
errors::{Error, Result},
|
||||
shaders::{CodePiece, EmptyPiece},
|
||||
utils::{find_file, Code, CodeBlock, Function, Hook, ShareVariable, SnippetCode},
|
||||
};
|
||||
mod util;
|
||||
@ -27,9 +28,33 @@ pub enum InputType {
|
||||
Other(Variable),
|
||||
}
|
||||
|
||||
pub enum CodeType<S: std::borrow::Borrow<str> = &'static str, P: AsRef<Path> = &'static str> {
|
||||
Code(S),
|
||||
Path(P),
|
||||
// pub enum CodeType<
|
||||
// CP: CodePiece = EmptyPiece,
|
||||
// S: std::borrow::Borrow<str> = &'static str,
|
||||
// P: AsRef<Path> = &'static str,
|
||||
// > {
|
||||
// Code(S),
|
||||
// Path(P),
|
||||
// CodePiece(CP),
|
||||
// }
|
||||
|
||||
pub enum CodeType {
|
||||
Code(String),
|
||||
Path(PathBuf),
|
||||
}
|
||||
|
||||
impl CodeType {
|
||||
pub fn from_path<P: AsRef<Path>>(path: P) -> Self {
|
||||
Self::Path(path.as_ref().to_path_buf())
|
||||
}
|
||||
|
||||
pub fn from_code<S: std::borrow::Borrow<str>>(code: S) -> Self {
|
||||
Self::Code(code.borrow().to_string())
|
||||
}
|
||||
|
||||
pub fn from_piece<CP: CodePiece>(piece: CP) -> Self {
|
||||
Self::Code(piece.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@ -44,14 +69,14 @@ pub struct Snippet {
|
||||
}
|
||||
|
||||
impl Snippet {
|
||||
pub fn new<S: std::borrow::Borrow<str>, P: AsRef<Path>>(
|
||||
pub fn new(
|
||||
name: &'static str,
|
||||
code: CodeType<S, P>,
|
||||
code: CodeType,
|
||||
mangling: bool,
|
||||
main: Option<String>,
|
||||
) -> Result<Self> {
|
||||
let code = match code {
|
||||
CodeType::Code(code) => code.borrow().to_string(),
|
||||
CodeType::Code(code) => code,
|
||||
CodeType::Path(path) => {
|
||||
let code = find_file(path).expect("Failed to find file");
|
||||
code
|
||||
@ -173,13 +198,7 @@ impl Add for Snippet {
|
||||
let code = rhs.parsed.to_string();
|
||||
|
||||
raw_code.push_str(&code);
|
||||
Snippet::new(
|
||||
self.name,
|
||||
CodeType::<std::string::String>::Code(raw_code),
|
||||
false,
|
||||
None,
|
||||
)
|
||||
.unwrap()
|
||||
Snippet::new(self.name, CodeType::from_code(raw_code), false, None).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,11 +226,9 @@ mod tests {
|
||||
}
|
||||
"#;
|
||||
|
||||
let snippet =
|
||||
Snippet::new("polar", CodeType::<&'static str>::Code(code), true, None).unwrap();
|
||||
let snippet = Snippet::new("polar", CodeType::from_code(code), true, None).unwrap();
|
||||
|
||||
let snippet2 =
|
||||
Snippet::new("polar2", CodeType::<&'static str>::Code(code), true, None).unwrap();
|
||||
let snippet2 = Snippet::new("polar2", CodeType::from_code(code), true, None).unwrap();
|
||||
|
||||
let snippet3 = snippet.clone() + snippet2.clone();
|
||||
|
||||
|
||||
@ -170,7 +170,7 @@ impl Data {
|
||||
};
|
||||
|
||||
use DataType::*;
|
||||
let valuetype = info.value_type.as_str();
|
||||
let valuetype = info.value_name.as_str();
|
||||
|
||||
let data_type = block_data_type_prepare!(valuetype,
|
||||
"ET" => ET,
|
||||
|
||||
@ -27,4 +27,7 @@ pub enum Error {
|
||||
|
||||
#[error("Invalid Font {0}")]
|
||||
FontError(String),
|
||||
|
||||
#[error("Invalid Setting {0}")]
|
||||
SettingError(String),
|
||||
}
|
||||
|
||||
@ -6,7 +6,6 @@ use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
use crate::components::{fetchcode, CodeComponent, CodeType, Program, Shader, Snippet};
|
||||
use crate::errors::*;
|
||||
use crate::graphics::transforms::viewport::Viewport;
|
||||
use crate::graphics::transforms::Transform;
|
||||
use crate::graphics::ty::Ty;
|
||||
use crate::graphics::{AttaWithBuffer, Config, Graphics};
|
||||
|
||||
@ -26,17 +25,17 @@ impl AggFastPath {
|
||||
pub fn new() -> Result<Self> {
|
||||
let vertex = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
CodeType::<String>::Path("agg-fast-path.vert".into()),
|
||||
CodeType::from_path("agg-fast-path.vert"),
|
||||
)?;
|
||||
|
||||
let fragment = Shader::new(
|
||||
glow::FRAGMENT_SHADER,
|
||||
CodeType::<String>::Path("agg-fast-path.frag".into()),
|
||||
CodeType::from_path("agg-fast-path.frag"),
|
||||
)?;
|
||||
|
||||
let input_snippet = Snippet::new(
|
||||
"input",
|
||||
CodeType::<&'static str>::Code(
|
||||
CodeType::from_code(
|
||||
"
|
||||
layout(location = 0) in vec3 prev;
|
||||
layout(location = 1) in vec3 curr;
|
||||
@ -72,10 +71,12 @@ impl AggFastPath {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_transform<T: Transform>(&mut self, transform: &T) {
|
||||
self.program.set_transform(transform);
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||
self.program.set_viewport(viewport);
|
||||
}
|
||||
@ -182,7 +183,6 @@ impl Graphics for AggFastPath {
|
||||
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
gl.bind_vertex_array(Some(self.vao.unwrap()));
|
||||
gl.draw_elements(
|
||||
glow::TRIANGLES,
|
||||
@ -425,8 +425,6 @@ impl DerefMut for Path {
|
||||
|
||||
mod test {
|
||||
|
||||
use crate::graphics::transforms::{polar::Polar, position::Position, trackball::Trackball};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
@ -1,40 +1,37 @@
|
||||
use glow::HasContext;
|
||||
|
||||
use super::ColorMap;
|
||||
use crate::components::{CodeType, Program, Snippet};
|
||||
use crate::errors::*;
|
||||
|
||||
use super::ColorMap;
|
||||
use crate::shaders::colormap::ColorMap as CmapPiece;
|
||||
use glow::HasContext;
|
||||
|
||||
pub struct LinearColormap {
|
||||
snippet: Snippet,
|
||||
colors: Vec<[u8; 4]>,
|
||||
|
||||
color_changed: bool,
|
||||
texture: Option<glow::NativeTexture>,
|
||||
|
||||
pub unvalid: f32,
|
||||
pub min: f32,
|
||||
pub max: f32,
|
||||
}
|
||||
|
||||
impl LinearColormap {
|
||||
pub fn new() -> Result<Self> {
|
||||
let snippet = Snippet::new(
|
||||
"linear",
|
||||
CodeType::<&'static str>::Path("colormap.glsl".into()),
|
||||
true,
|
||||
None,
|
||||
)?;
|
||||
|
||||
Ok(Self {
|
||||
snippet,
|
||||
colors: vec![],
|
||||
texture: None,
|
||||
color_changed: true,
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
unvalid: 0.0,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_unvalid_value(&mut self, value: f32) {
|
||||
self.unvalid = value;
|
||||
self.color_changed = true;
|
||||
}
|
||||
|
||||
pub fn set_colors(&mut self, colors: Vec<[u8; 4]>) {
|
||||
self.colors = colors;
|
||||
self.color_changed = true;
|
||||
@ -79,18 +76,14 @@ impl ColorMap for LinearColormap {
|
||||
glow::NEAREST as i32,
|
||||
);
|
||||
|
||||
let name = self.snippet.find_symbol("conf").unwrap();
|
||||
let location = program.get_uniform_location(gl, &name);
|
||||
|
||||
// gl.uniform_2_f32(location.as_ref(), 0);
|
||||
let location = program.get_uniform_location(gl, "colormap_conf");
|
||||
gl.uniform_4_f32(
|
||||
location.as_ref(),
|
||||
self.min,
|
||||
self.max,
|
||||
self.colors.len() as f32,
|
||||
125.0,
|
||||
self.unvalid,
|
||||
);
|
||||
|
||||
self.texture = Some(texture);
|
||||
}
|
||||
}
|
||||
@ -110,17 +103,12 @@ impl ColorMap for LinearColormap {
|
||||
unsafe {
|
||||
gl.active_texture(glow::TEXTURE0);
|
||||
gl.bind_texture(glow::TEXTURE_1D, self.texture);
|
||||
let name = self.snippet.find_symbol("colormap").unwrap();
|
||||
let location = program.get_uniform_location(gl, &name);
|
||||
let location = program.get_uniform_location(gl, "colormap");
|
||||
gl.uniform_1_i32(location.as_ref(), 0);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn snippet_ref(&self) -> &crate::components::Snippet {
|
||||
&self.snippet
|
||||
}
|
||||
}
|
||||
|
||||
mod test {
|
||||
|
||||
@ -11,7 +11,5 @@ pub trait ColorMap {
|
||||
|
||||
fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()>;
|
||||
|
||||
fn snippet_ref(&self) -> &crate::components::Snippet;
|
||||
|
||||
fn destroy(&mut self, gl: &glow::Context);
|
||||
}
|
||||
|
||||
@ -13,7 +13,7 @@ use crate::{
|
||||
utils::resources::RcGlTexture,
|
||||
};
|
||||
|
||||
use super::{threed::ThreeD, transforms::viewport::Viewport, AttaWithBuffer, Config, Graphics};
|
||||
use super::{transforms::viewport::Viewport, AttaWithBuffer, Config, Graphics};
|
||||
pub struct Text<'a> {
|
||||
gl: &'a glow::Context,
|
||||
font_manager: RefCell<FontManager>,
|
||||
@ -153,13 +153,13 @@ impl<'a> Text<'a> {
|
||||
pub fn new(gl: &'a glow::Context, font_manager: FontManager) -> Result<Self> {
|
||||
let vertex = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
crate::components::CodeType::<&str>::Path("font.vert"),
|
||||
crate::components::CodeType::from_path("font.vert"),
|
||||
)?;
|
||||
|
||||
let fragment = Shader::new(glow::FRAGMENT_SHADER, CodeType::<&str>::Path("font.frag"))?;
|
||||
let fragment = Shader::new(glow::FRAGMENT_SHADER, CodeType::from_path("font.frag"))?;
|
||||
|
||||
let transform = ThreeD::new(1.0, 0.1, 100.0, 45.0)?;
|
||||
let mut program = Program::new(vertex, fragment, None, "330 core");
|
||||
#[cfg(feature = "inparser")]
|
||||
program.set_transform(&transform);
|
||||
|
||||
Ok(Self {
|
||||
@ -171,6 +171,7 @@ impl<'a> Text<'a> {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "inparser")]
|
||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||
self.program.set_viewport(viewport);
|
||||
}
|
||||
|
||||
@ -20,15 +20,8 @@ pub struct Hello {
|
||||
|
||||
impl Hello {
|
||||
pub fn new() -> Result<Self> {
|
||||
let vertex = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
CodeType::<String>::Path("hello.vert".into()),
|
||||
)?;
|
||||
|
||||
let fragment = Shader::new(
|
||||
glow::FRAGMENT_SHADER,
|
||||
CodeType::<String>::Path("hello.frag".into()),
|
||||
)?;
|
||||
let vertex = Shader::new(glow::VERTEX_SHADER, CodeType::from_path("hello.vert"))?;
|
||||
let fragment = Shader::new(glow::FRAGMENT_SHADER, CodeType::from_path("hello.frag"))?;
|
||||
|
||||
let program = Program::new(vertex, fragment, None, "330 core");
|
||||
|
||||
@ -284,8 +277,6 @@ impl DerefMut for Path {
|
||||
|
||||
mod test {
|
||||
|
||||
use crate::graphics::transforms::{polar::Polar, position::Position, trackball::Trackball};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
|
||||
@ -9,7 +9,13 @@ pub mod tools;
|
||||
pub mod transforms;
|
||||
pub mod ty;
|
||||
|
||||
use crate::{components::Program, errors::*, graphics::font::FontConfig};
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
components::Program,
|
||||
errors::*,
|
||||
graphics::font::FontConfig,
|
||||
ui::{operation::Projection, typ::CameraOP},
|
||||
};
|
||||
|
||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
use ppi::PPIConfig;
|
||||
@ -113,11 +119,22 @@ pub enum Config {
|
||||
config_for_everyitem!({PPIConfig => PPI},{FontConfig => Font}, );
|
||||
|
||||
pub trait AttachWithMouse {
|
||||
fn attach_with_mouse(&mut self, state: &MouseState);
|
||||
type State: CameraOP;
|
||||
fn attach_with_mouse(
|
||||
&mut self,
|
||||
state: &Self::State,
|
||||
camera: &mut Camera,
|
||||
projection: &mut Projection,
|
||||
) -> bool;
|
||||
|
||||
fn reset(&mut self);
|
||||
|
||||
fn init_camera(&self) -> Camera;
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum MouseState {
|
||||
Drag { from: [f32; 2], delta: [f32; 2] },
|
||||
Wheel(f32),
|
||||
None,
|
||||
}
|
||||
|
||||
@ -1,92 +1,64 @@
|
||||
use super::colormap::ColorMap;
|
||||
use super::threed::ThreeD;
|
||||
use super::transforms::viewport::Viewport;
|
||||
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics};
|
||||
use crate::components::{CodeType, Program, Shader};
|
||||
use crate::data_loader::{CoordType, Data, DataType};
|
||||
use crate::errors::*;
|
||||
use crate::graphics::colormap::linear::LinearColormap;
|
||||
use crate::graphics::transforms::Transform;
|
||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
|
||||
pub struct PPI {
|
||||
program: Program,
|
||||
cmap: Option<Box<dyn ColorMap>>,
|
||||
cmap: LinearColormap,
|
||||
}
|
||||
|
||||
impl PPI {
|
||||
pub fn new() -> Result<Self> {
|
||||
let vertex = Shader::new(
|
||||
glow::VERTEX_SHADER,
|
||||
CodeType::<String>::Path("ppi.vert".into()),
|
||||
)?;
|
||||
|
||||
let geom = Shader::new(
|
||||
glow::GEOMETRY_SHADER,
|
||||
CodeType::<String>::Path("ppi.geom".into()),
|
||||
)?;
|
||||
|
||||
use crate::shaders::ppi::*;
|
||||
let vertex = Shader::new(glow::VERTEX_SHADER, CodeType::from_piece(PPIVertex::new()))?;
|
||||
let geom = Shader::new(glow::GEOMETRY_SHADER, CodeType::from_piece(PPIGeom::new()))?;
|
||||
let fragment = Shader::new(
|
||||
glow::FRAGMENT_SHADER,
|
||||
CodeType::<String>::Path("ppi.frag".into()),
|
||||
CodeType::from_piece(PPIFragment::new()),
|
||||
)?;
|
||||
|
||||
let mut cmap = LinearColormap::new()?;
|
||||
cmap.set_colors(vec![
|
||||
[170, 170, 170, 255],
|
||||
[0, 34, 255, 255],
|
||||
[1, 160, 246, 255],
|
||||
[0, 236, 236, 255],
|
||||
[0, 216, 0, 255],
|
||||
[1, 144, 0, 255],
|
||||
[255, 255, 0, 255],
|
||||
[231, 192, 0, 255],
|
||||
[255, 144, 0, 255],
|
||||
[255, 0, 0, 255],
|
||||
[214, 0, 0, 255],
|
||||
[192, 0, 0, 255],
|
||||
[255, 0, 240, 255],
|
||||
[150, 0, 180, 255],
|
||||
]);
|
||||
cmap.set_range(0.0, 70.0);
|
||||
|
||||
let transform = ThreeD::new(1.0, 0.1, 100.0, 45.0)?;
|
||||
|
||||
let mut program = Program::new(vertex, fragment, Some(geom), "330 core");
|
||||
program.set_transform(&transform);
|
||||
program.set_hook("colormap", cmap.snippet_ref());
|
||||
|
||||
Ok(Self {
|
||||
program,
|
||||
cmap: Some(Box::new(cmap)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||
self.program.set_viewport(viewport);
|
||||
Ok(Self { program, cmap })
|
||||
}
|
||||
|
||||
pub fn program(&mut self) -> &mut Program {
|
||||
&mut self.program
|
||||
}
|
||||
|
||||
fn set_conf(&self, gl: &glow::Context, rdpi: f32, adpi: f32) {
|
||||
fn set_conf(&mut self, gl: &glow::Context, config: &PPIConfig) {
|
||||
let rdpi = config.rdpi;
|
||||
let adpi = config.adpi;
|
||||
let location = self.program.get_uniform_location(gl, "conf");
|
||||
self.cmap
|
||||
.set_range(config.color_range[0], config.color_range[1]);
|
||||
self.cmap.set_colors(config.colors.clone());
|
||||
self.cmap.set_unvalid_value(config.unvalid_value);
|
||||
self.cmap.attach_with_program(gl, &self.program);
|
||||
|
||||
unsafe {
|
||||
gl.uniform_4_f32(location.as_ref(), rdpi, adpi, 0f32, 0f32);
|
||||
gl.uniform_4_f32(
|
||||
location.as_ref(),
|
||||
rdpi,
|
||||
adpi,
|
||||
0f32,
|
||||
if config.three_d { 1.0 } else { 0.0 },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// fn bake_data(&self, data: &Data, layer: usize) -> Result<(Vec<f32>, i32)> {
|
||||
|
||||
// }
|
||||
|
||||
pub fn data_info(&self, data: &Data) -> Result<(f32, f32, DataType)> {
|
||||
pub fn data_info(&self, data: &Data) -> Result<(f32, f32, DataType, usize, f32)> {
|
||||
let first_block = data.blocks.get(0).unwrap();
|
||||
if let CoordType::Polar {
|
||||
azimuth,
|
||||
r,
|
||||
r_range,
|
||||
elevation,
|
||||
..
|
||||
} = &first_block.coord_type
|
||||
{
|
||||
@ -94,24 +66,25 @@ impl PPI {
|
||||
sorted_azimuth.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater));
|
||||
let azi_step = max_step(&sorted_azimuth);
|
||||
let r_step = min_step(r) / (r_range[1]) as f32;
|
||||
return Ok((r_step, azi_step, first_block.data_type));
|
||||
|
||||
let unvalid = first_block.unvalid_value;
|
||||
|
||||
return Ok((
|
||||
r_step,
|
||||
azi_step,
|
||||
first_block.data_type,
|
||||
elevation.len(),
|
||||
unvalid,
|
||||
));
|
||||
} else {
|
||||
return Err(Error::InvalidDataType);
|
||||
}
|
||||
}
|
||||
|
||||
fn init(&mut self, gl: &glow::Context, config: &PPIConfig) {
|
||||
self.cmap
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.attach_with_program(gl, &self.program)
|
||||
.unwrap();
|
||||
|
||||
self.set_conf(gl, config);
|
||||
self.cmap.attach_with_program(gl, &self.program).unwrap();
|
||||
let origin = self.program.get_uniform_location(gl, "polar_origin");
|
||||
|
||||
let rdpi = config.rdpi;
|
||||
let adpi = config.adpi;
|
||||
self.set_conf(gl, rdpi, adpi);
|
||||
unsafe {
|
||||
gl.uniform_1_f32(origin.as_ref(), 90.0f32.to_radians());
|
||||
}
|
||||
@ -162,12 +135,7 @@ impl Graphics for PPI {
|
||||
|
||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
self.cmap
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.bind_texture(gl, &self.program)?;
|
||||
|
||||
self.cmap.bind_texture(gl, &self.program)?;
|
||||
gl.draw_arrays(glow::POINTS, 0, count);
|
||||
}
|
||||
Ok(())
|
||||
@ -215,6 +183,7 @@ impl AttaWithBuffer for PPI {
|
||||
if let CoordType::Polar {
|
||||
r_range,
|
||||
azimuth,
|
||||
elevation,
|
||||
r,
|
||||
..
|
||||
} = &first_block.coord_type
|
||||
@ -223,13 +192,15 @@ impl AttaWithBuffer for PPI {
|
||||
let r_len = r.len();
|
||||
|
||||
let mut vertices = Vec::with_capacity(azimuth_len * r_len);
|
||||
let ele = elevation.get(layer).unwrap();
|
||||
|
||||
for azi_idx in 0..azimuth_len {
|
||||
for r_idx in 0..r_len {
|
||||
let azi = azimuth.get(azi_idx).unwrap();
|
||||
let r = r.get(r_idx).unwrap() / r_range[1] as f32;
|
||||
// let r = *r.get(r_idx).unwrap();
|
||||
let dt = first_block_data.get([layer, azi_idx, r_idx]).unwrap();
|
||||
vertices.extend([r, *azi, *dt]);
|
||||
vertices.extend([r, *azi, *ele, *dt]);
|
||||
}
|
||||
}
|
||||
let len = vertices.len() as i32 / 3;
|
||||
@ -246,7 +217,7 @@ impl AttaWithBuffer for PPI {
|
||||
let vbo = gl.create_buffer().unwrap();
|
||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||
gl.enable_vertex_attrib_array(0);
|
||||
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 12, 0);
|
||||
gl.vertex_attrib_pointer_f32(0, 4, glow::FLOAT, false, 16, 0);
|
||||
gl.bind_vertex_array(None);
|
||||
|
||||
(vao, vbo, None)
|
||||
@ -256,9 +227,13 @@ impl AttaWithBuffer for PPI {
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct PPIConfig {
|
||||
pub unvalid_value: f32,
|
||||
pub layer: usize,
|
||||
pub colors: Vec<[u8; 4]>,
|
||||
pub color_range: [f32; 2],
|
||||
pub rdpi: f32,
|
||||
pub adpi: f32,
|
||||
pub three_d: bool,
|
||||
}
|
||||
|
||||
mod test {
|
||||
|
||||
@ -1,138 +1,75 @@
|
||||
use std::rc::Rc;
|
||||
use tracker::track;
|
||||
|
||||
use super::transforms::Transform;
|
||||
use super::transforms::{position::Position, trackball::Trackball, ChainedTransform};
|
||||
use super::transforms::{position::Position, trackball::TrackballModel};
|
||||
use super::{AttaWithProgram, AttachWithMouse};
|
||||
use crate::camera::Camera;
|
||||
use crate::camera::{self, Camera};
|
||||
use crate::errors::*;
|
||||
use crate::ui::operation::Projection;
|
||||
use glow::HasContext;
|
||||
use nalgebra_glm::Vec3;
|
||||
use nalgebra_glm::{Mat4, Vec3};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ThreeD {
|
||||
transform: Rc<ChainedTransform>,
|
||||
projection: nalgebra_glm::Mat4,
|
||||
trackball: Trackball,
|
||||
camera: Camera,
|
||||
pub struct Trackball {
|
||||
trackball: TrackballModel,
|
||||
}
|
||||
|
||||
impl ThreeD {
|
||||
impl Trackball {
|
||||
pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result<Self> {
|
||||
let trackball = Trackball::new()?;
|
||||
let transform = ChainedTransform::from(&trackball).chain(&Position::new()?);
|
||||
let trackball = TrackballModel::new(0.0, 90.0);
|
||||
|
||||
let camera = Camera::new(
|
||||
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.to_radians(), z_near, z_far);
|
||||
|
||||
Ok(Self {
|
||||
transform: Rc::new(transform),
|
||||
trackball,
|
||||
camera,
|
||||
projection,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn set_aspect(&mut self, aspect: f32) {
|
||||
self.projection = nalgebra_glm::perspective(aspect, 45.0f32.to_radians(), 0.1, 100.0);
|
||||
}
|
||||
|
||||
pub fn set_fov(&mut self, fov: f32) {
|
||||
self.projection = nalgebra_glm::perspective(1.0, fov.to_radians(), 0.1, 100.0);
|
||||
}
|
||||
|
||||
pub fn set_z_near(&mut self, z_near: f32) {
|
||||
self.projection = nalgebra_glm::perspective(1.0, 45.0f32.to_radians(), z_near, 100.0);
|
||||
}
|
||||
|
||||
pub fn set_z_far(&mut self, z_far: f32) {
|
||||
self.projection = nalgebra_glm::perspective(1.0, 45.0f32.to_radians(), 0.1, z_far);
|
||||
Ok(Self { trackball })
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ThreeD {
|
||||
impl Default for Trackball {
|
||||
fn default() -> Self {
|
||||
Self::new(16.0 / 9.0, 0.1, 1000.0, 45.0).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithProgram for ThreeD {
|
||||
impl AttaWithProgram for Trackball {
|
||||
fn attach_with_program(
|
||||
&self,
|
||||
gl: &glow::Context,
|
||||
program: &crate::components::Program,
|
||||
) -> Result<()> {
|
||||
unsafe {
|
||||
let view = program.get_uniform_location(gl, "trackball_view");
|
||||
let projection = program.get_uniform_location(gl, "trackball_projection");
|
||||
let model = program.get_uniform_location(gl, "trackball_model");
|
||||
|
||||
let view_mat = nalgebra_glm::translation(&nalgebra_glm::vec3(0.0, 0.0, -3.0));
|
||||
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
view.as_ref(),
|
||||
false,
|
||||
// nalgebra::Matrix4::identity().as_slice(),
|
||||
view_mat.as_slice(),
|
||||
// self.camera.get_view_matrix().as_slice(),
|
||||
);
|
||||
|
||||
// println!("projection: {:?}", self.projection);
|
||||
|
||||
// let scale_factor = nalgebra_glm::vec3(1.5, 1.5, 1.0);
|
||||
// let res = nalgebra_glm::scaling(&scale_factor);
|
||||
let ident: nalgebra_glm::Mat4 = nalgebra_glm::identity();
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
model.as_ref(),
|
||||
false,
|
||||
ident.as_slice(),
|
||||
// nalgebra::Matrix4::identity().as_slice(),
|
||||
);
|
||||
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
view.as_ref(),
|
||||
false,
|
||||
ident.as_slice(),
|
||||
// nalgebra::Matrix4::identity().as_slice(),
|
||||
);
|
||||
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
projection.as_ref(),
|
||||
false,
|
||||
ident.as_slice(),
|
||||
// nalgebra::Matrix4::identity().as_slice(),
|
||||
);
|
||||
|
||||
// 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,
|
||||
// rotate.as_slice(), // nalgebra::Matrix4::identity().as_slice(),
|
||||
// );
|
||||
|
||||
// gl.uniform_matrix_4_f32_slice(projection.as_ref(), false, self.projection.as_slice());
|
||||
}
|
||||
self.trackball.attach_with_program(gl, program);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for ThreeD {
|
||||
fn snippet(&self) -> &crate::components::Snippet {
|
||||
self.transform.snippet()
|
||||
impl AttachWithMouse for Trackball {
|
||||
type State = super::MouseState;
|
||||
fn attach_with_mouse(
|
||||
&mut self,
|
||||
state: &Self::State,
|
||||
camera: &mut Camera,
|
||||
projection: &mut Projection,
|
||||
) -> bool {
|
||||
match state {
|
||||
&super::MouseState::Wheel(delta) => {
|
||||
projection.set_fov((projection.fov() - delta).clamp(15.0, 120.0));
|
||||
true
|
||||
}
|
||||
super::MouseState::Drag { from, delta } => {
|
||||
self.trackball.drag_to(from[0], from[1], delta[0], delta[1]);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AttachWithMouse for ThreeD {
|
||||
fn attach_with_mouse(&mut self, state: &super::MouseState) {
|
||||
if let super::MouseState::Drag { from, delta } = state {
|
||||
self.trackball
|
||||
.on_mouse_drag(from[0], from[1], delta[0], delta[1]);
|
||||
fn reset(&mut self) {
|
||||
self.trackball.set_phi(90.0);
|
||||
self.trackball.set_theta(0.0);
|
||||
}
|
||||
|
||||
fn init_camera(&self) -> Camera {
|
||||
Camera::new(
|
||||
Vec3::new(0.0, 30.0, 10.0),
|
||||
Vec3::new(0.0, 1.0, 0.0),
|
||||
Vec3::new(0.0, 0.0, 0.0),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,59 +6,56 @@ use crate::components::{Program, Snippet};
|
||||
|
||||
use super::AttaWithProgram;
|
||||
|
||||
pub struct ChainedTransform {
|
||||
snippet: Snippet,
|
||||
chain: Vec<Box<dyn Transform>>,
|
||||
}
|
||||
// pub struct ChainedTransform {
|
||||
// snippet: Snippet,
|
||||
// chain: Vec<Box<dyn Transform>>,
|
||||
// }
|
||||
|
||||
impl ChainedTransform {
|
||||
pub fn from<T: Transform + Clone + 'static>(transform: &T) -> Self {
|
||||
let snippet = transform.snippet().clone();
|
||||
// let snippet = transform.snippet().to_owned();
|
||||
Self {
|
||||
snippet,
|
||||
chain: vec![Box::new(transform.clone())],
|
||||
}
|
||||
}
|
||||
// impl ChainedTransform {
|
||||
// pub fn from<T: Transform + Clone + 'static>(transform: &T) -> Self {
|
||||
// let snippet = transform.snippet().clone();
|
||||
// // let snippet = transform.snippet().to_owned();
|
||||
// Self {
|
||||
// snippet,
|
||||
// chain: vec![Box::new(transform.clone())],
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn chain<P: Transform + 'static + Clone>(mut self, other: &P) -> Self {
|
||||
let new_snippet = self.snippet.clone().chain(other.snippet().to_owned());
|
||||
self.snippet = new_snippet;
|
||||
self.chain.push(Box::new(other.clone()));
|
||||
self
|
||||
}
|
||||
}
|
||||
// pub fn chain<P: Transform + 'static + Clone>(mut self, other: &P) -> Self {
|
||||
// let new_snippet = self.snippet.clone().chain(other.snippet().to_owned());
|
||||
// self.snippet = new_snippet;
|
||||
// self.chain.push(Box::new(other.clone()));
|
||||
// self
|
||||
// }
|
||||
// }
|
||||
|
||||
impl Transform for ChainedTransform {
|
||||
fn snippet(&self) -> &Snippet {
|
||||
&self.snippet
|
||||
}
|
||||
}
|
||||
// impl Transform for ChainedTransform {
|
||||
// fn snippet(&self) -> &Snippet {
|
||||
// &self.snippet
|
||||
// }
|
||||
// }
|
||||
|
||||
impl AttaWithProgram for ChainedTransform {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> super::Result<()> {
|
||||
for transform in &self.chain {
|
||||
transform.attach_with_program(gl, program)?;
|
||||
}
|
||||
// impl AttaWithProgram for ChainedTransform {
|
||||
// fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> super::Result<()> {
|
||||
// for transform in &self.chain {
|
||||
// transform.attach_with_program(gl, program)?;
|
||||
// }
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub trait Transform: AttaWithProgram {
|
||||
fn snippet(&self) -> &Snippet;
|
||||
}
|
||||
// Ok(())
|
||||
// }
|
||||
// }
|
||||
|
||||
mod test {
|
||||
use super::*;
|
||||
// mod test {
|
||||
// use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_transform() {
|
||||
let polar = polar::Polar::new().unwrap();
|
||||
// let trackball = trackball::Trackball::new().unwrap();
|
||||
// #[test]
|
||||
// fn test_transform() {
|
||||
// let polar = polar::Polar::new().unwrap();
|
||||
// // let trackball = trackball::Trackball::new().unwrap();
|
||||
|
||||
// let chained = ChainedTransform::from(polar).chain(trackball);
|
||||
// // let chained = ChainedTransform::from(polar).chain(trackball);
|
||||
|
||||
// println!("{}", chained.snippet().prepare_code());
|
||||
// println!("{}", chained.snippet().call(&vec![]).unwrap());
|
||||
}
|
||||
}
|
||||
// // println!("{}", chained.snippet().prepare_code());
|
||||
// // println!("{}", chained.snippet().call(&vec![]).unwrap());
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -4,8 +4,6 @@ use crate::{
|
||||
graphics::AttaWithProgram,
|
||||
};
|
||||
|
||||
use super::Transform;
|
||||
|
||||
pub struct Polar {
|
||||
snippet: Snippet,
|
||||
origin: f32,
|
||||
@ -15,7 +13,7 @@ impl Polar {
|
||||
pub fn new() -> Result<Self> {
|
||||
let snippets = Snippet::new(
|
||||
"polar",
|
||||
CodeType::<&'static str>::Path("transform/polar.glsl".into()),
|
||||
CodeType::from_path("transform/polar.glsl"),
|
||||
true,
|
||||
Some("forward".to_string()),
|
||||
)?;
|
||||
@ -27,12 +25,6 @@ impl Polar {
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for Polar {
|
||||
fn snippet(&self) -> &Snippet {
|
||||
&self.snippet
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithProgram for Polar {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
Ok(())
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
use super::Transform;
|
||||
use crate::{
|
||||
components::{CodeType, Program, Snippet},
|
||||
errors::*,
|
||||
@ -13,7 +12,7 @@ impl Position {
|
||||
pub fn new() -> Result<Self> {
|
||||
let snippets = Snippet::new(
|
||||
"position",
|
||||
CodeType::<&'static str>::Path("transform/position.glsl".into()),
|
||||
CodeType::from_path("transform/position.glsl"),
|
||||
false,
|
||||
None,
|
||||
)?;
|
||||
@ -22,12 +21,6 @@ impl Position {
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for Position {
|
||||
fn snippet(&self) -> &Snippet {
|
||||
&self.snippet
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithProgram for Position {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
Ok(())
|
||||
|
||||
@ -2,8 +2,6 @@ use crate::components::{CodeType, Program, Snippet};
|
||||
use crate::errors::Result;
|
||||
use crate::graphics::AttaWithProgram;
|
||||
|
||||
use super::Transform;
|
||||
|
||||
use glow::HasContext;
|
||||
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
|
||||
|
||||
@ -27,7 +25,7 @@ impl TrackballModel {
|
||||
count: 0,
|
||||
model: Matrix4::identity(),
|
||||
renorm_count: 97,
|
||||
trackball_size: 0.8,
|
||||
trackball_size: 100.0,
|
||||
x: 0.0,
|
||||
y: 0.0,
|
||||
theta,
|
||||
@ -37,7 +35,7 @@ impl TrackballModel {
|
||||
trackball
|
||||
}
|
||||
|
||||
fn drag_to(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
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;
|
||||
self.count += 1;
|
||||
@ -56,7 +54,7 @@ impl TrackballModel {
|
||||
self.theta
|
||||
}
|
||||
|
||||
fn set_theta(&mut self, theta: f32) {
|
||||
pub fn set_theta(&mut self, theta: f32) {
|
||||
self.set_orientation(theta % 360.0, self.phi % 360.0);
|
||||
}
|
||||
|
||||
@ -64,7 +62,7 @@ impl TrackballModel {
|
||||
self.phi
|
||||
}
|
||||
|
||||
fn set_phi(&mut self, phi: f32) {
|
||||
pub fn set_phi(&mut self, phi: f32) {
|
||||
self.set_orientation(self.theta % 360.0, phi % 360.0);
|
||||
}
|
||||
|
||||
@ -83,12 +81,12 @@ impl TrackballModel {
|
||||
self.theta = theta;
|
||||
self.phi = phi;
|
||||
|
||||
let angle = self.theta * (std::f32::consts::PI / 180.0);
|
||||
let angle = self.theta.to_radians();
|
||||
let sine = (0.5 * angle).sin();
|
||||
let xrot =
|
||||
UnitQuaternion::from_quaternion(Quaternion::new((0.5 * angle).cos(), sine, 0.0, 0.0));
|
||||
|
||||
let angle = self.phi * (std::f32::consts::PI / 180.0);
|
||||
let angle = self.phi.to_radians();
|
||||
let sine = (0.5 * angle).sin();
|
||||
let zrot =
|
||||
UnitQuaternion::from_quaternion(Quaternion::new((0.5 * angle).cos(), 0.0, 0.0, sine));
|
||||
@ -129,49 +127,27 @@ impl TrackballModel {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Trackball {
|
||||
snippet: Snippet,
|
||||
model: TrackballModel,
|
||||
}
|
||||
// impl Trackball {
|
||||
// pub fn new() -> Result<Self> {
|
||||
// let model = TrackballModel::new(0.0, 0.0);
|
||||
|
||||
impl Trackball {
|
||||
pub fn new() -> Result<Self> {
|
||||
let snippets = Snippet::new(
|
||||
"trackball",
|
||||
CodeType::<&'static str>::Path("transform/trackball.glsl".into()),
|
||||
false,
|
||||
None,
|
||||
)?;
|
||||
// Ok(Self { model })
|
||||
// }
|
||||
|
||||
let model = TrackballModel::new(45.0, 45.0);
|
||||
// pub fn on_mouse_drag(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
// self.model.drag_to(x, y, dx, dy);
|
||||
// }
|
||||
|
||||
Ok(Self {
|
||||
snippet: snippets,
|
||||
model,
|
||||
})
|
||||
}
|
||||
// pub fn model(&self) -> &Matrix4<f32> {
|
||||
// self.model.model()
|
||||
// }
|
||||
// }
|
||||
|
||||
pub fn on_mouse_drag(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
||||
self.model.drag_to(x, y, dx, dy);
|
||||
}
|
||||
|
||||
pub fn model(&self) -> &Matrix4<f32> {
|
||||
self.model.model()
|
||||
}
|
||||
}
|
||||
|
||||
impl Transform for Trackball {
|
||||
fn snippet(&self) -> &Snippet {
|
||||
&self.snippet
|
||||
}
|
||||
}
|
||||
|
||||
impl AttaWithProgram for Trackball {
|
||||
impl AttaWithProgram for TrackballModel {
|
||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||
unsafe {
|
||||
let l = program.get_uniform_location(gl, "trackball_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().as_slice());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -183,6 +159,12 @@ mod test {
|
||||
|
||||
#[test]
|
||||
fn test_trackball() {
|
||||
let mut trackball = TrackballModel::new(45.0, 45.0);
|
||||
println!("{:?}", trackball.model());
|
||||
|
||||
trackball.drag_to(0.0, 10.0, 15.0, 30.0);
|
||||
println!("{:?}", trackball.model());
|
||||
|
||||
// let trackball = Trackball::new().unwrap();
|
||||
// println!("{}", trackball.snippet);
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ impl Viewport {
|
||||
pub fn new() -> Result<Self> {
|
||||
let snippets = Snippet::new(
|
||||
"viewport",
|
||||
CodeType::<&'static str>::Path("transform/viewport.glsl".into()),
|
||||
CodeType::from_path("transform/viewport.glsl"),
|
||||
true,
|
||||
None,
|
||||
)?;
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
#![feature(proc_macro_hygiene)]
|
||||
#![allow(unused)]
|
||||
mod camera;
|
||||
mod components;
|
||||
@ -6,6 +7,8 @@ mod errors;
|
||||
mod font_manager;
|
||||
mod graphics;
|
||||
mod pg;
|
||||
mod setting;
|
||||
mod shaders;
|
||||
mod support;
|
||||
mod ui;
|
||||
mod utils;
|
||||
@ -13,6 +16,9 @@ mod utils;
|
||||
use pg::App;
|
||||
use support::supporter::run;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
static SETTING: Lazy<setting::Setting> = Lazy::new(|| setting::Setting::new());
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
run(move |gl| App::new(gl).unwrap());
|
||||
|
||||
@ -5,7 +5,7 @@ use crate::{
|
||||
data_loader::Data,
|
||||
errors::*,
|
||||
graphics::{
|
||||
colormap::linear::LinearColormap, ppi::PPI, threed::ThreeD, AttaWithBuffer,
|
||||
colormap::linear::LinearColormap, ppi::PPI, threed::Trackball, AttaWithBuffer,
|
||||
AttaWithProgram, Graphics,
|
||||
},
|
||||
ui::{State, GUI},
|
||||
@ -20,7 +20,7 @@ use crate::{
|
||||
use glow::HasContext;
|
||||
use imgui::Ui;
|
||||
|
||||
use super::app_type::{self, AppType};
|
||||
use super::layout_type::{self, Layout};
|
||||
use super::{ModulePackage, Programs};
|
||||
use crate::{font_manager::FontManager, graphics::font::Text};
|
||||
|
||||
@ -28,30 +28,24 @@ pub struct App<'gl> {
|
||||
gl: &'gl GL,
|
||||
context: Context<'gl>,
|
||||
gui: GUI,
|
||||
app_type: AppType<'gl>,
|
||||
layout: Layout<'gl>,
|
||||
}
|
||||
|
||||
impl<'gl> App<'gl> {
|
||||
pub fn new(gl: &'gl GL) -> Result<Self> {
|
||||
let programs = Programs::new(gl).unwrap();
|
||||
let mut default_state = State::default();
|
||||
|
||||
let mut gui = GUI::new(State::default());
|
||||
let app_type = gui.apptype(gl);
|
||||
|
||||
let layout = gui.layout(gl);
|
||||
let context = Context::new(gl, Cache::new(), programs);
|
||||
Ok(Self {
|
||||
gui,
|
||||
gl,
|
||||
context,
|
||||
app_type,
|
||||
layout,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn init<'a>(&'a mut self) -> AppType {
|
||||
self.gui.apptype(&self.gl)
|
||||
}
|
||||
|
||||
pub fn prepare(&mut self) {
|
||||
if let Err(e) = self.context.programs.prepare() {
|
||||
error!("prepare failed: {:?}", e);
|
||||
@ -67,13 +61,13 @@ impl<'gl> App<'gl> {
|
||||
}
|
||||
|
||||
pub fn render<'a>(&'a mut self) {
|
||||
if let Err(e) = self.app_type.draw_program(&mut self.context) {
|
||||
if let Err(e) = self.layout.launch_render_task(&mut self.context) {
|
||||
error!("draw_program failed: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn render_ui<'a>(&'a mut self, ui: &Ui, window: &winit::window::Window, run: &mut bool) {
|
||||
*run = self.gui.render(ui, &mut self.context, &mut self.app_type);
|
||||
*run = self.gui.render(ui, &mut self.context, &mut self.layout);
|
||||
}
|
||||
|
||||
pub fn destroy(&mut self) {
|
||||
|
||||
@ -1,28 +1,70 @@
|
||||
use crate::errors::*;
|
||||
use crate::graphics::ty;
|
||||
use crate::pg::{Context, ModulePackage};
|
||||
use crate::ui::typ::{LayoutAppType, MainLoadTyp};
|
||||
use crate::ui::typ::{LayoutAttach, MainLoadAttach};
|
||||
use crate::utils::resources::{ManagedResource, RcGlRcFramebuffer, RcGlRcRenderbuffer, GL};
|
||||
use crate::{errors::*, main};
|
||||
use glow::HasContext;
|
||||
|
||||
const RBO_WIDTH: i32 = 1920;
|
||||
const RBO_HEIGHT: i32 = 1080;
|
||||
|
||||
// App Layout Type
|
||||
macro_rules! impl_layout {
|
||||
($({$name:ident => $attach:ty}),+ $(,)?) => {
|
||||
pub enum Layout<'gl> {
|
||||
$(
|
||||
$name($attach),
|
||||
)+
|
||||
}
|
||||
|
||||
impl<'gl> Layout<'gl> {
|
||||
pub fn launch_render_task(&mut self, mut context: &mut Context<'gl>) -> Result<()>
|
||||
{
|
||||
let programs = &mut context.programs;
|
||||
let gl = programs.gl;
|
||||
|
||||
match self {
|
||||
$(
|
||||
Self::$name(typ) => {
|
||||
typ.render_task(gl, programs)?;
|
||||
}
|
||||
)+
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn append_package(&mut self, package: ModulePackage<'gl>) {
|
||||
match self {
|
||||
$(
|
||||
Self::$name(typ) => {
|
||||
typ.append(package);
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub struct ViewPort {
|
||||
renderer_size: [f32; 2],
|
||||
main_fbo: RcGlRcFramebuffer,
|
||||
_main_rbo: RcGlRcRenderbuffer,
|
||||
_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);
|
||||
main_rbo.bind(glow::RENDERBUFFER);
|
||||
|
||||
unsafe {
|
||||
// Color Attachment
|
||||
main_rbo.bind(glow::RENDERBUFFER);
|
||||
gl.renderbuffer_storage(glow::RENDERBUFFER, glow::RGBA8, RBO_WIDTH, RBO_HEIGHT);
|
||||
gl.framebuffer_renderbuffer(
|
||||
glow::FRAMEBUFFER,
|
||||
@ -30,12 +72,33 @@ impl ViewPort {
|
||||
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);
|
||||
|
||||
@ -43,6 +106,7 @@ impl ViewPort {
|
||||
renderer_size: [0.0, 0.0],
|
||||
main_fbo,
|
||||
_main_rbo: main_rbo,
|
||||
_main_depth_rbo: main_depth_rbo,
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,70 +140,6 @@ impl ViewPort {
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! app_type_into {
|
||||
($({$t: ty => $b:tt},)+) => {
|
||||
$(
|
||||
impl<'gl> From<$t> for AppType<'gl> {
|
||||
fn from(t: $t) -> Self {
|
||||
Self::$b(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'gl> From<&'a AppType<'gl>> for &'a $t {
|
||||
fn from(t: &'a AppType<'gl>) -> Self {
|
||||
if let AppType::$b(t) = t {
|
||||
t
|
||||
} else {
|
||||
panic!("AppType is not {}", stringify!($b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'gl> From<&'a mut AppType<'gl>> for &'a mut $t {
|
||||
fn from(t: &'a mut AppType<'gl>) -> Self {
|
||||
if let AppType::$b(t) = t {
|
||||
t
|
||||
} else {
|
||||
panic!("AppType is not {}", stringify!($b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
pub enum AppType<'gl> {
|
||||
MainLoad(MainLoadTyp<'gl>),
|
||||
Other,
|
||||
}
|
||||
|
||||
app_type_into!({
|
||||
MainLoadTyp<'gl> => MainLoad
|
||||
},);
|
||||
|
||||
impl<'gl> AppType<'gl> {
|
||||
pub fn draw_program<'b>(&mut self, mut context: &mut Context<'gl>) -> Result<()>
|
||||
where
|
||||
'gl: 'b,
|
||||
{
|
||||
let programs = &mut context.programs;
|
||||
let gl = programs.gl;
|
||||
match self {
|
||||
Self::MainLoad(typ) => {
|
||||
programs.draw(typ)?;
|
||||
}
|
||||
Self::Other => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn deal_with_cursor(&mut self, package: ModulePackage<'gl>) {
|
||||
match self {
|
||||
Self::MainLoad(typ) => {
|
||||
typ.deal_with_cursor(package);
|
||||
}
|
||||
Self::Other => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_layout!(
|
||||
{MainLoad => MainLoadAttach<'gl>},
|
||||
);
|
||||
@ -1,17 +1,23 @@
|
||||
mod app;
|
||||
pub mod app_type;
|
||||
use glow::HasContext;
|
||||
pub mod layout_type;
|
||||
mod modules;
|
||||
|
||||
use crate::font_manager::FontManager;
|
||||
use crate::graphics::font::Text;
|
||||
use crate::graphics::ppi::PPI;
|
||||
use crate::graphics::threed::ThreeD;
|
||||
use crate::ui::typ::LayoutAppType;
|
||||
use crate::graphics::threed::Trackball;
|
||||
use crate::graphics::{AttaWithProgram, AttachWithMouse};
|
||||
use crate::ui::operation::Operation;
|
||||
use crate::ui::typ::LayoutAttach;
|
||||
use crate::utils::cache::CachedData;
|
||||
use crate::utils::resources::GL;
|
||||
use crate::{errors::*, graphics::Graphics};
|
||||
pub use app::{App, Context};
|
||||
pub use modules::{Module, ModuleCursor, ModuleData, PPIModule, PPIPackage};
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
|
||||
static MODULE_PACKAGE_ID: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
pub(super) struct Programs<'gl> {
|
||||
gl: &'gl GL,
|
||||
@ -69,26 +75,18 @@ impl<'gl> Programs<'gl> {
|
||||
pub fn draw_modules(
|
||||
&mut self,
|
||||
modules: &mut ModulePackage<'gl>,
|
||||
init_info: &ThreeD,
|
||||
operation: &Operation<Trackball>,
|
||||
) -> Result<()> {
|
||||
// if !modules.need_update {
|
||||
// return Ok(());
|
||||
// }
|
||||
match &mut modules.modules {
|
||||
_ModulePackage::PPI(ppi) => {
|
||||
self.ppi().start();
|
||||
self.ppi().init(init_info);
|
||||
self.ppi().render(ppi)?;
|
||||
self.ppi().render(ppi, operation)?;
|
||||
self.ppi().end();
|
||||
}
|
||||
}
|
||||
modules.need_update = false;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn draw<M: LayoutAppType<'gl>>(&mut self, ty: &mut M) -> Result<()> {
|
||||
ty.draw_program(self.gl, self)
|
||||
}
|
||||
}
|
||||
|
||||
pub enum Data<'a> {
|
||||
@ -119,8 +117,6 @@ macro_rules! impl_module_package {
|
||||
_ModulePackage::$b(t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
)+
|
||||
};
|
||||
}
|
||||
@ -130,7 +126,8 @@ impl_module_data!({
|
||||
});
|
||||
|
||||
pub struct ModulePackage<'gl> {
|
||||
need_update: bool,
|
||||
id: usize,
|
||||
pub need_update: bool,
|
||||
modules: _ModulePackage<'gl>,
|
||||
}
|
||||
|
||||
@ -148,19 +145,27 @@ where
|
||||
{
|
||||
fn from(t: T) -> Self {
|
||||
Self {
|
||||
id: MODULE_PACKAGE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
|
||||
modules: t.into(),
|
||||
need_update: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ModulePackage<'_> {
|
||||
pub fn ui_build(&mut self, ui: &imgui::Ui) -> Result<()> {
|
||||
match &mut self.modules {
|
||||
_ModulePackage::PPI(ppi) => {
|
||||
ppi.ui_build(ui);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
impl PartialEq for ModulePackage<'_> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.id == other.id
|
||||
}
|
||||
}
|
||||
|
||||
impl ModulePackage<'_> {
|
||||
pub fn ui_build(&mut self, ui: &imgui::Ui) -> Result<bool> {
|
||||
Ok(match &mut self.modules {
|
||||
_ModulePackage::PPI(ppi) => ppi.ui_build(ui),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dirty(&mut self) {
|
||||
self.need_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,13 @@
|
||||
use crate::utils::{
|
||||
use crate::{
|
||||
graphics::AttachWithMouse,
|
||||
ui::{
|
||||
operation::{self, Operation},
|
||||
typ::CameraOP,
|
||||
},
|
||||
utils::{
|
||||
cache::CachedData,
|
||||
resources::{ManagedResource, RcGlBuffer, RcGlVertexArray},
|
||||
},
|
||||
};
|
||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||
mod ppi;
|
||||
@ -63,14 +70,18 @@ impl<'a> Attach<'a> {
|
||||
pub trait Module: Sized {
|
||||
type Cursor: ModuleCursor;
|
||||
type Data;
|
||||
type InitInfo;
|
||||
type Operation: AttachWithMouse;
|
||||
|
||||
fn render(&mut self, cursor: &mut Self::Cursor) -> Result<()>;
|
||||
fn render(
|
||||
&mut self,
|
||||
cursor: &mut Self::Cursor,
|
||||
operation: &Operation<Self::Operation>,
|
||||
) -> Result<()>;
|
||||
fn resize(&self, size: [f32; 2]);
|
||||
fn destroy(&self);
|
||||
|
||||
fn start(&mut self);
|
||||
fn init(&mut self, info: &Self::InitInfo) -> Result<()>;
|
||||
// fn init(&mut self, info: &Operation<Self::Operation>) -> Result<()>;
|
||||
fn end(&mut self);
|
||||
fn load_data<'dt>(&self, data: &CachedData<Self::Data>) -> Result<Self::Cursor>;
|
||||
}
|
||||
@ -88,5 +99,5 @@ pub trait ModuleCursor {
|
||||
where
|
||||
F: FnOnce(&mut Self::Config);
|
||||
|
||||
fn ui_build(&mut self, ui: &imgui::Ui);
|
||||
fn ui_build(&mut self, ui: &imgui::Ui) -> bool;
|
||||
}
|
||||
|
||||
@ -1,6 +1,9 @@
|
||||
use std::rc::Rc;
|
||||
use tracker::track;
|
||||
|
||||
use crate::graphics::{font::Text, *};
|
||||
use crate::ui::operation::{self, Operation};
|
||||
use crate::SETTING;
|
||||
use crate::{
|
||||
data_loader::Data,
|
||||
errors::*,
|
||||
@ -10,9 +13,7 @@ use crate::{
|
||||
};
|
||||
use imgui::VerticalSlider;
|
||||
use ppi::{PPIConfig, PPI};
|
||||
use threed::ThreeD;
|
||||
|
||||
use crate::graphics::{font::Text, *};
|
||||
use threed::Trackball;
|
||||
|
||||
use super::{Attach, Module, ModuleCursor};
|
||||
pub struct PPIModule<'b, 'a: 'b> {
|
||||
@ -35,9 +36,13 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
let (vbo, ebo, len) = self.ppi_program.bake(
|
||||
data,
|
||||
&PPIConfig {
|
||||
unvalid_value: config.unvalid_value,
|
||||
color_range: config.color_range,
|
||||
colors: config.colors.clone(),
|
||||
layer: config.layer,
|
||||
rdpi: config.rdpi,
|
||||
adpi: config.adpi,
|
||||
three_d: config.is_three_d,
|
||||
},
|
||||
)?;
|
||||
attach.bind_data(&vbo, ebo.as_ref(), len);
|
||||
@ -48,7 +53,7 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||
impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
type Cursor = PPIPackage<'a>;
|
||||
type Data = Data;
|
||||
type InitInfo = ThreeD;
|
||||
type Operation = Trackball;
|
||||
|
||||
fn start(&mut self) {
|
||||
self.ppi_program.mount(&self.gl).unwrap();
|
||||
@ -58,16 +63,26 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
self.ppi_program.unmount(&self.gl).unwrap();
|
||||
}
|
||||
|
||||
fn render<'dt>(&mut self, cursor: &mut Self::Cursor) -> Result<()> {
|
||||
fn render<'dt>(
|
||||
&mut self,
|
||||
cursor: &mut Self::Cursor,
|
||||
operation: &Operation<Self::Operation>,
|
||||
) -> Result<()> {
|
||||
operation.attach_with_program(&self.gl, self.ppi_program.program());
|
||||
let attach = &mut cursor.ppi_attach;
|
||||
let data = &cursor.ppi_data.borrow();
|
||||
let config = &mut cursor.ppi_config;
|
||||
|
||||
self.ppi_program.set_config(
|
||||
&self.gl,
|
||||
&PPIConfig {
|
||||
unvalid_value: config.unvalid_value,
|
||||
color_range: config.color_range,
|
||||
colors: config.colors.clone(),
|
||||
layer: config.layer,
|
||||
rdpi: config.rdpi,
|
||||
adpi: config.adpi,
|
||||
three_d: config.is_three_d,
|
||||
},
|
||||
)?;
|
||||
|
||||
@ -92,11 +107,25 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
}
|
||||
let (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
|
||||
let mut attach = Attach::new(&self.gl, vao, vbo, ebo, None);
|
||||
let (r, a, t) = self.ppi_program.data_info(&_data)?;
|
||||
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&_data)?;
|
||||
|
||||
let cmap = SETTING.find(&t);
|
||||
|
||||
if cmap.is_none() {
|
||||
return Err(Error::InvalidDataType);
|
||||
}
|
||||
|
||||
let cmap = cmap.unwrap();
|
||||
|
||||
let config = PPIModuleConfig {
|
||||
color_range: cmap.value_range(),
|
||||
colors: cmap.color()?,
|
||||
layer: 0,
|
||||
rdpi: r,
|
||||
adpi: a,
|
||||
max_layer,
|
||||
unvalid_value: unvalid,
|
||||
is_three_d: true,
|
||||
tracker: 0,
|
||||
};
|
||||
|
||||
@ -104,16 +133,19 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||
|
||||
Ok(PPIPackage::new(config, attach, data))
|
||||
}
|
||||
|
||||
fn init(&mut self, info: &Self::InitInfo) -> Result<()> {
|
||||
info.attach_with_program(&self.gl, &self.ppi_program.program());
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[track]
|
||||
#[derive(PartialEq)]
|
||||
pub struct PPIModuleConfig {
|
||||
pub layer: usize,
|
||||
pub colors: Vec<[u8; 4]>,
|
||||
pub color_range: [f32; 2],
|
||||
pub is_three_d: bool,
|
||||
#[do_not_track]
|
||||
pub unvalid_value: f32,
|
||||
#[do_not_track]
|
||||
pub max_layer: usize,
|
||||
#[do_not_track]
|
||||
pub rdpi: f32,
|
||||
#[do_not_track]
|
||||
@ -148,12 +180,17 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> {
|
||||
f(&mut self.ppi_config);
|
||||
}
|
||||
|
||||
fn ui_build(&mut self, ui: &imgui::Ui) {
|
||||
fn ui_build(&mut self, ui: &imgui::Ui) -> bool {
|
||||
let mut layer = self.ppi_config.layer;
|
||||
let mut is_three_d = self.ppi_config.is_three_d;
|
||||
|
||||
ui.text("PPI Data Config");
|
||||
ui.slider("Layer", 0, 10, &mut layer);
|
||||
ui.slider("Layer", 0, self.ppi_config.max_layer - 1, &mut layer);
|
||||
ui.checkbox("three d?", &mut is_three_d);
|
||||
ui.separator();
|
||||
|
||||
self.ppi_config.set_layer(layer);
|
||||
self.ppi_config.set_is_three_d(is_three_d);
|
||||
self.ppi_config.changed_any()
|
||||
}
|
||||
}
|
||||
|
||||
101
src/setting.rs
Normal file
101
src/setting.rs
Normal file
@ -0,0 +1,101 @@
|
||||
use crate::errors::*;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs::{read, read_to_string};
|
||||
|
||||
use crate::{data_loader::DataType, utils::color_tools::hex_to_rgba_u8};
|
||||
|
||||
macro_rules! find_cmap {
|
||||
($c:ident,$find_on:ident,$({$b:tt => $name:literal}),*) => {
|
||||
|
||||
{
|
||||
let mut cmap = None;
|
||||
match $c {
|
||||
$(
|
||||
$b => {
|
||||
let find_v = $find_on.iter().find(|cb| cb.type_name == $name).map(|cb| cb);
|
||||
cmap = find_v;
|
||||
}
|
||||
)*
|
||||
_ => {}
|
||||
}
|
||||
cmap
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct Setting {
|
||||
pub cmap: Vec<CB>,
|
||||
}
|
||||
|
||||
impl Setting {
|
||||
pub fn find(&self, name: &DataType) -> Option<&CB> {
|
||||
let cmap = &self.cmap;
|
||||
use DataType::*;
|
||||
find_cmap!(
|
||||
name, cmap,
|
||||
{DBZ => "DBZ"},
|
||||
{VEl => "VEL"},
|
||||
{VIL => "VIL"}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl Setting {
|
||||
pub fn new() -> Self {
|
||||
let file = read_to_string("./radar.toml").unwrap();
|
||||
let setting: Setting = toml::from_str(&file).unwrap();
|
||||
setting
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct CB {
|
||||
#[serde(rename = "type")]
|
||||
pub type_name: String,
|
||||
pub colors: Vec<String>,
|
||||
pub levels: Vec<f32>,
|
||||
}
|
||||
|
||||
impl CB {
|
||||
pub fn value_range(&self) -> [f32; 2] {
|
||||
let mut range = [0.0, 0.0];
|
||||
let levels = &self.levels;
|
||||
range[0] = levels[0];
|
||||
range[1] = levels[levels.len() - 1];
|
||||
range
|
||||
}
|
||||
|
||||
pub fn color(&self) -> Result<Vec<[u8; 4]>> {
|
||||
if self.colors.len() != self.levels.len() - 1 {
|
||||
return Err(Error::SettingError("Color and level mismatch".to_string()));
|
||||
}
|
||||
|
||||
let mut result = self
|
||||
.colors
|
||||
.iter()
|
||||
.map(|v| hex_to_rgba_u8(v))
|
||||
.collect::<std::result::Result<Vec<_>, String>>()
|
||||
.map_err(|v| Error::SettingError(v.to_string()))?;
|
||||
|
||||
let mut span = Vec::with_capacity(self.levels.len() - 1);
|
||||
|
||||
for idx in 0..self.levels.len() - 1 {
|
||||
let start = self.levels[idx];
|
||||
let end = self.levels[idx + 1];
|
||||
let range = end - start;
|
||||
span.push(range);
|
||||
}
|
||||
|
||||
let range = self.value_range();
|
||||
let all_range = range[1] - range[0];
|
||||
|
||||
for (level, r) in span.iter().zip(result.iter_mut()) {
|
||||
r[3] = ((*level / all_range) * 255.0) as u8;
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
50
src/shaders/colormap.rs
Normal file
50
src/shaders/colormap.rs
Normal file
@ -0,0 +1,50 @@
|
||||
use super::CodePiece;
|
||||
use crate::impl_code_piece;
|
||||
use glsl::syntax::ShaderStage;
|
||||
use glsl::syntax::TranslationUnit;
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
use glsl_quasiquote::glsl;
|
||||
|
||||
pub struct ColorMap(pub ShaderStage);
|
||||
|
||||
impl ColorMap {
|
||||
pub fn new() -> Self {
|
||||
let raw = glsl! {
|
||||
uniform sampler1D colormap;
|
||||
uniform vec4 colormap_conf;
|
||||
|
||||
float find_idx(float ratio) {
|
||||
float i = 0;
|
||||
float count = colormap_conf.z - 1.0;
|
||||
float sum = 0.0;
|
||||
|
||||
while (ratio > sum) {
|
||||
sum += texture(colormap, float(i++) / count).w;
|
||||
}
|
||||
return i / count;
|
||||
}
|
||||
|
||||
vec4 linear_colormap(float value)
|
||||
{
|
||||
float vmin = colormap_conf.x;
|
||||
float vmax = colormap_conf.y;
|
||||
float count = colormap_conf.z - 1.0;
|
||||
|
||||
float invalid = colormap_conf.w;
|
||||
|
||||
if (value == invalid) {
|
||||
return vec4(0.0, 0.0, 0.0, 0.0);
|
||||
}
|
||||
|
||||
float v = clamp((value - vmin), vmin, vmax) / (vmax - vmin);
|
||||
float idx = find_idx(v);
|
||||
vec4 result = texture(colormap, idx);
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
Self(raw)
|
||||
}
|
||||
}
|
||||
|
||||
impl_code_piece!(ColorMap, 0);
|
||||
73
src/shaders/math.rs
Normal file
73
src/shaders/math.rs
Normal file
@ -0,0 +1,73 @@
|
||||
use glsl::syntax::ShaderStage;
|
||||
use glsl_quasiquote::glsl;
|
||||
|
||||
use super::CodePiece;
|
||||
use glsl::syntax::TranslationUnit;
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
|
||||
use crate::impl_code_piece;
|
||||
|
||||
pub struct Constants {
|
||||
pub raw: ShaderStage,
|
||||
}
|
||||
|
||||
impl Constants {
|
||||
pub fn new() -> Constants {
|
||||
let raw = glsl! {
|
||||
|
||||
#ifndef _GLUMPY__CONSTANTS__
|
||||
#define _GLUMPY__CONSTANTS__
|
||||
|
||||
// The base of natural logarithms (e)
|
||||
const float M_E = 2.71828182845904523536028747135266250;
|
||||
|
||||
// The logarithm to base 2 of M_E (log2(e))
|
||||
const float M_LOG2E = 1.44269504088896340735992468100189214;
|
||||
|
||||
// The logarithm to base 10 of M_E (log10(e))
|
||||
const float M_LOG10E = 0.434294481903251827651128918916605082;
|
||||
|
||||
// The natural logarithm of 2 (loge(2))
|
||||
const float M_LN2 = 0.693147180559945309417232121458176568;
|
||||
|
||||
// The natural logarithm of 10 (loge(10))
|
||||
const float M_LN10 = 2.30258509299404568401799145468436421;
|
||||
|
||||
// Pi, the ratio of a circle's circumference to its diameter.
|
||||
const float M_PI = 3.14159265358979323846264338327950288;
|
||||
|
||||
// Pi divided by two (pi/2)
|
||||
const float M_PI_2 = 1.57079632679489661923132169163975144;
|
||||
|
||||
// Pi divided by four (pi/4)
|
||||
const float M_PI_4 = 0.785398163397448309615660845819875721;
|
||||
|
||||
// The reciprocal of pi (1/pi)
|
||||
const float M_1_PI = 0.318309886183790671537767526745028724;
|
||||
|
||||
// Two times the reciprocal of pi (2/pi)
|
||||
const float M_2_PI = 0.636619772367581343075535053490057448;
|
||||
|
||||
// Two times the reciprocal of the square root of pi (2/sqrt(pi))
|
||||
const float M_2_SQRTPI = 1.12837916709551257389615890312154517;
|
||||
|
||||
// The square root of two (sqrt(2))
|
||||
const float M_SQRT2 = 1.41421356237309504880168872420969808;
|
||||
|
||||
// The reciprocal of the square root of two (1/sqrt(2))
|
||||
const float M_SQRT1_2 = 0.707106781186547524400844362104849039;
|
||||
|
||||
// 1 degree in radians
|
||||
const float degree = 180.0/M_PI;
|
||||
|
||||
// 1 radian in degrees
|
||||
const float radian = M_PI/180.0;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
Constants { raw }
|
||||
}
|
||||
}
|
||||
|
||||
impl_code_piece!(Constants, raw);
|
||||
97
src/shaders/mod.rs
Normal file
97
src/shaders/mod.rs
Normal file
@ -0,0 +1,97 @@
|
||||
pub mod colormap;
|
||||
pub mod math;
|
||||
pub mod polar;
|
||||
pub mod ppi;
|
||||
pub mod trackball;
|
||||
use glsl::{
|
||||
syntax::{ShaderStage, TranslationUnit},
|
||||
transpiler::glsl::{show_struct, show_translation_unit},
|
||||
};
|
||||
use glsl_quasiquote::glsl;
|
||||
|
||||
use crate::components::Shader;
|
||||
|
||||
struct PPI {
|
||||
vertex: ShaderStage,
|
||||
}
|
||||
|
||||
impl PPI {
|
||||
fn new() -> Self {
|
||||
let vertex: ShaderStage = glsl! {
|
||||
layout(location = 0) in vec3 position;
|
||||
out float in_value;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position.x, position.y, 0.5, 1.0);
|
||||
in_value = position.z;
|
||||
}
|
||||
};
|
||||
|
||||
Self { vertex }
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for PPI {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
show_translation_unit(f, &self.vertex);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(std::fmt::Debug)]
|
||||
pub struct EmptyPiece(pub TranslationUnit);
|
||||
|
||||
pub trait CodePiece: std::fmt::Display {
|
||||
fn raw(&self) -> &TranslationUnit;
|
||||
|
||||
fn include<T: CodePiece>(i: T, raw: TranslationUnit) -> TranslationUnit {
|
||||
let mut s = i.raw().clone();
|
||||
s.extend(raw);
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl CodePiece for EmptyPiece {
|
||||
fn raw(&self) -> &TranslationUnit {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for EmptyPiece {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! impl_code_piece {
|
||||
($t:ty, $c:tt) => {
|
||||
impl CodePiece for $t {
|
||||
fn raw(&self) -> &TranslationUnit {
|
||||
&self.$c
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for $t {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
show_translation_unit(f, &self.$c);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
mod test {
|
||||
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
|
||||
use super::math::Constants;
|
||||
use super::polar::PolarTransform;
|
||||
use super::PPI;
|
||||
|
||||
#[test]
|
||||
fn test() {
|
||||
let polar = PolarTransform::new();
|
||||
println!("{}", polar);
|
||||
}
|
||||
}
|
||||
58
src/shaders/polar.rs
Normal file
58
src/shaders/polar.rs
Normal file
@ -0,0 +1,58 @@
|
||||
use super::CodePiece;
|
||||
use crate::impl_code_piece;
|
||||
use glsl::syntax::ShaderStage;
|
||||
use glsl::syntax::TranslationUnit;
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
|
||||
use super::math::Constants;
|
||||
use glsl_quasiquote::glsl;
|
||||
|
||||
pub struct PolarTransform {
|
||||
pub raw: ShaderStage,
|
||||
}
|
||||
|
||||
impl PolarTransform {
|
||||
pub fn new() -> PolarTransform {
|
||||
let raw = glsl! {
|
||||
|
||||
uniform float polar_origin;
|
||||
|
||||
vec4 forward(float rho, float theta, float z, float w)
|
||||
{
|
||||
return vec4(rho * cos(theta + polar_origin),
|
||||
rho * sin(theta + polar_origin),
|
||||
rho * sin(z), w);
|
||||
}
|
||||
|
||||
vec4 forward(float x, float y) {return forward(x, y, 0.0, 1.0);}
|
||||
vec4 forward(float x, float y, float z) {return forward(x, y, z, 1.0);}
|
||||
vec4 forward(vec2 P) { return forward(P.x, P.y); }
|
||||
vec4 forward(vec3 P) { return forward(P.x, P.y, P.z, 1.0); }
|
||||
vec4 forward(vec4 P) { return forward(P.x, P.y, P.z, P.w); }
|
||||
|
||||
vec4 inverse(float x, float y, float z, float w)
|
||||
{
|
||||
float rho = length(vec2(x,y));
|
||||
float theta = atan(y,x);
|
||||
if( theta < 0.0 )
|
||||
theta = 2.0*M_PI+theta;
|
||||
return vec4(rho, theta-polar_origin, z, w);
|
||||
}
|
||||
|
||||
|
||||
vec4 inverse(float x, float y) {return inverse(x,y,0.0,1.0); }
|
||||
vec4 inverse(float x, float y, float z) {return inverse(x,y,z,1.0); }
|
||||
vec4 inverse(vec2 P) { return inverse(P.x, P.y, 0.0, 1.0); }
|
||||
vec4 inverse(vec3 P) { return inverse(P.x, P.y, P.z, 1.0); }
|
||||
vec4 inverse(vec4 P) { return inverse(P.x, P.y, P.z, P.w); }
|
||||
};
|
||||
|
||||
let mut constant = Constants::new().raw;
|
||||
|
||||
constant.extend(raw);
|
||||
|
||||
PolarTransform { raw: constant }
|
||||
}
|
||||
}
|
||||
|
||||
impl_code_piece!(PolarTransform, raw);
|
||||
147
src/shaders/ppi.rs
Normal file
147
src/shaders/ppi.rs
Normal file
@ -0,0 +1,147 @@
|
||||
use super::trackball::Trackball;
|
||||
use super::CodePiece;
|
||||
use crate::impl_code_piece;
|
||||
use glsl::syntax::ShaderStage;
|
||||
use glsl::syntax::TranslationUnit;
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
use glsl_quasiquote::glsl;
|
||||
|
||||
pub struct PPIVertex(pub ShaderStage);
|
||||
pub struct PPIGeom(pub ShaderStage);
|
||||
pub struct PPIFragment(pub ShaderStage);
|
||||
|
||||
impl PPIVertex {
|
||||
pub fn new() -> Self {
|
||||
let raw = glsl! {
|
||||
layout(location = 0) in vec4 position;
|
||||
out float in_value;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(position.x * 10.0, position.y, position.z, 1.0);
|
||||
in_value = position.w;
|
||||
}
|
||||
};
|
||||
|
||||
Self(raw)
|
||||
}
|
||||
}
|
||||
|
||||
impl PPIGeom {
|
||||
pub fn new() -> Self {
|
||||
let mut trackball = Trackball::new().0;
|
||||
let polar = super::polar::PolarTransform::new().raw;
|
||||
let raw = glsl! {
|
||||
layout(points) in;
|
||||
layout(triangle_strip, max_vertices = 4) out;
|
||||
|
||||
// conf: Range, Elevation, Resolution, mode
|
||||
uniform vec4 conf;
|
||||
in float in_value[];
|
||||
|
||||
out float x;
|
||||
out float y;
|
||||
out float value;
|
||||
|
||||
flat out vec4 vrange;
|
||||
|
||||
|
||||
void main() {
|
||||
float rdpi = conf.x * 10.0;
|
||||
float mode = conf.w;
|
||||
vec4 reso = vec4(rdpi/2.0, conf.y/2.0 * radian, 0.0, 0.0);
|
||||
vec4 loc;
|
||||
float c = cos(reso.y);
|
||||
|
||||
vec4 po = gl_in[0].gl_Position;
|
||||
po.y *= radian;
|
||||
po.z *= radian * mode;
|
||||
|
||||
vrange = vec4(po.x - reso.x, po.y - reso.y, po.x + reso.x, po.y + reso.y);
|
||||
value = in_value[0];
|
||||
|
||||
gl_Position = po - reso;
|
||||
loc = forward(gl_Position);
|
||||
x = loc.x;
|
||||
y = loc.y;
|
||||
gl_Position = transform(loc);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = po + vec4(reso.x, -reso.y, 0.0, 0.0);
|
||||
gl_Position.x = gl_Position.x / c;
|
||||
loc = forward(gl_Position);
|
||||
x = loc.x;
|
||||
y = loc.y;
|
||||
gl_Position = transform(loc);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = po + vec4(-reso.x, reso.y, 0.0, 0.0);
|
||||
loc = forward(gl_Position);
|
||||
x = loc.x;
|
||||
y = loc.y;
|
||||
gl_Position = transform(loc);
|
||||
EmitVertex();
|
||||
|
||||
gl_Position = po + reso;
|
||||
gl_Position.x = gl_Position.x / c;
|
||||
loc = forward(gl_Position);
|
||||
x = loc.x;
|
||||
y = loc.y;
|
||||
gl_Position = transform(loc);
|
||||
EmitVertex();
|
||||
|
||||
EndPrimitive();
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
trackball.extend(polar);
|
||||
trackball.extend(raw);
|
||||
|
||||
Self(trackball)
|
||||
}
|
||||
}
|
||||
|
||||
impl PPIFragment {
|
||||
pub fn new() -> Self {
|
||||
use super::polar::PolarTransform;
|
||||
let mut include = PolarTransform::new().raw;
|
||||
let mut colormap = super::colormap::ColorMap::new().0;
|
||||
let raw = glsl! {
|
||||
in float x;
|
||||
in float y;
|
||||
|
||||
in float value;
|
||||
flat in vec4 vrange;
|
||||
|
||||
out vec4 FragColor;
|
||||
|
||||
void main() {
|
||||
|
||||
vec4 inversed = inverse(x, y);
|
||||
|
||||
|
||||
if (inversed.x < vrange.x || inversed.x > vrange.z) {
|
||||
discard;
|
||||
}
|
||||
|
||||
vec4 result = linear_colormap(value);
|
||||
|
||||
if (result.w == 0.0) {
|
||||
discard;
|
||||
}
|
||||
|
||||
FragColor = result;
|
||||
}
|
||||
};
|
||||
|
||||
include.extend(colormap);
|
||||
include.extend(raw);
|
||||
|
||||
Self(include)
|
||||
}
|
||||
}
|
||||
|
||||
impl_code_piece!(PPIVertex, 0);
|
||||
impl_code_piece!(PPIGeom, 0);
|
||||
impl_code_piece!(PPIFragment, 0);
|
||||
30
src/shaders/trackball.rs
Normal file
30
src/shaders/trackball.rs
Normal file
@ -0,0 +1,30 @@
|
||||
use super::CodePiece;
|
||||
use glsl::syntax::ShaderStage;
|
||||
use glsl::syntax::TranslationUnit;
|
||||
use glsl::transpiler::glsl::show_translation_unit;
|
||||
|
||||
use crate::impl_code_piece;
|
||||
|
||||
pub struct Trackball(pub ShaderStage);
|
||||
|
||||
impl Trackball {
|
||||
pub fn new() -> Self {
|
||||
let raw = glsl_quasiquote::glsl! {
|
||||
uniform mat4 trackball_view;
|
||||
uniform mat4 trackball_model;
|
||||
uniform mat4 trackball_projection;
|
||||
|
||||
vec4 transform(vec4 position)
|
||||
{
|
||||
return trackball_projection
|
||||
* trackball_view
|
||||
* trackball_model
|
||||
* position;
|
||||
}
|
||||
};
|
||||
|
||||
Self(raw)
|
||||
}
|
||||
}
|
||||
|
||||
impl_code_piece!(Trackball, 0);
|
||||
@ -1,4 +1,4 @@
|
||||
use crate::{pg::App, utils::resources::GL};
|
||||
use crate::{graphics::font, pg::App, utils::resources::GL};
|
||||
|
||||
use glow::HasContext;
|
||||
use glutin::{
|
||||
@ -7,6 +7,7 @@ use glutin::{
|
||||
display::{GetGlDisplay, GlDisplay},
|
||||
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
|
||||
};
|
||||
use imgui::FontConfig;
|
||||
use imgui_winit_support::{
|
||||
winit::{
|
||||
dpi::LogicalSize,
|
||||
@ -202,9 +203,14 @@ fn imgui_init(window: &Window) -> (WinitPlatform, imgui::Context) {
|
||||
winit_platform.attach_window(imgui_context.io_mut(), &window, dpi_mode);
|
||||
}
|
||||
|
||||
let mut font_conf = FontConfig::default();
|
||||
font_conf.size_pixels = 16.0;
|
||||
|
||||
imgui_context
|
||||
.fonts()
|
||||
.add_font(&[imgui::FontSource::DefaultFontData { config: None }]);
|
||||
.add_font(&[imgui::FontSource::DefaultFontData {
|
||||
config: Some(font_conf),
|
||||
}]);
|
||||
|
||||
println!("imgui global scale: {}", winit_platform.hidpi_factor());
|
||||
|
||||
|
||||
11
src/ui/io.rs
11
src/ui/io.rs
@ -23,14 +23,21 @@ impl IO {
|
||||
let io = ui.io();
|
||||
|
||||
let delta = if ui.is_mouse_dragging(imgui::MouseButton::Left) {
|
||||
Some(ui.mouse_drag_delta_with_button(imgui::MouseButton::Left))
|
||||
let delta = ui.mouse_drag_delta_with_threshold(imgui::MouseButton::Left, 5.0);
|
||||
ui.reset_mouse_drag_delta(imgui::MouseButton::Left);
|
||||
Some(delta)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
let windows_position = ui.window_pos();
|
||||
|
||||
IO {
|
||||
mouse: MouseIO {
|
||||
position: io.mouse_pos,
|
||||
position: [
|
||||
io.mouse_pos[0] - windows_position[0],
|
||||
io.mouse_pos[1] - windows_position[1],
|
||||
],
|
||||
drag_delta: delta,
|
||||
is_dragging: ui.is_mouse_dragging(imgui::MouseButton::Left),
|
||||
left_button_pressed: io.mouse_down[0],
|
||||
|
||||
@ -4,7 +4,7 @@ use log::*;
|
||||
|
||||
use crate::data_loader::Data;
|
||||
use crate::errors::*;
|
||||
use crate::pg::app_type::AppType;
|
||||
use crate::pg::layout_type::Layout;
|
||||
use crate::pg::{ModulePackage, Programs};
|
||||
use crate::utils::cache::Cache;
|
||||
use crate::utils::resources::{RcGlRcFramebuffer, RcGlRcRenderbuffer, RcGlRcResource, GL};
|
||||
@ -18,10 +18,11 @@ mod state;
|
||||
pub mod typ;
|
||||
pub use layout::*;
|
||||
pub use state::State;
|
||||
pub mod operation;
|
||||
|
||||
pub struct GUI {
|
||||
state: State,
|
||||
layout: layout::Layout,
|
||||
layout_manager: layout::Layout,
|
||||
renderer_size: [f32; 2],
|
||||
}
|
||||
|
||||
@ -29,12 +30,12 @@ impl GUI {
|
||||
pub fn new(state: State) -> Self {
|
||||
GUI {
|
||||
state,
|
||||
layout: layout::Layout::new(),
|
||||
layout_manager: layout::Layout::new(),
|
||||
renderer_size: [0.0, 0.0],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apptype<'a, 'gl>(&'a mut self, gl: &'gl GL) -> AppType<'gl> {
|
||||
pub fn layout<'a, 'gl>(&'a mut self, gl: &'gl GL) -> Layout<'gl> {
|
||||
self.state.app_type.init_apptype(gl)
|
||||
}
|
||||
|
||||
@ -42,22 +43,22 @@ impl GUI {
|
||||
&mut self,
|
||||
ui: &Ui,
|
||||
context: &'b mut crate::pg::Context<'gl>,
|
||||
app_type: &'b mut AppType<'gl>,
|
||||
layout_atta: &'b mut Layout<'gl>,
|
||||
) -> bool {
|
||||
// Menu bar
|
||||
self.menu_bar(ui, context, app_type);
|
||||
self.menu_bar(ui, context, layout_atta);
|
||||
let menu_bar_height = ui.frame_height();
|
||||
let display_size = ui.io().display_size;
|
||||
|
||||
// Layout Size Reset
|
||||
self.layout.set_origin([0.0, menu_bar_height]);
|
||||
self.layout
|
||||
self.layout_manager.set_origin([0.0, menu_bar_height]);
|
||||
self.layout_manager
|
||||
.set_size([display_size[0], display_size[1] - menu_bar_height]);
|
||||
|
||||
// Render
|
||||
self.state
|
||||
.app_type
|
||||
.render(ui, context, &mut self.layout, app_type);
|
||||
.render(ui, context, &mut self.layout_manager, layout_atta);
|
||||
|
||||
true
|
||||
}
|
||||
@ -66,7 +67,7 @@ impl GUI {
|
||||
&self,
|
||||
ui: &Ui,
|
||||
context: &'b mut crate::pg::Context<'gl>,
|
||||
app_type: &mut AppType<'gl>,
|
||||
layout_atta: &mut Layout<'gl>,
|
||||
) {
|
||||
if let Some(top_menu) = ui.begin_main_menu_bar() {
|
||||
if let Some(menu) = ui.begin_menu("File") {
|
||||
@ -75,7 +76,7 @@ impl GUI {
|
||||
Some(file) => match context.load_data(file.clone()) {
|
||||
Ok(data) => {
|
||||
info!("Data loaded: {:?}", file);
|
||||
app_type.deal_with_cursor(data);
|
||||
layout_atta.append_package(data);
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to get or insert data: {:?}", e);
|
||||
|
||||
124
src/ui/operation.rs
Normal file
124
src/ui/operation.rs
Normal file
@ -0,0 +1,124 @@
|
||||
use super::typ::CameraOP;
|
||||
use crate::{
|
||||
camera::Camera,
|
||||
components::Program,
|
||||
graphics::{AttaWithProgram, AttachWithMouse},
|
||||
};
|
||||
|
||||
pub struct Operation<T: AttachWithMouse> {
|
||||
camera: Camera,
|
||||
projection: Projection,
|
||||
operation: T,
|
||||
need_update: bool,
|
||||
}
|
||||
|
||||
impl<T: AttachWithMouse + 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 {
|
||||
projection,
|
||||
camera: operation.init_camera(),
|
||||
operation,
|
||||
need_update: true,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deal_io(&mut self, io: &super::io::IO) {
|
||||
self.need_update = self.operation.attach_with_mouse(
|
||||
&T::State::from_context(io),
|
||||
&mut self.camera,
|
||||
&mut self.projection,
|
||||
);
|
||||
}
|
||||
|
||||
pub fn set_camera(&mut self, f: impl Fn(&mut Camera)) {
|
||||
f(&mut self.camera);
|
||||
self.need_update = true;
|
||||
}
|
||||
|
||||
pub fn set_projection(&mut self, f: impl Fn(&mut Projection)) {
|
||||
f(&mut self.projection);
|
||||
self.need_update = true;
|
||||
}
|
||||
|
||||
pub fn attach_with_program(&self, gl: &glow::Context, program: &mut Program) {
|
||||
use glow::HasContext;
|
||||
unsafe {
|
||||
let projection = program.get_uniform_location(gl, "trackball_projection");
|
||||
gl.uniform_matrix_4_f32_slice(projection.as_ref(), false, self.projection.as_slice());
|
||||
let view = program.get_uniform_location(gl, "trackball_view");
|
||||
gl.uniform_matrix_4_f32_slice(
|
||||
view.as_ref(),
|
||||
false,
|
||||
self.camera.get_view_matrix().as_slice(),
|
||||
);
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.operation.reset();
|
||||
self.need_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Projection {
|
||||
fov: f32,
|
||||
z_near: f32,
|
||||
z_far: f32,
|
||||
aspect: f32,
|
||||
projection: nalgebra_glm::Mat4,
|
||||
}
|
||||
|
||||
impl Projection {
|
||||
fn new(aspect: f32, fov: f32, z_near: f32, z_far: f32) -> Self {
|
||||
let projection = nalgebra_glm::perspective(aspect, fov.to_radians(), z_near, z_far);
|
||||
Self {
|
||||
aspect,
|
||||
fov,
|
||||
z_far,
|
||||
z_near,
|
||||
projection,
|
||||
}
|
||||
}
|
||||
fn new_perspective(&self) -> nalgebra_glm::Mat4 {
|
||||
nalgebra_glm::perspective(self.aspect, self.fov.to_radians(), self.z_near, self.z_far)
|
||||
}
|
||||
|
||||
pub fn set_aspect(&mut self, aspect: f32) {
|
||||
self.aspect = aspect;
|
||||
self.projection = self.new_perspective();
|
||||
}
|
||||
|
||||
pub fn set_fov(&mut self, fov: f32) {
|
||||
self.fov = fov;
|
||||
self.projection = self.new_perspective();
|
||||
}
|
||||
|
||||
pub fn set_z_near(&mut self, z_near: f32) {
|
||||
self.z_near = z_near;
|
||||
self.projection = self.new_perspective();
|
||||
}
|
||||
|
||||
pub fn set_z_far(&mut self, z_far: f32) {
|
||||
self.z_far = z_far;
|
||||
self.projection = self.new_perspective();
|
||||
}
|
||||
|
||||
pub fn fov(&self) -> f32 {
|
||||
self.fov
|
||||
}
|
||||
|
||||
fn as_slice(&self) -> &[f32] {
|
||||
self.projection.as_slice()
|
||||
}
|
||||
}
|
||||
@ -41,14 +41,14 @@ impl UiType {
|
||||
ui: &imgui::Ui,
|
||||
context: &mut crate::pg::Context<'gl>,
|
||||
layout: &mut crate::ui::layout::Layout,
|
||||
app_typ: &mut crate::pg::app_type::AppType<'gl>,
|
||||
app_typ: &mut crate::pg::layout_type::Layout<'gl>,
|
||||
) {
|
||||
let gl = context.gl;
|
||||
let app_typ = app_typ.into();
|
||||
uit!(self, {Mainload => render(ui,context,layout,app_typ)},);
|
||||
}
|
||||
|
||||
pub fn init_apptype<'gl>(&mut self, gl: &'gl GL) -> crate::pg::app_type::AppType<'gl> {
|
||||
pub fn init_apptype<'gl>(&mut self, gl: &'gl GL) -> crate::pg::layout_type::Layout<'gl> {
|
||||
uit!(self, {Mainload => init(gl)},).into()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,26 +1,32 @@
|
||||
use super::{CameraOP, Layout, LayoutAppType, LayoutMod, Size};
|
||||
use crate::graphics::threed::ThreeD;
|
||||
use std::thread::panicking;
|
||||
|
||||
use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size};
|
||||
use crate::camera::Camera;
|
||||
use crate::graphics::threed::Trackball;
|
||||
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
|
||||
use crate::pg::ModulePackage;
|
||||
use crate::pg::{_ModulePackage, app_type::ViewPort};
|
||||
use crate::pg::{_ModulePackage, layout_type::ViewPort};
|
||||
use crate::ui::io::IO;
|
||||
use crate::ui::operation::Operation;
|
||||
use crate::utils::resources::GL;
|
||||
use glow::HasContext;
|
||||
use imgui::{Condition, Ui, WindowFlags};
|
||||
use nalgebra_glm::Vec3;
|
||||
|
||||
pub struct MainLoad {}
|
||||
|
||||
impl LayoutMod for MainLoad {
|
||||
type AppType<'gl> = MainLoadTyp<'gl>;
|
||||
type Attach<'gl> = MainLoadAttach<'gl>;
|
||||
fn render<'b, 'gl>(
|
||||
&mut self,
|
||||
ui: &imgui::Ui,
|
||||
context: &mut crate::pg::Context<'gl>,
|
||||
layout: &mut Layout,
|
||||
apptyp: &mut Self::AppType<'gl>,
|
||||
apptyp: &mut Self::Attach<'gl>,
|
||||
) where
|
||||
'gl: 'b,
|
||||
{
|
||||
let mut changed = true;
|
||||
let mut grid = layout.grid(2, 1, [0.0, 0.0]);
|
||||
grid.set_col_size(&[size!(20.0%), size!(fill)]);
|
||||
grid.set_row_size(&[size!(fill)]);
|
||||
@ -35,8 +41,27 @@ impl LayoutMod for MainLoad {
|
||||
grid.with(0, 0, [1, 1])
|
||||
.start_window(ui, "MainLoad")
|
||||
.build(|| {
|
||||
for package in 0..apptyp.packages.len() {
|
||||
if ui.button(format!("Delete Package {}", package)) {
|
||||
apptyp.packages.remove(package);
|
||||
}
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
for package in apptyp.packages.iter_mut() {
|
||||
package.ui_build(ui);
|
||||
if package.ui_build(ui).unwrap() {
|
||||
package.dirty();
|
||||
}
|
||||
}
|
||||
|
||||
ui.separator();
|
||||
|
||||
if ui.button("ON TOP") {
|
||||
apptyp
|
||||
.operation
|
||||
.set_camera(|c| c.set_position(Vec3::new(0.0, 0.0, 20.0)));
|
||||
apptyp.operation.reset();
|
||||
}
|
||||
});
|
||||
|
||||
@ -58,6 +83,9 @@ impl LayoutMod for MainLoad {
|
||||
|
||||
// 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();
|
||||
|
||||
@ -87,19 +115,36 @@ 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",
|
||||
);
|
||||
});
|
||||
|
||||
if ui.is_window_hovered() {
|
||||
let cio = IO::new(ui);
|
||||
apptyp.deal_with_camera(&cio);
|
||||
apptyp.operation.deal_io(&cio);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
fn init<'gl>(&mut self, gl: &'gl GL) -> Self::AppType<'gl> {
|
||||
let typ = MainLoadTyp {
|
||||
fn init<'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl> {
|
||||
let typ = MainLoadAttach {
|
||||
main_viewport: ViewPort::new(gl),
|
||||
packages: Vec::new(),
|
||||
camera_op: ThreeD::default(),
|
||||
operation: Operation::new(Trackball::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0),
|
||||
};
|
||||
typ
|
||||
}
|
||||
@ -109,13 +154,11 @@ impl MainLoad {
|
||||
pub fn new() -> Self {
|
||||
MainLoad {}
|
||||
}
|
||||
|
||||
fn render_window(&mut self, ui: &Ui, context: &mut crate::pg::Context) {}
|
||||
}
|
||||
|
||||
pub struct MainLoadTyp<'gl> {
|
||||
pub struct MainLoadAttach<'gl> {
|
||||
operation: Operation<Trackball>,
|
||||
main_viewport: ViewPort,
|
||||
camera_op: ThreeD,
|
||||
packages: Vec<ModulePackage<'gl>>,
|
||||
}
|
||||
|
||||
@ -126,33 +169,43 @@ impl CameraOP for MouseState {
|
||||
from: context.mouse.position,
|
||||
delta: context.mouse.drag_delta.unwrap(),
|
||||
}
|
||||
} else {
|
||||
if context.mouse.wheel_delta != 0.0 {
|
||||
Self::Wheel(context.mouse.wheel_delta)
|
||||
} else {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'gl> LayoutAppType<'gl> for MainLoadTyp<'gl> {
|
||||
type CameraOP = MouseState;
|
||||
fn deal_with_cursor(&mut self, package: ModulePackage<'gl>) {
|
||||
impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> {
|
||||
fn append(&mut self, package: ModulePackage<'gl>) {
|
||||
self.packages.push(package);
|
||||
}
|
||||
|
||||
fn draw_program(
|
||||
fn render_task(
|
||||
&mut self,
|
||||
gl: &glow::Context,
|
||||
programs: &mut crate::pg::Programs<'gl>,
|
||||
) -> crate::errors::Result<()> {
|
||||
self.main_viewport.bind(gl);
|
||||
if self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update() {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
||||
}
|
||||
|
||||
for package in self.packages.iter_mut() {
|
||||
programs.draw_modules(package, &self.camera_op)?;
|
||||
programs.draw_modules(package, &self.operation)?;
|
||||
}
|
||||
}
|
||||
|
||||
if self.packages.is_empty() {
|
||||
unsafe {
|
||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||
}
|
||||
}
|
||||
self.main_viewport.unbind();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn _deal_with_camera(&mut self, camera_op: Self::CameraOP) {
|
||||
// println!("Camera Op: {:?}", camera_op);
|
||||
self.camera_op.attach_with_mouse(&camera_op);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,35 +3,61 @@ use std::fmt::Debug;
|
||||
use super::io::IO;
|
||||
use super::layout::{Layout, Size};
|
||||
mod main_load;
|
||||
use crate::pg::app_type::AppType;
|
||||
use crate::pg::layout_type::Layout as _Layout;
|
||||
use crate::pg::{self, ModuleCursor, ModulePackage, Programs};
|
||||
use crate::utils::resources::GL;
|
||||
pub use main_load::*;
|
||||
|
||||
macro_rules! app_type_into {
|
||||
($({$t: ty => $b:tt},)+) => {
|
||||
$(
|
||||
impl<'gl> From<$t> for _Layout<'gl> {
|
||||
fn from(t: $t) -> Self {
|
||||
Self::$b(t)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'gl> From<&'a _Layout<'gl>> for &'a $t {
|
||||
fn from(t: &'a _Layout<'gl>) -> Self {
|
||||
if let _Layout::$b(t) = t {
|
||||
t
|
||||
} else {
|
||||
panic!("_Layout is not {}", stringify!($b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a,'gl> From<&'a mut _Layout<'gl>> for &'a mut $t {
|
||||
fn from(t: &'a mut _Layout<'gl>) -> Self {
|
||||
if let _Layout::$b(t) = t {
|
||||
t
|
||||
} else {
|
||||
panic!("_Layout is not {}", stringify!($b));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
)+
|
||||
};
|
||||
}
|
||||
|
||||
pub trait LayoutMod {
|
||||
type AppType<'gl>: Into<AppType<'gl>> + LayoutAppType<'gl>;
|
||||
type Attach<'gl>: Into<_Layout<'gl>> + LayoutAttach<'gl>;
|
||||
fn render<'dt, 'b, 'gl>(
|
||||
&mut self,
|
||||
ui: &imgui::Ui,
|
||||
context: &mut crate::pg::Context<'gl>,
|
||||
layout: &mut Layout,
|
||||
apptyp: &mut Self::AppType<'gl>,
|
||||
apptyp: &mut Self::Attach<'gl>,
|
||||
) where
|
||||
'gl: 'b;
|
||||
fn init<'dt, 'gl>(&mut self, gl: &'gl GL) -> Self::AppType<'gl>;
|
||||
fn init<'dt, 'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl>;
|
||||
}
|
||||
|
||||
pub trait LayoutAppType<'gl> {
|
||||
type CameraOP: CameraOP + Debug;
|
||||
fn deal_with_cursor(&mut self, package: ModulePackage<'gl>);
|
||||
pub trait LayoutAttach<'gl> {
|
||||
fn append(&mut self, package: ModulePackage<'gl>);
|
||||
|
||||
fn deal_with_camera(&mut self, camera_op: &IO) {
|
||||
self._deal_with_camera(CameraOP::from_context(camera_op));
|
||||
}
|
||||
|
||||
fn _deal_with_camera(&mut self, camera_op: Self::CameraOP);
|
||||
|
||||
fn draw_program(
|
||||
fn render_task(
|
||||
&mut self,
|
||||
gl: &glow::Context,
|
||||
programs: &mut Programs<'gl>,
|
||||
@ -47,3 +73,7 @@ impl CameraOP for () {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
app_type_into!({
|
||||
MainLoadAttach<'gl> => MainLoad
|
||||
},);
|
||||
|
||||
18
src/utils/color_tools.rs
Normal file
18
src/utils/color_tools.rs
Normal file
@ -0,0 +1,18 @@
|
||||
pub fn hex_to_rgba_u8(hex: &str) -> Result<[u8; 4], String> {
|
||||
let hex = hex.trim_start_matches('#');
|
||||
|
||||
if hex.len() != 6 && hex.len() != 8 {
|
||||
return Err("Hex color should be in #RRGGBB or #RRGGBBAA format".to_string());
|
||||
}
|
||||
|
||||
let r = u8::from_str_radix(&hex[0..2], 16).map_err(|e| e.to_string())?;
|
||||
let g = u8::from_str_radix(&hex[2..4], 16).map_err(|e| e.to_string())?;
|
||||
let b = u8::from_str_radix(&hex[4..6], 16).map_err(|e| e.to_string())?;
|
||||
let a = if hex.len() == 8 {
|
||||
u8::from_str_radix(&hex[6..8], 16).map_err(|e| e.to_string())?
|
||||
} else {
|
||||
255 // 默认不透明
|
||||
};
|
||||
|
||||
Ok([r, g, b, a])
|
||||
}
|
||||
@ -1,3 +1,4 @@
|
||||
pub mod color_tools;
|
||||
mod parser;
|
||||
pub mod resources;
|
||||
use include_dir::{include_dir, Dir};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user