ofFbo vertical flip, sometimes

I have this:

///////////////////////////////////// setup
ofFbo fboA;
ofFbo fboB;
// allocate ...

/////////////////////////////////// draw 
fboA.begin();
// draw some stuff

fboB.begin();
ofClear(0); // Does not draw
fboB.end();

house.draw(); // <---- Upside down

fboA.end();

If I use fboB, the house object is drawn upside down. If I comment it out it draws correctly. I see it has been discussed on this issue but it’s supposed to be solved. Any thoughts?

it doesn’t make much sense to anidate fbos like that, the renderer should track the state and it should be doing the right thing, ill look into it but why not just do:

fbo1.begin()
...
fbo1.end();

fbo2.begin()
..
fbo2.end();

you can’t bind 2 fbos at the same time so anidating them like that won’t have any different effect than just binding one and then the other

1 Like

Thanks. That will probably fix the issue, but I’d like to understand why the issue was originated in the first place. I understand this is a recurring topic and that there’s an open issue tackling this specifically.

Is ofViewport() the culprit? Why can a nested fbo cause this?

the orignal coordinates in opengl (when you have the indentity matrix as projection view model) has y growing upwards but when working with textures their coordinates grow downwards. on top of that OF by default changes the coordinate space to have y grow downwards so it makes more sense when working with 2d (images work like that, the mouse coordinates work like that…)

when drawing to an fbo if we didn’t flipped the world coordinates you would get a texture that would be flipped so when an fbo is bound, the renderer inverts y, so when you draw the fbo texture it looks correct.

probably if you bind a second fbo without unbinding the first, the renderer is double flipping y so you get the original coordinates in which the texture will appear flipped. the renderer should be smarter and check if there was an fbo already bound and in that case don’t flip the coordinates again.

this is something that would happen in raw opengl, OF just fixes it but if you do something weird like anidating 2 fbos it might fail.

1 Like

Does ofCamera also affect the vFlipped state? I have situations in which nested FBOs work well, but others in which I get a flipped state.

I think it makes sense to have nested fbos. For instance to blend two fbos that share a camera perspective that both render inside another fbo.

Wouldn’t it make sense to allow this in OF? Why is it weird to nest fbos?

openGL only allows 1 fbo bound so when you anidate fbos there’s really not 2 fbos bound at the same time, only one of them. in pseudocode this is roughtly what happens internally:

fbo1.bind() -> glBindFbo(fbo1.id)
fbo2.bind() -> glBindFbo(fbo2.id)
fbo2.unbind() -> glBindFbo(fbo1.id)
fbo1.unbind() -> glBindFbo(0)
1 Like

and yes when you bind an ofCamera y grows upwards and that’s taken into account to set the flip of the fbo

Yes I’m aware of that, but it would be a nice feature to have an fbo stack that remembers the previously bound fbo.

This way you can just use fbos whenever you want without being constrained to the current state. Just like ofPushMatrix.

yes it already does that, there’s a stack that keeps the last bound fbo so when you unbind one it binds the previous one as it’s shown in the example above. it just doesn’t make sense from a GL point of view the idea of anidating fbos.

I know I know, but it’s not anidating. It’s just that I fill another fbo and the code happens to be between a begin() end() from another one.

Here’s a minimal working example that shows the problem I have. It seems that it is ofCamera that gets confused with the current flip state.

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{

    public:
        void setup()
        {
            fbo.allocate(100,100);
            fboInside.allocate(100,100);
            cam.setNearClip(1.0f);
            cam.setFarClip(100.0f);
        }

        void draw()
        {
            ////draw only inner fbo -> does not y-flip the red sphere
            //fbo.begin();
            //	cam.begin();
            //		ofClear(0);
            //		ofSetColor(ofColor::red);
            //		ofDrawSphere(0.0f, 20.0f, -50.0f, 10.0f);
            //	cam.end();
            //fbo.end();

            //draw inner and outer fbo -> y-flips the red sphere
            fbo.begin();

                fboInside.begin();
                    ofClear(0);
                    //fill in fboInside
                fboInside.end();


                // fill in fbo with camera's perspective
                cam.begin();
                    ofClear(0);
                    ofSetColor(ofColor::red);
                    ofDrawSphere(0.0f, 20.0f, -50.0f, 10.0f);
                    // use fboInside here is a shader or something...

                cam.end();

            fbo.end();

            fbo.draw(0,0, ofGetWidth(), ofGetHeight());
        }


        ofFbo fbo;
        ofFbo fboInside;
        ofCamera cam;
};

There should be a sphere rendered on top of the window, uncomment the first snippet to see the normal behaviour.

i’ll take a look but this:

    void draw(){
            fboInside.begin();
                ofClear(0);
                //fill in fboInside
            fboInside.end();

            //draw inner and outer fbo -&gt; y-flips the red sphere
            fbo.begin();
                // fill in fbo with camera's perspective
                cam.begin();
                    ofClear(0);
                    ofSetColor(ofColor::red);
                    ofDrawSphere(0.0f, 20.0f, -50.0f, 10.0f);
                    // use fboInside here is a shader or something...
                cam.end();
            fbo.end();

            fbo.draw(0,0, ofGetWidth(), ofGetHeight());
    }

should have the same effect and it makes much more sense

we probably shouldn’t even have fbo.begin/end and just have something like ofSetRenderSurface(fbo). which is what happens internally anyway