ofFbo texture vs ofImage texture in Shader

Hi,

When filling an ofFbo with begin/end, and trying to use the texture in a shader, the texture shows up black.

fbo.begin();
ofClear(0);
// draw stuff
fbo.end();

shader.begin();
shader.setUniformTexture("image", fbo.getTexture(), 0);
// draw vbo
shader.end();

//black result

When filling an ofImage with a file .png, and using the texture in a shader, the texture shows up correctly.

ofImage image("sample.png");
    
shader.begin();
shader.setUniformTexture("image", image.getTexture(), 0);
// draw vbo
shader.end();

//good result

More info:

When reading the ofFbo pixels into an ofImage and using the ofImage’s texture for the shader, it shows up correctly.

fbo.begin();
ofClear(0);
// draw stuff
fbo.end();

ofPixels pixels;
fbo.readToPixels(pixels);
ofImage image(pixels);

shader.begin();
shader.setUniformTexture("image", image.getTexture(), 0);
// draw vbo
shader.end();

//good result

When drawing the ofFbo texture directly on screen, the texture is correct, but I cannot use it in the shader.

fbo.begin();
ofClear(0);
// draw stuff
fbo.end();

fbo.draw(0,0);
// the texture is there, but cannot use it in the shader

Edit: ofDisableArbTex() has been called before, in the setup();

Any ideas why I cannot use the ofFbo’s texture?

Thanks!

before allocating your FBO test to declare ofDisableArbTex();

good day

1 Like

Yep, I have tried that

Editing.

Yep… you got it.

It seems that I was allocating the ofFbos BEFORE calling ofDisableArbTex(), so they were created targeting ARB.

The ofFbos were constructed in the class constructor, as they were declared as such:

class ofApp
{
ofFbo fbo;

void ofApp()
{
    ofDisableArbTex();
}

void draw()
{
//do stuff
} 
};

For the ARB textures not to be targeted, the Fbos construction should be delayed:

class ofApp
{
shared_ptr<ofFbo> fbo;

void ofApp()
{
    ofDisableArbTex();
    fbo = make_shared<ofFbo>();
    fbo.allocate(...);
}

void draw()
{
//do stuff
} 
};

Is there any other solution?

Thanks @kashim

1 Like

just out of curiosity, you can also try this?

#include "ofMain.h"

class TestFboShader : public ofBaseApp{
        public:
        ofShader shader;
        ofFbo fbo;
        ofEasyCam cam;
        int w,h;

        void setup(){
                shader.load("v.glsl","f.glsl");
                w=ofGetWidth();
                h=ofGetHeight();
                ofDisableArbTex();
                fbo.allocate(w,h);
        }

        void update(){
                fbo.begin();
                ofClear(0,0,0,255);
                cam.begin();
                ofSetColor(255,0,0);
                ofDrawBox(100);
                cam.end();
                fbo.end();

        }

        void draw(){
                shader.begin();
                shader.setUniformTexture("tex",fbo.getTextureReference(),0);
                        fbo.draw(0,0);
                shader.end();
        }

};

int main( ){
        ofSetupOpenGL(1024,768, OF_WINDOW);
        ofRunApp( new TestFboShader());
}

shader test:

fragment:

uniform sampler2D tex;
varying vec2 texcoord;

void main()
{
    gl_FragColor = texture2D(tex, texcoord);
}

vertex:

varying vec2 texcoord;

void main(){
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
        texcoord = gl_MultiTexCoord0.st;
}

good day!
Dario

Is it not best to call ofDisableArbTex() in main instead of calling it within your classes or even ofApp? It’s safer to make sure it affects all classes.

Is there a reason not to do in in main?