From 0ef604bbb19837716c1e552af57052b56d0752da Mon Sep 17 00:00:00 2001 From: Robin Date: Thu, 2 Feb 2023 15:00:28 +0100 Subject: [PATCH] Update to glow 0.12 --- imgui-glow-renderer/Cargo.toml | 2 +- imgui-glow-renderer/examples/utils/mod.rs | 10 +- imgui-glow-renderer/src/lib.rs | 111 ++++++++++-------- imgui-sdl2-support/Cargo.toml | 2 +- .../Cargo.toml | 2 +- .../src/lib.rs | 70 ++++------- imgui/src/render/renderer.rs | 14 ++- 7 files changed, 107 insertions(+), 104 deletions(-) diff --git a/imgui-glow-renderer/Cargo.toml b/imgui-glow-renderer/Cargo.toml index d2fdcb3..b82819a 100644 --- a/imgui-glow-renderer/Cargo.toml +++ b/imgui-glow-renderer/Cargo.toml @@ -10,7 +10,7 @@ categories = ["gui", "rendering"] [dependencies] imgui = { version = "0.10.0", path = "../imgui" } -glow = "0.10.0" +glow = "0.12.0" memoffset = "0.6.4" [dev-dependencies] diff --git a/imgui-glow-renderer/examples/utils/mod.rs b/imgui-glow-renderer/examples/utils/mod.rs index f5c0287..3f8399d 100644 --- a/imgui-glow-renderer/examples/utils/mod.rs +++ b/imgui-glow-renderer/examples/utils/mod.rs @@ -104,8 +104,8 @@ void main() { "#; let mut shaders = [ - (glow::VERTEX_SHADER, VERTEX_SHADER_SOURCE, 0), - (glow::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE, 0), + (glow::VERTEX_SHADER, VERTEX_SHADER_SOURCE, None), + (glow::FRAGMENT_SHADER, FRAGMENT_SHADER_SOURCE, None), ]; unsafe { @@ -123,7 +123,7 @@ void main() { panic!("{}", gl.get_shader_info_log(shader)); } gl.attach_shader(program, shader); - *handle = shader; + *handle = Some(shader); } gl.link_program(program); @@ -132,8 +132,8 @@ void main() { } for &(_, _, shader) in &shaders { - gl.detach_shader(program, shader); - gl.delete_shader(shader); + gl.detach_shader(program, shader.unwrap()); + gl.delete_shader(shader.unwrap()); } Self { diff --git a/imgui-glow-renderer/src/lib.rs b/imgui-glow-renderer/src/lib.rs index 1f3f3cb..a5911f8 100644 --- a/imgui-glow-renderer/src/lib.rs +++ b/imgui-glow-renderer/src/lib.rs @@ -45,7 +45,7 @@ //! is sRGB (if you don't know, it probably is) the `internal_format` is //! one of the `SRGB*` values. -use std::{borrow::Cow, error::Error, fmt::Display, mem::size_of}; +use std::{borrow::Cow, error::Error, fmt::Display, mem::size_of, num::NonZeroU32}; use imgui::{internal::RawWrapper, DrawCmd, DrawData, DrawVert}; @@ -61,7 +61,7 @@ pub type GlBuffer = ::Buffer; pub type GlTexture = ::Texture; pub type GlVertexArray = ::VertexArray; type GlProgram = ::Program; -type GlUniformLocation = ::Program; +type GlUniformLocation = ::UniformLocation; /// Renderer which owns the OpenGL context and handles textures itself. Also /// converts all output colors to sRGB for display. Useful for simple applications, @@ -135,11 +135,11 @@ impl Drop for AutoRenderer { pub struct Renderer { shaders: Shaders, state_backup: GlStateBackup, - pub vbo_handle: GlBuffer, - pub ebo_handle: GlBuffer, - pub font_atlas_texture: GlTexture, + pub vbo_handle: Option, + pub ebo_handle: Option, + pub font_atlas_texture: Option, #[cfg(feature = "bind_vertex_array_support")] - pub vertex_array_object: GlVertexArray, + pub vertex_array_object: Option, pub gl_version: GlVersion, pub has_clip_origin_support: bool, pub is_destroyed: bool, @@ -216,11 +216,11 @@ impl Renderer { let out = Self { shaders, state_backup, - vbo_handle, - ebo_handle, - font_atlas_texture, + vbo_handle: Some(vbo_handle), + ebo_handle: Some(ebo_handle), + font_atlas_texture: Some(font_atlas_texture), #[cfg(feature = "bind_vertex_array_support")] - vertex_array_object: 0, + vertex_array_object: None, gl_version, has_clip_origin_support, is_destroyed: false, @@ -240,21 +240,21 @@ impl Renderer { return; } - if self.vbo_handle != 0 { - unsafe { gl.delete_buffer(self.vbo_handle) }; - self.vbo_handle = 0; + if let Some(h) = self.vbo_handle { + unsafe { gl.delete_buffer(h) }; + self.vbo_handle = None; } - if self.ebo_handle != 0 { - unsafe { gl.delete_buffer(self.ebo_handle) }; - self.ebo_handle = 0; + if let Some(h) = self.ebo_handle { + unsafe { gl.delete_buffer(h) }; + self.ebo_handle = None; } - let program = self.shaders.program; - if program != 0 { - unsafe { gl.delete_program(program) }; + if let Some(p) = self.shaders.program { + unsafe { gl.delete_program(p) }; + self.shaders.program = None; } - if self.font_atlas_texture != 0 { - unsafe { gl.delete_texture(self.font_atlas_texture) }; - self.font_atlas_texture = 0; + if let Some(h) = self.font_atlas_texture { + unsafe { gl.delete_texture(h) }; + self.font_atlas_texture = None; } self.is_destroyed = true; @@ -285,10 +285,10 @@ impl Renderer { #[cfg(feature = "bind_vertex_array_support")] if self.gl_version.bind_vertex_array_support() { unsafe { - self.vertex_array_object = gl + self.vertex_array_object = Some(gl .create_vertex_array() - .map_err(|err| format!("Error creating vertex array object: {}", err))?; - gl.bind_vertex_array(Some(self.vertex_array_object)); + .map_err(|err| format!("Error creating vertex array object: {}", err))?); + gl.bind_vertex_array(self.vertex_array_object); } } @@ -333,7 +333,8 @@ impl Renderer { #[cfg(feature = "bind_vertex_array_support")] if self.gl_version.bind_vertex_array_support() { - unsafe { gl.delete_vertex_array(self.vertex_array_object) }; + unsafe { gl.delete_vertex_array(self.vertex_array_object.unwrap()) }; + self.vertex_array_object = None; } self.state_backup.post_render(gl, self.gl_version); @@ -398,7 +399,7 @@ impl Renderer { let projection_matrix = calculate_matrix(draw_data, clip_origin_is_lower_left); unsafe { - gl.use_program(Some(self.shaders.program)); + gl.use_program(self.shaders.program); gl.uniform_1_i32(Some(&self.shaders.texture_uniform_location), 0); gl.uniform_matrix_4_f32_slice( Some(&self.shaders.matrix_uniform_location), @@ -418,8 +419,8 @@ impl Renderer { let color_field_offset = memoffset::offset_of!(DrawVert, col) as _; unsafe { - gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.vbo_handle)); - gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(self.ebo_handle)); + gl.bind_buffer(glow::ARRAY_BUFFER, self.vbo_handle); + gl.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, self.ebo_handle); gl.enable_vertex_attrib_array(self.shaders.position_attribute_index); gl.vertex_attrib_pointer_f32( self.shaders.position_attribute_index, @@ -565,13 +566,13 @@ pub struct SimpleTextureMap(); impl TextureMap for SimpleTextureMap { #[inline(always)] fn register(&mut self, gl_texture: glow::Texture) -> Option { - Some(imgui::TextureId::new(gl_texture as _)) + Some(imgui::TextureId::new(gl_texture.0.get() as _)) } #[inline(always)] fn gl_texture(&self, imgui_texture: imgui::TextureId) -> Option { #[allow(clippy::cast_possible_truncation)] - Some(imgui_texture.id() as _) + Some(glow::NativeTexture(NonZeroU32::new(imgui_texture.id() as _).unwrap())) } } @@ -602,12 +603,12 @@ impl TextureMap for imgui::Textures { #[allow(clippy::struct_excessive_bools)] #[derive(Default)] pub struct GlStateBackup { - active_texture: i32, - program: i32, - texture: i32, + active_texture: u32, + program: u32, + texture: u32, #[cfg(feature = "bind_sampler_support")] - sampler: Option, - array_buffer: i32, + sampler: Option, + array_buffer: u32, #[cfg(feature = "polygon_mode_support")] polygon_mode: Option<[i32; 2]>, viewport: [i32; 4], @@ -626,34 +627,42 @@ pub struct GlStateBackup { #[cfg(feature = "primitive_restart_support")] primitive_restart_enabled: Option, #[cfg(feature = "bind_vertex_array_support")] - vertex_array_object: Option, + vertex_array_object: Option, +} + +fn to_native_gl(handle: u32, constructor: fn(NonZeroU32) -> T) -> Option { + if handle != 0 { + Some(constructor(NonZeroU32::new(handle).unwrap())) + } else { + None + } } impl GlStateBackup { fn pre_init(&mut self, gl: &Context) { - self.texture = unsafe { gl.get_parameter_i32(glow::TEXTURE_BINDING_2D) }; + self.texture = unsafe { gl.get_parameter_i32(glow::TEXTURE_BINDING_2D) as _ }; } fn post_init(&mut self, gl: &Context) { #[allow(clippy::cast_sign_loss)] unsafe { - gl.bind_texture(glow::TEXTURE_2D, Some(self.texture as _)); + gl.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture)); } } fn pre_render(&mut self, gl: &Context, gl_version: GlVersion) { #[allow(clippy::cast_sign_loss)] unsafe { - self.active_texture = gl.get_parameter_i32(glow::ACTIVE_TEXTURE); - self.program = gl.get_parameter_i32(glow::CURRENT_PROGRAM); - self.texture = gl.get_parameter_i32(glow::TEXTURE_BINDING_2D); + self.active_texture = gl.get_parameter_i32(glow::ACTIVE_TEXTURE) as _; + self.program = gl.get_parameter_i32(glow::CURRENT_PROGRAM) as _; + self.texture = gl.get_parameter_i32(glow::TEXTURE_BINDING_2D) as _; #[cfg(feature = "bind_sampler_support")] if gl_version.bind_sampler_support() { - self.sampler = Some(gl.get_parameter_i32(glow::SAMPLER_BINDING)); + self.sampler = Some(gl.get_parameter_i32(glow::SAMPLER_BINDING) as _); } else { self.sampler = None; } - self.array_buffer = gl.get_parameter_i32(glow::ARRAY_BUFFER_BINDING); + self.array_buffer = gl.get_parameter_i32(glow::ARRAY_BUFFER_BINDING) as _; #[cfg(feature = "bind_vertex_array_support")] if gl_version.bind_vertex_array_support() { @@ -695,18 +704,18 @@ impl GlStateBackup { fn post_render(&mut self, gl: &Context, _gl_version: GlVersion) { #![allow(clippy::cast_sign_loss)] unsafe { - gl.use_program(Some(self.program as _)); - gl.bind_texture(glow::TEXTURE_2D, Some(self.texture as _)); + gl.use_program(to_native_gl(self.program, glow::NativeProgram)); + gl.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture)); #[cfg(feature = "bind_sampler_support")] if let Some(sampler) = self.sampler { - gl.bind_sampler(0, Some(sampler as _)); + gl.bind_sampler(0, to_native_gl(sampler, glow::NativeSampler)); } gl.active_texture(self.active_texture as _); #[cfg(feature = "bind_vertex_array_support")] if let Some(vao) = self.vertex_array_object { - gl.bind_vertex_array(Some(vao)); + gl.bind_vertex_array(to_native_gl(vao, glow::NativeVertexArray)); } - gl.bind_buffer(glow::ARRAY_BUFFER, Some(self.array_buffer as _)); + gl.bind_buffer(glow::ARRAY_BUFFER, to_native_gl(self.array_buffer, glow::NativeBuffer)); gl.blend_equation_separate( self.blend_equation_rgb as _, self.blend_equation_alpha as _, @@ -774,7 +783,7 @@ impl GlStateBackup { /// generate shaders which should work on a wide variety of modern devices /// (GL >= 3.3 and GLES >= 2.0 are expected to work). struct Shaders { - program: GlProgram, + program: Option, texture_uniform_location: GlUniformLocation, matrix_uniform_location: GlUniformLocation, position_attribute_index: u32, @@ -829,7 +838,7 @@ impl Shaders { Ok(unsafe { Self { - program, + program: Some(program), texture_uniform_location: gl .get_uniform_location(program, "tex") .ok_or_else(|| ShaderError::UniformNotFound("tex".into()))?, diff --git a/imgui-sdl2-support/Cargo.toml b/imgui-sdl2-support/Cargo.toml index 62644bc..cb20925 100644 --- a/imgui-sdl2-support/Cargo.toml +++ b/imgui-sdl2-support/Cargo.toml @@ -15,6 +15,6 @@ imgui = { version = "0.10.0", path = "../imgui" } sdl2 = "0.34.5" [dev-dependencies] -glow = "0.10.0" +glow = "0.12.0" imgui-glow-renderer = { version = "0.10.0", path = "../imgui-glow-renderer" } sdl2 = { version = "0.34.5", features = ["bundled", "static-link"] } diff --git a/imgui-winit-glow-renderer-viewports/Cargo.toml b/imgui-winit-glow-renderer-viewports/Cargo.toml index 62d4c32..b910a81 100644 --- a/imgui-winit-glow-renderer-viewports/Cargo.toml +++ b/imgui-winit-glow-renderer-viewports/Cargo.toml @@ -8,7 +8,7 @@ edition = "2021" [dependencies] imgui = { version="0.10.0", path="../imgui", features=["docking"] } -glow = "0.11.2" +glow = "0.12.0" glutin = "0.30.3" raw-window-handle = "0.5.0" winit = "0.27.5" diff --git a/imgui-winit-glow-renderer-viewports/src/lib.rs b/imgui-winit-glow-renderer-viewports/src/lib.rs index 3a2c8fa..7b52091 100644 --- a/imgui-winit-glow-renderer-viewports/src/lib.rs +++ b/imgui-winit-glow-renderer-viewports/src/lib.rs @@ -226,12 +226,20 @@ struct GlStateBackup { blend_func_dst: i32, scissor_enabled: bool, scissor: [i32; 4], - vao: i32, - vbo: i32, - ibo: i32, - active_texture: i32, - texture: i32, - program: i32, + vao: u32, + vbo: u32, + ibo: u32, + active_texture: u32, + texture: u32, + program: u32, +} + +fn to_native_gl(handle: u32, constructor: fn(NonZeroU32) -> T) -> Option { + if handle != 0 { + Some(constructor(NonZeroU32::new(handle).unwrap())) + } else { + None + } } impl GlStateBackup { @@ -248,15 +256,15 @@ impl GlStateBackup { let mut scissor = [0; 4]; context.get_parameter_i32_slice(glow::SCISSOR_BOX, &mut scissor); - let vao = context.get_parameter_i32(glow::VERTEX_ARRAY_BINDING); - let vbo = context.get_parameter_i32(glow::ARRAY_BUFFER_BINDING); - let ibo = context.get_parameter_i32(glow::ELEMENT_ARRAY_BUFFER_BINDING); + let vao = context.get_parameter_i32(glow::VERTEX_ARRAY_BINDING) as _; + let vbo = context.get_parameter_i32(glow::ARRAY_BUFFER_BINDING) as _; + let ibo = context.get_parameter_i32(glow::ELEMENT_ARRAY_BUFFER_BINDING) as _; - let active_texture = context.get_parameter_i32(glow::ACTIVE_TEXTURE); + let active_texture = context.get_parameter_i32(glow::ACTIVE_TEXTURE) as _; context.active_texture(0); - let texture = context.get_parameter_i32(glow::TEXTURE_BINDING_2D); + let texture = context.get_parameter_i32(glow::TEXTURE_BINDING_2D) as _; - let program = context.get_parameter_i32(glow::CURRENT_PROGRAM); + let program = context.get_parameter_i32(glow::CURRENT_PROGRAM) as _; Self { viewport, @@ -295,41 +303,15 @@ impl GlStateBackup { self.scissor[3], ); - if self.vao != 0 { - let vao = std::mem::transmute(self.vao); - context.bind_vertex_array(Some(vao)); - } else { - context.bind_vertex_array(None); - } + context.bind_vertex_array(to_native_gl(self.vao, glow::NativeVertexArray)); - if self.vbo != 0 { - let vbo = std::mem::transmute(self.vbo); - context.bind_buffer(glow::ARRAY_BUFFER, Some(vbo)); - } else { - context.bind_buffer(glow::ARRAY_BUFFER, None); - } + context.bind_buffer(glow::ARRAY_BUFFER, to_native_gl(self.vbo, glow::NativeBuffer)); + context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, to_native_gl(self.ibo, glow::NativeBuffer)); - if self.ibo != 0 { - let ibo = std::mem::transmute(self.ibo); - context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ibo)); - } else { - context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, None); - } + context.bind_texture(glow::TEXTURE_2D, to_native_gl(self.texture, glow::NativeTexture)); + context.active_texture(self.active_texture); - if self.texture != 0 { - let texture = std::mem::transmute(self.texture); - context.bind_texture(glow::TEXTURE_2D, Some(texture)); - } else { - context.bind_texture(glow::TEXTURE_2D, None); - } - context.active_texture(self.active_texture as _); - - if self.program != 0 { - let program = std::mem::transmute(self.program); - context.use_program(Some(program)); - } else { - context.use_program(None); - } + context.use_program(to_native_gl(self.program, glow::NativeProgram)); } } diff --git a/imgui/src/render/renderer.rs b/imgui/src/render/renderer.rs index 2b87e99..2ce7c07 100644 --- a/imgui/src/render/renderer.rs +++ b/imgui/src/render/renderer.rs @@ -54,12 +54,24 @@ fn test_texture_id_memory_layout() { } /// Generic texture mapping for use by renderers. -#[derive(Debug, Default)] +#[derive(Debug)] pub struct Textures { textures: HashMap, next: usize, } +/// We manually impl Default as `#[derive(Default)]` +/// incorrectly requires `T: Default` which is +/// not necessary at all. +impl Default for Textures { + fn default() -> Self { + Self { + textures: Default::default(), + next: Default::default(), + } + } +} + impl Textures { // TODO: hasher like rustc_hash::FxHashMap or something would let this be // `const fn`