layout manager test
This commit is contained in:
parent
4041190f57
commit
99c3bf35d7
844
Cargo.lock
generated
844
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -45,6 +45,8 @@ async-trait = "0.1.77"
|
|||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
once_cell = "1.19.0"
|
once_cell = "1.19.0"
|
||||||
relm4-icons = {version="0.6.0",features=["add-filled","delete-filled","chevron-up-filled","chevron-down-filled"]}
|
relm4-icons = {version="0.6.0",features=["add-filled","delete-filled","chevron-up-filled","chevron-down-filled"]}
|
||||||
|
surfman = "0.8.1"
|
||||||
|
euclid = "0.22.9"
|
||||||
# plotters-cairo = "0.5.0"
|
# plotters-cairo = "0.5.0"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
80
back.txt
80
back.txt
@ -263,3 +263,83 @@ pub enum CoordType {
|
|||||||
Polar,
|
Polar,
|
||||||
LatLon,
|
LatLon,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// let levels: Vec<i8> = vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65];
|
||||||
|
// let colors = vec![
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(0 as f32 / 255.0)
|
||||||
|
// .green(172 as f32 / 255.0)
|
||||||
|
// .blue(164 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(192 as f32 / 255.0)
|
||||||
|
// .green(192 as f32 / 255.0)
|
||||||
|
// .blue(254 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(122 as f32 / 255.0)
|
||||||
|
// .green(114 as f32 / 255.0)
|
||||||
|
// .blue(238 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(30 as f32 / 255.0)
|
||||||
|
// .green(38 as f32 / 255.0)
|
||||||
|
// .blue(208 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(166 as f32 / 255.0)
|
||||||
|
// .green(252 as f32 / 255.0)
|
||||||
|
// .blue(168 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(0 as f32 / 255.0)
|
||||||
|
// .green(234 as f32 / 255.0)
|
||||||
|
// .blue(0 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(16 as f32 / 255.0)
|
||||||
|
// .green(146 as f32 / 255.0)
|
||||||
|
// .blue(26 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(252 as f32 / 255.0)
|
||||||
|
// .green(244 as f32 / 255.0)
|
||||||
|
// .blue(100 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(200 as f32 / 255.0)
|
||||||
|
// .green(200 as f32 / 255.0)
|
||||||
|
// .blue(2 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(140 as f32 / 255.0)
|
||||||
|
// .green(140 as f32 / 255.0)
|
||||||
|
// .blue(0 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(254 as f32 / 255.0)
|
||||||
|
// .green(172 as f32 / 255.0)
|
||||||
|
// .blue(172 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(254 as f32 / 255.0)
|
||||||
|
// .green(100 as f32 / 255.0)
|
||||||
|
// .blue(92 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(238 as f32 / 255.0)
|
||||||
|
// .green(2 as f32 / 255.0)
|
||||||
|
// .blue(48 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(212 as f32 / 255.0)
|
||||||
|
// .green(142 as f32 / 255.0)
|
||||||
|
// .blue(254 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// RGBABuilder::default()
|
||||||
|
// .red(170 as f32 / 255.0)
|
||||||
|
// .green(36 as f32 / 255.0)
|
||||||
|
// .blue(250 as f32 / 255.0)
|
||||||
|
// .build(),
|
||||||
|
// ];
|
||||||
|
|||||||
@ -1,11 +1,15 @@
|
|||||||
use adw::subclass::bin::BinImpl;
|
use adw::subclass::bin::BinImpl;
|
||||||
|
use glib::Properties;
|
||||||
use gtk::glib::prelude::*;
|
use gtk::glib::prelude::*;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::subclass::prelude::*;
|
use gtk::subclass::prelude::*;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::{Cell, RefCell};
|
||||||
use std::num::NonZeroU32;
|
use std::num::NonZeroU32;
|
||||||
|
|
||||||
|
#[derive(Properties)]
|
||||||
|
#[properties(wrapper_type = super::DynamicCol)]
|
||||||
pub struct DynamicCol {
|
pub struct DynamicCol {
|
||||||
|
#[property(get, set)]
|
||||||
pub(super) child: RefCell<Option<gtk::Paned>>,
|
pub(super) child: RefCell<Option<gtk::Paned>>,
|
||||||
pub(super) ratio: RefCell<Option<f64>>,
|
pub(super) ratio: RefCell<Option<f64>>,
|
||||||
width: Cell<i32>,
|
width: Cell<i32>,
|
||||||
@ -33,6 +37,11 @@ impl ObjectSubclass for DynamicCol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectImpl for DynamicCol {
|
impl ObjectImpl for DynamicCol {
|
||||||
|
|
||||||
|
fn constructed(&self) {
|
||||||
|
self.parent_constructed();
|
||||||
|
}
|
||||||
|
|
||||||
fn dispose(&self) {
|
fn dispose(&self) {
|
||||||
if let Some(child) = self.child.borrow_mut().take() {
|
if let Some(child) = self.child.borrow_mut().take() {
|
||||||
child.unparent();
|
child.unparent();
|
||||||
|
|||||||
10
src/main.rs
10
src/main.rs
@ -1,10 +1,12 @@
|
|||||||
mod utils;
|
mod utils;
|
||||||
use gtk::prelude::*;
|
use gtk::prelude::*;
|
||||||
use gtk::{gio, glib, Application, ApplicationWindow};
|
use gtk::{gio, glib, Application, ApplicationWindow};
|
||||||
|
use pipeline::offscreen_renderer::OffscreenRenderer;
|
||||||
use relm4::menu;
|
use relm4::menu;
|
||||||
use relm4::RelmApp;
|
use relm4::RelmApp;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use tokio::runtime::Runtime;
|
use tokio::runtime::Runtime;
|
||||||
|
use utils::creator;
|
||||||
mod chart;
|
mod chart;
|
||||||
mod components;
|
mod components;
|
||||||
mod coords;
|
mod coords;
|
||||||
@ -23,14 +25,16 @@ const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
|||||||
static RUNTIME: Lazy<Runtime> =
|
static RUNTIME: Lazy<Runtime> =
|
||||||
Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
Lazy::new(|| Runtime::new().expect("Setting up tokio runtime needs to succeed."));
|
||||||
|
|
||||||
|
static OFFSCREEN: Lazy<OffscreenRenderer> = Lazy::new(|| OffscreenRenderer::new().expect("Can't create offscreen renderer."));
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Load GL pointers from epoxy (GL context management library used by GTK).
|
// Load GL pointers from epoxy (GL context management library used by GTK).
|
||||||
{
|
{
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
let library =
|
let library =
|
||||||
unsafe { libloading::os::unix::Library::new("/opt/homebrew/lib/libepoxy.0.dylib") }.or(unsafe{
|
unsafe { libloading::os::unix::Library::new("/opt/homebrew/lib/libepoxy.0.dylib") }
|
||||||
libloading::os::unix::Library::new("libepoxy.0.dylib")
|
.or(unsafe { libloading::os::unix::Library::new("libepoxy.0.dylib") })
|
||||||
}).unwrap();
|
.unwrap();
|
||||||
|
|
||||||
#[cfg(all(unix, not(target_os = "macos")))]
|
#[cfg(all(unix, not(target_os = "macos")))]
|
||||||
let library = unsafe { libloading::os::unix::Library::new("libepoxy.so.0") }.unwrap();
|
let library = unsafe { libloading::os::unix::Library::new("libepoxy.so.0") }.unwrap();
|
||||||
|
|||||||
@ -5,6 +5,7 @@ use image::RgbImage;
|
|||||||
use ndarray::parallel::prelude::*;
|
use ndarray::parallel::prelude::*;
|
||||||
use ndarray::{Array2, ArrayView2};
|
use ndarray::{Array2, ArrayView2};
|
||||||
use num_traits::{Num, AsPrimitive, FromPrimitive};
|
use num_traits::{Num, AsPrimitive, FromPrimitive};
|
||||||
|
pub mod offscreen_renderer;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
coords::Mapper,
|
coords::Mapper,
|
||||||
|
|||||||
79
src/pipeline/offscreen_renderer.rs
Normal file
79
src/pipeline/offscreen_renderer.rs
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
use euclid::Size2D;
|
||||||
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
use std::num::NonZeroU32;
|
||||||
|
use std::sync::{Mutex, RwLock};
|
||||||
|
use std::{cell::RefCell, sync::Arc};
|
||||||
|
use surfman::{device, Adapter, Connection, Context, Device, Error};
|
||||||
|
|
||||||
|
pub struct OffscreenRenderer {
|
||||||
|
context: Arc<RwLock<Context>>,
|
||||||
|
device: Device,
|
||||||
|
// renderer: Arc<Mutex<femtovg::renderer::OpenGl>>,
|
||||||
|
canvas: Arc<RwLock<Canvas<OpenGl>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OffscreenRenderer {
|
||||||
|
pub fn new() -> Result<Self, surfman::Error> {
|
||||||
|
let connection = Connection::new()?;
|
||||||
|
let adapter = connection.create_adapter()?;
|
||||||
|
let mut device = connection.create_device(&adapter)?;
|
||||||
|
|
||||||
|
let api = device.gl_api();
|
||||||
|
|
||||||
|
let descriptor = device.create_context_descriptor(&surfman::ContextAttributes {
|
||||||
|
version: surfman::GLVersion::new(3, 3),
|
||||||
|
flags: surfman::ContextAttributeFlags::empty(),
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let mut context = device.create_context(&descriptor, None)?;
|
||||||
|
let mut surface = device.create_surface(
|
||||||
|
&context,
|
||||||
|
surfman::SurfaceAccess::GPUOnly,
|
||||||
|
surfman::SurfaceType::Generic {
|
||||||
|
size: euclid::Size2D::new(500, 500),
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let surface_info = device.surface_info(&surface);
|
||||||
|
device
|
||||||
|
.bind_surface_to_context(&mut context, surface)
|
||||||
|
.expect("Failed to bind surface to context");
|
||||||
|
device.make_context_current(&context).unwrap();
|
||||||
|
|
||||||
|
static LOAD_FN: fn(&str) -> *const std::ffi::c_void =
|
||||||
|
|s| epoxy::get_proc_addr(s) as *const _;
|
||||||
|
|
||||||
|
let (mut renderer, fbo) = unsafe {
|
||||||
|
let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer");
|
||||||
|
let fbo =
|
||||||
|
glow::NativeFramebuffer(NonZeroU32::new(surface_info.framebuffer_object).unwrap());
|
||||||
|
(renderer, fbo)
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.set_screen_target(Some(fbo));
|
||||||
|
|
||||||
|
let mut canvas = Canvas::new(renderer).expect("Cannot create canvas");
|
||||||
|
canvas.set_size(500, 500, 1.0);
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
context: Arc::new(RwLock::new(context)),
|
||||||
|
device,
|
||||||
|
canvas: Arc::new(RwLock::new(canvas)),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn canvas(&self) -> Arc<RwLock<Canvas<OpenGl>>> {
|
||||||
|
self.canvas.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for OffscreenRenderer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
let mut context = self.context.write().unwrap();
|
||||||
|
self.device.destroy_context(&mut context).unwrap();
|
||||||
|
let _ = self;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for OffscreenRenderer {}
|
||||||
|
unsafe impl Sync for OffscreenRenderer {}
|
||||||
@ -8,6 +8,9 @@ pub struct CMS {
|
|||||||
bounds: (f64, f64, f64, f64),
|
bounds: (f64, f64, f64, f64),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe impl Send for CMS {}
|
||||||
|
unsafe impl Sync for CMS {}
|
||||||
|
|
||||||
impl CMS {
|
impl CMS {
|
||||||
pub fn new(mapper: Mapper, window_size: (f32, f32)) -> Self {
|
pub fn new(mapper: Mapper, window_size: (f32, f32)) -> Self {
|
||||||
let bounds = mapper.get_bounds();
|
let bounds = mapper.get_bounds();
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
use crate::render::cms::CMS;
|
||||||
use crate::{coords::Range, render::Render};
|
use crate::{coords::Range, render::Render};
|
||||||
use femtovg::Paint;
|
use femtovg::Paint;
|
||||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
||||||
@ -10,8 +11,15 @@ use std::{
|
|||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
type PrepareFunc =
|
type PrepareFunc = Box<
|
||||||
Box<dyn FnOnce(Arc<Layer>, Render) -> Pin<Box<dyn Future<Output = ()>>> + Sync + Send>;
|
dyn FnOnce(
|
||||||
|
Box<dyn LayerImpl>,
|
||||||
|
&mut Canvas<OpenGl>,
|
||||||
|
CMS,
|
||||||
|
) -> Pin<Box<dyn Future<Output = Target>>>
|
||||||
|
+ Sync
|
||||||
|
+ Send,
|
||||||
|
>;
|
||||||
type DrawFunc = Box<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
type DrawFunc = Box<dyn Fn(&Layer, Render, (f32, f32)) + Send + Sync>;
|
||||||
type LayerImplSync = Box<dyn LayerImpl + Send + Sync>;
|
type LayerImplSync = Box<dyn LayerImpl + Send + Sync>;
|
||||||
|
|
||||||
@ -37,14 +45,14 @@ impl Debug for Layer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait LayerImpl: Debug {
|
pub trait LayerImpl: Debug {
|
||||||
fn draw(&self, render: Render) -> Option<Target>;
|
fn draw(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS) -> Option<Target>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Layer {
|
impl Layer {
|
||||||
pub fn new<
|
pub fn new<
|
||||||
FU: Future<Output = ()> + 'static,
|
FU: Future<Output = Target> + Send + Sync + 'static,
|
||||||
F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync,
|
F: 'static + Fn(&Self, Render, (f32, f32)) + Send + Sync,
|
||||||
PREPARE: FnOnce(Arc<Layer>, Render) -> FU + Send + Sync + 'static,
|
PREPARE: FnOnce(Box<dyn LayerImpl>, &mut Canvas<OpenGl>, CMS) -> FU + Send + Sync + 'static,
|
||||||
IMP: LayerImpl + Sync + Send + 'static,
|
IMP: LayerImpl + Sync + Send + 'static,
|
||||||
>(
|
>(
|
||||||
visiable: bool,
|
visiable: bool,
|
||||||
|
|||||||
@ -190,4 +190,10 @@ impl Render {
|
|||||||
pub fn render_range(&self) -> ((f64, f64), (f64, f64)) {
|
pub fn render_range(&self) -> ((f64, f64), (f64, f64)) {
|
||||||
self.imp().window_range().unwrap()
|
self.imp().window_range().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn create_cms(&self) -> CMS {
|
||||||
|
let borrowed_mapper = &*self.imp().mapper.borrow();
|
||||||
|
let new_mapper = borrowed_mapper.clone();
|
||||||
|
CMS::new(new_mapper, (500.0, 500.0))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,7 @@
|
|||||||
use super::color_mapper::{BoundaryNorm, ColorMapper};
|
use super::color_mapper::{BoundaryNorm, ColorMapper};
|
||||||
use femtovg::{ImageFlags, Paint, Path, PixelFormat::Rgba8, RenderTarget};
|
use femtovg::{
|
||||||
|
renderer::OpenGl, Canvas, ImageFlags, Paint, Path, PixelFormat::Rgba8, RenderTarget,
|
||||||
|
};
|
||||||
use geo_types::LineString;
|
use geo_types::LineString;
|
||||||
use ndarray::ArrayView2;
|
use ndarray::ArrayView2;
|
||||||
use num_traits::{Num, NumOps};
|
use num_traits::{Num, NumOps};
|
||||||
@ -8,7 +10,7 @@ use std::{fmt::Debug, marker::PhantomData};
|
|||||||
use super::super::renders::DataRenderer;
|
use super::super::renders::DataRenderer;
|
||||||
use crate::{
|
use crate::{
|
||||||
data::Radar2d,
|
data::Radar2d,
|
||||||
render::{LayerImpl, Render, Target},
|
render::{cms::CMS, LayerImpl, Render, Target},
|
||||||
utils::meshgrid,
|
utils::meshgrid,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -32,8 +34,8 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
|||||||
fn draw_2d(
|
fn draw_2d(
|
||||||
&self,
|
&self,
|
||||||
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
||||||
|
cms: &CMS,
|
||||||
data: ArrayView2<T>,
|
data: ArrayView2<T>,
|
||||||
render: &Render,
|
|
||||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||||
window_size: (f32, f32),
|
window_size: (f32, f32),
|
||||||
fill_value: T,
|
fill_value: T,
|
||||||
@ -48,7 +50,6 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
|||||||
let d2_s = dim2[[0, 0]];
|
let d2_s = dim2[[0, 0]];
|
||||||
let d2_e = dim2[[rows - 1, 0]];
|
let d2_e = dim2[[rows - 1, 0]];
|
||||||
|
|
||||||
render.create_drawer((d1_s, d1_e, d2_s, d2_e), window_size, |cms| {
|
|
||||||
for r in 0..rows - 1 {
|
for r in 0..rows - 1 {
|
||||||
for c in 0..cols - 1 {
|
for c in 0..cols - 1 {
|
||||||
let lb_lat = dim2[[r, c]];
|
let lb_lat = dim2[[r, c]];
|
||||||
@ -86,7 +87,6 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
|||||||
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,47 +96,42 @@ where
|
|||||||
CMAP: ColorMapper<T>,
|
CMAP: ColorMapper<T>,
|
||||||
{
|
{
|
||||||
type Data = Radar2d<T>;
|
type Data = Radar2d<T>;
|
||||||
fn render(&self, render: Render, data: &Self::Data) -> Target {
|
|
||||||
let mut canvas = render.get_canvas();
|
|
||||||
let canvas = canvas.as_mut().unwrap();
|
|
||||||
|
|
||||||
let new_img = canvas
|
fn render(
|
||||||
.create_image_empty(3000, 3000, Rgba8, ImageFlags::empty())
|
&self,
|
||||||
.expect("Can't Create Image");
|
canvas: &mut Canvas<OpenGl>,
|
||||||
|
cms: &CMS,
|
||||||
canvas.save();
|
data: &Self::Data,
|
||||||
canvas.reset();
|
size: (f32, f32),
|
||||||
|
) -> Target {
|
||||||
if let Ok(_) = canvas.image_size(new_img) {
|
let (w, h) = size;
|
||||||
canvas.set_render_target(RenderTarget::Image(new_img));
|
|
||||||
let _data = data.data.view();
|
|
||||||
let (_dim1, _dim2) = meshgrid(data.dim1.view(), data.dim2.view());
|
|
||||||
self.draw_2d(
|
|
||||||
canvas,
|
|
||||||
_data,
|
|
||||||
&render,
|
|
||||||
(_dim1.view(), _dim2.view()),
|
|
||||||
(3000.0, 3000.0),
|
|
||||||
data.fill_value,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canvas.restore();
|
// fn render(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS, data: &Self::Data) -> Target {
|
||||||
canvas.set_render_target(RenderTarget::Screen);
|
// let _data = data.data.view();
|
||||||
|
// let (_dim1, _dim2) = meshgrid(data.dim1.view(), data.dim2.view());
|
||||||
|
// self.draw_2d(
|
||||||
|
// canvas,
|
||||||
|
// cms,
|
||||||
|
// _data,
|
||||||
|
// (_dim1.view(), _dim2.view()),
|
||||||
|
// (3000.0, 3000.0),
|
||||||
|
// data.fill_value,
|
||||||
|
// );
|
||||||
|
|
||||||
let d1_start = (data.dim1.view()).first().unwrap().clone();
|
// let d1_start = (data.dim1.view()).first().unwrap().clone();
|
||||||
let d1_end = (data.dim1.view()).last().unwrap().clone();
|
// let d1_end = (data.dim1.view()).last().unwrap().clone();
|
||||||
|
|
||||||
let d2_start = data.dim2.view().first().unwrap().clone();
|
// let d2_start = data.dim2.view().first().unwrap().clone();
|
||||||
let d2_end = data.dim2.view().last().unwrap().clone();
|
// let d2_end = data.dim2.view().last().unwrap().clone();
|
||||||
|
|
||||||
Target::new(
|
// Target::new(
|
||||||
new_img,
|
// new_img,
|
||||||
3000f32,
|
// 3000f32,
|
||||||
3000f32,
|
// 3000f32,
|
||||||
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
// ((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -166,7 +161,22 @@ where
|
|||||||
T: Num + NumOps + PartialOrd + Copy + Clone + Debug + Send + Sync,
|
T: Num + NumOps + PartialOrd + Copy + Clone + Debug + Send + Sync,
|
||||||
CMAP: ColorMapper<T> + Debug,
|
CMAP: ColorMapper<T> + Debug,
|
||||||
{
|
{
|
||||||
fn draw(&self, render: Render) -> Option<Target> {
|
fn draw(
|
||||||
Some(self.renderer.render(render, &self.data))
|
&self,
|
||||||
|
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
||||||
|
cms: &crate::render::cms::CMS,
|
||||||
|
) -> Option<Target> {
|
||||||
|
let new_img = canvas
|
||||||
|
.create_image_empty(3000, 3000, Rgba8, ImageFlags::empty())
|
||||||
|
.expect("Can't Create Image");
|
||||||
|
|
||||||
|
if let Ok(_) = canvas.image_size(new_img) {
|
||||||
|
canvas.reset();
|
||||||
|
canvas.set_render_target(RenderTarget::Image(new_img));
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.set_render_target(RenderTarget::Screen);
|
||||||
|
|
||||||
|
Some(self.renderer.render(Render::new(canvas, cms), &self.data))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,12 @@
|
|||||||
use femtovg::{renderer::OpenGl, Canvas, Paint};
|
use femtovg::{renderer::OpenGl, Canvas, Paint};
|
||||||
use num_traits::{Num, NumOps};
|
use num_traits::{Num, NumOps};
|
||||||
use std::path::Path;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::thread::spawn;
|
||||||
|
use std::{os::unix::thread, path::Path};
|
||||||
|
|
||||||
|
use crate::render::cms::CMS;
|
||||||
|
use crate::render::{LayerImpl, Target};
|
||||||
|
use crate::OFFSCREEN;
|
||||||
use crate::{
|
use crate::{
|
||||||
data::{AsyncDataLoader, DataLoader, Radar2d},
|
data::{AsyncDataLoader, DataLoader, Radar2d},
|
||||||
render::{Layer, Render},
|
render::{Layer, Render},
|
||||||
@ -33,12 +37,13 @@ impl Layer {
|
|||||||
path.rect(ox, oy, x, y);
|
path.rect(ox, oy, x, y);
|
||||||
c.fill_path(&path, &painter);
|
c.fill_path(&path, &painter);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if let Some(renderer) = s.get_imp().as_ref() {
|
},
|
||||||
|
layer_name,
|
||||||
|
Some(
|
||||||
|
|s_imp: Box<dyn LayerImpl>, c: &mut Canvas<OpenGl>, cms: CMS| async move {
|
||||||
|
if let Some(renderer) = s.as_ref() {
|
||||||
let img = renderer.draw(render.clone()).unwrap();
|
let img = renderer.draw(render.clone()).unwrap();
|
||||||
|
|
||||||
let mut c = render.get_canvas();
|
|
||||||
let c = c.as_mut().unwrap();
|
|
||||||
if let Ok(_) = c.image_size(img.target) {
|
if let Ok(_) = c.image_size(img.target) {
|
||||||
let (x, y) = img.size(&render);
|
let (x, y) = img.size(&render);
|
||||||
let (ox, oy) = img.origin(&render);
|
let (ox, oy) = img.origin(&render);
|
||||||
@ -50,14 +55,8 @@ impl Layer {
|
|||||||
c.fill_path(&path, &painter);
|
c.fill_path(&path, &painter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
},
|
},
|
||||||
layer_name,
|
),
|
||||||
Some(|s: Arc<Layer>, render: Render| async move {
|
|
||||||
if let None = s.render_target() {
|
|
||||||
if let Some(renderer) = s.get_imp().as_ref() {}
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)),
|
Some(GridLayerImpl::new(GridFieldRenderer::new(color_map), data)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,15 @@
|
|||||||
|
use super::cms::CMS;
|
||||||
use super::Render;
|
use super::Render;
|
||||||
use super::Target;
|
use super::Target;
|
||||||
use femtovg::{renderer::OpenGl, Canvas};
|
use femtovg::{renderer::OpenGl, Canvas};
|
||||||
|
|
||||||
pub trait DataRenderer {
|
pub trait DataRenderer {
|
||||||
type Data;
|
type Data;
|
||||||
fn render(&self, render: Render, data: &Self::Data) -> Target;
|
fn render(
|
||||||
|
&self,
|
||||||
|
canvas: &mut Canvas<OpenGl>,
|
||||||
|
cms: &CMS,
|
||||||
|
data: &Self::Data,
|
||||||
|
size: (f32, f32),
|
||||||
|
) -> Target;
|
||||||
}
|
}
|
||||||
|
|||||||
125
src/utils.rs
125
src/utils.rs
@ -1,4 +1,12 @@
|
|||||||
|
use std::{borrow::BorrowMut, num::NonZeroU32};
|
||||||
|
|
||||||
|
use euclid::Size2D;
|
||||||
|
use femtovg::Canvas;
|
||||||
use ndarray::{Array2, ArrayView1};
|
use ndarray::{Array2, ArrayView1};
|
||||||
|
use surfman::{
|
||||||
|
Connection, Context, ContextAttributeFlags, ContextAttributes, ContextDescriptor,
|
||||||
|
NativeConnection, NativeContext, SurfaceAccess, SurfaceType, Device, GLVersion,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn meshgrid<T>(x: ArrayView1<T>, y: ArrayView1<T>) -> (Array2<T>, Array2<T>)
|
pub fn meshgrid<T>(x: ArrayView1<T>, y: ArrayView1<T>) -> (Array2<T>, Array2<T>)
|
||||||
where
|
where
|
||||||
@ -10,81 +18,42 @@ where
|
|||||||
let yy = Array2::from_shape_fn(shape, |(i, _)| y[i].clone());
|
let yy = Array2::from_shape_fn(shape, |(i, _)| y[i].clone());
|
||||||
(xx, yy)
|
(xx, yy)
|
||||||
}
|
}
|
||||||
// let levels: Vec<i8> = vec![0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65];
|
|
||||||
// let colors = vec![
|
pub fn creator() {
|
||||||
// RGBABuilder::default()
|
let connection = Connection::new().unwrap();
|
||||||
// .red(0 as f32 / 255.0)
|
let adapter = connection.create_adapter().unwrap();
|
||||||
// .green(172 as f32 / 255.0)
|
let mut device = connection.create_device(&adapter).unwrap();
|
||||||
// .blue(164 as f32 / 255.0)
|
let api = device.gl_api();
|
||||||
// .build(),
|
let descriptor = device.create_context_descriptor(&ContextAttributes {
|
||||||
// RGBABuilder::default()
|
version: GLVersion::new(3, 3),
|
||||||
// .red(192 as f32 / 255.0)
|
flags: ContextAttributeFlags::empty(),
|
||||||
// .green(192 as f32 / 255.0)
|
}).unwrap();
|
||||||
// .blue(254 as f32 / 255.0)
|
|
||||||
// .build(),
|
let mut context = device.create_context(&descriptor, None).unwrap();
|
||||||
// RGBABuilder::default()
|
let mut surface = device
|
||||||
// .red(122 as f32 / 255.0)
|
.create_surface(
|
||||||
// .green(114 as f32 / 255.0)
|
&context,
|
||||||
// .blue(238 as f32 / 255.0)
|
SurfaceAccess::GPUOnly,
|
||||||
// .build(),
|
SurfaceType::Generic {
|
||||||
// RGBABuilder::default()
|
size: Size2D::new(500, 500),
|
||||||
// .red(30 as f32 / 255.0)
|
},
|
||||||
// .green(38 as f32 / 255.0)
|
)
|
||||||
// .blue(208 as f32 / 255.0)
|
.unwrap();
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
let surface_info = device.surface_info(&surface);
|
||||||
// .red(166 as f32 / 255.0)
|
device
|
||||||
// .green(252 as f32 / 255.0)
|
.bind_surface_to_context(&mut context, surface)
|
||||||
// .blue(168 as f32 / 255.0)
|
.expect("Failed to bind surface to context");
|
||||||
// .build(),
|
device.make_context_current(&context).unwrap();
|
||||||
// RGBABuilder::default()
|
use femtovg::renderer::OpenGl;
|
||||||
// .red(0 as f32 / 255.0)
|
static LOAD_FN: fn(&str) -> *const std::ffi::c_void = |s| epoxy::get_proc_addr(s) as *const _;
|
||||||
// .green(234 as f32 / 255.0)
|
let (mut renderer, fbo) = unsafe {
|
||||||
// .blue(0 as f32 / 255.0)
|
let renderer = OpenGl::new_from_function(LOAD_FN).expect("Cannot create renderer");
|
||||||
// .build(),
|
let fbo =
|
||||||
// RGBABuilder::default()
|
glow::NativeFramebuffer(NonZeroU32::new(surface_info.framebuffer_object).unwrap());
|
||||||
// .red(16 as f32 / 255.0)
|
(renderer, fbo)
|
||||||
// .green(146 as f32 / 255.0)
|
};
|
||||||
// .blue(26 as f32 / 255.0)
|
|
||||||
// .build(),
|
renderer.set_screen_target(Some(fbo));
|
||||||
// RGBABuilder::default()
|
device.destroy_context(&mut context);
|
||||||
// .red(252 as f32 / 255.0)
|
}
|
||||||
// .green(244 as f32 / 255.0)
|
|
||||||
// .blue(100 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(200 as f32 / 255.0)
|
|
||||||
// .green(200 as f32 / 255.0)
|
|
||||||
// .blue(2 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(140 as f32 / 255.0)
|
|
||||||
// .green(140 as f32 / 255.0)
|
|
||||||
// .blue(0 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(254 as f32 / 255.0)
|
|
||||||
// .green(172 as f32 / 255.0)
|
|
||||||
// .blue(172 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(254 as f32 / 255.0)
|
|
||||||
// .green(100 as f32 / 255.0)
|
|
||||||
// .blue(92 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(238 as f32 / 255.0)
|
|
||||||
// .green(2 as f32 / 255.0)
|
|
||||||
// .blue(48 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(212 as f32 / 255.0)
|
|
||||||
// .green(142 as f32 / 255.0)
|
|
||||||
// .blue(254 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// RGBABuilder::default()
|
|
||||||
// .red(170 as f32 / 255.0)
|
|
||||||
// .green(36 as f32 / 255.0)
|
|
||||||
// .blue(250 as f32 / 255.0)
|
|
||||||
// .build(),
|
|
||||||
// ];
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user