mirror of https://github.com/sotrh/learn-wgpu
finished cleanup
parent
7e9f305f7b
commit
f1d35b6b38
@ -0,0 +1,135 @@
|
||||
# Basic Imgui Demo
|
||||
|
||||
This is not an in depth guid on how to use Imgui. But here are some of the basics you'll need to get started. We'll need to import [imgui-rs](https://docs.rs/imgui), [imgui-wgpu](https://docs.rs/imgui-wgpu), and [imgui-winit-support](https://docs.rs/imgui-winit-support).
|
||||
|
||||
```toml
|
||||
imgui = "0.6"
|
||||
imgui-wgpu = "0.12"
|
||||
imgui-winit-support = "0.6"
|
||||
```
|
||||
|
||||
<div class="note">
|
||||
|
||||
I've excluded some dependencies for brevity. I'm also using the [framework crate](https://github.com/sotrh/learn-wgpu/tree/master/code/showcase/framework) I've created for showcases to simplify setup. If you see a `display` variable in code, it's from the `framework`. `Display` is where the the `device`, `queue`, `swap_chain`, and other basic wgpu objects are stored.
|
||||
|
||||
</div>
|
||||
|
||||
We need to setup imgui and a `WinitPlatform` to get started. Do this after creating you're `winit::Window`.
|
||||
|
||||
```rust
|
||||
let mut imgui = imgui::Context::create();
|
||||
let mut platform = imgui_winit_support::WinitPlatform::init(&mut imgui);
|
||||
platform.attach_window(
|
||||
imgui.io_mut(),
|
||||
&display.window,
|
||||
imgui_winit_support::HiDpiMode::Default,
|
||||
);
|
||||
imgui.set_ini_filename(None);
|
||||
```
|
||||
|
||||
Now we need to configure the default font. We'll using the window's scale factor to keep things from being too big or small.
|
||||
|
||||
```rust
|
||||
let hidpi_factor = display.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(&[FontSource::DefaultFontData {
|
||||
config: Some(imgui::FontConfig {
|
||||
oversample_h: 1,
|
||||
pixel_snap_h: true,
|
||||
size_pixels: font_size,
|
||||
..Default::default()
|
||||
}),
|
||||
}]);
|
||||
```
|
||||
|
||||
Then you need to create the renderer. We need to use the swap chains `TextureFormat` in order for things to work properly.
|
||||
|
||||
```rust
|
||||
let renderer_config = RendererConfig {
|
||||
texture_format: display.sc_desc.format,
|
||||
..Default::default()
|
||||
};
|
||||
let renderer = Renderer::new(&mut imgui, &display.device, &display.queue, renderer_config);
|
||||
```
|
||||
|
||||
When we update the scene, we'll need to update imgui.
|
||||
|
||||
```rust
|
||||
self.imgui.io_mut().update_delta_time(dt); // dt: std::time::Duration
|
||||
```
|
||||
|
||||
I'm not an expert with imgui, so I'll let the code speak for itself.
|
||||
|
||||
```rust
|
||||
// Build the UI
|
||||
self.platform
|
||||
.prepare_frame(self.imgui.io_mut(), &display.window)
|
||||
.expect("Failed to prepare frame!");
|
||||
let ui = self.imgui.frame();
|
||||
{
|
||||
let window = imgui::Window::new(im_str!("Hello Imgui from WGPU!"));
|
||||
window
|
||||
.size([300.0, 100.0], Condition::FirstUseEver)
|
||||
.build(&ui, || {
|
||||
ui.text(im_str!("Hello world!"));
|
||||
ui.text(im_str!("This is a demo of imgui-rs using imgui-wgpu!"));
|
||||
ui.separator();
|
||||
let mouse_pos = ui.io().mouse_pos;
|
||||
ui.text(im_str!(
|
||||
"Mouse Position: ({:.1}, {:.1})",
|
||||
mouse_pos[0],
|
||||
mouse_pos[1],
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
// Prepare to render
|
||||
let mut encoder = display.device.create_command_encoder(&Default::default());
|
||||
let output = match display.swap_chain.get_current_frame() {
|
||||
Ok(frame) => frame,
|
||||
Err(e) => {
|
||||
eprintln!("Error getting frame: {:?}", e);
|
||||
return;
|
||||
}
|
||||
}.output;
|
||||
|
||||
// Render the scene
|
||||
self.canvas.render(
|
||||
&display.queue,
|
||||
&mut encoder,
|
||||
&output.view,
|
||||
display.sc_desc.width as f32,
|
||||
display.sc_desc.height as f32
|
||||
);
|
||||
|
||||
// Render the UI
|
||||
if self.last_cursor != ui.mouse_cursor() {
|
||||
self.last_cursor = ui.mouse_cursor();
|
||||
self.platform.prepare_render(&ui, &display.window);
|
||||
}
|
||||
|
||||
let mut pass = encoder.begin_render_pass(&wgpu::RenderPassDescriptor {
|
||||
color_attachments: &[wgpu::RenderPassColorAttachmentDescriptor {
|
||||
attachment: &output.view,
|
||||
resolve_target: None,
|
||||
ops: wgpu::Operations {
|
||||
load: wgpu::LoadOp::Load,
|
||||
store: true,
|
||||
},
|
||||
}],
|
||||
depth_stencil_attachment: None,
|
||||
});
|
||||
self.renderer
|
||||
.render(ui.render(), &display.queue, &display.device, &mut pass)
|
||||
.expect("Failed to render UI!");
|
||||
drop(pass);
|
||||
|
||||
display.queue.submit(Some(encoder.finish()));
|
||||
```
|
||||
|
||||
That's all there is to it. Here's a picture of the results!
|
||||
|
||||
![./screenshot.png](./screenshot.png)
|
||||
|
||||
<AutoGithubLink/>
|
Binary file not shown.
After Width: | Height: | Size: 11 KiB |
Loading…
Reference in New Issue