summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-12-13 17:06:43 -0500
committerpommicket <pommicket@gmail.com>2022-12-13 17:06:43 -0500
commit3f699f3720ef8d912e509bc3785485b527419dc0 (patch)
treee598c780453ca2b7b4fc39e1f971a18213930708 /src/main.rs
parent2e4f8e26edf0a3c367c4e12ce8e80e8797149df3 (diff)
sphere->cube!
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs144
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(())
}