From 96085a30769b8bca2a685adf40e1574850b1ac0d Mon Sep 17 00:00:00 2001 From: Quaternions Date: Wed, 7 Feb 2024 19:44:39 -0800 Subject: [PATCH] graphics rewrite (one error left) --- Cargo.lock | 3 +- Cargo.toml | 2 +- src/graphics.rs | 958 ++++++++++++++++++++--------------------- src/graphics_worker.rs | 2 +- src/model_graphics.rs | 47 +- src/model_physics.rs | 4 +- src/physics.rs | 4 +- src/physics_worker.rs | 2 +- 8 files changed, 493 insertions(+), 529 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8a1ce7a..2290748 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1304,9 +1304,10 @@ dependencies = [ [[package]] name = "strafesnet_common" version = "0.1.0" -source = "git+https://git.itzana.me/StrafesNET/common?rev=434ca29aef7e3015c9ca1ed45de8fef42e33fdfb#434ca29aef7e3015c9ca1ed45de8fef42e33fdfb" +source = "git+https://git.itzana.me/StrafesNET/common?rev=a1fa2c278174dabbb56db1d814340611dab67575#a1fa2c278174dabbb56db1d814340611dab67575" dependencies = [ "glam", + "id", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 56aba65..ab006d7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ glam = "0.25.0" id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" } parking_lot = "0.12.1" pollster = "0.3.0" -strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "434ca29aef7e3015c9ca1ed45de8fef42e33fdfb" } +strafesnet_common = { git = "https://git.itzana.me/StrafesNET/common", rev = "a1fa2c278174dabbb56db1d814340611dab67575" } strafesnet_snf = { git = "https://git.itzana.me/StrafesNET/snf", rev = "dea408daeef576cff8ffa61356c89a9d03d95f6b" } wgpu = "0.19.0" winit = "0.29.2" diff --git a/src/graphics.rs b/src/graphics.rs index 0762f41..1e82523 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -1,9 +1,10 @@ use std::borrow::Cow; +use std::collections::{HashSet,HashMap}; use strafesnet_common::map; use strafesnet_common::integer; -use strafesnet_common::model::{self,ColorId,NormalId,PositionId,TextureCoordinateId,VertexId}; +use strafesnet_common::model::{self, ColorId, MapVertexId, NormalId, PolygonIter, PositionId, RenderConfigId, TextureCoordinateId, VertexId}; use wgpu::{util::DeviceExt,AstcBlock,AstcChannel}; -use crate::model_graphics::{GraphicsVertex,GraphicsModelColor4,GraphicsModelInstance,GraphicsModelSingleTexture,IndexedGraphicsModelSingleTexture,IndexedGroupFixedTexture}; +use crate::model_graphics::{self,IndexedGraphicsMeshOwnedRenderConfig,IndexedGraphicsMeshOwnedRenderConfigId,GraphicsMeshOwnedRenderConfig,GraphicsModelColor4,GraphicsModelOwned,GraphicsVertex}; #[derive(Clone)] pub struct GraphicsModelUpdate{ @@ -11,84 +12,83 @@ pub struct GraphicsModelUpdate{ color:Option, } -struct Entity{ - index_count:u32, - index_buf:wgpu::Buffer, +struct Indices{ + count:u32, + buf:wgpu::Buffer, + format:wgpu::IndexFormat, } -fn create_entities(device:&wgpu::Device,entities:&Vec>)->Vec{ - entities.iter().map(|indices|{ - let index_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{ - label:Some("Index"), - contents:bytemuck::cast_slice(indices), - usage:wgpu::BufferUsages::INDEX, - }); - Entity{ - index_buf, - index_count:indices.len() as u32, +impl Indices{ + fn new(device:&wgpu::Device,indices:&Vec,format:wgpu::IndexFormat)->Self{ + Self{ + buf:device.create_buffer_init(&wgpu::util::BufferInitDescriptor{ + label:Some("Index"), + contents:bytemuck::cast_slice(indices), + usage:wgpu::BufferUsages::INDEX, + }), + count:indices.len() as u32, + format, } - }).collect() + } } - struct GraphicsModel{ - entities:Vec, + indices:Indices, model_buf:wgpu::Buffer, vertex_buf:wgpu::Buffer, bind_group:wgpu::BindGroup, - index_format:wgpu::IndexFormat, - instances:Vec, + instance_count:u32, } -pub struct GraphicsSamplers{ - repeat: wgpu::Sampler, +struct GraphicsSamplers{ + repeat:wgpu::Sampler, } -pub struct GraphicsBindGroupLayouts{ - model: wgpu::BindGroupLayout, +struct GraphicsBindGroupLayouts{ + model:wgpu::BindGroupLayout, } -pub struct GraphicsBindGroups { - camera: wgpu::BindGroup, - skybox_texture: wgpu::BindGroup, +struct GraphicsBindGroups{ + camera:wgpu::BindGroup, + skybox_texture:wgpu::BindGroup, } -pub struct GraphicsPipelines{ - skybox: wgpu::RenderPipeline, - model: wgpu::RenderPipeline, +struct GraphicsPipelines{ + skybox:wgpu::RenderPipeline, + model:wgpu::RenderPipeline, } -pub struct GraphicsCamera{ - screen_size: glam::UVec2, - fov: glam::Vec2,//slope +struct GraphicsCamera{ + screen_size:glam::UVec2, + fov:glam::Vec2,//slope //camera angles and such are extrapolated and passed in every time } #[inline] -fn perspective_rh(fov_x_slope: f32, fov_y_slope: f32, z_near: f32, z_far: f32) -> glam::Mat4 { +fn perspective_rh(fov_x_slope:f32,fov_y_slope:f32,z_near:f32,z_far:f32)->glam::Mat4{ //glam_assert!(z_near > 0.0 && z_far > 0.0); - let r = z_far / (z_near - z_far); + let r=z_far / (z_near-z_far); glam::Mat4::from_cols( - glam::Vec4::new(1.0/fov_x_slope, 0.0, 0.0, 0.0), - glam::Vec4::new(0.0, 1.0/fov_y_slope, 0.0, 0.0), - glam::Vec4::new(0.0, 0.0, r, -1.0), - glam::Vec4::new(0.0, 0.0, r * z_near, 0.0), + glam::Vec4::new(1.0/fov_x_slope,0.0,0.0,0.0), + glam::Vec4::new(0.0,1.0/fov_y_slope,0.0,0.0), + glam::Vec4::new(0.0,0.0,r,-1.0), + glam::Vec4::new(0.0,0.0,r * z_near,0.0), ) } impl GraphicsCamera{ pub fn proj(&self)->glam::Mat4{ - perspective_rh(self.fov.x, self.fov.y, 0.5, 2000.0) + perspective_rh(self.fov.x,self.fov.y,0.5,2000.0) } pub fn world(&self,pos:glam::Vec3,angles:glam::Vec2)->glam::Mat4{ //f32 good enough for view matrix - glam::Mat4::from_translation(pos) * glam::Mat4::from_euler(glam::EulerRot::YXZ, angles.x, angles.y, 0f32) + glam::Mat4::from_translation(pos) * glam::Mat4::from_euler(glam::EulerRot::YXZ,angles.x,angles.y,0f32) } - pub fn to_uniform_data(&self,(pos,angles): (glam::Vec3,glam::Vec2)) -> [f32; 16 * 4] { + pub fn to_uniform_data(&self,(pos,angles):(glam::Vec3,glam::Vec2))->[f32; 16 * 4]{ let proj=self.proj(); - let proj_inv = proj.inverse(); + let proj_inv=proj.inverse(); let view_inv=self.world(pos,angles); let view=view_inv.inverse(); - let mut raw = [0f32; 16 * 4]; + let mut raw=[0f32; 16 * 4]; raw[..16].copy_from_slice(&AsRef::<[f32; 16]>::as_ref(&proj)[..]); raw[16..32].copy_from_slice(&AsRef::<[f32; 16]>::as_ref(&proj_inv)[..]); raw[32..48].copy_from_slice(&AsRef::<[f32; 16]>::as_ref(&view)[..]); @@ -106,37 +106,37 @@ impl std::default::Default for GraphicsCamera{ } pub struct GraphicsState{ - pipelines: GraphicsPipelines, - bind_groups: GraphicsBindGroups, - bind_group_layouts: GraphicsBindGroupLayouts, - samplers: GraphicsSamplers, + pipelines:GraphicsPipelines, + bind_groups:GraphicsBindGroups, + bind_group_layouts:GraphicsBindGroupLayouts, + samplers:GraphicsSamplers, camera:GraphicsCamera, - camera_buf: wgpu::Buffer, - temp_squid_texture_view: wgpu::TextureView, - models: Vec, - depth_view: wgpu::TextureView, - staging_belt: wgpu::util::StagingBelt, + camera_buf:wgpu::Buffer, + temp_squid_texture_view:wgpu::TextureView, + models:Vec, + depth_view:wgpu::TextureView, + staging_belt:wgpu::util::StagingBelt, } impl GraphicsState{ - const DEPTH_FORMAT: wgpu::TextureFormat=wgpu::TextureFormat::Depth24Plus; + const DEPTH_FORMAT:wgpu::TextureFormat=wgpu::TextureFormat::Depth24Plus; fn create_depth_texture( - config: &wgpu::SurfaceConfiguration, - device: &wgpu::Device, - ) -> wgpu::TextureView { - let depth_texture=device.create_texture(&wgpu::TextureDescriptor { - size: wgpu::Extent3d { - width: config.width, - height: config.height, - depth_or_array_layers: 1, + config:&wgpu::SurfaceConfiguration, + device:&wgpu::Device, + )->wgpu::TextureView{ + let depth_texture=device.create_texture(&wgpu::TextureDescriptor{ + size:wgpu::Extent3d{ + width:config.width, + height:config.height, + depth_or_array_layers:1, }, - mip_level_count: 1, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: Self::DEPTH_FORMAT, - usage: wgpu::TextureUsages::RENDER_ATTACHMENT, - label: None, - view_formats: &[], + mip_level_count:1, + sample_count:1, + dimension:wgpu::TextureDimension::D2, + format:Self::DEPTH_FORMAT, + usage:wgpu::TextureUsages::RENDER_ATTACHMENT, + label:None, + view_formats:&[], }); depth_texture.create_view(&wgpu::TextureViewDescriptor::default()) @@ -147,148 +147,137 @@ impl GraphicsState{ pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){ self.camera.fov=user_settings.calculate_fov(1.0,&self.camera.screen_size).as_vec2(); } - pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::Map){ + pub fn generate_models(&mut self,device:&wgpu::Device,queue:&wgpu::Queue,map:&map::CompleteMap){ //generate texture view per texture - - //idk how to do this gooder lol - let mut double_map=std::collections::HashMap::::new(); - let mut texture_loading_threads=Vec::new(); let num_textures=map.textures.len(); - for (i,texture_id) in map.textures.into_iter().enumerate(){ - let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_id)); - if let Ok(mut file) = std::fs::File::open(path.clone()){ - double_map.insert(i as u32, texture_loading_threads.len() as u32); - texture_loading_threads.push((texture_id,std::thread::spawn(move ||{ - ddsfile::Dds::read(&mut file).unwrap() - }))); - }else{ - //println!("missing texture path={:?}",path); - } - } - - let texture_views:Vec=texture_loading_threads.into_iter().map(|(texture_id,thread)|{ - let image=thread.join().unwrap(); + let texture_views:Vec=map.textures.into_iter().enumerate().map(|(texture_id,texture_data)|{ + let image=ddsfile::Dds::read(std::io::Cursor::new(texture_data)).unwrap(); let (mut width,mut height)=(image.get_width(),image.get_height()); let format=match image.header10.unwrap().dxgi_format{ - ddsfile::DxgiFormat::R8G8B8A8_UNorm_sRGB => wgpu::TextureFormat::Rgba8UnormSrgb, - ddsfile::DxgiFormat::BC7_UNorm_sRGB => { - //floor(w,4), should be ceil(w,4) + ddsfile::DxgiFormat::R8G8B8A8_UNorm_sRGB=>wgpu::TextureFormat::Rgba8UnormSrgb, + ddsfile::DxgiFormat::BC7_UNorm_sRGB =>{ + //floor(w,4),should be ceil(w,4) width=width/4*4; height=height/4*4; wgpu::TextureFormat::Bc7RgbaUnormSrgb }, - other=>panic!("unsupported format {:?}",other), + other=>panic!("unsupported format{:?}",other), }; - let size = wgpu::Extent3d { + let size=wgpu::Extent3d{ width, height, - depth_or_array_layers: 1, + depth_or_array_layers:1, }; - let layer_size = wgpu::Extent3d { - depth_or_array_layers: 1, + let layer_size=wgpu::Extent3d{ + depth_or_array_layers:1, ..size }; - let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2); + let max_mips=layer_size.max_mips(wgpu::TextureDimension::D2); - let texture = device.create_texture_with_data( + let texture=device.create_texture_with_data( queue, - &wgpu::TextureDescriptor { + &wgpu::TextureDescriptor{ size, - mip_level_count: max_mips, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, + mip_level_count:max_mips, + sample_count:1, + dimension:wgpu::TextureDimension::D2, format, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - label: Some(format!("Texture{}",texture_id).as_str()), - view_formats: &[], + usage:wgpu::TextureUsages::TEXTURE_BINDING|wgpu::TextureUsages::COPY_DST, + label:Some(format!("Texture{}",texture_id).as_str()), + view_formats:&[], }, wgpu::util::TextureDataOrder::LayerMajor, &image.data, ); - texture.create_view(&wgpu::TextureViewDescriptor { - label: Some(format!("Texture{} View",texture_id).as_str()), - dimension: Some(wgpu::TextureViewDimension::D2), + texture.create_view(&wgpu::TextureViewDescriptor{ + label:Some(format!("Texture{} View",texture_id).as_str()), + dimension:Some(wgpu::TextureViewDimension::D2), ..wgpu::TextureViewDescriptor::default() }) }).collect(); //split groups with different textures into separate models - //the models received here are supposed to be tightly packed, i.e. no code needs to check if two models are using the same groups. + //the models received here are supposed to be tightly packed,i.e. no code needs to check if two models are using the same groups. let indexed_models_len=map.models.len(); + //models split into graphics_group.RenderConfigId + let mut map_map:HashMap>=HashMap::new(); + let mut map_unique_textures=HashMap::new(); let mut unique_texture_models=Vec::with_capacity(indexed_models_len); - for model in map.models.into_iter(){ - //convert ModelInstance into GraphicsModelInstance - let instances:Vec=model.instances.into_iter().filter_map(|instance|{ - if instance.color.w==0.0{ - None - }else{ - Some(GraphicsModelInstance{ - transform: instance.transform.into(), - normal_transform: Into::::into(instance.transform.matrix3).inverse().transpose(), - color:GraphicsModelColor4::from(instance.color), - }) - } - }).collect(); - //skip pushing a model if all instances are invisible - if instances.len()==0{ - continue; - } + for model in &map.models{ + //wow + let instance=GraphicsModelOwned{ + transform:model.transform.into(), + normal_transform:Into::::into(model.transform.matrix3).inverse().transpose(), + color:GraphicsModelColor4::new(model.color), + }; + //convert Model into GraphicsModelOwned //check each group, if it's using a new texture then make a new clone of the model let id=unique_texture_models.len(); let mut unique_textures=Vec::new(); - for group in model.groups.into_iter(){ - //ignore zero copy optimization for now - let texture_index=if let Some(texture_index)=unique_textures.iter().position(|&texture|texture==group.texture){ - texture_index - }else{ - //create new texture_index - let texture_index=unique_textures.len(); - unique_textures.push(group.texture); - unique_texture_models.push(IndexedGraphicsModelSingleTexture{ - unique_pos:model.unique_pos.iter().map(|&v|*Into::::into(v).as_ref()).collect(), - unique_tex:model.unique_tex.iter().map(|v|*v.as_ref()).collect(), - unique_normal:model.unique_normal.iter().map(|&v|*Into::::into(v).as_ref()).collect(), - unique_color:model.unique_color.iter().map(|v|*v.as_ref()).collect(), - unique_vertices:model.unique_vertices.clone(), - texture:group.texture, - groups:Vec::new(), - instances:instances.clone(), - }); - texture_index - }; - unique_texture_models[id+texture_index].groups.push(IndexedGroupFixedTexture{ - polys:group.polys, - }); + if let Some(mesh)=map.meshes.get(model.mesh.get() as usize){ + for graphics_group in mesh.graphics_groups.iter(){ + let render_config=map.render_configs[graphics_group.render.get() as usize]; + if model.color.w==0.0&&render_config.texture.is_none(){ + continue; + } + //ignore zero copy optimization for now + let texture_index=if let Some(texture_index)=unique_textures.iter().position(|&texture|texture==render_config.texture){ + texture_index + }else{ + //create new texture_index + let texture_index=unique_textures.len(); + unique_textures.push(render_config.texture); + unique_texture_models.push(IndexedGraphicsMeshOwnedRenderConfig{ + unique_pos:mesh.unique_pos.iter().map(|&v|*Into::::into(v).as_ref()).collect(), + unique_tex:mesh.unique_tex.iter().map(|v|*v.as_ref()).collect(), + unique_normal:mesh.unique_normal.iter().map(|&v|*Into::::into(v).as_ref()).collect(), + unique_color:mesh.unique_color.iter().map(|v|*v.as_ref()).collect(), + unique_vertices:mesh.unique_vertices.clone(), + render_config:graphics_group.render, + polys:model::PolygonGroup::PolygonList(model::PolygonList::new( + graphics_group.groups.iter().flat_map(|polygon_group_id|{ + mesh.polygon_groups[polygon_group_id.get() as usize].polys() + }) + .map(|vertex_id_slice| + vertex_id_slice.iter().copied().collect() + ).collect() + )), + instances:Vec::new(), + }); + texture_index + }; + unique_texture_models[utm_id.get() as usize].instances.push(instance); + } } } - //check every model to see if it's using the same (texture,color) but has few instances, if it is combine it into one model - //1. collect unique instances of texture and color, note model id - //2. for each model id, check if removing it from the pool decreases both the model count and instance count by more than one + //check every model to see if it's using the same (texture,color) but has few instances,if it is combine it into one model + //1. collect unique instances of texture and color,note model id + //2. for each model id,check if removing it from the pool decreases both the model count and instance count by more than one //3. transpose all models that stay in the set - //best plan: benchmark set_bind_group, set_vertex_buffer, set_index_buffer and draw_indexed + //best plan:benchmark set_bind_group,set_vertex_buffer,set_index_buffer and draw_indexed //check if the estimated render performance is better by transposing multiple model instances into one model instance - //for now: just deduplicate single models... + //for now:just deduplicate single models... let mut deduplicated_models=Vec::with_capacity(indexed_models_len);//use indexed_models_len because the list will likely get smaller instead of bigger - let mut unique_texture_color=std::collections::HashMap::new();//texture->color->vec![(model_id,instance_id)] + let mut unique_texture_color=HashMap::new();//texture->color->vec![(model_id,instance_id)] for (model_id,model) in unique_texture_models.iter().enumerate(){ - //for now: filter out models with more than one instance + //for now:filter out models with more than one instance if 1=deduplicated_models.into_iter().map(|model|{ - let mut vertices = Vec::new(); - let mut index_from_vertex = std::collections::HashMap::new();//:: + let models:Vec=deduplicated_models.into_iter().map(|model|{ + let mut vertices=Vec::new(); + let mut index_from_vertex=HashMap::new();//:: //this mut be combined in a more complex way if the models use different render patterns per group - let mut indices = Vec::new(); - for group in model.groups { - for poly in group.polys { - for end_index in 2..poly.vertices.len() { - for &index in &[0, end_index - 1, end_index] { - let vertex_index = poly.vertices[index]; - if let Some(&i)=index_from_vertex.get(&vertex_index){ - indices.push(i); - }else{ - let i=vertices.len(); - let vertex=&model.unique_vertices[vertex_index.get() as usize]; - vertices.push(GraphicsVertex{ - pos: model.unique_pos[vertex.pos.get() as usize], - tex: model.unique_tex[vertex.tex.get() as usize], - normal: model.unique_normal[vertex.normal.get() as usize], - color:model.unique_color[vertex.color.get() as usize], - }); - index_from_vertex.insert(vertex_index,i); - indices.push(i); - } + let mut indices=Vec::new(); + for poly in model.polys.polys(){ + for end_index in 2..poly.len(){ + for index in [0,end_index-1,end_index]{ + let vertex_index=poly[index]; + if let Some(&i)=index_from_vertex.get(&vertex_index){ + indices.push(i); + }else{ + let i=vertices.len(); + let vertex=model.unique_vertices[vertex_index.get() as usize]; + vertices.push(GraphicsVertex{ + pos:model.unique_pos[vertex.pos.get() as usize], + tex:model.unique_tex[vertex.tex.get() as usize], + normal:model.unique_normal[vertex.normal.get() as usize], + color:model.unique_color[vertex.color.get() as usize], + }); + index_from_vertex.insert(vertex_index,i); + indices.push(i); } } } } - GraphicsModelSingleTexture{ + GraphicsMeshOwnedRenderConfig{ instances:model.instances, - entities:if (u32::MAX as usize){ - match double_map.get(&texture_id){ - Some(&mapped_texture_id)=>&texture_views[mapped_texture_id as usize], - None=>&self.temp_squid_texture_view, - } - }, + let render_config=map.render_configs[model.render_config.get() as usize]; + let texture_view=match render_config.texture{ + Some(texture_id)=>&texture_views[texture_id.get() as usize], None=>&self.temp_squid_texture_view, }; - let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &self.bind_group_layouts.model, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: model_buf.as_entire_binding(), + let bind_group=device.create_bind_group(&wgpu::BindGroupDescriptor{ + layout:&self.bind_group_layouts.model, + entries:&[ + wgpu::BindGroupEntry{ + binding:0, + resource:model_buf.as_entire_binding(), }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::TextureView(texture_view), + wgpu::BindGroupEntry{ + binding:1, + resource:wgpu::BindingResource::TextureView(texture_view), }, - wgpu::BindGroupEntry { - binding: 2, - resource: wgpu::BindingResource::Sampler(&self.samplers.repeat), + wgpu::BindGroupEntry{ + binding:2, + resource:wgpu::BindingResource::Sampler(&self.samplers.repeat), }, ], - label: Some(format!("Model{} Bind Group",model_count).as_str()), + label:Some(format!("Model{} Bind Group",model_count).as_str()), }); - let vertex_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Vertex"), - contents: bytemuck::cast_slice(&model.vertices), - usage: wgpu::BufferUsages::VERTEX, + let vertex_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{ + label:Some("Vertex"), + contents:bytemuck::cast_slice(&model.vertices), + usage:wgpu::BufferUsages::VERTEX, }); //all of these are being moved here self.models.push(GraphicsModel{ - instances:instances_chunk.to_vec(), + instance_count:instances_chunk.len() as u32, vertex_buf, - index_format:match &model.entities{ - crate::model_graphics::Entities::U32(_)=>wgpu::IndexFormat::Uint32, - crate::model_graphics::Entities::U16(_)=>wgpu::IndexFormat::Uint16, + indices:match &model.indices{ + model_graphics::Indices::U32(indices)=>Indices::new(device,indices,wgpu::IndexFormat::Uint32), + model_graphics::Indices::U16(indices)=>Indices::new(device,indices,wgpu::IndexFormat::Uint16), }, - entities:match &model.entities{ - crate::model_graphics::Entities::U32(entities)=>create_entities(device,entities), - crate::model_graphics::Entities::U16(entities)=>create_entities(device,entities), - }, - bind_group: model_bind_group, + bind_group, model_buf, }); } @@ -541,8 +518,8 @@ impl GraphicsState{ println!("Textures Loaded={}",texture_views.len()); println!("Indexed Models={}",indexed_models_len); println!("Deduplicated Models={}",deduplicated_models_len); - println!("Graphics Objects: {}",self.models.len()); - println!("Graphics Instances: {}",instance_count); + println!("Graphics Objects:{}",self.models.len()); + println!("Graphics Instances:{}",instance_count); } pub fn new( @@ -550,325 +527,325 @@ impl GraphicsState{ queue:&wgpu::Queue, config:&wgpu::SurfaceConfiguration, )->Self{ - let camera_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: None, - entries: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: None, + let camera_bind_group_layout=device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor{ + label:None, + entries:&[ + wgpu::BindGroupLayoutEntry{ + binding:0, + visibility:wgpu::ShaderStages::VERTEX, + ty:wgpu::BindingType::Buffer{ + ty:wgpu::BufferBindingType::Uniform, + has_dynamic_offset:false, + min_binding_size:None, }, - count: None, + count:None, }, ], }); - let skybox_texture_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some("Skybox Texture Bind Group Layout"), - entries: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - multisampled: false, - view_dimension: wgpu::TextureViewDimension::Cube, + let skybox_texture_bind_group_layout=device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor{ + label:Some("Skybox Texture Bind Group Layout"), + entries:&[ + wgpu::BindGroupLayoutEntry{ + binding:0, + visibility:wgpu::ShaderStages::FRAGMENT, + ty:wgpu::BindingType::Texture{ + sample_type:wgpu::TextureSampleType::Float{filterable:true}, + multisampled:false, + view_dimension:wgpu::TextureViewDimension::Cube, }, - count: None, + count:None, }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), - count: None, + wgpu::BindGroupLayoutEntry{ + binding:1, + visibility:wgpu::ShaderStages::FRAGMENT, + ty:wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count:None, }, ], }); - let model_bind_group_layout = device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor { - label: Some("Model Bind Group Layout"), - entries: &[ - wgpu::BindGroupLayoutEntry { - binding: 0, - visibility: wgpu::ShaderStages::VERTEX, - ty: wgpu::BindingType::Buffer { - ty: wgpu::BufferBindingType::Uniform, - has_dynamic_offset: false, - min_binding_size: None, + let model_bind_group_layout=device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor{ + label:Some("Model Bind Group Layout"), + entries:&[ + wgpu::BindGroupLayoutEntry{ + binding:0, + visibility:wgpu::ShaderStages::VERTEX, + ty:wgpu::BindingType::Buffer{ + ty:wgpu::BufferBindingType::Uniform, + has_dynamic_offset:false, + min_binding_size:None, }, - count: None, + count:None, }, - wgpu::BindGroupLayoutEntry { - binding: 1, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Texture { - sample_type: wgpu::TextureSampleType::Float { filterable: true }, - multisampled: false, - view_dimension: wgpu::TextureViewDimension::D2, + wgpu::BindGroupLayoutEntry{ + binding:1, + visibility:wgpu::ShaderStages::FRAGMENT, + ty:wgpu::BindingType::Texture{ + sample_type:wgpu::TextureSampleType::Float{filterable:true}, + multisampled:false, + view_dimension:wgpu::TextureViewDimension::D2, }, - count: None, + count:None, }, - wgpu::BindGroupLayoutEntry { - binding: 2, - visibility: wgpu::ShaderStages::FRAGMENT, - ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), - count: None, + wgpu::BindGroupLayoutEntry{ + binding:2, + visibility:wgpu::ShaderStages::FRAGMENT, + ty:wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering), + count:None, }, ], }); - let clamp_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("Clamp Sampler"), - address_mode_u: wgpu::AddressMode::ClampToEdge, - address_mode_v: wgpu::AddressMode::ClampToEdge, - address_mode_w: wgpu::AddressMode::ClampToEdge, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, + let clamp_sampler=device.create_sampler(&wgpu::SamplerDescriptor{ + label:Some("Clamp Sampler"), + address_mode_u:wgpu::AddressMode::ClampToEdge, + address_mode_v:wgpu::AddressMode::ClampToEdge, + address_mode_w:wgpu::AddressMode::ClampToEdge, + mag_filter:wgpu::FilterMode::Linear, + min_filter:wgpu::FilterMode::Linear, + mipmap_filter:wgpu::FilterMode::Linear, ..Default::default() }); - let repeat_sampler = device.create_sampler(&wgpu::SamplerDescriptor { - label: Some("Repeat Sampler"), - address_mode_u: wgpu::AddressMode::Repeat, - address_mode_v: wgpu::AddressMode::Repeat, - address_mode_w: wgpu::AddressMode::Repeat, - mag_filter: wgpu::FilterMode::Linear, - min_filter: wgpu::FilterMode::Linear, - mipmap_filter: wgpu::FilterMode::Linear, + let repeat_sampler=device.create_sampler(&wgpu::SamplerDescriptor{ + label:Some("Repeat Sampler"), + address_mode_u:wgpu::AddressMode::Repeat, + address_mode_v:wgpu::AddressMode::Repeat, + address_mode_w:wgpu::AddressMode::Repeat, + mag_filter:wgpu::FilterMode::Linear, + min_filter:wgpu::FilterMode::Linear, + mipmap_filter:wgpu::FilterMode::Linear, anisotropy_clamp:16, ..Default::default() }); // Create the render pipeline - let shader = device.create_shader_module(wgpu::ShaderModuleDescriptor { - label: None, - source: wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), + let shader=device.create_shader_module(wgpu::ShaderModuleDescriptor{ + label:None, + source:wgpu::ShaderSource::Wgsl(Cow::Borrowed(include_str!("shader.wgsl"))), }); //load textures - let device_features = device.features(); + let device_features=device.features(); let skybox_texture_view={ - let skybox_format = if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC) { + let skybox_format=if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_ASTC){ println!("Using ASTC"); - wgpu::TextureFormat::Astc { - block: AstcBlock::B4x4, - channel: AstcChannel::UnormSrgb, + wgpu::TextureFormat::Astc{ + block:AstcBlock::B4x4, + channel:AstcChannel::UnormSrgb, } - } else if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_ETC2) { + }else if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_ETC2){ println!("Using ETC2"); wgpu::TextureFormat::Etc2Rgb8UnormSrgb - } else if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC) { + }else if device_features.contains(wgpu::Features::TEXTURE_COMPRESSION_BC){ println!("Using BC"); wgpu::TextureFormat::Bc1RgbaUnormSrgb - } else { + }else{ println!("Using plain"); wgpu::TextureFormat::Bgra8UnormSrgb }; - let bytes = match skybox_format { - wgpu::TextureFormat::Astc { - block: AstcBlock::B4x4, - channel: AstcChannel::UnormSrgb, - } => &include_bytes!("../images/astc.dds")[..], - wgpu::TextureFormat::Etc2Rgb8UnormSrgb => &include_bytes!("../images/etc2.dds")[..], - wgpu::TextureFormat::Bc1RgbaUnormSrgb => &include_bytes!("../images/bc1.dds")[..], - wgpu::TextureFormat::Bgra8UnormSrgb => &include_bytes!("../images/bgra.dds")[..], - _ => unreachable!(), + let bytes=match skybox_format{ + wgpu::TextureFormat::Astc{ + block:AstcBlock::B4x4, + channel:AstcChannel::UnormSrgb, + }=>&include_bytes!("../images/astc.dds")[..], + wgpu::TextureFormat::Etc2Rgb8UnormSrgb=>&include_bytes!("../images/etc2.dds")[..], + wgpu::TextureFormat::Bc1RgbaUnormSrgb=>&include_bytes!("../images/bc1.dds")[..], + wgpu::TextureFormat::Bgra8UnormSrgb=>&include_bytes!("../images/bgra.dds")[..], + _=>unreachable!(), }; - let skybox_image = ddsfile::Dds::read(&mut std::io::Cursor::new(bytes)).unwrap(); + let skybox_image=ddsfile::Dds::read(&mut std::io::Cursor::new(bytes)).unwrap(); - let size = wgpu::Extent3d { - width: skybox_image.get_width(), - height: skybox_image.get_height(), - depth_or_array_layers: 6, + let size=wgpu::Extent3d{ + width:skybox_image.get_width(), + height:skybox_image.get_height(), + depth_or_array_layers:6, }; - let layer_size = wgpu::Extent3d { - depth_or_array_layers: 1, + let layer_size=wgpu::Extent3d{ + depth_or_array_layers:1, ..size }; - let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2); + let max_mips=layer_size.max_mips(wgpu::TextureDimension::D2); - let skybox_texture = device.create_texture_with_data( + let skybox_texture=device.create_texture_with_data( queue, - &wgpu::TextureDescriptor { + &wgpu::TextureDescriptor{ size, - mip_level_count: max_mips, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: skybox_format, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - label: Some("Skybox Texture"), - view_formats: &[], + mip_level_count:max_mips, + sample_count:1, + dimension:wgpu::TextureDimension::D2, + format:skybox_format, + usage:wgpu::TextureUsages::TEXTURE_BINDING|wgpu::TextureUsages::COPY_DST, + label:Some("Skybox Texture"), + view_formats:&[], }, wgpu::util::TextureDataOrder::LayerMajor, &skybox_image.data, ); - skybox_texture.create_view(&wgpu::TextureViewDescriptor { - label: Some("Skybox Texture View"), - dimension: Some(wgpu::TextureViewDimension::Cube), + skybox_texture.create_view(&wgpu::TextureViewDescriptor{ + label:Some("Skybox Texture View"), + dimension:Some(wgpu::TextureViewDimension::Cube), ..wgpu::TextureViewDescriptor::default() }) }; //squid let squid_texture_view={ - let bytes = include_bytes!("../images/squid.dds"); + let bytes=include_bytes!("../images/squid.dds"); - let image = ddsfile::Dds::read(&mut std::io::Cursor::new(bytes)).unwrap(); + let image=ddsfile::Dds::read(&mut std::io::Cursor::new(bytes)).unwrap(); - let size = wgpu::Extent3d { - width: image.get_width(), - height: image.get_height(), - depth_or_array_layers: 1, + let size=wgpu::Extent3d{ + width:image.get_width(), + height:image.get_height(), + depth_or_array_layers:1, }; - let layer_size = wgpu::Extent3d { - depth_or_array_layers: 1, + let layer_size=wgpu::Extent3d{ + depth_or_array_layers:1, ..size }; - let max_mips = layer_size.max_mips(wgpu::TextureDimension::D2); + let max_mips=layer_size.max_mips(wgpu::TextureDimension::D2); - let texture = device.create_texture_with_data( + let texture=device.create_texture_with_data( queue, - &wgpu::TextureDescriptor { + &wgpu::TextureDescriptor{ size, - mip_level_count: max_mips, - sample_count: 1, - dimension: wgpu::TextureDimension::D2, - format: wgpu::TextureFormat::Bc7RgbaUnorm, - usage: wgpu::TextureUsages::TEXTURE_BINDING | wgpu::TextureUsages::COPY_DST, - label: Some("Squid Texture"), - view_formats: &[], + mip_level_count:max_mips, + sample_count:1, + dimension:wgpu::TextureDimension::D2, + format:wgpu::TextureFormat::Bc7RgbaUnorm, + usage:wgpu::TextureUsages::TEXTURE_BINDING|wgpu::TextureUsages::COPY_DST, + label:Some("Squid Texture"), + view_formats:&[], }, wgpu::util::TextureDataOrder::LayerMajor, &image.data, ); - texture.create_view(&wgpu::TextureViewDescriptor { - label: Some("Squid Texture View"), - dimension: Some(wgpu::TextureViewDimension::D2), + texture.create_view(&wgpu::TextureViewDescriptor{ + label:Some("Squid Texture View"), + dimension:Some(wgpu::TextureViewDimension::D2), ..wgpu::TextureViewDescriptor::default() }) }; - let model_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[ + let model_pipeline_layout=device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor{ + label:None, + bind_group_layouts:&[ &camera_bind_group_layout, &skybox_texture_bind_group_layout, &model_bind_group_layout, ], - push_constant_ranges: &[], + push_constant_ranges:&[], }); - let sky_pipeline_layout = device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor { - label: None, - bind_group_layouts: &[ + let sky_pipeline_layout=device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor{ + label:None, + bind_group_layouts:&[ &camera_bind_group_layout, &skybox_texture_bind_group_layout, ], - push_constant_ranges: &[], + push_constant_ranges:&[], }); // Create the render pipelines - let sky_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Sky Pipeline"), - layout: Some(&sky_pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_sky", - buffers: &[], + let sky_pipeline=device.create_render_pipeline(&wgpu::RenderPipelineDescriptor{ + label:Some("Sky Pipeline"), + layout:Some(&sky_pipeline_layout), + vertex:wgpu::VertexState{ + module:&shader, + entry_point:"vs_sky", + buffers:&[], }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_sky", - targets: &[Some(config.view_formats[0].into())], + fragment:Some(wgpu::FragmentState{ + module:&shader, + entry_point:"fs_sky", + targets:&[Some(config.view_formats[0].into())], }), - primitive: wgpu::PrimitiveState { - front_face: wgpu::FrontFace::Cw, + primitive:wgpu::PrimitiveState{ + front_face:wgpu::FrontFace::Cw, ..Default::default() }, - depth_stencil: Some(wgpu::DepthStencilState { - format: Self::DEPTH_FORMAT, - depth_write_enabled: false, - depth_compare: wgpu::CompareFunction::LessEqual, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), + depth_stencil:Some(wgpu::DepthStencilState{ + format:Self::DEPTH_FORMAT, + depth_write_enabled:false, + depth_compare:wgpu::CompareFunction::LessEqual, + stencil:wgpu::StencilState::default(), + bias:wgpu::DepthBiasState::default(), }), - multisample: wgpu::MultisampleState::default(), - multiview: None, + multisample:wgpu::MultisampleState::default(), + multiview:None, }); - let model_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor { - label: Some("Model Pipeline"), - layout: Some(&model_pipeline_layout), - vertex: wgpu::VertexState { - module: &shader, - entry_point: "vs_entity_texture", - buffers: &[wgpu::VertexBufferLayout { - array_stride: std::mem::size_of::() as wgpu::BufferAddress, - step_mode: wgpu::VertexStepMode::Vertex, - attributes: &wgpu::vertex_attr_array![0 => Float32x3, 1 => Float32x2, 2 => Float32x3, 3 => Float32x4], + let model_pipeline=device.create_render_pipeline(&wgpu::RenderPipelineDescriptor{ + label:Some("Model Pipeline"), + layout:Some(&model_pipeline_layout), + vertex:wgpu::VertexState{ + module:&shader, + entry_point:"vs_entity_texture", + buffers:&[wgpu::VertexBufferLayout{ + array_stride:std::mem::size_of::() as wgpu::BufferAddress, + step_mode:wgpu::VertexStepMode::Vertex, + attributes:&wgpu::vertex_attr_array![0=>Float32x3,1=>Float32x2,2=>Float32x3,3=>Float32x4], }], }, - fragment: Some(wgpu::FragmentState { - module: &shader, - entry_point: "fs_entity_texture", - targets: &[Some(config.view_formats[0].into())], + fragment:Some(wgpu::FragmentState{ + module:&shader, + entry_point:"fs_entity_texture", + targets:&[Some(config.view_formats[0].into())], }), - primitive: wgpu::PrimitiveState { - front_face: wgpu::FrontFace::Cw, + primitive:wgpu::PrimitiveState{ + front_face:wgpu::FrontFace::Cw, cull_mode:Some(wgpu::Face::Front), ..Default::default() }, - depth_stencil: Some(wgpu::DepthStencilState { - format: Self::DEPTH_FORMAT, - depth_write_enabled: true, - depth_compare: wgpu::CompareFunction::LessEqual, - stencil: wgpu::StencilState::default(), - bias: wgpu::DepthBiasState::default(), + depth_stencil:Some(wgpu::DepthStencilState{ + format:Self::DEPTH_FORMAT, + depth_write_enabled:true, + depth_compare:wgpu::CompareFunction::LessEqual, + stencil:wgpu::StencilState::default(), + bias:wgpu::DepthBiasState::default(), }), - multisample: wgpu::MultisampleState::default(), - multiview: None, + multisample:wgpu::MultisampleState::default(), + multiview:None, }); let camera=GraphicsCamera::default(); - let camera_uniforms = camera.to_uniform_data(crate::physics::PhysicsOutputState::default().extrapolate(glam::IVec2::ZERO,integer::Time::ZERO)); - let camera_buf = device.create_buffer_init(&wgpu::util::BufferInitDescriptor { - label: Some("Camera"), - contents: bytemuck::cast_slice(&camera_uniforms), - usage: wgpu::BufferUsages::UNIFORM | wgpu::BufferUsages::COPY_DST, + let camera_uniforms=camera.to_uniform_data(crate::physics::PhysicsOutputState::default().extrapolate(glam::IVec2::ZERO,integer::Time::ZERO)); + let camera_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{ + label:Some("Camera"), + contents:bytemuck::cast_slice(&camera_uniforms), + usage:wgpu::BufferUsages::UNIFORM|wgpu::BufferUsages::COPY_DST, }); - let camera_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &camera_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: camera_buf.as_entire_binding(), + let camera_bind_group=device.create_bind_group(&wgpu::BindGroupDescriptor{ + layout:&camera_bind_group_layout, + entries:&[ + wgpu::BindGroupEntry{ + binding:0, + resource:camera_buf.as_entire_binding(), }, ], - label: Some("Camera"), + label:Some("Camera"), }); - let skybox_texture_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor { - layout: &skybox_texture_bind_group_layout, - entries: &[ - wgpu::BindGroupEntry { - binding: 0, - resource: wgpu::BindingResource::TextureView(&skybox_texture_view), + let skybox_texture_bind_group=device.create_bind_group(&wgpu::BindGroupDescriptor{ + layout:&skybox_texture_bind_group_layout, + entries:&[ + wgpu::BindGroupEntry{ + binding:0, + resource:wgpu::BindingResource::TextureView(&skybox_texture_view), }, - wgpu::BindGroupEntry { - binding: 1, - resource: wgpu::BindingResource::Sampler(&clamp_sampler), + wgpu::BindGroupEntry{ + binding:1, + resource:wgpu::BindingResource::Sampler(&clamp_sampler), }, ], - label: Some("Sky Texture"), + label:Some("Sky Texture"), }); - let depth_view = Self::create_depth_texture(config, device); + let depth_view=Self::create_depth_texture(config,device); Self{ pipelines:GraphicsPipelines{ @@ -881,12 +858,12 @@ impl GraphicsState{ }, camera, camera_buf, - models: Vec::new(), + models:Vec::new(), depth_view, - staging_belt: wgpu::util::StagingBelt::new(0x100), - bind_group_layouts: GraphicsBindGroupLayouts { model: model_bind_group_layout }, - samplers: GraphicsSamplers { repeat: repeat_sampler }, - temp_squid_texture_view: squid_texture_view, + staging_belt:wgpu::util::StagingBelt::new(0x100), + bind_group_layouts:GraphicsBindGroupLayouts{model:model_bind_group_layout}, + samplers:GraphicsSamplers{repeat:repeat_sampler}, + temp_squid_texture_view:squid_texture_view, } } pub fn resize( @@ -894,7 +871,7 @@ impl GraphicsState{ device:&wgpu::Device, config:&wgpu::SurfaceConfiguration, user_settings:&crate::settings::UserSettings, - ) { + ){ self.depth_view=Self::create_depth_texture(config,device); self.camera.screen_size=glam::uvec2(config.width,config.height); self.load_user_settings(user_settings); @@ -907,14 +884,13 @@ impl GraphicsState{ physics_output:crate::physics::PhysicsOutputState, predicted_time:integer::Time, mouse_pos:glam::IVec2, - ) { - //TODO: use scheduled frame times to create beautiful smoothing simulation physics extrapolation assuming no input + ){ + //TODO:use scheduled frame times to create beautiful smoothing simulation physics extrapolation assuming no input - let mut encoder = - device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None }); + let mut encoder=device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None}); // update rotation - let camera_uniforms = self.camera.to_uniform_data(physics_output.extrapolate(mouse_pos,predicted_time)); + let camera_uniforms=self.camera.to_uniform_data(physics_output.extrapolate(mouse_pos,predicted_time)); self.staging_belt .write_buffer( &mut encoder, @@ -926,8 +902,8 @@ impl GraphicsState{ .copy_from_slice(bytemuck::cast_slice(&camera_uniforms)); //This code only needs to run when the uniforms change /* - for model in self.models.iter() { - let model_uniforms = get_instances_buffer_data(&model.instances); + for model in self.models.iter(){ + let model_uniforms=get_instances_buffer_data(&model.instances); self.staging_belt .write_buffer( &mut encoder, @@ -942,49 +918,47 @@ impl GraphicsState{ self.staging_belt.finish(); { - let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor { - label: None, - color_attachments: &[Some(wgpu::RenderPassColorAttachment { + let mut rpass=encoder.begin_render_pass(&wgpu::RenderPassDescriptor{ + label:None, + color_attachments:&[Some(wgpu::RenderPassColorAttachment{ 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, + 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: Some(wgpu::RenderPassDepthStencilAttachment { - view: &self.depth_view, - depth_ops: Some(wgpu::Operations { - load: wgpu::LoadOp::Clear(1.0), + depth_stencil_attachment:Some(wgpu::RenderPassDepthStencilAttachment{ + view:&self.depth_view, + depth_ops:Some(wgpu::Operations{ + load:wgpu::LoadOp::Clear(1.0), store:wgpu::StoreOp::Discard, }), - stencil_ops: None, + stencil_ops:None, }), timestamp_writes:Default::default(), occlusion_query_set:Default::default(), }); - rpass.set_bind_group(0, &self.bind_groups.camera, &[]); - rpass.set_bind_group(1, &self.bind_groups.skybox_texture, &[]); + rpass.set_bind_group(0,&self.bind_groups.camera,&[]); + rpass.set_bind_group(1,&self.bind_groups.skybox_texture,&[]); rpass.set_pipeline(&self.pipelines.model); - for model in self.models.iter() { - rpass.set_bind_group(2, &model.bind_group, &[]); - rpass.set_vertex_buffer(0, model.vertex_buf.slice(..)); - - for entity in model.entities.iter(){ - rpass.set_index_buffer(entity.index_buf.slice(..),model.index_format); - rpass.draw_indexed(0..entity.index_count,0,0..model.instances.len() as u32); - } + for model in &self.models{ + rpass.set_bind_group(2,&model.bind_group,&[]); + rpass.set_vertex_buffer(0,model.vertex_buf.slice(..)); + rpass.set_index_buffer(model.indices.buf.slice(..),model.indices.format); + //TODO: loop over triangle strips + rpass.draw_indexed(0..model.indices.count,0,0..model.instance_count); } rpass.set_pipeline(&self.pipelines.skybox); - rpass.draw(0..3, 0..1); + rpass.draw(0..3,0..1); } queue.submit(std::iter::once(encoder.finish())); @@ -994,8 +968,8 @@ impl GraphicsState{ } const MODEL_BUFFER_SIZE:usize=4*4 + 12 + 4;//let size=std::mem::size_of::(); const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4; -fn get_instances_buffer_data(instances:&[GraphicsModelInstance]) -> Vec { - let mut raw = Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len()); +fn get_instances_buffer_data(instances:&[GraphicsModelOwned])->Vec{ + let mut raw=Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len()); for (i,mi) in instances.iter().enumerate(){ //model transform raw.extend_from_slice(&AsRef::<[f32; 4*4]>::as_ref(&mi.transform)[..]); diff --git a/src/graphics_worker.rs b/src/graphics_worker.rs index fdb1d74..b8fad9a 100644 --- a/src/graphics_worker.rs +++ b/src/graphics_worker.rs @@ -4,7 +4,7 @@ pub enum Instruction{ Render(crate::physics::PhysicsOutputState,integer::Time,glam::IVec2), //UpdateModel(crate::graphics::GraphicsModelUpdate), Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), - GenerateModels(strafesnet_common::map::Map), + GenerateModels(strafesnet_common::map::CompleteMap), ClearModels, } diff --git a/src/model_graphics.rs b/src/model_graphics.rs index 89200cd..1ad70df 100644 --- a/src/model_graphics.rs +++ b/src/model_graphics.rs @@ -1,5 +1,5 @@ -use bytemuck::{Pod, Zeroable}; -use strafesnet_common::model::{IndexedVertex,PolygonGroup}; +use bytemuck::{Pod,Zeroable}; +use strafesnet_common::model::{IndexedVertex,PolygonGroup,RenderConfigId,TextureId}; #[derive(Clone,Copy,Pod,Zeroable)] #[repr(C)] pub struct GraphicsVertex{ @@ -8,43 +8,32 @@ pub struct GraphicsVertex{ pub normal:[f32;3], pub color:[f32;4], } -pub struct IndexedGroupFixedTexture{ - pub polys:Vec, -} -pub struct IndexedGraphicsModelSingleTexture{ +#[derive(id::Id)] +pub struct IndexedGraphicsMeshOwnedRenderConfigId(u32); +pub struct IndexedGraphicsMeshOwnedRenderConfig{ pub unique_pos:Vec<[f32;3]>, pub unique_tex:Vec<[f32;2]>, pub unique_normal:Vec<[f32;3]>, pub unique_color:Vec<[f32;4]>, pub unique_vertices:Vec, - pub texture:Option,//RenderPattern? material/texture/shader/flat color - pub groups:Vec, - pub instances:Vec, + pub render_config:RenderConfigId, + pub polys:PolygonGroup, + pub instances:Vec, } -pub enum Entities{ - U32(Vec>), - U16(Vec>), +pub enum Indices{ + U32(Vec), + U16(Vec), } -pub struct GraphicsModelSingleTexture{ - pub instances:Vec, +pub struct GraphicsMeshOwnedRenderConfig{ pub vertices:Vec, - pub entities:Entities, - pub texture:Option, + pub indices:Indices, + pub render_config:RenderConfigId, + pub instances:Vec, } -#[derive(Clone,PartialEq)] +#[derive(Clone,PartialEq,id::Id)] pub struct GraphicsModelColor4(glam::Vec4); -impl GraphicsModelColor4{ - pub const fn get(&self)->glam::Vec4{ - self.0 - } -} -impl From for GraphicsModelColor4{ - fn from(value:glam::Vec4)->Self{ - Self(value) - } -} impl std::hash::Hash for GraphicsModelColor4{ - fn hash(&self,state:&mut H) { + fn hash(&self,state:&mut H) { for &f in self.0.as_ref(){ bytemuck::cast::(f).hash(state); } @@ -52,7 +41,7 @@ impl std::hash::Hash for GraphicsModelColor4{ } impl Eq for GraphicsModelColor4{} #[derive(Clone)] -pub struct GraphicsModelInstance{ +pub struct GraphicsModelOwned{ pub transform:glam::Mat4, pub normal_transform:glam::Mat3, pub color:GraphicsModelColor4, diff --git a/src/model_physics.rs b/src/model_physics.rs index 53cebbc..5a47fec 100644 --- a/src/model_physics.rs +++ b/src/model_physics.rs @@ -261,8 +261,8 @@ impl EdgePool{ (&mut unsafe{self.edge_guys.get_unchecked_mut(edge_id)}.1,SubmeshEdgeId::new(edge_id as u32)) } } -impl From<&model::IndexedModel> for PhysicsMesh{ - fn from(indexed_model:&model::IndexedModel)->Self{ +impl From<&model::Mesh> for PhysicsMesh{ + fn from(indexed_model:&model::Mesh)->Self{ assert!(indexed_model.unique_pos.len()!=0,"Mesh cannot have 0 vertices"); let verts=indexed_model.unique_pos.iter().map(|v|Vert(v.clone())).collect(); let mut vert_ref_guys=vec![VertRefGuy::default();indexed_model.unique_pos.len()]; diff --git a/src/physics.rs b/src/physics.rs index 37871f5..93b8d91 100644 --- a/src/physics.rs +++ b/src/physics.rs @@ -925,11 +925,11 @@ impl PhysicsContext{ }); } - pub fn generate_models(&mut self,map:&map::Map){ + pub fn generate_models(&mut self,map:&map::CompleteMap){ let mut starts=Vec::new(); let mut spawns=Vec::new(); let mut attr_hash=HashMap::new(); - for (&model_id,model) in &map.models{ + for model in &map.models{ let mesh_id=self.data.models.meshes.len(); let mut make_mesh=false; for model_instance in &model.instances{ diff --git a/src/physics_worker.rs b/src/physics_worker.rs index ae558bb..c716999 100644 --- a/src/physics_worker.rs +++ b/src/physics_worker.rs @@ -18,7 +18,7 @@ pub enum Instruction{ Input(InputInstruction), Render, Resize(winit::dpi::PhysicalSize,crate::settings::UserSettings), - GenerateModels(strafesnet_common::map::Map), + GenerateModels(strafesnet_common::map::CompleteMap), ClearModels, //Graphics(crate::graphics_worker::Instruction), }