diff --git a/imgui-glow-renderer/examples/01_basic.rs b/imgui-glow-renderer/examples/01_basic.rs index 2172c44..ed4803c 100644 --- a/imgui-glow-renderer/examples/01_basic.rs +++ b/imgui-glow-renderer/examples/01_basic.rs @@ -22,7 +22,7 @@ fn main() { let gl = glow_context(&window); // OpenGL renderer from this crate - let mut ig_renderer = imgui_glow_renderer::auto_renderer(gl, &mut imgui_context) + let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context) .expect("failed to create renderer"); let mut last_frame = Instant::now(); diff --git a/imgui-glow-renderer/examples/02_triangle.rs b/imgui-glow-renderer/examples/02_triangle.rs index fb41a00..0ad1a44 100644 --- a/imgui-glow-renderer/examples/02_triangle.rs +++ b/imgui-glow-renderer/examples/02_triangle.rs @@ -17,8 +17,7 @@ fn main() { let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window); let gl = utils::glow_context(&window); - let mut ig_renderer = imgui_glow_renderer::RendererBuilder::new() - .build_owning(gl, &mut imgui_context) + let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context) .expect("failed to create renderer"); let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330"); diff --git a/imgui-glow-renderer/examples/03_triangle_gles.rs b/imgui-glow-renderer/examples/03_triangle_gles.rs index b62f058..b895f56 100644 --- a/imgui-glow-renderer/examples/03_triangle_gles.rs +++ b/imgui-glow-renderer/examples/03_triangle_gles.rs @@ -18,9 +18,10 @@ fn main() { let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window); let gl = utils::glow_context(&window); - let mut ig_renderer = imgui_glow_renderer::RendererBuilder::new() - .build_borrowing(&gl, &mut imgui_context) - .expect("failed to create renderer"); + let mut texture_map = imgui_glow_renderer::SimpleTextureMap::default(); + let mut ig_renderer = + imgui_glow_renderer::Renderer::initialize(&gl, &mut imgui_context, &mut texture_map) + .expect("failed to create renderer"); // Note the shader header now needs a precision specifier let tri_renderer = Triangler::new(&gl, "#version 300 es\nprecision mediump float;"); @@ -51,7 +52,7 @@ fn main() { winit_platform.prepare_render(&ui, window.window()); let draw_data = ui.render(); ig_renderer - .render(&gl, &draw_data) + .render(&gl, &texture_map, &draw_data) .expect("error rendering imgui"); window.swap_buffers().unwrap(); diff --git a/imgui-glow-renderer/examples/04_custom_textures.rs b/imgui-glow-renderer/examples/04_custom_textures.rs index 172020f..e7913f3 100644 --- a/imgui-glow-renderer/examples/04_custom_textures.rs +++ b/imgui-glow-renderer/examples/04_custom_textures.rs @@ -6,7 +6,8 @@ use std::{io::Cursor, time::Instant}; use glow::HasContext; use image::{jpeg::JpegDecoder, ImageDecoder}; use imgui::{im_str, Condition}; -use imgui_glow_renderer::RendererBuilder; + +use imgui_glow_renderer::Renderer; #[allow(dead_code)] mod utils; @@ -18,11 +19,10 @@ fn main() { let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window); let gl = utils::glow_context(&window); - let mut ig_renderer = RendererBuilder::new() - .with_texture_map(imgui::Textures::::default()) - .build_borrowing(&gl, &mut imgui_context) + let mut textures = imgui::Textures::::default(); + let mut ig_renderer = Renderer::initialize(&gl, &mut imgui_context, &mut textures) .expect("failed to create renderer"); - let textures_ui = TexturesUi::new(&gl, &mut ig_renderer.texture_map); + let textures_ui = TexturesUi::new(&gl, &mut textures); let mut last_frame = Instant::now(); event_loop.run(move |event, _, control_flow| { @@ -51,7 +51,7 @@ fn main() { winit_platform.prepare_render(&ui, window.window()); let draw_data = ui.render(); ig_renderer - .render(&gl, &draw_data) + .render(&gl, &textures, &draw_data) .expect("error rendering imgui"); window.swap_buffers().unwrap(); diff --git a/imgui-glow-renderer/src/lib.rs b/imgui-glow-renderer/src/lib.rs index 037d49e..82e3093 100644 --- a/imgui-glow-renderer/src/lib.rs +++ b/imgui-glow-renderer/src/lib.rs @@ -1,4 +1,4 @@ -use std::{borrow::Cow, error::Error, fmt::Display, marker::PhantomData, mem::size_of}; +use std::{borrow::Cow, error::Error, fmt::Display, mem::size_of}; use imgui::internal::RawWrapper; @@ -38,106 +38,32 @@ impl< { } -/// Convenience function to get you going quickly. In most larger programs -/// you probably want to take more control (including ownership of the GL -/// context). In those cases, construct an appropriate renderer with -/// `[RendererBuilder]`. -/// -/// By default, it constructs a renderer which owns the OpenGL context and -/// attempts to backup the OpenGL state before rendering and restore it after -/// rendering. -/// -/// # Errors -/// Any error initialising the OpenGL objects (including shaders) will -/// result in an error. -pub fn auto_renderer( - gl: G, - imgui_context: &mut imgui::Context, -) -> Result, InitError> { - RendererBuilder::new().build_owning(gl, imgui_context) -} - -pub struct RendererBuilder -where - G: Gl, - T: TextureMap, -{ - texture_map: T, - phantom_gl: PhantomData, -} - -impl RendererBuilder { - #[allow(clippy::new_without_default)] - #[must_use] - pub fn new() -> Self { - Self { - texture_map: TrivialTextureMap(), - phantom_gl: PhantomData::default(), - } - } -} - -impl RendererBuilder -where - G: Gl, - T: TextureMap, -{ - pub fn with_texture_map(self, texture_map: T2) -> RendererBuilder { - RendererBuilder { - texture_map, - phantom_gl: self.phantom_gl, - } - } - - /// Build a renderer which owns the OpenGL context (which can be borrowed - /// from the renderer, but not taken). - /// - /// # Errors - /// Any error initialising the OpenGL objects (including shaders) will - /// result in an error. - pub fn build_owning( - self, - gl: G, - imgui_context: &mut imgui::Context, - ) -> Result, InitError> { - let renderer = self.build_borrowing(&gl, imgui_context)?; - Ok(OwningRenderer:: { gl, renderer }) - } - - /// Build a renderer which needs to borrow a context in order to render. - /// - /// # Errors - /// Any error initialising the OpenGL objects (including shaders) will - /// result in an error. - pub fn build_borrowing( - self, - gl: &G, - imgui_context: &mut imgui::Context, - ) -> Result, InitError> { - Renderer::::initialize(gl, imgui_context, self.texture_map) - } -} - -/// Renderer which owns the OpenGL context. Useful for simple applications, but -/// more complicated applications may prefer to keep control of their own -/// OpenGL context, or even change that context at runtime. +/// Renderer which owns the OpenGL context and handles textures itself. +/// Useful for simple applications, but more complicated applications may prefer +/// to use `[Renderer]`. /// /// OpenGL context is still available to the rest of the application through /// the `[gl_context]` method. -pub struct OwningRenderer -where - G: Gl, - T: TextureMap, -{ +pub struct AutoRenderer { gl: G, - renderer: Renderer, + texture_map: SimpleTextureMap, + renderer: Renderer, } -impl OwningRenderer -where - G: Gl, - T: TextureMap, -{ +impl AutoRenderer { + /// # Errors + /// Any error initialising the OpenGL objects (including shaders) will + /// result in an error. + pub fn initialize(gl: G, imgui_context: &mut imgui::Context) -> Result { + let mut texture_map = SimpleTextureMap::default(); + let renderer = Renderer::initialize(&gl, imgui_context, &mut texture_map)?; + Ok(Self { + gl, + texture_map, + renderer, + }) + } + /// Note: no need to provide a `mut` version of this, as all methods on /// `[glow::HasContext]` are immutable. #[inline] @@ -146,7 +72,17 @@ where } #[inline] - pub fn renderer(&self) -> &Renderer { + pub fn texture_map(&self) -> &SimpleTextureMap { + &self.texture_map + } + + #[inline] + pub fn texture_map_mut(&mut self) -> &mut SimpleTextureMap { + &mut self.texture_map + } + + #[inline] + pub fn renderer(&self) -> &Renderer { &self.renderer } @@ -155,26 +91,17 @@ where /// however) #[inline] pub fn render(&mut self, draw_data: &imgui::DrawData) -> Result<(), RenderError> { - self.renderer.render(&self.gl, draw_data) + self.renderer.render(&self.gl, &self.texture_map, draw_data) } } -impl Drop for OwningRenderer -where - G: Gl, - T: TextureMap, -{ +impl Drop for AutoRenderer { fn drop(&mut self) { self.renderer.destroy(&self.gl); } } -pub struct Renderer -where - G: Gl, - T: TextureMap, -{ - pub texture_map: T, +pub struct Renderer { shaders: Shaders, state_backup: GlStateBackup, pub vbo_handle: G::Buffer, @@ -187,18 +114,14 @@ where pub is_destroyed: bool, } -impl Renderer -where - G: Gl, - T: TextureMap, -{ +impl Renderer { /// # Errors /// Any error initialising the OpenGL objects (including shaders) will /// result in an error. - pub fn initialize( + pub fn initialize( gl: &G, imgui_context: &mut imgui::Context, - mut texture_map: T, + texture_map: &mut T, ) -> Result { #![allow( clippy::similar_names, @@ -232,7 +155,7 @@ where let mut state_backup = GlStateBackup::default(); state_backup.pre_init(gl); - let font_atlas_texture = prepare_font_atlas(gl, imgui_context.fonts(), &mut texture_map)?; + let font_atlas_texture = prepare_font_atlas(gl, imgui_context.fonts(), texture_map)?; let shaders = Shaders::new(gl, gl_version)?; let vbo_handle = unsafe { gl.create_buffer() }.map_err(InitError::CreateBufferObject)?; @@ -241,7 +164,6 @@ where state_backup.post_init(gl); let out = Self { - texture_map, shaders, state_backup, vbo_handle, @@ -289,7 +211,12 @@ where /// # Errors /// Some OpenGL errors trigger an error (few are explicitly checked, /// however) - pub fn render(&mut self, gl: &G, draw_data: &imgui::DrawData) -> Result<(), RenderError> { + pub fn render( + &mut self, + gl: &G, + texture_map: &T, + draw_data: &imgui::DrawData, + ) -> Result<(), RenderError> { if self.is_destroyed { return Err(Self::renderer_destroyed()); } @@ -323,9 +250,15 @@ where gl_debug_message(gl, "start loop over commands"); for command in draw_list.commands() { match command { - imgui::DrawCmd::Elements { count, cmd_params } => { - self.render_elements(gl, count, cmd_params, draw_data, fb_width, fb_height) - } + imgui::DrawCmd::Elements { count, cmd_params } => self.render_elements( + gl, + texture_map, + count, + cmd_params, + draw_data, + fb_width, + fb_height, + ), imgui::DrawCmd::RawCallback { callback, raw_cmd } => unsafe { callback(draw_list.raw(), raw_cmd) }, @@ -467,9 +400,11 @@ where Ok(()) } - fn render_elements( + #[allow(clippy::too_many_arguments)] + fn render_elements( &self, gl: &G, + texture_map: &T, element_count: usize, element_params: imgui::DrawCmdParams, draw_data: &imgui::DrawData, @@ -507,7 +442,7 @@ where (clip_x2 - clip_x1) as i32, (clip_y2 - clip_y1) as i32, ); - gl.bind_texture(glow::TEXTURE_2D, self.texture_map.gl_texture(texture_id)); + gl.bind_texture(glow::TEXTURE_2D, texture_map.gl_texture(texture_id)); #[cfg(feature = "vertex_offset_support")] let with_offset = self.gl_version.vertex_offset_support(); @@ -560,9 +495,9 @@ pub trait TextureMap { /// Texture map where the imgui texture ID is simply the OpenGL texture ID #[derive(Default)] -pub struct TrivialTextureMap(); +pub struct SimpleTextureMap(); -impl TextureMap for TrivialTextureMap { +impl TextureMap for SimpleTextureMap { #[inline(always)] fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option { #[allow(clippy::cast_possible_truncation)]