summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock323
-rw-r--r--Cargo.toml2
-rw-r--r--README.md3
-rw-r--r--settings.txt1
-rw-r--r--src/fshader_main.glsl2
-rw-r--r--src/main.rs110
-rw-r--r--src/sdf.rs1
-rw-r--r--src/sdl.rs10
-rw-r--r--src/vshader_post.glsl2
-rw-r--r--src/win.rs43
11 files changed, 445 insertions, 53 deletions
diff --git a/.gitignore b/.gitignore
index 51fae58..22756b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,6 @@
target
tags
+screenshots
*.swp
*.out
*.dll
diff --git a/Cargo.lock b/Cargo.lock
index 094a578..41f5ac5 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3,6 +3,21 @@
version = 3
[[package]]
+name = "adler"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
+
+[[package]]
+name = "android_system_properties"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -21,10 +36,12 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
name = "autosdf"
version = "0.1.0"
dependencies = [
+ "chrono",
"gen_random",
"gen_random_proc_macro",
"gl",
"nalgebra",
+ "png",
"rand",
"serde",
"serde_cbor",
@@ -33,18 +50,130 @@ dependencies = [
]
[[package]]
+name = "bitflags"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
+
+[[package]]
+name = "bumpalo"
+version = "3.12.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535"
+
+[[package]]
name = "bytemuck"
version = "1.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f"
[[package]]
+name = "cc"
+version = "1.0.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a20104e2335ce8a659d6dd92a51a767a0c062599c73b343fd152cb401e828c3d"
+
+[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "chrono"
+version = "0.4.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f"
+dependencies = [
+ "iana-time-zone",
+ "js-sys",
+ "num-integer",
+ "num-traits",
+ "time",
+ "wasm-bindgen",
+ "winapi",
+]
+
+[[package]]
+name = "codespan-reporting"
+version = "0.11.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e"
+dependencies = [
+ "termcolor",
+ "unicode-width",
+]
+
+[[package]]
+name = "core-foundation-sys"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
+
+[[package]]
+name = "crc32fast"
+version = "1.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "cxx"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b61a7545f753a88bcbe0a70de1fcc0221e10bfc752f576754fa91e663db1622e"
+dependencies = [
+ "cc",
+ "cxxbridge-flags",
+ "cxxbridge-macro",
+ "link-cplusplus",
+]
+
+[[package]]
+name = "cxx-build"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f464457d494b5ed6905c63b0c4704842aba319084a0a3561cdc1359536b53200"
+dependencies = [
+ "cc",
+ "codespan-reporting",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "scratch",
+ "syn",
+]
+
+[[package]]
+name = "cxxbridge-flags"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "43c7119ce3a3701ed81aca8410b9acf6fc399d2629d057b87e2efa4e63a3aaea"
+
+[[package]]
+name = "cxxbridge-macro"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "65e07508b90551e610910fa648a1878991d367064997a596135b86df30daf07e"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "flate2"
+version = "1.0.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
name = "gen_random"
version = "0.1.0"
dependencies = [
@@ -68,7 +197,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
- "wasi",
+ "wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
@@ -98,6 +227,39 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
[[package]]
+name = "iana-time-zone"
+version = "0.1.53"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765"
+dependencies = [
+ "android_system_properties",
+ "core-foundation-sys",
+ "iana-time-zone-haiku",
+ "js-sys",
+ "wasm-bindgen",
+ "winapi",
+]
+
+[[package]]
+name = "iana-time-zone-haiku"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca"
+dependencies = [
+ "cxx",
+ "cxx-build",
+]
+
+[[package]]
+name = "js-sys"
+version = "0.3.60"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[package]]
name = "khronos_api"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -110,6 +272,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
[[package]]
+name = "link-cplusplus"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5"
+dependencies = [
+ "cc",
+]
+
+[[package]]
name = "log"
version = "0.4.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -128,6 +299,15 @@ dependencies = [
]
[[package]]
+name = "miniz_oxide"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
+dependencies = [
+ "adler",
+]
+
+[[package]]
name = "nalgebra"
version = "0.31.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -194,12 +374,30 @@ dependencies = [
]
[[package]]
+name = "once_cell"
+version = "1.17.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66"
+
+[[package]]
name = "paste"
version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1de2e551fb905ac83f73f7aedf2f0cb4a0da7e35efa24a202a936269f1f18e1"
[[package]]
+name = "png"
+version = "0.17.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5d708eaf860a19b19ce538740d2b4bdeeb8337fa53f7738455e706623ad5c638"
+dependencies = [
+ "bitflags",
+ "crc32fast",
+ "flate2",
+ "miniz_oxide",
+]
+
+[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -269,6 +467,12 @@ dependencies = [
]
[[package]]
+name = "scratch"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2"
+
+[[package]]
name = "serde"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -320,6 +524,26 @@ dependencies = [
]
[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
+name = "time"
+version = "0.1.45"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
+dependencies = [
+ "libc",
+ "wasi 0.10.0+wasi-snapshot-preview1",
+ "winapi",
+]
+
+[[package]]
name = "toml"
version = "0.5.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -341,12 +565,78 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3"
[[package]]
+name = "unicode-width"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
+
+[[package]]
+name = "wasi"
+version = "0.10.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
+
+[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
+name = "wasm-bindgen"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
+dependencies = [
+ "bumpalo",
+ "log",
+ "once_cell",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.83"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
+
+[[package]]
name = "wide"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -357,6 +647,37 @@ dependencies = [
]
[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
name = "winres"
version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index dff7d65..398f700 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -14,6 +14,8 @@ serde = "1.0.150"
serde_derive = "1.0.150"
gl = "0.14.0"
nalgebra = "0.31.4"
+png = "0.17.7"
+chrono = "0.4.23"
[target.'cfg(windows)'.build-dependencies]
winres = "0.1.12"
diff --git a/README.md b/README.md
index e288402..90bad06 100644
--- a/README.md
+++ b/README.md
@@ -12,7 +12,7 @@ you can also reduce `max-iterations` and increase `distance-threshold` if it's s
- move mouse to look around
- W,A,S,D/arrow keys to move forward/backwards/left/right + Q,E/PageUp,PageDown to move up/down
- R to create a new SDF - use this a lot! most SDFs are boring!
-- Space to "unpause time" (start animating). On some SDFs this might not do much.
+- Space to "unpause time" (start animating).
Press space again to pause time, and shift+space to rewind time.
- [ and ] to go forwards and backwards in time
- 0 to reset location + time
@@ -20,6 +20,7 @@ you can also reduce `max-iterations` and increase `distance-threshold` if it's s
- Ctrl+C to copy SDF to clipboard, Ctrl+V to paste SDF from clipboard. On Linux
if you close the application the clipboard contents will be lost (thanks a lot X11).
- F to go fullscreen
+- F10 to take a screenshot (will be saved to a folder called `screenshots`)
- Escape to quit
- You can use Shift to move faster and Ctrl to move slower.
diff --git a/settings.txt b/settings.txt
index 16f7445..6456874 100644
--- a/settings.txt
+++ b/settings.txt
@@ -2,6 +2,7 @@ mouse-sensitivity 50
# you can set this to 0.5 to render the SDF at half resolution for example
# (e.g. the SDF will be rendered at 960x540 on a 1080p monitor)
# making this lower will increase performance significantly, but will look more pixelated
+# you can also make this higher to take super high-res screenshots (but it will run slower)
scale 1
# complexity of SDF
# making this bigger will make more complex scenes, but will require more gpu computation
diff --git a/src/fshader_main.glsl b/src/fshader_main.glsl
index 0f13a01..2a6864a 100644
--- a/src/fshader_main.glsl
+++ b/src/fshader_main.glsl
@@ -20,6 +20,7 @@ uniform int u_flash_icon;
#define ICON_PLAY 2
#define ICON_PAUSE 3
#define ICON_REWIND 4
+#define ICON_SCREENSHOT 5
%COMMON%
%SDF%
@@ -131,6 +132,7 @@ void main() {
switch (u_flash_icon) {
case 0: break;
case ICON_COPY:
+ case ICON_SCREENSHOT:
icon = abs(pos.x) > u_aspect_ratio - 0.1 || abs(pos.y) > 0.9;
break;
case ICON_PLAY:
diff --git a/src/main.rs b/src/main.rs
index 2651c9b..782ef32 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,11 +1,9 @@
/*
@TODO:
-- screenshot
- pause screen
-- start time at -3 seconds
- autoplay setting
- strip ' ' and '\n' from *inside* string
-- flash error on bad string
+- flash error on bad string (see @TODO(error handling))
- RnToRn functions (& add back in RToR)
- also add PerComponent(Box<RToR>,Box<RToR>,Box<RToR>) in R3ToR3
- ProjectX, ProjectY, ProjectZ in R3ToR?
@@ -20,18 +18,21 @@
*/
#![windows_subsystem = "windows"]
+extern crate chrono;
extern crate nalgebra;
+extern crate png;
pub mod sdf;
mod sdl;
pub mod win;
+use chrono::prelude::*;
use nalgebra::{Matrix3, Matrix4, Rotation3, Vector3};
use sdf::ImportExport;
use std::{
collections::HashMap,
fs::File,
- io::{prelude::*, BufReader},
+ io::{prelude::*, BufReader, BufWriter},
time::Instant,
};
use win::{ColorF32, ColorGrayscaleF32, ColorU8};
@@ -49,6 +50,7 @@ enum Icon {
Play = 2,
Pause = 3,
Rewind = 4,
+ Screenshot = 5,
}
#[derive(Clone)]
@@ -160,7 +162,7 @@ impl Programs {
.link_program(&mut self.test, vsource_test, &fsource_test)
.map_err(|e| format!("Error compiling shader:\n{e}"))?;
window
- .link_program(&mut self.post, vsource_post, &fsource_post)
+ .link_program(&mut self.post, vsource_post, fsource_post)
.map_err(|e| format!("Error compiling shader:\n{e}"))?;
Ok(())
}
@@ -275,15 +277,14 @@ impl State {
win::FramebufferAttachment::Color0,
&test_framebuffer_texture,
);
-
-
+
let main_texconfig = win::TextureParams {
mag_filter: win::TextureFilter::Nearest,
..Default::default()
};
let main_framebuffer_texture = window.create_texture(&main_texconfig);
let main_framebuffer = window.create_framebuffer();
-
+
let mut main_buffer = window.create_buffer();
let mut test_buffer = window.create_buffer();
let mut post_buffer = window.create_buffer();
@@ -368,8 +369,8 @@ impl State {
self.window.bind_framebuffer(None);
let mut sdf_values: Vec<f32> = self
- .window
- .get_texture_data_vec::<ColorGrayscaleF32>(&self.test_framebuffer_texture)
+ .test_framebuffer_texture
+ .get_data_vec::<ColorGrayscaleF32>()
.iter()
.map(|c| c.value)
.collect();
@@ -394,20 +395,64 @@ impl State {
fn flash(&mut self, icon: Icon) {
self.flash = match icon {
Icon::None => ColorF32::BLACK,
- Icon::Copy => ColorF32::GREEN,
+ Icon::Copy | Icon::Screenshot => ColorF32::GREEN,
_ => ColorF32::rgb(1.0, 0.5, 0.0),
};
self.flash_icon = icon;
}
-
+
fn render_resolution(&self) -> (i32, i32) {
let scale = self.settings.get_f32("scale").unwrap_or(1.0);
- if scale <= 0.0 || scale > 1.0 {
+ if scale <= 0.0 || scale > 100.0 {
win::display_error_message(&format!("bad scale: {scale}"));
std::process::exit(1);
}
let (w, h) = self.window.size();
- ((w as f32 * scale) as i32, (h as f32 * scale) as i32)
+ let w = (w as f32 * scale) as i32;
+ let h = (h as f32 * scale) as i32;
+ assert!(w >= 0);
+ assert!(h >= 0);
+ (w, h)
+ }
+
+ /// save a screenshot
+ fn take_screenshot(&mut self) -> Result<(), String> {
+ let texture = &self.main_framebuffer_texture;
+ let size = (texture.width(), texture.height());
+ let texture_data = texture.get_data_vec();
+ if size.0 == 0 || size.1 == 0 {
+ // there isnt anything to save . why did you set the scale so small...
+ return Ok(());
+ }
+ let time = Utc::now();
+ let filename = time
+ .format("screenshots/autosdf-%Y-%m-%d-%H-%M-%S.png")
+ .to_string();
+ if std::fs::create_dir("screenshots").is_err() {
+ // (do nothing.)
+ // we get an error if it already exists.
+ // even if this is another error, that will just make File::create fail.
+ }
+ let file =
+ File::create(&filename).map_err(|e| format!("error creating {filename}: {e}"))?;
+ let mut writer = BufWriter::new(file);
+ let mut encoder = png::Encoder::new(&mut writer, size.0 as u32, size.1 as u32);
+ encoder.set_color(png::ColorType::Rgba);
+ encoder.set_depth(png::BitDepth::Eight);
+ encoder
+ .add_text_chunk(
+ "\n\n\n\nAutoSDF scene".to_string(),
+ "\n".to_string() + &self.scene.export_string() + "\n\n\n\n",
+ )
+ .map_err(|e| format!("error adding PNG tEXt chunk for {filename}: {e}"))?;
+ let mut png_writer = encoder
+ .write_header()
+ .map_err(|e| format!("error writing PNG header for {filename}: {e}"))?;
+ png_writer
+ .write_image_data(ColorU8::slice_to_bytes(&texture_data))
+ .map_err(|e| format!("error writing {filename}: {e}"))?;
+ self.flash(Icon::Screenshot);
+ Ok(())
}
// returns false if we should quit
@@ -441,6 +486,7 @@ impl State {
match self.window.set_clipboard_text(&self.scene.export_string()) {
Ok(()) => {}
Err(e) => {
+ // @TODO(error handling)
eprintln!("couldn't copy text to clipboard: {e}")
}
}
@@ -460,16 +506,27 @@ impl State {
self.load_scene(new_scene);
}
None => {
+ // @TODO(error handling)
eprintln!("bad string")
}
},
Err(e) => {
- // very unlikely to happen
+ // @TODO(error handling)
eprintln!("couldn't get clipboard text: {e}")
}
}
}
KeyDown { key: N0, .. } => self.view = self.initial_view.clone(),
+ KeyDown { key: F10, .. } => {
+ // screenshot
+ match self.take_screenshot() {
+ Ok(()) => {}
+ Err(e) => {
+ // @TODO(error handling)
+ eprintln!("screenshot fail: {e}");
+ }
+ }
+ }
KeyDown {
key: Space,
modifier,
@@ -564,20 +621,24 @@ impl State {
let render_resolution = self.render_resolution();
if render_resolution != self.main_framebuffer_size {
- let result = self.main_framebuffer_texture.set_data::<ColorU8>(None, render_resolution.0 as usize, render_resolution.1 as usize);
-
+ let result = self.main_framebuffer_texture.set_data::<ColorU8>(
+ None,
+ render_resolution.0 as usize,
+ render_resolution.1 as usize,
+ );
+
match result {
- Ok(()) => {},
+ Ok(()) => {}
Err(e) => eprintln!("warning:{e}"),
}
-
+
self.main_framebuffer.set_texture(
win::FramebufferAttachment::Color0,
&self.main_framebuffer_texture,
);
self.main_framebuffer_size = render_resolution;
}
-
+
let window = &mut self.window;
let view = &self.view;
window.viewport(0, 0, render_resolution.0, render_resolution.1);
@@ -585,7 +646,10 @@ impl State {
window.clear_screen(win::ColorF32::BLACK);
window.use_program(&self.programs.main);
window.bind_framebuffer(Some(&self.main_framebuffer));
- window.uniform1f("u_aspect_ratio", render_resolution.0 as f32 / render_resolution.1 as f32);
+ window.uniform1f(
+ "u_aspect_ratio",
+ render_resolution.0 as f32 / render_resolution.1 as f32,
+ );
{
let (w, h) = window.size();
window.uniform2f("u_screen_size", w as f32, h as f32);
@@ -623,7 +687,7 @@ impl State {
}
self.main_array.draw();
-
+
window.bind_framebuffer(None);
window.viewport_full_screen();
window.use_program(&self.programs.post);
@@ -632,7 +696,7 @@ impl State {
self.post_array.draw();
window.swap();
-
+
if self.show_debug_info {
println!("frame time = {:?}ms", frame_dt * 1000.0);
}
diff --git a/src/sdf.rs b/src/sdf.rs
index 9a92905..e84c2f0 100644
--- a/src/sdf.rs
+++ b/src/sdf.rs
@@ -30,7 +30,6 @@ impl GenRandomParams for SdfParams {
fn inc_depth(self) -> Self {
Self {
max_depth: self.max_depth - 1,
- ..self
}
}
}
diff --git a/src/sdl.rs b/src/sdl.rs
index 5574373..0b06ed4 100644
--- a/src/sdl.rs
+++ b/src/sdl.rs
@@ -738,16 +738,18 @@ impl SDL_Surface {
self.flags
}
pub fn width(&self) -> i32 {
- self.w.try_into().unwrap()
+ assert!(self.w >= 0);
+ self.w
}
pub fn height(&self) -> i32 {
- self.h.try_into().unwrap()
+ assert!(self.h >= 0);
+ self.h
}
pub fn pitch(&self) -> i32 {
- self.pitch.try_into().unwrap()
+ self.pitch
}
pub fn locked(&self) -> i32 {
- self.locked.try_into().unwrap()
+ self.locked
}
pub fn pixel_format(&self) -> &SDL_PixelFormat {
// SAFETY: this should be a valid pointer as long as self is a valid SDL_Surface
diff --git a/src/vshader_post.glsl b/src/vshader_post.glsl
index 89e76ff..964ace3 100644
--- a/src/vshader_post.glsl
+++ b/src/vshader_post.glsl
@@ -1,4 +1,4 @@
-attribute vec2 v_pos;
+IN vec2 v_pos;
OUT vec2 uv;
void main() {
diff --git a/src/win.rs b/src/win.rs
index 18f3757..3835730 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -561,6 +561,15 @@ impl ColorU8 {
assert_eq!(suffix.len(), 0);
colors
}
+
+ pub fn slice_to_bytes(slice: &[ColorU8]) -> &[u8] {
+ // SAFETY: it is safe to transmute since ColorU8 is repr(C)
+ let (prefix, bytes, suffix) = unsafe { slice.align_to() };
+ // these should never panic since align_of(u8) == 1
+ assert_eq!(prefix.len(), 0);
+ assert_eq!(suffix.len(), 0);
+ bytes
+ }
}
impl From<u32> for ColorU8 {
@@ -1003,19 +1012,21 @@ impl Texture {
}
/// panicks if `data` is the wrong length (should be exactly `self.width() * self.height()`).
- unsafe fn get_data<T: Color>(&self, data: &mut [T]) {
+ pub fn get_data<T: Color>(&self, data: &mut [T]) {
assert_eq!(data.len(), self.width * self.height, "Bad data size.");
self.bind();
- gl::GetTexImage(
- gl::TEXTURE_2D,
- 0,
- T::GL_FORMAT,
- T::GL_TYPE,
- data.as_ptr() as *mut GLvoid,
- );
+ unsafe {
+ gl::GetTexImage(
+ gl::TEXTURE_2D,
+ 0,
+ T::GL_FORMAT,
+ T::GL_TYPE,
+ data.as_ptr() as *mut GLvoid,
+ );
+ }
}
- unsafe fn get_data_vec<T: Color>(&self) -> Vec<T> {
+ pub fn get_data_vec<T: Color>(&self) -> Vec<T> {
let mut data = vec![T::default(); self.width * self.height];
self.get_data(&mut data);
data
@@ -1120,7 +1131,7 @@ impl Framebuffer {
pub fn set_texture(&mut self, attachment: FramebufferAttachment, texture: &Texture) {
self.bind();
texture.bind();
- unsafe {
+ unsafe {
gl::FramebufferTexture2D(
gl::FRAMEBUFFER,
attachment.to_gl(),
@@ -1366,18 +1377,6 @@ impl Window {
unsafe { Texture::new(params) }
}
- /// get texture image
- ///
- /// panicks if `data.len() != texture.width() * texture.height()`
- pub fn get_texture_data<T: Color>(&mut self, texture: &Texture, data: &mut [T]) {
- unsafe { texture.get_data(data) };
- }
-
- /// get texture image as a newly-allocated `Vec`
- pub fn get_texture_data_vec<T: Color>(&mut self, texture: &Texture) -> Vec<T> {
- unsafe { texture.get_data_vec() }
- }
-
pub fn set_audio_callback(&mut self, callback: AudioCallback) -> Result<(), String> {
if self.audio_data.is_some() {
return Err("audio callback already set.".into());