Add imgui
This commit is contained in:
parent
ab9d965630
commit
7a8b9a973c
4 changed files with 230 additions and 75 deletions
82
Cargo.lock
generated
82
Cargo.lock
generated
|
@ -384,9 +384,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.0"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0f606a85340376eef0d6d8fec399e6d4a544d648386c6645eb6d0653b27d9f"
|
||||
checksum = "a1aaa739f95311c2c7887a76863f500026092fb1dce0161dab577e559ef3569d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
|
@ -398,13 +398,12 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.0"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec91540d98355f690a86367e566ecad2e9e579f230230eb7c21398372be73ea5"
|
||||
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"cfg-if 1.0.0",
|
||||
"const_fn",
|
||||
"lazy_static",
|
||||
]
|
||||
|
||||
|
@ -870,6 +869,50 @@ dependencies = [
|
|||
"tiff",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a714f73a3f08446d92c47a38b536a03deba500aa6bb6fa805e8c0b6f90945e4f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"imgui-sys",
|
||||
"lazy_static",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-sys"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0522b693da8a64322afbb32c63c04f39d9b9435cc75199d630207eee48886fc1"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-wgpu"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8017f74f8880049c1c3fc055868486a610178ab93ad18eadaf5b0bb52f738365"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"imgui",
|
||||
"log",
|
||||
"smallvec",
|
||||
"wgpu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "imgui-winit-support"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e0fc247afc385ed9cd26860cdb7fae988d5c7e2ad1d70c70aef728ce9b78e85"
|
||||
dependencies = [
|
||||
"imgui",
|
||||
"winit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inplace_it"
|
||||
version = "0.3.2"
|
||||
|
@ -1017,9 +1060,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.5.6"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "043175f069eda7b85febe4a74abbaeff828d9f8b448515d3151a14a3542811aa"
|
||||
checksum = "157b4208e3059a8f9e78d559edc658e13df41410cb3ae03979c83130067fdd87"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
]
|
||||
|
@ -1184,9 +1227,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "6.0.0"
|
||||
version = "6.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4489ccc7d668957ddf64af7cd027c081728903afa6479d35da7e99bf5728f75f"
|
||||
checksum = "88034cfd6b4a0d54dd14f4a507eceee36c0b70e5a02236c4e4df571102be17f0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"version_check",
|
||||
|
@ -1353,9 +1396,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.1.11"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c917123afa01924fc84bb20c4c03f004d9c38e5127e3c039bbf7f4b9c76a2f6b"
|
||||
checksum = "6b063f57ec186e6140e2b8b6921e5f1bd89c7356dda5b33acc5401203ca6131c"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
|
@ -1732,9 +1775,9 @@ checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c"
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.50"
|
||||
version = "1.0.51"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443b4178719c5a851e1bde36ce12da21d74a0e60b4d982ec3385a933c812f0f6"
|
||||
checksum = "3b4f34193997d92804d359ed09953e25d5138df6bcc055a71bf68ee89fdf9223"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -1813,11 +1856,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.21"
|
||||
version = "0.1.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0987850db3733619253fe60e17cb59b82d37c7e6c0236bb81e4d6b87c879f27"
|
||||
checksum = "9f47026cdc4080c07e49b37087de021820269d996f581aac150ef9e5583eefe3"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"cfg-if 1.0.0",
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
@ -2023,9 +2066,9 @@ checksum = "3e2bb9fc8309084dd7cd651336673844c1d47f8ef6d2091ec160b27f5c4aa277"
|
|||
|
||||
[[package]]
|
||||
name = "wgpu"
|
||||
version = "0.6.0"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "549160f188eef412ac978499ddf0ceadad4c9159bb1160f9e6b9d4cc8ee977dc"
|
||||
checksum = "991903e4c9f5b7319732b30a3d0339e27a51ea992cea22769b5f6c7f7076af6d"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"futures",
|
||||
|
@ -2083,6 +2126,9 @@ dependencies = [
|
|||
"futures",
|
||||
"glob",
|
||||
"image",
|
||||
"imgui",
|
||||
"imgui-wgpu",
|
||||
"imgui-winit-support",
|
||||
"log",
|
||||
"shaderc",
|
||||
"tobj",
|
||||
|
|
|
@ -17,6 +17,9 @@ env_logger = "0.8"
|
|||
log = "0.4"
|
||||
tobj = "2"
|
||||
cgmath = "0.17"
|
||||
imgui = "0.6.0"
|
||||
imgui-wgpu = "0.12.0"
|
||||
imgui-winit-support = "0.6.0"
|
||||
|
||||
[build-dependencies]
|
||||
shaderc = "0.7"
|
||||
|
|
|
@ -98,8 +98,7 @@ impl CameraController {
|
|||
let f_spd = (self.speed * dt).min(forward_mag - 8.0);
|
||||
if self.is_forward_pressed && forward_mag > f_spd {
|
||||
camera.eye += forward_norm * f_spd;
|
||||
}
|
||||
else if self.is_backward_pressed {
|
||||
} else if self.is_backward_pressed {
|
||||
camera.eye -= forward_norm * self.speed * dt;
|
||||
}
|
||||
forward = camera.target - camera.eye;
|
||||
|
@ -111,10 +110,11 @@ impl CameraController {
|
|||
|
||||
if self.is_right_pressed != self.is_left_pressed {
|
||||
if self.is_right_pressed {
|
||||
camera.eye = camera.target - (forward - right * self.speed * dt).normalize() * forward_mag;
|
||||
}
|
||||
else if self.is_left_pressed {
|
||||
camera.eye = camera.target - (forward + right * self.speed * dt).normalize() * forward_mag;
|
||||
camera.eye =
|
||||
camera.target - (forward - right * self.speed * dt).normalize() * forward_mag;
|
||||
} else if self.is_left_pressed {
|
||||
camera.eye =
|
||||
camera.target - (forward + right * self.speed * dt).normalize() * forward_mag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
208
src/main.rs
208
src/main.rs
|
@ -1,3 +1,4 @@
|
|||
use imgui::im_str;
|
||||
use model::{DrawLight, DrawModel, Model, Vertex};
|
||||
use wgpu::util::DeviceExt;
|
||||
use winit::{
|
||||
|
@ -32,57 +33,62 @@ fn main() {
|
|||
.build(&event_loop)
|
||||
.expect("Failed to create window");
|
||||
|
||||
let mut state = futures::executor::block_on(State::new(&window));
|
||||
let mut previous_frame = std::time::Instant::now();
|
||||
let mut dt = std::time::Duration::new(0, 0);
|
||||
let mut state = futures::executor::block_on(State::new(window));
|
||||
let mut last_frame = std::time::Instant::now();
|
||||
|
||||
event_loop.run(move |event, _, control_flow| match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == window.id() => {
|
||||
if !state.input(event) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
} = input
|
||||
{
|
||||
*control_flow = ControlFlow::Exit
|
||||
event_loop.run(move |event, _, control_flow| {
|
||||
state
|
||||
.imgui_platform
|
||||
.handle_event(state.imgui.io_mut(), &state.window, &event);
|
||||
match event {
|
||||
Event::WindowEvent {
|
||||
ref event,
|
||||
window_id,
|
||||
} if window_id == state.window.id() => {
|
||||
if !state.input(event) {
|
||||
match event {
|
||||
WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
|
||||
WindowEvent::KeyboardInput { input, .. } => {
|
||||
if let KeyboardInput {
|
||||
state: ElementState::Pressed,
|
||||
virtual_keycode: Some(VirtualKeyCode::Escape),
|
||||
..
|
||||
} = input
|
||||
{
|
||||
*control_flow = ControlFlow::Exit
|
||||
}
|
||||
}
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
state.resize(*physical_size);
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
state.resize(**new_inner_size);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
WindowEvent::Resized(physical_size) => {
|
||||
state.resize(*physical_size);
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { new_inner_size, .. } => {
|
||||
state.resize(**new_inner_size);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
match state.render() {
|
||||
Ok(_) => {}
|
||||
Err(wgpu::SwapChainError::Lost) => state.resize(state.size),
|
||||
Err(wgpu::SwapChainError::OutOfMemory) => {
|
||||
eprintln!("Recieved a swapchain OOM error, exiting...");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
Err(_) => {}
|
||||
};
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
let now = std::time::Instant::now();
|
||||
let dt = now - last_frame;
|
||||
state.imgui.io_mut().update_delta_time(dt);
|
||||
state.update(dt.as_secs_f32());
|
||||
last_frame = now;
|
||||
state.window.request_redraw();
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
Event::RedrawRequested(_) => {
|
||||
match state.render() {
|
||||
Ok(_) => {}
|
||||
Err(wgpu::SwapChainError::Lost) => state.resize(state.size),
|
||||
Err(wgpu::SwapChainError::OutOfMemory) => {
|
||||
eprintln!("Recieved a swapchain OOM error, exiting...");
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
Err(_) => {}
|
||||
};
|
||||
}
|
||||
Event::MainEventsCleared => {
|
||||
state.update(dt.as_secs_f32());
|
||||
let now = std::time::Instant::now();
|
||||
dt = now - previous_frame;
|
||||
previous_frame = now;
|
||||
window.request_redraw();
|
||||
}
|
||||
_ => {}
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -168,6 +174,7 @@ struct InstanceRaw {
|
|||
}
|
||||
|
||||
struct State {
|
||||
window: Window,
|
||||
_instance: wgpu::Instance,
|
||||
surface: wgpu::Surface,
|
||||
_adapter: wgpu::Adapter,
|
||||
|
@ -197,14 +204,20 @@ struct State {
|
|||
render_pipeline: wgpu::RenderPipeline,
|
||||
|
||||
size: winit::dpi::PhysicalSize<u32>,
|
||||
|
||||
imgui: imgui::Context,
|
||||
imgui_platform: imgui_winit_support::WinitPlatform,
|
||||
imgui_renderer: imgui_wgpu::Renderer,
|
||||
|
||||
rotation_speed: f32,
|
||||
}
|
||||
|
||||
impl State {
|
||||
async fn new(window: &Window) -> Self {
|
||||
async fn new(window: Window) -> Self {
|
||||
let size = window.inner_size();
|
||||
let instance = wgpu::Instance::new(wgpu::BackendBit::PRIMARY);
|
||||
|
||||
let surface = unsafe { instance.create_surface(window) };
|
||||
let surface = unsafe { instance.create_surface(&window) };
|
||||
|
||||
let adapter = instance
|
||||
.request_adapter(&wgpu::RequestAdapterOptions {
|
||||
|
@ -292,7 +305,7 @@ impl State {
|
|||
(0..NUM_INSTANCES_PER_ROW).map(move |x| {
|
||||
let x = SPACE_BETWEEN * (x as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
|
||||
let z = SPACE_BETWEEN * (z as f32 - NUM_INSTANCES_PER_ROW as f32 / 2.0);
|
||||
let position = Vec3 {x, y: 0.0, z};
|
||||
let position = Vec3 { x, y: 0.0, z };
|
||||
|
||||
let rotation = if position.is_zero() {
|
||||
cgmath::Quaternion::from_axis_angle(Vec3::unit_z(), cgmath::Deg(0.0))
|
||||
|
@ -430,7 +443,43 @@ impl State {
|
|||
let depth_texture =
|
||||
texture::Texture::create_depth_texture(&device, &sc_desc, "depth_texture");
|
||||
|
||||
let mut imgui = imgui::Context::create();
|
||||
let mut imgui_platform = imgui_winit_support::WinitPlatform::init(&mut imgui);
|
||||
imgui_platform.attach_window(
|
||||
imgui.io_mut(),
|
||||
&window,
|
||||
imgui_winit_support::HiDpiMode::Default,
|
||||
);
|
||||
|
||||
imgui.set_ini_filename(None);
|
||||
|
||||
let hidpi_factor = window.scale_factor();
|
||||
let font_size = (13.0 * hidpi_factor) as f32;
|
||||
imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32;
|
||||
|
||||
imgui
|
||||
.fonts()
|
||||
.add_font(&[imgui::FontSource::DefaultFontData {
|
||||
config: Some(imgui::FontConfig {
|
||||
oversample_h: 1,
|
||||
pixel_snap_h: true,
|
||||
size_pixels: font_size,
|
||||
..Default::default()
|
||||
}),
|
||||
}]);
|
||||
|
||||
let imgui_renderer = imgui_wgpu::Renderer::new(
|
||||
&mut imgui,
|
||||
&device,
|
||||
&queue,
|
||||
imgui_wgpu::RendererConfig {
|
||||
texture_format: sc_desc.format,
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
Self {
|
||||
window,
|
||||
_instance: instance,
|
||||
surface,
|
||||
_adapter: adapter,
|
||||
|
@ -453,6 +502,10 @@ impl State {
|
|||
instance_buffer,
|
||||
render_pipeline,
|
||||
size,
|
||||
imgui,
|
||||
imgui_platform,
|
||||
imgui_renderer,
|
||||
rotation_speed: 1.0,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,6 +520,16 @@ impl State {
|
|||
}
|
||||
|
||||
fn input(&mut self, event: &WindowEvent) -> bool {
|
||||
if let WindowEvent::KeyboardInput { .. } = event {
|
||||
if self.imgui.io().want_capture_keyboard {
|
||||
return true;
|
||||
}
|
||||
} else if let WindowEvent::MouseInput { .. } = event {
|
||||
if self.imgui.io().want_capture_mouse {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
self.camera_controller.process_events(event)
|
||||
}
|
||||
|
||||
|
@ -504,14 +567,18 @@ impl State {
|
|||
self.queue
|
||||
.write_buffer(&self.light_buffer, 0, bytemuck::cast_slice(&[self.light]));
|
||||
|
||||
let deg = cgmath::Deg(30.0 * dt * self.rotation_speed);
|
||||
for instance in &mut self.instances {
|
||||
let deg = cgmath::Deg(30.0 * dt);
|
||||
let rot = cgmath::Quaternion::from(cgmath::Euler::new(deg, deg, deg));
|
||||
let rot = cgmath::Quaternion::from(cgmath::Euler::new(deg, deg*1.1, deg*1.2));
|
||||
instance.rotation = instance.rotation * rot;
|
||||
}
|
||||
|
||||
let instance_data: Vec<_> = self.instances.iter().map(Instance::to_raw).collect();
|
||||
self.queue.write_buffer(&self.instance_buffer, 0, bytemuck::cast_slice(&instance_data));
|
||||
self.queue.write_buffer(
|
||||
&self.instance_buffer,
|
||||
0,
|
||||
bytemuck::cast_slice(&instance_data),
|
||||
);
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
}
|
||||
|
@ -519,6 +586,24 @@ impl State {
|
|||
fn render(&mut self) -> Result<(), wgpu::SwapChainError> {
|
||||
let frame = self.swap_chain.get_current_frame()?;
|
||||
|
||||
self.imgui_platform
|
||||
.prepare_frame(self.imgui.io_mut(), &self.window)
|
||||
.expect("Failed to prepare imgui frame");
|
||||
let ui = self.imgui.frame();
|
||||
|
||||
{
|
||||
let mut spd = self.rotation_speed;
|
||||
imgui::Window::new(im_str!("wgpu tutorial!"))
|
||||
.size([300.0, 100.0], imgui::Condition::FirstUseEver)
|
||||
.build(&ui, || {
|
||||
ui.text(im_str!("wooo!"));
|
||||
imgui::Slider::new(im_str!("RotSpeed"))
|
||||
.range(-10.0..=10.0)
|
||||
.build(&ui, &mut spd);
|
||||
});
|
||||
self.rotation_speed = spd;
|
||||
}
|
||||
|
||||
let mut encoder = self
|
||||
.device
|
||||
.create_command_encoder(&wgpu::CommandEncoderDescriptor {
|
||||
|
@ -568,6 +653,27 @@ impl State {
|
|||
|
||||
drop(render_pass);
|
||||
|
||||
self.imgui_platform.prepare_render(&ui, &self.window);
|
||||
|
||||
let mut rpass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &frame.output.view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load, // Do not clear
|
||||
// load: wgpu::LoadOp::Clear(clear_color),
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
|
||||
self.imgui_renderer
|
||||
.render(ui.render(), &self.queue, &self.device, &mut rpass)
|
||||
.expect("Failed to render UI!");
|
||||
|
||||
drop(rpass);
|
||||
|
||||
self.queue.submit(Some(encoder.finish()));
|
||||
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue