UI Camera movement
This commit is contained in:
41
Cargo.lock
generated
41
Cargo.lock
generated
@@ -939,6 +939,12 @@ dependencies = [
|
||||
"crossbeam-utils",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_panic"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
@@ -1051,7 +1057,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e3d747f100290a1ca24b752186f61f6637e1deffe3bf6320de6fcb29510a307"
|
||||
dependencies = [
|
||||
"bitflags 2.5.0",
|
||||
"libloading 0.7.4",
|
||||
"libloading 0.8.3",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
@@ -1230,6 +1236,37 @@ dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a9299a95fa5671ddf29ecc22b00e121843a65cb9ff24911e394b4ae556baf36"
|
||||
dependencies = [
|
||||
"const_panic",
|
||||
"encase_derive",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase_derive"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e09decb3beb1fe2db6940f598957b2e1f7df6206a804d438ff6cb2a9cddc10"
|
||||
dependencies = [
|
||||
"encase_derive_impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encase_derive_impl"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd31dbbd9743684d339f907a87fe212cb7b51d75b9e8e74181fe363199ee9b47"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enumflags2"
|
||||
version = "0.7.10"
|
||||
@@ -3611,6 +3648,8 @@ dependencies = [
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui-wgpu",
|
||||
"encase",
|
||||
"nalgebra",
|
||||
"slicer",
|
||||
"wgpu",
|
||||
]
|
||||
|
@@ -12,3 +12,5 @@ egui-wgpu = "0.27.2"
|
||||
wgpu = "0.19.4"
|
||||
|
||||
slicer = { path = "../slicer" }
|
||||
encase = "0.8.0"
|
||||
nalgebra = "0.32.6"
|
||||
|
113
ui/src/main.rs
113
ui/src/main.rs
@@ -2,20 +2,38 @@ use std::{fs::File, mem};
|
||||
|
||||
use anyhow::Result;
|
||||
use eframe::NativeOptions;
|
||||
use egui::{CentralPanel, Frame, Sense, TopBottomPanel, Vec2, Window};
|
||||
use egui::{CentralPanel, Frame, Sense, Slider, Stroke, TopBottomPanel, Vec2, Window};
|
||||
use egui_wgpu::{Callback, CallbackTrait};
|
||||
use slicer::mesh::Mesh;
|
||||
use nalgebra::{Matrix4, Point3, Vector3};
|
||||
use slicer::{mesh::Mesh, Pos};
|
||||
use wgpu::{
|
||||
BindGroup, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingType, Buffer, BufferAddress, BufferBindingType, BufferDescriptor, BufferSize, BufferUsages, ColorTargetState, ColorWrites, Face, FragmentState, IndexFormat, MultisampleState, PipelineLayoutDescriptor, PrimitiveState, RenderPipeline, RenderPipelineDescriptor, ShaderModuleDescriptor, ShaderStages, TextureFormat, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode
|
||||
BindGroup, BindGroupEntry, BindGroupLayoutDescriptor, Buffer, BufferAddress, BufferBinding,
|
||||
BufferDescriptor, BufferUsages, ColorTargetState, ColorWrites, FragmentState, IndexFormat,
|
||||
MultisampleState, PipelineLayoutDescriptor, PrimitiveState, RenderPipeline,
|
||||
RenderPipelineDescriptor, ShaderModuleDescriptor, TextureFormat, VertexAttribute,
|
||||
VertexBufferLayout, VertexFormat, VertexState, VertexStepMode,
|
||||
};
|
||||
|
||||
const TEXTURE_FORMAT: TextureFormat = TextureFormat::Bgra8Unorm;
|
||||
|
||||
struct App {}
|
||||
struct App {
|
||||
camera: Camera,
|
||||
}
|
||||
|
||||
struct Camera {
|
||||
eye: Point3<f32>,
|
||||
target: Point3<f32>,
|
||||
up: Vector3<f32>,
|
||||
fovy: f32,
|
||||
znear: f32,
|
||||
zfar: f32,
|
||||
}
|
||||
|
||||
struct WorkspaceRenderResources {
|
||||
vertex_buffer: Buffer,
|
||||
index_buffer: Buffer,
|
||||
uniform_buffer: Buffer,
|
||||
|
||||
render_pipeline: RenderPipeline,
|
||||
bind_group: BindGroup,
|
||||
|
||||
@@ -51,9 +69,25 @@ fn main() -> Result<()> {
|
||||
source: wgpu::ShaderSource::Wgsl(include_str!("shader/workspace.wgsl").into()),
|
||||
});
|
||||
|
||||
let uniform_buffer = device.create_buffer(&BufferDescriptor {
|
||||
label: None,
|
||||
size: mem::size_of::<WorkspaceRenderCallback>() as u64,
|
||||
usage: BufferUsages::UNIFORM | BufferUsages::COPY_DST,
|
||||
mapped_at_creation: false,
|
||||
});
|
||||
|
||||
let bind_group_layout = device.create_bind_group_layout(&BindGroupLayoutDescriptor {
|
||||
label: None,
|
||||
entries: &[],
|
||||
entries: &[wgpu::BindGroupLayoutEntry {
|
||||
binding: 0,
|
||||
visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
|
||||
ty: wgpu::BindingType::Buffer {
|
||||
ty: wgpu::BufferBindingType::Uniform,
|
||||
has_dynamic_offset: false,
|
||||
min_binding_size: None,
|
||||
},
|
||||
count: None,
|
||||
}],
|
||||
});
|
||||
|
||||
let vertex_buffers = [VertexBufferLayout {
|
||||
@@ -107,7 +141,14 @@ fn main() -> Result<()> {
|
||||
let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
|
||||
label: None,
|
||||
layout: &bind_group_layout,
|
||||
entries: &[],
|
||||
entries: &[BindGroupEntry {
|
||||
binding: 0,
|
||||
resource: wgpu::BindingResource::Buffer(BufferBinding {
|
||||
buffer: &uniform_buffer,
|
||||
offset: 0,
|
||||
size: None,
|
||||
}),
|
||||
}],
|
||||
});
|
||||
|
||||
render_state
|
||||
@@ -117,12 +158,24 @@ fn main() -> Result<()> {
|
||||
.insert(WorkspaceRenderResources {
|
||||
vertex_buffer,
|
||||
index_buffer,
|
||||
uniform_buffer,
|
||||
|
||||
render_pipeline,
|
||||
bind_group,
|
||||
|
||||
modal: test_modal,
|
||||
});
|
||||
|
||||
Box::new(App {})
|
||||
Box::new(App {
|
||||
camera: Camera {
|
||||
eye: Point3::new(0.0, -50.0, 5.0),
|
||||
target: Point3::new(0.0, 50.0, 0.0),
|
||||
up: Vector3::new(0.0, 1.0, 0.0),
|
||||
fovy: 25.0,
|
||||
znear: 0.1,
|
||||
zfar: 100.0,
|
||||
},
|
||||
})
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
@@ -142,18 +195,43 @@ impl eframe::App for App {
|
||||
});
|
||||
});
|
||||
|
||||
CentralPanel::default().show(ctx, |ui| {
|
||||
Frame::canvas(ui.style()).show(ui, |ui| {
|
||||
let (rect, response) = ui.allocate_exact_size(Vec2::splat(300.0), Sense::drag());
|
||||
Window::new("Controls").show(ctx, |ui| {});
|
||||
|
||||
let callback = Callback::new_paint_callback(rect, WorkspaceRenderCallback);
|
||||
CentralPanel::default()
|
||||
.frame(Frame::none())
|
||||
.show(ctx, |ui| {
|
||||
let (rect, _response) = ui.allocate_exact_size(ui.available_size(), Sense::drag());
|
||||
|
||||
let callback = Callback::new_paint_callback(
|
||||
rect,
|
||||
WorkspaceRenderCallback {
|
||||
transform: self
|
||||
.camera
|
||||
.build_view_projection_matrix(rect.width() / rect.height()),
|
||||
},
|
||||
);
|
||||
ui.painter().add(callback);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
struct WorkspaceRenderCallback;
|
||||
impl Camera {
|
||||
fn build_view_projection_matrix(&self, aspect: f32) -> Matrix4<f32> {
|
||||
const OPENGL_TO_WGPU_MATRIX: Matrix4<f32> = Matrix4::new(
|
||||
1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0,
|
||||
);
|
||||
|
||||
let fov = self.fovy * std::f32::consts::PI / 180.0;
|
||||
|
||||
let view = Matrix4::look_at_rh(&self.eye, &self.target, &self.up);
|
||||
let proj = Matrix4::new_perspective(aspect, fov, self.znear, self.zfar);
|
||||
OPENGL_TO_WGPU_MATRIX * proj * view
|
||||
}
|
||||
}
|
||||
|
||||
struct WorkspaceRenderCallback {
|
||||
transform: Matrix4<f32>,
|
||||
}
|
||||
|
||||
impl CallbackTrait for WorkspaceRenderCallback {
|
||||
fn prepare(
|
||||
@@ -186,6 +264,8 @@ impl CallbackTrait for WorkspaceRenderCallback {
|
||||
bytemuck::cast_slice(&resources.modal.faces),
|
||||
);
|
||||
|
||||
queue.write_buffer(&resources.uniform_buffer, 0, &self.to_wgsl());
|
||||
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
@@ -207,6 +287,13 @@ impl CallbackTrait for WorkspaceRenderCallback {
|
||||
}
|
||||
}
|
||||
|
||||
impl WorkspaceRenderCallback {
|
||||
fn to_wgsl(&self) -> Vec<u8> {
|
||||
let mut out = Vec::new();
|
||||
out.extend_from_slice(bytemuck::cast_slice(&self.transform.as_slice()));
|
||||
out
|
||||
}
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, bytemuck::Pod, bytemuck::Zeroable)]
|
||||
pub struct ModelVertex {
|
||||
|
@@ -1,3 +1,9 @@
|
||||
@group(0) @binding(0) var<uniform> context: Context;
|
||||
|
||||
struct Context {
|
||||
transform: mat4x4<f32>,
|
||||
}
|
||||
|
||||
struct VertexOutput {
|
||||
@builtin(position)
|
||||
position: vec4<f32>,
|
||||
@@ -11,7 +17,7 @@ fn vert(
|
||||
@location(1) tex_coord: vec2<f32>,
|
||||
) -> VertexOutput {
|
||||
var out: VertexOutput;
|
||||
out.position = position;
|
||||
out.position = context.transform * position;
|
||||
out.tex_coord = tex_coord;
|
||||
return out;
|
||||
}
|
||||
|
Reference in New Issue
Block a user