Sharing ofFbo between multiple windows: how? (shared_ptr?) [solved]

Hi Guys,

I’m doing some initial testing with the 0.9.0 version, and am really liking the possibility of using multiple windows in one app (without using addons). I can’t figure out though how to share a frame buffer (ofFbo) between the windows. (or if this is at all possible). I have a hunch I should use a shared_ptr, but have no clue how to do that yet.

I’ve tried it based upon the multiWindowOneAppExample project, but this is the only result I get:

main.cpp:

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

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

    settings.width = 300;
    settings.height = 300;
    settings.setPosition(ofVec2f(300,0));
    settings.resizable = true;
    shared_ptr<ofAppBaseWindow> secondWindow = ofCreateWindow(settings);

    shared_ptr<ofApp> mainApp(new ofApp);
    mainApp->setupSecondWindow();
    ofAddListener(secondWindow->events().draw, mainApp.get(), &ofApp::drawSecondWindow);

    ofRunApp(mainWindow, mainApp);
    ofRunMainLoop();
}

ofApp.h:

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

        void setupSecondWindow();
        void drawSecondWindow(ofEventArgs & args);

        ofFbo fbo;
		
};

ofApp.cpp:

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

    fbo.allocate(180, 100, GL_RGBA, ofFbo::maxSamples());

}

//--------------------------------------------------------------
void ofApp::update(){

}

//--------------------------------------------------------------
void ofApp::draw(){

    ofBackground(ofColor::black);
    ofSetColor(ofColor::white);
    ofDrawBitmapString("Main Window", 20, 20);

    fbo.begin();

    ofBackground(ofColor::white);
    ofSetColor(ofColor::red);
    ofDrawBitmapString("Frame buffer object", 10, 20);

    // animate the cube
    ofPushMatrix();
    ofTranslate(90, 60);
    ofRotate(sin(ofGetElapsedTimef()) * 180);
    ofDrawRectangle(-25, -25, 50, 50);
    ofPopMatrix();

    fbo.end();

    // draw the fbo
    ofSetColor(ofColor::white);
    fbo.draw(30,30);
    fbo.draw(50,150);


}

//--------------------------------------------------------------
void ofApp::setupSecondWindow(){

}

//--------------------------------------------------------------
void ofApp::drawSecondWindow(ofEventArgs & args){

    ofBackground(ofColor::black);
    ofSetColor(ofColor::white);
    ofDrawBitmapString("Second Window", 20, 20);

    // draw the fbo
    ofSetColor(ofColor::white);
    fbo.draw(30,30);
    fbo.draw(50,150);

}

Any ideas? Thanks!

you can’t share an fbo among windows but you can share the texture an ofFbo holds intetrnally. when creating the windows, on the second window set:

    settings.shareContextWith = mainWindow;
    shared_ptr<ofAppBaseWindow> secondWindow = ofCreateWindow(settings);

which will create the second window sharing the context with the first one. that allows to use most data GL objects, like textures, vbos, or any buffer but won’t allow you to use state objects like fbos, vaos or shaders.

5 Likes

That is great, thank you @arturo! I added settings.shareContextWith = mainWindow; to main.cpp, and on the secondary window I use fbo.getTexture().draw(30, 30);, and now it works fine.

1 Like

ok but if i had a texture extracted from an fbo in my main window (ofApp) then how can i draw it in the second window (named GuiApp, like in the example)? with shared pointers? or can i even share it somehow or can be shared only with multiWindowOneAppExample method? i used the multiWindowExample.

all opengl objects have shallow copy semantics that meaning that whenever you make a copy of something like a texture it’s just a reference to the original so if for example you have an fbo in the second window, setup that window first so the fbo is initialized and the in main do:

mainWindow->fboTexture = secondWindow->fbo.getTexture();

where fboTexture is just an ofTexture, that texture will get updated whenever the fbo in the second window get’s updated. you can also just use a raw pointer or shared_ptr whenever you need to share something between windows

thanks!