741 lines
24 KiB
Rust
741 lines
24 KiB
Rust
use crate::data_loader::Data;
|
|
use crate::graphics::colormap::linear::LinearColormap;
|
|
use crate::graphics::ppi::PPIConfig;
|
|
use crate::graphics::transforms::position::Position;
|
|
use crate::graphics::transforms::viewport::Viewport;
|
|
use crate::graphics::transforms::ChainedTransform;
|
|
use crate::graphics::{ppi::PPI, Graphics};
|
|
use crate::graphics::{AttaWithBuffer, AttaWithProgram, Config, MouseState};
|
|
use crate::{errors::*, ui::base};
|
|
use glow::{HasContext, NativeBuffer, NativeFramebuffer, NativeTexture, NativeVertexArray};
|
|
use imgui::{ImStr, ImString, Textures, Ui};
|
|
use log::info;
|
|
use serde::de;
|
|
use std::collections::HashSet;
|
|
use std::{cell::RefCell, collections::HashMap, rc::Rc};
|
|
use winit::window;
|
|
pub type Graphic<Data> = Rc<RefCell<dyn Graphics<Data = Data>>>;
|
|
type RcGraphic<T> = Rc<RefCell<T>>;
|
|
|
|
pub struct App<'a> {
|
|
pub ui_state: State,
|
|
gl: &'a glow::Context,
|
|
viewport: Viewport,
|
|
windows: HashMap<ImString, WindowData>,
|
|
programs: [Graphic<Data>; 1],
|
|
pub ppi_module: RcGraphic<PPI>,
|
|
program_with_window: HashMap<usize, Vec<ImString>>,
|
|
// Auto clean up
|
|
all_vaos: HashMap<NativeVertexArray, usize>,
|
|
all_other_buffers: HashMap<NativeBuffer, usize>,
|
|
all_framebuffers: HashMap<NativeFramebuffer, usize>,
|
|
all_frametextures: HashMap<NativeTexture, usize>,
|
|
}
|
|
|
|
impl<'a> App<'a> {
|
|
pub fn new(gl: &'a glow::Context) -> Result<Self> {
|
|
let viewport = Viewport::new()?;
|
|
|
|
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 cmap = Box::new(cmap);
|
|
|
|
let mut ppi = PPI::new()?;
|
|
ppi.set_viewport(&viewport);
|
|
ppi.set_colormap(cmap);
|
|
|
|
let ppi = Rc::new(RefCell::new(ppi));
|
|
let programs = [ppi.clone() as Graphic<Data>];
|
|
|
|
Ok(Self {
|
|
ui_state: State {},
|
|
viewport,
|
|
programs,
|
|
windows: HashMap::new(),
|
|
ppi_module: ppi,
|
|
gl,
|
|
program_with_window: HashMap::new(),
|
|
all_vaos: HashMap::with_capacity(30),
|
|
all_other_buffers: HashMap::with_capacity(30),
|
|
all_framebuffers: HashMap::with_capacity(30),
|
|
all_frametextures: HashMap::with_capacity(30),
|
|
})
|
|
}
|
|
|
|
pub fn render(&mut self) {
|
|
let mut need_clean = false;
|
|
for (id, program) in self.programs.iter().enumerate() {
|
|
let mut p = program.borrow_mut();
|
|
|
|
if self.program_with_window.len() == 0 {
|
|
return;
|
|
}
|
|
|
|
p.mount(&self.gl).unwrap();
|
|
self.program_with_window.get(&id).map(|windows| {
|
|
for window in windows.iter() {
|
|
let window_info = self.windows.get_mut(window).unwrap();
|
|
if !window_info.need_redraw {
|
|
continue;
|
|
}
|
|
|
|
let conf = if window_info.re_init {
|
|
window_info.config.as_ref()
|
|
} else {
|
|
None
|
|
};
|
|
|
|
{
|
|
p.set_config(self.gl, conf).unwrap();
|
|
window_info.re_init = false;
|
|
}
|
|
|
|
unsafe {
|
|
self.gl
|
|
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer);
|
|
|
|
let attach = window_info.attach.as_ref();
|
|
|
|
if attach.is_some() {
|
|
self.gl.bind_vertex_array(Some(attach.unwrap().vao));
|
|
}
|
|
|
|
if attach.is_some() {
|
|
let window_size = window_info.size;
|
|
|
|
self.gl
|
|
.viewport(0, 0, window_size[0] as i32, window_size[1] as i32);
|
|
p.draw(&self.gl, attach.as_ref().unwrap().len).unwrap();
|
|
}
|
|
|
|
if attach.is_some() {
|
|
self.gl.bind_vertex_array(None);
|
|
}
|
|
self.gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
|
window_info.need_redraw = false;
|
|
need_clean = true;
|
|
}
|
|
}
|
|
});
|
|
p.unmount(&self.gl).unwrap();
|
|
}
|
|
|
|
if need_clean {
|
|
self.clean();
|
|
}
|
|
}
|
|
|
|
pub fn render_ui(&mut self, ui: &Ui, window: &winit::window::Window, run: &mut bool) {
|
|
base(ui, window, run, self);
|
|
}
|
|
|
|
pub fn create_framebuffer(
|
|
&mut self,
|
|
id: &str,
|
|
size: (i32, i32),
|
|
) -> Result<(NativeFramebuffer, NativeTexture)> {
|
|
let id = &ImString::new(id);
|
|
let gl = self.gl;
|
|
let tex = unsafe {
|
|
let already = self.windows.contains_key(id)
|
|
&& self.windows.get(id).unwrap().framebuffer.is_some();
|
|
|
|
if already {
|
|
return Ok((
|
|
self.windows[id].framebuffer.unwrap(),
|
|
self.windows[id].frametexture.unwrap(),
|
|
));
|
|
}
|
|
|
|
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,
|
|
size.0,
|
|
size.1,
|
|
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.framebuffer_texture_2d(
|
|
glow::FRAMEBUFFER,
|
|
glow::COLOR_ATTACHMENT0,
|
|
glow::TEXTURE_2D,
|
|
Some(texture),
|
|
0,
|
|
);
|
|
|
|
assert_eq!(
|
|
gl.check_framebuffer_status(glow::FRAMEBUFFER),
|
|
glow::FRAMEBUFFER_COMPLETE
|
|
);
|
|
|
|
gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
|
gl.bind_texture(glow::TEXTURE_2D, None);
|
|
|
|
self.all_framebuffers_add(&framebuffer);
|
|
self.all_frametextures_add(&texture);
|
|
(framebuffer, texture)
|
|
};
|
|
|
|
Ok(tex)
|
|
}
|
|
|
|
pub fn prepare(&mut self) {
|
|
for program in self.programs.iter() {
|
|
let mut p = program.borrow_mut();
|
|
p.compile(&self.gl).unwrap();
|
|
}
|
|
}
|
|
|
|
pub fn destroy(&mut self) {
|
|
for p in self.programs.iter() {
|
|
let mut p = p.borrow_mut();
|
|
p.unmount(&self.gl).unwrap();
|
|
p.destroy(&self.gl).unwrap();
|
|
}
|
|
|
|
info!("Cleaning up all resources");
|
|
|
|
unsafe {
|
|
for vao in self.all_vaos.keys() {
|
|
self.gl.delete_vertex_array(*vao);
|
|
}
|
|
|
|
for vbo in self.all_other_buffers.keys() {
|
|
self.gl.delete_buffer(*vbo);
|
|
}
|
|
|
|
for framebuffer in self.all_framebuffers.keys() {
|
|
self.gl.delete_framebuffer(*framebuffer);
|
|
}
|
|
|
|
for texture in self.all_frametextures.keys() {
|
|
self.gl.delete_texture(*texture);
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn create_ppi_render(&mut self, id: &str, config: Option<PPIConfig>) {
|
|
let id = &ImString::new(id);
|
|
let (vao, vbo, ebo) = self.ppi_module.borrow().init(&self.gl);
|
|
self.windows.get_mut(id).map(|w| {
|
|
w.attach = Some(Attach {
|
|
vao,
|
|
vbo,
|
|
ebo,
|
|
len: 0,
|
|
});
|
|
w.need_redraw = true;
|
|
w.program = 0;
|
|
w.config = Some(config.unwrap_or_default().into());
|
|
});
|
|
|
|
let v = self.program_with_window.entry(0).or_insert(vec![]);
|
|
v.push(id.clone());
|
|
|
|
self.all_vaos_add(&vao);
|
|
self.all_other_buffers_add(&vbo);
|
|
ebo.map(|ebo| self.all_other_buffers_add(&ebo));
|
|
}
|
|
|
|
pub fn bind_data(&mut self, id: &str, data: &Data) -> Result<()> {
|
|
let id = &ImString::new(id);
|
|
use bytemuck::cast_slice;
|
|
|
|
let window = self.windows.get_mut(id).unwrap();
|
|
|
|
let program = window.program;
|
|
let program = self.programs[program].borrow();
|
|
|
|
let data = program.bake(data)?;
|
|
|
|
assert!(window.attach.is_some());
|
|
let attach = window.attach.as_mut().unwrap();
|
|
|
|
attach.len = data.2;
|
|
|
|
unsafe {
|
|
self.gl.bind_buffer(glow::VERTEX_ARRAY, Some(attach.vbo));
|
|
self.gl.buffer_data_u8_slice(
|
|
glow::ARRAY_BUFFER,
|
|
cast_slice(data.0.as_slice()),
|
|
glow::STATIC_DRAW,
|
|
);
|
|
if let Some(ebo) = attach.ebo {
|
|
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, attach.ebo);
|
|
self.gl.buffer_data_u8_slice(
|
|
glow::ELEMENT_ARRAY_BUFFER,
|
|
cast_slice(&data.1.as_ref().unwrap()),
|
|
glow::STATIC_DRAW,
|
|
);
|
|
|
|
self.gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None);
|
|
}
|
|
self.gl.bind_buffer(glow::VERTEX_ARRAY, None);
|
|
}
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn all_framebuffers_add(&mut self, framebuffer: &NativeFramebuffer) {
|
|
self.all_framebuffers
|
|
.entry(*framebuffer)
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
|
|
info!(
|
|
"Framebuffer: {:?} + 1, Framebuffer {:?}: {}",
|
|
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
|
|
);
|
|
}
|
|
|
|
fn all_framebuffers_minus(&mut self, framebuffer: &NativeFramebuffer) {
|
|
self.all_framebuffers
|
|
.entry(*framebuffer)
|
|
.and_modify(|v| *v -= 1);
|
|
|
|
info!(
|
|
"Framebuffer: {:?} - 1, Framebuffer {:?}: {}",
|
|
framebuffer, framebuffer, self.all_framebuffers[framebuffer]
|
|
);
|
|
}
|
|
|
|
fn all_frametextures_add(&mut self, texture: &NativeTexture) {
|
|
self.all_frametextures
|
|
.entry(*texture)
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
|
|
info!(
|
|
"Texture: {:?} + 1, Frametexture {:?}: {}",
|
|
texture, texture, self.all_frametextures[texture]
|
|
);
|
|
}
|
|
|
|
fn all_frametextures_minus(&mut self, texture: &NativeTexture) {
|
|
self.all_frametextures
|
|
.entry(*texture)
|
|
.and_modify(|v| *v -= 1);
|
|
|
|
info!(
|
|
"Texture: {:?} - 1, Frametexture {:?}: {}",
|
|
texture, texture, self.all_frametextures[texture]
|
|
);
|
|
}
|
|
|
|
fn all_vaos_add(&mut self, vao: &NativeVertexArray) {
|
|
self.all_vaos
|
|
.entry(*vao)
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
|
|
info!("Vao: {:?} + 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
|
|
}
|
|
|
|
fn all_vaos_minus(&mut self, vao: &NativeVertexArray) {
|
|
self.all_vaos.entry(*vao).and_modify(|v| *v -= 1);
|
|
|
|
info!("Vao: {:?} - 1, Vao {:?}: {}", vao, vao, self.all_vaos[vao]);
|
|
}
|
|
|
|
fn all_other_buffers_add(&mut self, buffer: &NativeBuffer) {
|
|
self.all_other_buffers
|
|
.entry(*buffer)
|
|
.and_modify(|v| *v += 1)
|
|
.or_insert(1);
|
|
|
|
info!(
|
|
"Buffer: {:?} + 1, Buffer {:?}: {}",
|
|
buffer, buffer, self.all_other_buffers[buffer]
|
|
);
|
|
}
|
|
|
|
fn all_other_buffers_minus(&mut self, buffer: &NativeBuffer) {
|
|
self.all_other_buffers
|
|
.entry(*buffer)
|
|
.and_modify(|v| *v -= 1);
|
|
|
|
info!(
|
|
"Buffer: {:?} - 1, Buffer {:?}: {}",
|
|
buffer, buffer, self.all_other_buffers[buffer]
|
|
);
|
|
}
|
|
|
|
pub fn show_window(&mut self, ui: &Ui) {
|
|
let mut need_resize = vec![];
|
|
|
|
for (id, window) in self.windows.iter_mut() {
|
|
ui.window(&window.title)
|
|
.size(window.size, imgui::Condition::FirstUseEver)
|
|
.opened(&mut window.open)
|
|
.flags(imgui::WindowFlags::NO_SCROLLBAR)
|
|
.build(|| {
|
|
if ui.is_mouse_clicked(imgui::MouseButton::Left) {
|
|
let io = ui.io();
|
|
let pos = io.mouse_pos;
|
|
window.last_mouse_position = pos;
|
|
}
|
|
|
|
if ui.is_mouse_dragging(imgui::MouseButton::Left) {
|
|
let delta = ui.mouse_drag_delta();
|
|
window.last_mouse_delta = delta;
|
|
window.accmulate_mouse_delta = [
|
|
window.accmulate_mouse_delta[0] + delta[0],
|
|
window.accmulate_mouse_delta[1] + delta[1],
|
|
];
|
|
window.motion = Some(MouseState::Drag {
|
|
from: window.last_mouse_position,
|
|
delta: delta,
|
|
});
|
|
}
|
|
if ui.is_mouse_released(imgui::MouseButton::Left) {
|
|
if window.size != ui.window_size() {
|
|
window.size = ui.window_size();
|
|
println!("resized: {:?}", window.size);
|
|
need_resize.push((window.title.clone(), ui.window_size()));
|
|
}
|
|
}
|
|
|
|
if let Some(texture) = window.frametexture {
|
|
let cursor = ui.cursor_pos();
|
|
imgui::Image::new(
|
|
imgui::TextureId::new(texture.0.get() as usize),
|
|
ui.window_size(),
|
|
)
|
|
.build(ui);
|
|
ui.set_cursor_pos(cursor);
|
|
if ui.invisible_button(&window.title, ui.window_size()) {
|
|
let io = ui.io();
|
|
let pos = io.mouse_pos;
|
|
let window_pos = ui.window_pos();
|
|
let related_pos = [pos[0] - window_pos[0], pos[1] - window_pos[1]];
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
for (id, size) in need_resize.iter() {
|
|
self.reset_window_size(id, *size);
|
|
}
|
|
}
|
|
|
|
// pub fn copy_window_resource(
|
|
// &mut self,
|
|
// src: &str,
|
|
// dst: &str,
|
|
// stick: bool,
|
|
// ) -> Option<NativeTexture> {
|
|
// let src = &ImString::new(src);
|
|
// let window_info = self.windows.get(src).unwrap();
|
|
|
|
// let new_texture = if stick {
|
|
// let new_framebuffer_tex = self.create_framebuffer(dst, (300, 300)).unwrap();
|
|
// unsafe {
|
|
// self.gl
|
|
// .bind_framebuffer(glow::READ_FRAMEBUFFER, window_info.framebuffer);
|
|
// self.gl
|
|
// .bind_framebuffer(glow::DRAW_FRAMEBUFFER, Some(self.framebuffers[dst].0));
|
|
// self.gl.blit_framebuffer(
|
|
// 0,
|
|
// 0,
|
|
// 300,
|
|
// 300,
|
|
// 0,
|
|
// 0,
|
|
// 300,
|
|
// 300,
|
|
// glow::COLOR_BUFFER_BIT,
|
|
// glow::NEAREST,
|
|
// );
|
|
// self.gl.bind_framebuffer(glow::READ_FRAMEBUFFER, None);
|
|
// self.gl.bind_framebuffer(glow::DRAW_FRAMEBUFFER, None);
|
|
// }
|
|
|
|
// self.framebuffers
|
|
// .get_mut(dst)
|
|
// .map(|(_, redraw, program, atta)| {
|
|
// *atta = new_framebuffer.as_ref().map(|v| v.3.clone()).flatten();
|
|
// *redraw = true;
|
|
// *program = new_framebuffer.as_ref().map(|v| v.2).unwrap();
|
|
// });
|
|
|
|
// Some(new_framebuffer_tex)
|
|
// } else {
|
|
// let texture = self.frametextures.get(src).map(|texture| *texture);
|
|
// if let Some(ref framebuffer) = new_framebuffer {
|
|
// if let Some(ref texture) = texture {
|
|
// self.all_framebuffers_add(&framebuffer.0);
|
|
// self.all_frametextures_add(&texture);
|
|
// self.framebuffers
|
|
// .insert(ImString::new(dst), framebuffer.clone());
|
|
// self.frametextures
|
|
// .insert(ImString::new(dst), texture.clone());
|
|
// }
|
|
// }
|
|
// texture
|
|
// };
|
|
|
|
// new_framebuffer.map(|framebuffer| {
|
|
// new_texture.map(|_| {
|
|
// self.all_vaos_add(&framebuffer.3.as_ref().unwrap().vao);
|
|
// self.all_other_buffers_add(&framebuffer.3.as_ref().unwrap().vbo);
|
|
// framebuffer.3.as_ref().unwrap().ebo.map(|ebo| {
|
|
// self.all_other_buffers_add(&ebo);
|
|
// });
|
|
|
|
// self.program_with_window.get_mut(&framebuffer.2).map(|v| {
|
|
// v.push(ImString::new(dst));
|
|
// });
|
|
// });
|
|
// });
|
|
|
|
// new_texture
|
|
// }
|
|
pub fn create_render_window(&mut self, title: &str, size: [f32; 2]) -> Result<()> {
|
|
// Insert the window data into the windows hashmap
|
|
let id = ImString::new(title);
|
|
let mut data = WindowData::new(id.clone(), size);
|
|
let (fb, tex) =
|
|
self.create_framebuffer(title, (size[0].floor() as i32, size[1].floor() as i32))?;
|
|
|
|
data.framebuffer = Some(fb);
|
|
data.frametexture = Some(tex);
|
|
self.windows.insert(id, data);
|
|
Ok(())
|
|
}
|
|
|
|
pub fn set_config(&mut self, id: &str) -> Option<&mut Config> {
|
|
let id = &ImString::new(id);
|
|
self.windows
|
|
.get_mut(id)
|
|
.map(|v| {
|
|
v.re_init = true;
|
|
v.config.as_mut()
|
|
})
|
|
.flatten()
|
|
}
|
|
|
|
fn reset_window_size(&mut self, id: &ImString, size: [f32; 2]) {
|
|
let window_info = self.windows.get_mut(id).unwrap();
|
|
window_info.need_redraw = true;
|
|
let tex = unsafe {
|
|
self.gl
|
|
.bind_framebuffer(glow::FRAMEBUFFER, window_info.framebuffer);
|
|
let texture = self.gl.create_texture().unwrap();
|
|
self.gl.bind_texture(glow::TEXTURE_2D, Some(texture));
|
|
self.gl.tex_image_2d(
|
|
glow::TEXTURE_2D,
|
|
0,
|
|
glow::RGB8 as i32,
|
|
size[0].floor() as i32,
|
|
size[1].floor() as i32,
|
|
0,
|
|
glow::RGB,
|
|
glow::UNSIGNED_BYTE,
|
|
None,
|
|
);
|
|
self.gl.tex_parameter_i32(
|
|
glow::TEXTURE_2D,
|
|
glow::TEXTURE_MIN_FILTER,
|
|
glow::LINEAR as i32,
|
|
);
|
|
self.gl.tex_parameter_i32(
|
|
glow::TEXTURE_2D,
|
|
glow::TEXTURE_MAG_FILTER,
|
|
glow::LINEAR as i32,
|
|
);
|
|
|
|
self.gl.framebuffer_texture_2d(
|
|
glow::FRAMEBUFFER,
|
|
glow::COLOR_ATTACHMENT0,
|
|
glow::TEXTURE_2D,
|
|
Some(texture),
|
|
0,
|
|
);
|
|
|
|
assert_eq!(
|
|
self.gl.check_framebuffer_status(glow::FRAMEBUFFER),
|
|
glow::FRAMEBUFFER_COMPLETE
|
|
);
|
|
|
|
self.gl.bind_framebuffer(glow::FRAMEBUFFER, None);
|
|
self.gl.bind_texture(glow::TEXTURE_2D, None);
|
|
|
|
texture
|
|
};
|
|
let raw_tex = window_info.frametexture.as_ref().unwrap().to_owned();
|
|
self.all_frametextures_minus(&raw_tex);
|
|
self.all_frametextures_add(&tex);
|
|
}
|
|
|
|
pub fn destroy_window(&mut self) {
|
|
let ids: Vec<_> = self
|
|
.windows
|
|
.iter()
|
|
.filter(|v| v.1.open == false)
|
|
.map(|v| v.0.clone())
|
|
.collect();
|
|
|
|
for id in ids.iter() {
|
|
let window = self.windows.remove(id).unwrap();
|
|
|
|
window.framebuffer.map(|framebuffer| {
|
|
self.all_framebuffers_minus(&framebuffer);
|
|
});
|
|
|
|
window.frametexture.map(|texture| {
|
|
self.all_frametextures_minus(&texture);
|
|
});
|
|
|
|
if let Some(atta) = window.attach {
|
|
self.all_vaos_minus(&atta.vao);
|
|
self.all_other_buffers_minus(&atta.vbo);
|
|
atta.ebo.map(|ebo| {
|
|
self.all_other_buffers_minus(&ebo);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
fn clean(&mut self) {
|
|
info!("Cleaning up unused resources");
|
|
unsafe {
|
|
self.all_framebuffers
|
|
.iter()
|
|
.filter(|v| *v.1 == 0)
|
|
.for_each(|(bf, _)| {
|
|
info!("Deleting framebuffer: {:?}", bf);
|
|
self.gl.delete_framebuffer(*bf);
|
|
});
|
|
|
|
self.all_frametextures
|
|
.iter()
|
|
.filter(|v| *v.1 == 0)
|
|
.for_each(|(bf, _)| {
|
|
info!("Deleting texture: {:?}", bf);
|
|
self.gl.delete_texture(*bf);
|
|
});
|
|
|
|
self.all_vaos
|
|
.iter()
|
|
.filter(|v| *v.1 == 0)
|
|
.for_each(|(bf, _)| {
|
|
info!("Deleting vao: {:?}", bf);
|
|
self.gl.delete_vertex_array(*bf);
|
|
});
|
|
|
|
self.all_other_buffers
|
|
.iter()
|
|
.filter(|v| *v.1 == 0)
|
|
.for_each(|(bf, _)| {
|
|
info!("Deleting buffer: {:?}", bf);
|
|
self.gl.delete_buffer(*bf);
|
|
});
|
|
}
|
|
self.all_framebuffers.retain(|_, v| *v > 0);
|
|
self.all_frametextures.retain(|_, v| *v > 0);
|
|
self.all_vaos.retain(|_, v| *v > 0);
|
|
self.all_other_buffers.retain(|_, v| *v > 0);
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone)]
|
|
pub struct Attach {
|
|
pub vao: NativeVertexArray,
|
|
pub vbo: NativeBuffer,
|
|
pub ebo: Option<NativeBuffer>,
|
|
pub len: i32,
|
|
}
|
|
|
|
pub struct State {}
|
|
|
|
pub struct WindowData {
|
|
pub title: ImString,
|
|
pub open: bool,
|
|
pub copy_from: Option<ImString>,
|
|
pub size: [f32; 2],
|
|
framebuffer: Option<NativeFramebuffer>,
|
|
frametexture: Option<NativeTexture>,
|
|
need_redraw: bool,
|
|
program: usize,
|
|
attach: Option<Attach>,
|
|
|
|
re_init: bool,
|
|
last_mouse_position: [f32; 2],
|
|
last_mouse_delta: [f32; 2],
|
|
accmulate_mouse_delta: [f32; 2],
|
|
mouse_position: [f32; 2],
|
|
motion: Option<MouseState>,
|
|
config: Option<Config>,
|
|
}
|
|
|
|
impl WindowData {
|
|
pub fn new(title: ImString, size: [f32; 2]) -> Self {
|
|
Self {
|
|
title,
|
|
open: true,
|
|
copy_from: None,
|
|
size,
|
|
last_mouse_position: [0.0, 0.0],
|
|
last_mouse_delta: [0.0, 0.0],
|
|
accmulate_mouse_delta: [0.0, 0.0],
|
|
mouse_position: [0.0, 0.0],
|
|
motion: None,
|
|
|
|
framebuffer: None,
|
|
frametexture: None,
|
|
need_redraw: false,
|
|
program: 0,
|
|
attach: None,
|
|
re_init: false,
|
|
config: None,
|
|
}
|
|
}
|
|
|
|
fn set_current_mouse_delta(&mut self, delta: [f32; 2]) {
|
|
self.last_mouse_delta = delta;
|
|
self.accmulate_mouse_delta = [
|
|
self.accmulate_mouse_delta[0] + delta[0],
|
|
self.accmulate_mouse_delta[1] + delta[1],
|
|
];
|
|
}
|
|
|
|
fn set_mouse_postion(&mut self, pos: [f32; 2]) {
|
|
self.mouse_position = pos;
|
|
}
|
|
}
|