mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-11 13:38:35 +00:00
Added dockspace_over_main_viewport() to Ui, finished basic viewport example
This commit is contained in:
parent
76bd236a95
commit
cbb98f5289
@ -1,22 +1,37 @@
|
||||
use std::{mem::size_of, collections::HashMap};
|
||||
use std::{collections::HashMap, mem::size_of};
|
||||
|
||||
use glow::HasContext;
|
||||
use glutin::{PossiblyCurrent, event_loop::ControlFlow, event::WindowEvent};
|
||||
use imgui::{DrawVert, BackendFlags, ConfigFlags, ViewportFlags, DrawData};
|
||||
use glutin::{event::WindowEvent, event_loop::ControlFlow, PossiblyCurrent};
|
||||
use imgui::{BackendFlags, ConfigFlags, DrawData, DrawVert, ViewportFlags};
|
||||
|
||||
fn main() {
|
||||
let event_loop = glutin::event_loop::EventLoop::new();
|
||||
|
||||
let mut imgui = imgui::Context::create();
|
||||
imgui.io_mut().backend_flags.insert(BackendFlags::RENDERER_HAS_VIEWPORTS);
|
||||
imgui.io_mut().config_flags.insert(ConfigFlags::DOCKING_ENABLE);
|
||||
imgui.io_mut().config_flags.insert(ConfigFlags::VIEWPORTS_ENABLE);
|
||||
imgui
|
||||
.io_mut()
|
||||
.backend_flags
|
||||
.insert(BackendFlags::RENDERER_HAS_VIEWPORTS);
|
||||
imgui
|
||||
.io_mut()
|
||||
.config_flags
|
||||
.insert(ConfigFlags::DOCKING_ENABLE);
|
||||
imgui
|
||||
.io_mut()
|
||||
.config_flags
|
||||
.insert(ConfigFlags::VIEWPORTS_ENABLE);
|
||||
|
||||
imgui.set_ini_filename(None);
|
||||
|
||||
let mut main_viewport = Viewport::new(&event_loop, true, true);
|
||||
main_viewport.init_font_texture(&mut imgui);
|
||||
|
||||
let mut winit_platform = imgui_winit_support::WinitPlatform::init(&mut imgui);
|
||||
imgui_winit_support::WinitPlatform::init_viewports(&mut imgui, main_viewport.window(), &event_loop);
|
||||
imgui_winit_support::WinitPlatform::init_viewports(
|
||||
&mut imgui,
|
||||
main_viewport.window(),
|
||||
&event_loop,
|
||||
);
|
||||
|
||||
let mut viewports = HashMap::new();
|
||||
|
||||
@ -27,20 +42,30 @@ fn main() {
|
||||
window_target,
|
||||
viewports: &mut viewports,
|
||||
};
|
||||
winit_platform.handle_viewport_event(&mut imgui, main_viewport.window(), &mut storage, &event);
|
||||
winit_platform.handle_viewport_event(
|
||||
&mut imgui,
|
||||
main_viewport.window(),
|
||||
&mut storage,
|
||||
&event,
|
||||
);
|
||||
|
||||
match event {
|
||||
glutin::event::Event::WindowEvent { window_id, event: WindowEvent::CloseRequested } => {
|
||||
glutin::event::Event::WindowEvent {
|
||||
window_id,
|
||||
event: WindowEvent::CloseRequested,
|
||||
} => {
|
||||
if window_id == main_viewport.window().id() {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
},
|
||||
}
|
||||
glutin::event::Event::MainEventsCleared => {
|
||||
main_viewport.window().request_redraw();
|
||||
},
|
||||
}
|
||||
glutin::event::Event::RedrawRequested(window_id) => {
|
||||
if window_id == main_viewport.window().id() {
|
||||
winit_platform.prepare_frame(imgui.io_mut(), main_viewport.window()).unwrap();
|
||||
winit_platform
|
||||
.prepare_frame(imgui.io_mut(), main_viewport.window())
|
||||
.unwrap();
|
||||
|
||||
render(&mut imgui);
|
||||
|
||||
@ -62,7 +87,7 @@ fn main() {
|
||||
render_viewport(viewport, draw_data);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
});
|
||||
@ -71,6 +96,8 @@ fn main() {
|
||||
fn render(imgui: &mut imgui::Context) {
|
||||
let ui = imgui.new_frame();
|
||||
|
||||
ui.dockspace_over_main_viewport();
|
||||
|
||||
let mut open = true;
|
||||
ui.show_demo_window(&mut open);
|
||||
|
||||
@ -95,40 +122,87 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
||||
let top = draw_data.display_pos[1];
|
||||
let bottom = draw_data.display_pos[1] + draw_data.display_size[1];
|
||||
let matrix = [
|
||||
(2.0 / (right - left)), 0.0, 0.0, 0.0,
|
||||
0.0, (2.0 / (top - bottom)), 0.0, 0.0,
|
||||
0.0, 0.0, -1.0, 0.0,
|
||||
|
||||
(2.0 / (right - left)),
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
(2.0 / (top - bottom)),
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
(right + left) / (left - right),
|
||||
(top + bottom) / (bottom - top),
|
||||
0.0,
|
||||
1.0,
|
||||
];
|
||||
|
||||
let loc = viewport.context.get_uniform_location(viewport.shader, "u_Matrix").unwrap();
|
||||
viewport.context.uniform_matrix_4_f32_slice(Some(&loc), false, &matrix);
|
||||
let loc = viewport
|
||||
.context
|
||||
.get_uniform_location(viewport.shader, "u_Matrix")
|
||||
.unwrap();
|
||||
viewport
|
||||
.context
|
||||
.uniform_matrix_4_f32_slice(Some(&loc), false, &matrix);
|
||||
|
||||
viewport.context.blend_func_separate(glow::SRC_ALPHA, glow::ONE_MINUS_SRC_ALPHA, glow::ONE, glow::ZERO);
|
||||
viewport.context.blend_func_separate(
|
||||
glow::SRC_ALPHA,
|
||||
glow::ONE_MINUS_SRC_ALPHA,
|
||||
glow::ONE,
|
||||
glow::ZERO,
|
||||
);
|
||||
viewport.context.enable(glow::BLEND);
|
||||
|
||||
viewport.context.bind_buffer(glow::ARRAY_BUFFER, Some(viewport.vbo));
|
||||
viewport.context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(viewport.ibo));
|
||||
viewport
|
||||
.context
|
||||
.bind_buffer(glow::ARRAY_BUFFER, Some(viewport.vbo));
|
||||
viewport
|
||||
.context
|
||||
.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(viewport.ibo));
|
||||
|
||||
viewport.context.bind_texture(glow::TEXTURE_2D, viewport.font_tex);
|
||||
viewport
|
||||
.context
|
||||
.bind_texture(glow::TEXTURE_2D, viewport.font_tex);
|
||||
|
||||
viewport.context.viewport(0, 0, viewport.window().inner_size().width as i32, viewport.window().inner_size().height as i32);
|
||||
viewport.context.viewport(
|
||||
0,
|
||||
0,
|
||||
viewport.window().inner_size().width as i32,
|
||||
viewport.window().inner_size().height as i32,
|
||||
);
|
||||
}
|
||||
|
||||
for draw_list in draw_data.draw_lists() {
|
||||
unsafe {
|
||||
viewport.context.buffer_data_u8_slice(glow::ARRAY_BUFFER, std::slice::from_raw_parts(draw_list.vtx_buffer().as_ptr() as *const u8, draw_list.vtx_buffer().len() * size_of::<DrawVert>()), glow::STREAM_DRAW);
|
||||
viewport.context.buffer_data_u8_slice(glow::ELEMENT_ARRAY_BUFFER, std::slice::from_raw_parts(draw_list.idx_buffer().as_ptr() as *const u8, draw_list.idx_buffer().len() * size_of::<u16>()), glow::STREAM_DRAW);
|
||||
viewport.context.bind_vertex_buffer(0, Some(viewport.vbo), 0, size_of::<DrawVert>() as i32);
|
||||
viewport.context.buffer_data_u8_slice(
|
||||
glow::ARRAY_BUFFER,
|
||||
std::slice::from_raw_parts(
|
||||
draw_list.vtx_buffer().as_ptr() as *const u8,
|
||||
draw_list.vtx_buffer().len() * size_of::<DrawVert>(),
|
||||
),
|
||||
glow::STREAM_DRAW,
|
||||
);
|
||||
viewport.context.buffer_data_u8_slice(
|
||||
glow::ELEMENT_ARRAY_BUFFER,
|
||||
std::slice::from_raw_parts(
|
||||
draw_list.idx_buffer().as_ptr() as *const u8,
|
||||
draw_list.idx_buffer().len() * size_of::<u16>(),
|
||||
),
|
||||
glow::STREAM_DRAW,
|
||||
);
|
||||
viewport.context.bind_vertex_buffer(
|
||||
0,
|
||||
Some(viewport.vbo),
|
||||
0,
|
||||
size_of::<DrawVert>() as i32,
|
||||
);
|
||||
}
|
||||
|
||||
for cmd in draw_list.commands() {
|
||||
match cmd {
|
||||
imgui::DrawCmd::Elements { count, cmd_params } => {
|
||||
if let imgui::DrawCmd::Elements { count, cmd_params } = cmd {
|
||||
unsafe {
|
||||
let window_height = viewport.window().inner_size().height as i32;
|
||||
|
||||
@ -137,17 +211,18 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
||||
let width = (cmd_params.clip_rect[2] - cmd_params.clip_rect[0]) as i32;
|
||||
let height = (cmd_params.clip_rect[3] - cmd_params.clip_rect[1]) as i32;
|
||||
|
||||
viewport.context.scissor(
|
||||
x,
|
||||
window_height - (y + height),
|
||||
width,
|
||||
height
|
||||
);
|
||||
viewport
|
||||
.context
|
||||
.scissor(x, window_height - (y + height), width, height);
|
||||
viewport.context.enable(glow::SCISSOR_TEST);
|
||||
viewport.context.draw_elements_base_vertex(glow::TRIANGLES, count as i32, glow::UNSIGNED_SHORT, (cmd_params.idx_offset * size_of::<u16>()) as i32, cmd_params.vtx_offset as i32);
|
||||
viewport.context.draw_elements_base_vertex(
|
||||
glow::TRIANGLES,
|
||||
count as i32,
|
||||
glow::UNSIGNED_SHORT,
|
||||
(cmd_params.idx_offset * size_of::<u16>()) as i32,
|
||||
cmd_params.vtx_offset as i32,
|
||||
);
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,7 +237,11 @@ struct ViewportStorage<'a, T: 'static> {
|
||||
|
||||
impl<'a, T: 'static> imgui_winit_support::WinitPlatformViewportStorage for ViewportStorage<'a, T> {
|
||||
fn create_window(&mut self, id: imgui::Id, flags: imgui::ViewportFlags) {
|
||||
let viewport = Viewport::new(self.window_target, false, !flags.contains(ViewportFlags::NO_DECORATION));
|
||||
let viewport = Viewport::new(
|
||||
self.window_target,
|
||||
false,
|
||||
!flags.contains(ViewportFlags::NO_DECORATION),
|
||||
);
|
||||
self.viewports.insert(id, viewport);
|
||||
}
|
||||
|
||||
@ -174,7 +253,9 @@ impl<'a, T: 'static> imgui_winit_support::WinitPlatformViewportStorage for Viewp
|
||||
&mut self,
|
||||
id: glutin::window::WindowId,
|
||||
) -> Option<(imgui::Id, &glutin::window::Window)> {
|
||||
self.viewports.iter().find(|(viewport_id, viewport)| viewport.window().id() == id)
|
||||
self.viewports
|
||||
.iter()
|
||||
.find(|(_, viewport)| viewport.window().id() == id)
|
||||
.map(|(viewport_id, viewport)| (*viewport_id, viewport.window()))
|
||||
}
|
||||
|
||||
@ -196,22 +277,30 @@ struct Viewport {
|
||||
}
|
||||
|
||||
impl Viewport {
|
||||
fn new<T>(event_loop: &glutin::event_loop::EventLoopWindowTarget<T>, visible: bool, decorated: bool) -> Self {
|
||||
fn new<T>(
|
||||
event_loop: &glutin::event_loop::EventLoopWindowTarget<T>,
|
||||
visible: bool,
|
||||
decorated: bool,
|
||||
) -> Self {
|
||||
let wb = glutin::window::WindowBuilder::new()
|
||||
.with_inner_size(glutin::dpi::LogicalSize::new(800.0, 600.0))
|
||||
.with_resizable(true)
|
||||
.with_title("Viewports")
|
||||
.with_visible(visible)
|
||||
.with_decorations(decorated);
|
||||
let window = unsafe{glutin::ContextBuilder::new()
|
||||
let window = unsafe {
|
||||
glutin::ContextBuilder::new()
|
||||
.with_double_buffer(Some(true))
|
||||
.with_vsync(true)
|
||||
.build_windowed(wb, &event_loop)
|
||||
.build_windowed(wb, event_loop)
|
||||
.unwrap()
|
||||
.make_current()
|
||||
.unwrap()};
|
||||
.unwrap()
|
||||
};
|
||||
|
||||
let context = unsafe{glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)};
|
||||
let context = unsafe {
|
||||
glow::Context::from_loader_function(|s| window.get_proc_address(s) as *const _)
|
||||
};
|
||||
|
||||
let (vao, vbo, ibo, shader) = unsafe {
|
||||
let vao = context.create_vertex_array().unwrap();
|
||||
@ -273,11 +362,37 @@ impl Viewport {
|
||||
|
||||
let data = imgui.fonts().build_rgba32_texture();
|
||||
self.context.bind_texture(glow::TEXTURE_2D, Some(font_tex));
|
||||
self.context.tex_image_2d(glow::TEXTURE_2D, 0, glow::RGBA as i32, data.width as i32, data.height as i32, 0, glow::RGBA, glow::UNSIGNED_BYTE, Some(data.data));
|
||||
self.context.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MAG_FILTER, glow::LINEAR as i32);
|
||||
self.context.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_MIN_FILTER, glow::LINEAR as i32);
|
||||
self.context.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_S, glow::CLAMP_TO_EDGE as i32);
|
||||
self.context.tex_parameter_i32(glow::TEXTURE_2D, glow::TEXTURE_WRAP_T, glow::CLAMP_TO_EDGE as i32);
|
||||
self.context.tex_image_2d(
|
||||
glow::TEXTURE_2D,
|
||||
0,
|
||||
glow::RGBA as i32,
|
||||
data.width as i32,
|
||||
data.height as i32,
|
||||
0,
|
||||
glow::RGBA,
|
||||
glow::UNSIGNED_BYTE,
|
||||
Some(data.data),
|
||||
);
|
||||
self.context.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MAG_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
self.context.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_MIN_FILTER,
|
||||
glow::LINEAR as i32,
|
||||
);
|
||||
self.context.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_WRAP_S,
|
||||
glow::CLAMP_TO_EDGE as i32,
|
||||
);
|
||||
self.context.tex_parameter_i32(
|
||||
glow::TEXTURE_2D,
|
||||
glow::TEXTURE_WRAP_T,
|
||||
glow::CLAMP_TO_EDGE as i32,
|
||||
);
|
||||
|
||||
self.font_tex = Some(font_tex);
|
||||
}
|
||||
@ -289,7 +404,7 @@ impl Viewport {
|
||||
|
||||
fn make_current(&mut self) {
|
||||
let window = self.window.take().unwrap();
|
||||
self.window = unsafe{Some(window.make_current().unwrap())};
|
||||
self.window = unsafe { Some(window.make_current().unwrap()) };
|
||||
}
|
||||
|
||||
fn swap_buffers(&self) {
|
||||
@ -297,7 +412,7 @@ impl Viewport {
|
||||
}
|
||||
}
|
||||
|
||||
const VERTEX_SHADER: &'static str = "#version 450 core
|
||||
const VERTEX_SHADER: &str = "#version 450 core
|
||||
|
||||
layout(location = 0) in vec2 in_Position;
|
||||
layout(location = 1) in vec2 in_UV;
|
||||
@ -316,7 +431,7 @@ void main() {
|
||||
|
||||
";
|
||||
|
||||
const FRAGMENT_SHADER: &'static str = "#version 450 core
|
||||
const FRAGMENT_SHADER: &str = "#version 450 core
|
||||
|
||||
in vec2 v2f_UV;
|
||||
in vec4 v2f_Color;
|
||||
|
||||
15
imgui/src/dock_space.rs
Normal file
15
imgui/src/dock_space.rs
Normal file
@ -0,0 +1,15 @@
|
||||
use std::ptr::null;
|
||||
|
||||
use crate::Ui;
|
||||
|
||||
impl Ui {
|
||||
pub fn dockspace_over_main_viewport(&self) {
|
||||
unsafe {
|
||||
sys::igDockSpaceOverViewport(
|
||||
sys::igGetMainViewport(),
|
||||
sys::ImGuiDockNodeFlags_PassthruCentralNode as i32,
|
||||
null(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,8 @@ use std::os::raw::c_char;
|
||||
pub use self::clipboard::*;
|
||||
pub use self::color::ImColor32;
|
||||
pub use self::context::*;
|
||||
#[cfg(feature = "docking")]
|
||||
pub use self::dock_space::*;
|
||||
pub use self::drag_drop::{DragDropFlags, DragDropSource, DragDropTarget};
|
||||
pub use self::draw_list::{ChannelsSplit, DrawListMut};
|
||||
pub use self::fonts::atlas::*;
|
||||
@ -63,6 +65,8 @@ mod clipboard;
|
||||
pub mod color;
|
||||
mod columns;
|
||||
mod context;
|
||||
#[cfg(feature = "docking")]
|
||||
mod dock_space;
|
||||
pub mod drag_drop;
|
||||
pub mod draw_list;
|
||||
mod fonts;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user