diff options
author | pommicket <pommicket@gmail.com> | 2022-12-13 18:52:43 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-12-13 18:52:43 -0500 |
commit | 0649f21d9b60ebedffc3731374feb6132e38804a (patch) | |
tree | 0ca6fcd99f08a02f4f3baf361374a06ad829d08f /src | |
parent | 3f699f3720ef8d912e509bc3785485b527419dc0 (diff) |
more functions
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 94 | ||||
-rw-r--r-- | src/sdf.rs | 28 | ||||
-rw-r--r-- | src/sdl.rs | 1 | ||||
-rw-r--r-- | src/win.rs | 56 |
4 files changed, 127 insertions, 52 deletions
diff --git a/src/main.rs b/src/main.rs index 6fef680..c55d1c0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,14 +27,19 @@ struct View { pos: Vec3, yaw: f32, pitch: f32, + level_set: f32, } impl Default for View { fn default() -> Self { + // don't start out right next to the origin, since weird stuff might be happening there + let pos = Vec3::new(0.0, 0.0, 4.0); + Self { - pos: Vec3::zeros(), + pos, yaw: 0.0, pitch: 0.0, + level_set: 0.0, } } } @@ -49,16 +54,18 @@ impl View { Mat4::new_translation(&self.pos) } + #[allow(dead_code)] fn transform(&self) -> Mat4 { self.translation() * self.rotation().to_homogeneous() } - } fn try_main() -> Result<(), String> { - use sdf::{R3ToR, Constant}; - let funciton = R3ToR::mix(R3ToR::sphere_f32(1.0), R3ToR::cube_f32(1.0), - Constant::Time(0.1, 0.0)); + use sdf::{R3ToR}; + let funciton = R3ToR::min( + R3ToR::sphere_f32(1.5), + R3ToR::cube_f32(1.0), + ); let my_sdf = sdf::Sdf::from_function(funciton); let mut window = win::Window::new("AutoSDF", 1280, 720, true) @@ -68,8 +75,12 @@ fn try_main() -> Result<(), String> { fshader_source.push_str( " IN vec2 pos; -uniform mat4 u_transform; +uniform mat3 u_rotation; +uniform vec3 u_translation; uniform float u_time; +uniform float u_fov; +uniform float u_focal_length; +uniform float u_level_set; ", ); my_sdf.to_glsl(&mut fshader_source); @@ -79,27 +90,11 @@ uniform float u_time; #define AA_X 1 #define AA_Y 1 - - -float fbm(vec3 p) { - float t = 0.0; - float freq = 24.0; - mat3 m = mat3(cos(1.),sin(1.),0, - -sin(1.),cos(1.),0, - 0, 0, 1) * mat3( - 1, 0, 0, - 0, cos(1.),sin(1.), - 0, -sin(1.),cos(1.) - ); - for(int i = 0; i < 5; i++) - { - p = m * p; - t += pow(0.6, float(i)) * sin(freq*p.x)*sin(freq*p.y)*sin(freq*p.z); - freq *= 2.0; - } - return t; +float sdf_adjusted(vec3 p) { + return sdf(p) - u_level_set; } - +#define sdf sdf_adjusted + vec3 normal(vec3 p) { // thanks to https://iquilezles.org/articles/normalsSDF/ @@ -113,7 +108,6 @@ vec3 normal(vec3 p) } void main() { - float focal_length = 1.0; float min_dist = 10.; vec2 inv_screen_size = 1.0 / vec2(1280.0, 720.0); // @TODO vec2 aa_delta = inv_screen_size / vec2(AA_X, AA_Y); @@ -121,8 +115,10 @@ void main() { for (int m = 0; m < AA_X; m++) { for (int n = 0; n < AA_Y; n++) { vec2 aa_offset = vec2(float(m), float(n)) * aa_delta; - vec3 p = (u_transform * vec4(pos + aa_offset, -focal_length, 1.0)).xyz; + vec3 pos3d = vec3((pos + aa_offset) * sin(u_fov * 0.5), -1.0) * u_focal_length; + vec3 p = u_rotation * pos3d; vec3 delta = normalize(p); + p += u_translation; if (sdf(p) < 0.0) { // looking inside object o_color = vec4(1.0, 0.0, 1.0, 1.0); @@ -187,7 +183,7 @@ void main() { 'mainloop: loop { let frame_dt = frame_time.elapsed().as_secs_f32(); frame_time = Instant::now(); - + while let Some(event) = window.next_event() { use win::Event::*; use win::Key::*; @@ -201,22 +197,26 @@ void main() { _ => {} } } - - { // movement + + { + // movement let mut dx = 0.0; let mut dy = 0.0; let mut dz = 0.0; - use win::Key::{Left, Right, Up, Down, W, A, S, D, Q, E}; - if window.is_key_down(W) || window.is_key_down(Up) { + let mut dl = 0.0; + use win::Key::{ + Down, Left, NumPad3, NumPad9, PageDown, PageUp, Right, Up, A, D, E, M, N, Q, S, W, + }; + if window.any_key_down(&[W, Up]) { dz -= 1.0; } - if window.is_key_down(S) || window.is_key_down(Down) { + if window.any_key_down(&[S, Down]) { dz += 1.0; } - if window.is_key_down(A) || window.is_key_down(Left) { + if window.any_key_down(&[A, Left]) { dx -= 1.0; } - if window.is_key_down(D) || window.is_key_down(Right) { + if window.any_key_down(&[D, Right]) { dx += 1.0; } if window.is_key_down(Q) { @@ -225,21 +225,35 @@ void main() { if window.is_key_down(E) { dy -= 1.0; } + if window.any_key_down(&[PageUp, NumPad9, M]) { + dl += 1.0; + } + if window.any_key_down(&[PageDown, NumPad3, N]) { + dl -= 1.0; + } let motion = Vec3::new(dx, dy, dz); if let Some(motion) = motion.try_normalize(0.001) { - let motion = motion * frame_dt; + let move_speed = 2.0; + let motion = motion * frame_dt * move_speed; let motion = view.rotation() * motion; view.pos += motion; } + + let level_set_speed = 1.0; + view.level_set += dl * frame_dt * level_set_speed; } - + window.viewport_full_screen(); window.clear_screen(win::ColorF32::BLACK); window.use_program(&program); window.uniform1f("u_aspect_ratio", window.aspect_ratio()); window.uniform1f("u_time", total_time); - window.uniform4x4f("u_transform", view.transform().as_slice()); + window.uniform1f("u_fov", std::f32::consts::PI * 0.25); + window.uniform1f("u_focal_length", 1.0); + window.uniform1f("u_level_set", view.level_set); + window.uniform3x3f("u_rotation", view.rotation().as_slice()); + window.uniform3f_slice("u_translation", view.pos.as_slice()); window.draw_array(&array); @@ -247,7 +261,7 @@ void main() { if show_debug_info { println!("frame time = {:?}ms", frame_dt * 1000.0); } - + total_time += frame_dt; } @@ -65,7 +65,7 @@ impl R3ToR { pub fn sphere_f32(r: f32) -> Self { Self::Sphere(r.into()) } - + pub fn cube_f32(r: f32) -> Self { Self::Cube(r.into()) } @@ -73,10 +73,14 @@ impl R3ToR { pub fn mix(a: Self, b: Self, t: Constant) -> Self { Self::Mix(Box::new(a), Box::new(b), t) } - + pub fn mix_f32(a: Self, b: Self, t: f32) -> Self { Self::mix(a, b, t.into()) } + + pub fn min(a: Self, b: Self) -> Self { + Self::Min(Box::new(a), Box::new(b)) + } } struct VarCounter { @@ -178,6 +182,15 @@ impl Function for R3ToR { var.next() ); } + Min(a, b) => { + let a_output = a.to_glsl(input, code, var); + let b_output = b.to_glsl(input, code, var); + write_str!( + code, + "float v{} = min(v{a_output}, v{b_output});\n", + var.next() + ); + }, _ => todo!(), } @@ -197,18 +210,11 @@ impl Sdf { Self { distance_function } } - /// appends some glsl code including a function `float sdf(vec3 p) { ... }` + /// appends some glsl code including a function `float sdf(vec3) { ... }` pub fn to_glsl(&self, code: &mut String) { code.push_str("float sdf(vec3 p) {\n"); - // don't start out right next to the origin, since weird stuff might be happening there - let origin_dist: f32 = 3.0; let mut var = VarCounter::new(); - write_str!( - code, - "vec3 v{} = p - vec3(0,0,-{}.);\n", - var.next(), - origin_dist - ); + write_str!(code, "vec3 v{} = p;\n", var.next()); let output = self.distance_function.to_glsl(var.prev(), code, &mut var); write_str!(code, "return v{output};\n"); code.push('}'); @@ -1001,6 +1001,7 @@ pub unsafe fn get_keyboard_state() -> &'static [u8] { pub unsafe fn poll_event() -> Option<SDL_Event> { let mut event = mem::MaybeUninit::zeroed(); + if SDL_PollEvent(event.as_mut_ptr()) != 0 { let event = event.assume_init(); Some(event) @@ -61,10 +61,22 @@ pub enum Key { N7, N8, N9, + NumPad0, + NumPad1, + NumPad2, + NumPad3, + NumPad4, + NumPad5, + NumPad6, + NumPad7, + NumPad8, + NumPad9, Up, Left, Right, Down, + PageUp, + PageDown, Space, Enter, Escape, @@ -129,6 +141,8 @@ impl Key { RIGHT => Key::Right, DOWN => Key::Down, ESCAPE => Key::Escape, + PAGEUP => Key::PageUp, + PAGEDOWN => Key::PageDown, F1 => Key::F1, F2 => Key::F2, F3 => Key::F3, @@ -141,6 +155,16 @@ impl Key { F10 => Key::F10, F11 => Key::F11, F12 => Key::F12, + KP_0 => Key::NumPad0, + KP_1 => Key::NumPad1, + KP_2 => Key::NumPad2, + KP_3 => Key::NumPad3, + KP_4 => Key::NumPad4, + KP_5 => Key::NumPad5, + KP_6 => Key::NumPad6, + KP_7 => Key::NumPad7, + KP_8 => Key::NumPad8, + KP_9 => Key::NumPad9, _ => return None, }) } @@ -191,6 +215,8 @@ impl Key { Key::Right => RIGHT, Key::Down => DOWN, Key::Escape => ESCAPE, + Key::PageUp => PAGEUP, + Key::PageDown => PAGEDOWN, Key::F1 => F1, Key::F2 => F2, Key::F3 => F3, @@ -203,6 +229,16 @@ impl Key { Key::F10 => F10, Key::F11 => F11, Key::F12 => F12, + Key::NumPad0 => KP_0, + Key::NumPad1 => KP_1, + Key::NumPad2 => KP_2, + Key::NumPad3 => KP_3, + Key::NumPad4 => KP_4, + Key::NumPad5 => KP_5, + Key::NumPad6 => KP_6, + Key::NumPad7 => KP_7, + Key::NumPad8 => KP_8, + Key::NumPad9 => KP_9, } } } @@ -962,6 +998,11 @@ impl Window { } } + pub fn uniform2f_slice(&mut self, name: &str, xy: &[f32]) { + assert_eq!(xy.len(), 2); + self.uniform2f(name, xy[0], xy[1]) + } + pub fn uniform3f(&mut self, name: &str, x: f32, y: f32, z: f32) { let loc = self.get_uniform_location(name).unwrap_or(-1); unsafe { @@ -969,6 +1010,11 @@ impl Window { } } + pub fn uniform3f_slice(&mut self, name: &str, xyz: &[f32]) { + assert_eq!(xyz.len(), 3); + self.uniform3f(name, xyz[0], xyz[1], xyz[2]) + } + pub fn uniform4f(&mut self, name: &str, x: f32, y: f32, z: f32, w: f32) { let loc = self.get_uniform_location(name).unwrap_or(-1); unsafe { @@ -976,6 +1022,11 @@ impl Window { } } + pub fn uniform4f_slice(&mut self, name: &str, xyzw: &[f32]) { + assert_eq!(xyzw.len(), 4); + self.uniform4f(name, xyzw[0], xyzw[1], xyzw[2], xyzw[3]) + } + pub fn uniform3x3f(&mut self, name: &str, matrix: &[f32]) { assert_eq!(matrix.len(), 9); let loc = self.get_uniform_location(name).unwrap_or(-1); @@ -1000,12 +1051,15 @@ impl Window { array.draw(); } - #[allow(dead_code)] pub fn is_key_down(&mut self, key: Key) -> bool { let kbd_state = unsafe { sdl::get_keyboard_state() }; kbd_state[key.to_sdl() as usize] != 0 } + pub fn any_key_down(&mut self, keys: &[Key]) -> bool { + keys.iter().any(|&k| self.is_key_down(k)) + } + pub fn swap(&mut self) { unsafe { sdl::gl_swap_window(self.sdlwin) }; } |