Skip to content

Commit

Permalink
Implement wafel_window crate
Browse files Browse the repository at this point in the history
  • Loading branch information
branpk committed Oct 3, 2023
1 parent d5723e8 commit eda26a8
Show file tree
Hide file tree
Showing 23 changed files with 1,255 additions and 36 deletions.
22 changes: 22 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ members = [
"wafel_viz_demo",
"wafel_viz_tests",
"wafel_viz",
"wafel_window",
]
resolver = "2"

Expand Down
2 changes: 1 addition & 1 deletion fast3d/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ pub mod decode;
mod error;
mod f3d_render_data;
pub mod interpret;
#[cfg(any(feature = "wgpu", doc))]
#[cfg(feature = "wgpu")]
#[doc(cfg(feature = "wgpu"))]
pub mod render;
mod trig_tables;
Expand Down
25 changes: 13 additions & 12 deletions fast3d/src/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -405,8 +405,8 @@ impl F3DRenderer {
&data.rgba8,
wgpu::ImageDataLayout {
offset: 0,
bytes_per_row: Some((4 * data.width).try_into().unwrap()),
rows_per_image: Some(data.height.try_into().unwrap()),
bytes_per_row: Some(4 * data.width),
rows_per_image: Some(data.height),
},
wgpu::Extent3d {
width: data.width,
Expand Down Expand Up @@ -483,14 +483,15 @@ impl F3DRenderer {
}
}

pub fn render<'r>(&'r self, rp: &mut wgpu::RenderPass<'r>) {
self.render_command_range(rp, 0..self.commands.len());
pub fn render<'r>(&'r self, rp: &mut wgpu::RenderPass<'r>, scale_factor: f32) {
self.render_command_range(rp, 0..self.commands.len(), scale_factor);
}

pub fn render_command_range<'r>(
&'r self,
rp: &mut wgpu::RenderPass<'r>,
cmd_indices: Range<usize>,
scale_factor: f32,
) {
let mut current_pipeline = None;

Expand All @@ -500,10 +501,10 @@ impl F3DRenderer {
continue;
}
rp.set_viewport(
x as f32 + self.screen_top_left[0] as f32,
y as f32 + self.screen_top_left[1] as f32,
w as f32,
h as f32,
(x as f32 + self.screen_top_left[0] as f32) * scale_factor,
(y as f32 + self.screen_top_left[1] as f32) * scale_factor,
(w as f32) * scale_factor,
(h as f32) * scale_factor,
0.0,
1.0,
);
Expand All @@ -519,10 +520,10 @@ impl F3DRenderer {
continue;
}
rp.set_scissor_rect(
x as u32 + self.screen_top_left[0],
y as u32 + self.screen_top_left[1],
w as u32,
h as u32,
((x as f32 + self.screen_top_left[0] as f32) * scale_factor) as u32,
((y as f32 + self.screen_top_left[1] as f32) * scale_factor) as u32,
((w as f32) * scale_factor) as u32,
((h as f32) * scale_factor) as u32,
);

if current_pipeline != Some(command.pipeline) {
Expand Down
4 changes: 3 additions & 1 deletion wafel_app/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ impl WindowedApp for WafelApp {
&msaa_output_view,
&depth_texture_view,
output_format,
scale_factor,
&mut clear_op,
);

Expand Down Expand Up @@ -206,6 +207,7 @@ impl WafelApp {
msaa_output_view: &wgpu::TextureView,
depth_texture_view: &wgpu::TextureView,
output_format: wgpu::TextureFormat,
scale_factor: f32,
clear_op: &mut Option<wgpu::LoadOp<wgpu::Color>>,
) {
for viz_render_data in &self.viz_render_data {
Expand All @@ -232,7 +234,7 @@ impl WafelApp {
}),
});

self.viz_renderer.render(&mut rp);
self.viz_renderer.render(&mut rp, scale_factor);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion wafel_core/src/graphics/viz_container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl VizContainer {
}),
});

self.renderer.render(&mut rp);
self.renderer.render(&mut rp, 1.0);
}

let command_buffer = encoder.finish();
Expand Down
4 changes: 2 additions & 2 deletions wafel_viz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
pub use config::*;
pub use error::*;
pub use render_data::*;
#[cfg(any(feature = "wgpu", doc))]
#[cfg(feature = "wgpu")]
#[doc(cfg(feature = "wgpu"))]
pub use renderer::VizRenderer;
pub use rotate_camera_control::*;
Expand All @@ -16,7 +16,7 @@ mod f3d_builder;
// mod ortho_camera_control;
mod ortho_camera_control;
mod render_data;
#[cfg(any(feature = "wgpu", doc))]
#[cfg(feature = "wgpu")]
mod renderer;
mod rotate_camera_control;
mod skybox;
Expand Down
50 changes: 34 additions & 16 deletions wafel_viz/src/renderer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,32 @@ impl VizRenderer {
}
}

pub fn render<'r>(&'r self, rp: &mut wgpu::RenderPass<'r>) {
pub fn render<'r>(&'r self, rp: &mut wgpu::RenderPass<'r>, scale_factor: f32) {
if let Some(render_data) = &self.per_frame_data {
self.f3d_renderer
.render_command_range(rp, render_data.f3d_pre_depth_cmd_range.clone());
self.f3d_renderer.render_command_range(
rp,
render_data.f3d_pre_depth_cmd_range.clone(),
scale_factor,
);

let vx = render_data.screen_top_left[0];
let vy = render_data.screen_top_left[1];
let vw = render_data.screen_size[0];
let vh = render_data.screen_size[1];
rp.set_viewport(vx as f32, vy as f32, vw as f32, vh as f32, 0.0, 1.0);
rp.set_scissor_rect(vx, vy, vw, vh);
rp.set_viewport(
(vx as f32) * scale_factor,
(vy as f32) * scale_factor,
(vw as f32) * scale_factor,
(vh as f32) * scale_factor,
0.0,
1.0,
);
rp.set_scissor_rect(
((vx as f32) * scale_factor) as u32,
((vy as f32) * scale_factor) as u32,
((vw as f32) * scale_factor) as u32,
((vh as f32) * scale_factor) as u32,
);

rp.set_pipeline(&self.pipelines.surface);
rp.set_bind_group(0, &render_data.transform_bind_group, &[]);
Expand All @@ -91,18 +106,18 @@ impl VizRenderer {
0..render_data.point_instance_buffer.0,
);

self.f3d_renderer
.render_command_range(rp, render_data.f3d_depth_cmd_range.clone());
self.f3d_renderer.render_command_range(
rp,
render_data.f3d_depth_cmd_range.clone(),
scale_factor,
);

{
// Render wall hitbox outline first since tris write to z buffer
rp.set_pipeline(&self.pipelines.line);
rp.set_bind_group(0, &render_data.transform_bind_group, &[]);
rp.set_vertex_buffer(0, render_data.wall_hitbox_outline_vertex_buffer.1.slice(..));
rp.draw(
0..render_data.wall_hitbox_outline_vertex_buffer.0 as u32,
0..1,
);
rp.draw(0..render_data.wall_hitbox_outline_vertex_buffer.0, 0..1);

// When two wall hitboxes overlap, we should not increase the opacity within
// their region of overlap (preference).
Expand All @@ -112,20 +127,23 @@ impl VizRenderer {
rp.set_vertex_buffer(0, render_data.wall_hitbox_vertex_buffer.1.slice(..));

rp.set_pipeline(&self.pipelines.wall_hitbox_depth_pass);
rp.draw(0..render_data.wall_hitbox_vertex_buffer.0 as u32, 0..1);
rp.draw(0..render_data.wall_hitbox_vertex_buffer.0, 0..1);
rp.set_pipeline(&self.pipelines.wall_hitbox);
rp.draw(0..render_data.wall_hitbox_vertex_buffer.0 as u32, 0..1);
rp.draw(0..render_data.wall_hitbox_vertex_buffer.0, 0..1);
}

rp.set_pipeline(&self.pipelines.transparent_surface);
rp.set_bind_group(0, &render_data.transform_bind_group, &[]);
rp.set_vertex_buffer(0, render_data.transparent_surface_vertex_buffer.1.slice(..));
rp.draw(0..render_data.transparent_surface_vertex_buffer.0, 0..1);

self.f3d_renderer
.render_command_range(rp, render_data.f3d_post_depth_cmd_range.clone());
self.f3d_renderer.render_command_range(
rp,
render_data.f3d_post_depth_cmd_range.clone(),
scale_factor,
);
} else {
self.f3d_renderer.render(rp);
self.f3d_renderer.render(rp, scale_factor);
}
}
}
2 changes: 1 addition & 1 deletion wafel_viz_demo/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ impl App for VizApp {
}),
});

self.viz_renderer.render(&mut rp);
self.viz_renderer.render(&mut rp, 1.0);
}

queue.submit([encoder.finish()]);
Expand Down
2 changes: 1 addition & 1 deletion wafel_viz_demo/src/remote_dll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ impl App for RemoteDllApp {
}),
});

self.viz_renderer.render(&mut rp);
self.viz_renderer.render(&mut rp, 1.0);
}

queue.submit([encoder.finish()]);
Expand Down
2 changes: 1 addition & 1 deletion wafel_viz_tests/src/renderer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ impl SizedRenderer {
stencil_ops: None,
}),
});
self.viz_renderer.render(&mut rp);
self.viz_renderer.render(&mut rp, 1.0);
}

encoder.copy_texture_to_buffer(
Expand Down
28 changes: 28 additions & 0 deletions wafel_window/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[package]
name = "wafel_window"
version = "0.1.0"
edition = "2021"

[dependencies]
chrono = "0.4.29"
wgpu = { workspace = true }
winit = "0.28.6"
once_cell = "1.18.0"
tracing = "0.1.37"
tracing-log = "0.1.3"
tracing-subscriber = "0.3.17"
pollster = "0.3.0"
image = { version = "0.24.7", optional = true }
egui = "0.22.0"
egui-wgpu = "0.22.0"
egui-winit = "0.22.0"
hot-lib-reloader = "0.6.5"
wafel_viz = { path = "../wafel_viz", features = ["wgpu"], optional = true }
static_assertions = "1.1.0"

[dev-dependencies]
wafel_api = { path = "../wafel_api" }

[[example]]
name = "sm64"
required-features = ["wafel_viz"]
17 changes: 17 additions & 0 deletions wafel_window/examples/minimal.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This prevents the console window from appearing on Windows in release mode.
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use wafel_window::Config;

fn main() {
let config = Config::new().with_title("Minimal example");

wafel_window::run(&config, move |env| {
let ctx = env.egui_ctx();

egui::CentralPanel::default().show(ctx, |ui| {
ui.label(format!("{:#?}", env.config()));
ui.label(format!("{:.3} mspf = {:.1} fps", env.mspf(), env.fps()));
});
});
}
71 changes: 71 additions & 0 deletions wafel_window/examples/sm64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::time;

use wafel_api::{Game, Input};
use wafel_viz::{ObjectCull, VizConfig};
use wafel_window::Config;

fn main() {
let mut game = unsafe { Game::new("libsm64/sm64_us") };

for frame in 0..1400 {
if frame % 2 == 1 {
game.write("gControllerPads[0].button", game.constant("START_BUTTON"));
}
game.advance();
}
let mut last_update_time = time::Instant::now();

let mut a_down = false;
let mut b_down = false;
let mut stick_x: i8 = 0;
let mut stick_y: i8 = 0;

let config = Config::new();
wafel_window::run(&config, move |env| {
let ctx = env.egui_ctx();

if last_update_time.elapsed().as_secs_f32() >= 1.0 / 30.0 {
last_update_time = time::Instant::now();

let mut buttons = 0;
if a_down {
buttons |= game.constant("A_BUTTON").as_int() as u16;
}
if b_down {
buttons |= game.constant("B_BUTTON").as_int() as u16;
}
game.set_input(Input {
buttons,
stick_x,
stick_y,
});

game.advance();
}

egui::CentralPanel::default().show(ctx, |ui| {
ui.label(format!("{:.3} mspf = {:.1} fps", env.mspf(), env.fps()));
ui.label(format!("frame = {}", game.frame()));

ui.checkbox(&mut a_down, "A");
ui.checkbox(&mut b_down, "B");
ui.add(egui::Slider::new(&mut stick_x, -127..=127).text("X"));
ui.add(egui::Slider::new(&mut stick_y, -127..=127).text("Y"));

let rect = ui.available_rect_before_wrap();

if rect.width() as u32 > 0 && rect.height() as u32 > 0 {
let render_data = game.render(&VizConfig {
screen_top_left: [rect.left() as u32, rect.top() as u32],
screen_size: [rect.width() as u32, rect.height() as u32],
object_cull: ObjectCull::ShowAll,
..Default::default()
});

env.draw_viz(render_data);
}
});
});
}
Loading

0 comments on commit eda26a8

Please sign in to comment.