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",
|
"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]]
|
[[package]]
|
||||||
name = "glutin"
|
name = "glutin"
|
||||||
version = "0.31.3"
|
version = "0.31.3"
|
||||||
@ -1860,6 +1881,12 @@ dependencies = [
|
|||||||
"toml_edit 0.21.1",
|
"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]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.85"
|
version = "1.0.85"
|
||||||
@ -1938,6 +1965,8 @@ dependencies = [
|
|||||||
"freetype-rs",
|
"freetype-rs",
|
||||||
"geo",
|
"geo",
|
||||||
"glow",
|
"glow",
|
||||||
|
"glsl",
|
||||||
|
"glsl-quasiquote",
|
||||||
"glutin",
|
"glutin",
|
||||||
"glutin-winit",
|
"glutin-winit",
|
||||||
"image",
|
"image",
|
||||||
@ -1960,6 +1989,7 @@ dependencies = [
|
|||||||
"serde_json",
|
"serde_json",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tinyfiledialogs",
|
"tinyfiledialogs",
|
||||||
|
"toml",
|
||||||
"tracker",
|
"tracker",
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
@ -2290,9 +2320,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_spanned"
|
name = "serde_spanned"
|
||||||
version = "0.6.6"
|
version = "0.6.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "79e674e01f999af37c49f70a6ede167a8a60b2503e56c5599532a65baa5969a0"
|
checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -2549,21 +2579,21 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml"
|
name = "toml"
|
||||||
version = "0.8.15"
|
version = "0.8.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
|
checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"toml_edit 0.22.16",
|
"toml_edit 0.22.20",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_datetime"
|
name = "toml_datetime"
|
||||||
version = "0.6.6"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
@ -2581,15 +2611,15 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "toml_edit"
|
name = "toml_edit"
|
||||||
version = "0.22.16"
|
version = "0.22.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_spanned",
|
"serde_spanned",
|
||||||
"toml_datetime",
|
"toml_datetime",
|
||||||
"winnow 0.6.15",
|
"winnow 0.6.18",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3213,9 +3243,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winnow"
|
name = "winnow"
|
||||||
version = "0.6.15"
|
version = "0.6.18"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0"
|
checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|||||||
@ -16,7 +16,7 @@ dirs = "5.0.1"
|
|||||||
env_logger = "0.11.3"
|
env_logger = "0.11.3"
|
||||||
flate2 = "1.0.30"
|
flate2 = "1.0.30"
|
||||||
# font-kit = {version = "0.14.1"}
|
# font-kit = {version = "0.14.1"}
|
||||||
freetype-rs = "0.37.0"
|
freetype-rs = {version="0.37.0",features = ["bundled"]}
|
||||||
geo = "0.28.0"
|
geo = "0.28.0"
|
||||||
glow = "0.13.1"
|
glow = "0.13.1"
|
||||||
glutin = "0.31.3"
|
glutin = "0.31.3"
|
||||||
@ -43,9 +43,13 @@ thiserror = "1.0.61"
|
|||||||
winit = "0.29.3"
|
winit = "0.29.3"
|
||||||
tinyfiledialogs = "3.0"
|
tinyfiledialogs = "3.0"
|
||||||
tracker = "0.2.2"
|
tracker = "0.2.2"
|
||||||
|
glsl = "7.0.0"
|
||||||
|
glsl-quasiquote = "7.0.0"
|
||||||
|
toml = "0.8.19"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["sdf_font"]
|
default = ["sdf_font"]
|
||||||
|
|
||||||
normal_font = []
|
normal_font = []
|
||||||
sdf_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 {
|
pub(crate) struct Camera {
|
||||||
pos: Vec3,
|
pos: Vec3,
|
||||||
upward: Vec3,
|
upward: Vec3,
|
||||||
front: Vec3,
|
center: Vec3,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type CameraPositon = Vec3;
|
pub type CameraPositon = Vec3;
|
||||||
|
|
||||||
impl Camera {
|
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 {
|
Self {
|
||||||
pos: world_loc,
|
pos: world_loc,
|
||||||
upward,
|
upward,
|
||||||
front,
|
center,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,14 +29,6 @@ impl Camera {
|
|||||||
self.pos = pos;
|
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 {
|
pub fn get_upward(&self) -> Vec3 {
|
||||||
self.upward
|
self.upward
|
||||||
}
|
}
|
||||||
@ -46,8 +38,8 @@ impl Camera {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_view_matrix(&self) -> Mat4x4 {
|
pub fn get_view_matrix(&self) -> Mat4x4 {
|
||||||
let l = self.pos + self.front;
|
let l = self.center;
|
||||||
look_at(&l, &self.pos, &self.upward)
|
look_at(&self.pos, &l, &self.upward)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +48,7 @@ impl Default for Camera {
|
|||||||
Self {
|
Self {
|
||||||
pos: Vec3::new(0.0, 0.0, 0.0),
|
pos: Vec3::new(0.0, 0.0, 0.0),
|
||||||
upward: Vec3::new(0.0, 1.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::shader::Shader;
|
||||||
use super::snippets::{CodeType, Snippet};
|
use super::snippets::{CodeType, Snippet};
|
||||||
use crate::components::CodeComponent;
|
use crate::components::CodeComponent;
|
||||||
use crate::graphics::transforms::{viewport::Viewport, Transform};
|
use crate::graphics::transforms::viewport::Viewport;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Program {
|
pub struct Program {
|
||||||
@ -45,16 +45,19 @@ impl Program {
|
|||||||
self.geometry.as_ref()
|
self.geometry.as_ref()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
||||||
self.vertex.set_hook(hook, code);
|
self.vertex.set_hook(hook, code);
|
||||||
self.fragment.set_hook(hook, code);
|
self.fragment.set_hook(hook, code);
|
||||||
self.geometry.as_mut().map(|g| g.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) {
|
pub fn set_transform<T: Transform>(&mut self, value: &T) {
|
||||||
self.set_hook("transform", value.snippet());
|
self.set_hook("transform", value.snippet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||||
self.set_hook("viewport", viewport.snippet());
|
self.set_hook("viewport", viewport.snippet());
|
||||||
}
|
}
|
||||||
@ -62,8 +65,11 @@ impl Program {
|
|||||||
pub fn compile(&mut self, gl: &glow::Context) -> crate::errors::Result<()> {
|
pub fn compile(&mut self, gl: &glow::Context) -> crate::errors::Result<()> {
|
||||||
use crate::errors::Error;
|
use crate::errors::Error;
|
||||||
|
|
||||||
self.vertex.define("_GLUMPY__VERTEX_SHADER__");
|
#[cfg(feature = "inparser")]
|
||||||
self.fragment.define("_GLUMPY__FRAGMENT_SHADER__");
|
{
|
||||||
|
self.vertex.define("_GLUMPY__VERTEX_SHADER__");
|
||||||
|
self.fragment.define("_GLUMPY__FRAGMENT_SHADER__");
|
||||||
|
}
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let program = gl.create_program().map_err(|e| Error::InvalidProgram(e))?;
|
let program = gl.create_program().map_err(|e| Error::InvalidProgram(e))?;
|
||||||
@ -76,6 +82,7 @@ impl Program {
|
|||||||
|
|
||||||
// Geom Shader
|
// Geom Shader
|
||||||
let geom_shader = if let Some(geometry) = self.geometry.as_mut() {
|
let geom_shader = if let Some(geometry) = self.geometry.as_mut() {
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
geometry.define("_GLUMPY__GEOMETRY_SHADER__");
|
geometry.define("_GLUMPY__GEOMETRY_SHADER__");
|
||||||
let geometry_shader = geometry.compile(&self.version, gl);
|
let geometry_shader = geometry.compile(&self.version, gl);
|
||||||
|
|
||||||
@ -138,13 +145,13 @@ mod test {
|
|||||||
fn test_program() {
|
fn test_program() {
|
||||||
let vertex = Shader::new(
|
let vertex = Shader::new(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
CodeType::<&'static str>::Path("agg-fast-path.vert".into()),
|
CodeType::from_path("agg-fast-path.vert"),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let fragment = Shader::new(
|
let fragment = Shader::new(
|
||||||
glow::FRAGMENT_SHADER,
|
glow::FRAGMENT_SHADER,
|
||||||
CodeType::<&'static str>::Path("agg-fast-path.frag".into()),
|
CodeType::from_path("agg-fast-path.frag"),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -15,7 +15,10 @@ pub type ShaderType = u32;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Shader {
|
pub struct Shader {
|
||||||
target: u32,
|
target: u32,
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
parsed: CodeBlock,
|
parsed: CodeBlock,
|
||||||
|
parsed: String,
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub hooks: Vec<String>,
|
pub hooks: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,25 +29,34 @@ impl std::fmt::Display for Shader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
let code = match code {
|
||||||
CodeType::Code(code) => code.borrow().to_string(),
|
CodeType::Code(code) => code,
|
||||||
CodeType::Path(path) => {
|
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
|
code
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let code = merge_includes(code).map_err(|e| Error::InvalidSnippet(e.to_string()))?;
|
#[cfg(feature = "inparser")]
|
||||||
let parsed = CodeBlock::new(&code)?;
|
{
|
||||||
|
let code = merge_includes(code).map_err(|e| Error::InvalidSnippet(e.to_string()))?;
|
||||||
let hooks = parsed.all_hooks().iter().map(|h| h.name.clone()).collect();
|
let parsed = CodeBlock::new(&code)?;
|
||||||
info!("Shader:{} Hooks: {:?}", target, hooks);
|
let hooks = parsed.all_hooks().iter().map(|h| h.name.clone()).collect();
|
||||||
|
info!("Shader:{} Hooks: {:?}", target, hooks);
|
||||||
|
return Ok(Self {
|
||||||
|
target,
|
||||||
|
parsed,
|
||||||
|
hooks,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
target,
|
target,
|
||||||
parsed,
|
parsed: code,
|
||||||
hooks,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,11 +80,13 @@ impl Shader {
|
|||||||
shader
|
shader
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn define(&mut self, s: &str) {
|
pub fn define(&mut self, s: &str) {
|
||||||
self.parsed
|
self.parsed
|
||||||
.insert(Code::new(&format!("#define {}\n", s)), 0);
|
.insert(Code::new(&format!("#define {}\n", s)), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
pub fn set_hook(&mut self, hook: &str, code: &Snippet) {
|
||||||
self.parsed.set_hook(hook, code);
|
self.parsed.set_hook(hook, code);
|
||||||
}
|
}
|
||||||
@ -217,13 +231,8 @@ mod utils {
|
|||||||
body.push_str("}\n\n");
|
body.push_str("}\n\n");
|
||||||
let input = header + &body;
|
let input = header + &body;
|
||||||
|
|
||||||
let result = Snippet::new(
|
let result =
|
||||||
"fetch_uniform",
|
Snippet::new("fetch_uniform", CodeType::from_code(input), false, None).unwrap();
|
||||||
CodeType::<String>::Code(input),
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
@ -237,7 +246,7 @@ mod test {
|
|||||||
fn test_shader() {
|
fn test_shader() {
|
||||||
let shader = Shader::new(
|
let shader = Shader::new(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
CodeType::<&'static str>::Path("agg-fast-path.vert".into()),
|
CodeType::from_path("agg-fast-path.vert"),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -3,7 +3,7 @@ use std::{
|
|||||||
cell::{Ref, RefCell},
|
cell::{Ref, RefCell},
|
||||||
collections::{HashMap, HashSet},
|
collections::{HashMap, HashSet},
|
||||||
ops::Add,
|
ops::Add,
|
||||||
path::Path,
|
path::{Path, PathBuf},
|
||||||
rc::Rc,
|
rc::Rc,
|
||||||
sync::atomic::{AtomicUsize, Ordering},
|
sync::atomic::{AtomicUsize, Ordering},
|
||||||
};
|
};
|
||||||
@ -11,6 +11,7 @@ pub use util::Variable;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{Error, Result},
|
errors::{Error, Result},
|
||||||
|
shaders::{CodePiece, EmptyPiece},
|
||||||
utils::{find_file, Code, CodeBlock, Function, Hook, ShareVariable, SnippetCode},
|
utils::{find_file, Code, CodeBlock, Function, Hook, ShareVariable, SnippetCode},
|
||||||
};
|
};
|
||||||
mod util;
|
mod util;
|
||||||
@ -27,9 +28,33 @@ pub enum InputType {
|
|||||||
Other(Variable),
|
Other(Variable),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum CodeType<S: std::borrow::Borrow<str> = &'static str, P: AsRef<Path> = &'static str> {
|
// pub enum CodeType<
|
||||||
Code(S),
|
// CP: CodePiece = EmptyPiece,
|
||||||
Path(P),
|
// 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)]
|
#[derive(Debug, Clone)]
|
||||||
@ -44,14 +69,14 @@ pub struct Snippet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Snippet {
|
impl Snippet {
|
||||||
pub fn new<S: std::borrow::Borrow<str>, P: AsRef<Path>>(
|
pub fn new(
|
||||||
name: &'static str,
|
name: &'static str,
|
||||||
code: CodeType<S, P>,
|
code: CodeType,
|
||||||
mangling: bool,
|
mangling: bool,
|
||||||
main: Option<String>,
|
main: Option<String>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let code = match code {
|
let code = match code {
|
||||||
CodeType::Code(code) => code.borrow().to_string(),
|
CodeType::Code(code) => code,
|
||||||
CodeType::Path(path) => {
|
CodeType::Path(path) => {
|
||||||
let code = find_file(path).expect("Failed to find file");
|
let code = find_file(path).expect("Failed to find file");
|
||||||
code
|
code
|
||||||
@ -173,13 +198,7 @@ impl Add for Snippet {
|
|||||||
let code = rhs.parsed.to_string();
|
let code = rhs.parsed.to_string();
|
||||||
|
|
||||||
raw_code.push_str(&code);
|
raw_code.push_str(&code);
|
||||||
Snippet::new(
|
Snippet::new(self.name, CodeType::from_code(raw_code), false, None).unwrap()
|
||||||
self.name,
|
|
||||||
CodeType::<std::string::String>::Code(raw_code),
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
)
|
|
||||||
.unwrap()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,11 +226,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
let snippet =
|
let snippet = Snippet::new("polar", CodeType::from_code(code), true, None).unwrap();
|
||||||
Snippet::new("polar", CodeType::<&'static str>::Code(code), true, None).unwrap();
|
|
||||||
|
|
||||||
let snippet2 =
|
let snippet2 = Snippet::new("polar2", CodeType::from_code(code), true, None).unwrap();
|
||||||
Snippet::new("polar2", CodeType::<&'static str>::Code(code), true, None).unwrap();
|
|
||||||
|
|
||||||
let snippet3 = snippet.clone() + snippet2.clone();
|
let snippet3 = snippet.clone() + snippet2.clone();
|
||||||
|
|
||||||
|
|||||||
@ -170,7 +170,7 @@ impl Data {
|
|||||||
};
|
};
|
||||||
|
|
||||||
use DataType::*;
|
use DataType::*;
|
||||||
let valuetype = info.value_type.as_str();
|
let valuetype = info.value_name.as_str();
|
||||||
|
|
||||||
let data_type = block_data_type_prepare!(valuetype,
|
let data_type = block_data_type_prepare!(valuetype,
|
||||||
"ET" => ET,
|
"ET" => ET,
|
||||||
|
|||||||
@ -27,4 +27,7 @@ pub enum Error {
|
|||||||
|
|
||||||
#[error("Invalid Font {0}")]
|
#[error("Invalid Font {0}")]
|
||||||
FontError(String),
|
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::components::{fetchcode, CodeComponent, CodeType, Program, Shader, Snippet};
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::graphics::transforms::viewport::Viewport;
|
use crate::graphics::transforms::viewport::Viewport;
|
||||||
use crate::graphics::transforms::Transform;
|
|
||||||
use crate::graphics::ty::Ty;
|
use crate::graphics::ty::Ty;
|
||||||
use crate::graphics::{AttaWithBuffer, Config, Graphics};
|
use crate::graphics::{AttaWithBuffer, Config, Graphics};
|
||||||
|
|
||||||
@ -26,17 +25,17 @@ impl AggFastPath {
|
|||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let vertex = Shader::new(
|
let vertex = Shader::new(
|
||||||
glow::VERTEX_SHADER,
|
glow::VERTEX_SHADER,
|
||||||
CodeType::<String>::Path("agg-fast-path.vert".into()),
|
CodeType::from_path("agg-fast-path.vert"),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let fragment = Shader::new(
|
let fragment = Shader::new(
|
||||||
glow::FRAGMENT_SHADER,
|
glow::FRAGMENT_SHADER,
|
||||||
CodeType::<String>::Path("agg-fast-path.frag".into()),
|
CodeType::from_path("agg-fast-path.frag"),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let input_snippet = Snippet::new(
|
let input_snippet = Snippet::new(
|
||||||
"input",
|
"input",
|
||||||
CodeType::<&'static str>::Code(
|
CodeType::from_code(
|
||||||
"
|
"
|
||||||
layout(location = 0) in vec3 prev;
|
layout(location = 0) in vec3 prev;
|
||||||
layout(location = 1) in vec3 curr;
|
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) {
|
pub fn set_transform<T: Transform>(&mut self, transform: &T) {
|
||||||
self.program.set_transform(transform);
|
self.program.set_transform(transform);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||||
self.program.set_viewport(viewport);
|
self.program.set_viewport(viewport);
|
||||||
}
|
}
|
||||||
@ -182,7 +183,6 @@ impl Graphics for AggFastPath {
|
|||||||
|
|
||||||
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
|
||||||
gl.bind_vertex_array(Some(self.vao.unwrap()));
|
gl.bind_vertex_array(Some(self.vao.unwrap()));
|
||||||
gl.draw_elements(
|
gl.draw_elements(
|
||||||
glow::TRIANGLES,
|
glow::TRIANGLES,
|
||||||
@ -425,8 +425,6 @@ impl DerefMut for Path {
|
|||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use crate::graphics::transforms::{polar::Polar, position::Position, trackball::Trackball};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -1,40 +1,37 @@
|
|||||||
use glow::HasContext;
|
use super::ColorMap;
|
||||||
|
|
||||||
use crate::components::{CodeType, Program, Snippet};
|
use crate::components::{CodeType, Program, Snippet};
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
use crate::shaders::colormap::ColorMap as CmapPiece;
|
||||||
use super::ColorMap;
|
use glow::HasContext;
|
||||||
|
|
||||||
pub struct LinearColormap {
|
pub struct LinearColormap {
|
||||||
snippet: Snippet,
|
|
||||||
colors: Vec<[u8; 4]>,
|
colors: Vec<[u8; 4]>,
|
||||||
|
|
||||||
color_changed: bool,
|
color_changed: bool,
|
||||||
texture: Option<glow::NativeTexture>,
|
texture: Option<glow::NativeTexture>,
|
||||||
|
|
||||||
|
pub unvalid: f32,
|
||||||
pub min: f32,
|
pub min: f32,
|
||||||
pub max: f32,
|
pub max: f32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LinearColormap {
|
impl LinearColormap {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let snippet = Snippet::new(
|
|
||||||
"linear",
|
|
||||||
CodeType::<&'static str>::Path("colormap.glsl".into()),
|
|
||||||
true,
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
snippet,
|
|
||||||
colors: vec![],
|
colors: vec![],
|
||||||
texture: None,
|
texture: None,
|
||||||
color_changed: true,
|
color_changed: true,
|
||||||
min: 0.0,
|
min: 0.0,
|
||||||
max: 1.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]>) {
|
pub fn set_colors(&mut self, colors: Vec<[u8; 4]>) {
|
||||||
self.colors = colors;
|
self.colors = colors;
|
||||||
self.color_changed = true;
|
self.color_changed = true;
|
||||||
@ -79,18 +76,14 @@ impl ColorMap for LinearColormap {
|
|||||||
glow::NEAREST as i32,
|
glow::NEAREST as i32,
|
||||||
);
|
);
|
||||||
|
|
||||||
let name = self.snippet.find_symbol("conf").unwrap();
|
let location = program.get_uniform_location(gl, "colormap_conf");
|
||||||
let location = program.get_uniform_location(gl, &name);
|
|
||||||
|
|
||||||
// gl.uniform_2_f32(location.as_ref(), 0);
|
|
||||||
gl.uniform_4_f32(
|
gl.uniform_4_f32(
|
||||||
location.as_ref(),
|
location.as_ref(),
|
||||||
self.min,
|
self.min,
|
||||||
self.max,
|
self.max,
|
||||||
self.colors.len() as f32,
|
self.colors.len() as f32,
|
||||||
125.0,
|
self.unvalid,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.texture = Some(texture);
|
self.texture = Some(texture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,17 +103,12 @@ impl ColorMap for LinearColormap {
|
|||||||
unsafe {
|
unsafe {
|
||||||
gl.active_texture(glow::TEXTURE0);
|
gl.active_texture(glow::TEXTURE0);
|
||||||
gl.bind_texture(glow::TEXTURE_1D, self.texture);
|
gl.bind_texture(glow::TEXTURE_1D, self.texture);
|
||||||
let name = self.snippet.find_symbol("colormap").unwrap();
|
let location = program.get_uniform_location(gl, "colormap");
|
||||||
let location = program.get_uniform_location(gl, &name);
|
|
||||||
gl.uniform_1_i32(location.as_ref(), 0);
|
gl.uniform_1_i32(location.as_ref(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn snippet_ref(&self) -> &crate::components::Snippet {
|
|
||||||
&self.snippet
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
|
|||||||
@ -11,7 +11,5 @@ pub trait ColorMap {
|
|||||||
|
|
||||||
fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()>;
|
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);
|
fn destroy(&mut self, gl: &glow::Context);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,7 +13,7 @@ use crate::{
|
|||||||
utils::resources::RcGlTexture,
|
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> {
|
pub struct Text<'a> {
|
||||||
gl: &'a glow::Context,
|
gl: &'a glow::Context,
|
||||||
font_manager: RefCell<FontManager>,
|
font_manager: RefCell<FontManager>,
|
||||||
@ -153,13 +153,13 @@ impl<'a> Text<'a> {
|
|||||||
pub fn new(gl: &'a glow::Context, font_manager: FontManager) -> Result<Self> {
|
pub fn new(gl: &'a glow::Context, font_manager: FontManager) -> Result<Self> {
|
||||||
let vertex = Shader::new(
|
let vertex = Shader::new(
|
||||||
glow::VERTEX_SHADER,
|
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");
|
let mut program = Program::new(vertex, fragment, None, "330 core");
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
program.set_transform(&transform);
|
program.set_transform(&transform);
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@ -171,6 +171,7 @@ impl<'a> Text<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "inparser")]
|
||||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
||||||
self.program.set_viewport(viewport);
|
self.program.set_viewport(viewport);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -20,15 +20,8 @@ pub struct Hello {
|
|||||||
|
|
||||||
impl Hello {
|
impl Hello {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let vertex = Shader::new(
|
let vertex = Shader::new(glow::VERTEX_SHADER, CodeType::from_path("hello.vert"))?;
|
||||||
glow::VERTEX_SHADER,
|
let fragment = Shader::new(glow::FRAGMENT_SHADER, CodeType::from_path("hello.frag"))?;
|
||||||
CodeType::<String>::Path("hello.vert".into()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let fragment = Shader::new(
|
|
||||||
glow::FRAGMENT_SHADER,
|
|
||||||
CodeType::<String>::Path("hello.frag".into()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let program = Program::new(vertex, fragment, None, "330 core");
|
let program = Program::new(vertex, fragment, None, "330 core");
|
||||||
|
|
||||||
@ -284,8 +277,6 @@ impl DerefMut for Path {
|
|||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
|
|
||||||
use crate::graphics::transforms::{polar::Polar, position::Position, trackball::Trackball};
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@ -9,7 +9,13 @@ pub mod tools;
|
|||||||
pub mod transforms;
|
pub mod transforms;
|
||||||
pub mod ty;
|
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 glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||||
use ppi::PPIConfig;
|
use ppi::PPIConfig;
|
||||||
@ -113,11 +119,22 @@ pub enum Config {
|
|||||||
config_for_everyitem!({PPIConfig => PPI},{FontConfig => Font}, );
|
config_for_everyitem!({PPIConfig => PPI},{FontConfig => Font}, );
|
||||||
|
|
||||||
pub trait AttachWithMouse {
|
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)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum MouseState {
|
pub enum MouseState {
|
||||||
Drag { from: [f32; 2], delta: [f32; 2] },
|
Drag { from: [f32; 2], delta: [f32; 2] },
|
||||||
|
Wheel(f32),
|
||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,92 +1,64 @@
|
|||||||
use super::colormap::ColorMap;
|
use super::colormap::ColorMap;
|
||||||
use super::threed::ThreeD;
|
|
||||||
use super::transforms::viewport::Viewport;
|
use super::transforms::viewport::Viewport;
|
||||||
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics};
|
use super::{transforms, AttaWithBuffer, AttaWithProgram, AttachWithMouse, Config, Graphics};
|
||||||
use crate::components::{CodeType, Program, Shader};
|
use crate::components::{CodeType, Program, Shader};
|
||||||
use crate::data_loader::{CoordType, Data, DataType};
|
use crate::data_loader::{CoordType, Data, DataType};
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::graphics::colormap::linear::LinearColormap;
|
use crate::graphics::colormap::linear::LinearColormap;
|
||||||
use crate::graphics::transforms::Transform;
|
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||||
|
|
||||||
pub struct PPI {
|
pub struct PPI {
|
||||||
program: Program,
|
program: Program,
|
||||||
cmap: Option<Box<dyn ColorMap>>,
|
cmap: LinearColormap,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PPI {
|
impl PPI {
|
||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let vertex = Shader::new(
|
use crate::shaders::ppi::*;
|
||||||
glow::VERTEX_SHADER,
|
let vertex = Shader::new(glow::VERTEX_SHADER, CodeType::from_piece(PPIVertex::new()))?;
|
||||||
CodeType::<String>::Path("ppi.vert".into()),
|
let geom = Shader::new(glow::GEOMETRY_SHADER, CodeType::from_piece(PPIGeom::new()))?;
|
||||||
)?;
|
|
||||||
|
|
||||||
let geom = Shader::new(
|
|
||||||
glow::GEOMETRY_SHADER,
|
|
||||||
CodeType::<String>::Path("ppi.geom".into()),
|
|
||||||
)?;
|
|
||||||
|
|
||||||
let fragment = Shader::new(
|
let fragment = Shader::new(
|
||||||
glow::FRAGMENT_SHADER,
|
glow::FRAGMENT_SHADER,
|
||||||
CodeType::<String>::Path("ppi.frag".into()),
|
CodeType::from_piece(PPIFragment::new()),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut cmap = LinearColormap::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");
|
let mut program = Program::new(vertex, fragment, Some(geom), "330 core");
|
||||||
program.set_transform(&transform);
|
|
||||||
program.set_hook("colormap", cmap.snippet_ref());
|
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self { program, cmap })
|
||||||
program,
|
|
||||||
cmap: Some(Box::new(cmap)),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn set_viewport(&mut self, viewport: &Viewport) {
|
|
||||||
self.program.set_viewport(viewport);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn program(&mut self) -> &mut Program {
|
pub fn program(&mut self) -> &mut Program {
|
||||||
&mut self.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");
|
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 {
|
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, usize, f32)> {
|
||||||
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn data_info(&self, data: &Data) -> Result<(f32, f32, DataType)> {
|
|
||||||
let first_block = data.blocks.get(0).unwrap();
|
let first_block = data.blocks.get(0).unwrap();
|
||||||
if let CoordType::Polar {
|
if let CoordType::Polar {
|
||||||
azimuth,
|
azimuth,
|
||||||
r,
|
r,
|
||||||
r_range,
|
r_range,
|
||||||
|
elevation,
|
||||||
..
|
..
|
||||||
} = &first_block.coord_type
|
} = &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));
|
sorted_azimuth.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Greater));
|
||||||
let azi_step = max_step(&sorted_azimuth);
|
let azi_step = max_step(&sorted_azimuth);
|
||||||
let r_step = min_step(r) / (r_range[1]) as f32;
|
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 {
|
} else {
|
||||||
return Err(Error::InvalidDataType);
|
return Err(Error::InvalidDataType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&mut self, gl: &glow::Context, config: &PPIConfig) {
|
fn init(&mut self, gl: &glow::Context, config: &PPIConfig) {
|
||||||
self.cmap
|
self.set_conf(gl, config);
|
||||||
.as_mut()
|
self.cmap.attach_with_program(gl, &self.program).unwrap();
|
||||||
.unwrap()
|
|
||||||
.attach_with_program(gl, &self.program)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let origin = self.program.get_uniform_location(gl, "polar_origin");
|
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 {
|
unsafe {
|
||||||
gl.uniform_1_f32(origin.as_ref(), 90.0f32.to_radians());
|
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<()> {
|
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
gl.clear(glow::COLOR_BUFFER_BIT);
|
self.cmap.bind_texture(gl, &self.program)?;
|
||||||
self.cmap
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.bind_texture(gl, &self.program)?;
|
|
||||||
|
|
||||||
gl.draw_arrays(glow::POINTS, 0, count);
|
gl.draw_arrays(glow::POINTS, 0, count);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -215,6 +183,7 @@ impl AttaWithBuffer for PPI {
|
|||||||
if let CoordType::Polar {
|
if let CoordType::Polar {
|
||||||
r_range,
|
r_range,
|
||||||
azimuth,
|
azimuth,
|
||||||
|
elevation,
|
||||||
r,
|
r,
|
||||||
..
|
..
|
||||||
} = &first_block.coord_type
|
} = &first_block.coord_type
|
||||||
@ -223,13 +192,15 @@ impl AttaWithBuffer for PPI {
|
|||||||
let r_len = r.len();
|
let r_len = r.len();
|
||||||
|
|
||||||
let mut vertices = Vec::with_capacity(azimuth_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 azi_idx in 0..azimuth_len {
|
||||||
for r_idx in 0..r_len {
|
for r_idx in 0..r_len {
|
||||||
let azi = azimuth.get(azi_idx).unwrap();
|
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() / r_range[1] as f32;
|
||||||
|
// let r = *r.get(r_idx).unwrap();
|
||||||
let dt = first_block_data.get([layer, azi_idx, 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;
|
let len = vertices.len() as i32 / 3;
|
||||||
@ -246,7 +217,7 @@ impl AttaWithBuffer for PPI {
|
|||||||
let vbo = gl.create_buffer().unwrap();
|
let vbo = gl.create_buffer().unwrap();
|
||||||
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||||
gl.enable_vertex_attrib_array(0);
|
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);
|
gl.bind_vertex_array(None);
|
||||||
|
|
||||||
(vao, vbo, None)
|
(vao, vbo, None)
|
||||||
@ -256,9 +227,13 @@ impl AttaWithBuffer for PPI {
|
|||||||
|
|
||||||
#[derive(Default, Clone, Debug)]
|
#[derive(Default, Clone, Debug)]
|
||||||
pub struct PPIConfig {
|
pub struct PPIConfig {
|
||||||
|
pub unvalid_value: f32,
|
||||||
pub layer: usize,
|
pub layer: usize,
|
||||||
|
pub colors: Vec<[u8; 4]>,
|
||||||
|
pub color_range: [f32; 2],
|
||||||
pub rdpi: f32,
|
pub rdpi: f32,
|
||||||
pub adpi: f32,
|
pub adpi: f32,
|
||||||
|
pub three_d: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
mod test {
|
mod test {
|
||||||
|
|||||||
@ -1,138 +1,75 @@
|
|||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
|
use tracker::track;
|
||||||
|
|
||||||
use super::transforms::Transform;
|
use super::transforms::{position::Position, trackball::TrackballModel};
|
||||||
use super::transforms::{position::Position, trackball::Trackball, ChainedTransform};
|
|
||||||
use super::{AttaWithProgram, AttachWithMouse};
|
use super::{AttaWithProgram, AttachWithMouse};
|
||||||
use crate::camera::Camera;
|
use crate::camera::{self, Camera};
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
use crate::ui::operation::Projection;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use nalgebra_glm::Vec3;
|
use nalgebra_glm::{Mat4, Vec3};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ThreeD {
|
pub struct Trackball {
|
||||||
transform: Rc<ChainedTransform>,
|
trackball: TrackballModel,
|
||||||
projection: nalgebra_glm::Mat4,
|
|
||||||
trackball: Trackball,
|
|
||||||
camera: Camera,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ThreeD {
|
impl Trackball {
|
||||||
pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result<Self> {
|
pub fn new(aspect: f32, z_near: f32, z_far: f32, fov: f32) -> Result<Self> {
|
||||||
let trackball = Trackball::new()?;
|
let trackball = TrackballModel::new(0.0, 90.0);
|
||||||
let transform = ChainedTransform::from(&trackball).chain(&Position::new()?);
|
|
||||||
|
|
||||||
let camera = Camera::new(
|
Ok(Self { trackball })
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ThreeD {
|
impl Default for Trackball {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self::new(16.0 / 9.0, 0.1, 1000.0, 45.0).unwrap()
|
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(
|
fn attach_with_program(
|
||||||
&self,
|
&self,
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
program: &crate::components::Program,
|
program: &crate::components::Program,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
unsafe {
|
self.trackball.attach_with_program(gl, program);
|
||||||
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());
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform for ThreeD {
|
impl AttachWithMouse for Trackball {
|
||||||
fn snippet(&self) -> &crate::components::Snippet {
|
type State = super::MouseState;
|
||||||
self.transform.snippet()
|
fn attach_with_mouse(
|
||||||
}
|
&mut self,
|
||||||
}
|
state: &Self::State,
|
||||||
|
camera: &mut Camera,
|
||||||
impl AttachWithMouse for ThreeD {
|
projection: &mut Projection,
|
||||||
fn attach_with_mouse(&mut self, state: &super::MouseState) {
|
) -> bool {
|
||||||
if let super::MouseState::Drag { from, delta } = state {
|
match state {
|
||||||
self.trackball
|
&super::MouseState::Wheel(delta) => {
|
||||||
.on_mouse_drag(from[0], from[1], delta[0], delta[1]);
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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;
|
use super::AttaWithProgram;
|
||||||
|
|
||||||
pub struct ChainedTransform {
|
// pub struct ChainedTransform {
|
||||||
snippet: Snippet,
|
// snippet: Snippet,
|
||||||
chain: Vec<Box<dyn Transform>>,
|
// chain: Vec<Box<dyn Transform>>,
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl ChainedTransform {
|
// impl ChainedTransform {
|
||||||
pub fn from<T: Transform + Clone + 'static>(transform: &T) -> Self {
|
// pub fn from<T: Transform + Clone + 'static>(transform: &T) -> Self {
|
||||||
let snippet = transform.snippet().clone();
|
// let snippet = transform.snippet().clone();
|
||||||
// let snippet = transform.snippet().to_owned();
|
// // let snippet = transform.snippet().to_owned();
|
||||||
Self {
|
// Self {
|
||||||
snippet,
|
// snippet,
|
||||||
chain: vec![Box::new(transform.clone())],
|
// chain: vec![Box::new(transform.clone())],
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn chain<P: Transform + 'static + Clone>(mut self, other: &P) -> Self {
|
// pub fn chain<P: Transform + 'static + Clone>(mut self, other: &P) -> Self {
|
||||||
let new_snippet = self.snippet.clone().chain(other.snippet().to_owned());
|
// let new_snippet = self.snippet.clone().chain(other.snippet().to_owned());
|
||||||
self.snippet = new_snippet;
|
// self.snippet = new_snippet;
|
||||||
self.chain.push(Box::new(other.clone()));
|
// self.chain.push(Box::new(other.clone()));
|
||||||
self
|
// self
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl Transform for ChainedTransform {
|
// impl Transform for ChainedTransform {
|
||||||
fn snippet(&self) -> &Snippet {
|
// fn snippet(&self) -> &Snippet {
|
||||||
&self.snippet
|
// &self.snippet
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
impl AttaWithProgram for ChainedTransform {
|
// impl AttaWithProgram for ChainedTransform {
|
||||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> super::Result<()> {
|
// fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> super::Result<()> {
|
||||||
for transform in &self.chain {
|
// for transform in &self.chain {
|
||||||
transform.attach_with_program(gl, program)?;
|
// transform.attach_with_program(gl, program)?;
|
||||||
}
|
// }
|
||||||
|
|
||||||
Ok(())
|
// Ok(())
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
pub trait Transform: AttaWithProgram {
|
|
||||||
fn snippet(&self) -> &Snippet;
|
|
||||||
}
|
|
||||||
|
|
||||||
mod test {
|
// mod test {
|
||||||
use super::*;
|
// use super::*;
|
||||||
|
|
||||||
#[test]
|
// #[test]
|
||||||
fn test_transform() {
|
// fn test_transform() {
|
||||||
let polar = polar::Polar::new().unwrap();
|
// let polar = polar::Polar::new().unwrap();
|
||||||
// let trackball = trackball::Trackball::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().prepare_code());
|
||||||
// println!("{}", chained.snippet().call(&vec![]).unwrap());
|
// // println!("{}", chained.snippet().call(&vec![]).unwrap());
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@ -4,8 +4,6 @@ use crate::{
|
|||||||
graphics::AttaWithProgram,
|
graphics::AttaWithProgram,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Transform;
|
|
||||||
|
|
||||||
pub struct Polar {
|
pub struct Polar {
|
||||||
snippet: Snippet,
|
snippet: Snippet,
|
||||||
origin: f32,
|
origin: f32,
|
||||||
@ -15,7 +13,7 @@ impl Polar {
|
|||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let snippets = Snippet::new(
|
let snippets = Snippet::new(
|
||||||
"polar",
|
"polar",
|
||||||
CodeType::<&'static str>::Path("transform/polar.glsl".into()),
|
CodeType::from_path("transform/polar.glsl"),
|
||||||
true,
|
true,
|
||||||
Some("forward".to_string()),
|
Some("forward".to_string()),
|
||||||
)?;
|
)?;
|
||||||
@ -27,12 +25,6 @@ impl Polar {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform for Polar {
|
|
||||||
fn snippet(&self) -> &Snippet {
|
|
||||||
&self.snippet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttaWithProgram for Polar {
|
impl AttaWithProgram for Polar {
|
||||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
use super::Transform;
|
|
||||||
use crate::{
|
use crate::{
|
||||||
components::{CodeType, Program, Snippet},
|
components::{CodeType, Program, Snippet},
|
||||||
errors::*,
|
errors::*,
|
||||||
@ -13,7 +12,7 @@ impl Position {
|
|||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let snippets = Snippet::new(
|
let snippets = Snippet::new(
|
||||||
"position",
|
"position",
|
||||||
CodeType::<&'static str>::Path("transform/position.glsl".into()),
|
CodeType::from_path("transform/position.glsl"),
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
@ -22,12 +21,6 @@ impl Position {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Transform for Position {
|
|
||||||
fn snippet(&self) -> &Snippet {
|
|
||||||
&self.snippet
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AttaWithProgram for Position {
|
impl AttaWithProgram for Position {
|
||||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -2,8 +2,6 @@ use crate::components::{CodeType, Program, Snippet};
|
|||||||
use crate::errors::Result;
|
use crate::errors::Result;
|
||||||
use crate::graphics::AttaWithProgram;
|
use crate::graphics::AttaWithProgram;
|
||||||
|
|
||||||
use super::Transform;
|
|
||||||
|
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
|
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
|
||||||
|
|
||||||
@ -27,7 +25,7 @@ impl TrackballModel {
|
|||||||
count: 0,
|
count: 0,
|
||||||
model: Matrix4::identity(),
|
model: Matrix4::identity(),
|
||||||
renorm_count: 97,
|
renorm_count: 97,
|
||||||
trackball_size: 0.8,
|
trackball_size: 100.0,
|
||||||
x: 0.0,
|
x: 0.0,
|
||||||
y: 0.0,
|
y: 0.0,
|
||||||
theta,
|
theta,
|
||||||
@ -37,7 +35,7 @@ impl TrackballModel {
|
|||||||
trackball
|
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);
|
let q = self.rotate(x, y, dx, dy);
|
||||||
self.rotation *= q;
|
self.rotation *= q;
|
||||||
self.count += 1;
|
self.count += 1;
|
||||||
@ -56,7 +54,7 @@ impl TrackballModel {
|
|||||||
self.theta
|
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);
|
self.set_orientation(theta % 360.0, self.phi % 360.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +62,7 @@ impl TrackballModel {
|
|||||||
self.phi
|
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);
|
self.set_orientation(self.theta % 360.0, phi % 360.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,12 +81,12 @@ impl TrackballModel {
|
|||||||
self.theta = theta;
|
self.theta = theta;
|
||||||
self.phi = phi;
|
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 sine = (0.5 * angle).sin();
|
||||||
let xrot =
|
let xrot =
|
||||||
UnitQuaternion::from_quaternion(Quaternion::new((0.5 * angle).cos(), sine, 0.0, 0.0));
|
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 sine = (0.5 * angle).sin();
|
||||||
let zrot =
|
let zrot =
|
||||||
UnitQuaternion::from_quaternion(Quaternion::new((0.5 * angle).cos(), 0.0, 0.0, sine));
|
UnitQuaternion::from_quaternion(Quaternion::new((0.5 * angle).cos(), 0.0, 0.0, sine));
|
||||||
@ -129,49 +127,27 @@ impl TrackballModel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
// impl Trackball {
|
||||||
pub struct Trackball {
|
// pub fn new() -> Result<Self> {
|
||||||
snippet: Snippet,
|
// let model = TrackballModel::new(0.0, 0.0);
|
||||||
model: TrackballModel,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Trackball {
|
// Ok(Self { model })
|
||||||
pub fn new() -> Result<Self> {
|
// }
|
||||||
let snippets = Snippet::new(
|
|
||||||
"trackball",
|
|
||||||
CodeType::<&'static str>::Path("transform/trackball.glsl".into()),
|
|
||||||
false,
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
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 {
|
// pub fn model(&self) -> &Matrix4<f32> {
|
||||||
snippet: snippets,
|
// self.model.model()
|
||||||
model,
|
// }
|
||||||
})
|
// }
|
||||||
}
|
|
||||||
|
|
||||||
pub fn on_mouse_drag(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
|
impl AttaWithProgram for TrackballModel {
|
||||||
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 {
|
|
||||||
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let l = program.get_uniform_location(gl, "trackball_model");
|
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(())
|
Ok(())
|
||||||
@ -183,6 +159,12 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_trackball() {
|
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();
|
// let trackball = Trackball::new().unwrap();
|
||||||
// println!("{}", trackball.snippet);
|
// println!("{}", trackball.snippet);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ impl Viewport {
|
|||||||
pub fn new() -> Result<Self> {
|
pub fn new() -> Result<Self> {
|
||||||
let snippets = Snippet::new(
|
let snippets = Snippet::new(
|
||||||
"viewport",
|
"viewport",
|
||||||
CodeType::<&'static str>::Path("transform/viewport.glsl".into()),
|
CodeType::from_path("transform/viewport.glsl"),
|
||||||
true,
|
true,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
#![feature(proc_macro_hygiene)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
mod camera;
|
mod camera;
|
||||||
mod components;
|
mod components;
|
||||||
@ -6,6 +7,8 @@ mod errors;
|
|||||||
mod font_manager;
|
mod font_manager;
|
||||||
mod graphics;
|
mod graphics;
|
||||||
mod pg;
|
mod pg;
|
||||||
|
mod setting;
|
||||||
|
mod shaders;
|
||||||
mod support;
|
mod support;
|
||||||
mod ui;
|
mod ui;
|
||||||
mod utils;
|
mod utils;
|
||||||
@ -13,6 +16,9 @@ mod utils;
|
|||||||
use pg::App;
|
use pg::App;
|
||||||
use support::supporter::run;
|
use support::supporter::run;
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
static SETTING: Lazy<setting::Setting> = Lazy::new(|| setting::Setting::new());
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
run(move |gl| App::new(gl).unwrap());
|
run(move |gl| App::new(gl).unwrap());
|
||||||
|
|||||||
@ -5,7 +5,7 @@ use crate::{
|
|||||||
data_loader::Data,
|
data_loader::Data,
|
||||||
errors::*,
|
errors::*,
|
||||||
graphics::{
|
graphics::{
|
||||||
colormap::linear::LinearColormap, ppi::PPI, threed::ThreeD, AttaWithBuffer,
|
colormap::linear::LinearColormap, ppi::PPI, threed::Trackball, AttaWithBuffer,
|
||||||
AttaWithProgram, Graphics,
|
AttaWithProgram, Graphics,
|
||||||
},
|
},
|
||||||
ui::{State, GUI},
|
ui::{State, GUI},
|
||||||
@ -20,7 +20,7 @@ use crate::{
|
|||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use imgui::Ui;
|
use imgui::Ui;
|
||||||
|
|
||||||
use super::app_type::{self, AppType};
|
use super::layout_type::{self, Layout};
|
||||||
use super::{ModulePackage, Programs};
|
use super::{ModulePackage, Programs};
|
||||||
use crate::{font_manager::FontManager, graphics::font::Text};
|
use crate::{font_manager::FontManager, graphics::font::Text};
|
||||||
|
|
||||||
@ -28,30 +28,24 @@ pub struct App<'gl> {
|
|||||||
gl: &'gl GL,
|
gl: &'gl GL,
|
||||||
context: Context<'gl>,
|
context: Context<'gl>,
|
||||||
gui: GUI,
|
gui: GUI,
|
||||||
app_type: AppType<'gl>,
|
layout: Layout<'gl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gl> App<'gl> {
|
impl<'gl> App<'gl> {
|
||||||
pub fn new(gl: &'gl GL) -> Result<Self> {
|
pub fn new(gl: &'gl GL) -> Result<Self> {
|
||||||
let programs = Programs::new(gl).unwrap();
|
let programs = Programs::new(gl).unwrap();
|
||||||
let mut default_state = State::default();
|
let mut default_state = State::default();
|
||||||
|
|
||||||
let mut gui = GUI::new(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);
|
let context = Context::new(gl, Cache::new(), programs);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
gui,
|
gui,
|
||||||
gl,
|
gl,
|
||||||
context,
|
context,
|
||||||
app_type,
|
layout,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init<'a>(&'a mut self) -> AppType {
|
|
||||||
self.gui.apptype(&self.gl)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn prepare(&mut self) {
|
pub fn prepare(&mut self) {
|
||||||
if let Err(e) = self.context.programs.prepare() {
|
if let Err(e) = self.context.programs.prepare() {
|
||||||
error!("prepare failed: {:?}", e);
|
error!("prepare failed: {:?}", e);
|
||||||
@ -67,13 +61,13 @@ impl<'gl> App<'gl> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<'a>(&'a mut self) {
|
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);
|
error!("draw_program failed: {:?}", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_ui<'a>(&'a mut self, ui: &Ui, window: &winit::window::Window, run: &mut bool) {
|
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) {
|
pub fn destroy(&mut self) {
|
||||||
|
|||||||
@ -1,28 +1,70 @@
|
|||||||
use crate::errors::*;
|
|
||||||
use crate::graphics::ty;
|
use crate::graphics::ty;
|
||||||
use crate::pg::{Context, ModulePackage};
|
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::utils::resources::{ManagedResource, RcGlRcFramebuffer, RcGlRcRenderbuffer, GL};
|
||||||
|
use crate::{errors::*, main};
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
|
|
||||||
const RBO_WIDTH: i32 = 1920;
|
const RBO_WIDTH: i32 = 1920;
|
||||||
const RBO_HEIGHT: i32 = 1080;
|
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 {
|
pub struct ViewPort {
|
||||||
renderer_size: [f32; 2],
|
renderer_size: [f32; 2],
|
||||||
main_fbo: RcGlRcFramebuffer,
|
main_fbo: RcGlRcFramebuffer,
|
||||||
_main_rbo: RcGlRcRenderbuffer,
|
_main_rbo: RcGlRcRenderbuffer,
|
||||||
|
_main_depth_rbo: RcGlRcRenderbuffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ViewPort {
|
impl ViewPort {
|
||||||
pub fn new(gl: &GL) -> Self {
|
pub fn new(gl: &GL) -> Self {
|
||||||
let main_fbo: RcGlRcFramebuffer = gl.create_resource_rc();
|
let main_fbo: RcGlRcFramebuffer = gl.create_resource_rc();
|
||||||
let main_rbo: RcGlRcRenderbuffer = 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_fbo.bind(glow::FRAMEBUFFER);
|
||||||
main_rbo.bind(glow::RENDERBUFFER);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
|
// Color Attachment
|
||||||
|
main_rbo.bind(glow::RENDERBUFFER);
|
||||||
gl.renderbuffer_storage(glow::RENDERBUFFER, glow::RGBA8, RBO_WIDTH, RBO_HEIGHT);
|
gl.renderbuffer_storage(glow::RENDERBUFFER, glow::RGBA8, RBO_WIDTH, RBO_HEIGHT);
|
||||||
gl.framebuffer_renderbuffer(
|
gl.framebuffer_renderbuffer(
|
||||||
glow::FRAMEBUFFER,
|
glow::FRAMEBUFFER,
|
||||||
@ -30,12 +72,33 @@ impl ViewPort {
|
|||||||
glow::RENDERBUFFER,
|
glow::RENDERBUFFER,
|
||||||
Some(main_rbo.native()),
|
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_color(1.0, 0.0, 0.0, 1.0);
|
||||||
// gl.clear(glow::COLOR_BUFFER_BIT);
|
// gl.clear(glow::COLOR_BUFFER_BIT);
|
||||||
// 检查帧缓冲是否完整
|
// 检查帧缓冲是否完整
|
||||||
if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE {
|
if gl.check_framebuffer_status(glow::FRAMEBUFFER) != glow::FRAMEBUFFER_COMPLETE {
|
||||||
panic!("Framebuffer is not complete!");
|
panic!("Framebuffer is not complete!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gl.enable(glow::DEPTH_TEST);
|
||||||
}
|
}
|
||||||
main_fbo.unbind(glow::FRAMEBUFFER);
|
main_fbo.unbind(glow::FRAMEBUFFER);
|
||||||
|
|
||||||
@ -43,6 +106,7 @@ impl ViewPort {
|
|||||||
renderer_size: [0.0, 0.0],
|
renderer_size: [0.0, 0.0],
|
||||||
main_fbo,
|
main_fbo,
|
||||||
_main_rbo: main_rbo,
|
_main_rbo: main_rbo,
|
||||||
|
_main_depth_rbo: main_depth_rbo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,70 +140,6 @@ impl ViewPort {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! app_type_into {
|
impl_layout!(
|
||||||
($({$t: ty => $b:tt},)+) => {
|
{MainLoad => MainLoadAttach<'gl>},
|
||||||
$(
|
);
|
||||||
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 => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,17 +1,23 @@
|
|||||||
mod app;
|
mod app;
|
||||||
pub mod app_type;
|
use glow::HasContext;
|
||||||
|
pub mod layout_type;
|
||||||
mod modules;
|
mod modules;
|
||||||
|
|
||||||
use crate::font_manager::FontManager;
|
use crate::font_manager::FontManager;
|
||||||
use crate::graphics::font::Text;
|
use crate::graphics::font::Text;
|
||||||
use crate::graphics::ppi::PPI;
|
use crate::graphics::ppi::PPI;
|
||||||
use crate::graphics::threed::ThreeD;
|
use crate::graphics::threed::Trackball;
|
||||||
use crate::ui::typ::LayoutAppType;
|
use crate::graphics::{AttaWithProgram, AttachWithMouse};
|
||||||
|
use crate::ui::operation::Operation;
|
||||||
|
use crate::ui::typ::LayoutAttach;
|
||||||
use crate::utils::cache::CachedData;
|
use crate::utils::cache::CachedData;
|
||||||
use crate::utils::resources::GL;
|
use crate::utils::resources::GL;
|
||||||
use crate::{errors::*, graphics::Graphics};
|
use crate::{errors::*, graphics::Graphics};
|
||||||
pub use app::{App, Context};
|
pub use app::{App, Context};
|
||||||
pub use modules::{Module, ModuleCursor, ModuleData, PPIModule, PPIPackage};
|
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> {
|
pub(super) struct Programs<'gl> {
|
||||||
gl: &'gl GL,
|
gl: &'gl GL,
|
||||||
@ -69,26 +75,18 @@ impl<'gl> Programs<'gl> {
|
|||||||
pub fn draw_modules(
|
pub fn draw_modules(
|
||||||
&mut self,
|
&mut self,
|
||||||
modules: &mut ModulePackage<'gl>,
|
modules: &mut ModulePackage<'gl>,
|
||||||
init_info: &ThreeD,
|
operation: &Operation<Trackball>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
// if !modules.need_update {
|
|
||||||
// return Ok(());
|
|
||||||
// }
|
|
||||||
match &mut modules.modules {
|
match &mut modules.modules {
|
||||||
_ModulePackage::PPI(ppi) => {
|
_ModulePackage::PPI(ppi) => {
|
||||||
self.ppi().start();
|
self.ppi().start();
|
||||||
self.ppi().init(init_info);
|
self.ppi().render(ppi, operation)?;
|
||||||
self.ppi().render(ppi)?;
|
|
||||||
self.ppi().end();
|
self.ppi().end();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modules.need_update = false;
|
modules.need_update = false;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw<M: LayoutAppType<'gl>>(&mut self, ty: &mut M) -> Result<()> {
|
|
||||||
ty.draw_program(self.gl, self)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum Data<'a> {
|
pub enum Data<'a> {
|
||||||
@ -119,8 +117,6 @@ macro_rules! impl_module_package {
|
|||||||
_ModulePackage::$b(t)
|
_ModulePackage::$b(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
)+
|
)+
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -130,7 +126,8 @@ impl_module_data!({
|
|||||||
});
|
});
|
||||||
|
|
||||||
pub struct ModulePackage<'gl> {
|
pub struct ModulePackage<'gl> {
|
||||||
need_update: bool,
|
id: usize,
|
||||||
|
pub need_update: bool,
|
||||||
modules: _ModulePackage<'gl>,
|
modules: _ModulePackage<'gl>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,19 +145,27 @@ where
|
|||||||
{
|
{
|
||||||
fn from(t: T) -> Self {
|
fn from(t: T) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
id: MODULE_PACKAGE_ID.fetch_add(1, std::sync::atomic::Ordering::SeqCst),
|
||||||
modules: t.into(),
|
modules: t.into(),
|
||||||
need_update: true,
|
need_update: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModulePackage<'_> {
|
impl PartialEq for ModulePackage<'_> {
|
||||||
pub fn ui_build(&mut self, ui: &imgui::Ui) -> Result<()> {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
match &mut self.modules {
|
self.id == other.id
|
||||||
_ModulePackage::PPI(ppi) => {
|
}
|
||||||
ppi.ui_build(ui);
|
}
|
||||||
}
|
|
||||||
}
|
impl ModulePackage<'_> {
|
||||||
Ok(())
|
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::{
|
||||||
cache::CachedData,
|
graphics::AttachWithMouse,
|
||||||
resources::{ManagedResource, RcGlBuffer, RcGlVertexArray},
|
ui::{
|
||||||
|
operation::{self, Operation},
|
||||||
|
typ::CameraOP,
|
||||||
|
},
|
||||||
|
utils::{
|
||||||
|
cache::CachedData,
|
||||||
|
resources::{ManagedResource, RcGlBuffer, RcGlVertexArray},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
||||||
mod ppi;
|
mod ppi;
|
||||||
@ -63,14 +70,18 @@ impl<'a> Attach<'a> {
|
|||||||
pub trait Module: Sized {
|
pub trait Module: Sized {
|
||||||
type Cursor: ModuleCursor;
|
type Cursor: ModuleCursor;
|
||||||
type Data;
|
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 resize(&self, size: [f32; 2]);
|
||||||
fn destroy(&self);
|
fn destroy(&self);
|
||||||
|
|
||||||
fn start(&mut 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 end(&mut self);
|
||||||
fn load_data<'dt>(&self, data: &CachedData<Self::Data>) -> Result<Self::Cursor>;
|
fn load_data<'dt>(&self, data: &CachedData<Self::Data>) -> Result<Self::Cursor>;
|
||||||
}
|
}
|
||||||
@ -88,5 +99,5 @@ pub trait ModuleCursor {
|
|||||||
where
|
where
|
||||||
F: FnOnce(&mut Self::Config);
|
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 std::rc::Rc;
|
||||||
use tracker::track;
|
use tracker::track;
|
||||||
|
|
||||||
|
use crate::graphics::{font::Text, *};
|
||||||
|
use crate::ui::operation::{self, Operation};
|
||||||
|
use crate::SETTING;
|
||||||
use crate::{
|
use crate::{
|
||||||
data_loader::Data,
|
data_loader::Data,
|
||||||
errors::*,
|
errors::*,
|
||||||
@ -10,9 +13,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use imgui::VerticalSlider;
|
use imgui::VerticalSlider;
|
||||||
use ppi::{PPIConfig, PPI};
|
use ppi::{PPIConfig, PPI};
|
||||||
use threed::ThreeD;
|
use threed::Trackball;
|
||||||
|
|
||||||
use crate::graphics::{font::Text, *};
|
|
||||||
|
|
||||||
use super::{Attach, Module, ModuleCursor};
|
use super::{Attach, Module, ModuleCursor};
|
||||||
pub struct PPIModule<'b, 'a: 'b> {
|
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(
|
let (vbo, ebo, len) = self.ppi_program.bake(
|
||||||
data,
|
data,
|
||||||
&PPIConfig {
|
&PPIConfig {
|
||||||
|
unvalid_value: config.unvalid_value,
|
||||||
|
color_range: config.color_range,
|
||||||
|
colors: config.colors.clone(),
|
||||||
layer: config.layer,
|
layer: config.layer,
|
||||||
rdpi: config.rdpi,
|
rdpi: config.rdpi,
|
||||||
adpi: config.adpi,
|
adpi: config.adpi,
|
||||||
|
three_d: config.is_three_d,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len);
|
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> {
|
impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
||||||
type Cursor = PPIPackage<'a>;
|
type Cursor = PPIPackage<'a>;
|
||||||
type Data = Data;
|
type Data = Data;
|
||||||
type InitInfo = ThreeD;
|
type Operation = Trackball;
|
||||||
|
|
||||||
fn start(&mut self) {
|
fn start(&mut self) {
|
||||||
self.ppi_program.mount(&self.gl).unwrap();
|
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();
|
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 attach = &mut cursor.ppi_attach;
|
||||||
let data = &cursor.ppi_data.borrow();
|
let data = &cursor.ppi_data.borrow();
|
||||||
let config = &mut cursor.ppi_config;
|
let config = &mut cursor.ppi_config;
|
||||||
|
|
||||||
self.ppi_program.set_config(
|
self.ppi_program.set_config(
|
||||||
&self.gl,
|
&self.gl,
|
||||||
&PPIConfig {
|
&PPIConfig {
|
||||||
|
unvalid_value: config.unvalid_value,
|
||||||
|
color_range: config.color_range,
|
||||||
|
colors: config.colors.clone(),
|
||||||
layer: config.layer,
|
layer: config.layer,
|
||||||
rdpi: config.rdpi,
|
rdpi: config.rdpi,
|
||||||
adpi: config.adpi,
|
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 (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
|
||||||
let mut attach = Attach::new(&self.gl, vao, vbo, ebo, None);
|
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 {
|
let config = PPIModuleConfig {
|
||||||
|
color_range: cmap.value_range(),
|
||||||
|
colors: cmap.color()?,
|
||||||
layer: 0,
|
layer: 0,
|
||||||
rdpi: r,
|
rdpi: r,
|
||||||
adpi: a,
|
adpi: a,
|
||||||
|
max_layer,
|
||||||
|
unvalid_value: unvalid,
|
||||||
|
is_three_d: true,
|
||||||
tracker: 0,
|
tracker: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -104,16 +133,19 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
|
|
||||||
Ok(PPIPackage::new(config, attach, data))
|
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]
|
#[track]
|
||||||
|
#[derive(PartialEq)]
|
||||||
pub struct PPIModuleConfig {
|
pub struct PPIModuleConfig {
|
||||||
pub layer: usize,
|
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]
|
#[do_not_track]
|
||||||
pub rdpi: f32,
|
pub rdpi: f32,
|
||||||
#[do_not_track]
|
#[do_not_track]
|
||||||
@ -148,12 +180,17 @@ impl<'gl> ModuleCursor for PPIPackage<'gl> {
|
|||||||
f(&mut self.ppi_config);
|
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 layer = self.ppi_config.layer;
|
||||||
|
let mut is_three_d = self.ppi_config.is_three_d;
|
||||||
|
|
||||||
ui.text("PPI Data Config");
|
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();
|
ui.separator();
|
||||||
|
|
||||||
self.ppi_config.set_layer(layer);
|
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 glow::HasContext;
|
||||||
use glutin::{
|
use glutin::{
|
||||||
@ -7,6 +7,7 @@ use glutin::{
|
|||||||
display::{GetGlDisplay, GlDisplay},
|
display::{GetGlDisplay, GlDisplay},
|
||||||
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
|
surface::{GlSurface, Surface, SurfaceAttributesBuilder, WindowSurface},
|
||||||
};
|
};
|
||||||
|
use imgui::FontConfig;
|
||||||
use imgui_winit_support::{
|
use imgui_winit_support::{
|
||||||
winit::{
|
winit::{
|
||||||
dpi::LogicalSize,
|
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);
|
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
|
imgui_context
|
||||||
.fonts()
|
.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());
|
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 io = ui.io();
|
||||||
|
|
||||||
let delta = if ui.is_mouse_dragging(imgui::MouseButton::Left) {
|
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 {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let windows_position = ui.window_pos();
|
||||||
|
|
||||||
IO {
|
IO {
|
||||||
mouse: MouseIO {
|
mouse: MouseIO {
|
||||||
position: io.mouse_pos,
|
position: [
|
||||||
|
io.mouse_pos[0] - windows_position[0],
|
||||||
|
io.mouse_pos[1] - windows_position[1],
|
||||||
|
],
|
||||||
drag_delta: delta,
|
drag_delta: delta,
|
||||||
is_dragging: ui.is_mouse_dragging(imgui::MouseButton::Left),
|
is_dragging: ui.is_mouse_dragging(imgui::MouseButton::Left),
|
||||||
left_button_pressed: io.mouse_down[0],
|
left_button_pressed: io.mouse_down[0],
|
||||||
|
|||||||
@ -4,7 +4,7 @@ use log::*;
|
|||||||
|
|
||||||
use crate::data_loader::Data;
|
use crate::data_loader::Data;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::pg::app_type::AppType;
|
use crate::pg::layout_type::Layout;
|
||||||
use crate::pg::{ModulePackage, Programs};
|
use crate::pg::{ModulePackage, Programs};
|
||||||
use crate::utils::cache::Cache;
|
use crate::utils::cache::Cache;
|
||||||
use crate::utils::resources::{RcGlRcFramebuffer, RcGlRcRenderbuffer, RcGlRcResource, GL};
|
use crate::utils::resources::{RcGlRcFramebuffer, RcGlRcRenderbuffer, RcGlRcResource, GL};
|
||||||
@ -18,10 +18,11 @@ mod state;
|
|||||||
pub mod typ;
|
pub mod typ;
|
||||||
pub use layout::*;
|
pub use layout::*;
|
||||||
pub use state::State;
|
pub use state::State;
|
||||||
|
pub mod operation;
|
||||||
|
|
||||||
pub struct GUI {
|
pub struct GUI {
|
||||||
state: State,
|
state: State,
|
||||||
layout: layout::Layout,
|
layout_manager: layout::Layout,
|
||||||
renderer_size: [f32; 2],
|
renderer_size: [f32; 2],
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29,12 +30,12 @@ impl GUI {
|
|||||||
pub fn new(state: State) -> Self {
|
pub fn new(state: State) -> Self {
|
||||||
GUI {
|
GUI {
|
||||||
state,
|
state,
|
||||||
layout: layout::Layout::new(),
|
layout_manager: layout::Layout::new(),
|
||||||
renderer_size: [0.0, 0.0],
|
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)
|
self.state.app_type.init_apptype(gl)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,22 +43,22 @@ impl GUI {
|
|||||||
&mut self,
|
&mut self,
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
context: &'b mut crate::pg::Context<'gl>,
|
context: &'b mut crate::pg::Context<'gl>,
|
||||||
app_type: &'b mut AppType<'gl>,
|
layout_atta: &'b mut Layout<'gl>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Menu bar
|
// Menu bar
|
||||||
self.menu_bar(ui, context, app_type);
|
self.menu_bar(ui, context, layout_atta);
|
||||||
let menu_bar_height = ui.frame_height();
|
let menu_bar_height = ui.frame_height();
|
||||||
let display_size = ui.io().display_size;
|
let display_size = ui.io().display_size;
|
||||||
|
|
||||||
// Layout Size Reset
|
// Layout Size Reset
|
||||||
self.layout.set_origin([0.0, menu_bar_height]);
|
self.layout_manager.set_origin([0.0, menu_bar_height]);
|
||||||
self.layout
|
self.layout_manager
|
||||||
.set_size([display_size[0], display_size[1] - menu_bar_height]);
|
.set_size([display_size[0], display_size[1] - menu_bar_height]);
|
||||||
|
|
||||||
// Render
|
// Render
|
||||||
self.state
|
self.state
|
||||||
.app_type
|
.app_type
|
||||||
.render(ui, context, &mut self.layout, app_type);
|
.render(ui, context, &mut self.layout_manager, layout_atta);
|
||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
@ -66,7 +67,7 @@ impl GUI {
|
|||||||
&self,
|
&self,
|
||||||
ui: &Ui,
|
ui: &Ui,
|
||||||
context: &'b mut crate::pg::Context<'gl>,
|
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(top_menu) = ui.begin_main_menu_bar() {
|
||||||
if let Some(menu) = ui.begin_menu("File") {
|
if let Some(menu) = ui.begin_menu("File") {
|
||||||
@ -75,7 +76,7 @@ impl GUI {
|
|||||||
Some(file) => match context.load_data(file.clone()) {
|
Some(file) => match context.load_data(file.clone()) {
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
info!("Data loaded: {:?}", file);
|
info!("Data loaded: {:?}", file);
|
||||||
app_type.deal_with_cursor(data);
|
layout_atta.append_package(data);
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
error!("Failed to get or insert data: {:?}", 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,
|
ui: &imgui::Ui,
|
||||||
context: &mut crate::pg::Context<'gl>,
|
context: &mut crate::pg::Context<'gl>,
|
||||||
layout: &mut crate::ui::layout::Layout,
|
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 gl = context.gl;
|
||||||
let app_typ = app_typ.into();
|
let app_typ = app_typ.into();
|
||||||
uit!(self, {Mainload => render(ui,context,layout,app_typ)},);
|
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()
|
uit!(self, {Mainload => init(gl)},).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,26 +1,32 @@
|
|||||||
use super::{CameraOP, Layout, LayoutAppType, LayoutMod, Size};
|
use std::thread::panicking;
|
||||||
use crate::graphics::threed::ThreeD;
|
|
||||||
|
use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size};
|
||||||
|
use crate::camera::Camera;
|
||||||
|
use crate::graphics::threed::Trackball;
|
||||||
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
|
use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState};
|
||||||
use crate::pg::ModulePackage;
|
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::io::IO;
|
||||||
|
use crate::ui::operation::Operation;
|
||||||
use crate::utils::resources::GL;
|
use crate::utils::resources::GL;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use imgui::{Condition, Ui, WindowFlags};
|
use imgui::{Condition, Ui, WindowFlags};
|
||||||
|
use nalgebra_glm::Vec3;
|
||||||
|
|
||||||
pub struct MainLoad {}
|
pub struct MainLoad {}
|
||||||
|
|
||||||
impl LayoutMod for MainLoad {
|
impl LayoutMod for MainLoad {
|
||||||
type AppType<'gl> = MainLoadTyp<'gl>;
|
type Attach<'gl> = MainLoadAttach<'gl>;
|
||||||
fn render<'b, 'gl>(
|
fn render<'b, 'gl>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ui: &imgui::Ui,
|
ui: &imgui::Ui,
|
||||||
context: &mut crate::pg::Context<'gl>,
|
context: &mut crate::pg::Context<'gl>,
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
apptyp: &mut Self::AppType<'gl>,
|
apptyp: &mut Self::Attach<'gl>,
|
||||||
) where
|
) where
|
||||||
'gl: 'b,
|
'gl: 'b,
|
||||||
{
|
{
|
||||||
|
let mut changed = true;
|
||||||
let mut grid = layout.grid(2, 1, [0.0, 0.0]);
|
let mut grid = layout.grid(2, 1, [0.0, 0.0]);
|
||||||
grid.set_col_size(&[size!(20.0%), size!(fill)]);
|
grid.set_col_size(&[size!(20.0%), size!(fill)]);
|
||||||
grid.set_row_size(&[size!(fill)]);
|
grid.set_row_size(&[size!(fill)]);
|
||||||
@ -35,8 +41,27 @@ impl LayoutMod for MainLoad {
|
|||||||
grid.with(0, 0, [1, 1])
|
grid.with(0, 0, [1, 1])
|
||||||
.start_window(ui, "MainLoad")
|
.start_window(ui, "MainLoad")
|
||||||
.build(|| {
|
.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() {
|
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,48 +83,68 @@ impl LayoutMod for MainLoad {
|
|||||||
|
|
||||||
// ui.set_cursor_screen_pos([pos[0] + size[0], pos[1] + size[1]]);
|
// ui.set_cursor_screen_pos([pos[0] + size[0], pos[1] + size[1]]);
|
||||||
let draws = ui.get_window_draw_list();
|
let draws = ui.get_window_draw_list();
|
||||||
let fbo = apptyp.main_viewport.fbo();
|
|
||||||
let fbo = fbo.native();
|
|
||||||
|
|
||||||
draws
|
draws.channels_split(2, |channels| {
|
||||||
.add_callback({
|
channels.set_current(0);
|
||||||
move || unsafe {
|
let fbo = apptyp.main_viewport.fbo();
|
||||||
let x = pos[0] * scale[0];
|
let fbo = fbo.native();
|
||||||
let y = (dsp_size[1] - pos[1]) * scale[1];
|
|
||||||
|
|
||||||
// gl.enable(glow::SCISSOR_TEST);
|
draws
|
||||||
// gl.scissor(0, 0, size[0] as i32, size[1] as i32);
|
.add_callback({
|
||||||
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(fbo));
|
move || unsafe {
|
||||||
gl.blit_framebuffer(
|
let x = pos[0] * scale[0];
|
||||||
0,
|
let y = (dsp_size[1] - pos[1]) * scale[1];
|
||||||
0,
|
|
||||||
(content_size[0]) as i32,
|
// gl.enable(glow::SCISSOR_TEST);
|
||||||
(content_size[1]) as i32,
|
// gl.scissor(0, 0, size[0] as i32, size[1] as i32);
|
||||||
x as i32,
|
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(fbo));
|
||||||
y as i32,
|
gl.blit_framebuffer(
|
||||||
(x + content_size[0] * scale[0]) as i32,
|
0,
|
||||||
(y - content_size[1] * scale[1]) as i32,
|
0,
|
||||||
glow::COLOR_BUFFER_BIT,
|
(content_size[0]) as i32,
|
||||||
glow::NEAREST,
|
(content_size[1]) as i32,
|
||||||
);
|
x as i32,
|
||||||
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
|
y as i32,
|
||||||
}
|
(x + content_size[0] * scale[0]) as i32,
|
||||||
})
|
(y - content_size[1] * scale[1]) as i32,
|
||||||
.build();
|
glow::COLOR_BUFFER_BIT,
|
||||||
|
glow::NEAREST,
|
||||||
|
);
|
||||||
|
gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.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() {
|
if ui.is_window_hovered() {
|
||||||
let cio = IO::new(ui);
|
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> {
|
fn init<'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl> {
|
||||||
let typ = MainLoadTyp {
|
let typ = MainLoadAttach {
|
||||||
main_viewport: ViewPort::new(gl),
|
main_viewport: ViewPort::new(gl),
|
||||||
packages: Vec::new(),
|
packages: Vec::new(),
|
||||||
camera_op: ThreeD::default(),
|
operation: Operation::new(Trackball::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0),
|
||||||
};
|
};
|
||||||
typ
|
typ
|
||||||
}
|
}
|
||||||
@ -109,13 +154,11 @@ impl MainLoad {
|
|||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
MainLoad {}
|
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,
|
main_viewport: ViewPort,
|
||||||
camera_op: ThreeD,
|
|
||||||
packages: Vec<ModulePackage<'gl>>,
|
packages: Vec<ModulePackage<'gl>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,32 +170,42 @@ impl CameraOP for MouseState {
|
|||||||
delta: context.mouse.drag_delta.unwrap(),
|
delta: context.mouse.drag_delta.unwrap(),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Self::None
|
if context.mouse.wheel_delta != 0.0 {
|
||||||
|
Self::Wheel(context.mouse.wheel_delta)
|
||||||
|
} else {
|
||||||
|
Self::None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'gl> LayoutAppType<'gl> for MainLoadTyp<'gl> {
|
impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> {
|
||||||
type CameraOP = MouseState;
|
fn append(&mut self, package: ModulePackage<'gl>) {
|
||||||
fn deal_with_cursor(&mut self, package: ModulePackage<'gl>) {
|
|
||||||
self.packages.push(package);
|
self.packages.push(package);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_program(
|
fn render_task(
|
||||||
&mut self,
|
&mut self,
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
programs: &mut crate::pg::Programs<'gl>,
|
programs: &mut crate::pg::Programs<'gl>,
|
||||||
) -> crate::errors::Result<()> {
|
) -> crate::errors::Result<()> {
|
||||||
self.main_viewport.bind(gl);
|
self.main_viewport.bind(gl);
|
||||||
for package in self.packages.iter_mut() {
|
if self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update() {
|
||||||
programs.draw_modules(package, &self.camera_op)?;
|
unsafe {
|
||||||
|
gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
for package in self.packages.iter_mut() {
|
||||||
|
programs.draw_modules(package, &self.operation)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.packages.is_empty() {
|
||||||
|
unsafe {
|
||||||
|
gl.clear(glow::COLOR_BUFFER_BIT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.main_viewport.unbind();
|
self.main_viewport.unbind();
|
||||||
Ok(())
|
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::io::IO;
|
||||||
use super::layout::{Layout, Size};
|
use super::layout::{Layout, Size};
|
||||||
mod main_load;
|
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::pg::{self, ModuleCursor, ModulePackage, Programs};
|
||||||
use crate::utils::resources::GL;
|
use crate::utils::resources::GL;
|
||||||
pub use main_load::*;
|
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 {
|
pub trait LayoutMod {
|
||||||
type AppType<'gl>: Into<AppType<'gl>> + LayoutAppType<'gl>;
|
type Attach<'gl>: Into<_Layout<'gl>> + LayoutAttach<'gl>;
|
||||||
fn render<'dt, 'b, 'gl>(
|
fn render<'dt, 'b, 'gl>(
|
||||||
&mut self,
|
&mut self,
|
||||||
ui: &imgui::Ui,
|
ui: &imgui::Ui,
|
||||||
context: &mut crate::pg::Context<'gl>,
|
context: &mut crate::pg::Context<'gl>,
|
||||||
layout: &mut Layout,
|
layout: &mut Layout,
|
||||||
apptyp: &mut Self::AppType<'gl>,
|
apptyp: &mut Self::Attach<'gl>,
|
||||||
) where
|
) where
|
||||||
'gl: 'b;
|
'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> {
|
pub trait LayoutAttach<'gl> {
|
||||||
type CameraOP: CameraOP + Debug;
|
fn append(&mut self, package: ModulePackage<'gl>);
|
||||||
fn deal_with_cursor(&mut self, package: ModulePackage<'gl>);
|
|
||||||
|
|
||||||
fn deal_with_camera(&mut self, camera_op: &IO) {
|
fn render_task(
|
||||||
self._deal_with_camera(CameraOP::from_context(camera_op));
|
|
||||||
}
|
|
||||||
|
|
||||||
fn _deal_with_camera(&mut self, camera_op: Self::CameraOP);
|
|
||||||
|
|
||||||
fn draw_program(
|
|
||||||
&mut self,
|
&mut self,
|
||||||
gl: &glow::Context,
|
gl: &glow::Context,
|
||||||
programs: &mut Programs<'gl>,
|
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;
|
mod parser;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
use include_dir::{include_dir, Dir};
|
use include_dir::{include_dir, Dir};
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user