From 9db8cf94cf33b494e0ee225637c95e6e39d6c54f Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Tue, 21 Feb 2017 00:55:45 +0200 Subject: [PATCH 01/11] Initial gfx support in imgui-sys --- imgui-sys/Cargo.toml | 1 + imgui-sys/src/gfx_support.rs | 58 ++++++++++++++++++++++++++++++++++ imgui-sys/src/glium_support.rs | 2 +- imgui-sys/src/lib.rs | 7 ++++ 4 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 imgui-sys/src/gfx_support.rs diff --git a/imgui-sys/Cargo.toml b/imgui-sys/Cargo.toml index cbeeeb1..97b0097 100644 --- a/imgui-sys/Cargo.toml +++ b/imgui-sys/Cargo.toml @@ -12,6 +12,7 @@ build = "build.rs" [dependencies] bitflags = "0.8" glium = { version = "0.16", default-features = false, optional = true } +gfx = { version = "0.14", optional = true } [build-dependencies] gcc = "0.3" diff --git a/imgui-sys/src/gfx_support.rs b/imgui-sys/src/gfx_support.rs new file mode 100644 index 0000000..e6adb53 --- /dev/null +++ b/imgui-sys/src/gfx_support.rs @@ -0,0 +1,58 @@ +use gfx::format::{Format, Formatted, U8Norm}; +use gfx::pso::buffer::{Element, ElemOffset, Structure}; +use gfx::traits::Pod; +use std::mem; + +use super::{ImDrawVert, ImVec2}; + +unsafe impl Pod for ImDrawVert {} + +impl Structure for ImDrawVert { + fn query(name: &str) -> Option> { + // array query hack from gfx_impl_struct_meta macro + let (sub_name, big_offset) = { + let mut split = name.split(|c| c == '[' || c == ']'); + let _ = split.next().unwrap(); + match split.next() { + Some(s) => { + let array_id: ElemOffset = s.parse().unwrap(); + let sub_name = match split.next() { + Some(s) if s.starts_with('.') => &s[1..], + _ => name, + }; + (sub_name, array_id * (mem::size_of::() as ElemOffset)) + } + None => (name, 0), + } + }; + let dummy: &ImDrawVert = unsafe { mem::transmute(0usize) }; + match sub_name { + "pos" => { + Some(Element { + format: ::get_format(), + offset: unsafe { mem::transmute::<_, usize>(&dummy.pos) } as ElemOffset + + big_offset, + }) + } + "uv" => { + Some(Element { + format: ::get_format(), + offset: unsafe { mem::transmute::<_, usize>(&dummy.uv) } as ElemOffset + + big_offset, + }) + } + "col" => { + Some(Element { + format: <[U8Norm; 4] as Formatted>::get_format(), + offset: unsafe { mem::transmute::<_, usize>(&dummy.col) } as ElemOffset + + big_offset, + }) + } + _ => None, + } + } +} + +gfx_format! { + ImVec2: R32_G32 = Vec2 +} diff --git a/imgui-sys/src/glium_support.rs b/imgui-sys/src/glium_support.rs index 492266c..0ec4248 100644 --- a/imgui-sys/src/glium_support.rs +++ b/imgui-sys/src/glium_support.rs @@ -1,7 +1,7 @@ use glium::vertex::{Attribute, AttributeType, Vertex, VertexFormat}; use std::borrow::Cow; use std::mem; -use std::os::raw::{c_float}; +use std::os::raw::c_float; use super::{ImDrawVert, ImVec2, ImVec4}; diff --git a/imgui-sys/src/lib.rs b/imgui-sys/src/lib.rs index c8e2cb3..d0e2d1d 100644 --- a/imgui-sys/src/lib.rs +++ b/imgui-sys/src/lib.rs @@ -3,6 +3,10 @@ #[macro_use] extern crate bitflags; +#[cfg(feature = "gfx")] +#[macro_use] +extern crate gfx; + #[cfg(feature = "glium")] extern crate glium; @@ -11,6 +15,9 @@ use std::mem; use std::os::raw::{c_char, c_float, c_int, c_short, c_uchar, c_uint, c_ushort, c_void}; use std::slice; +#[cfg(feature = "gfx")] +mod gfx_support; + #[cfg(feature = "glium")] mod glium_support; From 4ee27d149cc387fdfe1656fbabc544d798f288f7 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Tue, 21 Feb 2017 01:01:55 +0200 Subject: [PATCH 02/11] Initial working but dirty gfx renderer --- CHANGELOG.markdown | 2 + Cargo.toml | 2 +- imgui-examples/Cargo.toml | 6 +- imgui-examples/examples/hello_gfx.rs | 73 +++++++++ imgui-examples/examples/support_gfx/mod.rs | 114 ++++++++++++++ imgui-gfx-renderer/Cargo.toml | 13 ++ imgui-gfx-renderer/src/lib.rs | 160 ++++++++++++++++++++ imgui-gfx-renderer/src/shader/frag_110.glsl | 10 ++ imgui-gfx-renderer/src/shader/frag_140.glsl | 12 ++ imgui-gfx-renderer/src/shader/vert_110.glsl | 16 ++ imgui-gfx-renderer/src/shader/vert_140.glsl | 16 ++ 11 files changed, 422 insertions(+), 2 deletions(-) create mode 100644 imgui-examples/examples/hello_gfx.rs create mode 100644 imgui-examples/examples/support_gfx/mod.rs create mode 100644 imgui-gfx-renderer/Cargo.toml create mode 100644 imgui-gfx-renderer/src/lib.rs create mode 100644 imgui-gfx-renderer/src/shader/frag_110.glsl create mode 100644 imgui-gfx-renderer/src/shader/frag_140.glsl create mode 100644 imgui-gfx-renderer/src/shader/vert_110.glsl create mode 100644 imgui-gfx-renderer/src/shader/vert_140.glsl diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index e100ba8..f6e74e1 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -32,6 +32,8 @@ - Support for 2-4 -element float sliders - `ImVec4::zero()` - `Into` array and tuple conversions for ImVec2 and ImVec4 +- gfx 0.14 support in imgui-sys +- gfx 0.14 renderer implementation ### Changed diff --git a/Cargo.toml b/Cargo.toml index 12a5211..e0f1302 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,4 +16,4 @@ travis-ci = { repository = "gekkio/imgui-rs" } imgui-sys = { version = "0.0.14-pre", path = "imgui-sys" } [workspace] -members = ["imgui-examples", "imgui-sys", "imgui-glium-renderer"] +members = ["imgui-examples", "imgui-sys", "imgui-gfx-renderer", "imgui-glium-renderer"] diff --git a/imgui-examples/Cargo.toml b/imgui-examples/Cargo.toml index dd40129..4cb2853 100644 --- a/imgui-examples/Cargo.toml +++ b/imgui-examples/Cargo.toml @@ -9,7 +9,11 @@ license = "MIT/Apache-2.0" publish = false [dev-dependencies] +gfx = "0.14" +gfx_window_glutin = "0.14" glium = { version = "0.16", default-features = true } +glutin = "0.7" imgui = { version = "0.0.14-pre", path = "../" } +imgui-gfx-renderer = { version = "0.0.14-pre", path = "../imgui-gfx-renderer" } imgui-glium-renderer = { version = "0.0.14-pre", path = "../imgui-glium-renderer" } -imgui-sys = { version = "0.0.14-pre", path = "../imgui-sys", features = ["glium"] } +imgui-sys = { version = "0.0.14-pre", path = "../imgui-sys", features = ["gfx", "glium"] } diff --git a/imgui-examples/examples/hello_gfx.rs b/imgui-examples/examples/hello_gfx.rs new file mode 100644 index 0000000..b38535d --- /dev/null +++ b/imgui-examples/examples/hello_gfx.rs @@ -0,0 +1,73 @@ +extern crate gfx; +extern crate gfx_window_glutin; +extern crate glutin; + +#[macro_use] +extern crate imgui; +extern crate imgui_gfx_renderer; +extern crate imgui_sys; + +use gfx::Device; + +use imgui::*; +use imgui_gfx_renderer::Renderer; + +mod support_gfx; + +const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; + +pub type ColorFormat = gfx::format::Rgba8; +pub type DepthFormat = gfx::format::DepthStencil; + +pub fn main() { + let mut support = support_gfx::Support::init(); + let builder = glutin::WindowBuilder::new() + .with_title("Hello World (GFX)".to_string()) + .with_dimensions(1024, 768) + .with_vsync(); + let (window, mut device, mut factory, mut main_color, mut main_depth) = + gfx_window_glutin::init::(builder); + let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); + let mut renderer = Renderer::init(&mut support.imgui, &mut factory, main_color.clone()); + + 'main: loop { + for event in window.poll_events() { + support.update_event(&event); + match event { + glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) | + glutin::Event::Closed => break 'main, + glutin::Event::Resized(_width, _height) => { + gfx_window_glutin::update_views(&window, &mut main_color, &mut main_depth); + } + _ => (), + } + } + + support.update_mouse(); + + let size_points = window.get_inner_size_points().unwrap(); + let size_pixels = window.get_inner_size_pixels().unwrap(); + let ui = support.imgui.frame(size_points, size_pixels, 1.0 / 16.0); + hello_world(&ui); + + encoder.clear(&mut main_color, CLEAR_COLOR); + + renderer.render(ui, &mut factory, &mut encoder) + .expect("Rendering failed"); + encoder.flush(&mut device); + window.swap_buffers().unwrap(); + device.cleanup(); + } +} + +fn hello_world<'a>(ui: &Ui<'a>) { + ui.window(im_str!("Hello world")) + .size((300.0, 100.0), ImGuiSetCond_FirstUseEver) + .build(|| { + ui.text(im_str!("Hello world!")); + ui.text(im_str!("This...is...imgui-rs!")); + ui.separator(); + let mouse_pos = ui.imgui().mouse_pos(); + ui.text(im_str!("Mouse Position: ({:.1},{:.1})", mouse_pos.0, mouse_pos.1)); + }) +} diff --git a/imgui-examples/examples/support_gfx/mod.rs b/imgui-examples/examples/support_gfx/mod.rs new file mode 100644 index 0000000..5dcdaf9 --- /dev/null +++ b/imgui-examples/examples/support_gfx/mod.rs @@ -0,0 +1,114 @@ +use glutin; +use glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode, TouchPhase}; +use imgui::{ImGui, ImGuiKey}; + +pub struct Support { + pub imgui: ImGui, + mouse_pos: (i32, i32), + mouse_pressed: (bool, bool, bool), + mouse_wheel: f32, +} + +impl Support { + pub fn init() -> Support { + let mut imgui = ImGui::init(); + + imgui.set_imgui_key(ImGuiKey::Tab, 0); + imgui.set_imgui_key(ImGuiKey::LeftArrow, 1); + imgui.set_imgui_key(ImGuiKey::RightArrow, 2); + imgui.set_imgui_key(ImGuiKey::UpArrow, 3); + imgui.set_imgui_key(ImGuiKey::DownArrow, 4); + imgui.set_imgui_key(ImGuiKey::PageUp, 5); + imgui.set_imgui_key(ImGuiKey::PageDown, 6); + imgui.set_imgui_key(ImGuiKey::Home, 7); + imgui.set_imgui_key(ImGuiKey::End, 8); + imgui.set_imgui_key(ImGuiKey::Delete, 9); + imgui.set_imgui_key(ImGuiKey::Backspace, 10); + imgui.set_imgui_key(ImGuiKey::Enter, 11); + imgui.set_imgui_key(ImGuiKey::Escape, 12); + imgui.set_imgui_key(ImGuiKey::A, 13); + imgui.set_imgui_key(ImGuiKey::C, 14); + imgui.set_imgui_key(ImGuiKey::V, 15); + imgui.set_imgui_key(ImGuiKey::X, 16); + imgui.set_imgui_key(ImGuiKey::Y, 17); + imgui.set_imgui_key(ImGuiKey::Z, 18); + + Support { + imgui: imgui, + mouse_pos: (0, 0), + mouse_pressed: (false, false, false), + mouse_wheel: 0.0, + } + } + + pub fn update_mouse(&mut self) { + let scale = self.imgui.display_framebuffer_scale(); + self.imgui.set_mouse_pos(self.mouse_pos.0 as f32 / scale.0, + self.mouse_pos.1 as f32 / scale.1); + self.imgui.set_mouse_down(&[self.mouse_pressed.0, + self.mouse_pressed.1, + self.mouse_pressed.2, + false, + false]); + self.imgui.set_mouse_wheel(self.mouse_wheel / scale.1); + self.mouse_wheel = 0.0; + } + + pub fn update_event(&mut self, event: &glutin::Event) -> bool { + match *event { + Event::Closed => return false, + Event::KeyboardInput(state, _, code) => { + let pressed = state == ElementState::Pressed; + match code { + Some(VirtualKeyCode::Tab) => self.imgui.set_key(0, pressed), + Some(VirtualKeyCode::Left) => self.imgui.set_key(1, pressed), + Some(VirtualKeyCode::Right) => self.imgui.set_key(2, pressed), + Some(VirtualKeyCode::Up) => self.imgui.set_key(3, pressed), + Some(VirtualKeyCode::Down) => self.imgui.set_key(4, pressed), + Some(VirtualKeyCode::PageUp) => self.imgui.set_key(5, pressed), + Some(VirtualKeyCode::PageDown) => self.imgui.set_key(6, pressed), + Some(VirtualKeyCode::Home) => self.imgui.set_key(7, pressed), + Some(VirtualKeyCode::End) => self.imgui.set_key(8, pressed), + Some(VirtualKeyCode::Delete) => self.imgui.set_key(9, pressed), + Some(VirtualKeyCode::Back) => self.imgui.set_key(10, pressed), + Some(VirtualKeyCode::Return) => self.imgui.set_key(11, pressed), + Some(VirtualKeyCode::Escape) => self.imgui.set_key(12, pressed), + Some(VirtualKeyCode::A) => self.imgui.set_key(13, pressed), + Some(VirtualKeyCode::C) => self.imgui.set_key(14, pressed), + Some(VirtualKeyCode::V) => self.imgui.set_key(15, pressed), + Some(VirtualKeyCode::X) => self.imgui.set_key(16, pressed), + Some(VirtualKeyCode::Y) => self.imgui.set_key(17, pressed), + Some(VirtualKeyCode::Z) => self.imgui.set_key(18, pressed), + Some(VirtualKeyCode::LControl) | + Some(VirtualKeyCode::RControl) => self.imgui.set_key_ctrl(pressed), + Some(VirtualKeyCode::LShift) | + Some(VirtualKeyCode::RShift) => self.imgui.set_key_shift(pressed), + Some(VirtualKeyCode::LAlt) | + Some(VirtualKeyCode::RAlt) => self.imgui.set_key_alt(pressed), + Some(VirtualKeyCode::LWin) | + Some(VirtualKeyCode::RWin) => self.imgui.set_key_super(pressed), + _ => {} + } + } + Event::MouseMoved(x, y) => self.mouse_pos = (x, y), + Event::MouseInput(state, MouseButton::Left) => { + self.mouse_pressed.0 = state == ElementState::Pressed + } + Event::MouseInput(state, MouseButton::Right) => { + self.mouse_pressed.1 = state == ElementState::Pressed + } + Event::MouseInput(state, MouseButton::Middle) => { + self.mouse_pressed.2 = state == ElementState::Pressed + } + Event::MouseWheel(MouseScrollDelta::LineDelta(_, y), TouchPhase::Moved) => { + self.mouse_wheel = y + } + Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y), TouchPhase::Moved) => { + self.mouse_wheel = y + } + Event::ReceivedCharacter(c) => self.imgui.add_input_character(c), + _ => (), + } + true + } +} diff --git a/imgui-gfx-renderer/Cargo.toml b/imgui-gfx-renderer/Cargo.toml new file mode 100644 index 0000000..fe0caf3 --- /dev/null +++ b/imgui-gfx-renderer/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "imgui-gfx-renderer" +version = "0.0.14-pre" +authors = ["Joonas Javanainen ", "imgui-rs contributors"] +description = "gfx renderer for the imgui crate" +homepage = "https://github.com/gekkio/imgui-rs" +repository = "https://github.com/gekkio/imgui-rs" +license = "MIT/Apache-2.0" + +[dependencies] +gfx = "0.14" +imgui = { version = "0.0.14-pre", path = "../" } +imgui-sys = { version = "0.0.14-pre", path = "../imgui-sys", features = ["gfx"] } diff --git a/imgui-gfx-renderer/src/lib.rs b/imgui-gfx-renderer/src/lib.rs new file mode 100644 index 0000000..b8d750e --- /dev/null +++ b/imgui-gfx-renderer/src/lib.rs @@ -0,0 +1,160 @@ +#[macro_use] +extern crate gfx; +extern crate imgui; + +use gfx::{Bind, Bundle, CommandBuffer, Encoder, Factory, IntoIndexBuffer, Rect, Resources, Slice}; +use gfx::handle::{Buffer, RenderTargetView}; +use gfx::traits::FactoryExt; +use imgui::{DrawList, ImDrawIdx, ImDrawVert, ImGui, Ui}; + +pub type RendererResult = Result; + +#[derive(Clone, Debug)] +pub enum RendererError { + Update(gfx::UpdateError), +} + +impl From> for RendererError { + fn from(e: gfx::UpdateError) -> RendererError { RendererError::Update(e) } +} + +gfx_defines!{ + pipeline pipe { + vertex_buffer: gfx::VertexBuffer = (), + matrix: gfx::Global<[[f32; 4]; 4]> = "matrix", + tex: gfx::TextureSampler<[f32; 4]> = "tex", + out: gfx::BlendTarget = ("Target0", gfx::state::MASK_ALL, gfx::preset::blend::ALPHA), + scissor: gfx::Scissor = (), + } +} + +pub struct Renderer { + bundle: Bundle>, + index_buffer: Buffer, +} + +impl Renderer { + pub fn init>(imgui: &mut ImGui, + factory: &mut F, + out: RenderTargetView) + -> Renderer { + let pso = factory.create_pipeline_simple(include_bytes!("shader/vert_110.glsl"), + include_bytes!("shader/frag_110.glsl"), + pipe::new()) + .expect("Failed to setup PSO"); + let vertex_buffer = factory.create_buffer::(256, + gfx::buffer::Role::Vertex, + gfx::memory::Usage::Dynamic, + Bind::empty()) + .expect("Failed to create vertex buffer"); + let index_buffer = factory.create_buffer::(256, + gfx::buffer::Role::Index, + gfx::memory::Usage::Dynamic, + Bind::empty()) + .expect("Failed to create index buffer"); + let (_, texture) = imgui.prepare_texture(|handle| { + factory.create_texture_immutable_u8::(gfx::texture::Kind::D2(handle.width as u16, handle.height as u16, gfx::texture::AaMode::Single), &[handle.pixels]) + }).expect("Failed to create texture"); + // TODO: set texture id in imgui + let sampler = factory.create_sampler_linear(); + let data = pipe::Data { + vertex_buffer: vertex_buffer, + matrix: [[0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 0.0], + [0.0, 0.0, -1.0, 0.0], + [-1.0, 1.0, 0.0, 1.0]], + tex: (texture, sampler), + out: out.clone(), + scissor: Rect { + x: 0, + y: 0, + w: 0, + h: 0, + }, + }; + let slice = Slice { + start: 0, + end: 0, + base_vertex: 0, + instances: None, + buffer: index_buffer.clone().into_index_buffer(factory), + }; + Renderer { + bundle: Bundle::new(slice, pso, data), + index_buffer: index_buffer, + } + } + pub fn render<'a, F: Factory, C: CommandBuffer>(&mut self, + ui: Ui<'a>, + factory: &mut F, + encoder: &mut Encoder) + -> RendererResult<()> { + let (width, height) = ui.imgui().display_size(); + + if width == 0.0 || height == 0.0 { + return Ok(()); + } + self.bundle.data.matrix = [[2.0 / width as f32, 0.0, 0.0, 0.0], + [0.0, -2.0 / height as f32, 0.0, 0.0], + [0.0, 0.0, -1.0, 0.0], + [-1.0, 1.0, 0.0, 1.0]]; + + ui.render(|ui, draw_list| self.render_draw_list(ui, factory, encoder, draw_list)) + } + fn render_draw_list<'a, F: Factory, C: CommandBuffer>(&mut self, + ui: &'a Ui<'a>, + factory: &mut F, + encoder: &mut Encoder, + draw_list: DrawList<'a>) + -> RendererResult<()> { + let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale(); + + self.bundle.slice.start = 0; + for cmd in draw_list.cmd_buffer { + // TODO: check cmd.texture_id + + self.upload_vertex_buffer(factory, encoder, draw_list.vtx_buffer)?; + self.upload_index_buffer(factory, encoder, draw_list.idx_buffer)?; + + self.bundle.slice.end = self.bundle.slice.start + cmd.elem_count; + self.bundle.data.scissor = Rect { + x: (cmd.clip_rect.x * scale_width) as u16, + y: (cmd.clip_rect.y * scale_height) as u16, + w: ((cmd.clip_rect.z - cmd.clip_rect.x).abs() * scale_width) as u16, + h: ((cmd.clip_rect.w - cmd.clip_rect.y).abs() * scale_height) as u16, + }; + self.bundle.encode(encoder); + self.bundle.slice.start = self.bundle.slice.end; + } + Ok(()) + } + fn upload_vertex_buffer, C: CommandBuffer>(&mut self, + factory: &mut F, + encoder: &mut Encoder, + vtx_buffer: &[ImDrawVert]) + -> RendererResult<()> { + if self.bundle.data.vertex_buffer.len() < vtx_buffer.len() { + self.bundle.data.vertex_buffer = factory.create_buffer::(vtx_buffer.len(), + gfx::buffer::Role::Vertex, + gfx::memory::Usage::Dynamic, + Bind::empty()) + .expect("Failed to create vertex buffer"); + } + Ok(try!(encoder.update_buffer(&self.bundle.data.vertex_buffer, vtx_buffer, 0))) + } + fn upload_index_buffer, C: CommandBuffer>(&mut self, + factory: &mut F, + encoder: &mut Encoder, + idx_buffer: &[ImDrawIdx]) + -> RendererResult<()> { + if self.index_buffer.len() < idx_buffer.len() { + self.index_buffer = factory.create_buffer::(idx_buffer.len(), + gfx::buffer::Role::Index, + gfx::memory::Usage::Dynamic, + Bind::empty()) + .expect("Failed to create index buffer"); + self.bundle.slice.buffer = self.index_buffer.clone().into_index_buffer(factory); + } + Ok(try!(encoder.update_buffer(&self.index_buffer, idx_buffer, 0))) + } +} diff --git a/imgui-gfx-renderer/src/shader/frag_110.glsl b/imgui-gfx-renderer/src/shader/frag_110.glsl new file mode 100644 index 0000000..8bdec78 --- /dev/null +++ b/imgui-gfx-renderer/src/shader/frag_110.glsl @@ -0,0 +1,10 @@ +#version 110 + +uniform sampler2D tex; + +varying vec2 f_uv; +varying vec4 f_color; + +void main() { + gl_FragColor = f_color * texture2D(tex, f_uv.st); +} diff --git a/imgui-gfx-renderer/src/shader/frag_140.glsl b/imgui-gfx-renderer/src/shader/frag_140.glsl new file mode 100644 index 0000000..7fbd223 --- /dev/null +++ b/imgui-gfx-renderer/src/shader/frag_140.glsl @@ -0,0 +1,12 @@ +#version 140 + +uniform sampler2D tex; + +in vec2 f_uv; +in vec4 f_color; + +out vec4 Target0; + +void main() { + Target0 = f_color * texture(tex, f_uv.st); +} diff --git a/imgui-gfx-renderer/src/shader/vert_110.glsl b/imgui-gfx-renderer/src/shader/vert_110.glsl new file mode 100644 index 0000000..99ee8a5 --- /dev/null +++ b/imgui-gfx-renderer/src/shader/vert_110.glsl @@ -0,0 +1,16 @@ +#version 110 + +uniform mat4 matrix; + +attribute vec2 pos; +attribute vec2 uv; +attribute vec4 col; + +varying vec2 f_uv; +varying vec4 f_color; + +void main() { + f_uv = uv; + f_color = col; + gl_Position = matrix * vec4(pos.xy, 0, 1); +} diff --git a/imgui-gfx-renderer/src/shader/vert_140.glsl b/imgui-gfx-renderer/src/shader/vert_140.glsl new file mode 100644 index 0000000..be63844 --- /dev/null +++ b/imgui-gfx-renderer/src/shader/vert_140.glsl @@ -0,0 +1,16 @@ +#version 140 + +uniform mat4 matrix; + +in vec2 pos; +in vec2 uv; +in vec4 col; + +out vec2 f_uv; +out vec4 f_color; + +void main() { + f_uv = uv; + f_color = col; + gl_Position = matrix * vec4(pos.xy, 0, 1); +} From 19ff43ddf837484e83f83a57ab039fe722d3d61d Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Fri, 31 Mar 2017 18:48:33 +0300 Subject: [PATCH 03/11] Add Cargo.toml categories --- imgui-gfx-renderer/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui-gfx-renderer/Cargo.toml b/imgui-gfx-renderer/Cargo.toml index fe0caf3..f20bdb0 100644 --- a/imgui-gfx-renderer/Cargo.toml +++ b/imgui-gfx-renderer/Cargo.toml @@ -6,6 +6,7 @@ description = "gfx renderer for the imgui crate" homepage = "https://github.com/gekkio/imgui-rs" repository = "https://github.com/gekkio/imgui-rs" license = "MIT/Apache-2.0" +categories = ["gui", "rendering"] [dependencies] gfx = "0.14" From 7cdac30bba549ee83cd97acdb91edbb63302000d Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Wed, 10 May 2017 20:55:17 +0300 Subject: [PATCH 04/11] Upgrade to gfx 0.15 --- CHANGELOG.markdown | 4 ++-- imgui-examples/Cargo.toml | 4 ++-- imgui-gfx-renderer/Cargo.toml | 2 +- imgui-sys/Cargo.toml | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index f6e74e1..6926be0 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -32,8 +32,8 @@ - Support for 2-4 -element float sliders - `ImVec4::zero()` - `Into` array and tuple conversions for ImVec2 and ImVec4 -- gfx 0.14 support in imgui-sys -- gfx 0.14 renderer implementation +- gfx 0.15 support in imgui-sys +- gfx 0.15 renderer implementation ### Changed diff --git a/imgui-examples/Cargo.toml b/imgui-examples/Cargo.toml index 4cb2853..ad210fd 100644 --- a/imgui-examples/Cargo.toml +++ b/imgui-examples/Cargo.toml @@ -9,8 +9,8 @@ license = "MIT/Apache-2.0" publish = false [dev-dependencies] -gfx = "0.14" -gfx_window_glutin = "0.14" +gfx = "0.15" +gfx_window_glutin = "0.15" glium = { version = "0.16", default-features = true } glutin = "0.7" imgui = { version = "0.0.14-pre", path = "../" } diff --git a/imgui-gfx-renderer/Cargo.toml b/imgui-gfx-renderer/Cargo.toml index f20bdb0..9aaa980 100644 --- a/imgui-gfx-renderer/Cargo.toml +++ b/imgui-gfx-renderer/Cargo.toml @@ -9,6 +9,6 @@ license = "MIT/Apache-2.0" categories = ["gui", "rendering"] [dependencies] -gfx = "0.14" +gfx = "0.15" imgui = { version = "0.0.14-pre", path = "../" } imgui-sys = { version = "0.0.14-pre", path = "../imgui-sys", features = ["gfx"] } diff --git a/imgui-sys/Cargo.toml b/imgui-sys/Cargo.toml index 97b0097..8561c6b 100644 --- a/imgui-sys/Cargo.toml +++ b/imgui-sys/Cargo.toml @@ -12,7 +12,7 @@ build = "build.rs" [dependencies] bitflags = "0.8" glium = { version = "0.16", default-features = false, optional = true } -gfx = { version = "0.14", optional = true } +gfx = { version = "0.15", optional = true } [build-dependencies] gcc = "0.3" From 719a1a33178a5c9989c08f8220bb227a67e14111 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 12:58:58 +0300 Subject: [PATCH 05/11] Wrap gfx renderer errors --- imgui-examples/examples/hello_gfx.rs | 3 +- imgui-gfx-renderer/src/lib.rs | 42 +++++++++++++++++----------- 2 files changed, 28 insertions(+), 17 deletions(-) diff --git a/imgui-examples/examples/hello_gfx.rs b/imgui-examples/examples/hello_gfx.rs index b38535d..09d768a 100644 --- a/imgui-examples/examples/hello_gfx.rs +++ b/imgui-examples/examples/hello_gfx.rs @@ -28,7 +28,8 @@ pub fn main() { let (window, mut device, mut factory, mut main_color, mut main_depth) = gfx_window_glutin::init::(builder); let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); - let mut renderer = Renderer::init(&mut support.imgui, &mut factory, main_color.clone()); + let mut renderer = Renderer::init(&mut support.imgui, &mut factory, main_color.clone()) + .expect("Failed to initialize renderer"); 'main: loop { for event in window.poll_events() { diff --git a/imgui-gfx-renderer/src/lib.rs b/imgui-gfx-renderer/src/lib.rs index b8d750e..f97d490 100644 --- a/imgui-gfx-renderer/src/lib.rs +++ b/imgui-gfx-renderer/src/lib.rs @@ -12,12 +12,27 @@ pub type RendererResult = Result; #[derive(Clone, Debug)] pub enum RendererError { Update(gfx::UpdateError), + Buffer(gfx::buffer::CreationError), + Pipeline(gfx::PipelineStateError), + Combined(gfx::CombinedError) } impl From> for RendererError { fn from(e: gfx::UpdateError) -> RendererError { RendererError::Update(e) } } +impl From for RendererError { + fn from(e: gfx::buffer::CreationError) -> RendererError { RendererError::Buffer(e) } +} + +impl From> for RendererError { + fn from(e: gfx::PipelineStateError) -> RendererError { RendererError::Pipeline(e) } +} + +impl From for RendererError { + fn from(e: gfx::CombinedError) -> RendererError { RendererError::Combined(e) } +} + gfx_defines!{ pipeline pipe { vertex_buffer: gfx::VertexBuffer = (), @@ -37,24 +52,21 @@ impl Renderer { pub fn init>(imgui: &mut ImGui, factory: &mut F, out: RenderTargetView) - -> Renderer { + -> RendererResult> { let pso = factory.create_pipeline_simple(include_bytes!("shader/vert_110.glsl"), include_bytes!("shader/frag_110.glsl"), - pipe::new()) - .expect("Failed to setup PSO"); + pipe::new())?; let vertex_buffer = factory.create_buffer::(256, gfx::buffer::Role::Vertex, gfx::memory::Usage::Dynamic, - Bind::empty()) - .expect("Failed to create vertex buffer"); + Bind::empty())?; let index_buffer = factory.create_buffer::(256, gfx::buffer::Role::Index, gfx::memory::Usage::Dynamic, - Bind::empty()) - .expect("Failed to create index buffer"); + Bind::empty())?; let (_, texture) = imgui.prepare_texture(|handle| { factory.create_texture_immutable_u8::(gfx::texture::Kind::D2(handle.width as u16, handle.height as u16, gfx::texture::AaMode::Single), &[handle.pixels]) - }).expect("Failed to create texture"); + })?; // TODO: set texture id in imgui let sampler = factory.create_sampler_linear(); let data = pipe::Data { @@ -79,10 +91,10 @@ impl Renderer { instances: None, buffer: index_buffer.clone().into_index_buffer(factory), }; - Renderer { + Ok(Renderer { bundle: Bundle::new(slice, pso, data), index_buffer: index_buffer, - } + }) } pub fn render<'a, F: Factory, C: CommandBuffer>(&mut self, ui: Ui<'a>, @@ -137,10 +149,9 @@ impl Renderer { self.bundle.data.vertex_buffer = factory.create_buffer::(vtx_buffer.len(), gfx::buffer::Role::Vertex, gfx::memory::Usage::Dynamic, - Bind::empty()) - .expect("Failed to create vertex buffer"); + Bind::empty())?; } - Ok(try!(encoder.update_buffer(&self.bundle.data.vertex_buffer, vtx_buffer, 0))) + Ok(encoder.update_buffer(&self.bundle.data.vertex_buffer, vtx_buffer, 0)?) } fn upload_index_buffer, C: CommandBuffer>(&mut self, factory: &mut F, @@ -151,10 +162,9 @@ impl Renderer { self.index_buffer = factory.create_buffer::(idx_buffer.len(), gfx::buffer::Role::Index, gfx::memory::Usage::Dynamic, - Bind::empty()) - .expect("Failed to create index buffer"); + Bind::empty())?; self.bundle.slice.buffer = self.index_buffer.clone().into_index_buffer(factory); } - Ok(try!(encoder.update_buffer(&self.index_buffer, idx_buffer, 0))) + Ok(encoder.update_buffer(&self.index_buffer, idx_buffer, 0)?) } } From 16d19c1855d4fccc61ff44785e272649a2ca455c Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 13:17:30 +0300 Subject: [PATCH 06/11] Update render target after a resize --- imgui-examples/examples/hello_gfx.rs | 1 + imgui-gfx-renderer/src/lib.rs | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/imgui-examples/examples/hello_gfx.rs b/imgui-examples/examples/hello_gfx.rs index 09d768a..adaccc1 100644 --- a/imgui-examples/examples/hello_gfx.rs +++ b/imgui-examples/examples/hello_gfx.rs @@ -39,6 +39,7 @@ pub fn main() { glutin::Event::Closed => break 'main, glutin::Event::Resized(_width, _height) => { gfx_window_glutin::update_views(&window, &mut main_color, &mut main_depth); + renderer.update_render_target(main_color.clone()); } _ => (), } diff --git a/imgui-gfx-renderer/src/lib.rs b/imgui-gfx-renderer/src/lib.rs index f97d490..c6bfa94 100644 --- a/imgui-gfx-renderer/src/lib.rs +++ b/imgui-gfx-renderer/src/lib.rs @@ -76,7 +76,7 @@ impl Renderer { [0.0, 0.0, -1.0, 0.0], [-1.0, 1.0, 0.0, 1.0]], tex: (texture, sampler), - out: out.clone(), + out, scissor: Rect { x: 0, y: 0, @@ -96,6 +96,9 @@ impl Renderer { index_buffer: index_buffer, }) } + pub fn update_render_target(&mut self, out: RenderTargetView) { + self.bundle.data.out = out; + } pub fn render<'a, F: Factory, C: CommandBuffer>(&mut self, ui: Ui<'a>, factory: &mut F, From 68fec8a870bab9761c35d2422e9d1aaffc762bef Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 14:23:47 +0300 Subject: [PATCH 07/11] Upgrade to gfx 0.16 --- imgui-examples/Cargo.toml | 6 +- imgui-examples/examples/hello_gfx.rs | 51 +---- imgui-examples/examples/support_gfx/mod.rs | 253 ++++++++++++--------- imgui-gfx-renderer/Cargo.toml | 2 +- imgui-sys/Cargo.toml | 2 +- 5 files changed, 157 insertions(+), 157 deletions(-) diff --git a/imgui-examples/Cargo.toml b/imgui-examples/Cargo.toml index ad210fd..b68457d 100644 --- a/imgui-examples/Cargo.toml +++ b/imgui-examples/Cargo.toml @@ -9,10 +9,10 @@ license = "MIT/Apache-2.0" publish = false [dev-dependencies] -gfx = "0.15" -gfx_window_glutin = "0.15" +gfx = "0.16" +gfx_window_glutin = "0.16" glium = { version = "0.16", default-features = true } -glutin = "0.7" +glutin = "0.8" imgui = { version = "0.0.14-pre", path = "../" } imgui-gfx-renderer = { version = "0.0.14-pre", path = "../imgui-gfx-renderer" } imgui-glium-renderer = { version = "0.0.14-pre", path = "../imgui-glium-renderer" } diff --git a/imgui-examples/examples/hello_gfx.rs b/imgui-examples/examples/hello_gfx.rs index adaccc1..d1886de 100644 --- a/imgui-examples/examples/hello_gfx.rs +++ b/imgui-examples/examples/hello_gfx.rs @@ -1,65 +1,18 @@ extern crate gfx; extern crate gfx_window_glutin; extern crate glutin; - #[macro_use] extern crate imgui; extern crate imgui_gfx_renderer; -extern crate imgui_sys; - -use gfx::Device; use imgui::*; -use imgui_gfx_renderer::Renderer; mod support_gfx; const CLEAR_COLOR: [f32; 4] = [1.0, 1.0, 1.0, 1.0]; -pub type ColorFormat = gfx::format::Rgba8; -pub type DepthFormat = gfx::format::DepthStencil; - -pub fn main() { - let mut support = support_gfx::Support::init(); - let builder = glutin::WindowBuilder::new() - .with_title("Hello World (GFX)".to_string()) - .with_dimensions(1024, 768) - .with_vsync(); - let (window, mut device, mut factory, mut main_color, mut main_depth) = - gfx_window_glutin::init::(builder); - let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); - let mut renderer = Renderer::init(&mut support.imgui, &mut factory, main_color.clone()) - .expect("Failed to initialize renderer"); - - 'main: loop { - for event in window.poll_events() { - support.update_event(&event); - match event { - glutin::Event::KeyboardInput(_, _, Some(glutin::VirtualKeyCode::Escape)) | - glutin::Event::Closed => break 'main, - glutin::Event::Resized(_width, _height) => { - gfx_window_glutin::update_views(&window, &mut main_color, &mut main_depth); - renderer.update_render_target(main_color.clone()); - } - _ => (), - } - } - - support.update_mouse(); - - let size_points = window.get_inner_size_points().unwrap(); - let size_pixels = window.get_inner_size_pixels().unwrap(); - let ui = support.imgui.frame(size_points, size_pixels, 1.0 / 16.0); - hello_world(&ui); - - encoder.clear(&mut main_color, CLEAR_COLOR); - - renderer.render(ui, &mut factory, &mut encoder) - .expect("Rendering failed"); - encoder.flush(&mut device); - window.swap_buffers().unwrap(); - device.cleanup(); - } +fn main() { + support_gfx::run("hello_gfx.rs".to_owned(), CLEAR_COLOR, hello_world); } fn hello_world<'a>(ui: &Ui<'a>) { diff --git a/imgui-examples/examples/support_gfx/mod.rs b/imgui-examples/examples/support_gfx/mod.rs index 5dcdaf9..6c93f35 100644 --- a/imgui-examples/examples/support_gfx/mod.rs +++ b/imgui-examples/examples/support_gfx/mod.rs @@ -1,114 +1,161 @@ +use gfx; +use gfx::Device; +use gfx_window_glutin; use glutin; -use glutin::{ElementState, Event, MouseButton, MouseScrollDelta, VirtualKeyCode, TouchPhase}; -use imgui::{ImGui, ImGuiKey}; +use glutin::{ElementState, MouseButton, MouseScrollDelta, VirtualKeyCode, TouchPhase, WindowEvent}; +use imgui::{ImGui, Ui, ImGuiKey}; +use imgui_gfx_renderer::Renderer; +use std::time::Instant; -pub struct Support { - pub imgui: ImGui, - mouse_pos: (i32, i32), - mouse_pressed: (bool, bool, bool), - mouse_wheel: f32, +type ColorFormat = gfx::format::Rgba8; +type DepthFormat = gfx::format::DepthStencil; + +#[derive(Copy, Clone, PartialEq, Debug, Default)] +struct MouseState { + pos: (i32, i32), + pressed: (bool, bool, bool), + wheel: f32 } -impl Support { - pub fn init() -> Support { - let mut imgui = ImGui::init(); +pub fn run(title: String, clear_color: [f32; 4], mut run_ui: F) { + let mut imgui = ImGui::init(); - imgui.set_imgui_key(ImGuiKey::Tab, 0); - imgui.set_imgui_key(ImGuiKey::LeftArrow, 1); - imgui.set_imgui_key(ImGuiKey::RightArrow, 2); - imgui.set_imgui_key(ImGuiKey::UpArrow, 3); - imgui.set_imgui_key(ImGuiKey::DownArrow, 4); - imgui.set_imgui_key(ImGuiKey::PageUp, 5); - imgui.set_imgui_key(ImGuiKey::PageDown, 6); - imgui.set_imgui_key(ImGuiKey::Home, 7); - imgui.set_imgui_key(ImGuiKey::End, 8); - imgui.set_imgui_key(ImGuiKey::Delete, 9); - imgui.set_imgui_key(ImGuiKey::Backspace, 10); - imgui.set_imgui_key(ImGuiKey::Enter, 11); - imgui.set_imgui_key(ImGuiKey::Escape, 12); - imgui.set_imgui_key(ImGuiKey::A, 13); - imgui.set_imgui_key(ImGuiKey::C, 14); - imgui.set_imgui_key(ImGuiKey::V, 15); - imgui.set_imgui_key(ImGuiKey::X, 16); - imgui.set_imgui_key(ImGuiKey::Y, 17); - imgui.set_imgui_key(ImGuiKey::Z, 18); + let events_loop = glutin::EventsLoop::new(); + let builder = glutin::WindowBuilder::new() + .with_title(title) + .with_dimensions(1024, 768) + .with_vsync(); + let (window, mut device, mut factory, mut main_color, mut main_depth) = + gfx_window_glutin::init::(builder, &events_loop); + let mut encoder: gfx::Encoder<_, _> = factory.create_command_buffer().into(); + let mut renderer = Renderer::init(&mut imgui, &mut factory, main_color.clone()) + .expect("Failed to initialize renderer"); - Support { - imgui: imgui, - mouse_pos: (0, 0), - mouse_pressed: (false, false, false), - mouse_wheel: 0.0, - } - } + configure_keys(&mut imgui); - pub fn update_mouse(&mut self) { - let scale = self.imgui.display_framebuffer_scale(); - self.imgui.set_mouse_pos(self.mouse_pos.0 as f32 / scale.0, - self.mouse_pos.1 as f32 / scale.1); - self.imgui.set_mouse_down(&[self.mouse_pressed.0, - self.mouse_pressed.1, - self.mouse_pressed.2, - false, - false]); - self.imgui.set_mouse_wheel(self.mouse_wheel / scale.1); - self.mouse_wheel = 0.0; - } + let mut last_frame = Instant::now(); + let mut mouse_state = MouseState::default(); + let mut quit = false; - pub fn update_event(&mut self, event: &glutin::Event) -> bool { - match *event { - Event::Closed => return false, - Event::KeyboardInput(state, _, code) => { - let pressed = state == ElementState::Pressed; - match code { - Some(VirtualKeyCode::Tab) => self.imgui.set_key(0, pressed), - Some(VirtualKeyCode::Left) => self.imgui.set_key(1, pressed), - Some(VirtualKeyCode::Right) => self.imgui.set_key(2, pressed), - Some(VirtualKeyCode::Up) => self.imgui.set_key(3, pressed), - Some(VirtualKeyCode::Down) => self.imgui.set_key(4, pressed), - Some(VirtualKeyCode::PageUp) => self.imgui.set_key(5, pressed), - Some(VirtualKeyCode::PageDown) => self.imgui.set_key(6, pressed), - Some(VirtualKeyCode::Home) => self.imgui.set_key(7, pressed), - Some(VirtualKeyCode::End) => self.imgui.set_key(8, pressed), - Some(VirtualKeyCode::Delete) => self.imgui.set_key(9, pressed), - Some(VirtualKeyCode::Back) => self.imgui.set_key(10, pressed), - Some(VirtualKeyCode::Return) => self.imgui.set_key(11, pressed), - Some(VirtualKeyCode::Escape) => self.imgui.set_key(12, pressed), - Some(VirtualKeyCode::A) => self.imgui.set_key(13, pressed), - Some(VirtualKeyCode::C) => self.imgui.set_key(14, pressed), - Some(VirtualKeyCode::V) => self.imgui.set_key(15, pressed), - Some(VirtualKeyCode::X) => self.imgui.set_key(16, pressed), - Some(VirtualKeyCode::Y) => self.imgui.set_key(17, pressed), - Some(VirtualKeyCode::Z) => self.imgui.set_key(18, pressed), - Some(VirtualKeyCode::LControl) | - Some(VirtualKeyCode::RControl) => self.imgui.set_key_ctrl(pressed), - Some(VirtualKeyCode::LShift) | - Some(VirtualKeyCode::RShift) => self.imgui.set_key_shift(pressed), - Some(VirtualKeyCode::LAlt) | - Some(VirtualKeyCode::RAlt) => self.imgui.set_key_alt(pressed), - Some(VirtualKeyCode::LWin) | - Some(VirtualKeyCode::RWin) => self.imgui.set_key_super(pressed), - _ => {} + loop { + events_loop.poll_events(|glutin::Event::WindowEvent{event, ..}| { + match event { + WindowEvent::Resized(_, _) => { + gfx_window_glutin::update_views(&window, &mut main_color, &mut main_depth); + renderer.update_render_target(main_color.clone()); } + WindowEvent::Closed => quit = true, + WindowEvent::KeyboardInput(state, _, code, _) => { + let pressed = state == ElementState::Pressed; + match code { + Some(VirtualKeyCode::Tab) => imgui.set_key(0, pressed), + Some(VirtualKeyCode::Left) => imgui.set_key(1, pressed), + Some(VirtualKeyCode::Right) => imgui.set_key(2, pressed), + Some(VirtualKeyCode::Up) => imgui.set_key(3, pressed), + Some(VirtualKeyCode::Down) => imgui.set_key(4, pressed), + Some(VirtualKeyCode::PageUp) => imgui.set_key(5, pressed), + Some(VirtualKeyCode::PageDown) => imgui.set_key(6, pressed), + Some(VirtualKeyCode::Home) => imgui.set_key(7, pressed), + Some(VirtualKeyCode::End) => imgui.set_key(8, pressed), + Some(VirtualKeyCode::Delete) => imgui.set_key(9, pressed), + Some(VirtualKeyCode::Back) => imgui.set_key(10, pressed), + Some(VirtualKeyCode::Return) => imgui.set_key(11, pressed), + Some(VirtualKeyCode::Escape) => quit = true, + Some(VirtualKeyCode::A) => imgui.set_key(13, pressed), + Some(VirtualKeyCode::C) => imgui.set_key(14, pressed), + Some(VirtualKeyCode::V) => imgui.set_key(15, pressed), + Some(VirtualKeyCode::X) => imgui.set_key(16, pressed), + Some(VirtualKeyCode::Y) => imgui.set_key(17, pressed), + Some(VirtualKeyCode::Z) => imgui.set_key(18, pressed), + Some(VirtualKeyCode::LControl) | + Some(VirtualKeyCode::RControl) => imgui.set_key_ctrl(pressed), + Some(VirtualKeyCode::LShift) | + Some(VirtualKeyCode::RShift) => imgui.set_key_shift(pressed), + Some(VirtualKeyCode::LAlt) | + Some(VirtualKeyCode::RAlt) => imgui.set_key_alt(pressed), + Some(VirtualKeyCode::LWin) | + Some(VirtualKeyCode::RWin) => imgui.set_key_super(pressed), + _ => {} + } + } + WindowEvent::MouseMoved(x, y) => mouse_state.pos = (x, y), + WindowEvent::MouseInput(state, MouseButton::Left) => { + mouse_state.pressed.0 = state == ElementState::Pressed + } + WindowEvent::MouseInput(state, MouseButton::Right) => { + mouse_state.pressed.1 = state == ElementState::Pressed + } + WindowEvent::MouseInput(state, MouseButton::Middle) => { + mouse_state.pressed.2 = state == ElementState::Pressed + } + WindowEvent::MouseWheel(MouseScrollDelta::LineDelta(_, y), TouchPhase::Moved) => { + mouse_state.wheel = y + } + WindowEvent::MouseWheel(MouseScrollDelta::PixelDelta(_, y), TouchPhase::Moved) => { + mouse_state.wheel = y + } + WindowEvent::ReceivedCharacter(c) => imgui.add_input_character(c), + _ => () } - Event::MouseMoved(x, y) => self.mouse_pos = (x, y), - Event::MouseInput(state, MouseButton::Left) => { - self.mouse_pressed.0 = state == ElementState::Pressed - } - Event::MouseInput(state, MouseButton::Right) => { - self.mouse_pressed.1 = state == ElementState::Pressed - } - Event::MouseInput(state, MouseButton::Middle) => { - self.mouse_pressed.2 = state == ElementState::Pressed - } - Event::MouseWheel(MouseScrollDelta::LineDelta(_, y), TouchPhase::Moved) => { - self.mouse_wheel = y - } - Event::MouseWheel(MouseScrollDelta::PixelDelta(_, y), TouchPhase::Moved) => { - self.mouse_wheel = y - } - Event::ReceivedCharacter(c) => self.imgui.add_input_character(c), - _ => (), - } - true - } + }); + + let now = Instant::now(); + let delta = now - last_frame; + let delta_s = delta.as_secs() as f32 + delta.subsec_nanos() as f32 / 1_000_000_000.0; + last_frame = now; + + update_mouse(&mut imgui, &mut mouse_state); + + let size_points = window.get_inner_size_points().unwrap(); + let size_pixels = window.get_inner_size_pixels().unwrap(); + + let ui = imgui.frame(size_points, size_pixels, delta_s); + + run_ui(&ui); + + encoder.clear(&mut main_color, clear_color); + + renderer.render(ui, &mut factory, &mut encoder) + .expect("Rendering failed"); + encoder.flush(&mut device); + window.swap_buffers().unwrap(); + device.cleanup(); + + if quit { break } + }; +} + +fn configure_keys(imgui: &mut ImGui) { + imgui.set_imgui_key(ImGuiKey::Tab, 0); + imgui.set_imgui_key(ImGuiKey::LeftArrow, 1); + imgui.set_imgui_key(ImGuiKey::RightArrow, 2); + imgui.set_imgui_key(ImGuiKey::UpArrow, 3); + imgui.set_imgui_key(ImGuiKey::DownArrow, 4); + imgui.set_imgui_key(ImGuiKey::PageUp, 5); + imgui.set_imgui_key(ImGuiKey::PageDown, 6); + imgui.set_imgui_key(ImGuiKey::Home, 7); + imgui.set_imgui_key(ImGuiKey::End, 8); + imgui.set_imgui_key(ImGuiKey::Delete, 9); + imgui.set_imgui_key(ImGuiKey::Backspace, 10); + imgui.set_imgui_key(ImGuiKey::Enter, 11); + imgui.set_imgui_key(ImGuiKey::Escape, 12); + imgui.set_imgui_key(ImGuiKey::A, 13); + imgui.set_imgui_key(ImGuiKey::C, 14); + imgui.set_imgui_key(ImGuiKey::V, 15); + imgui.set_imgui_key(ImGuiKey::X, 16); + imgui.set_imgui_key(ImGuiKey::Y, 17); + imgui.set_imgui_key(ImGuiKey::Z, 18); +} + +fn update_mouse(imgui: &mut ImGui, mouse_state: &mut MouseState) { + let scale = imgui.display_framebuffer_scale(); + imgui.set_mouse_pos(mouse_state.pos.0 as f32 / scale.0, + mouse_state.pos.1 as f32 / scale.1); + imgui.set_mouse_down(&[mouse_state.pressed.0, + mouse_state.pressed.1, + mouse_state.pressed.2, + false, + false]); + imgui.set_mouse_wheel(mouse_state.wheel / scale.1); + mouse_state.wheel = 0.0; } diff --git a/imgui-gfx-renderer/Cargo.toml b/imgui-gfx-renderer/Cargo.toml index 9aaa980..bc83f42 100644 --- a/imgui-gfx-renderer/Cargo.toml +++ b/imgui-gfx-renderer/Cargo.toml @@ -9,6 +9,6 @@ license = "MIT/Apache-2.0" categories = ["gui", "rendering"] [dependencies] -gfx = "0.15" +gfx = "0.16" imgui = { version = "0.0.14-pre", path = "../" } imgui-sys = { version = "0.0.14-pre", path = "../imgui-sys", features = ["gfx"] } diff --git a/imgui-sys/Cargo.toml b/imgui-sys/Cargo.toml index 8561c6b..8cf99c3 100644 --- a/imgui-sys/Cargo.toml +++ b/imgui-sys/Cargo.toml @@ -12,7 +12,7 @@ build = "build.rs" [dependencies] bitflags = "0.8" glium = { version = "0.16", default-features = false, optional = true } -gfx = { version = "0.15", optional = true } +gfx = { version = "0.16", optional = true } [build-dependencies] gcc = "0.3" From dfc8fe09218a6f57107b397d86e521304b4e3864 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 14:24:49 +0300 Subject: [PATCH 08/11] Bump minimum Rust version to 1.16 --- .travis.yml | 7 ++----- README.markdown | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 3303ac5..cb1b148 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ rust: - stable - beta - nightly - - 1.15.1 + - 1.16 os: - linux - osx @@ -18,8 +18,5 @@ before_install: - git submodule update --init --recursive script: - # 1.15 doesn't yet support cargo build --all - - cd imgui-sys && cargo build --verbose && cd .. - - cd imgui-glium-renderer && cargo build --verbose && cd .. - - cargo build --verbose + - cargo build --all --verbose - cargo test --all --verbose diff --git a/README.markdown b/README.markdown index 93fda3a..c2bc5b0 100644 --- a/README.markdown +++ b/README.markdown @@ -2,7 +2,7 @@ **Still fairly experimental!** -Minimum Rust version: 1.15 +Minimum Rust version: 1.16 [![Build Status](https://travis-ci.org/Gekkio/imgui-rs.svg?branch=master)](https://travis-ci.org/Gekkio/imgui-rs) [![Latest release on crates.io](https://meritbadge.herokuapp.com/imgui)](https://crates.io/crates/imgui) From 2b59e291d3625a80438b0303589b0bbef70b50bd Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 14:30:59 +0300 Subject: [PATCH 09/11] Fix Rust version in travis.yml --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index cb1b148..254b074 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,7 +5,7 @@ rust: - stable - beta - nightly - - 1.16 + - 1.16.0 os: - linux - osx From aa606f9111e70af4ec2844b29de5df569650893c Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 14:32:21 +0300 Subject: [PATCH 10/11] Update CHANGELOG --- CHANGELOG.markdown | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown index 6926be0..6404882 100644 --- a/CHANGELOG.markdown +++ b/CHANGELOG.markdown @@ -5,6 +5,8 @@ ### Added - ImString owned type for strings +- Experimental support for gfx-rs in imgui-sys +- Experimental renderer for gfx-rs ### Changed From d9fdf9b58b5041d946963ad44ecd8b9fb7ef2d64 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sat, 17 Jun 2017 15:07:08 +0300 Subject: [PATCH 11/11] Remove unintended struct field shorthand --- imgui-gfx-renderer/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui-gfx-renderer/src/lib.rs b/imgui-gfx-renderer/src/lib.rs index c6bfa94..67728d3 100644 --- a/imgui-gfx-renderer/src/lib.rs +++ b/imgui-gfx-renderer/src/lib.rs @@ -76,7 +76,7 @@ impl Renderer { [0.0, 0.0, -1.0, 0.0], [-1.0, 1.0, 0.0, 1.0]], tex: (texture, sampler), - out, + out: out, scissor: Rect { x: 0, y: 0,