1
0
Fork 0

Add imgui

This commit is contained in:
Adrian Hedqvist 2020-11-26 17:17:41 +01:00
parent ab9d965630
commit 7a8b9a973c
4 changed files with 230 additions and 75 deletions

82
Cargo.lock generated
View file

@ -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",

View file

@ -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"

View file

@ -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;
}
}
}

View file

@ -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(())