summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--src/main.rs70
-rw-r--r--src/sdf.rs2
-rw-r--r--src/sdl.rs5
-rw-r--r--src/win.rs60
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<f32>;
type Mat3 = Matrix3<f32>;
+type Mat4 = Matrix4<f32>;
type Rot3 = Rotation3<f32>;
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);