Make ImTexture a newtype for additional type safety

This commit is contained in:
Tad Hardesty 2018-09-10 00:59:55 -07:00
parent fb7ea044e2
commit e9b1552f05
4 changed files with 50 additions and 21 deletions

View File

@ -227,7 +227,7 @@ impl<R: Resources> Renderer<R> {
self.bundle.slice.start = 0;
for cmd in draw_list.cmd_buffer {
if let Some(tex) = self.textures.get(cmd.texture_id as usize) {
if let Some(tex) = self.textures.get(cmd.texture_id.into()) {
// cloning handles is okay, since they're Arcs internally
self.bundle.data.tex = tex.clone();
}

View File

@ -7,8 +7,8 @@ use glium::index::{self, PrimitiveType};
use glium::program;
use glium::texture;
use glium::vertex;
use glium::{DrawError, GlObject, IndexBuffer, Program, Surface, Texture2d, VertexBuffer};
use imgui::{DrawList, FrameSize, ImDrawIdx, ImDrawVert, ImGui, Ui};
use glium::{DrawError, IndexBuffer, Program, Surface, Texture2d, VertexBuffer};
use imgui::{DrawList, FrameSize, ImDrawIdx, ImDrawVert, ImGui, Ui, Textures};
use std::borrow::Cow;
use std::fmt;
use std::rc::Rc;
@ -81,6 +81,10 @@ impl Renderer {
})
}
pub fn textures(&mut self) -> &mut Textures<Texture2d> {
&mut self.device_objects.textures
}
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 FrameSize {
@ -128,12 +132,17 @@ impl Renderer {
self.device_objects
.upload_index_buffer(&self.ctx, draw_list.idx_buffer)?;
let font_texture_id = self.device_objects.texture.get_id() as usize;
let mut idx_start = 0;
for cmd in draw_list.cmd_buffer {
// We don't support custom textures...yet!
assert!(cmd.texture_id as usize == font_texture_id);
let texture = match self.device_objects.textures.get(cmd.texture_id.into()) {
Some(tex) => tex,
// if an invalid ID is supplied, fall back to the font
None => match self.device_objects.textures.get(0.into()) {
Some(tex) => tex,
// if the font is missing, which should never happen, skip
None => continue,
}
};
let idx_end = idx_start + cmd.elem_count as usize;
@ -147,7 +156,7 @@ impl Renderer {
&self.device_objects.program,
&uniform! {
matrix: matrix,
tex: self.device_objects.texture.sampled()
tex: texture.sampled()
},
&DrawParameters {
blend: Blend::alpha_blending(),
@ -178,7 +187,7 @@ pub struct DeviceObjects {
vertex_buffer: VertexBuffer<ImDrawVert>,
index_buffer: IndexBuffer<ImDrawIdx>,
program: Program,
texture: Texture2d,
textures: Textures<Texture2d>,
}
fn compile_default_program<F: Facade>(
@ -231,13 +240,14 @@ impl DeviceObjects {
};
Texture2d::new(ctx, data)
})?;
im_gui.set_texture_id(texture.get_id() as usize);
let mut textures = Textures::new();
im_gui.set_texture_id(textures.insert(texture));
Ok(DeviceObjects {
vertex_buffer: vertex_buffer,
index_buffer: index_buffer,
program: program,
texture: texture,
textures: textures,
})
}
pub fn upload_vertex_buffer<F: Facade>(

View File

@ -4,7 +4,26 @@ use std::collections::HashMap;
use std::os::raw::c_void;
use sys;
pub type ImTexture = usize;
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct ImTexture(usize);
impl ImTexture {
pub fn id(&self) -> usize {
self.0
}
}
impl From<usize> for ImTexture {
fn from(id: usize) -> Self {
ImTexture(id)
}
}
impl From<*mut c_void> for ImTexture {
fn from(ptr: *mut c_void) -> Self {
ImTexture(ptr as usize)
}
}
/// Represent an image about to be drawn.
/// See [`Ui::image`].
@ -22,7 +41,7 @@ pub struct Image<'ui> {
}
impl<'ui> Image<'ui> {
pub fn new<S>(_: &Ui<'ui>, texture_id: usize, size: S) -> Self
pub fn new<S>(_: &Ui<'ui>, texture_id: ImTexture, size: S) -> Self
where
S: Into<ImVec2>,
{
@ -79,7 +98,7 @@ impl<'ui> Image<'ui> {
pub fn build(self) {
unsafe {
sys::igImage(
self.texture_id as *mut c_void,
self.texture_id.0 as *mut c_void,
self.size,
self.uv0,
self.uv1,
@ -108,19 +127,19 @@ impl<T> Textures<T> {
let id = self.next;
self.textures.insert(id, texture);
self.next += 1;
id
ImTexture(id)
}
pub fn replace(&mut self, id: ImTexture, texture: T) {
assert!(self.textures.contains_key(&id));
self.textures.insert(id, texture);
assert!(self.textures.contains_key(&id.0));
self.textures.insert(id.0, texture);
}
pub fn remove(&mut self, id: ImTexture) {
self.textures.remove(&id);
self.textures.remove(&id.0);
}
pub fn get(&self, id: ImTexture) -> Option<&T> {
self.textures.get(&id)
self.textures.get(&id.0)
}
}

View File

@ -172,8 +172,8 @@ impl ImGui {
})
}
}
pub fn set_texture_id(&mut self, value: usize) {
self.fonts().set_texture_id(value);
pub fn set_texture_id(&mut self, value: ImTexture) {
self.fonts().set_texture_id(value.id());
}
pub fn set_ini_filename(&mut self, value: Option<ImString>) {
{