Add hidpi support

This commit is contained in:
Brendan Zabarauskas 2016-06-13 14:31:49 +10:00
parent b903f65def
commit 734eda2d57
3 changed files with 75 additions and 42 deletions

View File

@ -56,10 +56,10 @@ impl Support {
}
}
pub fn update_mouse(&mut self) {
self.imgui.set_mouse_pos(self.mouse_pos.0 as f32, self.mouse_pos.1 as f32);
pub fn update_mouse(&mut self, hidpi_factor: f32) {
self.imgui.set_mouse_pos(self.mouse_pos.0 as f32 / hidpi_factor, self.mouse_pos.1 as f32 / hidpi_factor);
self.imgui.set_mouse_down(&[self.mouse_pressed.0, self.mouse_pressed.1, self.mouse_pressed.2, false, false]);
self.imgui.set_mouse_wheel(self.mouse_wheel);
self.imgui.set_mouse_wheel(self.mouse_wheel / hidpi_factor);
}
pub fn render<'ui, 'a: 'ui , F: FnMut(&Ui<'ui>)>(
@ -69,7 +69,12 @@ impl Support {
let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0;
self.last_frame = now;
self.update_mouse();
let hidpi_factor =
self.display.get_window()
.expect("Failed to get window")
.hidpi_factor();
self.update_mouse(hidpi_factor);
self.mouse_wheel = 0.0;
let mut target = self.display.draw();
@ -77,8 +82,9 @@ impl Support {
clear_color.2, clear_color.3);
let (width, height) = target.get_dimensions();
let ui = self.imgui.frame(width, height, delta_f);
let ui = self.imgui.frame(width, height, hidpi_factor, delta_f);
f(&ui);
self.renderer.render(&mut target, ui).unwrap();
target.finish().unwrap();

View File

@ -1,8 +1,9 @@
use glium::{Blend, DrawError, DrawParameters, GlObject, IndexBuffer, Program, Rect, Surface,
Texture2d, VertexBuffer, index, program, texture, vertex};
use glium::{DrawError, GlObject, IndexBuffer, Program, Surface, Texture2d, VertexBuffer};
use glium::backend::{Context, Facade};
use glium::index::PrimitiveType;
use glium::texture::{ClientFormat, RawImage2d};
use glium::program;
use glium::index::{self, PrimitiveType};
use glium::texture;
use glium::vertex;
use libc::uintptr_t;
use std::borrow::Cow;
use std::fmt;
@ -67,22 +68,31 @@ impl Renderer {
device_objects: device_objects,
})
}
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 result = ui.render(|draw_list| self.render_draw_list(surface, draw_list));
let result = ui.render(|draw_list, hidpi_factor| {
self.render_draw_list(surface, draw_list, hidpi_factor)
});
let _ = self.ctx.insert_debug_marker("imgui-rs: rendering finished");
result
}
fn render_draw_list<'a, S: Surface>(&mut self,
surface: &mut S,
draw_list: DrawList<'a>)
draw_list: DrawList<'a>,
hidpi_factor: f32)
-> RendererResult<()> {
use glium::{Blend, DrawParameters, Rect};
use glium::uniforms::MagnifySamplerFilter;
try!(self.device_objects.upload_vertex_buffer(&self.ctx, draw_list.vtx_buffer));
try!(self.device_objects.upload_index_buffer(&self.ctx, draw_list.idx_buffer));
let (width, height) = surface.get_dimensions();
let matrix = [[2.0 / (width as f32), 0.0, 0.0, 0.0],
[0.0, 2.0 / -(height as f32), 0.0, 0.0],
let matrix = [[2.0 / (width as f32 / hidpi_factor), 0.0, 0.0, 0.0],
[0.0, 2.0 / -(height as f32 / hidpi_factor), 0.0, 0.0],
[0.0, 0.0, -1.0, 0.0],
[-1.0, 1.0, 0.0, 1.0]];
let font_texture_id = self.device_objects.texture.get_id() as uintptr_t;
@ -91,31 +101,34 @@ impl Renderer {
for cmd in draw_list.cmd_buffer {
// We don't support custom textures...yet!
assert!(cmd.texture_id as uintptr_t == font_texture_id);
let uniforms = uniform! {
matrix: matrix,
tex: &self.device_objects.texture
};
let draw_params = DrawParameters {
blend: Blend::alpha_blending(),
scissor: Some(Rect {
left: cmd.clip_rect.x as u32,
bottom: (height as f32 - cmd.clip_rect.w) as u32,
width: (cmd.clip_rect.z - cmd.clip_rect.x) as u32,
height: (cmd.clip_rect.w - cmd.clip_rect.y) as u32,
}),
..Default::default()
};
let idx_end = idx_start + cmd.elem_count as usize;
try!(surface.draw(&self.device_objects.vertex_buffer,
&self.device_objects
.index_buffer
.slice(idx_start..idx_end)
.expect("Invalid index buffer range"),
&self.device_objects.program,
&uniforms,
&draw_params));
&self.device_objects
.index_buffer
.slice(idx_start..idx_end)
.expect("Invalid index buffer range"),
&self.device_objects.program,
&uniform! {
matrix: matrix,
tex: self.device_objects.texture.sampled()
.magnify_filter(MagnifySamplerFilter::Nearest),
},
&DrawParameters {
blend: Blend::alpha_blending(),
scissor: Some(Rect {
left: (cmd.clip_rect.x * hidpi_factor) as u32,
bottom: (height as f32 - (cmd.clip_rect.w * hidpi_factor)) as u32,
width: ((cmd.clip_rect.z - cmd.clip_rect.x) * hidpi_factor) as u32,
height: ((cmd.clip_rect.w - cmd.clip_rect.y) * hidpi_factor) as u32,
}),
..DrawParameters::default()
}));
idx_start = idx_end;
}
Ok(())
}
}
@ -134,18 +147,20 @@ fn compile_default_program<F: Facade>(ctx: &F)
140 => {
vertex: include_str!("shader/vert_140.glsl"),
fragment: include_str!("shader/frag_140.glsl"),
outputs_srgb: true
outputs_srgb: true,
},
110 => {
vertex: include_str!("shader/vert_110.glsl"),
fragment: include_str!("shader/frag_110.glsl"),
outputs_srgb: true
}
outputs_srgb: true,
},
)
}
impl DeviceObjects {
pub fn init<F: Facade>(im_gui: &mut ImGui, ctx: &F) -> RendererResult<DeviceObjects> {
use glium::texture::{ClientFormat, RawImage2d};
let vertex_buffer = try!(VertexBuffer::empty_dynamic(ctx, 0));
let index_buffer = try!(IndexBuffer::empty_dynamic(ctx, PrimitiveType::TrianglesList, 0));

View File

@ -265,7 +265,12 @@ impl ImGui {
pub fn get_time(&self) -> f32 { unsafe { imgui_sys::igGetTime() } }
pub fn get_frame_count(&self) -> i32 { unsafe { imgui_sys::igGetFrameCount() } }
pub fn get_frame_rate(&self) -> f32 { self.io().framerate }
pub fn frame<'ui, 'a: 'ui>(&'a mut self, width: u32, height: u32, delta_time: f32) -> Ui<'ui> {
pub fn frame<'ui, 'a: 'ui>(&'a mut self,
width: u32,
height: u32,
hidpi_factor: f32,
delta_time: f32)
-> Ui<'ui> {
{
let io = self.io_mut();
io.display_size.x = width as c_float;
@ -274,9 +279,15 @@ impl ImGui {
}
unsafe {
imgui_sys::igNewFrame();
CURRENT_UI = Some(Ui { imgui: mem::transmute(self as &'a ImGui) });
CURRENT_UI = Some(Ui {
imgui: mem::transmute(self as &'a ImGui),
hidpi_factor: hidpi_factor,
});
}
Ui {
imgui: self,
hidpi_factor: hidpi_factor,
}
Ui { imgui: self }
}
}
@ -299,6 +310,7 @@ pub struct DrawList<'a> {
pub struct Ui<'ui> {
imgui: &'ui ImGui,
hidpi_factor: f32,
}
static FMT: &'static [u8] = b"%s\0";
@ -336,7 +348,7 @@ impl<'ui> Ui<'ui> {
io.metrics_active_windows
}
pub fn render<F, E>(self, mut f: F) -> Result<(), E>
where F: FnMut(DrawList<'ui>) -> Result<(), E>
where F: FnMut(DrawList<'ui>, f32) -> Result<(), E>
{
unsafe {
imgui_sys::igRender();
@ -348,7 +360,7 @@ impl<'ui> Ui<'ui> {
idx_buffer: (*cmd_list).idx_buffer.as_slice(),
vtx_buffer: (*cmd_list).vtx_buffer.as_slice(),
};
try!(f(draw_list));
try!(f(draw_list, self.hidpi_factor));
}
CURRENT_UI = None;
}