radar-g/gi/src/pg/modules/earth.rs
2024-09-13 09:53:17 +08:00

175 lines
4.4 KiB
Rust

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<radarg_core::Data>) -> bool {
false
}
}
impl<'b, 'gl: 'b> EarthModuleRef<'b, 'gl> {
pub fn name(&self) -> &'static str {
"Earth"
}
pub fn supported(&self, data: &Arc<radarg_core::Data>) -> 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<Self::Cursor> {
Ok(EarthModulePackage {})
}
fn render(
&mut self,
cursor: &mut Self::Cursor,
operation: &crate::ui::operation::Operation<Self::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<F>(&mut self, f: F)
where
F: FnOnce(&mut Self::Config),
{
}
fn component_config(&self) -> () {
()
}
fn component_sender(&self) -> Box<dyn Fn(Self::ComponentOutput) -> 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<Self>,
) -> relm4::ComponentParts<Self> {
let model = EarthModuleConfigComponent {};
let widgets = view_output!();
ComponentParts { model, widgets }
}
fn update(&mut self, message: Self::Input, sender: relm4::ComponentSender<Self>) {}
}