From 34b94609b8300b8288ee962ef53917bb807156ab Mon Sep 17 00:00:00 2001 From: Malik Olivier Boussejra Date: Wed, 9 May 2018 17:01:39 +0900 Subject: [PATCH] Remove IntoImTexture Functions should directly return texture type used by backend. No automatic conversion. This simplify uses of API. Everything is more straightforward. --- imgui-examples/examples/custom_textures.rs | 12 +++--- imgui-examples/examples/support_gfx/mod.rs | 48 +++++++++++++++++++++- imgui-glium-renderer/src/im_texture.rs | 46 +++++++++++++++++---- imgui-glium-renderer/src/lib.rs | 4 +- src/lib.rs | 45 ++++++++++---------- src/texture.rs | 9 ---- 6 files changed, 116 insertions(+), 48 deletions(-) diff --git a/imgui-examples/examples/custom_textures.rs b/imgui-examples/examples/custom_textures.rs index 3d966fbb3..de3bb7c1e 100644 --- a/imgui-examples/examples/custom_textures.rs +++ b/imgui-examples/examples/custom_textures.rs @@ -31,7 +31,7 @@ fn main() { // Constant texture (define once) ui.text("Constant texture"); - let constant_texture = ui.make_texture::<_, _, Texture>(im_str!("#Constant"), || { + let constant_texture = ui.make_texture(im_str!("#Constant"), || { let mut image_data: Vec> = Vec::new(); for i in 0..100 { let mut row: Vec<(f32, f32, f32, f32)> = Vec::new(); @@ -40,7 +40,7 @@ fn main() { } image_data.push(row); } - Texture2d::new(&gl_ctx, image_data).unwrap() + Texture::from_data(&gl_ctx, image_data).unwrap() }); let size = constant_texture.get_size(); ui.image(&constant_texture, (size.0 as f32, size.1 as f32)) @@ -48,7 +48,7 @@ fn main() { // Changing texture (re-defined and swap texture for each frame) ui.text("Variable texture"); - let changing_texture = ui.replace_texture::<_, Texture>(im_str!("#Changing"), { + let changing_texture = ui.replace_texture(im_str!("#Changing"), { let mut image_data: Vec> = Vec::new(); for i in 0..100 { let mut row: Vec<(f32, f32, f32, f32)> = Vec::new(); @@ -61,7 +61,7 @@ fn main() { if t > 1.0 { t = 0.0; } - Texture2d::new(&gl_ctx, image_data).unwrap() + Texture::from_data(&gl_ctx, image_data).unwrap() }); let size = changing_texture.get_size(); ui.image(&changing_texture, (size.0 as f32, size.1 as f32)) @@ -69,8 +69,8 @@ fn main() { // Texture defined only once, however, you can dynamically draw on it. ui.text("Draw on texture"); - let draw_texture = ui.make_texture::<_, _, Texture>(im_str!("#Draw"), || { - Texture2d::empty(&gl_ctx, 100, 100).unwrap() + let draw_texture = ui.make_texture(im_str!("#Draw"), || { + Texture::from_texture_2d(Texture2d::empty(&gl_ctx, 100, 100).unwrap()) }); // Get the texture as a surface. It must first be converted to a // `glium::Texture2d` object by using `Texture::from`. diff --git a/imgui-examples/examples/support_gfx/mod.rs b/imgui-examples/examples/support_gfx/mod.rs index e867f471c..a375a1901 100644 --- a/imgui-examples/examples/support_gfx/mod.rs +++ b/imgui-examples/examples/support_gfx/mod.rs @@ -1,5 +1,5 @@ use imgui::{FontGlyphRange, FrameSize, ImFontConfig, ImGui, ImGuiMouseCursor, ImVec4, Ui}; -use imgui_gfx_renderer::{Renderer, Shaders}; +use imgui_gfx_renderer::{Renderer, Shaders, Texture}; use std::time::Instant; #[derive(Copy, Clone, PartialEq, Debug, Default)] @@ -220,6 +220,12 @@ pub fn run bool>(title: String, clear_color: [f32; 4], mut run_ }; let ui = imgui.frame(frame_size, delta_s); + + let texture = ui.make_texture(im_str!("#STANDARD"), || gfx_load_texture(&mut factory)); + ui.image(&texture, (100.0, 100.0)).build(); + let texture = ui.replace_texture(im_str!("#CHANGE"), gfx_load_texture_change(&mut factory)); + ui.image(&texture, (100.0, 100.0)).build(); + if !run_ui(&ui) { break; } @@ -270,3 +276,43 @@ fn update_mouse(imgui: &mut ImGui, mouse_state: &mut MouseState) { imgui.set_mouse_wheel(mouse_state.wheel); mouse_state.wheel = 0.0; } + +use gfx; + +fn gfx_load_texture(factory: &mut F) -> Texture +where + F: gfx::Factory, + R: gfx::Resources, +{ + let mut data = Vec::new(); + let (width, height) = (100, 100); + for i in 0..width { + for j in 0..height { + data.push(i as u8); + data.push(j as u8); + data.push(255u8); + data.push(255u8); + } + } + Texture::from_raw(factory, width, height, &data).unwrap() +} + +fn gfx_load_texture_change(factory: &mut F) -> Texture +where + F: gfx::Factory, + R: gfx::Resources, +{ + static mut COUNT: u8 = 0; + let mut data = Vec::new(); + let (width, height) = (100, 100); + for i in 0..width { + for j in 0..height { + data.push(i as u8); + data.push(j as u8); + data.push(unsafe { COUNT }); + data.push(255u8); + } + } + unsafe { if COUNT == 255 { COUNT = 0 } else { COUNT += 1 } }; + Texture::from_raw(factory, width, height, &data).unwrap() +} diff --git a/imgui-glium-renderer/src/im_texture.rs b/imgui-glium-renderer/src/im_texture.rs index 7733d647c..36da1d17c 100644 --- a/imgui-glium-renderer/src/im_texture.rs +++ b/imgui-glium-renderer/src/im_texture.rs @@ -1,8 +1,11 @@ +use std::borrow::Cow; use std::mem; use std::ops::Deref; +use glium::backend::Facade; +use glium::texture::{PixelValue, RawImage2d, Texture2dDataSource, TextureCreationError}; use glium::Texture2d; -use imgui::{FromImTexture, ImTexture, ImTextureID, IntoImTexture}; +use imgui::{FromImTexture, ImTexture, ImTextureID}; /// Handle to a glium texture /// @@ -19,12 +22,6 @@ impl ImTexture for Texture { } } -impl IntoImTexture for Texture { - fn into_texture(texture: Texture2d) -> Texture { - Texture(texture) - } -} - impl Deref for Texture { type Target = Texture2d; fn deref(&self) -> &Self::Target { @@ -37,3 +34,38 @@ impl FromImTexture for Texture { unsafe { mem::transmute::<_, &Texture>(texture_id) } } } + +impl Texture { + pub fn from_texture_2d(texture: Texture2d) -> Self { + Texture(texture) + } + + pub fn from_data<'a, F, T>(facade: &F, data: T) -> Result + where + T: Texture2dDataSource<'a>, + F: Facade, + { + Texture2d::new(facade, data).map(Texture) + } + + pub fn from_raw( + facade: &F, + width: u32, + height: u32, + data: &[P], + ) -> Result + where + F: Facade, + P: PixelValue, + { + Self::from_data( + facade, + RawImage2d { + data: Cow::Borrowed(data), + width, + height, + format:

::get_format(), + }, + ) + } +} diff --git a/imgui-glium-renderer/src/lib.rs b/imgui-glium-renderer/src/lib.rs index 141362dae..221cc2cd5 100644 --- a/imgui-glium-renderer/src/lib.rs +++ b/imgui-glium-renderer/src/lib.rs @@ -221,14 +221,14 @@ impl DeviceObjects { let index_buffer = IndexBuffer::empty_dynamic(ctx, PrimitiveType::TrianglesList, 0)?; let program = compile_default_program(ctx)?; - let texture = im_gui.register_font_texture::<_, _, Texture, _>(|handle| { + let texture = im_gui.register_font_texture(|handle| { let data = RawImage2d { data: Cow::Borrowed(handle.pixels), width: handle.width, height: handle.height, format: ClientFormat::U8U8U8U8, }; - Texture2d::new(ctx, data) + Texture2d::new(ctx, data).map(Texture::from_texture_2d) })?; im_gui.set_texture_id(texture.get_id() as usize); diff --git a/src/lib.rs b/src/lib.rs index 6d0543189..7c03521db 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -39,7 +39,7 @@ pub use sys::{ ImGuiTreeNodeFlags, ImGuiWindowFlags, ImTextureID, ImVec2, ImVec4, }; use texture::TextureCache; -pub use texture::{AnyTexture, FromImTexture, ImTexture, IntoImTexture}; +pub use texture::{AnyTexture, FromImTexture, ImTexture}; pub use trees::{CollapsingHeader, TreeNode}; pub use window::Window; pub use window_draw_list::{ChannelsSplit, ImColor, WindowDrawList}; @@ -178,17 +178,17 @@ impl ImGui { } } /// Register font texture returned by closure to [`ImGui`] instance. - pub fn register_font_texture<'a, F, T, U, E>(&mut self, f: F) -> Result + pub fn register_font_texture<'a, F, T, E>(&mut self, f: F) -> Result where F: FnOnce(FontTextureHandle<'a>) -> Result, - U: 'static + IntoImTexture + ImTexture, + T: 'static + ImTexture, { let io = self.io(); let mut pixels: *mut c_uchar = ptr::null_mut(); let mut width: c_int = 0; let mut height: c_int = 0; let mut bytes_per_pixel: c_int = 0; - let texture: U = unsafe { + let texture = unsafe { sys::ImFontAtlas_GetTexDataAsRGBA32( io.fonts, &mut pixels, @@ -196,11 +196,11 @@ impl ImGui { &mut height, &mut bytes_per_pixel, ); - IntoImTexture::into_texture(f(FontTextureHandle { + f(FontTextureHandle { width: width as u32, height: height as u32, pixels: slice::from_raw_parts(pixels, (width * height * bytes_per_pixel) as usize), - })?) + })? }; self.textures.register_texture(im_str!("#FONT"), texture); Ok(self.textures.get_texture(im_str!("#FONT")).unwrap()) @@ -1425,13 +1425,13 @@ impl<'ui> Ui<'ui> { /// extern crate imgui_glium_renderer; /// /// use imgui::*; - /// use glium::Texture2d; + /// use imgui_glium_renderer::Texture; /// use glium::backend::Facade; /// /// fn make_a_texture(ui: &Ui, facade: &F, data: Vec>) { - /// let texture_handle = ui.replace_texture::<_, imgui_glium_renderer::Texture>( + /// let texture_handle = ui.replace_texture( /// im_str!("#Texture Name ID"), - /// Texture2d::new(facade, data).unwrap(), + /// Texture::from_data(facade, data).unwrap(), /// ); /// ui.image(&texture_handle, [100.0, 100.0]).build(); /// } @@ -1687,29 +1687,29 @@ impl<'ui> Ui<'ui> { /// extern crate imgui_glium_renderer; /// /// use imgui::*; - /// use glium::Texture2d; + /// use imgui_glium_renderer::Texture; /// use glium::backend::Facade; + /// use glium::Texture2d; /// /// fn make_a_texture(ui: &Ui, facade: &F) { - /// let texture_handle = ui.make_texture::<_, _, imgui_glium_renderer::Texture>(im_str!("#Texture Name ID"), || { - /// Texture2d::empty(facade, 100, 100).unwrap() + /// let texture_handle = ui.make_texture(im_str!("#Texture Name ID"), || { + /// Texture::from_texture_2d(Texture2d::empty(facade, 100, 100).unwrap()) /// }); /// // ... Do something with `texture_handle` /// } /// /// # fn main() {} /// ``` - pub fn make_texture(&self, name: &ImStr, f: F) -> AnyTexture + pub fn make_texture(&self, name: &ImStr, f: F) -> AnyTexture where F: FnOnce() -> T, - U: 'static + IntoImTexture + ImTexture, + T: 'static + ImTexture, { let imgui = self.imgui(); if let Some(texture) = imgui.textures.get_texture(name) { texture } else { - let texture: U = IntoImTexture::into_texture(f()); - imgui.textures.register_texture(name, texture); + imgui.textures.register_texture(name, f()); imgui.textures.get_texture(name).unwrap() } } @@ -1730,26 +1730,25 @@ impl<'ui> Ui<'ui> { /// extern crate imgui_glium_renderer; /// /// use imgui::*; - /// use glium::Texture2d; + /// use imgui_glium_renderer::Texture; /// use glium::backend::Facade; /// /// fn make_a_texture(ui: &Ui, facade: &F, data: Vec>) { - /// let texture_handle = ui.replace_texture::<_, imgui_glium_renderer::Texture>( + /// let texture_handle = ui.replace_texture( /// im_str!("#Texture Name ID"), - /// Texture2d::new(facade, data).unwrap(), + /// Texture::from_data(facade, data).unwrap(), /// ); /// // ... Do something with `texture_handle` /// } /// /// # fn main() {} /// ``` - pub fn replace_texture(&self, name: &ImStr, t: T) -> AnyTexture + pub fn replace_texture(&self, name: &ImStr, t: T) -> AnyTexture where - U: 'static + IntoImTexture + ImTexture, + T: 'static + ImTexture, { let imgui = self.imgui(); - let texture: U = IntoImTexture::into_texture(t); - imgui.textures.register_texture(name, texture); + imgui.textures.register_texture(name, t); imgui.textures.get_texture(name).unwrap() } } diff --git a/src/texture.rs b/src/texture.rs index ffe2eb512..87e4a8e04 100644 --- a/src/texture.rs +++ b/src/texture.rs @@ -62,15 +62,6 @@ impl Deref for AnyTexture { } } -/// Trait defining how an external type can be converted into a type implementing -/// [`ImTexture`]. -/// -/// Typically implemented to convert a native type (e.g. Texture2d from the -/// glium crate) to a type defined in the back-end implemnting [`ImTexture`]. -pub trait IntoImTexture: ImTexture { - fn into_texture(t: T) -> Self; -} - /// Trait defining how an object implementing [`ImTexture`] should be converted /// back to the native texture type used by the back-end. pub trait FromImTexture {