summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/fshader_test.glsl7
-rw-r--r--src/main.rs64
-rw-r--r--src/sdf.rs2
-rw-r--r--src/sdl.rs10
-rw-r--r--src/win.rs33
5 files changed, 99 insertions, 17 deletions
diff --git a/src/fshader_test.glsl b/src/fshader_test.glsl
index 4cd9ebd..709dedb 100644
--- a/src/fshader_test.glsl
+++ b/src/fshader_test.glsl
@@ -1,10 +1,13 @@
// used to determine the default level set
-%COMMON%
-%SDF%
IN vec2 pos;
+uniform float u_time;
+
+%COMMON%
+%SDF%
+
vec4 rand(vec2 coord) {
// this seems to give pretty good quality noise for |coord| < 2
vec4 a = sin((coord.xyyx + vec4(3.0)) * (coord.xyxy + vec4(4.0)) * 100.0 + 0.5832) * 1618.0;
diff --git a/src/main.rs b/src/main.rs
index 5be2399..5837f7e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,5 @@
/*
@TODO:
-- bring time back, w pause/rewind/adjust time speed (start out paused?)
-- fullscreen key
- options for:
- max framerate
- mouse sensitivity
@@ -9,11 +7,13 @@
- AA quality
- # iterations, distance cutoff
---release---
+- [ and ] to move through time
- switch framebuffer texture to grayscale
- show that θ = σ(z) / sqrt(x² + y²)
(x,y,z) → (x cosθ + y sinθ, y cosθ - x sinθ, z)
is lipschitz continuous, & add it
- feedback for copy/paste (flash screen or something)
+- feedback for pause/unpause/rewind
- Params instead of depth for GenRandom
- allow multiple endpoints (cube & sphere & ...)
- save seeds to a file then let user go back&forth through past sdfs
@@ -41,6 +41,7 @@ a263736466a167436f6d706f736583a166526f7461746583a163463332fa3f76cab2a163463332fa
a263736466a167436f6d706f736583a165537153696ea163463332fa3e784c98a1634d697883a166537068657265a163463332fa3ea1ce4ca1634d696e82a166537068657265a163463332fa3f55f124a167436f6d706f736583675369676d6f6964a166537068657265a163463332fa3ef84fb0684964656e74697479a163463332fa3d2f72c0684964656e746974796e636f6c6f725f66756e6374696f6ea16f496e66696e6974654d6972726f7273a163463332fa3e9d85d0
a263736466a1634d696e82a1634d696e82a166537068657265a163463332fa3f2365aca1634d697883a167436f6d706f736583a16641726374616ea163463332fa3eb04a5ca167436f6d706f736583675369676d6f6964a169536d6f6f74684d696e82a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3eeb25b8684964656e74697479a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3f10d6a2684964656e74697479684964656e74697479684964656e74697479a165546f727573a266726164697573a163463332fa3d9099f069746869636b6e657373a163463332fa3e00b102a163463332fa3f06b5a2a1634d696e82a165546f727573a266726164697573a163463332fa40121b0169746869636b6e657373a163463332fa3e32f4faa1634d697883a16443756265a163463332fa3f7f9dc8a1634d697883a165546f727573a266726164697573a163463332fa3f9286e369746869636b6e657373a163463332fa3d8a3f27a167436f6d706f736583a167436f6d706f736582a167436f6d706f736582684964656e74697479684964656e74697479a16f496e66696e6974654d6972726f7273a163463332fa3ea62688a168426f784672616d65a26473697a65a163463332fa3fc0fb4969746869636b6e657373a163463332fa3e472462684964656e74697479a163463332fa3f69a73ea163463332fa3f5b9c9e6e636f6c6f725f66756e6374696f6ea16f496e66696e6974654d6972726f7273a163463332fa3ef4ea8c
a263736466a169536d6f6f74684d696e82a1634d696e82a167436f6d706f736583a167436f6d706f736582a16641726374616ea163463332fa3e6d7230a1695472616e736c61746583a163463332fa3e7262f8a163463332fa3eece0eca163463332fa3f49c42ca168426f784672616d65a26473697a65a163463332fa3ff3ee1169746869636b6e657373a163463332fa3df6dfed684964656e74697479a167436f6d706f736583a16f496e66696e6974654d6972726f7273a163463332fa3f2a2de8a165546f727573a266726164697573a163463332fa3fc93f1e69746869636b6e657373a163463332fa3e0fa700684964656e74697479a169536d6f6f74684d696e82a169536d6f6f74684d696e82a1634d696e82a169536d6f6f74684d696e82a167436f6d706f736583675369676d6f6964a1634d696e82a166537068657265a163463332fa3e0586b0a166537068657265a163463332fa3f4d6214684964656e74697479a167436f6d706f736583a167436f6d706f736582684964656e74697479684964656e74697479a1634d697883a166537068657265a163463332fa3f5c46e6a166537068657265a163463332fa3f3f4896a163463332fa3f10ba30684964656e74697479a166537068657265a163463332fa3ef3b604a167436f6d706f736583a165537153696ea163463332fa3ef1bfb8a1634d697883a1634d697883a168426f784672616d65a26473697a65a163463332fa3ee4801069746869636b6e657373a163463332fa3dc84d37a168426f784672616d65a26473697a65a163463332fa4019d5d269746869636b6e657373a163463332fa3d5d0307a163463332fa3eb7554ca167436f6d706f736583a165537153696ea163463332fa3f31c33ca167436f6d706f736583684964656e74697479a166537068657265a163463332fa3e7db3c0684964656e74697479684964656e74697479a163463332fa3f3176c0684964656e74697479a165546f727573a266726164697573a163463332fa3f253f0c69746869636b6e657373a163463332fa3c96c48d6e636f6c6f725f66756e6374696f6ea16f496e66696e6974654d6972726f7273a163463332fa3ea219f4
+a263736466a169536d6f6f74684d696e82a1634d697883a167436f6d706f736583a16641726374616ea16454696d6582fa3da97b73fa3eddf3cca167436f6d706f736583a16f496e66696e6974654d6972726f7273a16454696d6582fabb6c5400fa3c230980a167436f6d706f736583675369676d6f6964a167436f6d706f736583a167436f6d706f736582684964656e74697479684964656e74697479a16443756265a163463332fa3edf6864684964656e74697479684964656e74697479684964656e74697479684964656e74697479a166537068657265a163463332fa3ee32af4a16454696d6582fa3db4b603fa3ea79394a1634d697883a167436f6d706f736583a16353696ea163463332fa3de4e160a167436f6d706f736583a16f496e66696e6974654d6972726f7273a163463332fa3f7493fea168426f784672616d65a26473697a65a16454696d6582fa3e92c08dfa3ee156b869746869636b6e657373a16454696d6582fa3c74f202fa3df09e1d684964656e74697479684964656e74697479a1634d697883a16443756265a163463332fa3f5f8194a1634d696e82a1634d697883a167436f6d706f736583675369676d6f6964a168426f784672616d65a26473697a65a163463332fa3fe3873769746869636b6e657373a163463332fa3e3524e7684964656e74697479a1634d696e82a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3f50ffb8684964656e74697479a167436f6d706f736583684964656e74697479a166537068657265a163463332fa3c693200684964656e74697479a163463332fa3e5d3250a168426f784672616d65a26473697a65a163463332fa3fb01f6669746869636b6e657373a16454696d6582fabc5d9d48fa3d1cc993a163463332fa3f394d40a16454696d6582fabda7629afa3eefd35c6e636f6c6f725f66756e6374696f6ea16f496e66696e6974654d6972726f7273a163463332fa3d8dc730
*/
extern crate nalgebra;
@@ -62,6 +63,8 @@ type Rot3 = Rotation3<f32>;
struct View {
pos: Vec3,
rotation: Mat3,
+ time: f64,
+ time_speed: f64,
level_set: f32,
}
@@ -73,6 +76,8 @@ impl Default for View {
Self {
pos,
rotation,
+ time: 0.0,
+ time_speed: 0.0,
level_set: 0.0,
}
}
@@ -84,6 +89,23 @@ impl View {
self.rotation
}
+ fn pause(&mut self) {
+ self.time_speed = 0.0;
+ }
+
+ fn paused(&self) -> bool {
+ self.time_speed == 0.0
+ }
+
+ fn unpause(&mut self, rewind: bool) {
+ self.time_speed = if rewind { -1.0 } else { 1.0 };
+ }
+
+ fn pass_time(&mut self, dt: f64) {
+ self.time += self.time_speed * dt;
+ }
+
+
fn yaw_by(&mut self, yaw: f32) {
self.rotation *= Rot3::from_euler_angles(0.0, yaw, 0.0);
}
@@ -182,7 +204,7 @@ struct State {
view: View,
initial_view: View,
show_debug_info: bool,
- total_time: f64,
+ fullscreen: bool,
frame_time: Instant,
programs: Programs,
config: sdf::SceneConfig,
@@ -195,7 +217,7 @@ struct State {
impl State {
fn new() -> Result<Self, String> {
- let mut window = win::Window::new("AutoSDF", 1280, 720, true)
+ let mut window = win::Window::new("AutoSDF", 1280, 720, &Default::default())
.map_err(|e| format!("Error creating window: {e}"))?;
let mut programs = Programs::new(&mut window);
let config = sdf::SceneConfig {
@@ -248,7 +270,7 @@ impl State {
config,
frame_time: Instant::now(),
show_debug_info: false,
- total_time: 0.0,
+ fullscreen: false,
scene: sdf::Scene::default(),
framebuffer_texture,
framebuffer,
@@ -308,7 +330,6 @@ impl State {
fn frame(&mut self) -> bool {
let frame_dt = self.frame_time.elapsed().as_secs_f32();
self.frame_time = Instant::now();
- self.total_time += f64::from(frame_dt);
while let Some(event) = self.window.next_event() {
use win::Event::*;
@@ -332,6 +353,12 @@ impl State {
}
}
KeyDown {
+ key: F, ..
+ } => {
+ self.fullscreen = !self.fullscreen;
+ self.window.set_fullscreen(self.fullscreen);
+ }
+ KeyDown {
key: V, modifier, ..
} if modifier.ctrl() => {
// paste scene
@@ -351,6 +378,15 @@ impl State {
}
}
KeyDown { key: N0, .. } => self.view = self.initial_view.clone(),
+ KeyDown { key: Space, modifier } => {
+ if !self.view.paused() {
+ self.view.pause();
+ } else if modifier.shift() {
+ self.view.unpause(true);
+ } else {
+ self.view.unpause(false);
+ }
+ }
MouseMotion { xrel, yrel, .. } => {
let mouse_sensitivity = 0.05;
self.view
@@ -361,7 +397,9 @@ impl State {
_ => {}
}
}
-
+
+ self.view.pass_time(frame_dt.into());
+
{
// movement
let mut dx = 0.0;
@@ -370,6 +408,8 @@ impl State {
let mut dl = 0.0;
let window = &self.window;
use win::Key::*;
+
+
if window.any_key_down(&[W, Up]) {
dz -= 1.0;
}
@@ -382,16 +422,16 @@ impl State {
if window.any_key_down(&[D, Right]) {
dx += 1.0;
}
- if window.is_key_down(Q) {
+ if window.any_key_down(&[PageUp, NumPad9, Q]) {
dy += 1.0;
}
- if window.is_key_down(E) {
+ if window.any_key_down(&[PageDown, NumPad3, E]) {
dy -= 1.0;
}
- if window.any_key_down(&[PageUp, NumPad9, Equals]) {
+ if window.any_key_down(&[Equals]) {
dl += 1.0;
}
- if window.any_key_down(&[PageDown, NumPad3, Minus]) {
+ if window.any_key_down(&[Minus]) {
dl -= 1.0;
}
let mut speed_multiplier = if window.is_shift_down() { 10.0 } else { 1.0 };
@@ -416,7 +456,7 @@ impl State {
window.clear_screen(win::ColorF32::BLACK);
window.use_program(&self.programs.main);
window.uniform1f("u_aspect_ratio", window.aspect_ratio());
- window.uniform1f("u_time", self.total_time as f32);
+ window.uniform1f("u_time", view.time as f32);
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);
diff --git a/src/sdf.rs b/src/sdf.rs
index 6f2dfa6..025373e 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -19,7 +19,7 @@ macro_rules! write_str {
pub enum Constant {
#[prob(0.5)]
F32(f32),
- #[prob(0)]
+ #[prob(0.5)]
Time(
#[scale(0.2)]
#[bias(-0.1)]
diff --git a/src/sdl.rs b/src/sdl.rs
index 74f2e77..056e8d8 100644
--- a/src/sdl.rs
+++ b/src/sdl.rs
@@ -714,6 +714,7 @@ extern "C" {
fn SDL_CloseAudioDevice(dev: SDL_AudioDeviceID);
fn SDL_GetClipboardText() -> *mut c_char;
fn SDL_SetClipboardText(text: *const c_char) -> c_int;
+ fn SDL_SetWindowFullscreen(window: *mut SDL_Window, flags: u32) -> c_int;
fn SDL_free(mem: *mut c_void);
}
@@ -1167,3 +1168,12 @@ pub unsafe fn set_clipboard_text(s: &str) -> Result<(), String> {
Err(get_err())
}
}
+
+pub unsafe fn set_window_fullscreen(win: *mut SDL_Window, flags: u32) -> Result<(), String> {
+ let result = SDL_SetWindowFullscreen(win, flags);
+ if result == 0 {
+ Ok(())
+ } else {
+ Err(get_err())
+ }
+}
diff --git a/src/win.rs b/src/win.rs
index c4dfc89..3f64892 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -985,8 +985,22 @@ impl Drop for Framebuffer {
}
}
+pub struct WindowProperties {
+ shown: bool,
+ resizable: bool,
+}
+
+impl Default for WindowProperties {
+ fn default() -> Self {
+ Self {
+ shown: true,
+ resizable: true,
+ }
+ }
+}
+
impl Window {
- pub fn new(title: &str, width: i32, height: i32, shown: bool) -> Result<Self, String> {
+ pub fn new(title: &str, width: i32, height: i32, properties: &WindowProperties) -> Result<Self, String> {
{
static WINDOW_CREATED: Mutex<bool> = Mutex::new(false);
let guard = WINDOW_CREATED.lock();
@@ -1009,9 +1023,12 @@ impl Window {
sdl::gl_set_context_version(3, 0);
}
let mut flags = sdl::SDL_WINDOW_OPENGL;
- if !shown {
+ if !properties.shown {
flags |= sdl::SDL_WINDOW_HIDDEN;
}
+ if properties.resizable {
+ flags |= sdl::SDL_WINDOW_RESIZABLE;
+ }
let sdlwin = unsafe { sdl::create_window(title, width, height, flags) }?;
let ctx = unsafe { sdl::gl_create_context(sdlwin) }?;
gl::load_with(|name| unsafe { sdl::gl_get_proc_address(name) });
@@ -1048,6 +1065,18 @@ impl Window {
sdl::gl_set_swap_interval(vsync.into());
}
}
+
+ pub fn set_fullscreen(&mut self, fullscreen: bool) {
+ unsafe {
+ // i dont care if going fullscreen fails
+ let _ = sdl::set_window_fullscreen(self.sdlwin,
+ if fullscreen {
+ sdl::SDL_WINDOW_FULLSCREEN_DESKTOP
+ } else {
+ 0
+ });
+ }
+ }
pub fn show(&mut self) {
unsafe { sdl::show_window(self.sdlwin) };