Sending FBO to Fragment Shader

#1

Hi;
I’m working to understand how o use shaders. As first example, I’m trying to send a FBO to a fragment shader without any modification, only I want to catch the FBO and return the same scene. This is only a white rectangle with a red rectangle inner.

I think if I don’t apply any color modification, only returning the texture as I sent it, I would getting the same rectangle white with is inner red rectangle. But I’m getting the big white rectangle.

My code is

ofApp.cpp
----------------
void ofApp::setup(){

  #ifdef TARGET_OPENGLES
    shader.load("shadersES2/shader");
  #else
    if(ofIsGLProgrammableRenderer()){
      shader.load("shadersGL3/shader");
    } else {
      shader.load("shadersGL2/shader");
    }
  #endif

  ofSetFrameRate(60);

  //Dimensiones y posiciones del canvas
  winW = ofGetWidth();
  winH = ofGetHeight();

  rectPosX = (int)winW*0.334;
  rectPosY = (int)winH*0.061;
  rectSizeX = (int)winW*0.335;
  rectSizeY = (int)winH*0.781;  

  rectCenter = ofVec3f(rectSizeX/2,rectSizeY/2,0);

  fbo.allocate(rectSizeX,rectSizeY);  
}

void ofApp::draw(){
fbo.begin();
  ofPushStyle();
  //Dibuja rectangulo para transparencia
  ofSetColor(255,255,255,255);
  ofDrawRectangle(0,0,rectSizeX,rectSizeY);  

  ofSetColor(255,0,0,255);
  ofSetRectMode(OF_RECTMODE_CENTER);
  ofDrawRectangle(rectSizeX/2,rectSizeY/2,200,200);
  ofPopStyle();
  
  fbo.end();

  shader.begin();
  shader.setUniformTexture("fboTexture", fbo.getTexture(), 1);
  fbo.draw(rectPosX,rectPosY);  
  shader.end(); 

}

shader.vert
------------------
#version 150

uniform mat4 modelViewProjectionMatrix;

uniform sampler2DRect fboTexture;
in vec4 position;
in vec2 textcoord;

out vec2 texCoordVarying;

void main(){
    texCoordVarying = textcoord;
	gl_Position = modelViewProjectionMatrix * position;
}

shader.frag
------------------
#version 150

uniform sampler2DRect fboTexture;

in vec2 texCoordVarying;
out vec4 outputColor;

void main()
{

    vec4 clr = texture(fboTexture, texCoordVarying);

	outputColor = clr;

}

Can anyone help me, why I’m not getting the result that I want?

Thanks in advance

#2

One obvious thing that I notice is that you probably shouldn’t be trying to draw the same fbo with the shader that you’re sending as a texture.

Does this work?

void ofApp::draw(){
fbo.begin();
ofPushStyle();
//Dibuja rectangulo para transparencia
ofSetColor(255,255,255,255);
ofDrawRectangle(0,0,rectSizeX,rectSizeY);

ofSetColor(255,0,0,255);
ofSetRectMode(OF_RECTMODE_CENTER);
ofDrawRectangle(rectSizeX/2,rectSizeY/2,200,200);
ofPopStyle();

fbo.end();

shader.begin();
shader.setUniformTexture(“fboTexture”, fbo.getTexture(), 1);
ofDrawRectangle(rectPosX,rectPosY, fbo.getWidth(), fbo.getHeight()); //the only change is here.
shader.end();
}
1 Like
#3

Hi ayruos;

Thanks for reply. But I get a black rectangle. Maybe I didn’t understand how shaders and fbo works, but, what I think is. If I don’t do any change to the FBO that I pass to the shader I would get the same scene that I sent, is that correct?

I this case, I’m sending the fbo with 2 rectangles, then, I would be getting the same 2 rectangles.

correct?

#4

Yes and no.

If you pass an FBO as a texture and try to update the SAME FBO with the shader holding the same texture, there can and probably will be errors/issues that come up. The common practise is to have two FBOs, one to use as a texture and one as the final output.

Not sure why you’re not seeing the shader as a texture on a blank rectangle, can you double check first that your FBO works by drawing it straight to screen once?

Couple of small cleanup issues in case it’s not working/there are issues,

  1. You should probably be doing fbo.allocate(rectSizeX, rectSizeY, GL_RGBA);
  2. Clearing the fbo at every draw/update cycle with
fbo.begin();
ofClear(255,255,255, 0);
//... draw code here. 
fbo.end();
#5

I follow your tips, but I’m getting the same result.
I now, attach 3 images. only FBO, FBO with shader and ofDrawRectangle and, same as last but with the shader frag modified in red and green components.

My code

fbo.allocate(rectSizeX,rectSizeY,GL_RGBA);

ofPushStyle();
ofSetColor(ofColor::magenta);
ofDrawLine(0,centerY,winW,centerY);
ofDrawLine(centerX,0,centerX,winH);
ofPopStyle();

fbo.begin();
ofClear(255,255,255, 0);
ofPushStyle();
//Dibuja rectangulo para transparencia
ofSetColor(255,255,255,255);
ofDrawRectangle(0,0,rectSizeX,rectSizeY);

ofSetColor(255,0,0,255);
ofSetRectMode(OF_RECTMODE_CENTER);
ofDrawRectangle(rectSizeX/2,rectSizeY/2,200,200);
ofPopStyle();
fbo.end();

shader.begin();
shader.setUniformTexture(“fboTexture”, fbo.getTexture(), 1);
//fbo.draw(rectPosX,rectPosY);
ofDrawRectangle(rectPosX,rectPosY, fbo.getWidth(), fbo.getHeight()); //the only change is here.
shader.end();