radar-gi/src/ui/typ/main_load.rs
2024-08-21 22:00:45 +08:00

220 lines
7.7 KiB
Rust

use std::thread::panicking;
use super::{CameraOP, Layout, LayoutAttach, LayoutMod, Size};
use crate::camera::Camera;
use crate::graphics::threed::Trackball;
use crate::graphics::transforms::plane::PlaneTrans;
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(&apptyp.main_viewport, &cio);
}
});
});
}
fn init<'gl>(&mut self, gl: &'gl GL) -> Self::Attach<'gl> {
let typ = MainLoadAttach {
main_viewport: ViewPort::<NativeRenderbuffer>::new(gl, true),
packages: Vec::new(),
operation: Operation::new(PlaneTrans::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<PlaneTrans>,
main_viewport: ViewPort,
packages: Vec<ModulePackage<'gl>>,
}
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(())
}
}