diff options
author | pommicket <pommicket@gmail.com> | 2023-01-24 11:48:57 -0500 |
---|---|---|
committer | pommicket <pommicket@gmail.com> | 2023-01-24 11:48:57 -0500 |
commit | f9dd273b9dfa9813ea29efe0ace9aba4c5fedf08 (patch) | |
tree | 489f6decabcecd32dee6f448341c2211d79b5777 /src | |
parent | 4d9eaeaac64c22290a524966a1c7ea6962057982 (diff) |
start pause menu
Diffstat (limited to 'src')
-rw-r--r-- | src/fshader_post.glsl | 8 | ||||
-rw-r--r-- | src/main.rs | 69 | ||||
-rw-r--r-- | src/menu.png | bin | 0 -> 17072 bytes | |||
-rw-r--r-- | src/menu.xcf | bin | 0 -> 92668 bytes | |||
-rw-r--r-- | src/win.rs | 83 |
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(¶ms); + 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 Binary files differnew file mode 100644 index 0000000..6a5a481 --- /dev/null +++ b/src/menu.png diff --git a/src/menu.xcf b/src/menu.xcf Binary files differnew file mode 100644 index 0000000..b231ee8 --- /dev/null +++ b/src/menu.xcf @@ -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 { |