From 761b4341088edae56349b9956a6810101d265835 Mon Sep 17 00:00:00 2001 From: Simon Gellis Date: Sun, 1 Dec 2024 15:52:11 -0500 Subject: [PATCH] Implement side-by-side view --- src/{anaglyph.wgsl => game.wgsl} | 14 +++++++++++++- src/window/game.rs | 28 ++++++++++++++++++++++++++-- src/window/game_screen.rs | 23 ++++++++++++++++++++--- 3 files changed, 59 insertions(+), 6 deletions(-) rename src/{anaglyph.wgsl => game.wgsl} (80%) diff --git a/src/anaglyph.wgsl b/src/game.wgsl similarity index 80% rename from src/anaglyph.wgsl rename to src/game.wgsl index a2e87dd..3a1aa37 100644 --- a/src/anaglyph.wgsl +++ b/src/game.wgsl @@ -57,7 +57,7 @@ fn fs_lefteye(in: VertexOutput) -> @location(0) vec4 { @fragment fn fs_righteye(in: VertexOutput) -> @location(0) vec4 { let brt = textureSample(u_texture, u_sampler, in.tex_coords); - return colors.right * brt[1]; + return colors.left * brt[1]; } @fragment @@ -65,3 +65,15 @@ fn fs_anaglyph(in: VertexOutput) -> @location(0) vec4 { let brt = textureSample(u_texture, u_sampler, in.tex_coords); return colors.left * brt[0] + colors.right * brt[1]; } + +@fragment +fn fs_sidebyside(in: VertexOutput) -> @location(0) vec4 { + var point = in.tex_coords; + point.x = (point.x * 2.0) % 1.0; + let brt = textureSample(u_texture, u_sampler, point); + if in.tex_coords.x < 0.5 { + return colors.left * brt[0]; + } else { + return colors.left * brt[1]; + }; +} \ No newline at end of file diff --git a/src/window/game.rs b/src/window/game.rs index ba2a188..c3a7437 100644 --- a/src/window/game.rs +++ b/src/window/game.rs @@ -90,7 +90,10 @@ impl GameWindow { for scale in 1..=4 { let label = format!("x{scale}"); let scale = scale as f32; - let dims = (384.0 * scale, 224.0 * scale + 22.0).into(); + let dims = { + let Vec2 { x, y } = self.display_mode.proportions(); + Vec2::new(x * scale, y * scale + 22.0) + }; if ui .selectable_button((current_dims - dims).length() < 1.0, label) .clicked() @@ -102,6 +105,7 @@ impl GameWindow { }); ui.menu_button("Display Mode", |ui| { + let old_proportions = self.display_mode.proportions(); if ui .selectable_option(&mut self.display_mode, DisplayMode::Anaglyph, "Anaglyph") .clicked() @@ -120,6 +124,25 @@ impl GameWindow { { ui.close_menu(); } + if ui + .selectable_option( + &mut self.display_mode, + DisplayMode::SideBySide, + "Side by Side", + ) + .clicked() + { + ui.close_menu(); + } + + let new_proportions = self.display_mode.proportions(); + let scale = new_proportions / old_proportions; + if scale != Vec2::new(1.0, 1.0) { + let current_dims = ctx.input(|i| i.viewport().inner_rect.unwrap()); + let current_dims = current_dims.max - current_dims.min; + + ctx.send_viewport_cmd(ViewportCommand::InnerSize(current_dims * scale)); + } }); ui.menu_button("Colors", |ui| { for preset in COLOR_PRESETS { @@ -183,9 +206,10 @@ impl AppWindow for GameWindow { } fn initial_viewport(&self) -> ViewportBuilder { + let dimensions = self.display_mode.proportions() + Vec2::new(0.0, 22.0); ViewportBuilder::default() .with_title("Shrooms VB") - .with_inner_size((384.0, 246.0)) + .with_inner_size(dimensions) } fn show(&mut self, ctx: &Context) { diff --git a/src/window/game_screen.rs b/src/window/game_screen.rs index 3e2e36c..10d8426 100644 --- a/src/window/game_screen.rs +++ b/src/window/game_screen.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, sync::Arc}; -use egui::{Color32, Rgba, Widget}; +use egui::{Color32, Rgba, Vec2, Widget}; use wgpu::{util::DeviceExt as _, BindGroup, BindGroupLayout, Buffer, RenderPipeline}; use crate::graphics::TextureSink; @@ -48,7 +48,7 @@ impl GameScreen { ], }); - let shader = device.create_shader_module(wgpu::include_wgsl!("../anaglyph.wgsl")); + let shader = device.create_shader_module(wgpu::include_wgsl!("../game.wgsl")); let render_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { label: Some("render pipeline layout"), @@ -100,6 +100,10 @@ impl GameScreen { render_pipelines.insert(DisplayMode::Anaglyph, create_render_pipeline("fs_anaglyph")); render_pipelines.insert(DisplayMode::LeftEye, create_render_pipeline("fs_lefteye")); render_pipelines.insert(DisplayMode::RightEye, create_render_pipeline("fs_righteye")); + render_pipelines.insert( + DisplayMode::SideBySide, + create_render_pipeline("fs_sidebyside"), + ); render_state .renderer @@ -217,7 +221,10 @@ impl egui_wgpu::CallbackTrait for GameScreenCallback { let top = viewport.top_px as f32; let width = viewport.width_px as f32; let height = viewport.height_px as f32; - let aspect_ratio = 384.0 / 224.0; + let aspect_ratio = { + let proportions = self.display_mode.proportions(); + proportions.x / proportions.y + }; let w = width.min(height * aspect_ratio); let h = height.min(width / aspect_ratio); let x = left + (width - w) / 2.0; @@ -258,4 +265,14 @@ pub enum DisplayMode { Anaglyph, LeftEye, RightEye, + SideBySide, +} + +impl DisplayMode { + pub fn proportions(self) -> Vec2 { + match self { + Self::SideBySide => Vec2::new(768.0, 224.0), + _ => Vec2::new(384.0, 224.0), + } + } }