diff options
author | pommicket <pommicket@gmail.com> | 2022-12-13 17:06:43 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2022-12-13 17:06:43 -0500 |
commit | 3f699f3720ef8d912e509bc3785485b527419dc0 (patch) | |
tree | e598c780453ca2b7b4fc39e1f971a18213930708 /src/main.rs | |
parent | 2e4f8e26edf0a3c367c4e12ce8e80e8797149df3 (diff) |
sphere->cube!
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 144 |
1 files changed, 96 insertions, 48 deletions
diff --git a/src/main.rs b/src/main.rs index 2ef9ff4..6fef680 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,21 +1,23 @@ /* @TODO: +- fix rotation - fullscreen key - options for: - - max framerate - - AA quality - - # iterations, distance cutoff + - max framerate + - mouse sensitivity + - AA quality + - # iterations, distance cutoff */ extern crate nalgebra; +pub mod sdf; mod sdl; pub mod win; -pub mod sdf; -use nalgebra::{Vector3, Matrix3, Rotation3, Matrix4}; +use nalgebra::{Matrix3, Matrix4, Rotation3, Vector3}; use std::time::Instant; - + type Vec3 = Vector3<f32>; type Mat3 = Matrix3<f32>; type Mat4 = Matrix4<f32>; @@ -24,7 +26,7 @@ type Rot3 = Rotation3<f32>; struct View { pos: Vec3, yaw: f32, - pitch: f32 + pitch: f32, } impl Default for View { @@ -32,7 +34,7 @@ impl Default for View { Self { pos: Vec3::zeros(), yaw: 0.0, - pitch: 0.0 + pitch: 0.0, } } } @@ -42,35 +44,37 @@ impl View { 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() - } -} +} fn try_main() -> Result<(), String> { - let my_sdf = sdf::Sdf::sphere(); + use sdf::{R3ToR, Constant}; + let funciton = R3ToR::mix(R3ToR::sphere_f32(1.0), R3ToR::cube_f32(1.0), + Constant::Time(0.1, 0.0)); + let my_sdf = sdf::Sdf::from_function(funciton); let mut window = win::Window::new("AutoSDF", 1280, 720, true) .map_err(|e| format!("Error creating window: {e}"))?; - + let mut fshader_source = String::new(); - fshader_source.push_str(" + fshader_source.push_str( + " IN vec2 pos; uniform mat4 u_transform; -"); +uniform float u_time; +", + ); my_sdf.to_glsl(&mut fshader_source); - fshader_source.push_str(" + fshader_source.push_str( + " #define ITERATIONS 20 #define AA_X 1 #define AA_Y 1 @@ -117,11 +121,15 @@ 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 absolute_pos = vec3(pos + aa_offset, -focal_length); - vec3 delta = normalize(absolute_pos); + vec3 p = (u_transform * vec4(pos + aa_offset, -focal_length, 1.0)).xyz; + vec3 delta = normalize(p); + if (sdf(p) < 0.0) { + // looking inside object + o_color = vec4(1.0, 0.0, 1.0, 1.0); + return; + } 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) { @@ -130,18 +138,20 @@ void main() { break; } if (dist > 100.0) break;//little optimization - absolute_pos += dist * delta; + p += dist * delta; } } } final_color *= 1.0 / (AA_X * AA_Y); o_color = vec4(final_color, 1.0); -}"); - +}", + ); + println!("{fshader_source}"); - - let program = window.create_program( - "attribute vec2 v_pos; + + let program = window + .create_program( + "attribute vec2 v_pos; OUT vec2 pos; uniform float u_aspect_ratio; @@ -149,9 +159,10 @@ void main() { pos = v_pos * vec2(u_aspect_ratio, 1.0); gl_Position = vec4(v_pos, 0.0, 1.0); }", - &fshader_source - ).map_err(|e| format!("Error compiling shader:\n{e}"))?; - + &fshader_source, + ) + .map_err(|e| format!("Error compiling shader:\n{e}"))?; + let mut buffer = window.create_buffer(); let data: &[[f32; 2]] = &[ [-1.0, -1.0], @@ -164,15 +175,19 @@ void main() { window.set_buffer_data(&mut buffer, data); let mut array = window.create_vertex_array(buffer, &program); window.array_attrib2f(&mut array, "v_pos", 0); - + let mut view = View::default(); - + window.set_mouse_relative(true); - + let mut frame_time = Instant::now(); let mut show_debug_info = false; - + let mut total_time = 0.0; + '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::*; @@ -180,29 +195,62 @@ void main() { 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; - }, - _ => {}, + view.yaw -= xrel as f32 * frame_dt; + view.pitch -= yrel as f32 * frame_dt; + } + _ => {} } } - window.viewport_full_screen(); + { // 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) { + dz -= 1.0; + } + if window.is_key_down(S) || window.is_key_down(Down) { + dz += 1.0; + } + if window.is_key_down(A) || window.is_key_down(Left) { + dx -= 1.0; + } + if window.is_key_down(D) || window.is_key_down(Right) { + dx += 1.0; + } + if window.is_key_down(Q) { + dy += 1.0; + } + if window.is_key_down(E) { + dy -= 1.0; + } + let motion = Vec3::new(dx, dy, dz); + if let Some(motion) = motion.try_normalize(0.001) { + let motion = motion * frame_dt; + let motion = view.rotation() * motion; + view.pos += motion; + } + } + window.viewport_full_screen(); + window.clear_screen(win::ColorF32::BLACK); window.use_program(&program); window.uniform1f("u_aspect_ratio", window.aspect_ratio()); - window.uniform4x4f("u_transform", view.inv_transform().as_slice()); - + window.uniform1f("u_time", total_time); + window.uniform4x4f("u_transform", view.transform().as_slice()); + window.draw_array(&array); - + window.swap(); if show_debug_info { - println!("frame time = {:?}",frame_time.elapsed()); - frame_time = Instant::now(); + println!("frame time = {:?}ms", frame_dt * 1000.0); } + + total_time += frame_dt; } - + Ok(()) } |