forked from StrafesNET/strafe-client
graphics rewrite (one error left)
This commit is contained in:
parent
2049e2dd2c
commit
96085a3076
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -1304,9 +1304,10 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "strafesnet_common"
|
name = "strafesnet_common"
|
||||||
version = "0.1.0"
|
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 = [
|
dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
|
"id",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -13,7 +13,7 @@ glam = "0.25.0"
|
|||||||
id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" }
|
id = { git = "https://git.itzana.me/Quaternions/id", rev = "1f710976cc786c8853dab73d6e1cee53158deeb0" }
|
||||||
parking_lot = "0.12.1"
|
parking_lot = "0.12.1"
|
||||||
pollster = "0.3.0"
|
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" }
|
strafesnet_snf = { git = "https://git.itzana.me/StrafesNET/snf", rev = "dea408daeef576cff8ffa61356c89a9d03d95f6b" }
|
||||||
wgpu = "0.19.0"
|
wgpu = "0.19.0"
|
||||||
winit = "0.29.2"
|
winit = "0.29.2"
|
||||||
|
246
src/graphics.rs
246
src/graphics.rs
@ -1,9 +1,10 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::collections::{HashSet,HashMap};
|
||||||
use strafesnet_common::map;
|
use strafesnet_common::map;
|
||||||
use strafesnet_common::integer;
|
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 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)]
|
#[derive(Clone)]
|
||||||
pub struct GraphicsModelUpdate{
|
pub struct GraphicsModelUpdate{
|
||||||
@ -11,52 +12,51 @@ pub struct GraphicsModelUpdate{
|
|||||||
color:Option<glam::Vec4>,
|
color:Option<glam::Vec4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Entity{
|
struct Indices{
|
||||||
index_count:u32,
|
count:u32,
|
||||||
index_buf:wgpu::Buffer,
|
buf:wgpu::Buffer,
|
||||||
|
format:wgpu::IndexFormat,
|
||||||
}
|
}
|
||||||
fn create_entities<T:bytemuck::Pod>(device:&wgpu::Device,entities:&Vec<Vec<T>>)->Vec<Entity>{
|
impl Indices{
|
||||||
entities.iter().map(|indices|{
|
fn new<T:bytemuck::Pod>(device:&wgpu::Device,indices:&Vec<T>,format:wgpu::IndexFormat)->Self{
|
||||||
let index_buf=device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
Self{
|
||||||
|
buf:device.create_buffer_init(&wgpu::util::BufferInitDescriptor{
|
||||||
label:Some("Index"),
|
label:Some("Index"),
|
||||||
contents:bytemuck::cast_slice(indices),
|
contents:bytemuck::cast_slice(indices),
|
||||||
usage:wgpu::BufferUsages::INDEX,
|
usage:wgpu::BufferUsages::INDEX,
|
||||||
});
|
}),
|
||||||
Entity{
|
count:indices.len() as u32,
|
||||||
index_buf,
|
format,
|
||||||
index_count:indices.len() as u32,
|
}
|
||||||
}
|
}
|
||||||
}).collect()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct GraphicsModel{
|
struct GraphicsModel{
|
||||||
entities:Vec<Entity>,
|
indices:Indices,
|
||||||
model_buf:wgpu::Buffer,
|
model_buf:wgpu::Buffer,
|
||||||
vertex_buf:wgpu::Buffer,
|
vertex_buf:wgpu::Buffer,
|
||||||
bind_group:wgpu::BindGroup,
|
bind_group:wgpu::BindGroup,
|
||||||
index_format:wgpu::IndexFormat,
|
instance_count:u32,
|
||||||
instances:Vec<GraphicsModelInstance>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphicsSamplers{
|
struct GraphicsSamplers{
|
||||||
repeat:wgpu::Sampler,
|
repeat:wgpu::Sampler,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphicsBindGroupLayouts{
|
struct GraphicsBindGroupLayouts{
|
||||||
model:wgpu::BindGroupLayout,
|
model:wgpu::BindGroupLayout,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphicsBindGroups {
|
struct GraphicsBindGroups{
|
||||||
camera:wgpu::BindGroup,
|
camera:wgpu::BindGroup,
|
||||||
skybox_texture:wgpu::BindGroup,
|
skybox_texture:wgpu::BindGroup,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphicsPipelines{
|
struct GraphicsPipelines{
|
||||||
skybox:wgpu::RenderPipeline,
|
skybox:wgpu::RenderPipeline,
|
||||||
model:wgpu::RenderPipeline,
|
model:wgpu::RenderPipeline,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GraphicsCamera{
|
struct GraphicsCamera{
|
||||||
screen_size:glam::UVec2,
|
screen_size:glam::UVec2,
|
||||||
fov:glam::Vec2,//slope
|
fov:glam::Vec2,//slope
|
||||||
//camera angles and such are extrapolated and passed in every time
|
//camera angles and such are extrapolated and passed in every time
|
||||||
@ -147,27 +147,11 @@ impl GraphicsState{
|
|||||||
pub fn load_user_settings(&mut self,user_settings:&crate::settings::UserSettings){
|
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();
|
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
|
//generate texture view per texture
|
||||||
|
|
||||||
//idk how to do this gooder lol
|
|
||||||
let mut double_map=std::collections::HashMap::<u32,u32>::new();
|
|
||||||
let mut texture_loading_threads=Vec::new();
|
|
||||||
let num_textures=map.textures.len();
|
let num_textures=map.textures.len();
|
||||||
for (i,texture_id) in map.textures.into_iter().enumerate(){
|
let texture_views:Vec<wgpu::TextureView>=map.textures.into_iter().enumerate().map(|(texture_id,texture_data)|{
|
||||||
let path=std::path::PathBuf::from(format!("textures/{}.dds",texture_id));
|
let image=ddsfile::Dds::read(std::io::Cursor::new(texture_data)).unwrap();
|
||||||
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<wgpu::TextureView>=texture_loading_threads.into_iter().map(|(texture_id,thread)|{
|
|
||||||
let image=thread.join().unwrap();
|
|
||||||
|
|
||||||
let (mut width,mut height)=(image.get_width(),image.get_height());
|
let (mut width,mut height)=(image.get_width(),image.get_height());
|
||||||
|
|
||||||
@ -219,50 +203,55 @@ impl GraphicsState{
|
|||||||
//split groups with different textures into separate models
|
//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();
|
let indexed_models_len=map.models.len();
|
||||||
|
//models split into graphics_group.RenderConfigId
|
||||||
|
let mut map_map:HashMap<model::MeshId,HashMap<RenderConfigId,IndexedGraphicsMeshOwnedRenderConfigId>>=HashMap::new();
|
||||||
|
let mut map_unique_textures=HashMap::new();
|
||||||
let mut unique_texture_models=Vec::with_capacity(indexed_models_len);
|
let mut unique_texture_models=Vec::with_capacity(indexed_models_len);
|
||||||
for model in map.models.into_iter(){
|
for model in &map.models{
|
||||||
//convert ModelInstance into GraphicsModelInstance
|
//wow
|
||||||
let instances:Vec<GraphicsModelInstance>=model.instances.into_iter().filter_map(|instance|{
|
let instance=GraphicsModelOwned{
|
||||||
if instance.color.w==0.0{
|
transform:model.transform.into(),
|
||||||
None
|
normal_transform:Into::<glam::Mat3>::into(model.transform.matrix3).inverse().transpose(),
|
||||||
}else{
|
color:GraphicsModelColor4::new(model.color),
|
||||||
Some(GraphicsModelInstance{
|
};
|
||||||
transform: instance.transform.into(),
|
//convert Model into GraphicsModelOwned
|
||||||
normal_transform: Into::<glam::Mat3>::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;
|
|
||||||
}
|
|
||||||
//check each group, if it's using a new texture then make a new clone of the model
|
//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 id=unique_texture_models.len();
|
||||||
let mut unique_textures=Vec::new();
|
let mut unique_textures=Vec::new();
|
||||||
for group in model.groups.into_iter(){
|
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
|
//ignore zero copy optimization for now
|
||||||
let texture_index=if let Some(texture_index)=unique_textures.iter().position(|&texture|texture==group.texture){
|
let texture_index=if let Some(texture_index)=unique_textures.iter().position(|&texture|texture==render_config.texture){
|
||||||
texture_index
|
texture_index
|
||||||
}else{
|
}else{
|
||||||
//create new texture_index
|
//create new texture_index
|
||||||
let texture_index=unique_textures.len();
|
let texture_index=unique_textures.len();
|
||||||
unique_textures.push(group.texture);
|
unique_textures.push(render_config.texture);
|
||||||
unique_texture_models.push(IndexedGraphicsModelSingleTexture{
|
unique_texture_models.push(IndexedGraphicsMeshOwnedRenderConfig{
|
||||||
unique_pos:model.unique_pos.iter().map(|&v|*Into::<glam::Vec3>::into(v).as_ref()).collect(),
|
unique_pos:mesh.unique_pos.iter().map(|&v|*Into::<glam::Vec3>::into(v).as_ref()).collect(),
|
||||||
unique_tex:model.unique_tex.iter().map(|v|*v.as_ref()).collect(),
|
unique_tex:mesh.unique_tex.iter().map(|v|*v.as_ref()).collect(),
|
||||||
unique_normal:model.unique_normal.iter().map(|&v|*Into::<glam::Vec3>::into(v).as_ref()).collect(),
|
unique_normal:mesh.unique_normal.iter().map(|&v|*Into::<glam::Vec3>::into(v).as_ref()).collect(),
|
||||||
unique_color:model.unique_color.iter().map(|v|*v.as_ref()).collect(),
|
unique_color:mesh.unique_color.iter().map(|v|*v.as_ref()).collect(),
|
||||||
unique_vertices:model.unique_vertices.clone(),
|
unique_vertices:mesh.unique_vertices.clone(),
|
||||||
texture:group.texture,
|
render_config:graphics_group.render,
|
||||||
groups:Vec::new(),
|
polys:model::PolygonGroup::PolygonList(model::PolygonList::new(
|
||||||
instances:instances.clone(),
|
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
|
texture_index
|
||||||
};
|
};
|
||||||
unique_texture_models[id+texture_index].groups.push(IndexedGroupFixedTexture{
|
unique_texture_models[utm_id.get() as usize].instances.push(instance);
|
||||||
polys:group.polys,
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//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
|
//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
|
||||||
@ -275,20 +264,20 @@ impl GraphicsState{
|
|||||||
|
|
||||||
//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 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 (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<model.instances.len(){
|
if 1<model.instances.len(){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
//populate hashmap
|
//populate hashmap
|
||||||
let unique_color=if let Some(unique_color)=unique_texture_color.get_mut(&model.texture){
|
let unique_color=if let Some(unique_color)=unique_texture_color.get_mut(&model.render_config){
|
||||||
unique_color
|
unique_color
|
||||||
}else{
|
}else{
|
||||||
//make new hashmap
|
//make new hashmap
|
||||||
let unique_color=std::collections::HashMap::new();
|
let unique_color=HashMap::new();
|
||||||
unique_texture_color.insert(model.texture,unique_color);
|
unique_texture_color.insert(model.render_config,unique_color);
|
||||||
unique_texture_color.get_mut(&model.texture).unwrap()
|
unique_texture_color.get_mut(&model.render_config).unwrap()
|
||||||
};
|
};
|
||||||
//separate instances by color
|
//separate instances by color
|
||||||
for (instance_id,instance) in model.instances.iter().enumerate(){
|
for (instance_id,instance) in model.instances.iter().enumerate(){
|
||||||
@ -306,22 +295,22 @@ impl GraphicsState{
|
|||||||
}
|
}
|
||||||
//populate a hashset of models selected for transposition
|
//populate a hashset of models selected for transposition
|
||||||
//construct transposed models
|
//construct transposed models
|
||||||
let mut selected_model_instances=std::collections::HashSet::new();
|
let mut selected_model_instances=HashSet::new();
|
||||||
for (texture,unique_color) in unique_texture_color.into_iter(){
|
for (render_config,unique_color) in unique_texture_color.into_iter(){
|
||||||
for (color,model_instance_list) in unique_color.into_iter(){
|
for (color,model_instance_list) in unique_color.into_iter(){
|
||||||
//world transforming one model does not meet the definition of deduplicaiton
|
//world transforming one model does not meet the definition of deduplicaiton
|
||||||
if 1<model_instance_list.len(){
|
if 1<model_instance_list.len(){
|
||||||
//create model
|
//create model
|
||||||
let mut unique_pos=Vec::new();
|
let mut unique_pos=Vec::new();
|
||||||
let mut pos_id_from=std::collections::HashMap::new();
|
let mut pos_id_from=HashMap::new();
|
||||||
let mut unique_tex=Vec::new();
|
let mut unique_tex=Vec::new();
|
||||||
let mut tex_id_from=std::collections::HashMap::new();
|
let mut tex_id_from=HashMap::new();
|
||||||
let mut unique_normal=Vec::new();
|
let mut unique_normal=Vec::new();
|
||||||
let mut normal_id_from=std::collections::HashMap::new();
|
let mut normal_id_from=HashMap::new();
|
||||||
let mut unique_color=Vec::new();
|
let mut unique_color=Vec::new();
|
||||||
let mut color_id_from=std::collections::HashMap::new();
|
let mut color_id_from=HashMap::new();
|
||||||
let mut unique_vertices=Vec::new();
|
let mut unique_vertices=Vec::new();
|
||||||
let mut vertex_id_from=std::collections::HashMap::new();
|
let mut vertex_id_from=HashMap::new();
|
||||||
|
|
||||||
let mut polys=Vec::new();
|
let mut polys=Vec::new();
|
||||||
//transform instance vertices
|
//transform instance vertices
|
||||||
@ -396,24 +385,22 @@ impl GraphicsState{
|
|||||||
vertex_id
|
vertex_id
|
||||||
}) as u32)
|
}) as u32)
|
||||||
}).collect();
|
}).collect();
|
||||||
for group in model.groups{
|
polys.extend(model.polys.polys().map(|poly|
|
||||||
for poly in group.polys{
|
poly.iter().map(|vertex_id|
|
||||||
polys.push(poly.map_vertex_id(|vertex_id|map_vertex_id[vertex_id.get() as usize]));
|
map_vertex_id[vertex_id.get() as usize]
|
||||||
}
|
).collect()
|
||||||
}
|
));
|
||||||
}
|
}
|
||||||
//push model into dedup
|
//push model into dedup
|
||||||
deduplicated_models.push(IndexedGraphicsModelSingleTexture{
|
deduplicated_models.push(IndexedGraphicsMeshOwnedRenderConfig{
|
||||||
unique_pos,
|
unique_pos,
|
||||||
unique_tex,
|
unique_tex,
|
||||||
unique_normal,
|
unique_normal,
|
||||||
unique_color,
|
unique_color,
|
||||||
unique_vertices,
|
unique_vertices,
|
||||||
texture,
|
render_config,
|
||||||
groups:vec![IndexedGroupFixedTexture{
|
polys:model::PolygonGroup::PolygonList(model::PolygonList::new(polys)),
|
||||||
polys
|
instances:vec![GraphicsModelOwned{
|
||||||
}],
|
|
||||||
instances:vec![GraphicsModelInstance{
|
|
||||||
transform:glam::Mat4::IDENTITY,
|
transform:glam::Mat4::IDENTITY,
|
||||||
normal_transform:glam::Mat3::IDENTITY,
|
normal_transform:glam::Mat3::IDENTITY,
|
||||||
color
|
color
|
||||||
@ -431,21 +418,20 @@ impl GraphicsState{
|
|||||||
|
|
||||||
//de-index models
|
//de-index models
|
||||||
let deduplicated_models_len=deduplicated_models.len();
|
let deduplicated_models_len=deduplicated_models.len();
|
||||||
let models:Vec<GraphicsModelSingleTexture>=deduplicated_models.into_iter().map(|model|{
|
let models:Vec<GraphicsMeshOwnedRenderConfig>=deduplicated_models.into_iter().map(|model|{
|
||||||
let mut vertices=Vec::new();
|
let mut vertices=Vec::new();
|
||||||
let mut index_from_vertex = std::collections::HashMap::new();//::<IndexedVertex,usize>
|
let mut index_from_vertex=HashMap::new();//::<IndexedVertex,usize>
|
||||||
//this mut be combined in a more complex way if the models use different render patterns per group
|
//this mut be combined in a more complex way if the models use different render patterns per group
|
||||||
let mut indices=Vec::new();
|
let mut indices=Vec::new();
|
||||||
for group in model.groups {
|
for poly in model.polys.polys(){
|
||||||
for poly in group.polys {
|
for end_index in 2..poly.len(){
|
||||||
for end_index in 2..poly.vertices.len() {
|
for index in [0,end_index-1,end_index]{
|
||||||
for &index in &[0, end_index - 1, end_index] {
|
let vertex_index=poly[index];
|
||||||
let vertex_index = poly.vertices[index];
|
|
||||||
if let Some(&i)=index_from_vertex.get(&vertex_index){
|
if let Some(&i)=index_from_vertex.get(&vertex_index){
|
||||||
indices.push(i);
|
indices.push(i);
|
||||||
}else{
|
}else{
|
||||||
let i=vertices.len();
|
let i=vertices.len();
|
||||||
let vertex=&model.unique_vertices[vertex_index.get() as usize];
|
let vertex=model.unique_vertices[vertex_index.get() as usize];
|
||||||
vertices.push(GraphicsVertex{
|
vertices.push(GraphicsVertex{
|
||||||
pos:model.unique_pos[vertex.pos.get() as usize],
|
pos:model.unique_pos[vertex.pos.get() as usize],
|
||||||
tex:model.unique_tex[vertex.tex.get() as usize],
|
tex:model.unique_tex[vertex.tex.get() as usize],
|
||||||
@ -458,18 +444,17 @@ impl GraphicsState{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
GraphicsMeshOwnedRenderConfig{
|
||||||
GraphicsModelSingleTexture{
|
|
||||||
instances:model.instances,
|
instances:model.instances,
|
||||||
entities:if (u32::MAX as usize)<vertices.len(){
|
indices:if (u32::MAX as usize)<vertices.len(){
|
||||||
panic!("Model has too many vertices!")
|
panic!("Model has too many vertices!")
|
||||||
}else if (u16::MAX as usize)<vertices.len(){
|
}else if (u16::MAX as usize)<vertices.len(){
|
||||||
crate::model_graphics::Entities::U32(vec![indices.into_iter().map(|vertex_id|vertex_id as u32).collect()])
|
model_graphics::Indices::U32(indices.into_iter().map(|vertex_idx|vertex_idx as u32).collect())
|
||||||
}else{
|
}else{
|
||||||
crate::model_graphics::Entities::U16(vec![indices.into_iter().map(|vertex_id|vertex_id as u16).collect()])
|
model_graphics::Indices::U16(indices.into_iter().map(|vertex_idx|vertex_idx as u16).collect())
|
||||||
},
|
},
|
||||||
vertices,
|
vertices,
|
||||||
texture:model.texture,
|
render_config:model.render_config,
|
||||||
}
|
}
|
||||||
}).collect();
|
}).collect();
|
||||||
//.into_iter() the modeldata vec so entities can be /moved/ to models.entities
|
//.into_iter() the modeldata vec so entities can be /moved/ to models.entities
|
||||||
@ -488,16 +473,12 @@ impl GraphicsState{
|
|||||||
contents:bytemuck::cast_slice(&model_uniforms),
|
contents:bytemuck::cast_slice(&model_uniforms),
|
||||||
usage:wgpu::BufferUsages::UNIFORM|wgpu::BufferUsages::COPY_DST,
|
usage:wgpu::BufferUsages::UNIFORM|wgpu::BufferUsages::COPY_DST,
|
||||||
});
|
});
|
||||||
let texture_view=match model.texture{
|
let render_config=map.render_configs[model.render_config.get() as usize];
|
||||||
Some(texture_id)=>{
|
let texture_view=match render_config.texture{
|
||||||
match double_map.get(&texture_id){
|
Some(texture_id)=>&texture_views[texture_id.get() as usize],
|
||||||
Some(&mapped_texture_id)=>&texture_views[mapped_texture_id as usize],
|
|
||||||
None=>&self.temp_squid_texture_view,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None=>&self.temp_squid_texture_view,
|
None=>&self.temp_squid_texture_view,
|
||||||
};
|
};
|
||||||
let model_bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
let bind_group=device.create_bind_group(&wgpu::BindGroupDescriptor{
|
||||||
layout:&self.bind_group_layouts.model,
|
layout:&self.bind_group_layouts.model,
|
||||||
entries:&[
|
entries:&[
|
||||||
wgpu::BindGroupEntry{
|
wgpu::BindGroupEntry{
|
||||||
@ -522,17 +503,13 @@ impl GraphicsState{
|
|||||||
});
|
});
|
||||||
//all of these are being moved here
|
//all of these are being moved here
|
||||||
self.models.push(GraphicsModel{
|
self.models.push(GraphicsModel{
|
||||||
instances:instances_chunk.to_vec(),
|
instance_count:instances_chunk.len() as u32,
|
||||||
vertex_buf,
|
vertex_buf,
|
||||||
index_format:match &model.entities{
|
indices:match &model.indices{
|
||||||
crate::model_graphics::Entities::U32(_)=>wgpu::IndexFormat::Uint32,
|
model_graphics::Indices::U32(indices)=>Indices::new(device,indices,wgpu::IndexFormat::Uint32),
|
||||||
crate::model_graphics::Entities::U16(_)=>wgpu::IndexFormat::Uint16,
|
model_graphics::Indices::U16(indices)=>Indices::new(device,indices,wgpu::IndexFormat::Uint16),
|
||||||
},
|
},
|
||||||
entities:match &model.entities{
|
bind_group,
|
||||||
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,
|
|
||||||
model_buf,
|
model_buf,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -910,8 +887,7 @@ impl GraphicsState{
|
|||||||
){
|
){
|
||||||
//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 =
|
let mut encoder=device.create_command_encoder(&wgpu::CommandEncoderDescriptor{label:None});
|
||||||
device.create_command_encoder(&wgpu::CommandEncoderDescriptor { label: None });
|
|
||||||
|
|
||||||
// update rotation
|
// 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));
|
||||||
@ -973,14 +949,12 @@ impl GraphicsState{
|
|||||||
rpass.set_bind_group(1,&self.bind_groups.skybox_texture,&[]);
|
rpass.set_bind_group(1,&self.bind_groups.skybox_texture,&[]);
|
||||||
|
|
||||||
rpass.set_pipeline(&self.pipelines.model);
|
rpass.set_pipeline(&self.pipelines.model);
|
||||||
for model in self.models.iter() {
|
for model in &self.models{
|
||||||
rpass.set_bind_group(2,&model.bind_group,&[]);
|
rpass.set_bind_group(2,&model.bind_group,&[]);
|
||||||
rpass.set_vertex_buffer(0,model.vertex_buf.slice(..));
|
rpass.set_vertex_buffer(0,model.vertex_buf.slice(..));
|
||||||
|
rpass.set_index_buffer(model.indices.buf.slice(..),model.indices.format);
|
||||||
for entity in model.entities.iter(){
|
//TODO: loop over triangle strips
|
||||||
rpass.set_index_buffer(entity.index_buf.slice(..),model.index_format);
|
rpass.draw_indexed(0..model.indices.count,0,0..model.instance_count);
|
||||||
rpass.draw_indexed(0..entity.index_count,0,0..model.instances.len() as u32);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpass.set_pipeline(&self.pipelines.skybox);
|
rpass.set_pipeline(&self.pipelines.skybox);
|
||||||
@ -994,7 +968,7 @@ impl GraphicsState{
|
|||||||
}
|
}
|
||||||
const MODEL_BUFFER_SIZE:usize=4*4 + 12 + 4;//let size=std::mem::size_of::<ModelInstance>();
|
const MODEL_BUFFER_SIZE:usize=4*4 + 12 + 4;//let size=std::mem::size_of::<ModelInstance>();
|
||||||
const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4;
|
const MODEL_BUFFER_SIZE_BYTES:usize=MODEL_BUFFER_SIZE*4;
|
||||||
fn get_instances_buffer_data(instances:&[GraphicsModelInstance]) -> Vec<f32> {
|
fn get_instances_buffer_data(instances:&[GraphicsModelOwned])->Vec<f32>{
|
||||||
let mut raw=Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len());
|
let mut raw=Vec::with_capacity(MODEL_BUFFER_SIZE*instances.len());
|
||||||
for (i,mi) in instances.iter().enumerate(){
|
for (i,mi) in instances.iter().enumerate(){
|
||||||
//model transform
|
//model transform
|
||||||
|
@ -4,7 +4,7 @@ pub enum Instruction{
|
|||||||
Render(crate::physics::PhysicsOutputState,integer::Time,glam::IVec2),
|
Render(crate::physics::PhysicsOutputState,integer::Time,glam::IVec2),
|
||||||
//UpdateModel(crate::graphics::GraphicsModelUpdate),
|
//UpdateModel(crate::graphics::GraphicsModelUpdate),
|
||||||
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
|
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
|
||||||
GenerateModels(strafesnet_common::map::Map),
|
GenerateModels(strafesnet_common::map::CompleteMap),
|
||||||
ClearModels,
|
ClearModels,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use bytemuck::{Pod,Zeroable};
|
use bytemuck::{Pod,Zeroable};
|
||||||
use strafesnet_common::model::{IndexedVertex,PolygonGroup};
|
use strafesnet_common::model::{IndexedVertex,PolygonGroup,RenderConfigId,TextureId};
|
||||||
#[derive(Clone,Copy,Pod,Zeroable)]
|
#[derive(Clone,Copy,Pod,Zeroable)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct GraphicsVertex{
|
pub struct GraphicsVertex{
|
||||||
@ -8,41 +8,30 @@ pub struct GraphicsVertex{
|
|||||||
pub normal:[f32;3],
|
pub normal:[f32;3],
|
||||||
pub color:[f32;4],
|
pub color:[f32;4],
|
||||||
}
|
}
|
||||||
pub struct IndexedGroupFixedTexture{
|
#[derive(id::Id)]
|
||||||
pub polys:Vec<PolygonGroup>,
|
pub struct IndexedGraphicsMeshOwnedRenderConfigId(u32);
|
||||||
}
|
pub struct IndexedGraphicsMeshOwnedRenderConfig{
|
||||||
pub struct IndexedGraphicsModelSingleTexture{
|
|
||||||
pub unique_pos:Vec<[f32;3]>,
|
pub unique_pos:Vec<[f32;3]>,
|
||||||
pub unique_tex:Vec<[f32;2]>,
|
pub unique_tex:Vec<[f32;2]>,
|
||||||
pub unique_normal:Vec<[f32;3]>,
|
pub unique_normal:Vec<[f32;3]>,
|
||||||
pub unique_color:Vec<[f32;4]>,
|
pub unique_color:Vec<[f32;4]>,
|
||||||
pub unique_vertices:Vec<IndexedVertex>,
|
pub unique_vertices:Vec<IndexedVertex>,
|
||||||
pub texture:Option<u32>,//RenderPattern? material/texture/shader/flat color
|
pub render_config:RenderConfigId,
|
||||||
pub groups:Vec<IndexedGroupFixedTexture>,
|
pub polys:PolygonGroup,
|
||||||
pub instances:Vec<GraphicsModelInstance>,
|
pub instances:Vec<GraphicsModelOwned>,
|
||||||
}
|
}
|
||||||
pub enum Entities{
|
pub enum Indices{
|
||||||
U32(Vec<Vec<u32>>),
|
U32(Vec<u32>),
|
||||||
U16(Vec<Vec<u16>>),
|
U16(Vec<u16>),
|
||||||
}
|
}
|
||||||
pub struct GraphicsModelSingleTexture{
|
pub struct GraphicsMeshOwnedRenderConfig{
|
||||||
pub instances:Vec<GraphicsModelInstance>,
|
|
||||||
pub vertices:Vec<GraphicsVertex>,
|
pub vertices:Vec<GraphicsVertex>,
|
||||||
pub entities:Entities,
|
pub indices:Indices,
|
||||||
pub texture:Option<u32>,
|
pub render_config:RenderConfigId,
|
||||||
|
pub instances:Vec<GraphicsModelOwned>,
|
||||||
}
|
}
|
||||||
#[derive(Clone,PartialEq)]
|
#[derive(Clone,PartialEq,id::Id)]
|
||||||
pub struct GraphicsModelColor4(glam::Vec4);
|
pub struct GraphicsModelColor4(glam::Vec4);
|
||||||
impl GraphicsModelColor4{
|
|
||||||
pub const fn get(&self)->glam::Vec4{
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<glam::Vec4> for GraphicsModelColor4{
|
|
||||||
fn from(value:glam::Vec4)->Self{
|
|
||||||
Self(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl std::hash::Hash for GraphicsModelColor4{
|
impl std::hash::Hash for GraphicsModelColor4{
|
||||||
fn hash<H:std::hash::Hasher>(&self,state:&mut H) {
|
fn hash<H:std::hash::Hasher>(&self,state:&mut H) {
|
||||||
for &f in self.0.as_ref(){
|
for &f in self.0.as_ref(){
|
||||||
@ -52,7 +41,7 @@ impl std::hash::Hash for GraphicsModelColor4{
|
|||||||
}
|
}
|
||||||
impl Eq for GraphicsModelColor4{}
|
impl Eq for GraphicsModelColor4{}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct GraphicsModelInstance{
|
pub struct GraphicsModelOwned{
|
||||||
pub transform:glam::Mat4,
|
pub transform:glam::Mat4,
|
||||||
pub normal_transform:glam::Mat3,
|
pub normal_transform:glam::Mat3,
|
||||||
pub color:GraphicsModelColor4,
|
pub color:GraphicsModelColor4,
|
||||||
|
@ -261,8 +261,8 @@ impl EdgePool{
|
|||||||
(&mut unsafe{self.edge_guys.get_unchecked_mut(edge_id)}.1,SubmeshEdgeId::new(edge_id as u32))
|
(&mut unsafe{self.edge_guys.get_unchecked_mut(edge_id)}.1,SubmeshEdgeId::new(edge_id as u32))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<&model::IndexedModel> for PhysicsMesh{
|
impl From<&model::Mesh> for PhysicsMesh{
|
||||||
fn from(indexed_model:&model::IndexedModel)->Self{
|
fn from(indexed_model:&model::Mesh)->Self{
|
||||||
assert!(indexed_model.unique_pos.len()!=0,"Mesh cannot have 0 vertices");
|
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 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()];
|
let mut vert_ref_guys=vec![VertRefGuy::default();indexed_model.unique_pos.len()];
|
||||||
|
@ -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 starts=Vec::new();
|
||||||
let mut spawns=Vec::new();
|
let mut spawns=Vec::new();
|
||||||
let mut attr_hash=HashMap::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 mesh_id=self.data.models.meshes.len();
|
||||||
let mut make_mesh=false;
|
let mut make_mesh=false;
|
||||||
for model_instance in &model.instances{
|
for model_instance in &model.instances{
|
||||||
|
@ -18,7 +18,7 @@ pub enum Instruction{
|
|||||||
Input(InputInstruction),
|
Input(InputInstruction),
|
||||||
Render,
|
Render,
|
||||||
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
|
Resize(winit::dpi::PhysicalSize<u32>,crate::settings::UserSettings),
|
||||||
GenerateModels(strafesnet_common::map::Map),
|
GenerateModels(strafesnet_common::map::CompleteMap),
|
||||||
ClearModels,
|
ClearModels,
|
||||||
//Graphics(crate::graphics_worker::Instruction),
|
//Graphics(crate::graphics_worker::Instruction),
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user