use std::thread::panicking; use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size}; use crate::camera::Camera; use crate::graphics::threed::Trackball; use crate::graphics::{AttaWithProgram, AttachWithMouse, MouseState}; use crate::pg::ModulePackage; use crate::pg::{_ModulePackage, layout_type::ViewPort}; use crate::ui::helper::Helper; use crate::ui::io::IO; use crate::ui::operation::Operation; use crate::utils::resources::GL; use bytemuck::Contiguous; use glow::{HasContext, NativeRenderbuffer}; use imgui::{Condition, TextureId, Ui, WindowFlags}; use nalgebra_glm::Vec3; pub struct MainLoad {} impl LayoutMod for MainLoad { type Attach<'gl> = MainLoadAttach<'gl>; fn render<'b, 'gl>( &mut self, ui: &imgui::Ui, context: &mut crate::pg::Context<'gl>, layout: &mut Layout, apptyp: &mut Self::Attach<'gl>, ) where 'gl: 'b, { let mut changed = true; let mut grid = layout.grid(2, 1, [0.0, 0.0]); grid.set_col_size(&[size!(20.0%), size!(fill)]); grid.set_row_size(&[size!(fill)]); let io = ui.io(); let window_flag = WindowFlags::empty() | WindowFlags::NO_MOVE | WindowFlags::NO_RESIZE | WindowFlags::NO_COLLAPSE | WindowFlags::NO_TITLE_BAR; grid.with(0, 0, [1, 1]) .start_window(ui, "MainLoad") .build(|| { for package in 0..apptyp.packages.len() { if ui.button(format!("Delete Package {}", package)) { apptyp.packages.remove(package); } } ui.separator(); for package in apptyp.packages.iter_mut() { if package.ui_build(ui).unwrap() { package.dirty(); } } ui.separator(); if ui.button("ON TOP") { apptyp .operation .set_camera(|c| c.set_position(Vec3::new(0.0, 0.0, 20.0))); apptyp.operation.reset(); } }); grid.with(0, 1, [1, 1]) .build(ui, |ui, window_size, origin| { let window_size = [window_size[0], window_size[0] / 16.0 * 9.0]; ui.window("Renderer") .size(window_size, Condition::Always) .flags(window_flag) .position(origin, Condition::Always) .build(|| { let gl = context.gl.gl_rc(); let scale = ui.io().display_framebuffer_scale; let pos = ui.cursor_screen_pos(); let dsp_size = ui.io().display_size; let content_size = ui.content_region_avail(); // Change the size of the viewport apptyp.main_viewport.set_size(content_size); // context.helper.set_size(content_size, scale[0]); let draws = ui.get_window_draw_list(); draws.channels_split(2, |channels| { channels.set_current(0); let fbo = apptyp.main_viewport.fbo(); let main_fbo = fbo.native(); draws .add_callback({ move || unsafe { let x = pos[0] * scale[0]; let y = (dsp_size[1] - pos[1]) * scale[1]; gl.bind_framebuffer(glow::READ_FRAMEBUFFER, Some(main_fbo)); gl.blit_framebuffer( 0, 0, (content_size[0]) as i32, (content_size[1]) as i32, x as i32, y as i32, (x + content_size[0] * scale[0]) as i32, (y - content_size[1] * scale[1]) as i32, glow::COLOR_BUFFER_BIT, glow::NEAREST, ); gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None); } }) .build(); channels.set_current(1); let helper = context.helper.viewport(); let texture = helper.texture().native(); let gl = context.gl.gl_rc(); draws .add_image( TextureId::new(texture.0.into_integer() as usize), pos, [ pos[0] + content_size[0] * scale[0], pos[1] + content_size[1] * scale[1], ], ) .build(); }); if ui.is_window_hovered() { let cio = IO::new(ui); apptyp.operation.deal_io(&cio); } }); }); } fn init<'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl> { let typ = MainLoadAttach { main_viewport: ViewPort::::new(gl, true), packages: Vec::new(), operation: Operation::new(Trackball::default(), 16.0 / 9.0, 45.0, 0.1, 1000.0), }; typ } } impl MainLoad { pub fn new() -> Self { MainLoad {} } } pub struct MainLoadAttach<'gl> { operation: Operation, main_viewport: ViewPort, packages: Vec>, } impl CameraOP for MouseState { fn from_context(context: &IO) -> Self { if context.mouse.is_dragging { Self::Drag { from: context.mouse.position, delta: context.mouse.drag_delta.unwrap(), } } else { if context.mouse.wheel_delta != 0.0 { Self::Wheel(context.mouse.wheel_delta) } else { Self::None } } } } impl<'gl> LayoutAttach<'gl> for MainLoadAttach<'gl> { fn append(&mut self, package: ModulePackage<'gl>) { self.packages.push(package); } fn render_task( &mut self, gl: &glow::Context, programs: &mut crate::pg::Programs<'gl>, helper: &mut Helper, ) -> crate::errors::Result<()> { // helper.draw_modules(gl, &self.packages); if self.packages.iter().any(|v| v.need_update) || self.operation.is_need_update() { // Helper task self.main_viewport.bind(gl); unsafe { gl.clear(glow::COLOR_BUFFER_BIT | glow::DEPTH_BUFFER_BIT); } for package in self.packages.iter_mut() { programs.draw_modules(package, &self.operation, &self.main_viewport)?; } } if self.packages.is_empty() { unsafe { gl.clear(glow::COLOR_BUFFER_BIT); } } self.main_viewport.unbind(); Ok(()) } }