imgui-rs icon indicating copy to clipboard operation
imgui-rs copied to clipboard

Expose Viewport functionality

Open Rob2309 opened this issue 4 years ago • 19 comments

This PR intends to expose most of the Viewport functionality of ImGui.

  • Exposes the essential structs like PlatformIo, Viewport, Monitor, etc.
  • Adds support for PlatformViewportBackend and RendererViewportBackend.
  • imgui-winit-support mostly supports multiple Viewports, without breaking code changes to code that does not support Viewports.

The backend functions are implemented via two traits called PlatformViewportBackend and RendererViewportBackend.

I'm very open for suggestions for improvement, as I am not sure if everything I did uses the best approach.

Rob2309 avatar Mar 04 '22 14:03 Rob2309

Yes the renderers and platform integrations will need to be extended in order to support viewports.

I would have liked to add viewport support to the examples directly, but at least with glium it is currently impossible to create new windows at runtime, although it seems like this will be fixed soon :)

I also thought about reverting all the changes to the examples and add a single example with viewport support, as this might be easier to understand. Consider the changes to the examples as temporary testing code that i forgot to remove before opening the PR...

I will probably do some more work on this next week.

Rob2309 avatar Mar 12 '22 17:03 Rob2309

I was finally able to work on this a bit more :)

The examples should now be the same as before my PR again. The viewport example now implements a working viewport example using glow (since it still seems impossible to create glium windows in the event_loop).

I will add documentation to the example as soon as I have time.

Rob2309 avatar Mar 15 '22 15:03 Rob2309

Last time I checked (year or two ago), glium had troubles with sharing of textures between GL contexts. Dropped texture is cleaned up only from parent context, but left dangling in shared contexts (which messes up internal texture indices). Maybe there are some other bugs related to multiple windows (cause original glium author probably never tested such use case). wgpu worked fine with viewports, except that it leaked surface&swapchain on window destruction (pool of reusable windows could work as workaround).

qthree avatar Mar 15 '22 15:03 qthree

Last time I checked (year or two ago), glium had troubles with sharing of textures between GL contexts. Dropped texture is cleaned up only from parent context, but left dangling in shared contexts (which messes up internal texture indices). Maybe there are some other bugs related to multiple windows. wgpu worked fine with viewports, except that it leaked surface&swapchain on window destruction (pool of reusable windows could work as workaround).

Those issues just add onto the problems with Glium i guess. It is just impossible to create windows at runtime as Glium relies on EventLoop rather than EventLoopWindowTarget, but this might be fixed soon on crates.io as in https://github.com/glium/glium/pull/1997.

The reusable window pool idea might work but that is a very dirty hack in my opinion :(

Rob2309 avatar Mar 15 '22 15:03 Rob2309

I will try to implement context sharing in the viewport example as soon as possible

Rob2309 avatar Mar 15 '22 15:03 Rob2309

Side note: I put this under the v0.10 milestone, but no pressure whatsoever if it's not done by then or if you stop working on the PR!

Plus we have a very lose schedule and are still working on 0.9, so who knows when 0.10 will even be a thing (I just put it in the milestone to keep track of it)

dbr avatar Mar 19 '22 10:03 dbr

Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1

naiba avatar Mar 19 '22 11:03 naiba

Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1

Not sure, the main focus of this feature are the extra viewports, the user is still responsible for the main window as far as i know

Rob2309 avatar Mar 19 '22 19:03 Rob2309

Side note: I put this under the v0.10 milestone, but no pressure whatsoever if it's not done by then or if you stop working on the PR!

Plus we have a very lose schedule and are still working on 0.9, so who knows when 0.10 will even be a thing (I just put it in the milestone to keep track of it)

We might need to do some more work before releasing this feature into the wild:

  • The platform_user_data and renderer_user_data fields of viewports are currently raw pointers, there might be a more rust-like approach
  • The imgui-winit-support crate currently assumes winit-26 when viewports are enabled

Rob2309 avatar Mar 19 '22 20:03 Rob2309

Hi there, BTW Can this PR achieve this goal? https://github.com/imgui-rs/imgui-rs/issues/299 also https://github.com/inkyblackness/imgui-go-examples/issues/1

I would assume the solution described in the imgui-go link should work here - basically make your "main imgui window" occupy the full (OS) window by doing something like

ui.window("Main")
    .flags(flags)
    .position([0.0, 0.0], imgui::Condition::Always)
    .size(ui.io().display_size, imgui::Condition::Always)
    .build(...)

Then hide the decoration on the OS-window via winit. Then make your other windows new viewports and it should do what you describe - just be a bunch of floating widnows

..at least, in theory!

The imgui-winit-support crate currently assumes winit-26 when viewports are enabled

I think this is fine - since the viewport handling would be a new thing, I think it's reasonable it would require a recent winit version. We could just make it error if you try adn use old winit + viewport feature, but.. maybe even simpler, I've made #627 to discuss if we need to support so many winit versions at all

dbr avatar Mar 20 '22 01:03 dbr

Yay, That works pretty well. But I can only resize the window, not move it. How can I make the window move freely?

As I understand it, imgui's window is restricted to the main window, which now cannot be moved. after this PR merge, the window will be free to move, and then it will be awesome. Is this right?

image

naiba avatar Mar 20 '22 02:03 naiba

Yay, That works pretty well. But I can only resize the window, not move it. How can I make the window move freely?

As I understand it, imgui's window is restricted to the main window, which now cannot be moved. after this PR merge, the window will be free to move, and then it will be awesome. Is this right?

image

You might be able to just set the winit window position to your imgui window position every frame. Not sure if this works very well though...

Rob2309 avatar Mar 20 '22 13:03 Rob2309

You might be able to just set the winit window position to your imgui window position every frame. Not sure if this works very well though...

// return window pos offset of "Hello world" window
let window_pos = run_ui(&mut run, ui);
if !run {
    *control_flow = ControlFlow::Exit;
}

let gl_window = display.gl_window();
let mut target = display.draw();
target.clear_color_srgb(0.0, 0.0, 0.0, 0.0);
platform.prepare_render(&ui, gl_window.window());

println!("window_pos {:?}", window_pos);

let draw_data = imgui.render();

let gl_window_pos = gl_window.window().outer_position().unwrap();
println!("gl_window_pos {:?}", gl_window_pos);

// set winit window position
gl_window.window().set_outer_position(PhysicalPosition {
    x: window_pos[0] + gl_window_pos.x as f32,
    y: window_pos[1] + gl_window_pos.y as f32,
});
// code of run_ui
 ui.window("Hello world")
    .flags(WindowFlags::NO_COLLAPSE)
    .position([0.0, 0.0], Condition::Once)
   .build(|| {
      // blablabla
      pos = ui.window_pos();
  });
pos

I have implemented the winit window movement according to your suggestion, but it keeps moving and I didn't find a way to reset the position of the imgui window after moving the winit window. 🌚

If I just execute ui.window("Hello world").position([0.0,0.0], Condition::Once) immediately after moving the winit window or after fetching the imgui's window position, it's display will get messed up.

naiba avatar Mar 20 '22 15:03 naiba

When viewports are enabled, the imgui window position will be in desktop corrdinates, so you need to set the winit window position to the imgui window position as is, without adding winit position as offset :) But I don't think this will work perfectly as imgui doesnt really have support for a "now main window" mode...

Rob2309 avatar Mar 20 '22 17:03 Rob2309

It might be a good idea to have separate winit-support modules, one for non-viewport support and one with viewports enabled. Since the coordinate system is completely different depending on whether viewports are enabled, it might make the code more readable. Adding to that, Viewports require very tight interaction between platform and renderer backend, so it might be better to provide a combined platform-and-renderer-with-viewport support package.

Rob2309 avatar Mar 21 '22 06:03 Rob2309

Hi, any new updates?

naiba avatar Apr 20 '22 14:04 naiba

I will try to work on a combined winit + glow viewports renderer that could serve as a complete example on how to use viewports :)

Rob2309 avatar Apr 22 '22 06:04 Rob2309

Combining the winit+glow into one crate for the viewport sounds like a good idea to me!

With the "combined" crate, I would suggest only supporting the latest version of winit. The imgui-winit-support supports a confusingly large range of versions, which I don't think is necessary for the viewport handling (it seems reasonable to require someone using new viewport feature to use a recent version of winit), and we may drop the handling of so many versions in a future release (https://github.com/imgui-rs/imgui-rs/issues/627#issuecomment-1073143077)

dbr avatar Apr 23 '22 02:04 dbr

Thought so too, latest winit should be enough.

Rob2309 avatar Apr 25 '22 06:04 Rob2309

Hi, long time no see, any news?

naiba avatar Dec 01 '22 13:12 naiba

Hey, I must admit I haven't done much on this lately, although I plan to continue working on this soon.

Rob2309 avatar Dec 01 '22 14:12 Rob2309

Don't worry, I know how hard it is to get something done when I don't need it.

naiba avatar Dec 01 '22 14:12 naiba