ofxGui not updated in multi-window config

Hi,

I want to have two windows, one with a UI with settings and another with live video.
The UI window is however not updated (i.e. no interaction with the widgets possible) when I also open the live video window.
If I disable the ofCreateWindow and corresponding ofRunApp for the live video window in main(), then the UI is working properly.

Do I need to create the windows in a certain order, or anything else to be done?

Thanks in advance, Patrick

Hi P,

I tried replicating your error by combining the two examples multiWindowOneAppExample ( in examples/windowing/multiWindowOneAppExample, or here ) and videoGrabberExample ( in examples/video/videoGrabberExample or here ) with success.

Here is the code, I recon maybe you need a listener on the second window?

ofApp.h :

#pragma once

#include "ofMain.h"
#include "ofxGui.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void setupGui();
		void update();
		void draw();
		void drawGui(ofEventArgs & args);

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

		ofParameterGroup parameters;
		ofParameter<float> radius;
		ofParameter<ofColor> color;
		ofxPanel gui;


		
        ofVideoGrabber vidGrabber;
        ofPixels videoInverted;
        ofTexture videoTexture;
        int camWidth;
        int camHeight;
};

main.cpp :

#include "ofMain.h"
#include "ofApp.h"
#include "ofAppGLFWWindow.h"

//========================================================================
int main( ){
	ofGLFWWindowSettings settings;
    settings.setSize(600, 600);
	settings.setPosition(ofVec2f(300,0));
	settings.resizable = true;
	shared_ptr<ofAppBaseWindow> mainWindow = ofCreateWindow(settings);

    settings.setSize(300, 300);
	settings.setPosition(ofVec2f(0,0));
	settings.resizable = false;
	// uncomment next line to share main's OpenGL resources with gui
	//settings.shareContextWith = mainWindow;	
	shared_ptr<ofAppBaseWindow> guiWindow = ofCreateWindow(settings);
	guiWindow->setVerticalSync(false);

	shared_ptr<ofApp> mainApp(new ofApp);
	mainApp->setupGui();
	ofAddListener(guiWindow->events().draw,mainApp.get(),&ofApp::drawGui);

	ofRunApp(mainWindow, mainApp);
	ofRunMainLoop();

}

ofApp.cpp :

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){
	ofBackground(255);
	ofSetCircleResolution(200);

    camWidth = 320;  // try to grab at this size.
    camHeight = 240;

    //get back a list of devices.
    vector<ofVideoDevice> devices = vidGrabber.listDevices();

    for(size_t i = 0; i < devices.size(); i++){
        if(devices[i].bAvailable){
            //log the device
            ofLogNotice() << devices[i].id << ": " << devices[i].deviceName;
        }else{
            //log the device and note it as unavailable
            ofLogNotice() << devices[i].id << ": " << devices[i].deviceName << " - unavailable ";
        }
    }

    vidGrabber.setDeviceID(0);
    vidGrabber.setDesiredFrameRate(60);
    vidGrabber.initGrabber(camWidth, camHeight);

    videoInverted.allocate(camWidth, camHeight, OF_PIXELS_RGB);
    videoTexture.allocate(videoInverted);
    ofSetVerticalSync(true);
}

//--------------------------------------------------------------
void ofApp::setupGui(){
	parameters.setName("parameters");
	parameters.add(radius.set("radius",50,1,100));
	parameters.add(color.set("color",100,ofColor(0,0),255));
	gui.setup(parameters);
	ofSetBackgroundColor(0);
}

//--------------------------------------------------------------
void ofApp::update(){
    ofBackground(100, 100, 100);
    vidGrabber.update();

    if(vidGrabber.isFrameNew()){
        ofPixels & pixels = vidGrabber.getPixels();
        for(size_t i = 0; i < pixels.size(); i++){
            //invert the color of the pixel
            videoInverted[i] = 255 - pixels[i];
        }
        //load the inverted pixels
        videoTexture.loadData(videoInverted);
    }

}

//--------------------------------------------------------------
void ofApp::draw(){
    ofSetHexColor(0xffffff);
    vidGrabber.draw(20, 20);
    videoTexture.draw(20 + camWidth, 20, camWidth, camHeight);

    
	ofSetColor(color);
	ofDrawCircle(ofGetWidth()*0.5,ofGetWidth()*0.5,radius);
	ofSetColor(0);
	ofDrawBitmapString(ofGetFrameRate(),20,20);

}

//--------------------------------------------------------------
void ofApp::drawGui(ofEventArgs & args){
	gui.draw();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
    // in fullscreen mode, on a pc at least, the 
    // first time video settings the come up
    // they come up *under* the fullscreen window
    // use alt-tab to navigate to the settings
    // window. we are working on a fix for this...

    // Video settings no longer works in 10.7
    // You'll need to compile with the 10.6 SDK for this
    // For Xcode 4.4 and greater, see this forum post on instructions on installing the SDK
    // http://forum.openframeworks.cc/index.php?topic=10343
    if(key == 's' || key == 'S'){
        vidGrabber.videoSettings();
    }

}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

//--------------------------------------------------------------
void ofApp::mouseMoved(int x, int y ){

}

//--------------------------------------------------------------
void ofApp::mouseDragged(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mousePressed(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseReleased(int x, int y, int button){

}

//--------------------------------------------------------------
void ofApp::mouseEntered(int x, int y){

}

//--------------------------------------------------------------
void ofApp::mouseExited(int x, int y){

}

//--------------------------------------------------------------
void ofApp::windowResized(int w, int h){

}

//--------------------------------------------------------------
void ofApp::gotMessage(ofMessage msg){

}

//--------------------------------------------------------------
void ofApp::dragEvent(ofDragInfo dragInfo){ 

}

addons.make (or recall the project with the project generator):

ofxGui

Maybe I’m missing something?

Hope this solves your problem.

Best,

P

Ok thanks! The trick is probably in the line:

ofAddListener(guiWindow->events().draw,mainApp.get(),&ofApp::drawGui);

I managed to get it working without this by using a special sequence of creating the windows and apps. See below. Using trial and error. But I like a more robust approach like yours.

int main()
{
    ofGLWindowSettings settings;

    settings.setSize(SOURCE_WINDOW_WIDTH, SOURCE_WINDOW_HEIGHT);
    settings.setPosition(ofVec2f(WINDOW_OFFSET, 2 * WINDOW_OFFSET + SETTINGS_WINDOW_HEIGHT));
    auto sourceWindow = ofCreateWindow(settings);
    auto sourceView = make_shared<SourceView>();

    settings.setSize(OUTPUT_WINDOW_WIDTH, OUTPUT_WINDOW_HEIGHT);
    settings.setPosition(ofVec2f(2 * WINDOW_OFFSET + SETTINGS_WINDOW_WIDTH, WINDOW_OFFSET));
    auto outWindow = ofCreateWindow(settings);
    auto outputView = make_shared<OutputView>();

    settings.setSize(SETTINGS_WINDOW_WIDTH, SETTINGS_WINDOW_HEIGHT);
    settings.setPosition(ofVec2f(WINDOW_OFFSET, WINDOW_OFFSET));
    auto settingsWindow = ofCreateWindow(settings);
    auto settingsView = make_shared<SettingsView>();

    // IMPORTANT: Order matters here.
    ofRunApp(settingsWindow, settingsView);
    settingsView->setupParameters(sourceView, outputView);
    ofRunApp(sourceWindow, sourceView);
    ofRunApp(outWindow, outputView);

    ofRunMainLoop();
}

I am also triggered by your statement:

// uncomment next line to share main’s OpenGL resources with gui
//settings.shareContextWith = mainWindow;

What’s the use of that?
I am encoutering a serious decrease in framerate when using the multi-windows setup. After closing the GUI window (“settingsView”) and source window, then the framerate of the output window increases. Even when in both settings and source windows I disable any update and drawing.
(But I realize, this is getting off-topic … :wink:

Hey!

I believe it is returning a ref to the GLFWwindow previously created, to reuse its elements.

I believe the framerate drop is due to the contexts dragging CPU usage (obviously), because the context are the same for each of the windows.

How to make a gui window which has a different context for optimisation?
I’m not sure how.