From f3f7ef65e53707f5fe5f76b3f2f76165c54ee20e Mon Sep 17 00:00:00 2001 From: pommicket Date: Tue, 13 Dec 2022 14:59:19 -0500 Subject: better looking rotation, etc --- .gitignore | 2 ++ src/main.rs | 70 +++++++++++++++++++++++++++++++++++++++++-------------------- src/sdf.rs | 2 +- src/sdl.rs | 5 +++++ src/win.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 114 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index 74c9a4a..d2459d5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ tags *.swp *.out +*.dll +*.lib diff --git a/src/main.rs b/src/main.rs index dc29e2b..b624c33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,9 +4,12 @@ mod sdl; pub mod win; pub mod sdf; -use nalgebra::{Vector3, Matrix3, Rotation3}; +use nalgebra::{Vector3, Matrix3, Rotation3, Matrix4}; +use std::time::Instant; + type Vec3 = Vector3; type Mat3 = Matrix3; +type Mat4 = Matrix4; type Rot3 = Rotation3; struct View { @@ -26,10 +29,23 @@ impl Default for View { } impl View { - /// `camera_rotation() * vec3(0, 0, -1)` is the direction the camera is pointing - fn camera_rotation(&self) -> Mat3 { + /// `rotation() * vec3(0, 0, -1)` is the direction the camera is pointing + fn rotation(&self) -> Mat3 { *Rot3::from_euler_angles(self.pitch, self.yaw, 0.0).matrix() } + + fn translation(&self) -> Mat4 { + Mat4::new_translation(&self.pos) + } + + fn transform(&self) -> Mat4 { + self.translation() * self.rotation().to_homogeneous() + } + + fn inv_transform(&self) -> Mat4 { + // this matrix should always be invertible + self.transform().try_inverse().unwrap() + } } @@ -42,14 +58,13 @@ fn try_main() -> Result<(), String> { let mut fshader_source = String::new(); fshader_source.push_str(" IN vec2 pos; -uniform vec3 u_camera_position; -uniform mat3 u_camera_rotation; +uniform mat4 u_transform; "); my_sdf.to_glsl(&mut fshader_source); fshader_source.push_str(" -#define ITERATIONS 30 -#define AA_X 2 -#define AA_Y 2 +#define ITERATIONS 20 +#define AA_X 1 +#define AA_Y 1 @@ -81,35 +96,32 @@ vec3 normal(vec3 p) k.yyx*sdf(p + k.yyx*h) + k.yxy*sdf(p + k.yxy*h) + k.xxx*sdf(p + k.xxx*h); - vec3 noise_normal = k.xyy*fbm(p + k.xyy*h) + - k.yyx*fbm(p + k.yyx*h) + - k.yxy*fbm(p + k.yxy*h) + - k.xxx*fbm(p + k.xxx*h); - return normalize(sdf_normal + 0.003 * noise_normal); + return normalize(sdf_normal); } void main() { - float focal_length = 0.3; + 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); vec3 final_color = vec3(0); for (int m = 0; m < AA_X; m++) { for (int n = 0; n < AA_Y; n++) { - vec3 p = u_camera_position; vec2 aa_offset = vec2(float(m), float(n)) * aa_delta; - vec3 delta = normalize(u_camera_rotation * vec3(pos + aa_offset, -focal_length)); + vec3 absolute_pos = vec3(pos + aa_offset, -focal_length); + vec3 delta = normalize(absolute_pos); int i; for (i = 0; i < ITERATIONS; i++) { + vec3 p = (u_transform * vec4(absolute_pos, 1.0)).xyz; float dist = sdf(p); min_dist = min(min_dist, dist); if (dist <= 0.01) { float L = 0.3 + max(0., dot(normal(p), normalize(vec3(.8,1,.6)))); final_color += L * vec3(1.0, 0.0, 0.0); - break; } - p += dist * delta; + if (dist > 100.0) break;//little optimization + absolute_pos += dist * delta; } } } @@ -146,28 +158,40 @@ void main() { let mut view = View::default(); + window.set_mouse_relative(true); + + let mut frame_time = Instant::now(); + let mut show_debug_info = false; + 'mainloop: loop { while let Some(event) = window.next_event() { use win::Event::*; + use win::Key::*; match event { - Quit => break 'mainloop, + Quit | KeyDown(Escape) => break 'mainloop, + KeyDown(F1) => show_debug_info = !show_debug_info, + MouseMotion { xrel, yrel, .. } => { + view.yaw += xrel as f32 * 0.01; + view.pitch += yrel as f32 * 0.01; + }, _ => {}, } } window.viewport_full_screen(); - view.yaw += 0.002; - window.clear_screen(win::ColorF32::BLACK); window.use_program(&program); window.uniform1f("u_aspect_ratio", window.aspect_ratio()); - window.uniform3f("u_camera_position", view.pos.x, view.pos.y, view.pos.z); - window.uniform3x3f("u_camera_rotation", view.camera_rotation().as_slice()); + window.uniform4x4f("u_transform", view.inv_transform().as_slice()); window.draw_array(&array); window.swap(); + if show_debug_info { + println!("frame time = {:?}",frame_time.elapsed()); + frame_time = Instant::now(); + } } Ok(()) diff --git a/src/sdf.rs b/src/sdf.rs index 51d85cc..f60eae5 100644 --- a/src/sdf.rs +++ b/src/sdf.rs @@ -69,7 +69,7 @@ impl Sdf { 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 = 2.0; + let origin_dist: f32 = 3.0; write_str!(code, "vec3 v0 = p - vec3(0,0,-{}.);\n", origin_dist); let mut var_idx = 0; self.pre.to_glsl(code, &mut var_idx); diff --git a/src/sdl.rs b/src/sdl.rs index 11873aa..1124a53 100644 --- a/src/sdl.rs +++ b/src/sdl.rs @@ -678,6 +678,7 @@ extern "C" { fn SDL_GetWindowID(window: *mut SDL_Window) -> u32; fn SDL_SetWindowResizable(window: *mut SDL_Window, resizable: SDL_bool); fn SDL_SetWindowSize(window: *mut SDL_Window, w: c_int, h: c_int); + fn SDL_SetRelativeMouseMode(enabled: SDL_bool) -> c_int; fn SDL_GetError() -> *const c_char; fn SDL_SetHint(name: *const c_char, value: *const c_char) -> SDL_bool; fn SDL_GL_SetAttribute(attr: SDL_GLattr, value: c_int); @@ -1049,6 +1050,10 @@ pub unsafe fn show_window(window: *mut SDL_Window) { SDL_ShowWindow(window); } +pub unsafe fn set_relative_mouse_mode(relative: bool) { + SDL_SetRelativeMouseMode(relative.into()); +} + pub unsafe fn gl_swap_window(window: *mut SDL_Window) { SDL_GL_SwapWindow(window); } diff --git a/src/win.rs b/src/win.rs index 65437d8..d54921e 100644 --- a/src/win.rs +++ b/src/win.rs @@ -68,6 +68,18 @@ pub enum Key { Space, Enter, Escape, + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12 } impl Key { @@ -117,6 +129,18 @@ impl Key { RIGHT => Key::Right, DOWN => Key::Down, ESCAPE => Key::Escape, + F1 => Key::F1, + F2 => Key::F2, + F3 => Key::F3, + F4 => Key::F4, + F5 => Key::F5, + F6 => Key::F6, + F7 => Key::F7, + F8 => Key::F8, + F9 => Key::F9, + F10 => Key::F10, + F11 => Key::F11, + F12 => Key::F12, _ => return None, }) } @@ -167,6 +191,18 @@ impl Key { Key::Right => RIGHT, Key::Down => DOWN, Key::Escape => ESCAPE, + Key::F1 => F1, + Key::F2 => F2, + Key::F3 => F3, + Key::F4 => F4, + Key::F5 => F5, + Key::F6 => F6, + Key::F7 => F7, + Key::F8 => F8, + Key::F9 => F9, + Key::F10 => F10, + Key::F11 => F11, + Key::F12 => F12, } } } @@ -176,6 +212,7 @@ pub enum Event { Quit, KeyDown(Key), KeyUp(Key), + MouseMotion { x: i32, y: i32, xrel: i32, yrel: i32 }, } pub fn display_error_message(message: &str) { @@ -625,6 +662,10 @@ impl Window { pub fn show(&mut self) { unsafe { sdl::show_window(self.sdlwin) }; } + + pub fn set_mouse_relative(&mut self, relative: bool) { + unsafe { sdl::set_relative_mouse_mode(relative); } + } pub fn create_program( &mut self, @@ -700,7 +741,16 @@ impl Window { return Some(Event::KeyUp(k)); } } - } + }, + sdl::SDL_MOUSEMOTION => { + let motion = unsafe { sdl.motion }; + return Some(Event::MouseMotion { + x: motion.x, + y: motion.y, + xrel: motion.xrel, + yrel: motion.yrel + }); + }, _ => {} } } @@ -905,6 +955,14 @@ impl Window { } } + pub fn uniform4x4f(&mut self, name: &str, matrix: &[f32]) { + assert_eq!(matrix.len(), 16); + let loc = self.get_uniform_location(name).unwrap_or(-1); + unsafe { + gl::UniformMatrix4fv(loc, 1, 0, matrix.as_ptr()); + } + } + pub fn uniform_texture(&mut self, name: &str, slot: u32) { self.uniform1i(name, slot as i32); -- cgit v1.2.3