This commit is contained in:
Tsuki 2024-10-04 14:05:37 +08:00
parent ebca8d2c31
commit ea48d236c2
18 changed files with 439 additions and 159 deletions

View File

@ -34,7 +34,8 @@ impl LinearColormap {
}
}
pub fn set_colors(&mut self, colors: Vec<[u8; 4]>) {
pub fn set_colors<T: Into<Vec<[u8; 4]>>>(&mut self, colors: T) {
let colors = colors.into();
if colors != self.colors {
self.colors = colors;
self.color_changed = true;
@ -49,7 +50,7 @@ impl LinearColormap {
impl ColorMap for LinearColormap {
fn attach_with_program(
&mut self,
&self,
gl: &glow::Context,
program: &crate::components::Program,
) -> crate::errors::Result<()> {
@ -80,7 +81,8 @@ impl ColorMap for LinearColormap {
glow::TEXTURE_MAG_FILTER,
glow::NEAREST as i32,
);
// self.texture = Some(texture);
}
let location = program.get_uniform_location(gl, "colormap_conf");
gl.uniform_4_f32(
location.as_ref(),
@ -89,29 +91,17 @@ impl ColorMap for LinearColormap {
self.colors.len() as f32,
self.unvalid,
);
self.texture = Some(texture);
}
}
#[cfg(not(target_os = "macos"))]
unsafe {
let texture = gl.create_named_texture(glow::TEXTURE_1D).unwrap();
gl.texture_parameter_i32(
texture,
glow::TEXTURE_MIN_FILTER,
glow::NEAREST as i32,
);
gl.texture_parameter_i32(
texture,
glow::TEXTURE_MAG_FILTER,
glow::NEAREST as i32,
);
gl.texture_parameter_i32(texture, glow::TEXTURE_MIN_FILTER, glow::NEAREST as i32);
gl.texture_parameter_i32(texture, glow::TEXTURE_MAG_FILTER, glow::NEAREST as i32);
// gl.tex_storage_1d(texture, 0, glow::RGBA, self.colors.len() as i32)
todo!("implement this");
}
Ok(())

View File

@ -4,7 +4,7 @@ pub mod linear;
pub trait ColorMap {
fn attach_with_program(
&mut self,
&self,
gl: &glow::Context,
program: &crate::components::Program,
) -> crate::errors::Result<()>;

View File

@ -157,6 +157,7 @@ macro_rules! config_for_everyitem {
pub trait AttachWithIO {
type State: CameraOP;
type Status;
fn attach_with_mouse(
&mut self,
state: &Self::State,
@ -168,6 +169,8 @@ pub trait AttachWithIO {
fn reset(&mut self);
fn init_camera(&self) -> Camera;
fn status(&self) -> Self::Status;
}
#[derive(Debug, Clone)]

View File

@ -3,6 +3,8 @@ use glow::HasContext;
use crate::components::Program;
use crate::errors::Result;
use crate::graphics::collections::agg_fast_path::Path;
use crate::graphics::colormap::linear::LinearColormap;
use crate::graphics::colormap::ColorMap;
use crate::graphics::{AttaWithBuffer, Graphics};
use crate::pg::Attach;
use crate::resources::RcGlRcResource;
@ -14,6 +16,7 @@ pub struct Terrain {
program: Program,
// Buffers
attach: Attach,
color_mapping: LinearColormap,
}
impl Terrain {
@ -26,19 +29,29 @@ impl Terrain {
let default_attach = config.create_attach(gl);
let program = Program::new(vertex, fragment, None, "330 core");
let mut color_mapping = LinearColormap::new()?;
color_mapping.set_colors([
[0, 77, 204, 0],
[194, 179, 128, 13],
[51, 204, 51, 77],
[51, 51, 51, 153],
[255, 255, 255, 255],
]);
color_mapping.set_range(0.0, 1.0);
Ok(Self {
program,
attach: default_attach,
color_mapping,
})
}
fn set_conf(&mut self, gl: &glow::Context, config: &TerrainConfig) -> Result<()> {
unsafe {
let sun_loc = self.program.get_uniform_location(gl, "sun_location");
gl.uniform_3_f32_slice(sun_loc.as_ref(), &config.sun_location);
let er = self.program.get_uniform_location(gl, "ER");
gl.uniform_1_f32(er.as_ref(), config.earth_radius);
let er = self.program.get_uniform_location(gl, "earth");
gl.uniform_3_f32(er.as_ref(), config.earth_radius, config.theta, config.phi);
let ts = self.program.get_uniform_location(gl, "terrain_scale");
gl.uniform_1_f32(ts.as_ref(), config.terrain_scale);
@ -49,6 +62,13 @@ impl Terrain {
gl.active_texture(glow::TEXTURE0);
gl.bind_texture(glow::TEXTURE_2D, Some(texture.native()));
}
let tex_range = self.program.get_uniform_location(gl, "tex_range");
gl.uniform_4_f32_slice(tex_range.as_ref(), config.tex_range.as_slice());
let max_height = self.program.get_uniform_location(gl, "maxHeight");
gl.uniform_1_f32(max_height.as_ref(), config.max_height);
}
Ok(())
}
@ -58,6 +78,8 @@ pub struct TerrainConfig {
pub earth_radius: f32,
pub sun_location: [f32; 3],
pub terrain_scale: f32,
pub theta: f32,
pub phi: f32,
max_height: f32,
tex_range: [f32; 4],
terrain_texture: Option<RcGlRcResource<glow::NativeTexture>>,
@ -100,11 +122,13 @@ impl TerrainConfig {
impl Default for TerrainConfig {
fn default() -> Self {
Self {
earth_radius: 3.0,
earth_radius: 300.0,
sun_location: [10.0, 0.0, 0.0],
terrain_scale: 1.0,
tex_range: [0.0, 0.0, 0.0, 0.0],
max_height: 1.0,
tex_range: [0.0, 90.0, 60.0, 90.0],
max_height: 10.0,
phi: 0.0,
theta: 0.0,
terrain_texture: None,
}
}
@ -118,24 +142,51 @@ impl TerrainConfig {
) -> crate::errors::Result<()> {
let img = image::open(path).unwrap();
let img = img.flipv();
let img = img.to_rgba8();
let img = img.to_luma8();
let (width, height) = img.dimensions();
let data = img.into_raw();
let texture = unsafe {
let texture = gl.create_texture().unwrap();
gl.bind_texture(glow::TEXTURE_2D, Some(texture));
gl.pixel_store_i32(glow::UNPACK_ALIGNMENT, 1);
gl.tex_parameter_f32(glow::TEXTURE_2D, glow::TEXTURE_BORDER_COLOR, 0.0);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_S,
glow::CLAMP_TO_BORDER as i32,
);
gl.tex_parameter_i32(
glow::TEXTURE_2D,
glow::TEXTURE_WRAP_T,
glow::CLAMP_TO_BORDER as i32,
);
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.tex_image_2d(
glow::TEXTURE_2D,
0,
glow::RGBA as i32,
glow::R8 as i32,
width as i32,
height as i32,
0,
glow::RGBA,
glow::RED,
glow::UNSIGNED_BYTE,
Some(&data),
);
gl.generate_mipmap(glow::TEXTURE_2D);
texture
};
@ -145,6 +196,10 @@ impl TerrainConfig {
Ok(())
}
pub fn get_alt_texture(&self) -> Option<&RcGlRcResource<glow::NativeTexture>> {
self.terrain_texture.as_ref()
}
}
impl Graphics for Terrain {
@ -161,6 +216,8 @@ impl Graphics for Terrain {
}
fn draw(&self, gl: &glow::Context, count: i32) -> Result<()> {
self.color_mapping.attach_with_program(gl, &self.program);
self.color_mapping.bind_texture(gl, &self.program);
self.attach.bind_self(gl, &self.program);
unsafe {
gl.draw_elements(glow::TRIANGLES, self.attach.len, glow::UNSIGNED_INT, 0);

View File

@ -42,6 +42,8 @@ impl AttaWithProgram for Trackball {
impl AttachWithIO for Trackball {
type State = super::MouseState;
type Status = ();
fn attach_with_mouse(
&mut self,
state: &Self::State,
@ -74,4 +76,8 @@ impl AttachWithIO for Trackball {
Vec3::new(0.0, 0.0, 0.0),
)
}
fn status(&self) -> Self::Status {
()
}
}

View File

@ -47,6 +47,7 @@ impl PlaneTrans {
impl AttachWithIO for PlaneTrans {
type State = MouseKeyboardState;
type Status = ();
fn attach_with_mouse(
&mut self,
@ -104,6 +105,10 @@ impl AttachWithIO for PlaneTrans {
}
fn reset(&mut self) {}
fn status(&self) -> Self::Status {
()
}
}
impl AttaWithProgram for PlaneTrans {

View File

@ -1,9 +1,13 @@
use crate::components::Program;
use crate::camera::Camera;
use crate::errors::Result;
use crate::graphics::AttaWithProgram;
use crate::graphics::{AttaWithProgram, MouseKeyboardState, MouseState};
use crate::pg::layout_type::ViewPort;
use crate::ui::operation::Projection;
use crate::{components::Program, graphics::AttachWithIO};
use glow::HasContext;
use nalgebra::{Matrix4, Quaternion, Translation3, Unit, UnitQuaternion, Vector3};
use nalgebra_glm::Vec3;
#[derive(Debug, Clone)]
pub struct TrackballModel {
@ -18,6 +22,12 @@ pub struct TrackballModel {
phi: f32,
}
impl Default for TrackballModel {
fn default() -> Self {
Self::new(0.0, 0.0, 200.0)
}
}
impl TrackballModel {
pub fn new(phi: f32, theta: f32, range: f32) -> Self {
let mut trackball = Self {
@ -55,6 +65,8 @@ impl TrackballModel {
self.count = 0;
}
self.model = self.rotation.to_homogeneous();
self.theta = self.get_orientation().0;
self.phi = self.get_orientation().1;
}
fn model(&self) -> &Matrix4<f32> {
@ -138,21 +150,38 @@ impl TrackballModel {
}
}
// impl Trackball {
// pub fn new() -> Result<Self> {
// let model = TrackballModel::new(0.0, 0.0);
impl AttachWithIO for TrackballModel {
type State = MouseKeyboardState;
type Status = (f32, f32);
// Ok(Self { model })
// }
fn attach_with_mouse(
&mut self,
state: &Self::State,
camera: &mut Camera,
projection: &mut Projection,
viewport: &ViewPort,
) -> bool {
match state.mouse_state {
MouseState::Drag { from, delta } => {
self.drag_to(from[0], from[1], delta[0], delta[1]);
true
}
_ => false,
}
}
// pub fn on_mouse_drag(&mut self, x: f32, y: f32, dx: f32, dy: f32) {
// self.model.drag_to(x, y, dx, dy);
// }
fn reset(&mut self) {}
// pub fn model(&self) -> &Matrix4<f32> {
// self.model.model()
// }
// }
fn init_camera(&self) -> Camera {
let mut camera = Camera::default();
camera.set_position(Vec3::new(0.0, 0.0, 1100.0));
camera
}
fn status(&self) -> Self::Status {
(self.theta, self.phi)
}
}
impl AttaWithProgram for TrackballModel {
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> Result<()> {

View File

@ -10,7 +10,7 @@ use crate::{
},
ui::{
helper::{self, Helper},
operation::Operation,
operation::{Operation, Operations},
},
utils::resources::{
ManagedResource, RcGlBuffer, RcGlFramebuffer, RcGlRcFramebuffer, RcGlRcRenderbuffer,
@ -51,14 +51,14 @@ impl App {
Ok(())
}
pub fn set_init_modules(&mut self, modules: ModulePackage) {
self.init_modules = Some(modules);
pub fn set_init_modules<T: Into<ModulePackage>>(&mut self, modules: T) {
self.init_modules = Some(modules.into());
}
pub fn render<'a>(
&'a mut self,
modules: &mut Vec<Rc<RefCell<ModulePackage>>>,
operation: &Operation<PlaneTrans>,
operation: &Operations,
viewport: &ViewPort,
) {
if let Some(module) = self.init_modules.as_mut() {

View File

@ -33,7 +33,10 @@ use crate::{
transforms::plane::PlaneTrans,
AttaWithProgram, AttachWithIO, Graphics,
},
ui::{operation::Operation, typ::LayoutAttach},
ui::{
operation::{Operation, Operations},
typ::LayoutAttach,
},
utils::resources::GL,
};
@ -259,13 +262,13 @@ macro_rules! impl_module_package {
pub fn draw_modules(
&mut self,
modules: &mut ModulePackage,
operation: &Operation<PlaneTrans>,
operation: &Operations,
viewport: &ViewPort,
) -> Result<()> {
match &mut modules.modules {
$(
_ModulePackage::$b(m) => {
self.$method().render(m, operation, viewport)?;
self.$method().render(m, operation.into(), viewport)?;
}
)+
}

View File

@ -13,6 +13,7 @@ use crate::{
transforms::plane::PlaneTrans,
Graphics,
},
ui::operation::Operations,
GL,
};
@ -34,7 +35,7 @@ pub struct EarthModulePackage {}
impl<'b, 'gl: 'b> Module for EarthModule<'b, 'gl> {
type Cursor = EarthModulePackage;
type Data = ();
type Operation = PlaneTrans;
// type Operation = PlaneTrans;
const NAME: &'static str = "Earth";
@ -49,13 +50,14 @@ impl<'b, 'gl: 'b> Module for EarthModule<'b, 'gl> {
fn render(
&mut self,
cursor: &mut Self::Cursor,
operation: &crate::ui::operation::Operation<Self::Operation>,
operation: &crate::ui::operation::Operations,
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());
if let Operations::PT(operation) = operation {
// Camera Info
let camera_loc = operation.camera().get_position();
@ -93,6 +95,7 @@ impl<'b, 'gl: 'b> Module for EarthModule<'b, 'gl> {
operation.camera().ca().as_slice(),
);
}
}
self.earth.draw(&self.gl, 1);
Ok(())

View File

@ -5,9 +5,10 @@ use crate::{
geoquadmesh::{GeoQuadMesh, GeoQuadMeshConfig},
ppi::{PPIConfig, PPI},
transforms::plane::PlaneTrans,
AttaWithBuffer, Graphics,
AttaWithBuffer, AttaWithProgram, Graphics,
},
pg::SideBarInputMsg,
ui::operation::Operations,
GL,
};
use radarg_core::{config::Setting, CoordType, Data};
@ -115,14 +116,14 @@ impl<'b, 'a: 'b> GeoQuadMeshModule<'b, 'a> {
impl<'b, 'a: 'b> Module for GeoQuadMeshModule<'b, 'a> {
type Cursor = GeoQuadMeshPackage;
type Data = Arc<RadarGridData>;
type Operation = PlaneTrans;
// type Operation = PlaneTrans;
const NAME: &'static str = "GeoQuadMesh";
fn render<'dt>(
&mut self,
cursor: &mut Self::Cursor,
operation: &Operation<Self::Operation>,
operation: &Operations,
viewport: &ViewPort,
) -> Result<()> {
// PPI Program

View File

@ -3,7 +3,7 @@ use crate::{
graphics::AttachWithIO,
resources::{RcGlRcBuffer, RcGlRcResource, RcGlRcVertexArray},
ui::{
operation::{self, Operation},
operation::{self, Operation, Operations},
typ::CameraOP,
},
utils::resources::{ManagedResource, RcGlBuffer, RcGlVertexArray},
@ -152,20 +152,22 @@ impl Attach {
pub trait Module: Sized {
type Cursor: ModuleCursor;
type Data;
type Operation: AttachWithIO;
// type Operation: AttachWithIO;
const NAME: &'static str;
fn render(
&mut self,
cursor: &mut Self::Cursor,
operation: &Operation<Self::Operation>,
operation: &Operations,
viewport: &ViewPort,
) -> Result<()>;
fn load_data<'dt>(&self, data: &Self::Data, setting: &Setting) -> Result<Self::Cursor>;
fn supported(&self, data: &Data) -> bool;
fn supported(&self, data: &Data) -> bool {
false
}
}
pub trait ModuleCursor {

View File

@ -4,9 +4,10 @@ use crate::{
font::{Anchor, FontConfig, LineStyle, PositionText, Text, TextLine},
ppi::{PPIConfig, PPI},
transforms::plane::PlaneTrans,
AttaWithBuffer, Graphics,
AttaWithBuffer, AttaWithProgram, Graphics,
},
pg::SideBarInputMsg,
ui::operation::Operations,
GL,
};
use radarg_core::{config::Setting, CoordType};
@ -283,14 +284,14 @@ impl<'b, 'a: 'b> PPIModule<'b, 'a> {
impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
type Cursor = PPIPackage;
type Data = Arc<RadarGridData>;
type Operation = PlaneTrans;
// type Operation = PlaneTrans;
const NAME: &'static str = "PPI";
fn render<'dt>(
&mut self,
cursor: &mut Self::Cursor,
operation: &Operation<Self::Operation>,
operation: &Operations,
viewport: &ViewPort,
) -> Result<()> {
// PPI Program
@ -299,7 +300,6 @@ impl<'b, 'a: 'b> Module for PPIModule<'b, 'a> {
// Mount PPI Program
self.ppi_program.mount(&self.gl)?;
// Deal with the operation
operation.attach_with_program(&self.gl, self.ppi_program.program());
let ppi_attach = &mut cursor.ppi_attach;

View File

@ -10,7 +10,7 @@ use std::{cell::RefCell, rc::Rc, sync::Arc};
use crate::{
graphics::{
planet::terrain::{Terrain, TerrainConfig},
transforms::plane::PlaneTrans,
transforms::{plane::PlaneTrans, trackball::TrackballModel},
Graphics,
},
GL,
@ -23,20 +23,24 @@ pub struct TerrainModule<'b, 'gl: 'b> {
terrain: &'b mut Terrain,
}
impl<'b, 'gl: 'b> TerrainModule<'b, 'gl> {
pub fn name(&self) -> &'static str {
"Terrain"
}
pub fn supported(&self, data: &Arc<radarg_core::Data>) -> bool {
false
}
}
impl<'b, 'gl: 'b> TerrainModule<'b, 'gl> {
pub fn new(gl: &'gl GL, terrain: &'b mut Terrain) -> Self {
Self { gl, terrain }
}
fn bind_texture(&self, conf: &TerrainConfig) {
unsafe {
if let Some(tex) = conf.get_alt_texture() {
self.gl.active_texture(glow::TEXTURE1);
self.gl.bind_texture(glow::TEXTURE_2D, Some(tex.native()));
let position = self
.terrain
.program_ref()
.get_uniform_location(&self.gl, "terrain_texture");
self.gl.uniform_1_i32(position.as_ref(), 1);
}
}
}
}
pub struct TerrainModulePackage {
@ -46,7 +50,7 @@ pub struct TerrainModulePackage {
impl<'b, 'gl: 'b> Module for TerrainModule<'b, 'gl> {
type Cursor = TerrainModulePackage;
type Data = ();
type Operation = PlaneTrans;
// type Operation = TrackballModel;
const NAME: &'static str = "Terrain";
@ -64,15 +68,22 @@ impl<'b, 'gl: 'b> Module for TerrainModule<'b, 'gl> {
fn render(
&mut self,
cursor: &mut Self::Cursor,
operation: &crate::ui::operation::Operation<Self::Operation>,
operation: &crate::ui::operation::Operations,
viewport: &crate::pg::layout_type::ViewPort,
) -> super::Result<()> {
self.terrain.mount(&self.gl)?;
let conf = &mut cursor.conf.terrain_conf;
let conf = &cursor.conf.terrain_conf;
match operation {
crate::ui::operation::Operations::TB(operation) => {
// Theta and Phi
let (theta, phi) = operation.status();
conf.theta = theta;
conf.phi = phi;
println!("Theta: {}, Phi: {}", theta, phi);
self.terrain.set_config(&self.gl, conf);
self.terrain.set_config(&self.gl, conf)?;
// operation.attach_with_program(&self.gl, self.earth.program_mut());
// Camera Info
let camera_loc = operation.camera().get_position();
@ -85,11 +96,39 @@ impl<'b, 'gl: 'b> Module for TerrainModule<'b, 'gl> {
let znear = operation.projection().z_near();
let zfar = operation.projection().z_far();
Ok(())
// Left Hand Coordinate System
let ca = operation.camera().ca();
unsafe {
let gl = &self.gl;
let program = self.terrain.program_ref();
let p = program.get_uniform_location(gl, "focal_length");
gl.uniform_1_f32(p.as_ref(), focal_length);
let p = program.get_uniform_location(gl, "resolution");
gl.uniform_2_f32_slice(p.as_ref(), &resolution);
let p = program.get_uniform_location(gl, "projection_params");
gl.uniform_2_f32(p.as_ref(), znear, zfar);
let p = program.get_uniform_location(gl, "ca");
gl.uniform_matrix_3_f32_slice(p.as_ref(), false, ca.as_slice());
let p = program.get_uniform_location(gl, "camera_location");
gl.uniform_3_f32_slice(
p.as_ref(),
operation.camera().get_position().as_slice(),
);
}
}
_ => {}
}
fn supported(&self, data: &radarg_core::Data) -> bool {
false
self.bind_texture(conf);
self.terrain.draw(&self.gl, 4);
Ok(())
}
}

View File

@ -67,22 +67,41 @@ impl TerrainFragment {
return vec2( max( max( t1.x, t1.y ), t1.z ),min( min( t2.x, t2.y ), t2.z ) );
}
vec2 sdf(vec3 p) {
float ER = earth.x;
float alpha = earth.y;
float beta = earth.z;
float theta = earth.y;
float phi = earth.z;
float longitude = atan(p.z, p.x) + alpha;
float latitude = atan(p.y, length(p.xz)) + beta;
// Lon and Lat
float lon = (atan(p.z, p.x) + theta) / (2.0 * PI) * 360.0;
float lat = (atan(p.y, length(p.xy)) + phi) / (2.0 * PI) * 360.0;
// 从高度图获取地形高度
vec2 uv = vec2((longitude + PI) / (2.0 * PI), (latitude + PI / 2.0) / PI);
// Texture UV
float lon_start = tex_range.x;
float lon_end = tex_range.y;
float lat_start = tex_range.z;
float lat_end = tex_range.w;
float baseDist = length(p) - ER;
vec2 uv = vec2((lon - lon_start) / (lon_end - lon_start), (lat - lat_start) / (lat_end - lat_start));
float height = texture(terrain_texture, uv).r * maxHeight;
float h = baseDist - height*5.0;
// 计算点到地球表面的最近距离
float baseDist = length(p) - ER - height;
return vec2(baseDist, height);
return vec2(h, height);
}
vec3 calcNormal( in vec3 pos )
{
vec2 e = vec2(1.0,-1.0)*0.5773*0.0005;
return normalize( e.xyy*sdf( pos + e.xyy).x +
e.yyx*sdf( pos + e.yyx).x +
e.yxy*sdf( pos + e.yxy).x +
e.xxx*sdf( pos + e.xxx).x );
}
vec2 raycast(vec3 ro, vec3 rd) {
@ -104,11 +123,12 @@ impl TerrainFragment {
int i = 0;
while (i < 70 && t < tmax) {
vec2 h = sdf(ro + rd * t);
if (abs(h.x) < (0.0001 * t)) {
res = vec2(t, h.y);
vec2 cast_result = sdf(ro + rd * t);
if (abs(cast_result.x) < (0.0001 * t)) {
res = cast_result;
break;
}
t += h.x;
t += cast_result.x;
i += 1;
}
}
@ -116,18 +136,51 @@ impl TerrainFragment {
}
void main() {
vec2 p = (2.0 * gl_FragCoord.xy - resolution) / resolution.y;
vec3 rd = normalize(ca * vec3(p, focal_length));
vec2 res = raycast(camera_location, rd);
float t = res.x;
float m = res.y;
if (m < 0.0) {
vec3 pos = camera_location + rd*t;
if (t < 0.0) {
discard;
}
FragColor = vec4(1.0, 0.0, 0.0, 1.0);
vec3 col = vec3(0.7, 0.7, 0.9) - max(1.0,0.0)*0.3;
float m = res.y;
// float m = 1.0 - res.y;
// col = 0.2 + 0.2*sin( m*2.0 + vec3(0.0,1.0,2.0) );
// col = linear_colormap(m).rgb;
col = vec3(1.0,1.0,1.0);
vec3 nor = calcNormal(pos);
vec3 lin = vec3(0.0);
float ks = 1.0;
// FragColor = vec4(m,m,m,1.0);
vec3 lig = normalize( vec3(-0.5, 0.4, -0.6) );
vec3 hal = normalize( lig-rd );
float dif = clamp( dot( nor, lig ), 0.0, 1.0 );
float spe = pow( clamp( dot( nor, hal ), 0.0, 1.0 ),16.0);
spe *= dif;
spe *= 0.04+0.96*pow(clamp(1.0-dot(hal,lig),0.0,1.0),5.0);
lin += col*2.20*dif*vec3(1.30,1.00,0.70);
lin += 5.00*spe*vec3(1.30,1.00,0.70)*ks;
col = clamp(mix( col, vec3(0.7,0.7,0.9), 1.0-exp( -0.0001*t*t*t ) ), 0.0, 1.0);
FragColor = vec4(col, 1.0);
}
"

View File

@ -2,10 +2,97 @@ use super::typ::CameraOP;
use crate::{
camera::Camera,
components::Program,
graphics::{AttaWithProgram, AttachWithIO},
graphics::{
transforms::{plane::PlaneTrans, trackball::TrackballModel},
AttaWithProgram, AttachWithIO,
},
pg::layout_type::ViewPort,
};
macro_rules! impl_operations {
($({$operation:ty => $b:tt, $method: ident}),+) => {
pub enum Operations {
$(
$b(Operation<$operation>)
),+
}
impl Operations {
$(
pub fn $method() -> Self {
Operations::$b(Operation::new(<$operation>::default(), 16.0/9.0, 45.0,0.1,1000.0 ))
}
)+
pub fn set_projection(&mut self, f: impl Fn(&mut Projection)) {
match self {
$(
Operations::$b(op) => {
op.set_projection(f);
op.need_update = true;
}
)+
}
}
pub fn deal_io(&mut self, viewport: &ViewPort, io: &super::io::IO) {
match self {
$(
Operations::$b(op) => {
op.deal_io(viewport, io);
}
)+
}
}
pub fn set_camera(&mut self, camera: Camera) {
match self {
$(
Operations::$b(op) => {
op.camera = camera;
op.need_update = true;
}
)+
}
}
}
$(
impl<'a> From<&'a Operations> for &'a Operation<$operation> {
fn from(operations: &'a Operations) -> Self {
match operations {
Operations::$b(op) => op,
_ => panic!("error transfer"),
}
}
}
)+
impl AttaWithProgram for Operations {
fn attach_with_program(&self, gl: &glow::Context, program: &Program) -> super::Result<()> {
match self {
$(
Operations::$b(op) => {
op.operation.attach_with_program(gl, program)?;
}
),+
}
Ok(())
}
}
};
}
pub struct Operation<T: AttachWithIO> {
camera: Camera,
projection: Projection,
@ -51,7 +138,7 @@ impl<T: AttachWithIO + AttaWithProgram> Operation<T> {
self.need_update = true;
}
pub fn attach_with_program(&self, gl: &glow::Context, program: &mut Program) {
pub fn attach_with_program(&self, gl: &glow::Context, program: &Program) {
use glow::HasContext;
unsafe {
let projection = program.get_uniform_location(gl, "trackball_projection");
@ -78,6 +165,10 @@ impl<T: AttachWithIO + AttaWithProgram> Operation<T> {
pub fn clean(&mut self) {
self.need_update = false;
}
pub fn status(&self) -> <T as AttachWithIO>::Status {
self.operation.status()
}
}
pub struct Projection {
@ -143,3 +234,8 @@ impl Projection {
self.projection.as_slice()
}
}
impl_operations!(
{PlaneTrans => PT, plane_trans},
{TrackballModel => TB, trackball_model}
);

View File

@ -56,8 +56,6 @@ fn main() {
});
}
// gi.prepare();
let app = adw::Application::builder().application_id(APP_ID).build();
let relm: RelmApp<AppMsg> = relm4::RelmApp::from_app(app.clone());
relm4_icons::initialize_icons();

View File

@ -8,7 +8,7 @@ use gi::graphics::transforms::plane::PlaneTrans;
use gi::pg::layout_type::ViewPort;
use gi::pg::{Module, ModulePackage};
use gi::ui::io::IO;
use gi::ui::operation::Operation;
use gi::ui::operation::Operations;
use gi::{App as GI, Helper, GL};
use glow::HasContext;
use gtk::glib::{self, prelude::*, Properties};
@ -64,7 +64,7 @@ pub struct Render {
#[property(get, set)]
scale: Cell<f64>,
pub(super) io: RefCell<IO>,
pub(super) opeartion: RefCell<Operation<PlaneTrans>>,
pub(super) opeartion: RefCell<Operations>,
pub(super) exterior: RefCell<ExteriorWidget>,
pub(super) interior: RefCell<InteriorWidget>,
pub(super) gi: RefCell<Option<GI>>,
@ -79,13 +79,7 @@ impl Default for Render {
fn default() -> Self {
Self {
scale: Cell::new(1.0),
opeartion: RefCell::new(Operation::new(
PlaneTrans::default(),
16.0 / 9.0,
45.0,
0.1,
1000.0,
)),
opeartion: RefCell::new(Operations::trackball_model()),
io: RefCell::new(IO::default()),
range_changing: Cell::new(0.0),
render_status: Cell::new(0),
@ -247,9 +241,10 @@ impl Render {
gi.prepare(&SETTING).expect("Cannot prepare GI");
// Terrain
let terrain_module = gi.program().terrain().load_data(&(), &SETTING).unwrap();
let init_module = gi.program().terrain().load_data(&(), &SETTING).unwrap();
// let init_module = gi.program().earth().load_data(&(), &SETTING).unwrap();
// Init Modules
gi.set_init_modules(terrain_module.into());
gi.set_init_modules(init_module);
// Set Modules
self.viewport.replace(Some(viewport));