summaryrefslogtreecommitdiff
path: root/client/src
diff options
context:
space:
mode:
Diffstat (limited to 'client/src')
-rw-r--r--client/src/renderer.rs19
-rw-r--r--client/src/state.rs63
-rw-r--r--client/src/ui.rs70
-rw-r--r--client/src/window.rs8
4 files changed, 115 insertions, 45 deletions
diff --git a/client/src/renderer.rs b/client/src/renderer.rs
index a9a2332..473349d 100644
--- a/client/src/renderer.rs
+++ b/client/src/renderer.rs
@@ -16,7 +16,7 @@
*/
use crate::{
camera::Camera, download::Downloader, scene_prepare::ScenePreparer,
- scene_render::ScenePipeline, ui::UiRenderer,
+ scene_render::ScenePipeline, state::InputState, ui::UiRenderer,
};
use anyhow::{Result, anyhow};
use log::{info, warn};
@@ -163,7 +163,12 @@ impl<'a> Renderer<'a> {
.create_view(&TextureViewDescriptor::default());
}
- pub fn draw(&mut self, scene: &SceneTree, camera: &Camera) -> Result<()> {
+ pub fn draw(
+ &mut self,
+ scene: &SceneTree,
+ camera: &Camera,
+ input_state: &InputState,
+ ) -> Result<()> {
if self.surface_needs_reconfigure {
self.surface
.configure(&self.device, &self.surface_configuration);
@@ -193,8 +198,14 @@ impl<'a> Renderer<'a> {
projection,
);
- self.ui_renderer
- .draw(&mut commands, &target_view, &self.depth, projection);
+ self.ui_renderer.draw(
+ &mut commands,
+ &target_view,
+ &self.depth,
+ projection,
+ input_state,
+ &self.surface_configuration,
+ );
let i = self.queue.submit(Some(commands.finish()));
self.device.poll(MaintainBase::WaitForSubmissionIndex(i));
diff --git a/client/src/state.rs b/client/src/state.rs
index cd11d4a..5176ca1 100644
--- a/client/src/state.rs
+++ b/client/src/state.rs
@@ -33,18 +33,19 @@ pub struct State<'a> {
pub renderer: Renderer<'a>,
pub tree: SceneTree,
pub camera: Camera,
- pub delta: DeltaState,
+ pub input_state: InputState,
- pub prefab_index: PrefabIndex,
+ pub prefab_index: Arc<PrefabIndex>,
pub prefab_index_res_loaded: Option<Resource<PrefabIndex>>,
pub prefab_index_res: Option<Resource<PrefabIndex>>,
}
-pub struct DeltaState {
+pub struct InputState {
time: Instant,
pub move_dir: Vec3,
pub mouse_acc: Vec2,
pub cursor_pos: Vec2,
+ pub egui_events: Vec<egui::Event>,
}
impl<'a> State<'a> {
@@ -57,19 +58,23 @@ impl<'a> State<'a> {
tree: SceneTree::default(),
renderer: Renderer::new(window, downloader.clone())?,
downloader,
- delta: DeltaState {
+ input_state: InputState {
time: Instant::now(),
move_dir: Vec3::ZERO,
mouse_acc: Vec2::ZERO,
cursor_pos: Vec2::ZERO,
+ egui_events: Vec::new(),
},
prefab_index_res: None,
prefab_index_res_loaded: None,
- prefab_index: PrefabIndex::default(),
+ prefab_index: PrefabIndex::default().into(),
})
}
pub fn draw(&mut self) {
- if let Err(e) = self.renderer.draw(&self.tree, &self.camera) {
+ if let Err(e) = self
+ .renderer
+ .draw(&self.tree, &self.camera, &self.input_state)
+ {
warn!("draw failed: {e:?}");
}
}
@@ -78,29 +83,51 @@ impl<'a> State<'a> {
self.camera.aspect = width as f32 / height as f32;
}
pub fn click(&mut self, button: MouseButton, down: bool) {
+ self.input_state
+ .egui_events
+ .push(egui::Event::PointerButton {
+ pos: egui::Pos2::new(self.input_state.cursor_pos.x, self.input_state.cursor_pos.y),
+ button: match button {
+ MouseButton::Left => egui::PointerButton::Primary,
+ MouseButton::Right => egui::PointerButton::Secondary,
+ MouseButton::Middle => egui::PointerButton::Middle,
+ MouseButton::Back => egui::PointerButton::Extra1,
+ MouseButton::Forward => egui::PointerButton::Extra2,
+ MouseButton::Other(_) => egui::PointerButton::Extra1,
+ },
+ pressed: down,
+ modifiers: egui::Modifiers::default(),
+ });
+
if !down || button != MouseButton::Right {
return;
}
+ let pi = self.prefab_index.clone();
self.renderer
.ui_renderer
- .add_surface(self.camera.new_ui_affine(), |ctx| {
- egui::Window::new("Funny window")
- .default_open(true)
+ .add_surface(self.camera.new_ui_affine(), move |ctx| {
+ let mut open = true;
+ egui::Window::new("Prefab Index")
+ .open(&mut open)
.show(ctx, |ui| {
- ui.label("world space ui actually kinda works now");
- ui.label("Does input work?");
- ui.button("Yes").clicked();
+ for (key, _res) in &pi.0 {
+ ui.horizontal(|ui| {
+ ui.label(key);
+ if ui.button("Add").clicked() {}
+ });
+ }
});
+ open
});
}
pub fn update(&mut self) -> Result<()> {
let now = Instant::now();
- let dt = (now - self.delta.time).as_secs_f32();
- self.delta.time = now;
+ let dt = (now - self.input_state.time).as_secs_f32();
+ self.input_state.time = now;
self.camera
- .update(self.delta.move_dir, self.delta.mouse_acc, dt);
- self.delta.mouse_acc = Vec2::ZERO;
+ .update(self.input_state.move_dir, self.input_state.mouse_acc, dt);
+ self.input_state.mouse_acc = Vec2::ZERO;
for p in self.network.packet_recv.try_iter() {
self.downloader.packet(&p)?;
@@ -117,11 +144,13 @@ impl<'a> State<'a> {
if let Some(res) = &self.prefab_index_res {
if let Some(index) = self.downloader.try_get(res.to_owned())? {
info!("prefab index loaded");
- self.prefab_index = index;
+ self.prefab_index = index.into();
self.prefab_index_res_loaded = Some(res.to_owned());
}
}
}
+
+ self.input_state.egui_events.clear();
Ok(())
}
}
diff --git a/client/src/ui.rs b/client/src/ui.rs
index 54192e4..13e58d0 100644
--- a/client/src/ui.rs
+++ b/client/src/ui.rs
@@ -15,10 +15,10 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use egui::{
- Context, ImageData, TextureId, ViewportId, ViewportInfo,
+ Context, Event, ImageData, TextureId, ViewportId, ViewportInfo,
epaint::{ImageDelta, Primitive, Vertex},
};
-use glam::{Affine3A, Mat2, Mat3, Mat4};
+use glam::{Affine3A, Mat2, Mat3, Mat4, Vec2, vec2};
use log::info;
use rand::random;
use std::{
@@ -36,13 +36,15 @@ use wgpu::{
PrimitiveTopology, PushConstantRange, Queue, RenderPassColorAttachment,
RenderPassDepthStencilAttachment, RenderPassDescriptor, RenderPipeline,
RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, ShaderStages, StoreOp,
- Texture, TextureAspect, TextureDescriptor, TextureDimension, TextureFormat, TextureSampleType,
- TextureUsages, TextureView, TextureViewDescriptor, TextureViewDimension, VertexBufferLayout,
- VertexState, VertexStepMode, include_wgsl,
+ SurfaceConfiguration, Texture, TextureAspect, TextureDescriptor, TextureDimension,
+ TextureFormat, TextureSampleType, TextureUsages, TextureView, TextureViewDescriptor,
+ TextureViewDimension, VertexBufferLayout, VertexState, VertexStepMode, include_wgsl,
util::{DeviceExt, TextureDataOrder},
vertex_attr_array,
};
+use crate::state::InputState;
+
pub struct UiRenderer {
device: Arc<Device>,
queue: Arc<Queue>,
@@ -55,7 +57,8 @@ pub struct UiRenderer {
pub struct UiSurface {
pub transform: Affine3A,
- pub content: Arc<dyn Fn(&Context) + Send + Sync + 'static>,
+ pub content: Arc<dyn Fn(&Context) -> bool + Send + Sync + 'static>,
+ size: Vec2,
index: Buffer,
index_capacity: usize,
vertex: Buffer,
@@ -149,7 +152,7 @@ impl UiRenderer {
pub fn add_surface(
&mut self,
transform: Affine3A,
- content: impl Fn(&Context) + Send + Sync + 'static,
+ content: impl Fn(&Context) -> bool + Send + Sync + 'static,
) {
let index_capacity = 1024;
let vertex_capacity = 1024;
@@ -165,17 +168,17 @@ impl UiRenderer {
usage: BufferUsages::VERTEX | BufferUsages::COPY_DST,
mapped_at_creation: false,
});
- self.surfaces.write().unwrap().insert(
- ViewportId::from_hash_of(random::<u128>()),
- UiSurface {
- transform,
- content: Arc::new(content),
- index,
- vertex,
- index_capacity,
- vertex_capacity,
- },
- );
+ let id = ViewportId::from_hash_of(random::<u128>());
+ info!("ui surface added: {id:?}");
+ self.surfaces.write().unwrap().insert(id, UiSurface {
+ transform,
+ content: Arc::new(content),
+ index,
+ vertex,
+ index_capacity,
+ vertex_capacity,
+ size: Vec2::ZERO,
+ });
}
pub fn apply_texture_delta(&self, texid: TextureId, delta: ImageDelta) {
@@ -273,6 +276,8 @@ impl UiRenderer {
target: &TextureView,
depth: &TextureView,
projection: Mat4,
+ input_state: &InputState,
+ surface_configuration: &SurfaceConfiguration,
) {
let mut surfaces = self.surfaces.write().unwrap();
if surfaces.is_empty() {
@@ -302,7 +307,20 @@ impl UiRenderer {
rpass.set_pipeline(&self.pipeline);
+ let _screen_size = vec2(
+ surface_configuration.width as f32,
+ surface_configuration.height as f32,
+ );
+
let mut raw_input = egui::RawInput::default();
+ raw_input.events.push(Event::PointerMoved(egui::Pos2::new(
+ input_state.cursor_pos.x,
+ input_state.cursor_pos.y,
+ )));
+ raw_input
+ .events
+ .extend(input_state.egui_events.iter().cloned());
+
raw_input.viewport_id = surfaces.keys().next().copied().unwrap();
raw_input.viewports = surfaces
.keys()
@@ -314,8 +332,16 @@ impl UiRenderer {
})
.collect();
- for (_viewport_id, surf) in surfaces.iter_mut() {
- let full_output = self.ctx.run(raw_input.clone(), |ctx| (surf.content)(ctx));
+ let mut surfaces_closed = Vec::new();
+ for (viewport_id, surf) in surfaces.iter_mut() {
+ let mut close = false;
+ let full_output = self.ctx.run(raw_input.clone(), |ctx| {
+ close = !(surf.content)(ctx);
+ surf.size = Vec2::new(ctx.used_size().x, ctx.used_size().y)
+ });
+ if close {
+ surfaces_closed.push(*viewport_id)
+ }
for (texid, delta) in full_output.textures_delta.set {
self.apply_texture_delta(texid, delta);
@@ -428,5 +454,9 @@ impl UiRenderer {
rpass.draw_indexed(index, base_vertex, 0..1);
}
}
+ for s in surfaces_closed {
+ info!("ui surface closed: {s:?}");
+ surfaces.remove(&s);
+ }
}
}
diff --git a/client/src/window.rs b/client/src/window.rs
index 107be34..68ca25b 100644
--- a/client/src/window.rs
+++ b/client/src/window.rs
@@ -85,7 +85,7 @@ impl ApplicationHandler for WindowState {
_ => (),
}
}
- sta.delta.move_dir += match event.physical_key {
+ sta.input_state.move_dir += match event.physical_key {
PhysicalKey::Code(KeyCode::KeyW) => Vec3::X,
PhysicalKey::Code(KeyCode::KeyS) => Vec3::NEG_X,
PhysicalKey::Code(KeyCode::KeyA) => Vec3::NEG_Z,
@@ -100,7 +100,7 @@ impl ApplicationHandler for WindowState {
sta.click(button, state.is_pressed());
}
WindowEvent::CursorMoved { position, .. } => {
- sta.delta.cursor_pos = vec2(position.x as f32, position.y as f32);
+ sta.input_state.cursor_pos = vec2(position.x as f32, position.y as f32);
}
WindowEvent::CloseRequested => {
event_loop.exit();
@@ -119,8 +119,8 @@ impl ApplicationHandler for WindowState {
match event {
DeviceEvent::MouseMotion { delta } => {
if self.lock {
- sta.delta.mouse_acc.x += delta.0 as f32;
- sta.delta.mouse_acc.y += delta.1 as f32;
+ sta.input_state.mouse_acc.x += delta.0 as f32;
+ sta.input_state.mouse_acc.y += delta.1 as f32;
}
}
_ => (),