-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
cd006eb
commit 22da1cf
Showing
2 changed files
with
208 additions
and
147 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,165 +1,226 @@ | ||
pub mod halvar { | ||
use winit::{ | ||
event::*, | ||
event_loop::{ControlFlow, EventLoop}, | ||
window::{Window, WindowBuilder}, | ||
}; | ||
use winit::{ | ||
event::*, | ||
event_loop::{ControlFlow, EventLoop}, | ||
window::{Window, WindowBuilder}, | ||
}; | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
use wasm_bindgen::prelude::*; | ||
|
||
struct State { | ||
surface: wgpu::Surface, | ||
device: wgpu::Device, | ||
queue: wgpu::Queue, | ||
config: wgpu::SurfaceConfiguration, | ||
size: winit::dpi::PhysicalSize<u32>, | ||
window: Window, | ||
} | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
use wasm_bindgen::prelude::*; | ||
|
||
struct State { | ||
surface: wgpu::Surface, | ||
device: wgpu::Device, | ||
queue: wgpu::Queue, | ||
config: wgpu::SurfaceConfiguration, | ||
size: winit::dpi::PhysicalSize<u32>, | ||
window: Window, | ||
} | ||
impl State { | ||
async fn new(window: Window) -> Self { | ||
let size = window.inner_size(); | ||
|
||
impl State { | ||
async fn new(window: Window) -> Self { | ||
let size = window.inner_size(); | ||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { | ||
backends: wgpu::Backends::all(), | ||
..Default::default() | ||
}); | ||
|
||
let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { | ||
backends: wgpu::Backends::all(), | ||
..Default::default() | ||
}); | ||
let surface = unsafe { instance.create_surface(&window) }.unwrap(); | ||
|
||
let surface = unsafe { instance.create_surface(&window) }.unwrap(); | ||
|
||
let adapter = instance | ||
.request_adapter(&wgpu::RequestAdapterOptions { | ||
power_preference: wgpu::PowerPreference::default(), | ||
compatible_surface: Some(&surface), | ||
force_fallback_adapter: false, | ||
}) | ||
.await | ||
.unwrap(); | ||
|
||
let (device, queue) = adapter | ||
.request_device( | ||
&wgpu::DeviceDescriptor { | ||
features: wgpu::Features::empty(), | ||
limits: if cfg!(target_arch = "wasm32") { | ||
wgpu::Limits::downlevel_webgl2_defaults() | ||
} else { | ||
wgpu::Limits::default() | ||
}, | ||
label: None, | ||
let adapter = instance | ||
.request_adapter(&wgpu::RequestAdapterOptions { | ||
power_preference: wgpu::PowerPreference::default(), | ||
compatible_surface: Some(&surface), | ||
force_fallback_adapter: false, | ||
}) | ||
.await | ||
.unwrap(); | ||
|
||
let (device, queue) = adapter | ||
.request_device( | ||
&wgpu::DeviceDescriptor { | ||
features: wgpu::Features::empty(), | ||
limits: if cfg!(target_arch = "wasm32") { | ||
wgpu::Limits::downlevel_webgl2_defaults() | ||
} else { | ||
wgpu::Limits::default() | ||
}, | ||
None, //trace_path | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
let surface_caps = surface.get_capabilities(&adapter); | ||
|
||
let surface_format = surface_caps | ||
.formats | ||
.iter() | ||
.copied() | ||
.find(|f| f.is_srgb()) | ||
.unwrap_or(surface_caps.formats[0]); | ||
|
||
let modes = &surface_caps.present_modes; | ||
|
||
let config = wgpu::SurfaceConfiguration { | ||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, | ||
format: surface_format, | ||
width: size.width, | ||
height: size.height, | ||
present_mode: wgpu::PresentMode::AutoVsync, | ||
alpha_mode: surface_caps.alpha_modes[0], | ||
view_formats: vec![], | ||
}; | ||
surface.configure(&device, &config); | ||
|
||
Self { | ||
surface, | ||
device, | ||
queue, | ||
config, | ||
size, | ||
window, | ||
} | ||
} | ||
label: None, | ||
}, | ||
None, //trace_path | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
pub fn window(&self) -> &Window { | ||
&self.window | ||
let surface_caps = surface.get_capabilities(&adapter); | ||
|
||
let surface_format = surface_caps | ||
.formats | ||
.iter() | ||
.copied() | ||
.find(|f| f.is_srgb()) | ||
.unwrap_or(surface_caps.formats[0]); | ||
|
||
let _modes = &surface_caps.present_modes; //TODO: Select which mode is needed based on settings | ||
|
||
let config = wgpu::SurfaceConfiguration { | ||
usage: wgpu::TextureUsages::RENDER_ATTACHMENT, | ||
format: surface_format, | ||
width: size.width, | ||
height: size.height, | ||
present_mode: wgpu::PresentMode::AutoVsync, | ||
alpha_mode: surface_caps.alpha_modes[0], | ||
view_formats: vec![], | ||
}; | ||
surface.configure(&device, &config); | ||
|
||
Self { | ||
surface, | ||
device, | ||
queue, | ||
config, | ||
size, | ||
window, | ||
} | ||
} | ||
|
||
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { | ||
todo!() | ||
} | ||
pub fn window(&self) -> &Window { | ||
&self.window | ||
} | ||
|
||
fn input(&mut self, event: &WindowEvent) -> bool { | ||
todo!() | ||
fn resize(&mut self, new_size: winit::dpi::PhysicalSize<u32>) { | ||
if new_size.width > 0 && new_size.height > 0 { | ||
self.size = new_size; | ||
self.config.width = new_size.width; | ||
self.config.height = new_size.height; | ||
self.surface.configure(&self.device, &self.config); | ||
} | ||
} | ||
|
||
fn update(&mut self) { | ||
todo!() | ||
} | ||
fn input(&mut self, _event: &WindowEvent) -> bool { | ||
false | ||
} | ||
|
||
fn render(&mut self) -> Result<(), wgpu::SurfaceError> { | ||
todo!() | ||
} | ||
fn update(&mut self) { | ||
//TODO: implement update | ||
} | ||
|
||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] | ||
pub async fn run() { | ||
cfg_if::cfg_if! { | ||
if #[cfg(target_arch = "wasm32")] { | ||
std::panic::set_hook(Box::new(console_error_panic_hook::hook)); | ||
console_log::init_with_level(log::Level::Warn).expect("couldn't initialize logger"); | ||
} else { | ||
env_logger::init(); | ||
} | ||
} | ||
let event_loop = EventLoop::new(); | ||
let title = env!("CARGO_PKG_NAME"); | ||
let window = WindowBuilder::new() | ||
.with_title(title) | ||
.build(&event_loop) | ||
.unwrap(); | ||
fn render(&mut self) -> Result<(), wgpu::SurfaceError> { | ||
let output = self.surface.get_current_texture()?; | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
{ | ||
use winit::dpi::PhysicalSize; | ||
window.set_inner_size(PhysicalSize::new(450, 400)); | ||
|
||
use winit::platform::web::WindowExtWebSys; | ||
web_sys::window() | ||
.and_then(|win| win.document()) | ||
.and_then(|doc| { | ||
let dst = doc.get_element_by_id("wasm-halvar")?; | ||
let canvas = web_sys::Element::from(window.canvas()); | ||
dst.append_child(&canvas).ok()?; | ||
Some(()) | ||
}) | ||
.expect("Couldn't append canvas to document body"); | ||
} | ||
let view = output | ||
.texture | ||
.create_view(&wgpu::TextureViewDescriptor::default()); | ||
|
||
let mut state = State::new(window).await; | ||
|
||
event_loop.run(move |event, _, control_flow| match event { | ||
Event::WindowEvent { | ||
ref event, | ||
window_id, | ||
} if window_id == state.window.id() => match event { | ||
WindowEvent::CloseRequested | ||
| WindowEvent::KeyboardInput { | ||
input: | ||
KeyboardInput { | ||
state: ElementState::Pressed, | ||
virtual_keycode: Some(VirtualKeyCode::Escape), | ||
.. | ||
}, | ||
.. | ||
} => *control_flow = ControlFlow::Exit, | ||
_ => {} | ||
}, | ||
_ => {} | ||
let mut encoder = self | ||
.device | ||
.create_command_encoder(&wgpu::CommandEncoderDescriptor { | ||
label: Some("Render Encoder"), | ||
}); | ||
|
||
let _render_pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { | ||
label: Some("Render Pass"), | ||
color_attachments: &[Some(wgpu::RenderPassColorAttachment { | ||
view: &view, | ||
resolve_target: None, | ||
ops: wgpu::Operations { | ||
load: wgpu::LoadOp::Clear(wgpu::Color { | ||
r: 0.1, | ||
g: 0.2, | ||
b: 0.3, | ||
a: 1.0, | ||
}), | ||
store: wgpu::StoreOp::Store, | ||
}, | ||
})], | ||
depth_stencil_attachment: None, | ||
occlusion_query_set: None, | ||
timestamp_writes: None, | ||
}); | ||
|
||
drop(_render_pass); | ||
|
||
self.queue.submit(std::iter::once(encoder.finish())); | ||
output.present(); | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))] | ||
pub async fn run() { | ||
cfg_if::cfg_if! { | ||
if #[cfg(target_arch = "wasm32")] { | ||
std::panic::set_hook(Box::new(console_error_panic_hook::hook)); | ||
console_log::init_with_level(log::Level::Warn).expect("couldn't initialize logger"); | ||
} else { | ||
env_logger::init(); | ||
} | ||
} | ||
let event_loop = EventLoop::new(); | ||
let title = env!("CARGO_PKG_NAME"); | ||
let window = WindowBuilder::new() | ||
.with_title(title) | ||
.build(&event_loop) | ||
.unwrap(); | ||
|
||
#[cfg(target_arch = "wasm32")] | ||
{ | ||
use winit::dpi::PhysicalSize; | ||
window.set_inner_size(PhysicalSize::new(450, 400)); | ||
|
||
use winit::platform::web::WindowExtWebSys; | ||
web_sys::window() | ||
.and_then(|win| win.document()) | ||
.and_then(|doc| { | ||
let dst = doc.get_element_by_id("wasm-halvar")?; | ||
let canvas = web_sys::Element::from(window.canvas()); | ||
dst.append_child(&canvas).ok()?; | ||
Some(()) | ||
}) | ||
.expect("Couldn't append canvas to document body"); | ||
} | ||
|
||
let mut state = State::new(window).await; | ||
|
||
event_loop.run(move |event, _, control_flow| match event { | ||
Event::WindowEvent { | ||
ref event, | ||
window_id, | ||
} if window_id == state.window.id() => { | ||
if !state.input(event) { | ||
match event { | ||
WindowEvent::CloseRequested | ||
| WindowEvent::KeyboardInput { | ||
input: | ||
KeyboardInput { | ||
state: ElementState::Pressed, | ||
virtual_keycode: Some(VirtualKeyCode::Escape), | ||
.. | ||
}, | ||
.. | ||
} => *control_flow = ControlFlow::Exit, | ||
WindowEvent::Resized(physical_size) => { | ||
state.resize(*physical_size); | ||
} | ||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => { | ||
state.resize(**new_inner_size) | ||
} | ||
_ => {} | ||
} | ||
} | ||
} | ||
Event::RedrawRequested(window_id) if window_id == state.window().id() => { | ||
state.update(); | ||
match state.render() { | ||
Ok(_) => {} | ||
Err(wgpu::SurfaceError::Lost) => state.resize(state.size), | ||
Err(wgpu::SurfaceError::OutOfMemory) => *control_flow = ControlFlow::Exit, | ||
Err(e) => eprintln!("{:?}", e), | ||
} | ||
} | ||
Event::MainEventsCleared => { | ||
state.window().request_redraw(); | ||
} | ||
_ => {} | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
use halvar::halvar::run; | ||
use halvar::run; | ||
|
||
fn main() { | ||
pollster::block_on(run()); | ||
|