This commit is contained in:
Arkitu 2024-08-29 09:52:03 +02:00
parent 2fd0fb9fc3
commit d3b662ebf6
5 changed files with 275 additions and 106 deletions

28
Cargo.lock generated
View File

@ -73,6 +73,23 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04" checksum = "fc7eb209b1518d6bb87b283c20095f5228ecda460da70b44f0802523dea6da04"
[[package]]
name = "android_log-sys"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ecc8056bf6ab9892dcd53216c83d1597487d7dacac16c8df6b877d127df9937"
[[package]]
name = "android_logger"
version = "0.14.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b07e8e73d720a1f2e4b6014766e6039fd2e96a4fa44e2a78d0e1fa2ff49826"
dependencies = [
"android_log-sys",
"env_filter",
"log",
]
[[package]] [[package]]
name = "android_system_properties" name = "android_system_properties"
version = "0.1.5" version = "0.1.5"
@ -582,11 +599,14 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
name = "forestiles" name = "forestiles"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"android_logger",
"bytemuck", "bytemuck",
"cfg-if", "cfg-if",
"console_error_panic_hook", "console_error_panic_hook",
"console_log", "console_log",
"env_logger", "env_logger",
"getrandom",
"lazy_static",
"log", "log",
"nalgebra", "nalgebra",
"noise", "noise",
@ -617,8 +637,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"js-sys",
"libc", "libc",
"wasi", "wasi",
"wasm-bindgen",
] ]
[[package]] [[package]]
@ -832,6 +854,12 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc" checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]] [[package]]
name = "libc" name = "libc"
version = "0.2.157" version = "0.2.157"

View File

@ -26,6 +26,7 @@ rand = { version = "0.8", features = ["small_rng"] }
nalgebra = "0.33" nalgebra = "0.33"
voronoice = "0.2" voronoice = "0.2"
noise = "0.9" noise = "0.9"
lazy_static = "1.5"
[target.'cfg(target_arch = "wasm32")'.dependencies] [target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6" console_error_panic_hook = "0.1.6"
@ -37,4 +38,8 @@ web-sys = { version = "0.3", features = [
"Document", "Document",
"Window", "Window",
"Element", "Element",
]} ]}
getrandom ={ version = "*", features = ["js"]}
[target.'cfg(target_os = "android")'.dependencies]
android_logger = "0.14"

View File

@ -2,7 +2,7 @@ use bytemuck::{Pod, Zeroable};
use wgpu::{include_wgsl, util::DeviceExt, BindGroup, Buffer, Device, Queue, RenderPipeline, Surface, SurfaceConfiguration, VertexBufferLayout}; use wgpu::{include_wgsl, util::DeviceExt, BindGroup, Buffer, Device, Queue, RenderPipeline, Surface, SurfaceConfiguration, VertexBufferLayout};
use winit::{event::{Event, WindowEvent}, event_loop::EventLoop, window::Window}; use winit::{event::{Event, WindowEvent}, event_loop::EventLoop, window::Window};
use crate::state::State; use crate::{state::State, App};
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy, Zeroable, Pod, Debug)] #[derive(Clone, Copy, Zeroable, Pod, Debug)]
@ -35,8 +35,7 @@ impl Default for Uniforms {
} }
pub struct Graphics<'a> { pub struct Graphics<'a> {
state: State, // window: &'a Window,
window: &'a Window,
surface_config: SurfaceConfiguration, surface_config: SurfaceConfiguration,
surface: Surface<'a>, surface: Surface<'a>,
device: Device, device: Device,
@ -48,14 +47,18 @@ pub struct Graphics<'a> {
uniforms_bind_group: BindGroup uniforms_bind_group: BindGroup
} }
impl<'a> Graphics<'a> { impl<'a> Graphics<'a> {
pub async fn init(window: &'a Window, state: State) -> Self { pub async fn init(/*window: &'a Window, state: &'a mut State*/app: &App<'a>) -> Self {
let mut size = window.inner_size(); let mut size = app.window.inner_size();
size.width = size.width.max(1); size.width = size.width.max(1);
size.height = size.height.max(1); size.height = size.height.max(1);
let instance = wgpu::Instance::default(); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor {
backends: wgpu::Backends::PRIMARY,
dx12_shader_compiler: Default::default(),
..Default::default()
});
let surface = instance.create_surface(window).unwrap(); let surface = instance.create_surface(app.window).unwrap();
let adapter = instance let adapter = instance
.request_adapter(&wgpu::RequestAdapterOptions { .request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(), power_preference: wgpu::PowerPreference::default(),
@ -81,22 +84,23 @@ impl<'a> Graphics<'a> {
) )
.await .await
.expect("Failed to create device"); .expect("Failed to create device");
dbg!(&device);
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Vertex Buffer"), label: Some("Vertex Buffer"),
contents: &[bytemuck::cast_slice::<Vertex, _>(&state.vertices), &[0; 100000]].concat(), contents: &[bytemuck::cast_slice::<Vertex, _>(&app.state.vertices), &[0; 100000]].concat(),
usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST, usage: wgpu::BufferUsages::VERTEX | wgpu::BufferUsages::COPY_DST,
}); });
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Index Buffer"), label: Some("Index Buffer"),
contents: &[bytemuck::cast_slice::<u32, _>(&state.indices), &[0; 100000]].concat(), contents: &[bytemuck::cast_slice::<u32, _>(&app.state.indices), &[0; 100000]].concat(),
usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST, usage: wgpu::BufferUsages::INDEX | wgpu::BufferUsages::COPY_DST,
}); });
let uniforms_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { let uniforms_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
label: Some("Uniforms Buffer"), label: Some("Uniforms Buffer"),
contents: bytemuck::cast_slice(&[state.uniforms]), contents: bytemuck::cast_slice(&[app.state.uniforms]),
usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST,
}); });
let uniforms_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { let uniforms_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
@ -170,8 +174,7 @@ impl<'a> Graphics<'a> {
surface.configure(&device, &surface_config); surface.configure(&device, &surface_config);
Self { Self {
state, // window,
window,
surface_config, surface_config,
surface, surface,
device, device,
@ -183,48 +186,62 @@ impl<'a> Graphics<'a> {
uniforms_bind_group uniforms_bind_group
} }
} }
pub fn run(&mut self, event_loop: EventLoop<()>) { pub fn event(&mut self, event: &Event<()>, window: &Window) {
event_loop.run(move |event, target| { match event {
// Have the closure take ownership of the resources. Event::WindowEvent {
// `event_loop.run` never returns, therefore we must do this to ensure event: WindowEvent::Resized(new_size),
// the resources are properly cleaned up. ..
let _ = &self; } => {
// Reconfigure the surface with the new size
match event { self.surface_config.width = new_size.width.max(1);
Event::WindowEvent { self.surface_config.height = new_size.height.max(1);
event: WindowEvent::Resized(new_size), self.surface.configure(&self.device, &self.surface_config);
.. // On macos the window needs to be redrawn manually after resizing
} => { window.request_redraw();
// Reconfigure the surface with the new size },
self.surface_config.width = new_size.width.max(1); Event::AboutToWait => {
self.surface_config.height = new_size.height.max(1); // RedrawRequested will only trigger once unless we manually
self.surface.configure(&self.device, &self.surface_config); // request it.
// On macos the window needs to be redrawn manually after resizing window.request_redraw();
self.window.request_redraw(); },
}, _ => {}
Event::WindowEvent { }
event: WindowEvent::RedrawRequested,
..
} => {
self.update();
self.render();
},
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => target.exit(),
Event::AboutToWait => {
// RedrawRequested will only trigger once unless we manually
// request it.
self.window.request_redraw();
},
e => self.state.input(e, &self.window)
}
})
.unwrap();
} }
fn render(&self) { // pub fn run(&mut self, event_loop: EventLoop<()>) {
// event_loop.run(move |event, target| {
// // Have the closure take ownership of the resources.
// // `event_loop.run` never returns, therefore we must do this to ensure
// // the resources are properly cleaned up.
// let _ = &self;
// match event {
// Event::WindowEvent {
// event: WindowEvent::Resized(new_size),
// ..
// } => {
// // Reconfigure the surface with the new size
// self.surface_config.width = new_size.width.max(1);
// self.surface_config.height = new_size.height.max(1);
// self.surface.configure(&self.device, &self.surface_config);
// // On macos the window needs to be redrawn manually after resizing
// self.window.request_redraw();
// },
// Event::WindowEvent {
// event: WindowEvent::CloseRequested,
// ..
// } => target.exit(),
// Event::AboutToWait => {
// // RedrawRequested will only trigger once unless we manually
// // request it.
// self.window.request_redraw();
// },
// _ => {}
// }
// })
// .unwrap();
// }
pub fn render(&self, state: &State) {
let frame = self.surface let frame = self.surface
.get_current_texture() .get_current_texture()
.expect("Failed to acquire next swap chain texture"); .expect("Failed to acquire next swap chain texture");
@ -255,19 +272,17 @@ impl<'a> Graphics<'a> {
rpass.set_bind_group(0, &self.uniforms_bind_group, &[]); rpass.set_bind_group(0, &self.uniforms_bind_group, &[]);
rpass.set_vertex_buffer(0, self.vertex_buf.slice(..)); rpass.set_vertex_buffer(0, self.vertex_buf.slice(..));
rpass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint32); rpass.set_index_buffer(self.index_buf.slice(..), wgpu::IndexFormat::Uint32);
rpass.draw_indexed(0..self.state.indices.len() as u32, 0, 0..1); rpass.draw_indexed(0..state.indices.len() as u32, 0, 0..1);
// rpass.draw(0..self.state.vertices.len() as u32, 0..1); // rpass.draw(0..self.state.vertices.len() as u32, 0..1);
} }
self.queue.submit(Some(encoder.finish())); self.queue.submit(Some(encoder.finish()));
frame.present(); frame.present();
} }
fn update(&mut self) { pub fn update(&mut self, state: &State) {
self.state.update_if_needed(); self.queue.write_buffer(&self.vertex_buf, 0, bytemuck::cast_slice(&state.vertices));
self.state.render(); self.queue.write_buffer(&self.index_buf, 0, bytemuck::cast_slice(&state.indices));
self.queue.write_buffer(&self.vertex_buf, 0, bytemuck::cast_slice(&self.state.vertices)); self.queue.write_buffer(&self.uniforms_buf, 0, bytemuck::cast_slice(&[state.uniforms]));
self.queue.write_buffer(&self.index_buf, 0, bytemuck::cast_slice(&self.state.indices));
self.queue.write_buffer(&self.uniforms_buf, 0, bytemuck::cast_slice(&[self.state.uniforms]));
} }
} }

View File

@ -1,65 +1,186 @@
mod graphics; mod graphics;
mod state; mod state;
use std::time::Duration;
use state::State; use state::State;
use graphics::Graphics; use graphics::Graphics;
use winit::{event::{Event, WindowEvent}, event_loop::EventLoop, window::Window};
struct App<'a> {
// event_loop: EventLoop<()>,
window: &'a Window,
graphics: Option<Graphics<'a>>,
state: State
}
impl<'a> App<'a> {
fn run(&mut self, event_loop: EventLoop<()>) {
dbg!("run");
event_loop.run(move |event, target| {
dbg!(&event);
let _ = &self;
// let _ = (&graphics, &window, &state);
match event {
Event::Resumed => {
std::thread::sleep(Duration::from_secs(10));
self.graphics = Some(pollster::block_on(Graphics::init(&self)));
},
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => target.exit(),
Event::WindowEvent {
event: WindowEvent::RedrawRequested,
..
} => {
if let Some(g) = &mut self.graphics {
self.state.update_if_needed();
self.state.render();
g.update(&self.state);
g.render(&self.state);
}
}
e => {
if let Some(g) = &mut self.graphics {
g.event(&e, &self.window);
}
self.state.event(&e, &self.window);
}
}
}).unwrap();
}
}
#[cfg(not(target_os = "android"))]
pub fn main() { pub fn main() {
#[cfg(target_arch = "wasm32")] // #[cfg(target_family = "wasm")]
{ // let (event_loop, window) = {
std::panic::set_hook(Box::new(console_error_panic_hook::hook)); // use winit::platform::web::WindowExtWebSys;
console_log::init().expect("could not initialize logger"); // std::panic::set_hook(Box::new(console_error_panic_hook::hook));
} // console_log::init().expect("could not initialize logger");
#[cfg(not(target_arch = "wasm32"))]
{
env_logger::init();
}
let event_loop = winit::event_loop::EventLoop::new().unwrap(); // let event_loop = winit::event_loop::EventLoop::new().unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap(); // let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
#[cfg(not(target_arch = "wasm32"))] // web_sys::window()
{ // .unwrap()
let state = State::new(); // .document()
pollster::block_on(Graphics::init(&window, state)).run(event_loop); // .unwrap()
} // .body()
#[cfg(target_arch = "wasm32")] // .unwrap()
{ // .append_child(&window.canvas().unwrap())
use winit::platform::web::WindowExtWebSys; // .unwrap();
web_sys::window() // (event_loop, window)
.unwrap() // };
.document() #[cfg(target_os = "android")]
.unwrap() let (event_loop, window) = {
.body() use winit::platform::android::EventLoopBuilderExtAndroid;
.unwrap() let event_loop = winit::event_loop::EventLoopBuilder::new()
.append_child(&window.canvas().unwrap()) .with_android_app(app)
.build()
.unwrap(); .unwrap();
wasm_bindgen_futures::spawn_local(async move { let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
Graphics::init(&window, State::new()).await.run(event_loop); (event_loop, window)
}); };
} #[cfg(not(any(target_family = "wasm", target_os = "android")))]
let (event_loop, window) = {
env_logger::init();
let event_loop = winit::event_loop::EventLoop::new().unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
(event_loop, window)
};
App {
window: &window,
graphics: None,
state: State::new()
}.run(event_loop);
// static mut graphics: Option<Graphics> = None;
// event_loop.run(move |event, target| {
// // let _ = (&graphics, &window, &state);
// match event {
// Event::Resumed => {
// graphics = Some(pollster::block_on(Graphics::init(&window, &mut state)));
// },
// Event::WindowEvent {
// event: WindowEvent::CloseRequested,
// ..
// } => target.exit(),
// Event::WindowEvent {
// event: WindowEvent::RedrawRequested,
// ..
// } => {
// if let Some(g) = &mut graphics {
// g.update(&state);
// g.render(&state);
// }
// }
// _ => {}
// }
// }).unwrap();
// #[cfg(not(target_arch = "wasm32"))]
// {
// let state = State::new();
// pollster::block_on(Graphics::init(&window, state)).run(event_loop);
// }
// #[cfg(target_arch = "wasm32")]
// {
// use winit::platform::web::WindowExtWebSys;
// web_sys::window()
// .unwrap()
// .document()
// .unwrap()
// .body()
// .unwrap()
// .append_child(&window.canvas().unwrap())
// .unwrap();
// wasm_bindgen_futures::spawn_local(async move {
// Graphics::init(&window, State::new()).await.run(event_loop);
// });
// }
} }
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
#[no_mangle] #[no_mangle]
fn android_main(app: winit::platform::android::activity::AndroidApp) { fn android_main(app: winit::platform::android::activity::AndroidApp) {
use std::thread;
use std::time::Duration;
use winit::platform::android::EventLoopBuilderExtAndroid; use winit::platform::android::EventLoopBuilderExtAndroid;
use winit::event_loop::EventLoopBuilder;
use winit::window::WindowBuilder;
let event_loop = EventLoopBuilder::new() android_logger::init_once(android_logger::Config::default());
log::error!("testbbbbbbbbbbb");
let event_loop = winit::event_loop::EventLoopBuilder::new()
.with_android_app(app) .with_android_app(app)
.build() .build()
.expect("Cant build event loop"); .unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
let mut window_builder = WindowBuilder::new(); App {
let window = window_builder.build(&event_loop) window: &window,
.expect("Can't create window!"); graphics: None,
state: State::new()
}.run(event_loop);
// main();
// use std::thread;
// use std::time::Duration;
thread::sleep(Duration::from_secs(2)); // use winit::platform::android::EventLoopBuilderExtAndroid;
// use winit::event_loop::EventLoopBuilder;
// use winit::window::WindowBuilder;
let state = State::new(); // let event_loop = EventLoopBuilder::new()
pollster::block_on(Graphics::init(&window, state)).run(event_loop); // .with_android_app(app)
// .build()
// .expect("Cant build event loop");
// let mut window_builder = WindowBuilder::new();
// let window = window_builder.build(&event_loop)
// .expect("Can't create window!");
// thread::sleep(Duration::from_secs(2));
// let state = State::new();
// pollster::block_on(Graphics::init(&window, state)).run(event_loop);
} }

View File

@ -285,7 +285,7 @@ impl State {
s.render(); s.render();
s s
} }
pub fn input(&mut self, event: Event<()>, window: &Window) { pub fn event(&mut self, event: &Event<()>, window: &Window) {
match event { match event {
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => { Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
if state.is_pressed() { if state.is_pressed() {
@ -329,7 +329,7 @@ impl State {
Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => { Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => {
self.uniforms.camera[2] -= match delta { self.uniforms.camera[2] -= match delta {
MouseScrollDelta::PixelDelta(pos) => pos.y as f32, MouseScrollDelta::PixelDelta(pos) => pos.y as f32,
MouseScrollDelta::LineDelta(_, y) => y MouseScrollDelta::LineDelta(_, y) => *y
}; };
self.uniforms.camera[2] = self.uniforms.camera[2].clamp(0.1, 1.); self.uniforms.camera[2] = self.uniforms.camera[2].clamp(0.1, 1.);
}, },