summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-01-24 11:48:57 -0500
committerpommicket <pommicket@gmail.com>2023-01-24 11:48:57 -0500
commitf9dd273b9dfa9813ea29efe0ace9aba4c5fedf08 (patch)
tree489f6decabcecd32dee6f448341c2211d79b5777 /src
parent4d9eaeaac64c22290a524966a1c7ea6962057982 (diff)
start pause menu
Diffstat (limited to 'src')
-rw-r--r--src/fshader_post.glsl8
-rw-r--r--src/main.rs69
-rw-r--r--src/menu.pngbin0 -> 17072 bytes
-rw-r--r--src/menu.xcfbin0 -> 92668 bytes
-rw-r--r--src/win.rs83
5 files changed, 127 insertions, 33 deletions
diff --git a/src/fshader_post.glsl b/src/fshader_post.glsl
index d7b9100..6e8a66f 100644
--- a/src/fshader_post.glsl
+++ b/src/fshader_post.glsl
@@ -1,6 +1,10 @@
-uniform sampler2D u_texture;
+uniform sampler2D u_main_texture;
+uniform sampler2D u_menu_texture;
+uniform float u_paused;
IN vec2 uv;
void main() {
- gl_FragColor = texture(u_texture, uv);
+ vec4 color = texture(u_main_texture, uv) * (1.0 - 0.5 * u_paused);
+ color += texture(u_menu_texture, uv).xxxx * u_paused;
+ gl_FragColor = clamp(color, 0.0, 1.0);
}
diff --git a/src/main.rs b/src/main.rs
index 65b68ff..310206c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -230,6 +230,7 @@ struct State {
initial_view: View,
show_debug_info: bool,
fullscreen: bool,
+ esc_menu: bool,
frame_time: Instant,
programs: Programs,
config: sdf::SceneConfig,
@@ -240,6 +241,7 @@ struct State {
test_framebuffer: win::Framebuffer,
main_framebuffer_texture: win::Texture,
main_framebuffer: win::Framebuffer,
+ menu_texture: win::Texture,
main_framebuffer_size: (i32, i32),
main_array: win::VertexArray,
test_array: win::VertexArray,
@@ -303,14 +305,38 @@ impl State {
let test_array = window.create_vertex_array(test_buffer, &programs.test);
let post_array = window.create_vertex_array(post_buffer, &programs.post);
- window.set_mouse_relative(true);
-
let scene_list = File::options()
.append(true)
.create(true)
.open("scenes.txt")
.ok();
+ let menu_texture = {
+ let params = win::TextureParams {
+ min_filter: win::TextureFilter::Linear,
+ ..Default::default()
+ };
+ let mut tex = window.create_texture(&params);
+ let png_data = include_bytes!("menu.png");
+ let decoder = png::Decoder::new(&png_data[..]);
+ if let Ok(mut reader) = decoder.read_info() {
+ let mut data = vec![0; reader.output_buffer_size()];
+ if let Ok(info) = reader.next_frame(&mut data) {
+ let width = info.width;
+ let height = info.height;
+ let bytes = &data[..info.buffer_size()];
+ let colors = win::ColorGrayscaleU8::slice_from_bytes(bytes);
+ if tex
+ .set_data(Some(colors), width as usize, height as usize)
+ .is_err()
+ {
+ // don't care
+ }
+ }
+ }
+ tex
+ };
+
let mut me = Self {
window,
programs,
@@ -326,8 +352,10 @@ impl State {
main_framebuffer_texture,
main_framebuffer,
main_framebuffer_size: (0, 0),
+ menu_texture,
main_array,
test_array,
+ esc_menu: false,
post_array,
scene_list,
settings,
@@ -472,11 +500,20 @@ impl State {
let frame_dt = self.frame_time.elapsed().as_secs_f32();
self.frame_time = Instant::now();
+ self.window.set_mouse_relative(!self.esc_menu);
+
while let Some(event) = self.window.next_event() {
use win::Event::*;
use win::Key::*;
match event {
- Quit | KeyDown { key: Escape, .. } => return false,
+ Quit => return false,
+ KeyDown { key: Escape, .. } => {
+ if self.esc_menu {
+ return false;
+ } else {
+ self.esc_menu = true;
+ }
+ }
KeyDown { key: F1, .. } => self.show_debug_info = !self.show_debug_info,
KeyDown { key: R, .. } => {
let new_scene = sdf::Scene::good_random(&mut get_rng(), &self.config);
@@ -546,20 +583,24 @@ impl State {
}
}
MouseMotion { xrel, yrel, .. } => {
- let mouse_sensitivity =
- 0.001 * self.settings.get_f32("mouse-sensitivity").unwrap_or(50.0);
- self.view
- .yaw_by(-xrel as f32 * mouse_sensitivity * frame_dt);
- self.view
- .pitch_by(-yrel as f32 * mouse_sensitivity * frame_dt);
+ if !self.esc_menu {
+ let mouse_sensitivity =
+ 0.001 * self.settings.get_f32("mouse-sensitivity").unwrap_or(50.0);
+ self.view
+ .yaw_by(-xrel as f32 * mouse_sensitivity * frame_dt);
+ self.view
+ .pitch_by(-yrel as f32 * mouse_sensitivity * frame_dt);
+ }
}
_ => {}
}
}
- self.view.pass_time(frame_dt.into());
+ if !self.esc_menu {
+ self.view.pass_time(frame_dt.into());
+ }
- {
+ if !self.esc_menu {
// movement
let mut dx = 0.0;
let mut dy = 0.0;
@@ -624,6 +665,7 @@ impl State {
let render_resolution = self.render_resolution();
if render_resolution != self.main_framebuffer_size {
+ // window resized. create new framebuffer
let result = self.main_framebuffer_texture.set_data::<ColorU8>(
None,
render_resolution.0 as usize,
@@ -695,7 +737,10 @@ impl State {
window.viewport_full_screen();
window.use_program(&self.programs.post);
window.active_texture(0, &self.main_framebuffer_texture);
- window.uniform_texture("u_texture", 0);
+ window.active_texture(1, &self.menu_texture);
+ window.uniform1f("u_paused", if self.esc_menu { 1.0 } else { 0.0 });
+ window.uniform_texture("u_main_texture", 0);
+ window.uniform_texture("u_menu_texture", 1);
self.post_array.draw();
window.swap();
diff --git a/src/menu.png b/src/menu.png
new file mode 100644
index 0000000..6a5a481
--- /dev/null
+++ b/src/menu.png
Binary files differ
diff --git a/src/menu.xcf b/src/menu.xcf
new file mode 100644
index 0000000..b231ee8
--- /dev/null
+++ b/src/menu.xcf
Binary files differ
diff --git a/src/win.rs b/src/win.rs
index 3835730..6a0dadc 100644
--- a/src/win.rs
+++ b/src/win.rs
@@ -494,6 +494,38 @@ pub struct ColorU8 {
pub a: u8,
}
+#[repr(C)]
+#[derive(Clone, Copy, Default)]
+pub struct ColorGrayscaleU8 {
+ pub value: u8,
+}
+
+#[repr(C)]
+#[derive(Clone, Copy, Default)]
+pub struct ColorGrayscaleF32 {
+ pub value: f32,
+}
+
+unsafe impl Color for ColorU8 {
+ const GL_FORMAT: GLenum = gl::RGBA;
+ const GL_TYPE: GLenum = gl::UNSIGNED_BYTE;
+}
+
+unsafe impl Color for ColorGrayscaleU8 {
+ const GL_FORMAT: GLenum = gl::RED;
+ const GL_TYPE: GLenum = gl::UNSIGNED_BYTE;
+}
+
+unsafe impl Color for ColorF32 {
+ const GL_FORMAT: GLenum = gl::RGBA;
+ const GL_TYPE: GLenum = gl::FLOAT;
+}
+
+unsafe impl Color for ColorGrayscaleF32 {
+ const GL_FORMAT: GLenum = gl::RED;
+ const GL_TYPE: GLenum = gl::FLOAT;
+}
+
impl fmt::Display for ColorU8 {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
@@ -510,11 +542,6 @@ impl fmt::Debug for ColorU8 {
}
}
-unsafe impl Color for ColorU8 {
- const GL_FORMAT: GLenum = gl::RGBA;
- const GL_TYPE: GLenum = gl::UNSIGNED_BYTE;
-}
-
impl ColorU8 {
pub const fn new(r: u8, g: u8, b: u8, a: u8) -> Self {
ColorU8 { r, g, b, a }
@@ -603,26 +630,34 @@ impl ColorF32 {
}
}
-unsafe impl Color for ColorF32 {
- const GL_FORMAT: GLenum = gl::RGBA;
- const GL_TYPE: GLenum = gl::FLOAT;
-}
-
-#[repr(C)]
-#[derive(Clone, Copy, Default)]
-pub struct ColorGrayscaleF32 {
- pub value: f32,
-}
-
impl ColorGrayscaleF32 {
pub const fn new(value: f32) -> Self {
Self { value }
}
}
-unsafe impl Color for ColorGrayscaleF32 {
- const GL_FORMAT: GLenum = gl::RED;
- const GL_TYPE: GLenum = gl::FLOAT;
+impl ColorGrayscaleU8 {
+ pub const fn new(value: u8) -> Self {
+ Self { value }
+ }
+
+ pub fn slice_from_bytes(bytes: &[u8]) -> &[ColorGrayscaleU8] {
+ // SAFETY: it is safe to transmute since ColorGrayscaleU8 is repr(C)
+ let (prefix, colors, suffix) = unsafe { bytes.align_to() };
+ // these should never panic since align_of(ColorGrayscaleU8) == 1
+ assert_eq!(prefix.len(), 0);
+ assert_eq!(suffix.len(), 0);
+ colors
+ }
+
+ pub fn slice_to_bytes(slice: &[ColorGrayscaleU8]) -> &[u8] {
+ // SAFETY: it is safe to transmute since ColorGrayscaleU8 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
+ }
}
pub struct Shader {
@@ -961,6 +996,16 @@ impl Texture {
let height: GLsizei = height.try_into().map_err(|_| "height too large")?;
let expected_len = width * height;
+ #[cfg(debug_assertions)]
+ {
+ let color_size = std::mem::size_of::<T>();
+ if width as usize * color_size % 4 != 0 {
+ eprintln!("WARNING: This texture has a width of {width} * {color_size} = {} bytes, which is not a multiple of 4.",
+ width as usize * color_size);
+ eprintln!(" See https://www.khronos.org/opengl/wiki/Common_Mistakes#Texture_upload_and_pixel_reads for more information.");
+ }
+ }
+
let ptr = match data {
Some(data) => {
if data.len() as GLsizei != expected_len {