mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-26 04:48:29 +00:00
Consolodate to two non-generic renderers
There are now only two renderers (only generic over the GL context) - `AutoRenderer` which is both the old `OwningRenderer` and also sets up a `SimpleTextureMap` automatically - `Renderer` which borrows both the GL context and the texture map on every call to Render This means the `RendererBuilder` can be entirely removed. Also `TrivialTextureMap` renamed to `SimpleTextureMap`.
This commit is contained in:
parent
82f1122e10
commit
0cafc5c22d
@ -22,7 +22,7 @@ fn main() {
|
|||||||
let gl = glow_context(&window);
|
let gl = glow_context(&window);
|
||||||
|
|
||||||
// OpenGL renderer from this crate
|
// 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");
|
.expect("failed to create renderer");
|
||||||
|
|
||||||
let mut last_frame = Instant::now();
|
let mut last_frame = Instant::now();
|
||||||
|
|||||||
@ -17,8 +17,7 @@ fn main() {
|
|||||||
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
||||||
let gl = utils::glow_context(&window);
|
let gl = utils::glow_context(&window);
|
||||||
|
|
||||||
let mut ig_renderer = imgui_glow_renderer::RendererBuilder::new()
|
let mut ig_renderer = imgui_glow_renderer::AutoRenderer::initialize(gl, &mut imgui_context)
|
||||||
.build_owning(gl, &mut imgui_context)
|
|
||||||
.expect("failed to create renderer");
|
.expect("failed to create renderer");
|
||||||
let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330");
|
let tri_renderer = Triangler::new(ig_renderer.gl_context(), "#version 330");
|
||||||
|
|
||||||
|
|||||||
@ -18,9 +18,10 @@ fn main() {
|
|||||||
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
||||||
let gl = utils::glow_context(&window);
|
let gl = utils::glow_context(&window);
|
||||||
|
|
||||||
let mut ig_renderer = imgui_glow_renderer::RendererBuilder::new()
|
let mut texture_map = imgui_glow_renderer::SimpleTextureMap::default();
|
||||||
.build_borrowing(&gl, &mut imgui_context)
|
let mut ig_renderer =
|
||||||
.expect("failed to create 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
|
// Note the shader header now needs a precision specifier
|
||||||
let tri_renderer = Triangler::new(&gl, "#version 300 es\nprecision mediump float;");
|
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());
|
winit_platform.prepare_render(&ui, window.window());
|
||||||
let draw_data = ui.render();
|
let draw_data = ui.render();
|
||||||
ig_renderer
|
ig_renderer
|
||||||
.render(&gl, &draw_data)
|
.render(&gl, &texture_map, &draw_data)
|
||||||
.expect("error rendering imgui");
|
.expect("error rendering imgui");
|
||||||
|
|
||||||
window.swap_buffers().unwrap();
|
window.swap_buffers().unwrap();
|
||||||
|
|||||||
@ -6,7 +6,8 @@ use std::{io::Cursor, time::Instant};
|
|||||||
use glow::HasContext;
|
use glow::HasContext;
|
||||||
use image::{jpeg::JpegDecoder, ImageDecoder};
|
use image::{jpeg::JpegDecoder, ImageDecoder};
|
||||||
use imgui::{im_str, Condition};
|
use imgui::{im_str, Condition};
|
||||||
use imgui_glow_renderer::RendererBuilder;
|
|
||||||
|
use imgui_glow_renderer::Renderer;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
mod utils;
|
mod utils;
|
||||||
@ -18,11 +19,10 @@ fn main() {
|
|||||||
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
let (mut winit_platform, mut imgui_context) = utils::imgui_init(&window);
|
||||||
let gl = utils::glow_context(&window);
|
let gl = utils::glow_context(&window);
|
||||||
|
|
||||||
let mut ig_renderer = RendererBuilder::new()
|
let mut textures = imgui::Textures::<glow::Texture>::default();
|
||||||
.with_texture_map(imgui::Textures::<glow::Texture>::default())
|
let mut ig_renderer = Renderer::initialize(&gl, &mut imgui_context, &mut textures)
|
||||||
.build_borrowing(&gl, &mut imgui_context)
|
|
||||||
.expect("failed to create renderer");
|
.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();
|
let mut last_frame = Instant::now();
|
||||||
event_loop.run(move |event, _, control_flow| {
|
event_loop.run(move |event, _, control_flow| {
|
||||||
@ -51,7 +51,7 @@ fn main() {
|
|||||||
winit_platform.prepare_render(&ui, window.window());
|
winit_platform.prepare_render(&ui, window.window());
|
||||||
let draw_data = ui.render();
|
let draw_data = ui.render();
|
||||||
ig_renderer
|
ig_renderer
|
||||||
.render(&gl, &draw_data)
|
.render(&gl, &textures, &draw_data)
|
||||||
.expect("error rendering imgui");
|
.expect("error rendering imgui");
|
||||||
|
|
||||||
window.swap_buffers().unwrap();
|
window.swap_buffers().unwrap();
|
||||||
|
|||||||
@ -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;
|
use imgui::internal::RawWrapper;
|
||||||
|
|
||||||
@ -38,106 +38,32 @@ impl<
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convenience function to get you going quickly. In most larger programs
|
/// Renderer which owns the OpenGL context and handles textures itself.
|
||||||
/// you probably want to take more control (including ownership of the GL
|
/// Useful for simple applications, but more complicated applications may prefer
|
||||||
/// context). In those cases, construct an appropriate renderer with
|
/// to use `[Renderer]`.
|
||||||
/// `[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<G: Gl>(
|
|
||||||
gl: G,
|
|
||||||
imgui_context: &mut imgui::Context,
|
|
||||||
) -> Result<OwningRenderer<G, TrivialTextureMap>, InitError> {
|
|
||||||
RendererBuilder::new().build_owning(gl, imgui_context)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct RendererBuilder<G, T>
|
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
texture_map: T,
|
|
||||||
phantom_gl: PhantomData<G>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<G: Gl> RendererBuilder<G, TrivialTextureMap> {
|
|
||||||
#[allow(clippy::new_without_default)]
|
|
||||||
#[must_use]
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
texture_map: TrivialTextureMap(),
|
|
||||||
phantom_gl: PhantomData::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<G, T> RendererBuilder<G, T>
|
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
pub fn with_texture_map<T2: TextureMap>(self, texture_map: T2) -> RendererBuilder<G, T2> {
|
|
||||||
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<OwningRenderer<G, T>, InitError> {
|
|
||||||
let renderer = self.build_borrowing(&gl, imgui_context)?;
|
|
||||||
Ok(OwningRenderer::<G, T> { 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<Renderer<G, T>, InitError> {
|
|
||||||
Renderer::<G, T>::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.
|
|
||||||
///
|
///
|
||||||
/// OpenGL context is still available to the rest of the application through
|
/// OpenGL context is still available to the rest of the application through
|
||||||
/// the `[gl_context]` method.
|
/// the `[gl_context]` method.
|
||||||
pub struct OwningRenderer<G, T = TrivialTextureMap>
|
pub struct AutoRenderer<G: Gl> {
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
gl: G,
|
gl: G,
|
||||||
renderer: Renderer<G, T>,
|
texture_map: SimpleTextureMap,
|
||||||
|
renderer: Renderer<G>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G, T> OwningRenderer<G, T>
|
impl<G: Gl> AutoRenderer<G> {
|
||||||
where
|
/// # Errors
|
||||||
G: Gl,
|
/// Any error initialising the OpenGL objects (including shaders) will
|
||||||
T: TextureMap,
|
/// result in an error.
|
||||||
{
|
pub fn initialize(gl: G, imgui_context: &mut imgui::Context) -> Result<Self, InitError> {
|
||||||
|
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
|
/// Note: no need to provide a `mut` version of this, as all methods on
|
||||||
/// `[glow::HasContext]` are immutable.
|
/// `[glow::HasContext]` are immutable.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -146,7 +72,17 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn renderer(&self) -> &Renderer<G, T> {
|
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<G> {
|
||||||
&self.renderer
|
&self.renderer
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,26 +91,17 @@ where
|
|||||||
/// however)
|
/// however)
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn render(&mut self, draw_data: &imgui::DrawData) -> Result<(), RenderError> {
|
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<G, T> Drop for OwningRenderer<G, T>
|
impl<G: Gl> Drop for AutoRenderer<G> {
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.renderer.destroy(&self.gl);
|
self.renderer.destroy(&self.gl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Renderer<G, T = TrivialTextureMap>
|
pub struct Renderer<G: Gl> {
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
pub texture_map: T,
|
|
||||||
shaders: Shaders<G>,
|
shaders: Shaders<G>,
|
||||||
state_backup: GlStateBackup,
|
state_backup: GlStateBackup,
|
||||||
pub vbo_handle: G::Buffer,
|
pub vbo_handle: G::Buffer,
|
||||||
@ -187,18 +114,14 @@ where
|
|||||||
pub is_destroyed: bool,
|
pub is_destroyed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<G, T> Renderer<G, T>
|
impl<G: Gl> Renderer<G> {
|
||||||
where
|
|
||||||
G: Gl,
|
|
||||||
T: TextureMap,
|
|
||||||
{
|
|
||||||
/// # Errors
|
/// # Errors
|
||||||
/// Any error initialising the OpenGL objects (including shaders) will
|
/// Any error initialising the OpenGL objects (including shaders) will
|
||||||
/// result in an error.
|
/// result in an error.
|
||||||
pub fn initialize(
|
pub fn initialize<T: TextureMap>(
|
||||||
gl: &G,
|
gl: &G,
|
||||||
imgui_context: &mut imgui::Context,
|
imgui_context: &mut imgui::Context,
|
||||||
mut texture_map: T,
|
texture_map: &mut T,
|
||||||
) -> Result<Self, InitError> {
|
) -> Result<Self, InitError> {
|
||||||
#![allow(
|
#![allow(
|
||||||
clippy::similar_names,
|
clippy::similar_names,
|
||||||
@ -232,7 +155,7 @@ where
|
|||||||
let mut state_backup = GlStateBackup::default();
|
let mut state_backup = GlStateBackup::default();
|
||||||
state_backup.pre_init(gl);
|
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 shaders = Shaders::new(gl, gl_version)?;
|
||||||
let vbo_handle = unsafe { gl.create_buffer() }.map_err(InitError::CreateBufferObject)?;
|
let vbo_handle = unsafe { gl.create_buffer() }.map_err(InitError::CreateBufferObject)?;
|
||||||
@ -241,7 +164,6 @@ where
|
|||||||
state_backup.post_init(gl);
|
state_backup.post_init(gl);
|
||||||
|
|
||||||
let out = Self {
|
let out = Self {
|
||||||
texture_map,
|
|
||||||
shaders,
|
shaders,
|
||||||
state_backup,
|
state_backup,
|
||||||
vbo_handle,
|
vbo_handle,
|
||||||
@ -289,7 +211,12 @@ where
|
|||||||
/// # Errors
|
/// # Errors
|
||||||
/// Some OpenGL errors trigger an error (few are explicitly checked,
|
/// Some OpenGL errors trigger an error (few are explicitly checked,
|
||||||
/// however)
|
/// however)
|
||||||
pub fn render(&mut self, gl: &G, draw_data: &imgui::DrawData) -> Result<(), RenderError> {
|
pub fn render<T: TextureMap>(
|
||||||
|
&mut self,
|
||||||
|
gl: &G,
|
||||||
|
texture_map: &T,
|
||||||
|
draw_data: &imgui::DrawData,
|
||||||
|
) -> Result<(), RenderError> {
|
||||||
if self.is_destroyed {
|
if self.is_destroyed {
|
||||||
return Err(Self::renderer_destroyed());
|
return Err(Self::renderer_destroyed());
|
||||||
}
|
}
|
||||||
@ -323,9 +250,15 @@ where
|
|||||||
gl_debug_message(gl, "start loop over commands");
|
gl_debug_message(gl, "start loop over commands");
|
||||||
for command in draw_list.commands() {
|
for command in draw_list.commands() {
|
||||||
match command {
|
match command {
|
||||||
imgui::DrawCmd::Elements { count, cmd_params } => {
|
imgui::DrawCmd::Elements { count, cmd_params } => self.render_elements(
|
||||||
self.render_elements(gl, count, cmd_params, draw_data, fb_width, fb_height)
|
gl,
|
||||||
}
|
texture_map,
|
||||||
|
count,
|
||||||
|
cmd_params,
|
||||||
|
draw_data,
|
||||||
|
fb_width,
|
||||||
|
fb_height,
|
||||||
|
),
|
||||||
imgui::DrawCmd::RawCallback { callback, raw_cmd } => unsafe {
|
imgui::DrawCmd::RawCallback { callback, raw_cmd } => unsafe {
|
||||||
callback(draw_list.raw(), raw_cmd)
|
callback(draw_list.raw(), raw_cmd)
|
||||||
},
|
},
|
||||||
@ -467,9 +400,11 @@ where
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_elements(
|
#[allow(clippy::too_many_arguments)]
|
||||||
|
fn render_elements<T: TextureMap>(
|
||||||
&self,
|
&self,
|
||||||
gl: &G,
|
gl: &G,
|
||||||
|
texture_map: &T,
|
||||||
element_count: usize,
|
element_count: usize,
|
||||||
element_params: imgui::DrawCmdParams,
|
element_params: imgui::DrawCmdParams,
|
||||||
draw_data: &imgui::DrawData,
|
draw_data: &imgui::DrawData,
|
||||||
@ -507,7 +442,7 @@ where
|
|||||||
(clip_x2 - clip_x1) as i32,
|
(clip_x2 - clip_x1) as i32,
|
||||||
(clip_y2 - clip_y1) 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")]
|
#[cfg(feature = "vertex_offset_support")]
|
||||||
let with_offset = self.gl_version.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
|
/// Texture map where the imgui texture ID is simply the OpenGL texture ID
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct TrivialTextureMap();
|
pub struct SimpleTextureMap();
|
||||||
|
|
||||||
impl TextureMap for TrivialTextureMap {
|
impl TextureMap for SimpleTextureMap {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option<glow::Texture> {
|
fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option<glow::Texture> {
|
||||||
#[allow(clippy::cast_possible_truncation)]
|
#[allow(clippy::cast_possible_truncation)]
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user