use geo_macros::{module_ref_impl, ModuleRef}; use glow::HasContext; use relm4::{ adw::{self, prelude::*}, gtk::{self, prelude::*}, view, ComponentParts, SimpleComponent, }; use std::{cell::RefCell, rc::Rc, sync::Arc}; use crate::{ graphics::{ planet::earth::{Earth, EarthConfig}, transforms::plane::PlaneTrans, Graphics, }, GL, }; use super::{Module, ModuleCursor}; #[derive(ModuleRef)] pub struct EarthModule<'b, 'gl: 'b> { gl: &'gl GL, earth: &'b mut Earth, } impl<'b, 'gl: 'b> EarthModule<'b, 'gl> { pub fn name(&self) -> &'static str { "Earth" } pub fn supported(&self, data: &Arc) -> bool { false } } impl<'b, 'gl: 'b> EarthModuleRef<'b, 'gl> { pub fn name(&self) -> &'static str { "Earth" } pub fn supported(&self, data: &Arc) -> bool { false } } impl<'b, 'gl: 'b> EarthModule<'b, 'gl> { pub fn new(gl: &'gl GL, earth: &'b mut Earth) -> Self { Self { gl, earth } } } impl<'b, 'gl: 'b> EarthModuleRef<'b, 'gl> { pub fn new(gl: &'gl GL, earth: &'b Earth) -> Self { Self { gl, earth } } } pub struct EarthModulePackage {} impl<'b, 'gl: 'b> Module for EarthModule<'b, 'gl> { type Cursor = EarthModulePackage; type Data = (); type Operation = PlaneTrans; const NAME: &'static str = "Earth"; fn load_data<'dt>( &self, data: &Self::Data, setting: &radarg_core::config::Setting, ) -> super::Result { Ok(EarthModulePackage {}) } fn render( &mut self, cursor: &mut Self::Cursor, operation: &crate::ui::operation::Operation, viewport: &crate::pg::layout_type::ViewPort, ) -> super::Result<()> { self.earth.mount(&self.gl)?; self.earth.set_config(&self.gl, &EarthConfig::default())?; operation.attach_with_program(&self.gl, self.earth.program_mut()); // Camera Info let camera_loc = operation.camera().get_position(); // focal length let focal_length = operation.projection().fov(); let focal_length = 1.0 / ((focal_length / 2.0).to_radians().tan()); // Viewport Info let resolution = viewport.size(); let znear = operation.projection().z_near(); let zfar = operation.projection().z_far(); unsafe { let earth_program = self.earth.program_mut(); let cloc = earth_program.get_uniform_location(&self.gl, "camera_location"); let foc = earth_program.get_uniform_location(&self.gl, "focal_length"); let res = earth_program.get_uniform_location(&self.gl, "resolution"); let projection_params = earth_program.get_uniform_location(&self.gl, "projection_params"); self.gl .uniform_3_f32(cloc.as_ref(), camera_loc.x, camera_loc.y, camera_loc.z); self.gl.uniform_1_f32(foc.as_ref(), focal_length); self.gl.uniform_2_f32_slice(res.as_ref(), &resolution); self.gl .uniform_2_f32(projection_params.as_ref(), znear, zfar); } self.earth.draw(&self.gl, 1); Ok(()) } fn supported(&self, data: &radarg_core::Data) -> bool { false } } impl ModuleCursor for EarthModulePackage { type Module<'rf, 'gl: 'rf> = EarthModule<'rf, 'gl>; type Config = (); type Data = (); type Component = EarthModuleConfigComponent; type ComponentOutput = (); fn set_config(&mut self, f: F) where F: FnOnce(&mut Self::Config), { } fn component_config(&self) -> () { () } fn component_sender(&self) -> Box crate::pg::SideBarInputMsg> { todo!() } } pub struct EarthModuleConfigComponent {} #[relm4::component(pub)] impl SimpleComponent for EarthModuleConfigComponent { type Widgets = EarthModuleConfigComponentWidgets; type Init = (); type Input = (); type Output = (); view! { adw::PreferencesPage { } } fn init( init: Self::Init, root: Self::Root, sender: relm4::ComponentSender, ) -> relm4::ComponentParts { let model = EarthModuleConfigComponent {}; let widgets = view_output!(); ComponentParts { model, widgets } } fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender) {} }