diff --git a/Cargo.lock b/Cargo.lock index e1b5fa3..5b33c59 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1647,9 +1647,9 @@ dependencies = [ [[package]] name = "strafesnet_graphics" -version = "0.0.6" +version = "0.0.7" source = "sparse+https://git.itzana.me/api/packages/strafesnet/cargo/" -checksum = "0956371782403270db1788d0af2977d3d30632e5bdb9e514cd1550db0999c82a" +checksum = "5b0afe15871f8205f3387dd5816e797c0576429d3013a33a3daed293bcaeedef" dependencies = [ "bytemuck", "ddsfile", diff --git a/Cargo.toml b/Cargo.toml index 5eeb840..a28b193 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,8 +15,13 @@ codegen-units = 1 glam = "0.32.0" strafesnet_common = { version = "0.8.6", registry = "strafesnet" } -strafesnet_graphics = { version = "0.0.6", registry = "strafesnet" } +strafesnet_graphics = { version = "0.0.7", registry = "strafesnet" } strafesnet_roblox_bot_file = { version = "0.9.3", registry = "strafesnet" } strafesnet_snf = { version = "0.3.2", registry = "strafesnet" } strafesnet_roblox_bot_player = { version = "0.2.0", path = "lib" } + +# strafesnet_common = { path = "../strafe-project/lib/common" } +# strafesnet_graphics = { path = "../strafe-project/engine/graphics" } +# strafesnet_roblox_bot_file = { path = "../roblox_bot_file" } +# strafesnet_snf = { path = "../strafe-project/lib/snf" } diff --git a/lib/src/graphics.rs b/lib/src/graphics.rs index 539b4fd..fcb003f 100644 --- a/lib/src/graphics.rs +++ b/lib/src/graphics.rs @@ -3,58 +3,28 @@ use strafesnet_graphics::graphics::GraphicsState; /// The graphics state, essentially a handle to all the information on the GPU. pub struct Graphics{ graphics:GraphicsState, - config:wgpu::SurfaceConfiguration, - device:wgpu::Device, - queue:wgpu::Queue, start_offset:glam::Vec3, } impl Graphics{ - pub fn new(device:wgpu::Device,queue:wgpu::Queue,config:wgpu::SurfaceConfiguration)->Self{ - let graphics=strafesnet_graphics::graphics::GraphicsState::new(&device,&queue,glam::uvec2(config.width,config.height),config.view_formats[0]); + pub fn new(device:&wgpu::Device,queue:&wgpu::Queue,size:glam::UVec2,view_format:wgpu::TextureFormat)->Self{ + let graphics=strafesnet_graphics::graphics::GraphicsState::new(device,queue,size,view_format); Self{ graphics, - device, - queue, - config, start_offset:glam::Vec3::ZERO, } } - pub fn change_map(&mut self,map:&strafesnet_common::map::CompleteMap){ + pub fn change_map(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&strafesnet_common::map::CompleteMap){ self.graphics.clear(); - self.graphics.generate_models(&self.device,&self.queue,map); + self.graphics.generate_models(device,queue,map); let modes=map.modes.clone().denormalize(); let mode=modes.get_mode(strafesnet_common::gameplay_modes::ModeId::MAIN).expect("Map does not have a main mode"); let start_zone=map.models.get(mode.get_start().get() as usize).expect("Map does not have a start zone"); self.start_offset=glam::Vec3::from_array(start_zone.transform.translation.map(|f|f.into()).to_array()); } - pub fn resize(&mut self,surface:&wgpu::Surface<'_>,size:glam::UVec2,fov:glam::Vec2){ - self.config.width=size.x.max(1); - self.config.height=size.y.max(1); - surface.configure(&self.device,&self.config); - self.graphics.resize(&self.device,size,fov); + pub fn resize(&mut self,device:&wgpu::Device,size:glam::UVec2,fov:glam::Vec2){ + self.graphics.resize(device,size,fov); } - pub fn render(&mut self,surface:&wgpu::Surface<'_>,pos:glam::Vec3,angles:glam::Vec2){ - //this has to go deeper somehow - let frame=match surface.get_current_texture(){ - Ok(frame)=>frame, - Err(_)=>{ - surface.configure(&self.device,&self.config); - surface - .get_current_texture() - .expect("Failed to acquire next surface texture!") - } - }; - let view=frame.texture.create_view(&wgpu::TextureViewDescriptor{ - format:Some(self.config.view_formats[0]), - ..wgpu::TextureViewDescriptor::default() - }); - - let mut encoder=self.device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None}); - - self.graphics.encode_commands(&mut encoder,&view,strafesnet_graphics::graphics::view_inv(pos+self.start_offset,angles)); - - self.queue.submit([encoder.finish()]); - - frame.present(); + pub fn encode_commands(&mut self,encoder:&mut wgpu::CommandEncoder,view:&wgpu::TextureView,pos:glam::Vec3,angles:glam::Vec2){ + self.graphics.encode_commands(encoder,view,strafesnet_graphics::graphics::view_inv(pos+self.start_offset,angles)); } } diff --git a/lib/src/lib.rs b/lib/src/lib.rs index a8ac694..35cf582 100644 --- a/lib/src/lib.rs +++ b/lib/src/lib.rs @@ -2,14 +2,4 @@ pub mod bot; pub mod head; pub mod time; pub mod state; -// pub mod surface; pub mod graphics; - -// Create Surface -// Create Graphics from map file and with surface as sample -// Create bot from bot file -// Create playback head -// loop{ -// advance head -// render frame -// } diff --git a/lib/src/surface.rs b/lib/src/surface.rs deleted file mode 100644 index b55cef1..0000000 --- a/lib/src/surface.rs +++ /dev/null @@ -1,2 +0,0 @@ -/// A render surface configuration, containing information such as resolution and pixel format -pub struct Surface{} diff --git a/native-player/src/player.rs b/native-player/src/player.rs index 28d8574..f1027de 100644 --- a/native-player/src/player.rs +++ b/native-player/src/player.rs @@ -2,6 +2,7 @@ use strafesnet_common::instruction::TimedInstruction; use strafesnet_common::session::Time as SessionTime; use strafesnet_common::timer::TimerState; use strafesnet_roblox_bot_player::{bot::CompleteBot,graphics::Graphics,head::{PlaybackHead,Time as PlaybackTime}}; +use strafesnet_graphics::surface::Surface; pub enum SessionControlInstruction{ SetPaused(bool), @@ -35,22 +36,22 @@ struct Playback{ } pub struct PlayerWorker<'a>{ - surface:wgpu::Surface<'a>, graphics_thread:Graphics, + surface:Surface<'a>, playback:Option, } impl<'a> PlayerWorker<'a>{ pub fn new( - surface:wgpu::Surface<'a>, graphics_thread:Graphics, + surface:Surface<'a>, )->Self{ Self{ - surface, graphics_thread, + surface, playback:None, } } - pub fn send(&mut self,ins:TimedInstruction){ + pub fn send(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,ins:TimedInstruction){ match ins.instruction{ Instruction::SessionControl(SessionControlInstruction::SetPaused(paused))=>if let Some(playback)=&mut self.playback{ playback.playback_head.set_paused(ins.time,paused); @@ -77,15 +78,28 @@ impl<'a> PlayerWorker<'a>{ Instruction::Render=>if let Some(playback)=&mut self.playback{ playback.playback_head.advance_time(&playback.bot,ins.time); let (pos,angles)=playback.playback_head.get_position_angles(&playback.bot,ins.time); - self.graphics_thread.render(&self.surface,pos,angles); + + //this has to go deeper somehow + let frame=self.surface.new_frame(device); + + let mut encoder=device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None}); + + self.graphics_thread.encode_commands(&mut encoder,frame.view(),pos,angles); + + queue.submit([encoder.finish()]); + + frame.present(); }, Instruction::Resize(physical_size)=>if let Some(playback)=&self.playback{ let fov_y=playback.playback_head.state().get_fov_y(); let fov_x=fov_y*physical_size.width as f64/physical_size.height as f64; - self.graphics_thread.resize(&self.surface,glam::uvec2(physical_size.width,physical_size.height),glam::vec2(fov_x as f32,fov_y as f32)); + let fov=glam::vec2(fov_x as f32,fov_y as f32); + let size=glam::uvec2(physical_size.width,physical_size.height); + self.surface.configure(device,size); + self.graphics_thread.resize(device,size,fov); }, Instruction::ChangeMap(complete_map)=>{ - self.graphics_thread.change_map(&complete_map); + self.graphics_thread.change_map(device,queue,&complete_map); }, Instruction::LoadReplay(bot)=>{ let bot=CompleteBot::new(bot); diff --git a/native-player/src/setup.rs b/native-player/src/setup.rs index 584fc49..5e36738 100644 --- a/native-player/src/setup.rs +++ b/native-player/src/setup.rs @@ -22,7 +22,7 @@ pub async fn setup_and_start(title:&str){ let (device,queue)=setup::step4::request_device(&adapter).await.unwrap(); let size=window.inner_size(); - let config=setup::step5::configure_surface(&adapter,&device,&surface,(size.width,size.height)).unwrap(); + let surface=setup::step5::configure_surface(&adapter,&device,surface,(size.width,size.height)).unwrap(); //dedicated thread to ping request redraw back and resize the window doesn't seem logical @@ -32,7 +32,6 @@ pub async fn setup_and_start(title:&str){ device, queue, surface, - config, ); for arg in std::env::args().skip(1){ diff --git a/native-player/src/window.rs b/native-player/src/window.rs index 87ff5a1..1c7db8c 100644 --- a/native-player/src/window.rs +++ b/native-player/src/window.rs @@ -13,15 +13,20 @@ pub struct WindowContext<'a>{ simulation_paused:bool, window:&'a winit::window::Window, physics_thread:PlayerWorker<'a>, + device:wgpu::Device, + queue:wgpu::Queue, } impl WindowContext<'_>{ + fn phys(&mut self,ins:TimedInstruction){ + self.physics_thread.send(&self.device,&self.queue,ins); + } fn window_event(&mut self,time:SessionTime,event:winit::event::WindowEvent){ match event{ winit::event::WindowEvent::DroppedFile(path)=>{ match crate::file::load(path.as_path()){ - Ok(LoadFormat::Map(map))=>self.physics_thread.send(TimedInstruction{time,instruction:PhysicsWorkerInstruction::ChangeMap(map)}), - Ok(LoadFormat::Bot(bot))=>self.physics_thread.send(TimedInstruction{time,instruction:PhysicsWorkerInstruction::LoadReplay(bot)}), + Ok(LoadFormat::Map(map))=>self.phys(TimedInstruction{time,instruction:PhysicsWorkerInstruction::ChangeMap(map)}), + Ok(LoadFormat::Bot(bot))=>self.phys(TimedInstruction{time,instruction:PhysicsWorkerInstruction::LoadReplay(bot)}), Err(e)=>println!("Failed to load file: {e}"), } }, @@ -31,7 +36,7 @@ impl WindowContext<'_>{ return; } //pause unpause - self.physics_thread.send(TimedInstruction{ + self.phys(TimedInstruction{ time, instruction:PhysicsWorkerInstruction::SessionControl(SessionControlInstruction::SetPaused(!state)), }); @@ -74,7 +79,7 @@ impl WindowContext<'_>{ }, _=>None, }{ - self.physics_thread.send(TimedInstruction{ + self.phys(TimedInstruction{ time, instruction, }); @@ -83,7 +88,7 @@ impl WindowContext<'_>{ } }, winit::event::WindowEvent::Resized(size)=>{ - self.physics_thread.send( + self.phys( TimedInstruction{ time, instruction:PhysicsWorkerInstruction::Resize(size) @@ -92,7 +97,7 @@ impl WindowContext<'_>{ }, winit::event::WindowEvent::RedrawRequested=>{ self.window.request_redraw(); - self.physics_thread.send( + self.phys( TimedInstruction{ time, instruction:PhysicsWorkerInstruction::Render @@ -121,17 +126,19 @@ impl WindowContext<'_>{ window:&'a winit::window::Window, device:wgpu::Device, queue:wgpu::Queue, - surface:wgpu::Surface<'a>, - config:wgpu::SurfaceConfiguration, + surface:strafesnet_graphics::surface::Surface<'a>, )->WindowContext<'a>{ - let graphics=strafesnet_roblox_bot_player::graphics::Graphics::new(device,queue,config); + let size=surface.size(); + let graphics=strafesnet_roblox_bot_player::graphics::Graphics::new(&device,&queue,size,surface.view_format()); WindowContext{ simulation_paused:false, window, physics_thread:crate::player::PlayerWorker::new( - surface, graphics, + surface, ), + device, + queue, } } } diff --git a/wasm-module/src/lib.rs b/wasm-module/src/lib.rs index 886eca5..7a33d35 100644 --- a/wasm-module/src/lib.rs +++ b/wasm-module/src/lib.rs @@ -2,7 +2,7 @@ use wasm_bindgen::prelude::wasm_bindgen; use wasm_bindgen::JsError; use strafesnet_roblox_bot_file::v0; use strafesnet_roblox_bot_player::{bot,head,time,graphics}; -use strafesnet_graphics::setup; +use strafesnet_graphics::{setup,surface}; // Hack to keep the code compiling, // SurfaceTarget::Canvas is not available in IDE for whatever reason. @@ -22,11 +22,13 @@ impl From for wgpu::SurfaceTarget<'static>{ #[wasm_bindgen] pub struct Graphics{ graphics:graphics::Graphics, - surface:wgpu::Surface<'static>, + surface:surface::Surface<'static>, + device:wgpu::Device, + queue:wgpu::Queue, } #[wasm_bindgen] pub async fn setup_graphics(canvas:web_sys::HtmlCanvasElement)->Result{ - let size=(canvas.width(),canvas.height()); + let size=glam::uvec2(canvas.width(),canvas.height()); let instance_desc=wgpu::InstanceDescriptor::from_env_or_default(); let instance=wgpu::util::new_instance_with_webgpu_detection(&instance_desc).await; @@ -37,10 +39,12 @@ pub async fn setup_graphics(canvas:web_sys::HtmlCanvasElement)->Result