This commit is contained in:
tsuki 2024-07-19 01:27:45 +08:00
parent db89b19eb4
commit 328a3127ae
6 changed files with 206 additions and 109 deletions

View File

@ -98,6 +98,14 @@ impl ColorMap for LinearColormap {
Ok(()) Ok(())
} }
fn destroy(&mut self, gl: &glow::Context) {
unsafe {
if let Some(texture) = self.texture {
gl.delete_texture(texture);
}
}
}
fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()> { fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()> {
unsafe { unsafe {
gl.active_texture(glow::TEXTURE0); gl.active_texture(glow::TEXTURE0);

View File

@ -12,4 +12,6 @@ pub trait ColorMap {
fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()>; fn bind_texture(&self, gl: &glow::Context, program: &Program) -> crate::errors::Result<()>;
fn snippet_ref(&self) -> &crate::components::Snippet; fn snippet_ref(&self) -> &crate::components::Snippet;
fn destroy(&mut self, gl: &glow::Context);
} }

View File

@ -9,6 +9,7 @@ pub mod ty;
use crate::{components::Program, errors::*}; use crate::{components::Program, errors::*};
pub use colormesh::ColorMesh; pub use colormesh::ColorMesh;
use imgui::TextureId;
pub trait Graphics { pub trait Graphics {
fn draw(&self, gl: &glow::Context) -> Result<()>; fn draw(&self, gl: &glow::Context) -> Result<()>;
@ -26,3 +27,10 @@ pub trait AttaWithBuffer {
type Data; type Data;
fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()>; fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()>;
} }
pub trait AttaWithWindow {
fn attach_with_window(&mut self, gl: &glow::Context) -> Result<TextureId>;
}

View File

@ -1,5 +1,8 @@
use std::cell::RefCell;
use std::rc::Rc;
use bytemuck::cast_slice; use bytemuck::cast_slice;
use glow::{HasContext, NativeBuffer, NativeVertexArray}; use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray};
use ndarray::{s, IndexLonger}; use ndarray::{s, IndexLonger};
use crate::components::{CodeType, Program, Shader, Snippet}; use crate::components::{CodeType, Program, Shader, Snippet};
@ -9,21 +12,23 @@ use crate::errors::*;
use super::colormap::ColorMap; use super::colormap::ColorMap;
use super::transforms::viewport::Viewport; use super::transforms::viewport::Viewport;
use super::transforms::Transform; use super::transforms::Transform;
use super::{ty, AttaWithBuffer, Graphics}; use super::{ty, AttaWithBuffer, AttaWithWindow, Graphics};
pub struct PPI<'a> { pub struct PPI {
program: Program, program: Program,
layer: isize, layer: isize,
vao: Option<NativeVertexArray>, vao: Option<NativeVertexArray>,
vbo: Option<NativeBuffer>, vbo: Option<NativeBuffer>,
cmap: &'a mut dyn ColorMap, cmap: Option<Box<dyn ColorMap>>,
framebuffer: Option<NativeFramebuffer>,
frametexture: Option<NativeTexture>,
buffer: Vec<[f32; 3]>, buffer: Vec<[f32; 3]>,
} }
impl<'a> PPI<'a> { impl PPI {
pub fn new(cmap: &'a mut dyn ColorMap) -> Result<Self> { pub fn new() -> Result<Self> {
let vertex = Shader::new( let vertex = Shader::new(
glow::VERTEX_SHADER, glow::VERTEX_SHADER,
CodeType::<String>::Path("ppi.vert".into()), CodeType::<String>::Path("ppi.vert".into()),
@ -39,9 +44,7 @@ impl<'a> PPI<'a> {
CodeType::<String>::Path("ppi.frag".into()), CodeType::<String>::Path("ppi.frag".into()),
)?; )?;
let mut program = Program::new(vertex, fragment, Some(geom), "330 core"); let program = Program::new(vertex, fragment, Some(geom), "330 core");
program.set_hook("colormap", cmap.snippet_ref());
Ok(Self { Ok(Self {
program, program,
@ -49,7 +52,9 @@ impl<'a> PPI<'a> {
vao: None, vao: None,
vbo: None, vbo: None,
buffer: Vec::with_capacity(180 * 50), buffer: Vec::with_capacity(180 * 50),
cmap, framebuffer: None,
frametexture: None,
cmap: None,
}) })
} }
@ -61,9 +66,9 @@ impl<'a> PPI<'a> {
self.program.set_viewport(viewport); self.program.set_viewport(viewport);
} }
pub fn set_colormap(&mut self, colormap: &'a mut dyn ColorMap) { pub fn set_colormap(&mut self, colormap: Box<dyn ColorMap>) {
self.cmap = colormap; self.program.set_hook("colormap", colormap.snippet_ref());
// self.program.set_hook("colormap", colormap.snippet_ref()); self.cmap = Some(colormap);
} }
pub fn program(&mut self) -> &mut Program { pub fn program(&mut self) -> &mut Program {
@ -165,10 +170,13 @@ fn max_step(data: &Vec<f32>) -> f32 {
return max_gap; return max_gap;
} }
impl<'a> Graphics for PPI<'a> { impl Graphics for PPI {
fn compile(&mut self, gl: &glow::Context) -> Result<()> { fn compile(&mut self, gl: &glow::Context) -> Result<()> {
self.program.compile(gl)?; self.program.compile(gl)?;
self.cmap.attach_with_program(gl, &self.program)?; self.cmap
.as_mut()
.unwrap()
.attach_with_program(gl, &self.program)?;
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));
@ -199,6 +207,9 @@ impl<'a> Graphics for PPI<'a> {
unsafe { unsafe {
self.vao.map(|vao| gl.delete_vertex_array(vao)); self.vao.map(|vao| gl.delete_vertex_array(vao));
self.vbo.map(|vbo| gl.delete_buffer(vbo)); self.vbo.map(|vbo| gl.delete_buffer(vbo));
self.framebuffer.map(|fb| gl.delete_framebuffer(fb));
self.frametexture.map(|ft| gl.delete_texture(ft));
self.cmap.as_mut().unwrap().destroy(gl);
} }
Ok(()) Ok(())
@ -208,11 +219,37 @@ impl<'a> Graphics for PPI<'a> {
unsafe { unsafe {
gl.clear(glow::COLOR_BUFFER_BIT); gl.clear(glow::COLOR_BUFFER_BIT);
gl.use_program(Some(self.program.native_program.unwrap())); gl.use_program(Some(self.program.native_program.unwrap()));
self.cmap.bind_texture(gl, &self.program)?; self.cmap
.as_ref()
.unwrap()
.bind_texture(gl, &self.program)?;
if self.framebuffer.is_some() {
gl.bind_framebuffer(glow::FRAMEBUFFER, self.framebuffer);
}
gl.depth_mask(false); gl.depth_mask(false);
gl.bind_vertex_array(Some(self.vao.unwrap())); gl.bind_vertex_array(Some(self.vao.unwrap()));
gl.draw_arrays(glow::POINTS, 0, self.buffer.len() as i32); gl.draw_arrays(glow::POINTS, 0, self.buffer.len() as i32);
gl.depth_mask(true); gl.depth_mask(true);
if self.framebuffer.is_some() {
gl.framebuffer_texture_2d(
glow::FRAMEBUFFER,
glow::COLOR_ATTACHMENT0,
glow::TEXTURE_2D,
self.frametexture,
0,
);
assert_eq!(
gl.check_framebuffer_status(glow::FRAMEBUFFER),
glow::FRAMEBUFFER_COMPLETE
);
gl.bind_texture(glow::TEXTURE_2D, None);
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
}
gl.bind_vertex_array(None); gl.bind_vertex_array(None);
gl.use_program(None); gl.use_program(None);
} }
@ -220,7 +257,7 @@ impl<'a> Graphics for PPI<'a> {
} }
} }
impl<'a> AttaWithBuffer for PPI<'a> { impl AttaWithBuffer for PPI {
type Data = Data; type Data = Data;
fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()> { fn attach_with_buffer(&mut self, gl: &glow::Context, data: &Self::Data) -> Result<()> {
@ -242,6 +279,51 @@ impl<'a> AttaWithBuffer for PPI<'a> {
} }
} }
impl AttaWithWindow for PPI {
fn attach_with_window(&mut self, gl: &glow::Context) -> Result<imgui::TextureId> {
unsafe {
if self.framebuffer.is_none() {
let framebuffer = gl.create_framebuffer().unwrap();
gl.bind_framebuffer(glow::FRAMEBUFFER, Some(framebuffer));
let texture = gl.create_texture().unwrap();
gl.bind_texture(glow::TEXTURE_2D, Some(texture));
gl.tex_image_2d(
glow::TEXTURE_2D,
0,
glow::RGB8 as i32,
800,
600,
0,
glow::RGB,
glow::UNSIGNED_BYTE,
None,
);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MIN_FILTER,
glow::LINEAR as i32,
);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_MAG_FILTER,
glow::LINEAR as i32,
);
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
gl.bind_texture(glow::TEXTURE_2D, None);
self.frametexture = Some(texture);
Ok(imgui::TextureId::from(texture.0.get() as usize))
} else {
Ok(imgui::TextureId::from(
self.frametexture.unwrap().0.get() as usize
))
}
}
}
}
mod test { mod test {
#[test] #[test]
fn test_ppi() { fn test_ppi() {

View File

@ -1,5 +1,12 @@
use std::cell::RefCell;
use std::rc::Rc;
use data_loader::Data; use data_loader::Data;
use graphics::AttaWithBuffer; use graphics::colormap::linear::LinearColormap;
use graphics::ppi::PPI;
use graphics::transforms::position::Position;
use graphics::transforms::viewport::Viewport;
use graphics::{AttaWithBuffer, Graphics, AttaWithWindow};
use imgui::Condition; use imgui::Condition;
mod camera; mod camera;
@ -9,45 +16,68 @@ mod errors;
mod graphics; mod graphics;
mod support; mod support;
mod utils; mod utils;
use imgui::*;
mod final_pg; mod final_pg;
fn main() { fn main() {
env_logger::init(); env_logger::init();
let choices = ["test test this is 1", "test test this is 2"];
let path = "/Users/tsuki/Desktop/ZJSXAA_20230113070200_R.dat.gz";
let data = Data::from_path(path).unwrap();
let mut value = 0;
support::supporter::init(move |_, ui, program, window, gl| {
ui.window("Hello world")
.size([300.0, 110.0], Condition::FirstUseEver)
.build(|| {
ui.text_wrapped("Hello world!");
ui.text_wrapped("こんにちは世界!");
if ui.button(choices[value]) {
value += 1;
value %= 2;
}
ui.button("This...is...imgui-rs!"); let transform = Position::new().unwrap();
ui.separator(); let mut viewport = Viewport::new().unwrap();
let mouse_pos = ui.io().mouse_pos; viewport.set_global(0.0, 0.0, 600.0, 800.0);
ui.text(format!(
"Mouse Position: ({:.1},{:.1})",
mouse_pos[0], mouse_pos[1]
));
if ui.button("Add Layer") { let mut cmap = LinearColormap::new().unwrap();
program.add_ppi_layer(1);
program.attach_with_buffer(gl, &data).unwrap();
window.request_redraw();
}
if ui.button("Remove Layer") { cmap.set_colors(vec![
program.add_ppi_layer(-1); [170, 170, 170, 255],
program.attach_with_buffer(gl, &data).unwrap(); [0, 34, 255, 255],
window.request_redraw(); [1, 160, 246, 255],
} [0, 236, 236, 255],
}); [0, 216, 0, 255],
}); [1, 144, 0, 255],
[255, 255, 0, 255],
[231, 192, 0, 255],
[255, 144, 0, 255],
[255, 0, 0, 255],
[214, 0, 0, 255],
[192, 0, 0, 255],
[255, 0, 240, 255],
[150, 0, 180, 255],
]);
cmap.set_range(0.0, 70.0);
let mut ppi = PPI::new().unwrap();
ppi.set_transform(&transform);
ppi.set_viewport(&viewport);
ppi.set_colormap(Box::new(cmap));
let ppi = Rc::new(RefCell::new(ppi));
let registers = vec![ppi.clone()];
let registers = registers.into_iter().map(|r| {
r as Rc<RefCell<dyn Graphics>>
}).collect();
support::supporter::init(move |run, ui, window, gl| {
let mut ppi = ppi.borrow_mut();
let texture = ppi.attach_with_window(gl).unwrap();
ui.window("test").build(||{
if ui.button("load") {
let data = Data::from_path(r#"C:\Users\qwin7\Downloads\ZJSXAA_20230113070200_R.dat.gz"#).unwrap();
ppi.attach_with_buffer(gl, &data).unwrap();
}
});
ui.window("Test").size([200.0,400.0], imgui::Condition::FirstUseEver).build(|| {
imgui::Image::new(texture, [200.0, 400.0]).build(ui);
});
},
registers,
);
} }

View File

@ -32,12 +32,14 @@ use imgui_winit_support::{
use nalgebra_glm::perspective; use nalgebra_glm::perspective;
use nalgebra_glm::Vec3; use nalgebra_glm::Vec3;
use raw_window_handle::HasRawWindowHandle; use raw_window_handle::HasRawWindowHandle;
use std::cell::RefCell;
use std::num::NonZeroU32; use std::num::NonZeroU32;
use std::rc::Rc;
use std::time::Instant; use std::time::Instant;
pub fn init<FUi>(mut run_ui: FUi) pub fn init<FUi>(mut run_ui: FUi, mut register: Vec<Rc<RefCell<dyn Graphics>>>)
where where
FUi: FnMut(&mut bool, &mut Ui, &mut PPI, &Window, &glow::Context) + 'static, FUi: FnMut(&mut bool, &mut Ui, &Window, &glow::Context) + 'static,
{ {
let (event_loop, window, surface, context) = create_window(); let (event_loop, window, surface, context) = create_window();
let (mut winit_platform, mut imgui_context) = imgui_init(&window); let (mut winit_platform, mut imgui_context) = imgui_init(&window);
@ -53,39 +55,13 @@ where
// OpenGL renderer from this crate // OpenGL renderer from this crate
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context) let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
.expect("failed to create renderer"); .expect("failed to create renderer");
let gl_context = ig_renderer.gl_context().clone();
for r in register.iter_mut() {
r.borrow_mut().compile(&gl_context).unwrap();
}
let mut last_frame = Instant::now(); let mut last_frame = Instant::now();
let transform = Position::new().unwrap();
let mut viewport = Viewport::new().unwrap();
let mut cmap = LinearColormap::new().unwrap();
cmap.set_colors(vec![
[170, 170, 170, 255],
[0, 34, 255, 255],
[1, 160, 246, 255],
[0, 236, 236, 255],
[0, 216, 0, 255],
[1, 144, 0, 255],
[255, 255, 0, 255],
[231, 192, 0, 255],
[255, 144, 0, 255],
[255, 0, 0, 255],
[214, 0, 0, 255],
[192, 0, 0, 255],
[255, 0, 240, 255],
[150, 0, 180, 255],
]);
cmap.set_range(0.0, 70.0);
let mut ppi = PPI::new(&mut cmap).unwrap();
ppi.set_transform(&transform);
ppi.set_viewport(&viewport);
ppi.compile(ig_renderer.gl_context()).unwrap();
transform
.attach_with_program(ig_renderer.gl_context(), ppi.program_ref())
.unwrap();
event_loop event_loop
.run(move |event, window_target| { .run(move |event, window_target| {
@ -112,27 +88,25 @@ where
// context from the `AutoRenderer`, which takes ownership of it. // context from the `AutoRenderer`, which takes ownership of it.
unsafe { unsafe {
let gl = ig_renderer.gl_context(); gl_context.clear(glow::DEPTH_BUFFER_BIT);
gl.clear(glow::DEPTH_BUFFER_BIT); gl_context.clear(glow::COLOR_BUFFER_BIT);
} }
ppi.draw(ig_renderer.gl_context()).unwrap();
let ui = imgui_context.frame(); let ui = imgui_context.frame();
if ui.is_mouse_pos_valid(ui.io().mouse_pos) { if ui.is_mouse_pos_valid(ui.io().mouse_pos) {
let mouse_pos = ui.io().mouse_pos; let mouse_pos = ui.io().mouse_pos;
if ui.is_mouse_dragging(imgui::MouseButton::Right) { if ui.is_mouse_dragging(imgui::MouseButton::Right) {
// mouse_callback(
// &mut last_position,
// PhysicalPosition::new(mouse_pos[0] as f64, mouse_pos[1] as f64),
// 0.05,
// &mut pitch,
// &mut yaw,
// &mut camera,
// );
} }
} }
for r in register.iter_mut() {
r.borrow_mut().draw(&gl_context).unwrap();
}
let mut run = true; let mut run = true;
run_ui(&mut run, ui, &mut ppi, &window, ig_renderer.gl_context());
run_ui(&mut run, ui, &window, ig_renderer.gl_context());
if !run { if !run {
window_target.exit(); window_target.exit();
@ -167,22 +141,15 @@ where
NonZeroU32::new(new_size.height).unwrap(), NonZeroU32::new(new_size.height).unwrap(),
); );
viewport.set_global(
0f32,
0f32,
new_size.width as f32,
new_size.height as f32,
);
viewport
.attach_with_program(ig_renderer.gl_context(), ppi.program_ref())
.unwrap();
} }
winit_platform.handle_event(imgui_context.io_mut(), &window, &event); winit_platform.handle_event(imgui_context.io_mut(), &window, &event);
} }
winit::event::Event::LoopExiting => { winit::event::Event::LoopExiting => {
let gl = ig_renderer.gl_context();
ppi.destroy(gl).unwrap(); for r in register.iter_mut() {
r.borrow_mut().destroy(&gl_context).unwrap();
}
} }
event => { event => {
winit_platform.handle_event(imgui_context.io_mut(), &window, &event); winit_platform.handle_event(imgui_context.io_mut(), &window, &event);