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"
|
||||
once_cell = "1.19.0"
|
||||
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"
|
||||
|
||||
|
||||
|
||||
82
back.txt
82
back.txt
@ -262,4 +262,84 @@ pub enum DownSampleMeth {
|
||||
pub enum CoordType {
|
||||
Polar,
|
||||
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 glib::Properties;
|
||||
use gtk::glib::prelude::*;
|
||||
use gtk::prelude::*;
|
||||
use gtk::subclass::prelude::*;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::num::NonZeroU32;
|
||||
|
||||
#[derive(Properties)]
|
||||
#[properties(wrapper_type = super::DynamicCol)]
|
||||
pub struct DynamicCol {
|
||||
#[property(get, set)]
|
||||
pub(super) child: RefCell<Option<gtk::Paned>>,
|
||||
pub(super) ratio: RefCell<Option<f64>>,
|
||||
width: Cell<i32>,
|
||||
@ -33,6 +37,11 @@ impl ObjectSubclass for DynamicCol {
|
||||
}
|
||||
|
||||
impl ObjectImpl for DynamicCol {
|
||||
|
||||
fn constructed(&self) {
|
||||
self.parent_constructed();
|
||||
}
|
||||
|
||||
fn dispose(&self) {
|
||||
if let Some(child) = self.child.borrow_mut().take() {
|
||||
child.unparent();
|
||||
|
||||
10
src/main.rs
10
src/main.rs
@ -1,10 +1,12 @@
|
||||
mod utils;
|
||||
use gtk::prelude::*;
|
||||
use gtk::{gio, glib, Application, ApplicationWindow};
|
||||
use pipeline::offscreen_renderer::OffscreenRenderer;
|
||||
use relm4::menu;
|
||||
use relm4::RelmApp;
|
||||
use std::ptr;
|
||||
use tokio::runtime::Runtime;
|
||||
use utils::creator;
|
||||
mod chart;
|
||||
mod components;
|
||||
mod coords;
|
||||
@ -23,14 +25,16 @@ const APP_ID: &str = "org.gtk_rs.HelloWorld2";
|
||||
static RUNTIME: Lazy<Runtime> =
|
||||
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() {
|
||||
// Load GL pointers from epoxy (GL context management library used by GTK).
|
||||
{
|
||||
#[cfg(target_os = "macos")]
|
||||
let library =
|
||||
unsafe { libloading::os::unix::Library::new("/opt/homebrew/lib/libepoxy.0.dylib") }.or(unsafe{
|
||||
libloading::os::unix::Library::new("libepoxy.0.dylib")
|
||||
}).unwrap();
|
||||
unsafe { libloading::os::unix::Library::new("/opt/homebrew/lib/libepoxy.0.dylib") }
|
||||
.or(unsafe { libloading::os::unix::Library::new("libepoxy.0.dylib") })
|
||||
.unwrap();
|
||||
|
||||
#[cfg(all(unix, not(target_os = "macos")))]
|
||||
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::{Array2, ArrayView2};
|
||||
use num_traits::{Num, AsPrimitive, FromPrimitive};
|
||||
pub mod offscreen_renderer;
|
||||
|
||||
use crate::{
|
||||
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),
|
||||
}
|
||||
|
||||
unsafe impl Send for CMS {}
|
||||
unsafe impl Sync for CMS {}
|
||||
|
||||
impl CMS {
|
||||
pub fn new(mapper: Mapper, window_size: (f32, f32)) -> Self {
|
||||
let bounds = mapper.get_bounds();
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
use crate::render::cms::CMS;
|
||||
use crate::{coords::Range, render::Render};
|
||||
use femtovg::Paint;
|
||||
use femtovg::{renderer::OpenGl, Canvas, ImageId};
|
||||
@ -10,8 +11,15 @@ use std::{
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
type PrepareFunc =
|
||||
Box<dyn FnOnce(Arc<Layer>, Render) -> Pin<Box<dyn Future<Output = ()>>> + Sync + Send>;
|
||||
type PrepareFunc = Box<
|
||||
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 LayerImplSync = Box<dyn LayerImpl + Send + Sync>;
|
||||
|
||||
@ -37,14 +45,14 @@ impl Debug for Layer {
|
||||
}
|
||||
|
||||
pub trait LayerImpl: Debug {
|
||||
fn draw(&self, render: Render) -> Option<Target>;
|
||||
fn draw(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS) -> Option<Target>;
|
||||
}
|
||||
|
||||
impl Layer {
|
||||
pub fn new<
|
||||
FU: Future<Output = ()> + 'static,
|
||||
FU: Future<Output = Target> + Send + Sync + 'static,
|
||||
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,
|
||||
>(
|
||||
visiable: bool,
|
||||
|
||||
@ -190,4 +190,10 @@ impl Render {
|
||||
pub fn render_range(&self) -> ((f64, f64), (f64, f64)) {
|
||||
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 femtovg::{ImageFlags, Paint, Path, PixelFormat::Rgba8, RenderTarget};
|
||||
use femtovg::{
|
||||
renderer::OpenGl, Canvas, ImageFlags, Paint, Path, PixelFormat::Rgba8, RenderTarget,
|
||||
};
|
||||
use geo_types::LineString;
|
||||
use ndarray::ArrayView2;
|
||||
use num_traits::{Num, NumOps};
|
||||
@ -8,7 +10,7 @@ use std::{fmt::Debug, marker::PhantomData};
|
||||
use super::super::renders::DataRenderer;
|
||||
use crate::{
|
||||
data::Radar2d,
|
||||
render::{LayerImpl, Render, Target},
|
||||
render::{cms::CMS, LayerImpl, Render, Target},
|
||||
utils::meshgrid,
|
||||
};
|
||||
|
||||
@ -32,8 +34,8 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
||||
fn draw_2d(
|
||||
&self,
|
||||
canvas: &mut femtovg::Canvas<femtovg::renderer::OpenGl>,
|
||||
cms: &CMS,
|
||||
data: ArrayView2<T>,
|
||||
render: &Render,
|
||||
dims: (ArrayView2<f64>, ArrayView2<f64>),
|
||||
window_size: (f32, f32),
|
||||
fill_value: T,
|
||||
@ -48,45 +50,43 @@ impl<T: NumOps + PartialOrd + Copy, CMAP: ColorMapper<T>> GridFieldRenderer<CMAP
|
||||
let d2_s = dim2[[0, 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 c in 0..cols - 1 {
|
||||
let lb_lat = dim2[[r, c]];
|
||||
let lb_lon = dim1[[r, c]];
|
||||
for r in 0..rows - 1 {
|
||||
for c in 0..cols - 1 {
|
||||
let lb_lat = dim2[[r, c]];
|
||||
let lb_lon = dim1[[r, c]];
|
||||
|
||||
let rt_lat = dim2[[r + 1, c + 1]];
|
||||
let rt_lon = dim1[[r + 1, c + 1]];
|
||||
let cell: LineString = vec![
|
||||
(lb_lon, lb_lat),
|
||||
(rt_lon + 0.001, lb_lat),
|
||||
(rt_lon + 0.001, rt_lat),
|
||||
(lb_lon, rt_lat + 0.001),
|
||||
(lb_lon, lb_lat + 0.001),
|
||||
]
|
||||
.into();
|
||||
let rt_lat = dim2[[r + 1, c + 1]];
|
||||
let rt_lon = dim1[[r + 1, c + 1]];
|
||||
let cell: LineString = vec![
|
||||
(lb_lon, lb_lat),
|
||||
(rt_lon + 0.001, lb_lat),
|
||||
(rt_lon + 0.001, rt_lat),
|
||||
(lb_lon, rt_lat + 0.001),
|
||||
(lb_lon, lb_lat + 0.001),
|
||||
]
|
||||
.into();
|
||||
|
||||
let v = &data[[r, c]];
|
||||
let mapped_color = self.cmap.map_value_to_color(*v, fill_value);
|
||||
let v = &data[[r, c]];
|
||||
let mapped_color = self.cmap.map_value_to_color(*v, fill_value);
|
||||
|
||||
if None == mapped_color {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mapped_ring = cms.ring_map(&cell).unwrap();
|
||||
|
||||
let mut path = Path::new();
|
||||
let mut points = mapped_ring.points();
|
||||
let first_point = points.next().unwrap();
|
||||
path.move_to(first_point.x(), first_point.y());
|
||||
|
||||
for point in points {
|
||||
path.line_to(point.x(), point.y());
|
||||
}
|
||||
path.close();
|
||||
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
||||
if None == mapped_color {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mapped_ring = cms.ring_map(&cell).unwrap();
|
||||
|
||||
let mut path = Path::new();
|
||||
let mut points = mapped_ring.points();
|
||||
let first_point = points.next().unwrap();
|
||||
path.move_to(first_point.x(), first_point.y());
|
||||
|
||||
for point in points {
|
||||
path.line_to(point.x(), point.y());
|
||||
}
|
||||
path.close();
|
||||
canvas.fill_path(&path, &Paint::color(mapped_color.unwrap()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,47 +96,42 @@ where
|
||||
CMAP: ColorMapper<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
|
||||
.create_image_empty(3000, 3000, Rgba8, ImageFlags::empty())
|
||||
.expect("Can't Create Image");
|
||||
|
||||
canvas.save();
|
||||
canvas.reset();
|
||||
|
||||
if let Ok(_) = canvas.image_size(new_img) {
|
||||
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();
|
||||
canvas.set_render_target(RenderTarget::Screen);
|
||||
|
||||
let d1_start = (data.dim1.view()).first().unwrap().clone();
|
||||
let d1_end = (data.dim1.view()).last().unwrap().clone();
|
||||
|
||||
let d2_start = data.dim2.view().first().unwrap().clone();
|
||||
let d2_end = data.dim2.view().last().unwrap().clone();
|
||||
|
||||
Target::new(
|
||||
new_img,
|
||||
3000f32,
|
||||
3000f32,
|
||||
((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
||||
)
|
||||
fn render(
|
||||
&self,
|
||||
canvas: &mut Canvas<OpenGl>,
|
||||
cms: &CMS,
|
||||
data: &Self::Data,
|
||||
size: (f32, f32),
|
||||
) -> Target {
|
||||
let (w, h) = size;
|
||||
}
|
||||
|
||||
// fn render(&self, canvas: &mut Canvas<OpenGl>, cms: &CMS, data: &Self::Data) -> Target {
|
||||
// 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_end = (data.dim1.view()).last().unwrap().clone();
|
||||
|
||||
// let d2_start = data.dim2.view().first().unwrap().clone();
|
||||
// let d2_end = data.dim2.view().last().unwrap().clone();
|
||||
|
||||
// Target::new(
|
||||
// new_img,
|
||||
// 3000f32,
|
||||
// 3000f32,
|
||||
// ((d1_start, d1_end).into(), (d2_start, d2_end).into()),
|
||||
// )
|
||||
// }
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@ -166,7 +161,22 @@ where
|
||||
T: Num + NumOps + PartialOrd + Copy + Clone + Debug + Send + Sync,
|
||||
CMAP: ColorMapper<T> + Debug,
|
||||
{
|
||||
fn draw(&self, render: Render) -> Option<Target> {
|
||||
Some(self.renderer.render(render, &self.data))
|
||||
fn draw(
|
||||
&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 num_traits::{Num, NumOps};
|
||||
use std::path::Path;
|
||||
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::{
|
||||
data::{AsyncDataLoader, DataLoader, Radar2d},
|
||||
render::{Layer, Render},
|
||||
@ -33,12 +37,13 @@ impl Layer {
|
||||
path.rect(ox, oy, x, y);
|
||||
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 mut c = render.get_canvas();
|
||||
let c = c.as_mut().unwrap();
|
||||
if let Ok(_) = c.image_size(img.target) {
|
||||
let (x, y) = img.size(&render);
|
||||
let (ox, oy) = img.origin(&render);
|
||||
@ -50,14 +55,8 @@ impl Layer {
|
||||
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)),
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,8 +1,15 @@
|
||||
use super::cms::CMS;
|
||||
use super::Render;
|
||||
use super::Target;
|
||||
use femtovg::{renderer::OpenGl, Canvas};
|
||||
|
||||
pub trait DataRenderer {
|
||||
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 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>)
|
||||
where
|
||||
@ -10,81 +18,42 @@ where
|
||||
let yy = Array2::from_shape_fn(shape, |(i, _)| y[i].clone());
|
||||
(xx, yy)
|
||||
}
|
||||
// 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(),
|
||||
// ];
|
||||
|
||||
pub fn creator() {
|
||||
let connection = Connection::new().unwrap();
|
||||
let adapter = connection.create_adapter().unwrap();
|
||||
let mut device = connection.create_device(&adapter).unwrap();
|
||||
let api = device.gl_api();
|
||||
let descriptor = device.create_context_descriptor(&ContextAttributes {
|
||||
version: GLVersion::new(3, 3),
|
||||
flags: ContextAttributeFlags::empty(),
|
||||
}).unwrap();
|
||||
|
||||
let mut context = device.create_context(&descriptor, None).unwrap();
|
||||
let mut surface = device
|
||||
.create_surface(
|
||||
&context,
|
||||
SurfaceAccess::GPUOnly,
|
||||
SurfaceType::Generic {
|
||||
size: Size2D::new(500, 500),
|
||||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
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();
|
||||
use femtovg::renderer::OpenGl;
|
||||
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));
|
||||
device.destroy_context(&mut context);
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user