jvcleave / ofxImGui

Use ImGui in openFrameworks
300 stars 123 forks source link

Merging forks : ImGuiContext and more #107

Closed Daandelange closed 3 years ago

Daandelange commented 3 years ago

Hello,

I'm looking into creating a non-api-breaking pull request merging various additions from various forks. (WIP branch) Creating a new issue here to not flood other issues and to discuss the merge. Feel free to join in if you made changes.

The biggest part of this merge is support of multi context, which also requires more control over the ofxImGui api, specially with the use of ImGuiContext. See also daandelange@a4a7209. In the Mosaic project, @d3cod3 and I need it for multiple ImGui::Begin() calls within a single frame (ofApp::Draw). Other use cases I've seen is using ImGui across multiple windows #91 ( @moebiussurfing @katotetsuro ). Or setting IO configs before calling setup().

List of picked features :

Furthermore, I'm wondering what the autoDraw parameter is used for.

73 @sphaero @jvcleave This is the only reference to autoDraw I found. What is this intended for ? How is this used ?

I'll also try to look at the latest ImGui integration examples; how they match ofxImGui. By the way, are the GLES and VK engines used by some people ?

sphaero commented 3 years ago

Great that you attempting the logistics of contributing this back. I kind of stopped using ofxImGui and am using Dear ImGui directly nowadays. If I recall correctly the autodraw parameter was there so you don't have to explicitly draw the ImGui drawlist but not sure.

moebiussurfing commented 3 years ago

hey @Daandelange , thanks a lot for sharing!

I am interested on this bc I have some addons where I use ImGui "internally" as gui (instead of typical ofxGui) but, when using another ImGui instance/context, like in ofApp, both ImGui instances collide. Sometimes, in some forks, it works but showing only a panel at the same time.

With the official addon from jvcleave, when using multiple instances on the same project, we get crashes on exit, and mouse colliding / blocking some windows too. So I'll try this repo to check if it works like that, and I will report here.

Now I tested the https://github.com/Daandelange/ofxImGui/tree/jvcleave/example-multiwindow example on Windows/VS2017. It works at starting, both sliders works. But when resizing/moving the windows they stop working, it's like the mouse pick coordinate lost the x,y/0,0 reference. So you can move the panel, but can't interact to the slider. Or maybe the window panels are colliding, I am not sure.

Daandelange commented 3 years ago

@sphaero, thanks, yes it looks like that.

@moebiussurfing : Then we have the exact same problem in Mosaic! Instance is more appropriated than context indeed, but related, as each instance need it's own ImGuiContext. (we'll also need to make it work with hot-loaded-plugins, but that's another issue) For clarification, my jvcleave branch is almost the same as the d3cod3 repo, rebased to fit jvcleave. The examples don't work yet, as doesn't multi-context. In the multiwindow example, there's some shading error too, only showing imgui-graphics in the bottom left quarter of the screen (disable autoDraw).

I've been reading trough ImGui updates : the new docking and viewport changes (how awesome!) come with changes that depreciate the current ofxImGui backend implementation, to be depreciated near ImGui2.0, so there's more to do than expected. The main differences are : no more RenderDrawListsFn + separated window manager (glfw) from renderer (opengl 2/3/ES). And it's not yet clear to me if we need multiple contexts or rather viewports. There's a chance that implementing the new backend solves our issue.

Daandelange commented 3 years ago

Ok, after experimenting a little (and reading ImGui docs again and again), I've got an idea of what needs to be done, on the GLFW side at least.

@moebiussurfing Then, there will only be our specific use-case left, where we need to call ofxImGui.begin() and end() multiple times in one render frame due to re-using code that drives it's own ImGui instance. (I'm wondering if our design choices are bad for that?!) In Mosaic, we fixed this by making ImGui calls "chainable" with an option in the setup(). Illustration:

void setup(){
  gui.setup(false,true); // No autodraw, Allow chaining
}
void draw(){
  // [...] some code
  gui.begin(); //   <-- First call = Normal behaviour
  ImGui::commands(); //....
  gui.end(); //     <-- Does nothing with chaining on
  // [...] more code
  { // scope = called plugin code that you can't change
    gui.begin(); // <-- Does nothing with chaining on
    ImGui::MoreCommands(); //....
    gui.end(); //   <-- Does nothing with chaining on
  }
  gui.draw(); //    <-- Also calls gui.end()
}

Would that solve your issue too ?

moebiussurfing commented 3 years ago

thanks a lot @Daandelange !, cool.

I pasted this above code into the example-multiwindow, (https://github.com/Daandelange/ofxImGui/tree/jvcleave) and it worked perfect: No crash on exit/closing windows, no rare blocking, and all 4 sliders work independent and still working after resizing or moving window.

(BTW the variables (v1-v1) are not linked. I don't know if they are shared or not, bc I never used multiwindow before. Maybe it's related to that scope thing... Nevermind.)

#pragma once

#include "ofMain.h"
#include "ofxImGui.h"

class ofApp : public ofBaseApp{

    public:

        void setup() {
            v2 = 0;
            v1 = 0;

            gui.setup(false, true); // No autodraw, Allow chaining
        }

        void draw() {
            // [...] some code
            gui.begin(); //   <-- First call = Normal behaviour
            ImGui::SliderFloat("slider1", &v1, 0.f, 10.f); //....
            ImGui::SliderFloat("slider2", &v2, 0.f, 10.f); //....
            gui.end(); //     <-- Does nothing with chaining on
            // [...] more code
            { // scope = called plugin code that you can't change
                gui.begin(); // <-- Does nothing with chaining on
                ImGui::SliderFloat("slider1", &v1, 0.f, 10.f); //....
                ImGui::SliderFloat("slider2", &v2, 0.f, 10.f); //....
                gui.end(); //   <-- Does nothing with chaining on
            }
            gui.draw(); //    <-- Also calls gui.end()
        }

    private:
        ofxImGui::Gui gui;
        float v1;
        float v2;
};

I tried that too on an add-on that uses an "internal" ofxImGui placed into MY_ADDON/libs, and another instance declared into ofApp and it worked too.

So this is finally working for my needs. Thanks again @Daandelange !

(I noticed that this branch/version(1.77) is not storing the docking layout by default (bc multi-instance?). Not only on exit/re-open app but also when opening closing windows on runtime. Could be maybe bc both instances are calling his own gui.setup(), and not chained like in your above code. So maybe I must tweak this and also make a kind of centralize windows style / fonts between instances. BTW on the example-demo it saves the docking/windows layout fine.)

Daandelange commented 3 years ago

For anyone interested, I've started pushing a proposal @ https://github.com/Daandelange/ofxImGui/tree/jvcleave You can follow / participate at https://github.com/Daandelange/ofxImGui/issues/1 I'll report back here when I feel it's ready to merge.

Daandelange commented 3 years ago

I could use some feedback now, it feels ready to be merged, although some testing is needed. (See the 2 links above.)

@jvcleave , as this brings in some important changes in depth, what's your interest into merging these changes ?

Daandelange commented 3 years ago

To be continued in #110 ...