summaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'client/src')
-rw-r--r--client/src/main.rs3
-rw-r--r--client/src/network.rs6
-rw-r--r--client/src/renderer.rs113
-rw-r--r--client/src/scene_prepare.rs30
-rw-r--r--client/src/scene_render.rs (renamed from client/src/part.rs)131
5 files changed, 96 insertions, 187 deletions
diff --git a/client/src/main.rs b/client/src/main.rs
index b90d26b..e1f556f 100644
--- a/client/src/main.rs
+++ b/client/src/main.rs
@@ -1,9 +1,10 @@
pub mod download;
pub mod network;
-pub mod part;
+pub mod scene_render;
pub mod renderer;
pub mod state;
pub mod window;
+pub mod scene_prepare;
use anyhow::Result;
use clap::Parser;
diff --git a/client/src/network.rs b/client/src/network.rs
index e542c7e..e54ecf7 100644
--- a/client/src/network.rs
+++ b/client/src/network.rs
@@ -7,7 +7,7 @@ use std::{
use anyhow::Result;
use log::{debug, info, warn};
-use weareshared::packets::Packet;
+use weareshared::packets::{Packet, ReadWrite};
pub struct Network {
pub packet_recv: Receiver<Packet>,
@@ -40,7 +40,7 @@ impl Network {
fn handle_conn_read(sock: TcpStream, tx: Sender<Packet>) -> Result<()> {
let mut sock = BufReader::new(sock);
loop {
- let packet = Packet::deserialize(&mut sock)?;
+ let packet = Packet::read(&mut sock)?;
debug!("<- {packet:?}");
tx.send(packet)?;
}
@@ -49,7 +49,7 @@ fn handle_conn_write(sock: TcpStream, rx: Receiver<Packet>) -> Result<()> {
let mut sock = BufWriter::new(sock);
for packet in rx {
debug!("-> {packet:?}");
- packet.serialize(&mut sock)?;
+ packet.write(&mut sock)?;
sock.flush()?;
}
Ok(())
diff --git a/client/src/renderer.rs b/client/src/renderer.rs
index 35bc0ef..1cbc3cc 100644
--- a/client/src/renderer.rs
+++ b/client/src/renderer.rs
@@ -1,31 +1,22 @@
-use crate::part::{PartData, PartRenderer};
+use crate::{scene_prepare::ScenePreparer, scene_render::ScenePipeline};
use anyhow::{Result, anyhow};
-use log::info;
+use log::{info, warn};
use pollster::FutureExt;
-use std::collections::HashMap;
-use weareshared::{packets::Resource, tree::SceneTree};
+use weareshared::tree::SceneTree;
use wgpu::{
- Backends, BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Color,
- ColorTargetState, ColorWrites, CommandEncoderDescriptor, Device, DeviceDescriptor, Features,
- FragmentState, FrontFace, Instance, InstanceDescriptor, Limits, LoadOp, MaintainBase,
- MultisampleState, Operations, PipelineCompilationOptions, PipelineLayoutDescriptor,
- PolygonMode, PowerPreference, PrimitiveState, PrimitiveTopology, Queue,
- RenderPassColorAttachment, RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor,
- RequestAdapterOptions, StoreOp, Surface, SurfaceConfiguration, TextureViewDescriptor,
- VertexState, include_wgsl,
+ Backends, CommandEncoderDescriptor, Device, DeviceDescriptor, Features, Instance,
+ InstanceDescriptor, Limits, MaintainBase, PowerPreference, Queue, RequestAdapterOptions,
+ Surface, SurfaceConfiguration, TextureViewDescriptor,
};
use winit::window::Window;
pub struct Renderer<'a> {
surface: Surface<'a>,
- pipeline: RenderPipeline,
- bind_group: BindGroup,
queue: Queue,
device: Device,
surface_configuration: SurfaceConfiguration,
-
- prefabs_loading: HashMap<Resource, Vec<PartData>>,
- prefabs: HashMap<Resource, Vec<PartRenderer>>,
+ scene_pipeline: ScenePipeline,
+ scene_prepare: ScenePreparer,
}
impl<'a> Renderer<'a> {
pub fn new(window: &'a Window) -> Result<Self> {
@@ -60,65 +51,15 @@ impl<'a> Renderer<'a> {
.get_default_config(&adapter, 256, 256)
.ok_or(anyhow!("no default config"))?;
- let module = device.create_shader_module(include_wgsl!("shader.wgsl"));
-
- let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
- entries: &[],
- label: None,
- });
- let bind_group = device.create_bind_group(&BindGroupDescriptor {
- label: None,
- layout: &bind_group_layout,
- entries: &[],
- });
- let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
- label: None,
- bind_group_layouts: &[&bind_group_layout],
- push_constant_ranges: &[],
- });
- let pipeline = device.create_render_pipeline(&RenderPipelineDescriptor {
- label: None,
- layout: Some(&pipeline_layout),
- fragment: Some(FragmentState {
- module: &module,
- entry_point: Some("fs_main"),
- targets: &[Some(ColorTargetState {
- blend: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING),
- format: surface_configuration.format,
- write_mask: ColorWrites::all(),
- })],
- compilation_options: PipelineCompilationOptions::default(),
- }),
- vertex: VertexState {
- module: &module,
- entry_point: Some("vs_main"),
- buffers: &[],
- compilation_options: PipelineCompilationOptions::default(),
- },
- primitive: PrimitiveState {
- topology: PrimitiveTopology::TriangleList,
- front_face: FrontFace::Ccw,
- cull_mode: None, //Some(Face::Back),
- polygon_mode: PolygonMode::Fill,
- ..Default::default()
- },
- depth_stencil: Default::default(),
- multisample: MultisampleState::default(),
- multiview: None,
- cache: None,
- });
-
surface.configure(&device, &surface_configuration);
Ok(Self {
+ scene_pipeline: ScenePipeline::new(&device, surface_configuration.format),
+ scene_prepare: ScenePreparer::new(),
surface,
- pipeline,
- bind_group,
device,
queue,
surface_configuration,
- prefabs: HashMap::new(),
- prefabs_loading: HashMap::new(),
})
}
@@ -131,6 +72,9 @@ impl<'a> Renderer<'a> {
pub fn draw(&mut self, scene: &SceneTree) -> Result<()> {
let target = self.surface.get_current_texture()?;
+ if target.suboptimal {
+ warn!("suboptimal swapchain texture")
+ }
let target_view = target
.texture
.create_view(&TextureViewDescriptor::default());
@@ -139,38 +83,11 @@ impl<'a> Renderer<'a> {
.device
.create_command_encoder(&CommandEncoderDescriptor { label: None });
- {
- let mut rpass = commands.begin_render_pass(&RenderPassDescriptor {
- label: None,
- color_attachments: &[Some(RenderPassColorAttachment {
- view: &target_view,
- resolve_target: None,
- ops: Operations {
- store: StoreOp::Store,
- load: LoadOp::Clear(Color::BLUE),
- },
- })],
- ..Default::default()
- });
-
- rpass.set_bind_group(0, &self.bind_group, &[]);
- rpass.set_pipeline(&self.pipeline);
- rpass.draw(0..3, 0..1);
- }
-
- for data in scene.objects.values() {
- if let Some(ob) = self.prefabs.get(&data.res) {
- for p in ob {
- p.draw(&mut commands, &target_view);
- }
- } else {
- let loading = self.prefabs_loading.entry(data.res).or_default();
-
- }
- }
+ self.scene_pipeline.draw(&mut commands, &target_view, scene);
let i = self.queue.submit(Some(commands.finish()));
self.device.poll(MaintainBase::WaitForSubmissionIndex(i));
+
target.present();
Ok(())
diff --git a/client/src/scene_prepare.rs b/client/src/scene_prepare.rs
new file mode 100644
index 0000000..8d52f49
--- /dev/null
+++ b/client/src/scene_prepare.rs
@@ -0,0 +1,30 @@
+use anyhow::Result;
+use std::{
+ collections::{HashMap, HashSet},
+ sync::Arc,
+};
+use weareshared::{packets::Resource, resources::Part, tree::SceneTree};
+use wgpu::Buffer;
+
+pub struct ScenePreparer {
+ index_buffers: HashMap<Resource, Buffer>,
+ vertex_buffers_x3: HashMap<[Resource; 1], Arc<Buffer>>,
+ vertex_buffers_x2: HashMap<[Resource; 2], Arc<Buffer>>,
+ vertex_buffers_x1: HashMap<[Resource; 3], Arc<Buffer>>,
+ parts: HashMap<Resource, Part>,
+}
+
+impl ScenePreparer {
+ pub fn new() -> Self {
+ Self {
+ index_buffers: HashMap::new(),
+ vertex_buffers_x3: HashMap::new(),
+ vertex_buffers_x2: HashMap::new(),
+ vertex_buffers_x1: HashMap::new(),
+ parts: HashMap::new(),
+ }
+ }
+ fn update(&mut self, tree: &SceneTree) -> Result<()> {
+ let x = tree.objects.values().map(|o| o.res).collect::<HashSet<_>>();
+ }
+}
diff --git a/client/src/part.rs b/client/src/scene_render.rs
index 7d02f0c..cc15e3f 100644
--- a/client/src/part.rs
+++ b/client/src/scene_render.rs
@@ -1,86 +1,31 @@
-use crate::download::Downloader;
-use anyhow::Result;
-use weareshared::resources::{Indecies, Part, VertexAttributes};
+use std::collections::HashMap;
+use weareshared::{packets::Resource, tree::SceneTree};
use wgpu::{
- BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Buffer, BufferUsages,
+ BindGroup, BindGroupDescriptor, BindGroupLayoutDescriptor, BlendState, Buffer, Color,
ColorTargetState, ColorWrites, CommandEncoder, Device, FragmentState, FrontFace, IndexFormat,
LoadOp, MultisampleState, Operations, PipelineCompilationOptions, PipelineLayoutDescriptor,
PolygonMode, PrimitiveState, PrimitiveTopology, RenderPassColorAttachment,
RenderPassDescriptor, RenderPipeline, RenderPipelineDescriptor, StoreOp, TextureFormat,
TextureView, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
include_wgsl,
- util::{BufferInitDescriptor, DeviceExt},
};
-pub struct PartRenderer {
- vertex: Buffer,
- index: Buffer,
+pub struct ScenePipeline {
pipeline: RenderPipeline,
bind_group: BindGroup,
- n_vertex: u32,
-}
-
-pub struct PrefabData {
-
+ prefabs: HashMap<Resource, RPrefab>,
}
-pub struct PartData {
- target: Part,
- vertex: Vec<Option<VertexAttributes>>,
- index: Option<Indecies>,
-}
-
-impl PartData {
- pub fn update(&mut self, dls: &mut Downloader) -> Result<bool> {
- let mut ready = true;
- if self.index.is_none() {
- ready = false;
- if let Some(hash) = self.target.index {
- if let Some(data) = dls.try_get(hash)? {
- self.index = Some(Indecies::deserialize(data.as_slice())?)
- }
- }
- }
- for (hash, slot) in self.target.vertex.iter().zip(self.vertex.iter_mut()) {
- if slot.is_none() {
- ready = false;
- if let Some(data) = dls.try_get(*hash)? {
- *slot = Some(VertexAttributes::deserialize(data.as_slice())?)
- }
- }
- }
- Ok(ready)
- }
+struct RPrefab(Vec<RPart>);
+struct RPart {
+ index_count: u32,
+ index: Buffer,
+ positions: Buffer,
+ normals: Buffer,
}
-impl PartRenderer {
- pub fn new(device: Device, data: PartData, format: TextureFormat) -> Self {
- let mut vertex = Vec::new();
- let mut index = Vec::new();
- for i in 0..data.vertex[0].as_ref().unwrap().0.len() {
- vertex.extend(data.vertex[0].as_ref().unwrap().0[i].to_le_bytes());
- vertex.extend(data.vertex[1].as_ref().unwrap().0[i].to_le_bytes());
- vertex.extend(data.vertex[2].as_ref().unwrap().0[i].to_le_bytes());
- }
- let mut n_vertex = 0;
- for ind in data.index.unwrap().0 {
- index.extend(ind[0].to_le_bytes());
- index.extend(ind[1].to_le_bytes());
- index.extend(ind[2].to_le_bytes());
- n_vertex += 3;
- }
-
- let vertex = device.create_buffer_init(&BufferInitDescriptor {
- label: None,
- contents: &vertex,
- usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
- });
- let index = device.create_buffer_init(&BufferInitDescriptor {
- label: None,
- contents: &index,
- usage: BufferUsages::INDEX | BufferUsages::COPY_DST,
- });
-
+impl ScenePipeline {
+ pub fn new(device: &Device, format: TextureFormat) -> Self {
let module = device.create_shader_module(include_wgsl!("shader.wgsl"));
let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
@@ -115,12 +60,19 @@ impl PartRenderer {
entry_point: Some("vs_main"),
buffers: &[VertexBufferLayout {
step_mode: VertexStepMode::Vertex,
- array_stride: 3,
- attributes: &[VertexAttribute {
- format: VertexFormat::Float32x3,
- offset: 0,
- shader_location: 0,
- }],
+ array_stride: 2 * 4 * 3,
+ attributes: &[
+ VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 0,
+ shader_location: 0,
+ },
+ VertexAttribute {
+ format: VertexFormat::Float32x3,
+ offset: 3 * 4,
+ shader_location: 1,
+ },
+ ],
}],
compilation_options: PipelineCompilationOptions::default(),
},
@@ -136,33 +88,42 @@ impl PartRenderer {
multiview: None,
cache: None,
});
-
Self {
bind_group,
- index,
- vertex,
pipeline,
- n_vertex,
+ prefabs: HashMap::new(),
}
}
- pub fn draw(&self, commands: &mut CommandEncoder, target: &TextureView) {
+ pub fn draw(&self, commands: &mut CommandEncoder, target: &TextureView, scene: &SceneTree) {
let mut rpass = commands.begin_render_pass(&RenderPassDescriptor {
label: None,
color_attachments: &[Some(RenderPassColorAttachment {
- view: &target,
+ view: target,
resolve_target: None,
ops: Operations {
store: StoreOp::Store,
- load: LoadOp::Load,
+ load: LoadOp::Clear(Color {
+ r: 0.1,
+ g: 0.1,
+ b: 0.1,
+ a: 1.,
+ }),
},
})],
..Default::default()
});
-
rpass.set_bind_group(0, &self.bind_group, &[]);
rpass.set_pipeline(&self.pipeline);
- rpass.set_vertex_buffer(0, self.vertex.slice(..));
- rpass.set_index_buffer(self.index.slice(..), IndexFormat::Uint16);
- rpass.draw(0..self.n_vertex, 0..1);
+
+ for ob in scene.objects.values() {
+ if let Some(prefab) = self.prefabs.get(&ob.res) {
+ for part in &prefab.0 {
+ rpass.set_index_buffer(part.index.slice(..), IndexFormat::Uint16);
+ rpass.set_vertex_buffer(0, part.positions.slice(..));
+ rpass.set_vertex_buffer(1, part.normals.slice(..));
+ rpass.draw_indexed(0..part.index_count, 0, 0..1);
+ }
+ }
+ }
}
}