Copy a FBO to a New texture in VRAM . best way ?

Hello all,

I need some advice in how to copy an FBO ( just need to copy color ) to 3 or 4 textures in vram, so i can apply diffrent shaders to this diffrent textures.

I want to try to do some post-Rendring effects using shaders.

(write now, i can use shaders, except if i bind them to FBO …
… and i have allready tryed the change GL_TEXTURE_RECTANGLE_ARB to GL_TEXTURE_2D ).

Many thanks,

CC

Copying can be done by drawing a fullscreen textured quad while the texture memory you want to copy to is bound with an FBO. From your description of what you want to do, I’m not sure this is exactly what you want.

If you’re wanting to take a texture, apply some effects to it, and then combine the results into a final output image, you should do the following:

  1. Render scene to FBO
  2. Process scene with shaders
    2a) bind another FBO
    2b) bind scene texture from 1
    2c) bind processing shader
    2d) draw fullscreen quad
    2e) unbind shader, texture, and fbo
  3. Combine processed textures from 2 into final outout

Typically step 2 is encapsulated into a class that is specialized for taking N texture inputs and drawing them to screen using a quad while applying a shader and another FBO are bound.

Greetings otherside,

Thank you for pointing me in the right direction (there were so many to me ).

i have managed to do the process like you said, but i think, i messed with somwthing, or i forgot something
don’t know yet :slight_smile:

When i do the process without the shaders , i got copys working, but if i use some shader to make some processing, i got a black FBO.

So, i will keep looking to see what is my bug.

Thanks again, for pointing me in the right way.

CC

[quote author=“Carlos”]Greetings otherside,

Thank you for pointing me in the right direction (there were so many to me ).

i have managed to do the process like you said, but i think, i messed with somwthing, or i forgot something
don’t know yet :slight_smile:

When i do the process without the shaders , i got copys working, but if i use some shader to make some processing, i got a black FBO.

So, i will keep looking to see what is my bug.

Thanks again, for pointing me in the right way.

CC[/quote]

The process is usually something like this (in pseudo-code):

  
fbo fbo1, fbo2;  
shader shader1, shader2, shader3;  
  
// draw the scene into fbo1  
fbo1.bind( );  
 shader1.run( );  
   scene.render( );  
 shader1.stop( );  
fbo1.unbind( );  
  
// second pass, draw to fbo2 from fbo1 while  
// applying a fragment shader effect, but you could also  
// draw the scene again here with a different effect that  
// you can later combine  
fbo2.bind( );  
  shader2.run( );  
    bindtexture( fbo1.colorbuffer );  
    renderFullscreenQuad( );  
  shader2.stop( );  
fbo2.unbind( );  
  
// final pass, output to screen, either combine the first two  
// fbo:s or apply a third effect  
shader3.run( );  
  bindtexture( fbo2.colorbuffer );  
  renderFullscreenQuad( );  
shader3.stop( );  
  

if you want to combine the first two textures then you need to feed them both
to the shader, then the final pass would look something more like this (pseudo-code):

  
shader3.run( );  
  bindtexture( 1, fbo1.colorbuffer );  
  bindtexture( 2, fbo2.colorbuffer );  
  
  shader.setUniform( "texture1", 1 );  
  shader.setUniform( "texture2", 2 );  
  
  drawFullscreenQuad( );  
shader3.stop( );  
  

In your shadercode you would need to define both the samplers.
Hope this helps, if not, I can try to put together a small demo for you.

Greetings edvinbesic,

Well, i dont have words for´describing the help you and otherside has given to me, really … thanks :slight_smile:

you leed me in the right way, thanks again.

( it’s working allredy , know it’s time to tweek the shaders)

CC

Hello all,

I have a problem feeding a FBOtexture (006 version Posted: Thu Apr 02, 2009 12:50 pm
by jroge) to a shader.

First I draw a Teapot and feed in to the FBO, if I draw the result using the .draw function
it is shown properly, but feeding the FBOtexture to the shader results in a black image.

Feeding my ‘texture1’ to the shader works… what’s wrong?

Here’s my code.

  
  
#include "testApp.h"  
  
// script to test a FBOtexture fed to a shader, this script results in a black screen while a texture fed to the shader works fine..  
   
//--------------------------------------------------------------  
void testApp::setup()  
{	  
	w = 256;  
	h = 256;  
	  
	// allocate texColor  
	texColor.allocate(w,h,GL_RGB, false);  
	   
 	// set fboTexture  
	fboTexture.allocate(1024, 768, true);  
	cout << fboTexture.getTextureData().textureName[0] << endl;  
	  
  
	colorPixels = new unsigned char [w*h*3];  
	// color pixels, use w and h to control red and green  
	for (int i = 0; i < w; i++){  
		for (int j = 0; j < h; j++){  
			colorPixels[(j*w+i)*3 + 0] = i;	// r  
			colorPixels[(j*w+i)*3 + 1] = j;	// g  
			colorPixels[(j*w+i)*3 + 2] = 0; // b  
		}  
	}  
	  
   
	// shader  
	Shader.loadShader("combi");  
	Shader.Validate();  
	  
 	bShaderOn = true;   
  	Shader.setShaderActive(bShaderOn);  
   
 	glActiveTexture(GL_TEXTURE1);   
    glBindTexture(GL_TEXTURE_2D,texColor.getTextureData().textureName[0]);  
	texColor.loadData(colorPixels, w,h, GL_RGB);  
	  
	glActiveTexture(GL_TEXTURE2);   
	glBindTexture(GL_TEXTURE_2D,(GLuint)fboTexture.texData.textureName[0]);  
	  
	cout << "texture1 textureName[0]   : " << texColor.getTextureData().textureName[0]<< endl;  
	cout << "fboTexture textureName[0] : " << fboTexture.getTextureData().textureName[0]<< endl;  
    
	   
	// glActiveTexture(GL_TEXTURE0);  
	  
	GLint texLoc;   
	texLoc   = glGetUniformLocation(Shader.shader, "texture1");   
	glUniform1i(texLoc, 1);      
    
	texLoc   = glGetUniformLocation(Shader.shader, "fboTexture");   
	glUniform1i(texLoc, 2);    
	  
   
	// 	glUseProgram(0);															// ?  
  
	glActiveTexture(GL_TEXTURE0);  
	  
	//lights  
 	camLight.specular(240, 120 , 240);  
 	camLight.ambient(220, 200, 210);  
	  
	ofxMaterialSpecular(150, 150, 250);  
	ofxMaterialShininess(20);  
	ofBackground(255,255,255);  
}  
  
   
  
//--------------------------------------------------------------  
void testApp::update(){  
	  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
   
	// draw a teapot and feed it into the fbo..  
	fboTexture.swapIn();  
 	fboTexture.setupScreenForMe();  
	  
 	ofxSetSmoothLight(true);  
	  
	// draw objects   
	glEnable(GL_DEPTH_TEST);  
	glEnable(GL_TEXTURE_2D);  
	ofSetColor(55,255,55);  
	glPushMatrix();  
	  
 	glBindTexture(GL_TEXTURE_2D, 1);  
	glTranslatef(ofGetWidth()/2,ofGetHeight()/2, 0);  
	glRotatef(ofGetElapsedTimeMillis()*0.021, 0.0, 1.0, 0.0);   
  	glutSolidTeapot(210.1);		  
	glDisable(GL_DEPTH_TEST);  
	glDisable(GL_TEXTURE_2D);  
	glPopMatrix();  
	  
	ofSetColor(120,0,0);  
    ofDrawBitmapString("fps: "+ofToString(ofGetFrameRate(), 2), 110, 115);  
	  
	fboTexture.swapOut();  
 	fboTexture.setupScreenForThem();  
	  
	// draw the result..  this works fine   
	ofSetColor(255,255,255);  
	fboTexture.draw(80,100, 256, 256 );	  
		  
		 	  
	// but an attempt to feed the fboTexture in a shader and output the results in a black screen..  
  	Shader.setShaderActive(true);   
  
	Shader.setUniformVariable("texture1", int(GLuint(0)), currentShader);	  
	Shader.setUniformVariable("fboTexture", int(GLuint(1)), currentShader);  
 	Shader.setUniformVariable("mode", 0.0, currentShader);	  
   
	texColor.draw(412,100,w,h);  
		  
	Shader.setUniformVariable("texture1", int(GLuint(0)), currentShader);	  
	Shader.setUniformVariable("fboTexture", int(GLuint(1)), currentShader);  
 	Shader.setUniformVariable("mode", 1.0, currentShader);	  
 	texColor.draw(702,100,w,h);  
   
	Shader.setShaderActive(false);  
	  
	ofSetColor(120,0,0);  
    ofDrawBitmapString("fps: "+ofToString(ofGetFrameRate(), 2), 110, 115);  
	// fboTexture.draw(0,0, 1024, 768);  
  
}  
  
//--------------------------------------------------------------  
void testApp::keyPressed  (int key){   
	switch (key){  
		case ' ':  
		 ofResetElapsedTimeCounter();  
		break;  
	}  
}  
  
//--------------------------------------------------------------  
void testApp::keyReleased(int key){   
	  
}  
  
//--------------------------------------------------------------  
void testApp::mouseMoved(int x, int y ){  
	  
	// when the mouse moves, we change the color image:  
	float pct = (float)x / (float)ofGetWidth();  
	for (int i = 0; i < w; i++){  
		for (int j = 0; j < h; j++){  
			colorPixels[(j*w+i)*3 + 0] = i;	// r  
			colorPixels[(j*w+i)*3 + 1] = (unsigned char)(ofRandomuf() * 255);	// g  
			colorPixels[(j*w+i)*3 + 2] = (unsigned char)(pct*255); // b  
		}  
	}  
	// finally, load those pixels into the texture  
	texColor.loadData(colorPixels, w,h, GL_RGB);  
	  
}  
  
//--------------------------------------------------------------  
void testApp::mouseDragged(int x, int y, int button){  
	  
}  
  
//--------------------------------------------------------------  
void testApp::mousePressed(int x, int y, int button){  
	  
}  
  
//--------------------------------------------------------------  
void testApp::mouseReleased(int x, int y, int button){  
  
}  
  
//--------------------------------------------------------------  
void testApp::windowResized(int w, int h){  
  
}  
  
  
  
  

  
  
#ifndef _TEST_APP  
#define _TEST_APP  
  
  
#include "ofMain.h"  
#include "ofShader.h"  
#include "ofGraphics.h"  
#include "ofxLight.h"  
#include "ofxVectorMath.h"  
#include "ofFBOTexture.h"  
  
class testApp : public ofBaseApp{  
	  
	public:  
		  
		void setup();  
		void update();  
		void draw();  
		  
		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 windowResized(int w, int h);  
		  
		   
		ofTexture 		texColor;  
	 	ofFBOTexture	fboTexture;  
			  
		int 			w, h;  
		  
		unsigned char 	* colorPixels;  
		unsigned char 	* colorPixels2;		  
		unsigned char 	* grayPixels;  
		unsigned char 	* colorAlphaPixels;  
		unsigned char 	* plaatjePixels;  
		unsigned char 	* fboPixels;  
		unsigned char 	* billboardPixels;	  
		  
		// shader  
		ofShader Shader;  
		  
		bool bShaderOn;  
		GLuint currentShader;  
		  
		ofxLight camLight;  
};  
  
#endif	  
  

I use this simple shader:

  
  
// combi fragment shader  
uniform sampler2D texture1;   
uniform sampler2D fboTexture;  
  
  
uniform float mode;  
  
varying vec2  TexCoord;   
ivec2 TextureSize = ivec2(640,480);  
float pixelRadius;  
int pixelSize;  
#define KERNEL_SIZE 9  
vec2 texCoords[KERNEL_SIZE];  
float tolerance = 0.4;  
#define TWOPI 6.283185307179586  
  
void main(void)   
{   
     // get texture data  
	vec4 color1 = texture2D(texture1, TexCoord);   
	vec4 color2 = texture2D(fboTexture, TexCoord);   
	   
	if( mode == 0.0 ) {  
	 	gl_FragColor = color1;    
	}  
	  
	if( mode == 1.0 ) {  
	 	gl_FragColor = color2;    
	}  
}  
  

  
  
varying vec2  TexCoord;   
  
void main(void)   
{   
  
	TexCoord = gl_MultiTexCoord0.st ;   
	gl_Position = ftransform();      
}   
  

Can anybody help me with this problem?

Kind regards,
Adger