mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
commit
6dfeae0237
@ -57,28 +57,33 @@ 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);
|
||||
let scale = self.imgui.display_framebuffer_scale();
|
||||
self.imgui.set_mouse_pos(self.mouse_pos.0 as f32 / scale.0, self.mouse_pos.1 as f32 / scale.1);
|
||||
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 / scale.1);
|
||||
self.mouse_wheel = 0.0;
|
||||
}
|
||||
|
||||
pub fn render<'ui, 'a: 'ui , F: FnMut(&Ui<'ui>)>(
|
||||
&'a mut self, clear_color: (f32, f32, f32, f32), mut f: F) {
|
||||
pub fn render<F: FnMut(&Ui)>(&mut self, clear_color: (f32, f32, f32, f32), mut run_ui: F) {
|
||||
let now = SteadyTime::now();
|
||||
let delta = now - self.last_frame;
|
||||
let delta_f = delta.num_nanoseconds().unwrap() as f32 / 1_000_000_000.0;
|
||||
self.last_frame = now;
|
||||
|
||||
self.update_mouse();
|
||||
self.mouse_wheel = 0.0;
|
||||
|
||||
let mut target = self.display.draw();
|
||||
target.clear_color(clear_color.0, clear_color.1,
|
||||
clear_color.2, clear_color.3);
|
||||
|
||||
let (width, height) = target.get_dimensions();
|
||||
let ui = self.imgui.frame(width, height, delta_f);
|
||||
f(&ui);
|
||||
let window = self.display.get_window().unwrap();
|
||||
let size_points = window.get_inner_size_points().unwrap();
|
||||
let size_pixels = window.get_inner_size_pixels().unwrap();
|
||||
|
||||
let ui = self.imgui.frame(size_points, size_pixels, delta_f);
|
||||
|
||||
run_ui(&ui);
|
||||
|
||||
self.renderer.render(&mut target, ui).unwrap();
|
||||
|
||||
target.finish().unwrap();
|
||||
|
||||
@ -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,21 +68,33 @@ 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(|ui, draw_list| self.render_draw_list(surface, ui, draw_list));
|
||||
let _ = self.ctx.insert_debug_marker("imgui-rs: rendering finished");
|
||||
result
|
||||
}
|
||||
|
||||
fn render_draw_list<'a, S: Surface>(&mut self,
|
||||
surface: &mut S,
|
||||
ui: &'a Ui<'a>,
|
||||
draw_list: DrawList<'a>)
|
||||
-> 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],
|
||||
let (width, height) = ui.imgui().display_size();
|
||||
let (scale_width, scale_height) = ui.imgui().display_framebuffer_scale();
|
||||
|
||||
if width == 0.0 || height == 0.0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let matrix = [[2.0 / width as f32, 0.0, 0.0, 0.0],
|
||||
[0.0, 2.0 / -(height as f32), 0.0, 0.0],
|
||||
[0.0, 0.0, -1.0, 0.0],
|
||||
[-1.0, 1.0, 0.0, 1.0]];
|
||||
@ -91,31 +104,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 * scale_width) as u32,
|
||||
bottom: ((height - cmd.clip_rect.w) * scale_height) as u32,
|
||||
width: ((cmd.clip_rect.z - cmd.clip_rect.x) * scale_width) as u32,
|
||||
height: ((cmd.clip_rect.w - cmd.clip_rect.y) * scale_height) as u32,
|
||||
}),
|
||||
..DrawParameters::default()
|
||||
}));
|
||||
|
||||
idx_start = idx_end;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
@ -134,18 +150,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));
|
||||
|
||||
|
||||
32
src/lib.rs
32
src/lib.rs
@ -206,6 +206,14 @@ impl ImGui {
|
||||
let io = self.io_mut();
|
||||
io.key_repeat_rate = value;
|
||||
}
|
||||
pub fn display_size(&self) -> (f32, f32) {
|
||||
let io = self.io();
|
||||
(io.display_size.x, io.display_size.y)
|
||||
}
|
||||
pub fn display_framebuffer_scale(&self) -> (f32, f32) {
|
||||
let io = self.io();
|
||||
(io.display_framebuffer_scale.x, io.display_framebuffer_scale.y)
|
||||
}
|
||||
pub fn mouse_pos(&self) -> (f32, f32) {
|
||||
let io = self.io();
|
||||
(io.mouse_pos.x, io.mouse_pos.y)
|
||||
@ -265,11 +273,25 @@ 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,
|
||||
size_points: (u32, u32),
|
||||
size_pixels: (u32, u32),
|
||||
delta_time: f32)
|
||||
-> Ui<'ui> {
|
||||
{
|
||||
let io = self.io_mut();
|
||||
io.display_size.x = width as c_float;
|
||||
io.display_size.y = height as c_float;
|
||||
io.display_size.x = size_points.0 as c_float;
|
||||
io.display_size.y = size_points.1 as c_float;
|
||||
io.display_framebuffer_scale.x = if size_points.0 > 0 {
|
||||
size_pixels.0 as c_float / size_points.0 as c_float
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
io.display_framebuffer_scale.y = if size_points.1 > 0 {
|
||||
size_pixels.1 as c_float / size_points.1 as c_float
|
||||
} else {
|
||||
0.0
|
||||
};
|
||||
io.delta_time = delta_time;
|
||||
}
|
||||
unsafe {
|
||||
@ -336,7 +358,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(&Ui, DrawList) -> Result<(), E>
|
||||
{
|
||||
unsafe {
|
||||
imgui_sys::igRender();
|
||||
@ -348,7 +370,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(&self, draw_list));
|
||||
}
|
||||
CURRENT_UI = None;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user