sync
This commit is contained in:
parent
129732cd7e
commit
0836c004eb
@ -1,12 +1,13 @@
|
|||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use bytemuck::{Pod, Zeroable};
|
use bytemuck::{Pod, Zeroable};
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeTexture, NativeVertexArray};
|
||||||
|
|
||||||
use crate::components::{Program, Shader};
|
use crate::components::{Program, Shader};
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
use crate::graphics::ty::Ty;
|
use crate::graphics::ty::Ty;
|
||||||
use crate::graphics::{AttaWithBuffer, Graphics};
|
use crate::graphics::{AttaWithBuffer, Graphics};
|
||||||
|
use crate::pg::Attach;
|
||||||
use crate::shaders::agg_path::{AggPathFragment, AggPathVertex};
|
use crate::shaders::agg_path::{AggPathFragment, AggPathVertex};
|
||||||
|
|
||||||
use super::Colletion;
|
use super::Colletion;
|
||||||
@ -129,7 +130,8 @@ impl AttaWithBuffer for AggFastPath {
|
|||||||
gl: &'gl glow::Context,
|
gl: &'gl glow::Context,
|
||||||
data: &Self::Data,
|
data: &Self::Data,
|
||||||
config: &<Self as Graphics>::Config,
|
config: &<Self as Graphics>::Config,
|
||||||
) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
attach: &mut Attach,
|
||||||
|
) -> Result<()> {
|
||||||
let points = data.iter().map(|v| &v.points).flatten().collect::<Vec<_>>();
|
let points = data.iter().map(|v| &v.points).flatten().collect::<Vec<_>>();
|
||||||
|
|
||||||
let mut lens = Vec::with_capacity(data.len());
|
let mut lens = Vec::with_capacity(data.len());
|
||||||
@ -156,10 +158,19 @@ impl AttaWithBuffer for AggFastPath {
|
|||||||
|
|
||||||
let len = ebo.len() as i32;
|
let len = ebo.len() as i32;
|
||||||
|
|
||||||
Ok((vbo, Some(ebo), len))
|
attach.bind_data(&vbo, Some(&ebo), len, glow::STATIC_DRAW);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>) {
|
fn init(
|
||||||
|
&self,
|
||||||
|
gl: &glow::Context,
|
||||||
|
) -> (
|
||||||
|
NativeVertexArray,
|
||||||
|
NativeBuffer,
|
||||||
|
Option<NativeBuffer>,
|
||||||
|
Option<NativeTexture>,
|
||||||
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let vao = gl.create_vertex_array().unwrap();
|
let vao = gl.create_vertex_array().unwrap();
|
||||||
gl.bind_vertex_array(Some(vao));
|
gl.bind_vertex_array(Some(vao));
|
||||||
@ -183,7 +194,7 @@ impl AttaWithBuffer for AggFastPath {
|
|||||||
gl.bind_vertex_array(None);
|
gl.bind_vertex_array(None);
|
||||||
|
|
||||||
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||||
(vao, vbo, Some(ebo))
|
(vao, vbo, Some(ebo), None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -108,9 +108,6 @@ impl ColorMap for LinearColormap {
|
|||||||
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 location = program.get_uniform_location(gl, "colormap");
|
let location = program.get_uniform_location(gl, "colormap");
|
||||||
|
|
||||||
let error = gl.get_error();
|
|
||||||
|
|
||||||
gl.uniform_1_i32(location.as_ref(), 0);
|
gl.uniform_1_i32(location.as_ref(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -289,19 +289,29 @@ impl Graphics for Text {
|
|||||||
impl AttaWithBuffer for Text {
|
impl AttaWithBuffer for Text {
|
||||||
type Data = PositionText;
|
type Data = PositionText;
|
||||||
|
|
||||||
|
// fn bake<'a, 'gl: 'a>(
|
||||||
|
// &'a self,
|
||||||
|
// gl: &'gl glow::Context,
|
||||||
|
// data: &Self::Data,
|
||||||
|
// config: &<Self as Graphics>::Config,
|
||||||
|
// ) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
fn bake<'a, 'gl: 'a>(
|
fn bake<'a, 'gl: 'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
gl: &'gl glow::Context,
|
gl: &'gl glow::Context,
|
||||||
data: &Self::Data,
|
data: &Self::Data,
|
||||||
config: &<Self as Graphics>::Config,
|
config: &<Self as Graphics>::Config,
|
||||||
) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
attach: &mut crate::pg::Attach,
|
||||||
|
) -> Result<()> {
|
||||||
let v = data.bake(
|
let v = data.bake(
|
||||||
&self.gl,
|
&self.gl,
|
||||||
&mut *self.font_manager.borrow_mut(),
|
&mut *self.font_manager.borrow_mut(),
|
||||||
&mut *self.cache.borrow_mut(),
|
&mut *self.cache.borrow_mut(),
|
||||||
)?;
|
)?;
|
||||||
|
attach.bind_data(&v.vertex(), None, v.len() as i32, glow::STATIC_DRAW);
|
||||||
Ok((v.vertex(), None, v.len() as i32))
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init(
|
fn init(
|
||||||
@ -311,6 +321,7 @@ impl AttaWithBuffer for Text {
|
|||||||
glow::NativeVertexArray,
|
glow::NativeVertexArray,
|
||||||
glow::NativeBuffer,
|
glow::NativeBuffer,
|
||||||
Option<glow::NativeBuffer>,
|
Option<glow::NativeBuffer>,
|
||||||
|
Option<NativeTexture>,
|
||||||
) {
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let vao = gl.create_vertex_array().unwrap();
|
let vao = gl.create_vertex_array().unwrap();
|
||||||
@ -326,7 +337,7 @@ impl AttaWithBuffer for Text {
|
|||||||
gl.bind_vertex_array(None);
|
gl.bind_vertex_array(None);
|
||||||
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||||
|
|
||||||
(vao, vbo, None)
|
(vao, vbo, None, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
385
gi/src/graphics/geoquadmesh.rs
Normal file
385
gi/src/graphics/geoquadmesh.rs
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
use glow::HasContext;
|
||||||
|
use radarg_core::{CoordType, ProbeDataType, RadarGridData};
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
components::{Program, Shader},
|
||||||
|
errors::*,
|
||||||
|
pg::Attach,
|
||||||
|
shaders::geoquadmesh::{GeoQuadMeshFragment, GeoQuadMeshVertex},
|
||||||
|
};
|
||||||
|
|
||||||
|
use super::{
|
||||||
|
colormap::{linear::LinearColormap, ColorMap},
|
||||||
|
AttaWithBuffer, Graphics,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub struct GeoQuadMesh {
|
||||||
|
program: Program,
|
||||||
|
cmap: LinearColormap,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeoQuadMesh {
|
||||||
|
pub fn new() -> Result<Self> {
|
||||||
|
let vertex = Shader::new(glow::VERTEX_SHADER, GeoQuadMeshVertex::new())?;
|
||||||
|
let fragment = Shader::new(glow::FRAGMENT_SHADER, GeoQuadMeshFragment::new())?;
|
||||||
|
let program = Program::new(vertex, fragment, None, "330 core");
|
||||||
|
|
||||||
|
let mut cmap = LinearColormap::new()?;
|
||||||
|
Ok(Self { program, cmap })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_conf(&mut self, gl: &glow::Context, config: &GeoQuadMeshConfig) {
|
||||||
|
let lon_dpi = config.lon_dpi;
|
||||||
|
let lat_dpi = config.lat_dpi;
|
||||||
|
let alt_dpi = config.alt_dpi;
|
||||||
|
|
||||||
|
let location = self.program.get_uniform_location(gl, "data_info");
|
||||||
|
|
||||||
|
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);
|
||||||
|
let location_r = self.program.get_uniform_location(gl, "R");
|
||||||
|
let location_layer = self.program.get_uniform_location(gl, "layer");
|
||||||
|
let tex_conf = self.program.get_uniform_location(gl, "tex_conf");
|
||||||
|
|
||||||
|
unsafe {
|
||||||
|
gl.uniform_1_f32(location_r.as_ref(), 6378137.0);
|
||||||
|
gl.uniform_4_f32(location.as_ref(), lon_dpi, lat_dpi, alt_dpi, 0.0);
|
||||||
|
gl.uniform_1_f32(location_layer.as_ref(), config.layer as f32);
|
||||||
|
|
||||||
|
let lon_s = config.lon_range[0];
|
||||||
|
let lon_e = config.lon_range[1];
|
||||||
|
let lat_s = config.lat_range[0];
|
||||||
|
let lat_e = config.lat_range[1];
|
||||||
|
gl.uniform_4_f32(tex_conf.as_ref(), lon_s, lon_e, lat_s, lat_e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn program(&mut self) -> &mut Program {
|
||||||
|
&mut self.program
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn data_info(
|
||||||
|
&self,
|
||||||
|
data: &RadarGridData,
|
||||||
|
) -> Result<(
|
||||||
|
Option<[f32; 2]>,
|
||||||
|
[f32; 2],
|
||||||
|
[f32; 2],
|
||||||
|
[f32; 3],
|
||||||
|
ProbeDataType,
|
||||||
|
)> {
|
||||||
|
if data.coord_type().is_none() {
|
||||||
|
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||||
|
}
|
||||||
|
match data.coord_type().unwrap() {
|
||||||
|
CoordType::Cartesian { hgt, lat, lon } => {
|
||||||
|
let lat_start = *lat.first().unwrap() as f32;
|
||||||
|
let lat_end = *lat.last().unwrap() as f32;
|
||||||
|
let lon_start = *lon.first().unwrap() as f32;
|
||||||
|
let lon_end = *lon.last().unwrap() as f32;
|
||||||
|
|
||||||
|
let lat_dpi = (lat[1] - lat[0]);
|
||||||
|
let lon_dpi = (lon[1] - lon[0]);
|
||||||
|
|
||||||
|
let (hgt_range, alt_dpi) = if let Some(ref hgt) = hgt {
|
||||||
|
let hgt_start = *hgt.first().unwrap() as f32;
|
||||||
|
let hgt_end = *hgt.last().unwrap() as f32;
|
||||||
|
let alt_dpi = (hgt[1] - hgt[0]);
|
||||||
|
(Some([hgt_start, hgt_end]), alt_dpi)
|
||||||
|
} else {
|
||||||
|
(None, 0.0)
|
||||||
|
};
|
||||||
|
|
||||||
|
let data_type = data.data_type();
|
||||||
|
Ok((
|
||||||
|
hgt_range,
|
||||||
|
[lat_start, lat_end],
|
||||||
|
[lon_start, lon_end],
|
||||||
|
[alt_dpi as f32, lat_dpi as f32, lon_dpi as f32],
|
||||||
|
data_type,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
_ => Err(Error::InvalidDataType(format!("Invalid CoordType"))),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct GeoQuadMeshConfig {
|
||||||
|
pub unvalid_value: f32,
|
||||||
|
pub layer: usize,
|
||||||
|
pub colors: Vec<[u8; 4]>,
|
||||||
|
pub color_range: [f32; 2],
|
||||||
|
pub lon_dpi: f32,
|
||||||
|
pub lat_dpi: f32,
|
||||||
|
pub alt_dpi: f32,
|
||||||
|
pub lat_range: [f32; 2],
|
||||||
|
pub lon_range: [f32; 2],
|
||||||
|
pub alt_range: [f32; 2],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Graphics for GeoQuadMesh {
|
||||||
|
const id: &'static str = "geoquadmesh";
|
||||||
|
type Config = GeoQuadMeshConfig;
|
||||||
|
|
||||||
|
fn compile(&mut self, gl: &glow::Context) -> Result<()> {
|
||||||
|
self.program.compile(gl)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn destroy(&mut self, gl: &glow::Context) -> Result<()> {
|
||||||
|
self.program.destroy(gl);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
|
||||||
|
unsafe {
|
||||||
|
gl.draw_arrays(glow::TRIANGLE_STRIP_ADJACENCY, 0, count);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
|
unsafe {
|
||||||
|
gl.use_program(self.program.native_program);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn unmount(&self, gl: &glow::Context) -> Result<()> {
|
||||||
|
unsafe {
|
||||||
|
gl.use_program(None);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn program_mut(&mut self) -> &mut Program {
|
||||||
|
&mut self.program
|
||||||
|
}
|
||||||
|
|
||||||
|
fn program_ref(&self) -> &Program {
|
||||||
|
&self.program
|
||||||
|
}
|
||||||
|
|
||||||
|
fn set_config(&mut self, gl: &glow::Context, config: &Self::Config) -> Result<()> {
|
||||||
|
self.set_conf(gl, config);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AttaWithBuffer for GeoQuadMesh {
|
||||||
|
type Data = RadarGridData;
|
||||||
|
|
||||||
|
fn bake<'a, 'gl: 'a>(
|
||||||
|
&'a self,
|
||||||
|
gl: &'gl glow::Context,
|
||||||
|
data: &Self::Data,
|
||||||
|
config: &<Self as Graphics>::Config,
|
||||||
|
attach: &mut Attach,
|
||||||
|
) -> Result<()> {
|
||||||
|
if let Some(coord_type) = data.coord_type() {
|
||||||
|
if let CoordType::Cartesian { hgt, lat, lon } = coord_type {
|
||||||
|
let mut vertices = Vec::with_capacity(12);
|
||||||
|
let lat_start = *lat.first().unwrap() as f32;
|
||||||
|
let lat_end = *lat.last().unwrap() as f32;
|
||||||
|
let lon_start = *lon.first().unwrap() as f32;
|
||||||
|
let lon_end = *lon.last().unwrap() as f32;
|
||||||
|
|
||||||
|
let start = mercator_project([lon_start, lat_start]);
|
||||||
|
let end = mercator_project([lon_end, lat_end]);
|
||||||
|
|
||||||
|
let lon_len = (end[0] - start[0]).abs();
|
||||||
|
let lat_len = (end[1] - start[1]).abs();
|
||||||
|
|
||||||
|
let rate = lat_len / lon_len;
|
||||||
|
let rel_width = 10.0;
|
||||||
|
let rel_height = rel_width * rate;
|
||||||
|
|
||||||
|
if let Some(ref hgt) = hgt {
|
||||||
|
let hgt_start = *hgt.first().unwrap() as f32;
|
||||||
|
let hgt_end = *hgt.last().unwrap() as f32;
|
||||||
|
|
||||||
|
vertices.extend_from_slice(&[
|
||||||
|
// Left Bottom
|
||||||
|
lon_start,
|
||||||
|
lat_start,
|
||||||
|
0.0,
|
||||||
|
-rel_width / 2.0,
|
||||||
|
-rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Right Bottom
|
||||||
|
lon_end,
|
||||||
|
lat_start,
|
||||||
|
0.0,
|
||||||
|
rel_width / 2.0,
|
||||||
|
-rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Left Top
|
||||||
|
lon_start,
|
||||||
|
lat_end,
|
||||||
|
0.0,
|
||||||
|
-rel_width / 2.0,
|
||||||
|
rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Right Top
|
||||||
|
lon_end,
|
||||||
|
lat_end,
|
||||||
|
0.0,
|
||||||
|
rel_width / 2.0,
|
||||||
|
rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
vertices.extend_from_slice(&[
|
||||||
|
// Left Bottom
|
||||||
|
lon_start,
|
||||||
|
lat_start,
|
||||||
|
0.0,
|
||||||
|
-rel_width / 2.0,
|
||||||
|
-rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Right Bottom
|
||||||
|
lon_end,
|
||||||
|
lat_start,
|
||||||
|
0.0,
|
||||||
|
rel_width / 2.0,
|
||||||
|
-rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Left Top
|
||||||
|
lon_start,
|
||||||
|
lat_end,
|
||||||
|
0.0,
|
||||||
|
-rel_width / 2.0,
|
||||||
|
rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
// Right Top
|
||||||
|
lon_end,
|
||||||
|
lat_end,
|
||||||
|
0.0,
|
||||||
|
rel_width / 2.0,
|
||||||
|
rel_height / 2.0,
|
||||||
|
0.0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
attach.bind_data(&vertices, None, 4, glow::STATIC_DRAW);
|
||||||
|
|
||||||
|
// Texture
|
||||||
|
unsafe {
|
||||||
|
use bytemuck::cast_slice;
|
||||||
|
gl.bind_texture(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
(attach.textures.as_ref()).map(|t| t.native()),
|
||||||
|
);
|
||||||
|
|
||||||
|
let _data = &data.data;
|
||||||
|
let shape = _data.shape();
|
||||||
|
|
||||||
|
let (depth, height, width) = if shape.len() == 2 {
|
||||||
|
(1i32, shape[0] as i32, shape[1] as i32)
|
||||||
|
} else {
|
||||||
|
(shape[0] as i32, shape[1] as i32, shape[2] as i32)
|
||||||
|
};
|
||||||
|
|
||||||
|
let pixels: &[u8] = cast_slice(_data.as_slice().unwrap());
|
||||||
|
|
||||||
|
gl.tex_image_3d(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
0,
|
||||||
|
glow::R8 as i32,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
depth,
|
||||||
|
0,
|
||||||
|
glow::RED,
|
||||||
|
glow::UNSIGNED_BYTE,
|
||||||
|
Some(pixels),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
} else {
|
||||||
|
return Err(Error::InvalidDataType(format!(
|
||||||
|
"Expect Cartesian, but got {}",
|
||||||
|
coord_type
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err(Error::InvalidDataType("No coord type".to_string()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
&self,
|
||||||
|
gl: &glow::Context,
|
||||||
|
) -> (
|
||||||
|
glow::NativeVertexArray,
|
||||||
|
glow::NativeBuffer,
|
||||||
|
Option<glow::NativeBuffer>,
|
||||||
|
Option<glow::NativeTexture>,
|
||||||
|
) {
|
||||||
|
unsafe {
|
||||||
|
let vao = gl.create_vertex_array().unwrap();
|
||||||
|
gl.bind_vertex_array(Some(vao));
|
||||||
|
|
||||||
|
let vbo = gl.create_buffer().unwrap();
|
||||||
|
gl.bind_buffer(glow::ARRAY_BUFFER, Some(vbo));
|
||||||
|
gl.enable_vertex_attrib_array(0);
|
||||||
|
gl.vertex_attrib_pointer_f32(0, 3, glow::FLOAT, false, 24, 0);
|
||||||
|
gl.enable_vertex_attrib_array(1);
|
||||||
|
gl.vertex_attrib_pointer_f32(1, 3, glow::FLOAT, false, 24, 12);
|
||||||
|
gl.bind_vertex_array(None);
|
||||||
|
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||||
|
|
||||||
|
// Create Texture
|
||||||
|
let texture = gl.create_texture().unwrap();
|
||||||
|
gl.bind_texture(glow::TEXTURE_3D, Some(texture));
|
||||||
|
|
||||||
|
gl.tex_parameter_i32(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
glow::TEXTURE_MIN_FILTER,
|
||||||
|
glow::NEAREST as i32,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i32(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
glow::TEXTURE_MAG_FILTER,
|
||||||
|
glow::NEAREST as i32,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i32(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
glow::TEXTURE_WRAP_S,
|
||||||
|
glow::CLAMP_TO_EDGE as i32,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i32(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
glow::TEXTURE_WRAP_T,
|
||||||
|
glow::CLAMP_TO_EDGE as i32,
|
||||||
|
);
|
||||||
|
gl.tex_parameter_i32(
|
||||||
|
glow::TEXTURE_3D,
|
||||||
|
glow::TEXTURE_WRAP_R,
|
||||||
|
glow::CLAMP_TO_EDGE as i32,
|
||||||
|
);
|
||||||
|
|
||||||
|
(vao, vbo, None, Some(texture))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mercator_project(loc: [f32; 2]) -> [f32; 2] {
|
||||||
|
// 将经纬度从度转换为弧度
|
||||||
|
let lon_rad = loc[0].to_radians();
|
||||||
|
let lat_rad = loc[1].to_radians();
|
||||||
|
|
||||||
|
// X轴投影 (线性映射经度)
|
||||||
|
let x = 6378137.0 * lon_rad;
|
||||||
|
|
||||||
|
// Y轴投影 (非线性映射纬度)
|
||||||
|
let y = 6378137.0 * (lat_rad / 2.0 + 45.0_f32.to_radians()).tan().ln();
|
||||||
|
|
||||||
|
return [x, y];
|
||||||
|
}
|
||||||
@ -2,6 +2,7 @@ pub mod collections;
|
|||||||
pub mod colormap;
|
pub mod colormap;
|
||||||
mod colormesh;
|
mod colormesh;
|
||||||
pub mod font;
|
pub mod font;
|
||||||
|
pub mod geoquadmesh;
|
||||||
pub mod ppi;
|
pub mod ppi;
|
||||||
pub mod threed;
|
pub mod threed;
|
||||||
pub mod tools;
|
pub mod tools;
|
||||||
@ -13,11 +14,11 @@ use crate::{
|
|||||||
components::Program,
|
components::Program,
|
||||||
errors::*,
|
errors::*,
|
||||||
graphics::font::FontConfig,
|
graphics::font::FontConfig,
|
||||||
pg::layout_type::ViewPort,
|
pg::{layout_type::ViewPort, Attach},
|
||||||
ui::{operation::Projection, typ::CameraOP},
|
ui::{operation::Projection, typ::CameraOP},
|
||||||
};
|
};
|
||||||
|
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeTexture, NativeVertexArray};
|
||||||
|
|
||||||
pub trait Graphics {
|
pub trait Graphics {
|
||||||
const id: &'static str;
|
const id: &'static str;
|
||||||
@ -64,8 +65,17 @@ pub trait AttaWithBuffer: Graphics {
|
|||||||
gl: &'gl glow::Context,
|
gl: &'gl glow::Context,
|
||||||
data: &Self::Data,
|
data: &Self::Data,
|
||||||
config: &<Self as Graphics>::Config,
|
config: &<Self as Graphics>::Config,
|
||||||
) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)>;
|
attach: &mut Attach,
|
||||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>);
|
) -> Result<()>;
|
||||||
|
fn init(
|
||||||
|
&self,
|
||||||
|
gl: &glow::Context,
|
||||||
|
) -> (
|
||||||
|
NativeVertexArray,
|
||||||
|
NativeBuffer,
|
||||||
|
Option<NativeBuffer>,
|
||||||
|
Option<NativeTexture>,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! config_for_everyitem {
|
macro_rules! config_for_everyitem {
|
||||||
|
|||||||
@ -186,7 +186,8 @@ impl AttaWithBuffer for PPI {
|
|||||||
gl: &'gl glow::Context,
|
gl: &'gl glow::Context,
|
||||||
data: &Self::Data,
|
data: &Self::Data,
|
||||||
config: &<Self as Graphics>::Config,
|
config: &<Self as Graphics>::Config,
|
||||||
) -> Result<(Vec<f32>, Option<Vec<u32>>, i32)> {
|
attach: &mut crate::pg::Attach,
|
||||||
|
) -> Result<()> {
|
||||||
let layer = config.layer;
|
let layer = config.layer;
|
||||||
|
|
||||||
match data.coord_type().unwrap() {
|
match data.coord_type().unwrap() {
|
||||||
@ -213,15 +214,24 @@ impl AttaWithBuffer for PPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
let len = vertices.len() as i32 / 4;
|
let len = vertices.len() as i32 / 4;
|
||||||
return Ok((vertices, None, len));
|
|
||||||
|
attach.bind_data(&vertices, None, len, glow::STATIC_DRAW);
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
return Err(Error::InvalidDataType(format!("Invalid CoordType")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn init(
|
||||||
fn init(&self, gl: &glow::Context) -> (NativeVertexArray, NativeBuffer, Option<NativeBuffer>) {
|
&self,
|
||||||
|
gl: &glow::Context,
|
||||||
|
) -> (
|
||||||
|
NativeVertexArray,
|
||||||
|
NativeBuffer,
|
||||||
|
Option<NativeBuffer>,
|
||||||
|
Option<glow::NativeTexture>,
|
||||||
|
) {
|
||||||
unsafe {
|
unsafe {
|
||||||
let vao = gl.create_vertex_array().unwrap();
|
let vao = gl.create_vertex_array().unwrap();
|
||||||
gl.bind_vertex_array(Some(vao));
|
gl.bind_vertex_array(Some(vao));
|
||||||
@ -232,7 +242,7 @@ impl AttaWithBuffer for PPI {
|
|||||||
gl.bind_vertex_array(None);
|
gl.bind_vertex_array(None);
|
||||||
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
gl.bind_buffer(glow::ARRAY_BUFFER, None);
|
||||||
|
|
||||||
(vao, vbo, None)
|
(vao, vbo, None, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#![feature(proc_macro_hygiene)]
|
#![feature(proc_macro_hygiene)]
|
||||||
|
#![feature(concat_idents)]
|
||||||
#![allow(unused)]
|
#![allow(unused)]
|
||||||
mod camera;
|
mod camera;
|
||||||
mod components;
|
mod components;
|
||||||
|
|||||||
123
gi/src/pg/mod.rs
123
gi/src/pg/mod.rs
@ -3,7 +3,10 @@ use femtovg::renderer::OpenGl;
|
|||||||
use femtovg::Canvas;
|
use femtovg::Canvas;
|
||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use layout_type::ViewPort;
|
use layout_type::ViewPort;
|
||||||
use modules::{PPIModuleConfigComponent, PPIModuleRef};
|
use modules::{
|
||||||
|
GeoQuadMeshModuleConfigComponent, GeoQuadMeshModuleRef, GeoQuadMeshPackage,
|
||||||
|
PPIModuleConfigComponent, PPIModuleRef,
|
||||||
|
};
|
||||||
use radarg_core::{datapool::Value, radarg_data::Data};
|
use radarg_core::{datapool::Value, radarg_data::Data};
|
||||||
|
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
@ -16,12 +19,13 @@ use relm4::{
|
|||||||
};
|
};
|
||||||
pub mod layout_type;
|
pub mod layout_type;
|
||||||
mod modules;
|
mod modules;
|
||||||
|
pub(crate) use modules::Attach;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::*,
|
errors::*,
|
||||||
font_manager::FontManager,
|
font_manager::FontManager,
|
||||||
graphics::{
|
graphics::{
|
||||||
collections::agg_fast_path::AggFastPath, font::Text, ppi::PPI,
|
collections::agg_fast_path::AggFastPath, font::Text, geoquadmesh::GeoQuadMesh, ppi::PPI,
|
||||||
transforms::plane::PlaneTrans, AttaWithProgram, AttachWithIO, Graphics,
|
transforms::plane::PlaneTrans, AttaWithProgram, AttachWithIO, Graphics,
|
||||||
},
|
},
|
||||||
ui::{operation::Operation, typ::LayoutAttach},
|
ui::{operation::Operation, typ::LayoutAttach},
|
||||||
@ -29,7 +33,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use app::{App, Context};
|
pub use app::{App, Context};
|
||||||
pub use modules::{Module, ModuleCursor, PPIModule, PPIPackage};
|
pub use modules::{GeoQuadMeshModule, Module, ModuleCursor, PPIModule, PPIPackage};
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::{cell::RefCell, collections::HashMap};
|
use std::{cell::RefCell, collections::HashMap};
|
||||||
use std::{rc::Rc, sync::Arc};
|
use std::{rc::Rc, sync::Arc};
|
||||||
@ -44,22 +48,42 @@ pub enum SideBarInputMsg {
|
|||||||
None,
|
None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! program_impl {
|
||||||
|
($({$name:ident | $name_ref:ident, $module: ty | $module_ref: ty, ($($m:ident),+)}),+) => {
|
||||||
|
impl Programs {
|
||||||
|
$(
|
||||||
|
pub fn $name(&mut self) -> $module {
|
||||||
|
<$module>::new(&self.gl, $(&mut self.$m),+)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn $name_ref(&self) -> $module_ref {
|
||||||
|
<$module_ref>::new(&self.gl, $(&self.$m),+)
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Programs {
|
pub struct Programs {
|
||||||
gl: GL,
|
gl: GL,
|
||||||
_ppi: PPI,
|
_ppi: PPI,
|
||||||
_text: Text,
|
_text: Text,
|
||||||
_line: AggFastPath,
|
_line: AggFastPath,
|
||||||
|
_geo_quad_mesh: GeoQuadMesh,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Programs {
|
impl Programs {
|
||||||
fn new(gl: GL) -> Result<Self> {
|
fn new(gl: GL) -> Result<Self> {
|
||||||
let font_manager = FontManager::new()?;
|
let font_manager = FontManager::new()?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
gl: gl.clone(),
|
gl: gl.clone(),
|
||||||
_ppi: PPI::new()?,
|
_ppi: PPI::new()?,
|
||||||
_text: Text::new(gl, font_manager)?,
|
_text: Text::new(gl, font_manager)?,
|
||||||
_line: AggFastPath::new()?,
|
_line: AggFastPath::new()?,
|
||||||
|
_geo_quad_mesh: GeoQuadMesh::new()?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,6 +91,7 @@ impl Programs {
|
|||||||
self._ppi.program().compile(&self.gl)?;
|
self._ppi.program().compile(&self.gl)?;
|
||||||
self._line.program().compile(&self.gl)?;
|
self._line.program().compile(&self.gl)?;
|
||||||
self._text.program_mut().compile(&self.gl)?;
|
self._text.program_mut().compile(&self.gl)?;
|
||||||
|
self._geo_quad_mesh.program().compile(&self.gl)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,48 +99,13 @@ impl Programs {
|
|||||||
self._ppi.destroy(&self.gl)?;
|
self._ppi.destroy(&self.gl)?;
|
||||||
self._text.destroy(&self.gl)?;
|
self._text.destroy(&self.gl)?;
|
||||||
self._line.destroy(&self.gl)?;
|
self._line.destroy(&self.gl)?;
|
||||||
Ok(())
|
self._geo_quad_mesh.destroy(&self.gl)?;
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ppi(&mut self) -> PPIModule {
|
|
||||||
PPIModule::new(&self.gl, &mut self._ppi, &mut self._text, &mut self._line)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn ppi_ref(&self) -> PPIModuleRef {
|
|
||||||
PPIModuleRef::new(&self.gl, &self._ppi, &self._text, &self._line)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn supported_modules<'a>(
|
|
||||||
&mut self,
|
|
||||||
data: &'a Value<Data>,
|
|
||||||
) -> HashMap<&'a Arc<Data>, Vec<ModuleRefs>> {
|
|
||||||
let mut result = HashMap::new();
|
|
||||||
|
|
||||||
for (k, d) in data.iter() {
|
|
||||||
result.insert(d, vec![ModuleRefs::PPI(self.ppi_ref())]);
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn draw_modules(
|
|
||||||
&mut self,
|
|
||||||
modules: &mut ModulePackage,
|
|
||||||
operation: &Operation<PlaneTrans>,
|
|
||||||
viewport: &ViewPort,
|
|
||||||
) -> Result<()> {
|
|
||||||
match &mut modules.modules {
|
|
||||||
_ModulePackage::PPI(ppi) => {
|
|
||||||
self.ppi().render(ppi, operation, viewport)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
modules.need_update = false;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_module_package {
|
macro_rules! impl_module_package {
|
||||||
($({$t:ty => $b: tt | $module:tt | $module_ref:tt | $c: ty}),+) => {
|
($({$method:ident|$ref_method:ident ,$t:ty => $b: tt | $module:tt | $module_ref:tt | $c: ty}),+) => {
|
||||||
|
|
||||||
pub enum Modules<'b, 'gl: 'b>{
|
pub enum Modules<'b, 'gl: 'b>{
|
||||||
$(
|
$(
|
||||||
@ -123,9 +113,10 @@ macro_rules! impl_module_package {
|
|||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone,Copy)]
|
||||||
pub enum ModuleRefs<'b, 'gl:'b>{
|
pub enum ModuleRefs<'b, 'gl:'b>{
|
||||||
$(
|
$(
|
||||||
$b($module_ref<'b,'gl>)
|
$b($module_ref<'b,'gl>),
|
||||||
)+
|
)+
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +125,7 @@ macro_rules! impl_module_package {
|
|||||||
match self {
|
match self {
|
||||||
$(
|
$(
|
||||||
Modules::$b(m) => {
|
Modules::$b(m) => {
|
||||||
let cursor = m.load_data(data.into(), setting)?;
|
let cursor = m.load_data(data.try_into().unwrap(), setting)?;
|
||||||
Ok(cursor.into())
|
Ok(cursor.into())
|
||||||
}
|
}
|
||||||
)+
|
)+
|
||||||
@ -241,11 +232,55 @@ macro_rules! impl_module_package {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Programs {
|
||||||
|
|
||||||
|
pub fn draw_modules(
|
||||||
|
&mut self,
|
||||||
|
modules: &mut ModulePackage,
|
||||||
|
operation: &Operation<PlaneTrans>,
|
||||||
|
viewport: &ViewPort,
|
||||||
|
) -> Result<()> {
|
||||||
|
match &mut modules.modules {
|
||||||
|
$(
|
||||||
|
_ModulePackage::$b(m) => {
|
||||||
|
self.$method().render(m, operation, viewport)?;
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
}
|
||||||
|
modules.need_update = false;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn supported_modules<'a>(&mut self, data: &'a Value<Data>) -> HashMap<&'a Arc<Data>, Vec<ModuleRefs>> {
|
||||||
|
let mut result = HashMap::with_capacity(data.len());
|
||||||
|
for (k, d) in data.iter() {
|
||||||
|
$(
|
||||||
|
{
|
||||||
|
if self.$ref_method().supported(d) {
|
||||||
|
let _ref = self.$ref_method();
|
||||||
|
result.entry(d).and_modify(|v:&mut Vec<ModuleRefs>| v.push(ModuleRefs::$b(_ref))).or_insert_with(|| vec![ModuleRefs::$b(_ref)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
)+
|
||||||
|
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
program_impl!(
|
||||||
|
{ppi | ppi_ref, PPIModule | PPIModuleRef, (_ppi, _text, _line)},
|
||||||
|
{geo_quad_mesh | geo_quad_mesh_ref, GeoQuadMeshModule | GeoQuadMeshModuleRef, (_geo_quad_mesh,_text, _line)}
|
||||||
|
);
|
||||||
|
|
||||||
impl_module_package!(
|
impl_module_package!(
|
||||||
{PPIPackage => PPI | PPIModule | PPIModuleRef | PPIModuleConfigComponent}
|
{ppi|ppi_ref,PPIPackage => PPI | PPIModule | PPIModuleRef | PPIModuleConfigComponent},
|
||||||
|
{geo_quad_mesh|geo_quad_mesh_ref,GeoQuadMeshPackage => GeoQuadMesh | GeoQuadMeshModule | GeoQuadMeshModuleRef | GeoQuadMeshModuleConfigComponent}
|
||||||
);
|
);
|
||||||
|
|
||||||
impl ModulePackage {
|
impl ModulePackage {
|
||||||
|
|||||||
478
gi/src/pg/modules/geoquadmesh.rs
Normal file
478
gi/src/pg/modules/geoquadmesh.rs
Normal file
@ -0,0 +1,478 @@
|
|||||||
|
use crate::{
|
||||||
|
graphics::{
|
||||||
|
collections::agg_fast_path::{AggFastPath, AggFastPathConfig, Path},
|
||||||
|
font::{Anchor, FontConfig, LineStyle, PositionText, Text, TextLine},
|
||||||
|
geoquadmesh::{GeoQuadMesh, GeoQuadMeshConfig},
|
||||||
|
ppi::{PPIConfig, PPI},
|
||||||
|
transforms::plane::PlaneTrans,
|
||||||
|
AttaWithBuffer, Graphics,
|
||||||
|
},
|
||||||
|
pg::SideBarInputMsg,
|
||||||
|
GL,
|
||||||
|
};
|
||||||
|
use radarg_core::{config::Setting, CoordType, Data};
|
||||||
|
use relm4::{
|
||||||
|
adw::{self, prelude::*},
|
||||||
|
gtk::{self, prelude::*},
|
||||||
|
ComponentParts, SimpleComponent,
|
||||||
|
};
|
||||||
|
|
||||||
|
use core::f32;
|
||||||
|
use glow::HasContext;
|
||||||
|
use std::{
|
||||||
|
cell::{RefCell, RefMut},
|
||||||
|
rc::Rc,
|
||||||
|
sync::Arc,
|
||||||
|
};
|
||||||
|
use tracker::track;
|
||||||
|
|
||||||
|
use crate::font_manager::{FontSize, FontStyle};
|
||||||
|
|
||||||
|
use crate::pg::layout_type::ViewPort;
|
||||||
|
use crate::ui::operation::{self, Operation};
|
||||||
|
use crate::{errors::*, font_manager::FontManager, ui::typ, utils::resources::ManagedResource};
|
||||||
|
|
||||||
|
use radarg_core::radarg_data::RadarGridData;
|
||||||
|
|
||||||
|
use super::{Attach, Module, ModuleCursor};
|
||||||
|
pub struct GeoQuadMeshModule<'b, 'gl: 'b> {
|
||||||
|
gl: &'gl GL,
|
||||||
|
geo_quad_mesh_program: &'b mut GeoQuadMesh,
|
||||||
|
line_program: &'b mut AggFastPath,
|
||||||
|
text_program: &'b mut Text,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct GeoQuadMeshModuleRef<'b, 'gl: 'b> {
|
||||||
|
gl: &'gl GL,
|
||||||
|
geo_quad_mesh_program: &'b GeoQuadMesh,
|
||||||
|
line_program: &'b AggFastPath,
|
||||||
|
text_program: &'b Text,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, 'a: 'b> GeoQuadMeshModuleRef<'b, 'a> {
|
||||||
|
pub fn new(gl: &'a GL, quad: &'b GeoQuadMesh, text: &'b Text, line: &'b AggFastPath) -> Self {
|
||||||
|
let config = PPIConfig::default();
|
||||||
|
Self {
|
||||||
|
gl,
|
||||||
|
geo_quad_mesh_program: quad,
|
||||||
|
text_program: text,
|
||||||
|
line_program: line,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_line_pg(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &GeoQuadMeshModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_tick(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &GeoQuadMeshModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn name(&self) -> &'static str {
|
||||||
|
"GeoQuadMesh"
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn supported(&self, data: &Data) -> bool {
|
||||||
|
let data: std::result::Result<&RadarGridData, radarg_core::errors::DataError> =
|
||||||
|
data.try_into();
|
||||||
|
if let Ok(data) = data {
|
||||||
|
match data.coord_type() {
|
||||||
|
Some(CoordType::Cartesian { .. }) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
|
||||||
|
pub fn new(
|
||||||
|
gl: &'a GL,
|
||||||
|
geo_quad_mesh: &'b mut GeoQuadMesh,
|
||||||
|
text: &'b mut Text,
|
||||||
|
line: &'b mut AggFastPath,
|
||||||
|
) -> Self {
|
||||||
|
let config = PPIConfig::default();
|
||||||
|
Self {
|
||||||
|
gl,
|
||||||
|
geo_quad_mesh_program: geo_quad_mesh,
|
||||||
|
text_program: text,
|
||||||
|
line_program: line,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_geo_quad_mesh_pg(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &GeoQuadMeshModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
self.geo_quad_mesh_program
|
||||||
|
.bake(&self.gl, data, &config.to_quad_config(), attach)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_line_pg(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &GeoQuadMeshModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bind_tick(
|
||||||
|
&self,
|
||||||
|
attach: &mut Attach,
|
||||||
|
data: &RadarGridData,
|
||||||
|
config: &GeoQuadMeshModuleConfig,
|
||||||
|
) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
|
||||||
|
type Cursor = GeoQuadMeshPackage;
|
||||||
|
type Data = RadarGridData;
|
||||||
|
type Operation = PlaneTrans;
|
||||||
|
|
||||||
|
const NAME: &'static str = "GeoQuadMesh";
|
||||||
|
|
||||||
|
fn render<'dt>(
|
||||||
|
&mut self,
|
||||||
|
cursor: &mut Self::Cursor,
|
||||||
|
operation: &Operation<Self::Operation>,
|
||||||
|
viewport: &ViewPort,
|
||||||
|
) -> Result<()> {
|
||||||
|
unsafe {
|
||||||
|
let err = self.gl.get_error();
|
||||||
|
if err != glow::NO_ERROR {
|
||||||
|
panic!("Error: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// PPI Program
|
||||||
|
let data = &cursor.data;
|
||||||
|
let mut config = &mut cursor.ppi_config.borrow_mut();
|
||||||
|
// Mount PPI Program
|
||||||
|
self.geo_quad_mesh_program.mount(&self.gl)?;
|
||||||
|
// Deal with the operation
|
||||||
|
operation.attach_with_program(&self.gl, self.geo_quad_mesh_program.program());
|
||||||
|
let quad_attach = &mut cursor.quad_attach;
|
||||||
|
unsafe {
|
||||||
|
let err = self.gl.get_error();
|
||||||
|
if err != glow::NO_ERROR {
|
||||||
|
panic!("Error: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the config
|
||||||
|
self.geo_quad_mesh_program
|
||||||
|
.set_config(&self.gl, &config.to_quad_config())?;
|
||||||
|
unsafe {
|
||||||
|
let err = self.gl.get_error();
|
||||||
|
if err != glow::NO_ERROR {
|
||||||
|
panic!("Error: {}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Quad Draw
|
||||||
|
quad_attach.bind_self(self.geo_quad_mesh_program.program_ref());
|
||||||
|
self.geo_quad_mesh_program
|
||||||
|
.draw(&self.gl, quad_attach.len())?;
|
||||||
|
|
||||||
|
// quad_attach.unbind_self();
|
||||||
|
|
||||||
|
// Unmount Program
|
||||||
|
self.geo_quad_mesh_program.unmount(&self.gl)?;
|
||||||
|
|
||||||
|
config.reset();
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
|
||||||
|
// Init the memory
|
||||||
|
let (vao, vbo, ebo, texs) = self.geo_quad_mesh_program.init(&self.gl);
|
||||||
|
let mut quad_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
|
// Get the data info
|
||||||
|
let (hgt_range, lat_range, lon_range, dpi, t) =
|
||||||
|
self.geo_quad_mesh_program.data_info(&data)?;
|
||||||
|
|
||||||
|
println!("name: {}", data.info.value_name);
|
||||||
|
|
||||||
|
// Find the color map
|
||||||
|
let cmap = setting.find(&t);
|
||||||
|
|
||||||
|
// Check if the color map is valid
|
||||||
|
if cmap.is_none() {
|
||||||
|
return Err(Error::InvalidDataType(format!(
|
||||||
|
"{}'s colormap is not found",
|
||||||
|
data.info.value_name
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
let cmap = cmap.unwrap();
|
||||||
|
|
||||||
|
// Init the memory for the line program
|
||||||
|
let (vao, vbo, ebo, texs) = self.line_program.init(&self.gl);
|
||||||
|
let mut line_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
|
// Tick Label
|
||||||
|
let (vao, vbo, ebo, texs) = self.text_program.init(&self.gl);
|
||||||
|
let mut tick_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
|
let mut config = GeoQuadMeshModuleConfig::default();
|
||||||
|
config.alt_dpi = dpi[0];
|
||||||
|
config.lat_dpi = dpi[1];
|
||||||
|
config.lon_dpi = dpi[2];
|
||||||
|
|
||||||
|
config.lat_range = lat_range;
|
||||||
|
config.lon_range = lon_range;
|
||||||
|
config.hgt_range = hgt_range.unwrap_or_default();
|
||||||
|
config.colors = cmap.color().unwrap();
|
||||||
|
config.color_range = cmap.value_range();
|
||||||
|
|
||||||
|
// Bind the data
|
||||||
|
self.bind_geo_quad_mesh_pg(&mut quad_attach, data, &config);
|
||||||
|
|
||||||
|
// self.bind_line_pg(&mut line_attach, &data, &config);
|
||||||
|
// self.bind_tick(&mut tick_attach, &data.borrow(), &config);
|
||||||
|
|
||||||
|
let data = data.clone();
|
||||||
|
Ok(Self::Cursor::new(
|
||||||
|
config,
|
||||||
|
quad_attach,
|
||||||
|
line_attach,
|
||||||
|
tick_attach,
|
||||||
|
data,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
fn supported(&self, data: &radarg_core::Data) -> bool {
|
||||||
|
let data: std::result::Result<&RadarGridData, radarg_core::errors::DataError> =
|
||||||
|
data.try_into();
|
||||||
|
if let Ok(data) = data {
|
||||||
|
match data.coord_type() {
|
||||||
|
Some(CoordType::Cartesian { .. }) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct GeoQuadMeshPackage {
|
||||||
|
draw_helper: bool,
|
||||||
|
ppi_config: Rc<RefCell<GeoQuadMeshModuleConfig>>,
|
||||||
|
quad_attach: Attach,
|
||||||
|
line_attach: Attach,
|
||||||
|
tick_attach: Attach,
|
||||||
|
data: Arc<RadarGridData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeoQuadMeshPackage {
|
||||||
|
fn new(
|
||||||
|
ppi_config: GeoQuadMeshModuleConfig,
|
||||||
|
quad_attach: Attach,
|
||||||
|
line_attach: Attach,
|
||||||
|
tick_attach: Attach,
|
||||||
|
data: Arc<RadarGridData>,
|
||||||
|
) -> Self {
|
||||||
|
Self {
|
||||||
|
draw_helper: true,
|
||||||
|
ppi_config: Rc::new(RefCell::new(ppi_config)),
|
||||||
|
quad_attach,
|
||||||
|
line_attach,
|
||||||
|
tick_attach,
|
||||||
|
data,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[track]
|
||||||
|
#[derive(PartialEq, Debug, Clone)]
|
||||||
|
pub struct GeoQuadMeshModuleConfig {
|
||||||
|
pub ticks: bool,
|
||||||
|
pub line_color: [f32; 4],
|
||||||
|
pub line_width: f32,
|
||||||
|
pub line_antialias: f32,
|
||||||
|
pub layer: usize,
|
||||||
|
pub colors: Vec<[u8; 4]>,
|
||||||
|
pub color_range: [f32; 2],
|
||||||
|
pub is_three_d: bool,
|
||||||
|
|
||||||
|
pub tick_label_color: [f32; 4],
|
||||||
|
pub tick_label_size: f32,
|
||||||
|
#[do_not_track]
|
||||||
|
pub lat_range: [f32; 2],
|
||||||
|
|
||||||
|
#[do_not_track]
|
||||||
|
pub lon_range: [f32; 2],
|
||||||
|
|
||||||
|
#[do_not_track]
|
||||||
|
pub hgt_range: [f32; 2],
|
||||||
|
|
||||||
|
#[do_not_track]
|
||||||
|
pub unvalid_value: f32,
|
||||||
|
#[do_not_track]
|
||||||
|
pub max_layer: usize,
|
||||||
|
#[do_not_track]
|
||||||
|
pub lat_dpi: f32,
|
||||||
|
#[do_not_track]
|
||||||
|
pub alt_dpi: f32,
|
||||||
|
#[do_not_track]
|
||||||
|
pub lon_dpi: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for GeoQuadMeshModuleConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
ticks: true,
|
||||||
|
line_color: [1.0, 1.0, 1.0, 1.0],
|
||||||
|
line_width: 1.5,
|
||||||
|
line_antialias: 0.5,
|
||||||
|
layer: 0,
|
||||||
|
colors: vec![],
|
||||||
|
color_range: [0.0, 0.0],
|
||||||
|
is_three_d: true,
|
||||||
|
unvalid_value: 0.0,
|
||||||
|
tick_label_color: [1.0, 1.0, 1.0, 1.0],
|
||||||
|
tick_label_size: 24.0,
|
||||||
|
max_layer: 0,
|
||||||
|
lat_dpi: 0.0,
|
||||||
|
alt_dpi: 0.0,
|
||||||
|
lon_dpi: 0.0,
|
||||||
|
tracker: 0,
|
||||||
|
lat_range: [0.0, 0.0],
|
||||||
|
lon_range: [0.0, 0.0],
|
||||||
|
hgt_range: [0.0, 0.0],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeoQuadMeshModuleConfig {
|
||||||
|
fn to_quad_config(&self) -> GeoQuadMeshConfig {
|
||||||
|
GeoQuadMeshConfig {
|
||||||
|
unvalid_value: self.unvalid_value,
|
||||||
|
layer: self.layer,
|
||||||
|
colors: self.colors.clone(),
|
||||||
|
color_range: self.color_range,
|
||||||
|
lon_dpi: self.lon_dpi,
|
||||||
|
lat_dpi: self.lat_dpi,
|
||||||
|
alt_dpi: self.alt_dpi,
|
||||||
|
lat_range: self.lat_range,
|
||||||
|
lon_range: self.lon_range,
|
||||||
|
alt_range: self.hgt_range,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_line_config(&self) -> AggFastPathConfig {
|
||||||
|
AggFastPathConfig {
|
||||||
|
color: self.line_color,
|
||||||
|
linewidth: self.line_width,
|
||||||
|
antialias: self.line_antialias,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_font_config(&self) -> FontConfig {
|
||||||
|
let line_style = LineStyle::default();
|
||||||
|
let mut font_style = FontStyle::default();
|
||||||
|
font_style.size = FontSize::Absolute(self.tick_label_size);
|
||||||
|
font_style.color = self.tick_label_color;
|
||||||
|
FontConfig::Textline(line_style, font_style)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GeoQuadMeshModuleConfigComponent {
|
||||||
|
config: Rc<RefCell<GeoQuadMeshModuleConfig>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum OutputMsg {
|
||||||
|
Refresh,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[relm4::component(pub)]
|
||||||
|
impl SimpleComponent for GeoQuadMeshModuleConfigComponent {
|
||||||
|
type Widgets = GeoQuadMeshModuleConfigComponentWidgets;
|
||||||
|
type Init = Rc<RefCell<GeoQuadMeshModuleConfig>>;
|
||||||
|
type Input = ();
|
||||||
|
type Output = OutputMsg;
|
||||||
|
|
||||||
|
view! {
|
||||||
|
adw::PreferencesPage {
|
||||||
|
adw::PreferencesGroup {
|
||||||
|
set_title:"PPI Config",
|
||||||
|
set_hexpand:true,
|
||||||
|
adw::SwitchRow {
|
||||||
|
set_title:"Ticks",
|
||||||
|
set_active: init_config.ticks,
|
||||||
|
connect_active_notify[sender, config_ref] => move |this| {
|
||||||
|
let active = this.is_active();
|
||||||
|
config_ref.borrow_mut().set_ticks(active);
|
||||||
|
sender.output(OutputMsg::Refresh);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn init(
|
||||||
|
init: Self::Init,
|
||||||
|
root: Self::Root,
|
||||||
|
sender: relm4::ComponentSender<Self>,
|
||||||
|
) -> relm4::ComponentParts<Self> {
|
||||||
|
let model = GeoQuadMeshModuleConfigComponent {
|
||||||
|
config: init.clone(),
|
||||||
|
};
|
||||||
|
let init_config = init.borrow().clone();
|
||||||
|
let config_ref = model.config.clone();
|
||||||
|
|
||||||
|
let widgets = view_output!();
|
||||||
|
|
||||||
|
ComponentParts { model, widgets }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender<Self>) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ModuleCursor for GeoQuadMeshPackage {
|
||||||
|
type Module<'rf, 'gl: 'rf> = GeoQuadMeshModule<'rf, 'gl>;
|
||||||
|
type Config = GeoQuadMeshModuleConfig;
|
||||||
|
type Data = RadarGridData;
|
||||||
|
type Component = GeoQuadMeshModuleConfigComponent;
|
||||||
|
|
||||||
|
type ComponentOutput = OutputMsg;
|
||||||
|
|
||||||
|
fn set_config<F>(&mut self, f: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&mut Self::Config),
|
||||||
|
{
|
||||||
|
let mut config = self.ppi_config.borrow_mut();
|
||||||
|
f(&mut config);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn component_config(&self) -> Rc<RefCell<Self::Config>> {
|
||||||
|
self.ppi_config.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn component_sender(&self) -> Box<dyn Fn(Self::ComponentOutput) -> crate::pg::SideBarInputMsg> {
|
||||||
|
Box::new(|c| match c {
|
||||||
|
OutputMsg::Refresh => SideBarInputMsg::Refresh,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
components::Program,
|
||||||
graphics::AttachWithIO,
|
graphics::AttachWithIO,
|
||||||
resources::{RcGlRcBuffer, RcGlRcVertexArray},
|
resources::{RcGlRcBuffer, RcGlRcResource, RcGlRcVertexArray},
|
||||||
ui::{
|
ui::{
|
||||||
operation::{self, Operation},
|
operation::{self, Operation},
|
||||||
typ::CameraOP,
|
typ::CameraOP,
|
||||||
@ -9,11 +10,16 @@ use crate::{
|
|||||||
GL,
|
GL,
|
||||||
};
|
};
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
use glow::{HasContext, NativeBuffer, NativeVertexArray};
|
use glow::{HasContext, NativeBuffer, NativeTexture, NativeVertexArray};
|
||||||
use radarg_core::config::Setting;
|
use radarg_core::{config::Setting, Data};
|
||||||
use std::{cell::RefCell, path::Component, rc::Rc, sync::Arc};
|
use std::{cell::RefCell, path::Component, rc::Rc, sync::Arc};
|
||||||
|
mod geoquadmesh;
|
||||||
mod ppi;
|
mod ppi;
|
||||||
use crate::errors::*;
|
use crate::errors::*;
|
||||||
|
pub use geoquadmesh::{
|
||||||
|
GeoQuadMeshModule, GeoQuadMeshModuleConfig, GeoQuadMeshModuleConfigComponent,
|
||||||
|
GeoQuadMeshModuleConfigComponentWidgets, GeoQuadMeshModuleRef, GeoQuadMeshPackage,
|
||||||
|
};
|
||||||
pub use ppi::{
|
pub use ppi::{
|
||||||
PPIModule, PPIModuleConfigComponent, PPIModuleConfigComponentWidgets, PPIModuleRef, PPIPackage,
|
PPIModule, PPIModuleConfigComponent, PPIModuleConfigComponentWidgets, PPIModuleRef, PPIPackage,
|
||||||
};
|
};
|
||||||
@ -23,40 +29,54 @@ use relm4::Component as RComponent;
|
|||||||
use super::{layout_type::ViewPort, SideBarInputMsg};
|
use super::{layout_type::ViewPort, SideBarInputMsg};
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct Attach {
|
pub(crate) struct Attach {
|
||||||
gl: GL,
|
gl: GL,
|
||||||
pub vao: RcGlRcVertexArray,
|
pub vao: RcGlRcVertexArray,
|
||||||
pub vbo: RcGlRcBuffer,
|
pub vbo: RcGlRcBuffer,
|
||||||
pub ebo: Option<RcGlRcBuffer>,
|
pub ebo: Option<RcGlRcBuffer>,
|
||||||
|
pub textures: Option<RcGlRcResource<NativeTexture>>,
|
||||||
pub len: i32,
|
pub len: i32,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Attach {
|
impl Attach {
|
||||||
fn new(
|
pub fn new(
|
||||||
gl: GL,
|
gl: GL,
|
||||||
vao: NativeVertexArray,
|
vao: NativeVertexArray,
|
||||||
vbo: NativeBuffer,
|
vbo: NativeBuffer,
|
||||||
ebo: Option<NativeBuffer>,
|
ebo: Option<NativeBuffer>,
|
||||||
|
texs: Option<NativeTexture>,
|
||||||
len: Option<i32>,
|
len: Option<i32>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let vao = gl.create_resource_rc_with(vao);
|
let vao = gl.create_resource_rc_with(vao);
|
||||||
let vbo = gl.create_resource_rc_with(vbo);
|
let vbo = gl.create_resource_rc_with(vbo);
|
||||||
let ebo = ebo.map(|ebo| gl.create_resource_rc_with(ebo));
|
let ebo = ebo.map(|ebo| gl.create_resource_rc_with(ebo));
|
||||||
|
let textures = texs.map(|texs| gl.create_resource_rc_with(texs));
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
gl,
|
gl,
|
||||||
vao,
|
vao,
|
||||||
vbo,
|
vbo,
|
||||||
ebo,
|
ebo,
|
||||||
|
textures,
|
||||||
len: len.unwrap_or(0),
|
len: len.unwrap_or(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_self(&self) {
|
fn bind_self(&self, program: &Program) {
|
||||||
self.vao.bind(glow::VERTEX_ARRAY);
|
self.vao.bind(glow::VERTEX_ARRAY);
|
||||||
self.vbo.bind(glow::ARRAY_BUFFER);
|
self.vbo.bind(glow::ARRAY_BUFFER);
|
||||||
if let Some(ebo) = self.ebo.as_ref() {
|
if let Some(ebo) = self.ebo.as_ref() {
|
||||||
ebo.bind(glow::ELEMENT_ARRAY_BUFFER);
|
ebo.bind(glow::ELEMENT_ARRAY_BUFFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(tex) = self.textures.as_ref() {
|
||||||
|
unsafe {
|
||||||
|
self.gl.active_texture(glow::TEXTURE0);
|
||||||
|
self.gl.bind_texture(glow::TEXTURE_3D, Some(tex.native()));
|
||||||
|
let loc = program.get_uniform_location(&self.gl, "_texture");
|
||||||
|
self.gl.uniform_1_i32(loc.as_ref(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unbind_self(&self) {
|
fn unbind_self(&self) {
|
||||||
@ -67,7 +87,7 @@ impl Attach {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_data(&mut self, vbo: &Vec<f32>, ebo: Option<&Vec<u32>>, len: i32, usage: u32) {
|
pub fn bind_data(&mut self, vbo: &Vec<f32>, ebo: Option<&Vec<u32>>, len: i32, usage: u32) {
|
||||||
use bytemuck::cast_slice;
|
use bytemuck::cast_slice;
|
||||||
self.vbo.bind(glow::ARRAY_BUFFER);
|
self.vbo.bind(glow::ARRAY_BUFFER);
|
||||||
unsafe {
|
unsafe {
|
||||||
@ -108,6 +128,8 @@ pub trait Module: Sized {
|
|||||||
) -> Result<()>;
|
) -> Result<()>;
|
||||||
|
|
||||||
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor>;
|
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor>;
|
||||||
|
|
||||||
|
fn supported(&self, data: &Data) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ModuleCursor {
|
pub trait ModuleCursor {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
pg::SideBarInputMsg,
|
pg::SideBarInputMsg,
|
||||||
GL,
|
GL,
|
||||||
};
|
};
|
||||||
use radarg_core::config::Setting;
|
use radarg_core::{config::Setting, CoordType};
|
||||||
use relm4::{
|
use relm4::{
|
||||||
adw::{self, prelude::*},
|
adw::{self, prelude::*},
|
||||||
gtk::{self, prelude::*},
|
gtk::{self, prelude::*},
|
||||||
@ -41,6 +41,7 @@ pub struct PPIModule<'b, 'gl: 'b> {
|
|||||||
text_program: &'b mut Text,
|
text_program: &'b mut Text,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy)]
|
||||||
pub struct PPIModuleRef<'b, 'gl: 'b> {
|
pub struct PPIModuleRef<'b, 'gl: 'b> {
|
||||||
gl: &'gl GL,
|
gl: &'gl GL,
|
||||||
ppi_program: &'b PPI,
|
ppi_program: &'b PPI,
|
||||||
@ -65,10 +66,8 @@ impl<'b, 'a: 'b> PPIModuleRef<'b, 'a> {
|
|||||||
data: &RadarGridData,
|
data: &RadarGridData,
|
||||||
config: &PPIModuleConfig,
|
config: &PPIModuleConfig,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (vbo, ebo, len) = self
|
self.ppi_program
|
||||||
.ppi_program
|
.bake(&self.gl, data, &config.to_ppi_config(), attach)?;
|
||||||
.bake(&self.gl, data, &config.to_ppi_config())?;
|
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::DYNAMIC_DRAW);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,8 +125,8 @@ impl<'b, 'a: 'b> PPIModuleRef<'b, 'a> {
|
|||||||
paths.push(path);
|
paths.push(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (vbo, ebo, len) = self.line_program.bake(&self.gl, &paths, &raw_config)?;
|
self.line_program
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
.bake(&self.gl, &paths, &raw_config, attach)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,10 +144,9 @@ impl<'b, 'a: 'b> PPIModuleRef<'b, 'a> {
|
|||||||
let position_text =
|
let position_text =
|
||||||
PositionText::new(new_text, [0.0, 0.0, 0.0], Anchor::BottomCenter);
|
PositionText::new(new_text, [0.0, 0.0, 0.0], Anchor::BottomCenter);
|
||||||
let text_pg_config = config.to_font_config();
|
let text_pg_config = config.to_font_config();
|
||||||
let (vbo, ebo, len) =
|
|
||||||
self.text_program
|
self.text_program
|
||||||
.bake(&self.gl, &position_text, &text_pg_config)?;
|
.bake(&self.gl, &position_text, &text_pg_config, attach)?;
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,6 +156,19 @@ impl<'b, 'a: 'b> PPIModuleRef<'b, 'a> {
|
|||||||
pub fn name(&self) -> &'static str {
|
pub fn name(&self) -> &'static str {
|
||||||
"PPI"
|
"PPI"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn supported(&self, data: &radarg_core::Data) -> bool {
|
||||||
|
let data: std::result::Result<&RadarGridData, radarg_core::errors::DataError> =
|
||||||
|
data.try_into();
|
||||||
|
if let Ok(data) = data {
|
||||||
|
match data.coord_type() {
|
||||||
|
Some(CoordType::Polar { .. }) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
||||||
@ -182,11 +193,8 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
|||||||
data: &RadarGridData,
|
data: &RadarGridData,
|
||||||
config: &PPIModuleConfig,
|
config: &PPIModuleConfig,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let (vbo, ebo, len) = self
|
self.ppi_program
|
||||||
.ppi_program
|
.bake(&self.gl, data, &config.to_ppi_config(), attach)
|
||||||
.bake(&self.gl, data, &config.to_ppi_config())?;
|
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::DYNAMIC_DRAW);
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bind_line_pg(
|
fn bind_line_pg(
|
||||||
@ -243,8 +251,8 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
|||||||
paths.push(path);
|
paths.push(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (vbo, ebo, len) = self.line_program.bake(&self.gl, &paths, &raw_config)?;
|
self.line_program
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
.bake(&self.gl, &paths, &raw_config, attach)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,10 +270,9 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
|
|||||||
let position_text =
|
let position_text =
|
||||||
PositionText::new(new_text, [0.0, 0.0, 0.0], Anchor::BottomCenter);
|
PositionText::new(new_text, [0.0, 0.0, 0.0], Anchor::BottomCenter);
|
||||||
let text_pg_config = config.to_font_config();
|
let text_pg_config = config.to_font_config();
|
||||||
let (vbo, ebo, len) =
|
|
||||||
self.text_program
|
self.text_program
|
||||||
.bake(&self.gl, &position_text, &text_pg_config)?;
|
.bake(&self.gl, &position_text, &text_pg_config, attach)?;
|
||||||
attach.bind_data(&vbo, ebo.as_ref(), len, glow::STATIC_DRAW);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +314,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// PPI Draw
|
// PPI Draw
|
||||||
ppi_attach.bind_self();
|
ppi_attach.bind_self(&self.ppi_program.program_ref());
|
||||||
self.ppi_program.draw(&self.gl, ppi_attach.len())?;
|
self.ppi_program.draw(&self.gl, ppi_attach.len())?;
|
||||||
ppi_attach.unbind_self();
|
ppi_attach.unbind_self();
|
||||||
|
|
||||||
@ -336,7 +343,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
|
|
||||||
// PPI Tick Draw
|
// PPI Tick Draw
|
||||||
let attach = &mut cursor.line_attach;
|
let attach = &mut cursor.line_attach;
|
||||||
attach.bind_self();
|
attach.bind_self(self.line_program.program_ref());
|
||||||
self.line_program.draw(&self.gl, attach.len())?;
|
self.line_program.draw(&self.gl, attach.len())?;
|
||||||
attach.unbind_self();
|
attach.unbind_self();
|
||||||
|
|
||||||
@ -351,7 +358,7 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
self.text_program
|
self.text_program
|
||||||
.set_config(&self.gl, &config.to_font_config());
|
.set_config(&self.gl, &config.to_font_config());
|
||||||
|
|
||||||
tick_attach.bind_self();
|
tick_attach.bind_self(self.text_program.program_ref());
|
||||||
self.text_program.draw(&self.gl, tick_attach.len())?;
|
self.text_program.draw(&self.gl, tick_attach.len())?;
|
||||||
tick_attach.unbind_self();
|
tick_attach.unbind_self();
|
||||||
|
|
||||||
@ -362,8 +369,8 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
|
|
||||||
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
|
fn load_data<'dt>(&self, data: &Arc<Self::Data>, setting: &Setting) -> Result<Self::Cursor> {
|
||||||
// Init the memory
|
// Init the memory
|
||||||
let (vao, vbo, ebo) = self.ppi_program.init(&self.gl);
|
let (vao, vbo, ebo, texs) = self.ppi_program.init(&self.gl);
|
||||||
let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
|
let mut ppi_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
// Get the data info
|
// Get the data info
|
||||||
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?;
|
let (r, a, t, max_layer, unvalid) = self.ppi_program.data_info(&data)?;
|
||||||
@ -383,12 +390,12 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
let cmap = cmap.unwrap();
|
let cmap = cmap.unwrap();
|
||||||
|
|
||||||
// Init the memory for the line program
|
// Init the memory for the line program
|
||||||
let (vao, vbo, ebo) = self.line_program.init(&self.gl);
|
let (vao, vbo, ebo, texs) = self.line_program.init(&self.gl);
|
||||||
let mut line_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
|
let mut line_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
// Tick Label
|
// Tick Label
|
||||||
let (vao, vbo, ebo) = self.text_program.init(&self.gl);
|
let (vao, vbo, ebo, texs) = self.text_program.init(&self.gl);
|
||||||
let mut tick_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, None);
|
let mut tick_attach = Attach::new(self.gl.clone(), vao, vbo, ebo, texs, None);
|
||||||
|
|
||||||
let mut config = PPIModuleConfig::default();
|
let mut config = PPIModuleConfig::default();
|
||||||
config.rdpi = r;
|
config.rdpi = r;
|
||||||
@ -412,6 +419,19 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
|
|||||||
data,
|
data,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn supported(&self, data: &radarg_core::Data) -> bool {
|
||||||
|
let data: std::result::Result<&RadarGridData, radarg_core::errors::DataError> =
|
||||||
|
data.try_into();
|
||||||
|
if let Ok(data) = data {
|
||||||
|
match data.coord_type() {
|
||||||
|
Some(CoordType::Polar { .. }) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|||||||
91
gi/src/shaders/geoquadmesh.rs
Normal file
91
gi/src/shaders/geoquadmesh.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
use super::colormap::ColorMap;
|
||||||
|
use super::trackball::Trackball;
|
||||||
|
use super::CodePiece;
|
||||||
|
use crate::impl_code_piece;
|
||||||
|
use glsl::syntax::{ShaderStage, TranslationUnit};
|
||||||
|
use glsl::transpiler::glsl::show_translation_unit;
|
||||||
|
use glsl_quasiquote::glsl;
|
||||||
|
|
||||||
|
use super::proj::Mercator;
|
||||||
|
|
||||||
|
pub struct GeoQuadMeshVertex(pub ShaderStage);
|
||||||
|
pub struct GeoQuadMeshGeom(pub ShaderStage);
|
||||||
|
pub struct GeoQuadMeshFragment(pub ShaderStage);
|
||||||
|
|
||||||
|
impl GeoQuadMeshVertex {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut mercator = Mercator::new().0;
|
||||||
|
let mut trackball = Trackball::new().0;
|
||||||
|
let raw = glsl! {
|
||||||
|
// Position (x, y, z) --- x, y are longitude and latitude, z is the Altitude.
|
||||||
|
layout(location = 0) in vec3 in_position;
|
||||||
|
layout(location = 1) in vec3 relative_position;
|
||||||
|
|
||||||
|
out vec2 projected_meter;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 projected = mercatorProject(in_position.xy);
|
||||||
|
projected_meter = projected;
|
||||||
|
gl_Position = transform(position(relative_position));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
mercator.extend(trackball);
|
||||||
|
mercator.extend(raw);
|
||||||
|
Self(mercator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GeoQuadMeshFragment {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let mut mercator = Mercator::new().0;
|
||||||
|
|
||||||
|
let color_map = ColorMap::new().0;
|
||||||
|
|
||||||
|
let raw = glsl! {
|
||||||
|
// lon_s,lon_e, lat_s, lat_e
|
||||||
|
uniform vec4 tex_conf;
|
||||||
|
|
||||||
|
// lon_reso, lat_reso, alt_reso
|
||||||
|
uniform vec4 data_info;
|
||||||
|
|
||||||
|
// Current layer
|
||||||
|
uniform float layer;
|
||||||
|
|
||||||
|
out vec4 fragColor;
|
||||||
|
in vec2 projected_meter;
|
||||||
|
|
||||||
|
// data array
|
||||||
|
uniform sampler3D _texture;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec2 lon_lat = mercatorInverse(projected_meter);
|
||||||
|
|
||||||
|
vec3 tex_coord = vec3(lon_lat.x / tex_conf.z, lon_lat.y / tex_conf.w, layer / tex_conf.x);
|
||||||
|
|
||||||
|
float value = texture(_texture, tex_coord).r;
|
||||||
|
|
||||||
|
vec4 color = linear_colormap(value);
|
||||||
|
|
||||||
|
fragColor = vec4(1.0,1.0,1.0,1.0);
|
||||||
|
|
||||||
|
// if (color.a < 0.1) {
|
||||||
|
// discard;
|
||||||
|
// } else {
|
||||||
|
// fragColor = color;
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mercator.extend(color_map);
|
||||||
|
mercator.extend(raw);
|
||||||
|
|
||||||
|
Self(mercator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_code_piece!(GeoQuadMeshVertex, 0);
|
||||||
|
impl_code_piece!(GeoQuadMeshFragment, 0);
|
||||||
@ -1,9 +1,11 @@
|
|||||||
pub mod agg_path;
|
pub mod agg_path;
|
||||||
pub mod colormap;
|
pub mod colormap;
|
||||||
pub mod font;
|
pub mod font;
|
||||||
|
pub mod geoquadmesh;
|
||||||
pub mod math;
|
pub mod math;
|
||||||
pub mod polar;
|
pub mod polar;
|
||||||
pub mod ppi;
|
pub mod ppi;
|
||||||
|
pub mod proj;
|
||||||
pub mod trackball;
|
pub mod trackball;
|
||||||
use glsl::{
|
use glsl::{
|
||||||
syntax::{ShaderStage, TranslationUnit},
|
syntax::{ShaderStage, TranslationUnit},
|
||||||
|
|||||||
45
gi/src/shaders/proj.rs
Normal file
45
gi/src/shaders/proj.rs
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
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 Mercator(pub ShaderStage);
|
||||||
|
|
||||||
|
impl Mercator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
let raw = glsl! {
|
||||||
|
|
||||||
|
uniform float R;
|
||||||
|
|
||||||
|
vec2 mercatorProject(vec2 loc) {
|
||||||
|
// 将经纬度从度转换为弧度
|
||||||
|
float lonRad = radians(loc.x);
|
||||||
|
float latRad = radians(loc.y);
|
||||||
|
|
||||||
|
// X轴投影 (线性映射经度)
|
||||||
|
float x = R * lonRad;
|
||||||
|
|
||||||
|
// Y轴投影 (非线性映射纬度)
|
||||||
|
float y = R * log(tan(latRad / 2.0 + radians(45.0)));
|
||||||
|
|
||||||
|
return vec2(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
vec2 mercatorInverse(vec2 loc) {
|
||||||
|
// 计算经度 (lon),线性反映射
|
||||||
|
float lon = degrees(loc.x / R); // 将弧度转换为度数
|
||||||
|
|
||||||
|
// 计算纬度 (lat),非线性反映射
|
||||||
|
float lat = degrees(2.0 * atan(exp(loc.y / R)) - radians(90.0));
|
||||||
|
|
||||||
|
return vec2(lon, lat); // 返回经纬度 (lon, lat)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Self(raw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_code_piece!(Mercator, 0);
|
||||||
@ -6,7 +6,7 @@ use std::{cell::RefCell, fmt::Debug, rc::Rc, sync::Arc};
|
|||||||
|
|
||||||
pub enum MonitorInputMsg {
|
pub enum MonitorInputMsg {
|
||||||
PushData(Value<Data>),
|
PushData(Value<Data>),
|
||||||
Draw(Arc<Data>),
|
Draw(&'static str, Arc<Data>),
|
||||||
Prepare(Vec<Arc<Data>>),
|
Prepare(Vec<Arc<Data>>),
|
||||||
KeyPress(u32),
|
KeyPress(u32),
|
||||||
KeyRelease(u32),
|
KeyRelease(u32),
|
||||||
@ -18,7 +18,7 @@ impl Debug for MonitorInputMsg {
|
|||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
MonitorInputMsg::QueueDraw => write!(f, "MonitorInputMsg::QueueDraw"),
|
MonitorInputMsg::QueueDraw => write!(f, "MonitorInputMsg::QueueDraw"),
|
||||||
MonitorInputMsg::Draw(data) => {
|
MonitorInputMsg::Draw(module, data) => {
|
||||||
write!(f, "MonitorInputMsg::Draw({:?})", data)
|
write!(f, "MonitorInputMsg::Draw({:?})", data)
|
||||||
}
|
}
|
||||||
MonitorInputMsg::Prepare(data) => {
|
MonitorInputMsg::Prepare(data) => {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use geo::k_nearest_concave_hull;
|
use geo::k_nearest_concave_hull;
|
||||||
use gi::graphics::transforms::plane::PlaneTrans;
|
use gi::graphics::transforms::plane::PlaneTrans;
|
||||||
use gi::pg::{Module, ModulePackage};
|
use gi::pg::{GeoQuadMeshModule, Module, ModulePackage, PPIModule};
|
||||||
use gi::ui::operation::Operation;
|
use gi::ui::operation::Operation;
|
||||||
use gtk::glib::clone;
|
use gtk::glib::clone;
|
||||||
|
|
||||||
@ -29,6 +29,43 @@ use slippy_map_tiles::Tile;
|
|||||||
use tokio::task;
|
use tokio::task;
|
||||||
use tracing::instrument::WithSubscriber;
|
use tracing::instrument::WithSubscriber;
|
||||||
|
|
||||||
|
macro_rules! impl_draw {
|
||||||
|
($slf:ident,$module_name:ident,$widgets:ident,$data:ident, $sender:ident, $({$module:ty | $method:ident }),+) => {
|
||||||
|
$widgets.renderer.get_gi(|gi| {
|
||||||
|
let data: &Data = &*$data;
|
||||||
|
|
||||||
|
match $module_name {
|
||||||
|
$(
|
||||||
|
<$module>::NAME => {
|
||||||
|
match gi.program().$method().load_data(data.try_into().unwrap(), &SETTING) {
|
||||||
|
Ok(package) => {
|
||||||
|
let package = Rc::new(RefCell::new(package.into()));
|
||||||
|
$slf.update_module_packages(|p| {
|
||||||
|
p.clear();
|
||||||
|
p.push((data.description.clone(), package));
|
||||||
|
});
|
||||||
|
$sender.output(MonitorOutputMsg::Attached($slf.module_packages.clone()));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
error!("Error loading data: {:?}", e);
|
||||||
|
$sender.output(MonitorOutputMsg::Alert(e.to_string(), format!("Close")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)+
|
||||||
|
_ => {
|
||||||
|
error!("Unsupported module: {}", $module_name);
|
||||||
|
$sender.output(MonitorOutputMsg::Alert(
|
||||||
|
format!("Unsupported module: {}", $module_name),
|
||||||
|
format!("Close"),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$sender.input(MonitorInputMsg::QueueDraw);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum MonitorCommand {
|
pub enum MonitorCommand {
|
||||||
LoadedTile,
|
LoadedTile,
|
||||||
@ -116,7 +153,10 @@ impl Component for MonitorModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if result.len() == 1 && result.values().next().unwrap().len() == 1 {
|
if result.len() == 1 && result.values().next().unwrap().len() == 1 {
|
||||||
sender.input(MonitorInputMsg::Draw(data.values().next().unwrap().clone()));
|
sender.input(MonitorInputMsg::Draw(
|
||||||
|
result.values().next().unwrap().first().unwrap().module_name,
|
||||||
|
data.values().next().unwrap().clone(),
|
||||||
|
));
|
||||||
} else {
|
} else {
|
||||||
let new_sender = sender.clone();
|
let new_sender = sender.clone();
|
||||||
let dialog = Dialog::builder().launch(result).forward(
|
let dialog = Dialog::builder().launch(result).forward(
|
||||||
@ -155,18 +195,15 @@ impl Component for MonitorModel {
|
|||||||
widgets.renderer.queue_render();
|
widgets.renderer.queue_render();
|
||||||
}
|
}
|
||||||
|
|
||||||
// MonitorInputMsg::KeyPress(key) => {
|
|
||||||
// widgets.renderer.set_key_pressed(key);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// MonitorInputMsg::KeyRelease(key) => {
|
|
||||||
// widgets.renderer.set_key_released(key);
|
|
||||||
// }
|
|
||||||
MonitorInputMsg::Prepare(datas) => widgets.renderer.get_gi(|gi| {
|
MonitorInputMsg::Prepare(datas) => widgets.renderer.get_gi(|gi| {
|
||||||
let mut packages: Vec<(String, Rc<RefCell<ModulePackage>>)> = vec![];
|
let mut packages: Vec<(String, Rc<RefCell<ModulePackage>>)> = vec![];
|
||||||
for data in datas {
|
for data in datas {
|
||||||
let data = &*data;
|
let data = &*data;
|
||||||
match gi.program().ppi().load_data(data.into(), &SETTING) {
|
match gi
|
||||||
|
.program()
|
||||||
|
.ppi()
|
||||||
|
.load_data(data.try_into().unwrap(), &SETTING)
|
||||||
|
{
|
||||||
Ok(package) => {
|
Ok(package) => {
|
||||||
let package = Rc::new(RefCell::new(package.into()));
|
let package = Rc::new(RefCell::new(package.into()));
|
||||||
packages.push((data.description.clone(), package));
|
packages.push((data.description.clone(), package));
|
||||||
@ -187,25 +224,10 @@ impl Component for MonitorModel {
|
|||||||
sender.output(MonitorOutputMsg::Attached(self.module_packages.clone()));
|
sender.output(MonitorOutputMsg::Attached(self.module_packages.clone()));
|
||||||
sender.output(MonitorOutputMsg::DialogClose);
|
sender.output(MonitorOutputMsg::DialogClose);
|
||||||
}),
|
}),
|
||||||
MonitorInputMsg::Draw(ref data) => {
|
MonitorInputMsg::Draw(module, ref data) => {
|
||||||
// widgets.renderer.get_gi(|gi| {
|
impl_draw!(self, module, widgets, data, sender, { PPIModule | ppi }, {
|
||||||
// let data: &Data = &*data;
|
GeoQuadMeshModule | geo_quad_mesh
|
||||||
|
});
|
||||||
// match gi.program().ppi().load_data(data.into(), &SETTING) {
|
|
||||||
// Ok(package) => {
|
|
||||||
// let package = Rc::new(RefCell::new(package.into()));
|
|
||||||
// self.set_module_packages(vec![package.clone()]);
|
|
||||||
// sender.output(MonitorOutputMsg::Attached(package));
|
|
||||||
// }
|
|
||||||
// Err(e) => {
|
|
||||||
// error!("Error loading data: {:?}", e);
|
|
||||||
// sender.output(MonitorOutputMsg::Alert(e.to_string(), format!("Close")));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// sender.input(MonitorInputMsg::QueueDraw);
|
|
||||||
// });
|
|
||||||
// sender.output(MonitorOutputMsg::DialogClose);
|
|
||||||
}
|
}
|
||||||
MonitorInputMsg::KeyPress(key) => {
|
MonitorInputMsg::KeyPress(key) => {
|
||||||
widgets.renderer.set_key_pressed(key);
|
widgets.renderer.set_key_pressed(key);
|
||||||
|
|||||||
@ -129,7 +129,6 @@ impl ObjectImpl for Render {
|
|||||||
impl WidgetImpl for Render {
|
impl WidgetImpl for Render {
|
||||||
fn realize(&self) {
|
fn realize(&self) {
|
||||||
self.parent_realize();
|
self.parent_realize();
|
||||||
self.ensure_canvas();
|
|
||||||
}
|
}
|
||||||
fn unrealize(&self) {
|
fn unrealize(&self) {
|
||||||
self.obj().make_current();
|
self.obj().make_current();
|
||||||
@ -158,6 +157,7 @@ impl GLAreaImpl for Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn render(&self, context: >k::gdk::GLContext) -> glib::Propagation {
|
fn render(&self, context: >k::gdk::GLContext) -> glib::Propagation {
|
||||||
|
self.ensure_canvas();
|
||||||
let viewport = self.viewport.borrow();
|
let viewport = self.viewport.borrow();
|
||||||
let viewport = viewport.as_ref().unwrap();
|
let viewport = viewport.as_ref().unwrap();
|
||||||
|
|
||||||
@ -172,9 +172,22 @@ impl GLAreaImpl for Render {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Some(gi) = gi.as_mut() {
|
if let Some(gi) = gi.as_mut() {
|
||||||
|
let gl = &gi.context.gl;
|
||||||
|
unsafe {
|
||||||
|
let err = gl.get_error();
|
||||||
|
if err != glow::NO_ERROR {
|
||||||
|
panic!("GL Error: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut operation = self.opeartion.borrow_mut();
|
let mut operation = self.opeartion.borrow_mut();
|
||||||
let viewport = self.viewport.borrow();
|
let viewport = self.viewport.borrow();
|
||||||
operation.deal_io(&viewport.as_ref().unwrap(), &self.io.borrow());
|
operation.deal_io(&viewport.as_ref().unwrap(), &self.io.borrow());
|
||||||
|
unsafe {
|
||||||
|
let err = gl.get_error();
|
||||||
|
if err != glow::NO_ERROR {
|
||||||
|
panic!("GL Error: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
gi.render(
|
gi.render(
|
||||||
&mut *self.modules.borrow_mut(),
|
&mut *self.modules.borrow_mut(),
|
||||||
@ -183,7 +196,7 @@ impl GLAreaImpl for Render {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
viewport.unbind();
|
// viewport.unbind();
|
||||||
|
|
||||||
self.io.borrow_mut().reset();
|
self.io.borrow_mut().reset();
|
||||||
|
|
||||||
@ -195,10 +208,11 @@ impl Render {
|
|||||||
fn ensure_canvas(&self) {
|
fn ensure_canvas(&self) {
|
||||||
use gi::{App as GI, Helper, GL};
|
use gi::{App as GI, Helper, GL};
|
||||||
let widget = self.obj();
|
let widget = self.obj();
|
||||||
widget.make_current();
|
|
||||||
widget.attach_buffers();
|
|
||||||
if self.gi.borrow().is_none() {
|
if self.gi.borrow().is_none() {
|
||||||
info!("Creating canvas");
|
info!("Creating canvas");
|
||||||
|
widget.make_current();
|
||||||
|
widget.attach_buffers();
|
||||||
let (mut gi, viewport) = unsafe {
|
let (mut gi, viewport) = unsafe {
|
||||||
static LOAD_FN: fn(&str) -> *const std::ffi::c_void =
|
static LOAD_FN: fn(&str) -> *const std::ffi::c_void =
|
||||||
|s| epoxy::get_proc_addr(s) as *const _;
|
|s| epoxy::get_proc_addr(s) as *const _;
|
||||||
|
|||||||
@ -195,6 +195,6 @@ impl Render {
|
|||||||
pub fn draw(&self, packages: &Vec<Rc<RefCell<ModulePackage>>>) {
|
pub fn draw(&self, packages: &Vec<Rc<RefCell<ModulePackage>>>) {
|
||||||
let mut modules = self.imp().modules.borrow_mut();
|
let mut modules = self.imp().modules.borrow_mut();
|
||||||
*(&mut *modules) = packages.clone();
|
*(&mut *modules) = packages.clone();
|
||||||
self.queue_draw();
|
self.queue_render();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -142,6 +142,15 @@ pub enum CoordType<'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Display for CoordType<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
CoordType::Cartesian { .. } => write!(f, "Cartesian"),
|
||||||
|
CoordType::Polar { .. } => write!(f, "Polar"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for RadarGridData {
|
impl Display for RadarGridData {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
write!(f, "shape: {:?}, dimension_names: {:?}, fill_value: {}, datetime: {:?}, value_description: {:?}, value_name: {}, maybe_probe_data_type: {:?}, dimension_description: {}",
|
write!(f, "shape: {:?}, dimension_names: {:?}, fill_value: {}, datetime: {:?}, value_description: {:?}, value_name: {}, maybe_probe_data_type: {:?}, dimension_description: {}",
|
||||||
@ -300,11 +309,33 @@ impl From<LoadedData> for Data {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
impl<'a> From<&'a Data> for &'a Arc<RadarGridData> {
|
// impl<'a> From<&'a Data> for &'a Arc<RadarGridData> {
|
||||||
fn from(data: &'a Data) -> Self {
|
// fn from(data: &'a Data) -> Self {
|
||||||
match &data._data {
|
// match &data._data {
|
||||||
_Data::RadarGridData(v) => v,
|
// _Data::RadarGridData(v) => v,
|
||||||
_ => panic!("Unsupported data type"),
|
// _ => panic!("Unsupported data type"),
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
impl<'a> TryFrom<&'a Data> for &'a Arc<RadarGridData> {
|
||||||
|
type Error = crate::errors::DataError;
|
||||||
|
|
||||||
|
fn try_from(value: &'a Data) -> Result<Self, Self::Error> {
|
||||||
|
match &value._data {
|
||||||
|
_Data::RadarGridData(v) => Ok(&v),
|
||||||
|
_ => Err(crate::errors::DataError::FormatError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TryFrom<&'a Data> for &'a RadarGridData {
|
||||||
|
type Error = crate::errors::DataError;
|
||||||
|
|
||||||
|
fn try_from(value: &'a Data) -> Result<Self, Self::Error> {
|
||||||
|
match &value._data {
|
||||||
|
_Data::RadarGridData(v) => Ok(&*v),
|
||||||
|
_ => Err(crate::errors::DataError::FormatError),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user