From 42e52ef6718470fc54f3d827889aa6b80c038daa Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Mon, 1 Jul 2019 13:29:13 +0300 Subject: [PATCH] Update gfx examples --- README.markdown | 3 +- imgui-gfx-examples/Cargo.lock | 2 + imgui-gfx-examples/Cargo.toml | 4 +- imgui-gfx-examples/examples/hello_gfx.rs | 34 --- imgui-gfx-examples/examples/hello_world.rs | 29 ++ imgui-gfx-examples/examples/support/mod.rs | 267 ++++++++++++++++++ .../examples/support_gfx/mod.rs | 239 ---------------- imgui-gfx-examples/examples/test_window.rs | 6 + 8 files changed, 309 insertions(+), 275 deletions(-) delete mode 100644 imgui-gfx-examples/examples/hello_gfx.rs create mode 100644 imgui-gfx-examples/examples/hello_world.rs create mode 100644 imgui-gfx-examples/examples/support/mod.rs delete mode 100644 imgui-gfx-examples/examples/support_gfx/mod.rs create mode 100644 imgui-gfx-examples/examples/test_window.rs diff --git a/README.markdown b/README.markdown index 47aa3e9..117f526 100644 --- a/README.markdown +++ b/README.markdown @@ -71,7 +71,8 @@ Examples for the gfx backend are under the imgui-gfx-examples directory. cd imgui-gfx-examples cargo test - cargo run --example hello_gfx + cargo run --example hello_world + cargo run --example test_window Note to Windows users: You will need to use the *MSVC ABI* version of the Rust compiler along with its associated [dependencies](https://www.rust-lang.org/en-US/downloads.html#win-foot) to diff --git a/imgui-gfx-examples/Cargo.lock b/imgui-gfx-examples/Cargo.lock index 7ffff64..2cc733f 100644 --- a/imgui-gfx-examples/Cargo.lock +++ b/imgui-gfx-examples/Cargo.lock @@ -361,6 +361,8 @@ name = "imgui-gfx-examples" version = "0.1.0-pre" dependencies = [ "gfx 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)", + "gfx_device_dx11 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", + "gfx_device_gl 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_window_dxgi 0.19.1 (registry+https://github.com/rust-lang/crates.io-index)", "gfx_window_glutin 0.31.0 (registry+https://github.com/rust-lang/crates.io-index)", "glutin 0.21.0 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/imgui-gfx-examples/Cargo.toml b/imgui-gfx-examples/Cargo.toml index 9fc13a1..f692dc0 100644 --- a/imgui-gfx-examples/Cargo.toml +++ b/imgui-gfx-examples/Cargo.toml @@ -16,6 +16,7 @@ default = ["opengl"] [dev-dependencies] gfx = "0.18" +gfx_device_gl = "0.16" gfx_window_glutin = "0.31" glutin = "0.21" imgui = { version = "0.1.0-pre", path = "../" } @@ -23,4 +24,5 @@ imgui-gfx-renderer = { version = "0.1.0-pre", path = "../imgui-gfx-renderer" } imgui-winit-support = { version = "0.1.0-pre", path = "../imgui-winit-support" } [target.'cfg(windows)'.dev-dependencies] -gfx_window_dxgi = "0.19" +gfx_device_dx11 = "0.8" +gfx_window_dxgi = "0.19" \ No newline at end of file diff --git a/imgui-gfx-examples/examples/hello_gfx.rs b/imgui-gfx-examples/examples/hello_gfx.rs deleted file mode 100644 index 8f7bc61..0000000 --- a/imgui-gfx-examples/examples/hello_gfx.rs +++ /dev/null @@ -1,34 +0,0 @@ -use imgui::*; - -mod support_gfx; - -const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; - -fn main() { - support_gfx::run("hello_gfx.rs".to_owned(), CLEAR_COLOR, hello_world); -} - -fn hello_world<'a>(ui: &Ui<'a>) -> bool { - #[cfg(feature = "opengl")] - let window_title = im_str!("Hello world (OpenGL)"); - - #[cfg(feature = "directx")] - let window_title = im_str!("Hello world (DirectX)"); - - ui.window(window_title) - .size([300.0, 100.0], Condition::FirstUseEver) - .build(|| { - ui.text(im_str!("Hello world!")); - ui.text(im_str!("こんにちは世界!")); - ui.text(im_str!("This...is...imgui-rs!")); - ui.separator(); - let mouse_pos = ui.io().mouse_pos; - ui.text(im_str!( - "Mouse Position: ({:.1},{:.1})", - mouse_pos[0], - mouse_pos[1] - )); - }); - - true -} diff --git a/imgui-gfx-examples/examples/hello_world.rs b/imgui-gfx-examples/examples/hello_world.rs new file mode 100644 index 0000000..cea8da9 --- /dev/null +++ b/imgui-gfx-examples/examples/hello_world.rs @@ -0,0 +1,29 @@ +use imgui::*; + +mod support; + +fn main() { + let system = support::init(file!()); + + #[cfg(feature = "opengl")] + let window_title = im_str!("Hello world (OpenGL)"); + + #[cfg(feature = "directx")] + let window_title = im_str!("Hello world (DirectX)"); + + system.main_loop(|_, ui| { + ui.window(window_title) + .size([300.0, 100.0], Condition::FirstUseEver) + .build(|| { + ui.text(im_str!("Hello world!")); + ui.text(im_str!("こんにちは世界!")); + ui.text(im_str!("This...is...imgui-rs!")); + ui.separator(); + let mouse_pos = ui.io().mouse_pos; + ui.text(format!( + "Mouse Position: ({:.1},{:.1})", + mouse_pos[0], mouse_pos[1] + )); + }); + }); +} diff --git a/imgui-gfx-examples/examples/support/mod.rs b/imgui-gfx-examples/examples/support/mod.rs new file mode 100644 index 0000000..0ecb8e8 --- /dev/null +++ b/imgui-gfx-examples/examples/support/mod.rs @@ -0,0 +1,267 @@ +use gfx::Device; +use glutin::{Event, WindowEvent}; +use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui}; +use imgui_gfx_renderer::{GfxRenderer, Shaders}; +use imgui_winit_support::{HiDpiMode, WinitPlatform}; +use std::time::Instant; + +type ColorFormat = gfx::format::Rgba8; + +pub struct System { + pub events_loop: glutin::EventsLoop, + pub imgui: Context, + pub platform: WinitPlatform, + pub render_sys: RenderSystem, + pub font_size: f32, +} + +pub fn init(title: &str) -> System { + let title = match title.rfind('/') { + Some(idx) => title.split_at(idx + 1).1, + None => title, + }; + let events_loop = glutin::EventsLoop::new(); + let builder = glutin::WindowBuilder::new() + .with_title(title.to_owned()) + .with_dimensions(glutin::dpi::LogicalSize::new(1024f64, 768f64)); + + let mut imgui = Context::create(); + imgui.set_ini_filename(None); + + let mut platform = WinitPlatform::init(&mut imgui); + + let hidpi_factor = platform.hidpi_factor(); + let font_size = (13.0 * hidpi_factor) as f32; + imgui.fonts().add_font(&[ + FontSource::DefaultFontData { + config: Some(FontConfig { + size_pixels: font_size, + ..FontConfig::default() + }), + }, + FontSource::TtfData { + data: include_bytes!("../../../resources/mplus-1p-regular.ttf"), + size_pixels: font_size, + config: Some(FontConfig { + rasterizer_multiply: 1.75, + glyph_ranges: FontGlyphRanges::japanese(), + ..FontConfig::default() + }), + }, + ]); + + imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32; + + let render_sys = RenderSystem::init(&mut imgui, builder, &events_loop); + platform.attach_window(imgui.io_mut(), render_sys.window(), HiDpiMode::Rounded); + System { + events_loop, + imgui, + platform, + render_sys, + font_size, + } +} + +impl System { + pub fn main_loop(self, mut run_ui: F) { + let System { + mut events_loop, + mut imgui, + mut platform, + mut render_sys, + .. + } = self; + let mut encoder: gfx::Encoder<_, _> = render_sys.factory.create_command_buffer().into(); + + let mut last_frame = Instant::now(); + let mut run = true; + + while run { + events_loop.poll_events(|event| { + platform.handle_event(imgui.io_mut(), render_sys.window(), &event); + + if let Event::WindowEvent { event, .. } = event { + match event { + WindowEvent::Resized(size) => render_sys.update_views(size), + WindowEvent::CloseRequested => run = false, + _ => (), + } + } + }); + + let io = imgui.io_mut(); + platform + .prepare_frame(io, render_sys.window()) + .expect("Failed to start frame"); + last_frame = io.update_delta_time(last_frame); + let mut ui = imgui.frame(); + run_ui(&mut run, &mut ui); + + if let Some(main_color) = render_sys.main_color.as_mut() { + encoder.clear(main_color, [1.0, 1.0, 1.0, 1.0]); + } + platform.prepare_render(&ui, render_sys.window()); + let draw_data = ui.render(); + if let Some(main_color) = render_sys.main_color.as_mut() { + render_sys + .renderer + .render(&mut render_sys.factory, &mut encoder, main_color, draw_data) + .expect("Rendering failed"); + } + encoder.flush(&mut render_sys.device); + render_sys.swap_buffers(); + render_sys.device.cleanup(); + } + } +} + +#[cfg(feature = "opengl")] +mod types { + pub type Device = gfx_device_gl::Device; + pub type Factory = gfx_device_gl::Factory; + pub type Resources = gfx_device_gl::Resources; +} + +#[cfg(feature = "opengl")] +pub struct RenderSystem { + pub renderer: GfxRenderer, + pub windowed_context: glutin::WindowedContext, + pub device: types::Device, + pub factory: types::Factory, + pub main_color: Option>, + pub main_depth: gfx::handle::DepthStencilView, +} + +#[cfg(feature = "opengl")] +impl RenderSystem { + pub fn init( + imgui: &mut Context, + builder: glutin::WindowBuilder, + events_loop: &glutin::EventsLoop, + ) -> RenderSystem { + { + // Fix incorrect colors with sRGB framebuffer + fn imgui_gamma_to_linear(col: [f32; 4]) -> [f32; 4] { + let x = col[0].powf(2.2); + let y = col[1].powf(2.2); + let z = col[2].powf(2.2); + let w = 1.0 - (1.0 - col[3]).powf(2.2); + [x, y, z, w] + } + + let style = imgui.style_mut(); + for col in 0..style.colors.len() { + style.colors[col] = imgui_gamma_to_linear(style.colors[col]); + } + } + + let context = glutin::ContextBuilder::new().with_vsync(true); + let (windowed_context, device, mut factory, main_color, main_depth) = + gfx_window_glutin::init(builder, context, &events_loop) + .expect("Failed to initialize graphics"); + let shaders = { + let version = device.get_info().shading_language; + if version.is_embedded { + if version.major >= 3 { + Shaders::GlSlEs300 + } else { + Shaders::GlSlEs100 + } + } else if version.major >= 4 { + Shaders::GlSl400 + } else if version.major >= 3 { + if version.minor >= 2 { + Shaders::GlSl150 + } else { + Shaders::GlSl130 + } + } else { + Shaders::GlSl110 + } + }; + let renderer = + GfxRenderer::init(imgui, &mut factory, shaders).expect("Failed to initialize renderer"); + RenderSystem { + renderer, + windowed_context, + device, + factory, + main_color: Some(main_color), + main_depth, + } + } + pub fn window(&self) -> &glutin::Window { + self.windowed_context.window() + } + pub fn update_views(&mut self, _: glutin::dpi::LogicalSize) { + if let Some(main_color) = self.main_color.as_mut() { + gfx_window_glutin::update_views( + &self.windowed_context, + main_color, + &mut self.main_depth, + ); + } + } + pub fn swap_buffers(&mut self) { + self.windowed_context.swap_buffers().unwrap(); + } +} + +#[cfg(feature = "directx")] +mod types { + pub type Device = gfx_device_dx11::Device; + pub type Factory = gfx_device_dx11::Factory; + pub type Resources = gfx_device_dx11::Resources; +} + +#[cfg(feature = "directx")] +pub struct RenderSystem { + pub renderer: GfxRenderer, + pub window: gfx_window_dxgi::Window, + pub device: types::Device, + pub factory: types::Factory, + pub main_color: Option>, +} + +#[cfg(feature = "directx")] +impl RenderSystem { + pub fn init( + imgui: &mut Context, + builder: glutin::WindowBuilder, + events_loop: &glutin::EventsLoop, + ) -> RenderSystem { + let (window, device, mut factory, main_color) = + gfx_window_dxgi::init(builder, &events_loop).expect("Failed to initialize graphics"); + let renderer = GfxRenderer::init(imgui, &mut factory, Shaders::HlslSm40) + .expect("Failed to initialize renderer"); + RenderSystem { + renderer, + window, + device, + factory, + main_color: Some(main_color), + } + } + pub fn window(&self) -> &glutin::Window { + &self.window.inner + } + pub fn update_views(&mut self, size: glutin::dpi::LogicalSize) { + let physical = size.to_physical(self.window().get_hidpi_factor()); + let (width, height): (u32, u32) = physical.into(); + let _ = self.main_color.take(); // we need to drop main_color before calling update_views + self.main_color = Some( + gfx_window_dxgi::update_views( + &mut self.window, + &mut self.factory, + &mut self.device, + width as u16, + height as u16, + ) + .expect("Failed to update resize"), + ); + } + pub fn swap_buffers(&mut self) { + self.window.swap_buffers(1); + } +} diff --git a/imgui-gfx-examples/examples/support_gfx/mod.rs b/imgui-gfx-examples/examples/support_gfx/mod.rs deleted file mode 100644 index 6a1ccf9..0000000 --- a/imgui-gfx-examples/examples/support_gfx/mod.rs +++ /dev/null @@ -1,239 +0,0 @@ -use gfx::Device; -use glutin::{Event, WindowEvent}; -use imgui::{Context, FontConfig, FontGlyphRanges, FontSource, Ui}; -use imgui_gfx_renderer::{GfxRenderer, Shaders}; -use imgui_winit_support::{HiDpiMode, WinitPlatform}; -use std::time::Instant; - -type ColorFormat = gfx::format::Rgba8; - -#[cfg(feature = "opengl")] -pub fn run bool>(title: String, clear_color: [f32; 4], mut run_ui: F) { - type DepthFormat = gfx::format::DepthStencil; - - let mut events_loop = glutin::EventsLoop::new(); - let context = glutin::ContextBuilder::new().with_vsync(true); - let builder = glutin::WindowBuilder::new() - .with_title(title.to_owned()) - .with_dimensions(glutin::dpi::LogicalSize::new(1024f64, 768f64)); - let (windowed_context, mut device, mut factory, mut main_color, mut main_depth) = - gfx_window_glutin::init::(builder, context, &events_loop) - .expect("Failed to initialize graphics"); - let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); - - let shaders = { - let version = device.get_info().shading_language; - if version.is_embedded { - if version.major >= 3 { - Shaders::GlSlEs300 - } else { - Shaders::GlSlEs100 - } - } else if version.major >= 4 { - Shaders::GlSl400 - } else if version.major >= 3 { - if version.minor >= 2 { - Shaders::GlSl150 - } else { - Shaders::GlSl130 - } - } else { - Shaders::GlSl110 - } - }; - - let mut imgui = Context::create(); - { - // Fix incorrect colors with sRGB framebuffer - fn imgui_gamma_to_linear(col: [f32; 4]) -> [f32; 4] { - let x = col[0].powf(2.2); - let y = col[1].powf(2.2); - let z = col[2].powf(2.2); - let w = 1.0 - (1.0 - col[3]).powf(2.2); - [x, y, z, w] - } - - let style = imgui.style_mut(); - for col in 0..style.colors.len() { - style.colors[col] = imgui_gamma_to_linear(style.colors[col]); - } - } - imgui.set_ini_filename(None); - - let mut platform = WinitPlatform::init(&mut imgui); - platform.attach_window( - imgui.io_mut(), - &windowed_context.window(), - HiDpiMode::Rounded, - ); - - let hidpi_factor = platform.hidpi_factor(); - let font_size = (13.0 * hidpi_factor) as f32; - imgui.fonts().add_font(&[ - FontSource::DefaultFontData { - config: Some(FontConfig { - size_pixels: font_size, - ..FontConfig::default() - }), - }, - FontSource::TtfData { - data: include_bytes!("../../../resources/mplus-1p-regular.ttf"), - size_pixels: font_size, - config: Some(FontConfig { - rasterizer_multiply: 1.75, - glyph_ranges: FontGlyphRanges::japanese(), - ..FontConfig::default() - }), - }, - ]); - - imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32; - - let mut renderer = GfxRenderer::init(&mut imgui, &mut factory, shaders) - .expect("Failed to initialize renderer"); - - let mut last_frame = Instant::now(); - let mut quit = false; - - loop { - events_loop.poll_events(|event| { - platform.handle_event(imgui.io_mut(), &windowed_context.window(), &event); - - if let Event::WindowEvent { event, .. } = event { - match event { - WindowEvent::Resized(_) => gfx_window_glutin::update_views( - &windowed_context, - &mut main_color, - &mut main_depth, - ), - WindowEvent::CloseRequested => quit = true, - _ => (), - } - } - }); - if quit { - break; - } - - let io = imgui.io_mut(); - platform - .prepare_frame(io, &windowed_context.window()) - .expect("Failed to start frame"); - last_frame = io.update_delta_time(last_frame); - - let ui = imgui.frame(); - if !run_ui(&ui) { - break; - } - - encoder.clear(&main_color, clear_color); - platform.prepare_render(&ui, &windowed_context.window()); - let draw_data = ui.render(); - renderer - .render(&mut factory, &mut encoder, &mut main_color, draw_data) - .expect("Rendering failed"); - encoder.flush(&mut device); - windowed_context.swap_buffers().unwrap(); - device.cleanup(); - } -} - -#[cfg(feature = "directx")] -pub fn run bool>(title: String, clear_color: [f32; 4], mut run_ui: F) { - let mut events_loop = glutin::EventsLoop::new(); - let window = glutin::WindowBuilder::new() - .with_title(title) - .with_dimensions(glutin::dpi::LogicalSize::new(1024f64, 768f64)); - let (mut window, mut device, mut factory, mut main_color) = - gfx_window_dxgi::init::(window, &events_loop) - .expect("Failed to initialize graphics"); - let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); - - let mut imgui = Context::create(); - imgui.set_ini_filename(None); - - let mut platform = WinitPlatform::init(&mut imgui); - platform.attach_window(imgui.io_mut(), &window.inner, HiDpiMode::Rounded); - - let hidpi_factor = platform.hidpi_factor(); - let font_size = (13.0 * hidpi_factor) as f32; - imgui.fonts().add_font(&[ - FontSource::DefaultFontData { - config: Some(FontConfig { - size_pixels: font_size, - ..FontConfig::default() - }), - }, - FontSource::TtfData { - data: include_bytes!("../../../resources/mplus-1p-regular.ttf"), - size_pixels: font_size, - config: Some(FontConfig { - rasterizer_multiply: 1.75, - glyph_ranges: FontGlyphRanges::japanese(), - ..FontConfig::default() - }), - }, - ]); - - imgui.io_mut().font_global_scale = (1.0 / hidpi_factor) as f32; - - let mut renderer = GfxRenderer::init(&mut imgui, &mut factory, Shaders::HlslSm40) - .expect("Failed to initialize renderer"); - - let mut last_frame = Instant::now(); - let mut quit = false; - - loop { - let mut new_size = None; - events_loop.poll_events(|event| { - platform.handle_event(imgui.io_mut(), &window.inner, &event); - - if let Event::WindowEvent { event, .. } = event { - match event { - WindowEvent::Resized(size) => { - let physical = size.to_physical(window.inner.get_hidpi_factor()); - let (width, height): (u32, u32) = physical.into(); - new_size = Some((width as u16, height as u16)); - } - WindowEvent::CloseRequested => quit = true, - _ => (), - } - } - }); - if quit { - break; - } - if let Some((width, height)) = new_size { - drop(main_color); - main_color = gfx_window_dxgi::update_views( - &mut window, - &mut factory, - &mut device, - width, - height, - ) - .expect("Failed to update resize"); - } - - let io = imgui.io_mut(); - platform - .prepare_frame(io, &window.inner) - .expect("Failed to start frame"); - last_frame = io.update_delta_time(last_frame); - - let ui = imgui.frame(); - if !run_ui(&ui) { - break; - } - - encoder.clear(&main_color, clear_color); - platform.prepare_render(&ui, &window.inner); - let draw_data = ui.render(); - renderer - .render(&mut factory, &mut encoder, &mut main_color, draw_data) - .expect("Rendering failed"); - encoder.flush(&mut device); - window.swap_buffers(1); - device.cleanup(); - } -} diff --git a/imgui-gfx-examples/examples/test_window.rs b/imgui-gfx-examples/examples/test_window.rs new file mode 100644 index 0000000..72d1bab --- /dev/null +++ b/imgui-gfx-examples/examples/test_window.rs @@ -0,0 +1,6 @@ +mod support; + +fn main() { + let system = support::init(file!()); + system.main_loop(|run, ui| ui.show_demo_window(run)); +}