From 70370611e5c3694e9ef9ba0ecf0679442fdbd077 Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sun, 3 Jun 2018 11:21:13 +0300 Subject: [PATCH 1/2] Renderers take DrawData, not DrawList --- imgui-gfx-renderer/src/lib.rs | 7 ++- imgui-glium-renderer/src/lib.rs | 7 ++- src/lib.rs | 77 ++++++++++++++++++++++++++++----- 3 files changed, 77 insertions(+), 14 deletions(-) diff --git a/imgui-gfx-renderer/src/lib.rs b/imgui-gfx-renderer/src/lib.rs index be792bd..ccd32fd 100644 --- a/imgui-gfx-renderer/src/lib.rs +++ b/imgui-gfx-renderer/src/lib.rs @@ -180,8 +180,11 @@ impl Renderer { [-1.0, 1.0, 0.0, 1.0], ]; - ui.render(|ui, draw_list| { - self.render_draw_list(ui, factory, encoder, &draw_list) + ui.render(|ui, draw_data| { + for draw_list in &draw_data { + self.render_draw_list(ui, factory, encoder, &draw_list)?; + } + Ok(()) }) } fn render_draw_list<'a, F: Factory, C: CommandBuffer>( diff --git a/imgui-glium-renderer/src/lib.rs b/imgui-glium-renderer/src/lib.rs index b24af57..4a70fba 100644 --- a/imgui-glium-renderer/src/lib.rs +++ b/imgui-glium-renderer/src/lib.rs @@ -73,8 +73,11 @@ impl Renderer { pub fn render<'a, S: Surface>(&mut self, surface: &mut S, ui: Ui<'a>) -> RendererResult<()> { let _ = self.ctx.insert_debug_marker("imgui-rs: starting rendering"); - let result = ui.render(|ui, draw_list| { - self.render_draw_list(surface, ui, &draw_list) + let result = ui.render(|ui, draw_data| { + for draw_list in draw_data.into_iter() { + self.render_draw_list(surface, ui, &draw_list)?; + } + Ok(()) }); let _ = self.ctx.insert_debug_marker("imgui-rs: rendering finished"); result diff --git a/src/lib.rs b/src/lib.rs index 737868a..8e22bc9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -396,6 +396,68 @@ impl Drop for ImGui { static mut CURRENT_UI: Option> = None; +pub struct DrawData<'a> { + raw: &'a mut sys::ImDrawData, +} + +impl<'a> DrawData<'a> { + pub fn is_valid(&self) -> bool { + self.raw.valid + } + pub fn draw_list_count(&self) -> usize { + self.raw.cmd_lists_count as usize + } + pub fn total_vtx_count(&self) -> usize { + self.raw.total_vtx_count as usize + } + pub fn total_idx_count(&self) -> usize { + self.raw.total_idx_count as usize + } + pub fn deindex_all_buffers(&mut self) { + unsafe { + sys::ImDrawData_DeIndexAllBuffers(self.raw); + } + } + pub fn scale_clip_rects>(&mut self, sc: S) { + unsafe { + sys::ImDrawData_ScaleClipRects(self.raw, sc.into()); + } + } +} + +impl<'a> IntoIterator for &'a DrawData<'a> { + type Item = DrawList<'a>; + type IntoIter = DrawListIterator<'a>; + + fn into_iter(self) -> Self::IntoIter { + unsafe { + DrawListIterator { + iter: self.raw.cmd_lists().iter(), + } + } + } +} + +pub struct DrawListIterator<'a> { + iter: std::slice::Iter<'a, *const sys::ImDrawList>, +} + +impl<'a> Iterator for DrawListIterator<'a> { + type Item = DrawList<'a>; + + fn next(&mut self) -> Option { + self.iter.next().map(|&ptr| { + unsafe { + DrawList { + cmd_buffer: (*ptr).cmd_buffer.as_slice(), + idx_buffer: (*ptr).idx_buffer.as_slice(), + vtx_buffer: (*ptr).vtx_buffer.as_slice(), + } + } + }) + } +} + pub struct DrawList<'a> { pub cmd_buffer: &'a [sys::ImDrawCmd], pub idx_buffer: &'a [sys::ImDrawIdx], @@ -442,20 +504,15 @@ impl<'ui> Ui<'ui> { } pub fn render(self, mut f: F) -> Result<(), E> where - F: FnMut(&Ui, DrawList) -> Result<(), E>, + F: FnMut(&Ui, DrawData) -> Result<(), E>, { unsafe { sys::igRender(); - let draw_data = sys::igGetDrawData(); - for &cmd_list in (*draw_data).cmd_lists() { - let draw_list = DrawList { - cmd_buffer: (*cmd_list).cmd_buffer.as_slice(), - idx_buffer: (*cmd_list).idx_buffer.as_slice(), - vtx_buffer: (*cmd_list).vtx_buffer.as_slice(), - }; - try!(f(&self, draw_list)); - } + let draw_data = DrawData { + raw: &mut *sys::igGetDrawData(), + }; + f(&self, draw_data)?; CURRENT_UI = None; } Ok(()) From 9537fd83b3c2ef9812c816db0b8133388bbdd33e Mon Sep 17 00:00:00 2001 From: Joonas Javanainen Date: Sun, 3 Jun 2018 11:27:10 +0300 Subject: [PATCH 2/2] Render callback should be FnOnce The callback is no longer called multiple times --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8e22bc9..87c0190 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -502,9 +502,9 @@ impl<'ui> Ui<'ui> { let io = self.imgui.io(); io.metrics_active_windows } - pub fn render(self, mut f: F) -> Result<(), E> + pub fn render(self, f: F) -> Result<(), E> where - F: FnMut(&Ui, DrawData) -> Result<(), E>, + F: FnOnce(&Ui, DrawData) -> Result<(), E>, { unsafe { sys::igRender();