mirror of
https://github.com/eliasstepanik/imgui-rs.git
synced 2026-01-25 04:18:46 +00:00
Implemented basic context sharing in viewport example
This commit is contained in:
parent
cbb98f5289
commit
57230dc81f
@ -23,8 +23,8 @@ fn main() {
|
|||||||
|
|
||||||
imgui.set_ini_filename(None);
|
imgui.set_ini_filename(None);
|
||||||
|
|
||||||
let mut main_viewport = Viewport::new(&event_loop, true, true);
|
let (mut main_viewport, context) = Viewport::new(&event_loop);
|
||||||
main_viewport.init_font_texture(&mut imgui);
|
main_viewport.init_font_texture(&mut imgui, &context);
|
||||||
|
|
||||||
let mut winit_platform = imgui_winit_support::WinitPlatform::init(&mut imgui);
|
let mut winit_platform = imgui_winit_support::WinitPlatform::init(&mut imgui);
|
||||||
imgui_winit_support::WinitPlatform::init_viewports(
|
imgui_winit_support::WinitPlatform::init_viewports(
|
||||||
@ -40,6 +40,8 @@ fn main() {
|
|||||||
|
|
||||||
let mut storage = ViewportStorage {
|
let mut storage = ViewportStorage {
|
||||||
window_target,
|
window_target,
|
||||||
|
context: &context,
|
||||||
|
main_viewport: &main_viewport,
|
||||||
viewports: &mut viewports,
|
viewports: &mut viewports,
|
||||||
};
|
};
|
||||||
winit_platform.handle_viewport_event(
|
winit_platform.handle_viewport_event(
|
||||||
@ -73,18 +75,20 @@ fn main() {
|
|||||||
|
|
||||||
let mut storage = ViewportStorage {
|
let mut storage = ViewportStorage {
|
||||||
window_target,
|
window_target,
|
||||||
|
context: &context,
|
||||||
|
main_viewport: &main_viewport,
|
||||||
viewports: &mut viewports,
|
viewports: &mut viewports,
|
||||||
};
|
};
|
||||||
winit_platform.update_viewports(&mut imgui, &mut storage);
|
winit_platform.update_viewports(&mut imgui, &mut storage);
|
||||||
|
|
||||||
let main_draw_data = imgui.render();
|
let main_draw_data = imgui.render();
|
||||||
render_viewport(&mut main_viewport, main_draw_data);
|
render_viewport(&mut main_viewport, main_draw_data, &context);
|
||||||
|
|
||||||
for (id, viewport) in &mut viewports {
|
for (id, viewport) in &mut viewports {
|
||||||
viewport.init_font_texture(&mut imgui);
|
viewport.init_font_texture(&mut imgui, &context);
|
||||||
|
|
||||||
let draw_data = imgui.viewport_by_id(*id).unwrap().draw_data();
|
let draw_data = imgui.viewport_by_id(*id).unwrap().draw_data();
|
||||||
render_viewport(viewport, draw_data);
|
render_viewport(viewport, draw_data, &context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,18 +108,18 @@ fn render(imgui: &mut imgui::Context) {
|
|||||||
ui.end_frame_early();
|
ui.end_frame_early();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData, context: &glow::Context) {
|
||||||
let pos = viewport.window().inner_position().unwrap();
|
let pos = viewport.window().inner_position().unwrap();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
viewport.make_current();
|
viewport.make_current();
|
||||||
|
|
||||||
viewport.context.disable(glow::SCISSOR_TEST);
|
context.disable(glow::SCISSOR_TEST);
|
||||||
viewport.context.clear(glow::COLOR_BUFFER_BIT);
|
context.clear(glow::COLOR_BUFFER_BIT);
|
||||||
viewport.context.enable(glow::SCISSOR_TEST);
|
context.enable(glow::SCISSOR_TEST);
|
||||||
|
|
||||||
viewport.context.bind_vertex_array(Some(viewport.vao));
|
context.bind_vertex_array(Some(viewport.vao));
|
||||||
viewport.context.use_program(Some(viewport.shader));
|
context.use_program(Some(viewport.shader));
|
||||||
|
|
||||||
let left = draw_data.display_pos[0];
|
let left = draw_data.display_pos[0];
|
||||||
let right = draw_data.display_pos[0] + draw_data.display_size[0];
|
let right = draw_data.display_pos[0] + draw_data.display_size[0];
|
||||||
@ -140,34 +144,25 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
1.0,
|
1.0,
|
||||||
];
|
];
|
||||||
|
|
||||||
let loc = viewport
|
let loc = context
|
||||||
.context
|
|
||||||
.get_uniform_location(viewport.shader, "u_Matrix")
|
.get_uniform_location(viewport.shader, "u_Matrix")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
viewport
|
context.uniform_matrix_4_f32_slice(Some(&loc), false, &matrix);
|
||||||
.context
|
|
||||||
.uniform_matrix_4_f32_slice(Some(&loc), false, &matrix);
|
|
||||||
|
|
||||||
viewport.context.blend_func_separate(
|
context.blend_func_separate(
|
||||||
glow::SRC_ALPHA,
|
glow::SRC_ALPHA,
|
||||||
glow::ONE_MINUS_SRC_ALPHA,
|
glow::ONE_MINUS_SRC_ALPHA,
|
||||||
glow::ONE,
|
glow::ONE,
|
||||||
glow::ZERO,
|
glow::ZERO,
|
||||||
);
|
);
|
||||||
viewport.context.enable(glow::BLEND);
|
context.enable(glow::BLEND);
|
||||||
|
|
||||||
viewport
|
context.bind_buffer(glow::ARRAY_BUFFER, Some(viewport.vbo));
|
||||||
.context
|
context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(viewport.ibo));
|
||||||
.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);
|
||||||
.context
|
|
||||||
.bind_texture(glow::TEXTURE_2D, viewport.font_tex);
|
|
||||||
|
|
||||||
viewport.context.viewport(
|
context.viewport(
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
viewport.window().inner_size().width as i32,
|
viewport.window().inner_size().width as i32,
|
||||||
@ -177,7 +172,7 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
|
|
||||||
for draw_list in draw_data.draw_lists() {
|
for draw_list in draw_data.draw_lists() {
|
||||||
unsafe {
|
unsafe {
|
||||||
viewport.context.buffer_data_u8_slice(
|
context.buffer_data_u8_slice(
|
||||||
glow::ARRAY_BUFFER,
|
glow::ARRAY_BUFFER,
|
||||||
std::slice::from_raw_parts(
|
std::slice::from_raw_parts(
|
||||||
draw_list.vtx_buffer().as_ptr() as *const u8,
|
draw_list.vtx_buffer().as_ptr() as *const u8,
|
||||||
@ -185,7 +180,7 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
),
|
),
|
||||||
glow::STREAM_DRAW,
|
glow::STREAM_DRAW,
|
||||||
);
|
);
|
||||||
viewport.context.buffer_data_u8_slice(
|
context.buffer_data_u8_slice(
|
||||||
glow::ELEMENT_ARRAY_BUFFER,
|
glow::ELEMENT_ARRAY_BUFFER,
|
||||||
std::slice::from_raw_parts(
|
std::slice::from_raw_parts(
|
||||||
draw_list.idx_buffer().as_ptr() as *const u8,
|
draw_list.idx_buffer().as_ptr() as *const u8,
|
||||||
@ -193,12 +188,7 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
),
|
),
|
||||||
glow::STREAM_DRAW,
|
glow::STREAM_DRAW,
|
||||||
);
|
);
|
||||||
viewport.context.bind_vertex_buffer(
|
context.bind_vertex_buffer(0, Some(viewport.vbo), 0, size_of::<DrawVert>() as i32);
|
||||||
0,
|
|
||||||
Some(viewport.vbo),
|
|
||||||
0,
|
|
||||||
size_of::<DrawVert>() as i32,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for cmd in draw_list.commands() {
|
for cmd in draw_list.commands() {
|
||||||
@ -211,11 +201,9 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
let width = (cmd_params.clip_rect[2] - cmd_params.clip_rect[0]) as i32;
|
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;
|
let height = (cmd_params.clip_rect[3] - cmd_params.clip_rect[1]) as i32;
|
||||||
|
|
||||||
viewport
|
context.scissor(x, window_height - (y + height), width, height);
|
||||||
.context
|
context.enable(glow::SCISSOR_TEST);
|
||||||
.scissor(x, window_height - (y + height), width, height);
|
context.draw_elements_base_vertex(
|
||||||
viewport.context.enable(glow::SCISSOR_TEST);
|
|
||||||
viewport.context.draw_elements_base_vertex(
|
|
||||||
glow::TRIANGLES,
|
glow::TRIANGLES,
|
||||||
count as i32,
|
count as i32,
|
||||||
glow::UNSIGNED_SHORT,
|
glow::UNSIGNED_SHORT,
|
||||||
@ -232,16 +220,15 @@ fn render_viewport(viewport: &mut Viewport, draw_data: &DrawData) {
|
|||||||
|
|
||||||
struct ViewportStorage<'a, T: 'static> {
|
struct ViewportStorage<'a, T: 'static> {
|
||||||
window_target: &'a glutin::event_loop::EventLoopWindowTarget<T>,
|
window_target: &'a glutin::event_loop::EventLoopWindowTarget<T>,
|
||||||
|
main_viewport: &'a Viewport,
|
||||||
|
context: &'a glow::Context,
|
||||||
viewports: &'a mut HashMap<imgui::Id, Viewport>,
|
viewports: &'a mut HashMap<imgui::Id, Viewport>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: 'static> imgui_winit_support::WinitPlatformViewportStorage for ViewportStorage<'a, T> {
|
impl<'a, T: 'static> imgui_winit_support::WinitPlatformViewportStorage for ViewportStorage<'a, T> {
|
||||||
fn create_window(&mut self, id: imgui::Id, flags: imgui::ViewportFlags) {
|
fn create_window(&mut self, id: imgui::Id, flags: imgui::ViewportFlags) {
|
||||||
let viewport = Viewport::new(
|
let viewport =
|
||||||
self.window_target,
|
Viewport::new_shared(self.window_target, self.main_viewport, self.context, flags);
|
||||||
false,
|
|
||||||
!flags.contains(ViewportFlags::NO_DECORATION),
|
|
||||||
);
|
|
||||||
self.viewports.insert(id, viewport);
|
self.viewports.insert(id, viewport);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,7 +255,6 @@ impl<'a, T: 'static> imgui_winit_support::WinitPlatformViewportStorage for Viewp
|
|||||||
|
|
||||||
struct Viewport {
|
struct Viewport {
|
||||||
window: Option<glutin::ContextWrapper<PossiblyCurrent, glutin::window::Window>>,
|
window: Option<glutin::ContextWrapper<PossiblyCurrent, glutin::window::Window>>,
|
||||||
context: glow::Context,
|
|
||||||
vao: glow::VertexArray,
|
vao: glow::VertexArray,
|
||||||
vbo: glow::Buffer,
|
vbo: glow::Buffer,
|
||||||
ibo: glow::Buffer,
|
ibo: glow::Buffer,
|
||||||
@ -277,17 +263,13 @@ struct Viewport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Viewport {
|
impl Viewport {
|
||||||
fn new<T>(
|
fn new<T>(event_loop: &glutin::event_loop::EventLoopWindowTarget<T>) -> (Self, glow::Context) {
|
||||||
event_loop: &glutin::event_loop::EventLoopWindowTarget<T>,
|
|
||||||
visible: bool,
|
|
||||||
decorated: bool,
|
|
||||||
) -> Self {
|
|
||||||
let wb = glutin::window::WindowBuilder::new()
|
let wb = glutin::window::WindowBuilder::new()
|
||||||
.with_inner_size(glutin::dpi::LogicalSize::new(800.0, 600.0))
|
.with_inner_size(glutin::dpi::LogicalSize::new(800.0, 600.0))
|
||||||
.with_resizable(true)
|
.with_resizable(true)
|
||||||
.with_title("Viewports")
|
.with_title("Viewports")
|
||||||
.with_visible(visible)
|
.with_visible(true)
|
||||||
.with_decorations(decorated);
|
.with_decorations(true);
|
||||||
let window = unsafe {
|
let window = unsafe {
|
||||||
glutin::ContextBuilder::new()
|
glutin::ContextBuilder::new()
|
||||||
.with_double_buffer(Some(true))
|
.with_double_buffer(Some(true))
|
||||||
@ -339,9 +321,66 @@ impl Viewport {
|
|||||||
(vao, vbo, ibo, program)
|
(vao, vbo, ibo, program)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
(
|
||||||
|
Self {
|
||||||
|
window: Some(window),
|
||||||
|
vao,
|
||||||
|
vbo,
|
||||||
|
ibo,
|
||||||
|
shader,
|
||||||
|
font_tex: None,
|
||||||
|
},
|
||||||
|
context,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn new_shared<T>(
|
||||||
|
event_loop: &glutin::event_loop::EventLoopWindowTarget<T>,
|
||||||
|
main_viewport: &Viewport,
|
||||||
|
context: &glow::Context,
|
||||||
|
flags: imgui::ViewportFlags,
|
||||||
|
) -> Self {
|
||||||
|
let wb = glutin::window::WindowBuilder::new()
|
||||||
|
.with_inner_size(glutin::dpi::LogicalSize::new(100.0, 100.0))
|
||||||
|
.with_resizable(true)
|
||||||
|
.with_title("<unnamed>")
|
||||||
|
.with_always_on_top(flags.contains(ViewportFlags::TOP_MOST))
|
||||||
|
.with_decorations(!flags.contains(ViewportFlags::NO_DECORATION))
|
||||||
|
.with_visible(false);
|
||||||
|
let window = unsafe {
|
||||||
|
glutin::ContextBuilder::new()
|
||||||
|
.with_double_buffer(Some(true))
|
||||||
|
.with_vsync(true)
|
||||||
|
.with_shared_lists(main_viewport.window.as_ref().unwrap().context())
|
||||||
|
.build_windowed(wb, event_loop)
|
||||||
|
.unwrap()
|
||||||
|
.make_current()
|
||||||
|
.unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let (vao, vbo, ibo, shader) = unsafe {
|
||||||
|
let vao = context.create_vertex_array().unwrap();
|
||||||
|
let vbo = context.create_buffer().unwrap();
|
||||||
|
let ibo = context.create_buffer().unwrap();
|
||||||
|
|
||||||
|
context.bind_vertex_array(Some(vao));
|
||||||
|
context.vertex_attrib_binding(0, 0);
|
||||||
|
context.vertex_attrib_binding(1, 0);
|
||||||
|
context.vertex_attrib_binding(2, 0);
|
||||||
|
context.vertex_attrib_format_f32(0, 2, glow::FLOAT, false, 0);
|
||||||
|
context.vertex_attrib_format_f32(1, 2, glow::FLOAT, false, 8);
|
||||||
|
context.vertex_attrib_format_f32(2, 4, glow::UNSIGNED_BYTE, true, 16);
|
||||||
|
context.enable_vertex_attrib_array(0);
|
||||||
|
context.enable_vertex_attrib_array(1);
|
||||||
|
context.enable_vertex_attrib_array(2);
|
||||||
|
context.bind_buffer(glow::ELEMENT_ARRAY_BUFFER, Some(ibo));
|
||||||
|
context.bind_vertex_array(None);
|
||||||
|
|
||||||
|
(vao, vbo, ibo, main_viewport.shader)
|
||||||
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
window: Some(window),
|
window: Some(window),
|
||||||
context,
|
|
||||||
vao,
|
vao,
|
||||||
vbo,
|
vbo,
|
||||||
ibo,
|
ibo,
|
||||||
@ -350,7 +389,7 @@ impl Viewport {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_font_texture(&mut self, imgui: &mut imgui::Context) {
|
fn init_font_texture(&mut self, imgui: &mut imgui::Context, context: &glow::Context) {
|
||||||
if self.font_tex.is_some() {
|
if self.font_tex.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -358,11 +397,11 @@ impl Viewport {
|
|||||||
unsafe {
|
unsafe {
|
||||||
self.make_current();
|
self.make_current();
|
||||||
|
|
||||||
let font_tex = self.context.create_texture().unwrap();
|
let font_tex = context.create_texture().unwrap();
|
||||||
|
|
||||||
let data = imgui.fonts().build_rgba32_texture();
|
let data = imgui.fonts().build_rgba32_texture();
|
||||||
self.context.bind_texture(glow::TEXTURE_2D, Some(font_tex));
|
context.bind_texture(glow::TEXTURE_2D, Some(font_tex));
|
||||||
self.context.tex_image_2d(
|
context.tex_image_2d(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
0,
|
0,
|
||||||
glow::RGBA as i32,
|
glow::RGBA as i32,
|
||||||
@ -373,22 +412,22 @@ impl Viewport {
|
|||||||
glow::UNSIGNED_BYTE,
|
glow::UNSIGNED_BYTE,
|
||||||
Some(data.data),
|
Some(data.data),
|
||||||
);
|
);
|
||||||
self.context.tex_parameter_i32(
|
context.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_MAG_FILTER,
|
glow::TEXTURE_MAG_FILTER,
|
||||||
glow::LINEAR as i32,
|
glow::LINEAR as i32,
|
||||||
);
|
);
|
||||||
self.context.tex_parameter_i32(
|
context.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_MIN_FILTER,
|
glow::TEXTURE_MIN_FILTER,
|
||||||
glow::LINEAR as i32,
|
glow::LINEAR as i32,
|
||||||
);
|
);
|
||||||
self.context.tex_parameter_i32(
|
context.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_WRAP_S,
|
glow::TEXTURE_WRAP_S,
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
glow::CLAMP_TO_EDGE as i32,
|
||||||
);
|
);
|
||||||
self.context.tex_parameter_i32(
|
context.tex_parameter_i32(
|
||||||
glow::TEXTURE_2D,
|
glow::TEXTURE_2D,
|
||||||
glow::TEXTURE_WRAP_T,
|
glow::TEXTURE_WRAP_T,
|
||||||
glow::CLAMP_TO_EDGE as i32,
|
glow::CLAMP_TO_EDGE as i32,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user