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"
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]]
name = "android_system_properties"
version = "0.1.5"
@ -582,11 +599,14 @@ checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b"
name = "forestiles"
version = "0.1.0"
dependencies = [
"android_logger",
"bytemuck",
"cfg-if",
"console_error_panic_hook",
"console_log",
"env_logger",
"getrandom",
"lazy_static",
"log",
"nalgebra",
"noise",
@ -617,8 +637,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
@ -832,6 +854,12 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2db585e1d738fc771bf08a151420d3ed193d9d895a36df7f6f8a9456b911ddc"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.157"

View File

@ -26,6 +26,7 @@ rand = { version = "0.8", features = ["small_rng"] }
nalgebra = "0.33"
voronoice = "0.2"
noise = "0.9"
lazy_static = "1.5"
[target.'cfg(target_arch = "wasm32")'.dependencies]
console_error_panic_hook = "0.1.6"
@ -38,3 +39,7 @@ web-sys = { version = "0.3", features = [
"Window",
"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 winit::{event::{Event, WindowEvent}, event_loop::EventLoop, window::Window};
use crate::state::State;
use crate::{state::State, App};
#[repr(C)]
#[derive(Clone, Copy, Zeroable, Pod, Debug)]
@ -35,8 +35,7 @@ impl Default for Uniforms {
}
pub struct Graphics<'a> {
state: State,
window: &'a Window,
// window: &'a Window,
surface_config: SurfaceConfiguration,
surface: Surface<'a>,
device: Device,
@ -48,14 +47,18 @@ pub struct Graphics<'a> {
uniforms_bind_group: BindGroup
}
impl<'a> Graphics<'a> {
pub async fn init(window: &'a Window, state: State) -> Self {
let mut size = window.inner_size();
pub async fn init(/*window: &'a Window, state: &'a mut State*/app: &App<'a>) -> Self {
let mut size = app.window.inner_size();
size.width = size.width.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
.request_adapter(&wgpu::RequestAdapterOptions {
power_preference: wgpu::PowerPreference::default(),
@ -81,22 +84,23 @@ impl<'a> Graphics<'a> {
)
.await
.expect("Failed to create device");
dbg!(&device);
let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
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,
});
let index_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
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,
});
let uniforms_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor {
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,
});
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);
Self {
state,
window,
// window,
surface_config,
surface,
device,
@ -183,48 +186,62 @@ impl<'a> Graphics<'a> {
uniforms_bind_group
}
}
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::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();
pub fn event(&mut self, event: &Event<()>, window: &Window) {
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
window.request_redraw();
},
Event::AboutToWait => {
// RedrawRequested will only trigger once unless we manually
// request it.
window.request_redraw();
},
_ => {}
}
}
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
.get_current_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_vertex_buffer(0, self.vertex_buf.slice(..));
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);
}
self.queue.submit(Some(encoder.finish()));
frame.present();
}
fn update(&mut self) {
self.state.update_if_needed();
self.state.render();
self.queue.write_buffer(&self.vertex_buf, 0, bytemuck::cast_slice(&self.state.vertices));
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]));
pub fn update(&mut self, state: &State) {
self.queue.write_buffer(&self.vertex_buf, 0, bytemuck::cast_slice(&state.vertices));
self.queue.write_buffer(&self.index_buf, 0, bytemuck::cast_slice(&state.indices));
self.queue.write_buffer(&self.uniforms_buf, 0, bytemuck::cast_slice(&[state.uniforms]));
}
}

View File

@ -1,65 +1,186 @@
mod graphics;
mod state;
use std::time::Duration;
use state::State;
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() {
#[cfg(target_arch = "wasm32")]
{
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();
}
// #[cfg(target_family = "wasm")]
// let (event_loop, window) = {
// use winit::platform::web::WindowExtWebSys;
// std::panic::set_hook(Box::new(console_error_panic_hook::hook));
// console_log::init().expect("could not initialize logger");
let event_loop = winit::event_loop::EventLoop::new().unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
// let event_loop = winit::event_loop::EventLoop::new().unwrap();
// let window = winit::window::WindowBuilder::new().build(&event_loop).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())
// web_sys::window()
// .unwrap()
// .document()
// .unwrap()
// .body()
// .unwrap()
// .append_child(&window.canvas().unwrap())
// .unwrap();
// (event_loop, window)
// };
#[cfg(target_os = "android")]
let (event_loop, window) = {
use winit::platform::android::EventLoopBuilderExtAndroid;
let event_loop = winit::event_loop::EventLoopBuilder::new()
.with_android_app(app)
.build()
.unwrap();
wasm_bindgen_futures::spawn_local(async move {
Graphics::init(&window, State::new()).await.run(event_loop);
});
}
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
(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")]
#[no_mangle]
fn android_main(app: winit::platform::android::activity::AndroidApp) {
use std::thread;
use std::time::Duration;
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)
.build()
.expect("Cant build event loop");
.unwrap();
let window = winit::window::WindowBuilder::new().build(&event_loop).unwrap();
let mut window_builder = WindowBuilder::new();
let window = window_builder.build(&event_loop)
.expect("Can't create window!");
App {
window: &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();
pollster::block_on(Graphics::init(&window, state)).run(event_loop);
// let event_loop = EventLoopBuilder::new()
// .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
}
pub fn input(&mut self, event: Event<()>, window: &Window) {
pub fn event(&mut self, event: &Event<()>, window: &Window) {
match event {
Event::WindowEvent { event: WindowEvent::MouseInput { state, button, ..}, ..} => {
if state.is_pressed() {
@ -329,7 +329,7 @@ impl State {
Event::DeviceEvent { event: DeviceEvent::MouseWheel { delta }, ..} => {
self.uniforms.camera[2] -= match delta {
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.);
},