Skip to content

Commit

Permalink
configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
TadaTeruki committed Aug 14, 2024
1 parent 1995d84 commit fd5d6c4
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 38 deletions.
35 changes: 30 additions & 5 deletions graphics/Cargo.lock

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

4 changes: 2 additions & 2 deletions graphics/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ crate-type = ["cdylib", "rlib"]

[dependencies]
log = "0.4.22"
wgpu = "22.1.0"

wasm-bindgen = "0.2.92"
wasm-bindgen-futures = "0.4.30"
wgpu = "22.1.0"
web-sys = { version = "0.3", features = [
"Document",
"Window",
"HtmlCanvasElement",
"Element",
]}
wasm-logger = "0.2.0"
wee_alloc = "0.4.5"
64 changes: 50 additions & 14 deletions graphics/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
use log::error;
use wasm_bindgen::prelude::*;
use wgpu::SurfaceTarget;

#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

#[wasm_bindgen]
pub struct State {
surface: wgpu::Surface<'static>,
Expand All @@ -9,10 +13,31 @@ pub struct State {
config: wgpu::SurfaceConfiguration,
}

#[wasm_bindgen(start)]
fn start() {
wasm_logger::init(wasm_logger::Config::default());
}

#[wasm_bindgen]
pub async fn create_state(
canvas: web_sys::HtmlCanvasElement,
use_gl_instead: bool,
) -> Option<State> {
match State::new(canvas, use_gl_instead).await {
Ok(state) => Some(state),
Err(e) => {
error!("Failed to create state: {:?}", e);
None
}
}
}

#[wasm_bindgen]
impl State {
#[wasm_bindgen(constructor)]
pub async fn new(canvas: web_sys::HtmlCanvasElement) -> Self {
async fn new(
canvas: web_sys::HtmlCanvasElement,
use_gl_instead: bool,
) -> Result<Self, Box<dyn std::error::Error>> {
let width = canvas.width();
let height = canvas.height();

Expand All @@ -22,7 +47,7 @@ impl State {
});

let surface_target = SurfaceTarget::Canvas(canvas);
let surface = instance.create_surface(surface_target).unwrap();
let surface = instance.create_surface(surface_target)?;

let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions {
Expand All @@ -31,13 +56,13 @@ impl State {
force_fallback_adapter: false,
})
.await
.unwrap();
.expect("Failed to find an appropriate adapter");

let (device, queue) = adapter
.request_device(
&wgpu::DeviceDescriptor {
required_features: wgpu::Features::empty(),
required_limits: if cfg!(target_arch = "wasm32") {
required_limits: if use_gl_instead {
wgpu::Limits::downlevel_webgl2_defaults()
} else {
wgpu::Limits::default()
Expand All @@ -47,36 +72,47 @@ impl State {
},
None,
)
.await
.unwrap();
.await?;

let surface_caps: wgpu::SurfaceCapabilities = surface.get_capabilities(&adapter);
let surface_format = surface_caps
.formats
.iter()
.find(|f| f.is_srgb())
.copied()
.unwrap_or(surface_caps.formats[0]);
.unwrap_or(
surface_caps
.formats
.first()
.copied()
.expect("No surface formats"),
);

let config = wgpu::SurfaceConfiguration {
usage: wgpu::TextureUsages::RENDER_ATTACHMENT,
format: surface_format,
width,
height,
present_mode: surface_caps.present_modes[0],
alpha_mode: surface_caps.alpha_modes[0],
present_mode: surface_caps
.present_modes
.first()
.copied()
.expect("No present modes"),
alpha_mode: surface_caps
.alpha_modes
.first()
.copied()
.expect("No alpha modes"),
view_formats: vec![],
desired_maximum_frame_latency: 2,
};

surface.configure(&device, &config);

Self {
Ok(Self {
surface,
device,
queue,
config,
}
})
}

#[wasm_bindgen]
Expand Down
5 changes: 4 additions & 1 deletion view/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"recommended": true,
"suspicious": {
"noExplicitAny": "off"
}
}
}
}
45 changes: 29 additions & 16 deletions view/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,39 @@
import init, { State } from "../pkg/graphics.js";
import init, { create_state, type State } from "../pkg/graphics.js";

function fullscreenCanvas(
canvas: HTMLCanvasElement,
state: State | undefined = undefined,
) {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
if (state) {
state.resize(window.innerWidth, window.innerHeight);
}
}

async function main() {
await init();

// initialize
const canvas = document.getElementById("main-canvas") as HTMLCanvasElement;
fullscreenCanvas(canvas);
await init();

const fullscreenOnlyCanvas = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
};
fullscreenOnlyCanvas();

const state = await new State(canvas);
// if the navigator does not have field 'gpu' then use WebGL
const useGlInstead = !navigator as any["gpu"];
if (useGlInstead) {
console.error("WebGPU not supported, falling back to WebGL");
}

const fullscreen = () => {
fullscreenOnlyCanvas();
state.resize(window.innerWidth, window.innerHeight);
};
// create state
const state = await create_state(canvas, useGlInstead);
if (!state) {
return;
}

addEventListener("resize", fullscreen);
fullscreen();
// resize
addEventListener("resize", () => fullscreenCanvas(canvas, state));
fullscreenCanvas(canvas, state);

// mainloop
const update = () => {
state.render();
requestAnimationFrame(update);
Expand Down

0 comments on commit fd5d6c4

Please sign in to comment.