Lost with Textures Shaders and FBO

Hello, i´m traing to implement ping-pong FBO technique. I´m using Reaction-Diffusion example from Cinder ( https://github.com/cinder/Cinder/blob/master/samples/RDiffusion/src/RDiffusionApp.cpp )But I´m not getting any good result. It seams that is applying the shader but something it´s missing that doesn´t appear the Gray Scott effect.

Any idea why? Am I doing things correctly?

testApp.h: (Sorry for the commented parts… I´m geting lost on the trial and error process)

  
  
void testApp::setup(){  
	ofDisableArbTex();  
	//ofEnableNormalizedTexCoords();  
	ofSetFrameRate(60);  
	  
	image.loadImage("starter.jpg");  
	  
	width = image.getWidth();  
	height = image.getHeight();  
	ofSetWindowShape(512, 512); //ofSetWindowShape(width, height);  
	  
	mShader.setup("passThru.vert","gsrd.frag");  
	mReactionU = 0.25f;  
	mReactionV = 0.04f;  
	mReactionK = 0.047f;  
	mReactionF = 0.1f;  
	  
	mMousePressed = false;  
	  
	mCurrentFBO = 0;  
	mOtherFBO = 1;  
	mFBOs[0].setup(width,height,GL_RGB);  
	mFBOs[1].setup(width,height,GL_RGB);  
	  
	mTexture.allocate(width, height, GL_RGB);  
	mTexture.loadData(image.getPixels(), image.getWidth(), image.getHeight(), GL_RGB);  
	mTexture.setTextureWrap(GL_REPEAT, GL_REPEAT);  
	mTexture.setTextureMinMagFilter(GL_LINEAR, GL_LINEAR);  
	  
	//CINDER EQUIVALENT TO mTexture.bind(1);  
	//glActiveTexture( GL_TEXTURE0 +1);  
	//glBindTexture(mTexture.getTextureData().textureTarget, mTexture.getTextureData().textureID); //glBindTexture( mObj->mTarget, mObj->mTextureID );  
	//glActiveTexture( GL_TEXTURE0 );  
	  
	glActiveTexture( GL_TEXTURE0 + 1);  
	mTexture.bind();  
	//glBindTexture(GL_TEXTURE_2D,  mTexture.getTextureData().textureID);  
	  
	resetFBO();  
}  
  
void testApp::resetFBO(){  
	//CINDER EQUIVALENT TO mTexture.bind(0);  
	//glActiveTexture( GL_TEXTURE0 );  
	//glBindTexture(mTexture.getTextureData().textureTarget, mTexture.getTextureData().textureID); //glBindTexture( mObj->mTarget, mObj->mTextureID );  
	//glActiveTexture( GL_TEXTURE0 );  
	  
	//glEnable(GL_TEXTURE0);  
	//glBindTexture(GL_TEXTURE0,  mTexture.getTextureData().textureID);  
	  
	mTexture.bind();  
	for( int i = 0; i < 2; i++ ){  
		mFBOs[i].begin();  
		  
		glColor4f( 1.0f,1.0f,1.0f,1.0f);  
		  
		glBegin(GL_QUADS);  
        glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f);    
        glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( width, 0.0f, 0.0f);    
		glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( width,height, 0.0f);    
        glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f( 0.0f, height, 0.0f);    
		glEnd();  
		  
		mFBOs[i].end();  
	}  
	  
	mTexture.unbind();  
	//glDisable(GL_TEXTURE0);  
	  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
	const int ITERATIONS = 25;  
	for( int i = 0; i < ITERATIONS; i++ ) {  
		mCurrentFBO = ( mCurrentFBO + 1 ) % 2;  
		mOtherFBO   = ( mCurrentFBO + 1 ) % 2;  
		  
		//CINDER equivalen? mFBOs[ mCurrentFBO ].bindFramebuffer();  
		mFBOs[mCurrentFBO].begin();  
		  
		glEnable(GL_TEXTURE);  
		//CINDER equivalen? mFBOs[ mOtherFBO ].bindTexture();  
		glActiveTexture( GL_TEXTURE0 );  
		mFBOs[mOtherFBO].getTexture(0).bind();	  
		glBindTexture(GL_TEXTURE_2D, mFBOs[mOtherFBO].getTexture().getTextureData().textureID);   
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );  
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );  
		  
		glActiveTexture( GL_TEXTURE1);  
		mTexture.bind();  
		  
		mShader.begin();  
		mShader.setUniform1f("texture",0);  
		mShader.setUniform1f("srcTexture",1);  
		mShader.setUniform1f( "width", (float)width );  
		mShader.setUniform1f( "ru", mReactionU );  
		mShader.setUniform1f( "rv", mReactionV );  
		mShader.setUniform1f( "k", mReactionK );  
		mShader.setUniform1f( "f", mReactionF );  
		  
		glColor4f( 1.0f,1.0f,1.0f,1.0f);  
		glBegin(GL_QUADS);  
        glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f);    
        glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( width, 0.0f, 0.0f);    
		glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( width,height, 0.0f);    
        glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f( 0.0f, height, 0.0f);    
		glEnd();  
		  
		mShader.end();  
		  
		glActiveTexture( GL_TEXTURE1);  
		mTexture.unbind();  
		  
		glActiveTexture( GL_TEXTURE0);  
		mFBOs[mOtherFBO].getTexture(0).unbind();	  
		  
		if( mMousePressed ){  
			glColor3f( 1.0f,1.0f,1.0f);  
			ofSetColor(255, 255);  
			ofCircle(mouseX, mouseY, 10);  
		}  
		   
		mFBOs[ mCurrentFBO ].end();  
	}  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
	glClearColor( 1.0f,1.0f,1.0f,1.0f);  
	mFBOs[mCurrentFBO].draw(0, 0, ofGetWidth(), ofGetHeight());  
}  
  
   

testApp.h:

  
  
class testApp : public ofBaseApp{  
public:  
	void		setup();  
	void		resetFBO();  
	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);  
	void		dragEvent(ofDragInfo dragInfo);  
	void		gotMessage(ofMessage msg);  
	  
	ofImage		image;  
	int			width,height;  
	  
	ofShader	mShader;  
	ofFbo		mFBOs[2];  
	ofTexture	mTexture;  
	  
	float		mReactionU;  
	float		mReactionV;  
	float		mReactionK;  
	float		mReactionF;  
	  
	int			mCurrentFBO, mOtherFBO;  
	  
	bool		mMousePressed;  
};  
  

Frag shader:

  
  
// Based on a Gray Scott Frag shader from rdex-fluxus  
// [https://code.google.com/p/rdex-fluxus/source/browse/trunk/reactiondiffusion.frag](https://code.google.com/p/rdex-fluxus/source/browse/trunk/reactiondiffusion.frag)  
  
  
#version 120  
#define KERNEL_SIZE 9  
  
float kernel[KERNEL_SIZE];  
uniform float width;  
  
vec2 offset[KERNEL_SIZE];  
  
uniform sampler2D srcTexture;  
uniform sampler2D texture; // U := r, V := g, other channels ignored  
uniform float ru;          // rate of diffusion of U  
uniform float rv;          // rate of diffusion of V  
uniform float f;           // some coupling parameter  
uniform float k;           // another coupling parameter  
  
void main(void)  
{  
	vec2 texCoord	= gl_TexCoord[0].st;		// center coordinates  
	float w			= 1.0/width;  
	float h			= 1.0/width;  
	float w2		= w*2.0;  
	float h2		= h*2.0;  
	  
	kernel[0] = 0.707106781;  
	kernel[1] = 1.0;  
	kernel[2] = 0.707106781;  
	kernel[3] = 1.0;  
	kernel[4] =-6.82842712;  
	kernel[5] = 1.0;  
	kernel[6] = 0.707106781;  
	kernel[7] = 1.0;  
	kernel[8] = 0.707106781;  
	  
	offset[0] = vec2( -w, -h);  
	offset[1] = vec2(0.0, -h);  
	offset[2] = vec2(  w, -h);  
	  
	offset[3] = vec2( -w, 0.0);  
	offset[4] = vec2(0.0, 0.0);  
	offset[5] = vec2(  w, 0.0);  
  
	offset[6] = vec2( -w, h);  
	offset[7] = vec2(0.0, h);  
	offset[8] = vec2(  w, h);  
	  
  
	vec2 texColor		= texture2D( texture, texCoord ).rb;  
	float srcTexColor	= texture2D( srcTexture, texCoord ).r;  
	  
	vec2 sum			= vec2( 0.0, 0.0 );  
	  
	for( int i=0; i<KERNEL_SIZE; i++ ){  
		vec2 tmp	= texture2D( texture, texCoord + offset[i] ).rb;  
		sum			+= tmp * kernel[i];  
	}  
	  
	  
	float F		= f + srcTexColor * 0.025 - 0.0005;  
	float K		= k + srcTexColor * 0.025 - 0.0005;  
	  
	float u		= texColor.r;  
	float v		= texColor.g;  
	float uvv	= u * v * v;  
//============================================================================  
	float du	= ru * sum.r - uvv + F * (1.0 - u);		// Gray-Scott equation  
	float dv	= rv * sum.g + uvv - (F + K) * v;		// diffusion+-reaction  
//============================================================================  
	u += du*0.6;  
	v += dv*0.6;  
	gl_FragColor = vec4( clamp( u, 0.0, 1.0 ), 1.0 - u/v, clamp( v, 0.0, 1.0 ), 1.0 );  
}  
  
  

Any help it will be appreciated
Thanks!

I’m not sure how this got posted as a poll but it’s hiding your actual question. Also, I may be misunderstanding something, but instead of:

  
    for( int i = 0; i < ITERATIONS; i++ ) {    
        mCurrentFBO = ( mCurrentFBO + 1 ) % 2;    
        mOtherFBO   = ( mCurrentFBO + 1 ) % 2;    

don’t you want:

  
    for( int i = 0; i < ITERATIONS; i++ ) {    
        mCurrentFBO = ( i ) % 2;    
        mOtherFBO   = ( i + 1 ) % 2;    

Joshua, you are right. I completely miss understood this pull thing and I messed up.
I copy literally the lines

  
  
mCurrentFBO = ( mCurrentFBO + 1 ) % 2;      
mOtherFBO   = ( mCurrentFBO + 1 ) % 2;    

from rDiffusion cinder code. I agree with you that have lot of more sense your way of writing it.
Any way I try it and there isn´t any results.

I will re post my question in order others to see it.
Thanks Joshua


Hello, i´m traing to implement ping-pong FBO technique. I´m using Reaction-Diffusion example from Cinder ( https://github.com/cinder/Cinder/blob/master/samples/RDiffusion/src/RDiffusionApp.cpp )But I´m not getting any good result. It seams that is applying the shader but something it´s missing that doesn´t appear the Gray Scott effect.

Any idea why? Am I doing things correctly?

testApp.h: (Sorry for the commented parts… I´m geting lost on the trial and error process)

  
  
void testApp::setup(){    
    ofDisableArbTex();    
    //ofEnableNormalizedTexCoords();    
    ofSetFrameRate(60);    
        
    image.loadImage("starter.jpg");    
        
    width = image.getWidth();    
    height = image.getHeight();    
    ofSetWindowShape(512, 512); //ofSetWindowShape(width, height);    
        
    mShader.setup("passThru.vert","gsrd.frag");    
    mReactionU = 0.25f;    
    mReactionV = 0.04f;    
    mReactionK = 0.047f;    
    mReactionF = 0.1f;    
        
    mMousePressed = false;    
        
    mCurrentFBO = 0;    
    mOtherFBO = 1;    
    mFBOs[0].setup(width,height,GL_RGB);    
    mFBOs[1].setup(width,height,GL_RGB);    
        
    mTexture.allocate(width, height, GL_RGB);    
    mTexture.loadData(image.getPixels(), image.getWidth(), image.getHeight(), GL_RGB);    
    mTexture.setTextureWrap(GL_REPEAT, GL_REPEAT);    
    mTexture.setTextureMinMagFilter(GL_LINEAR, GL_LINEAR);    
        
    //CINDER EQUIVALENT TO mTexture.bind(1);    
    //glActiveTexture( GL_TEXTURE0 +1);    
    //glBindTexture(mTexture.getTextureData().textureTarget, mTexture.getTextureData().textureID); //glBindTexture( mObj->mTarget, mObj->mTextureID );    
    //glActiveTexture( GL_TEXTURE0 );    
        
    glActiveTexture( GL_TEXTURE0 + 1);    
    mTexture.bind();    
    //glBindTexture(GL_TEXTURE_2D,  mTexture.getTextureData().textureID);    
        
    resetFBO();    
}    
    
void testApp::resetFBO(){    
    //CINDER EQUIVALENT TO mTexture.bind(0);    
    //glActiveTexture( GL_TEXTURE0 );    
    //glBindTexture(mTexture.getTextureData().textureTarget, mTexture.getTextureData().textureID); //glBindTexture( mObj->mTarget, mObj->mTextureID );    
    //glActiveTexture( GL_TEXTURE0 );    
        
    //glEnable(GL_TEXTURE0);    
    //glBindTexture(GL_TEXTURE0,  mTexture.getTextureData().textureID);    
        
    mTexture.bind();    
    for( int i = 0; i < 2; i++ ){    
        mFBOs[i].begin();    
            
        glColor4f( 1.0f,1.0f,1.0f,1.0f);    
            
        glBegin(GL_QUADS);    
        glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f);      
        glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( width, 0.0f, 0.0f);      
        glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( width,height, 0.0f);      
        glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f( 0.0f, height, 0.0f);      
        glEnd();    
            
        mFBOs[i].end();    
    }    
        
    mTexture.unbind();    
    //glDisable(GL_TEXTURE0);    
        
}    
    
//--------------------------------------------------------------    
void testApp::update(){    
    const int ITERATIONS = 25;    
    for( int i = 0; i < ITERATIONS; i++ ) {    
        mCurrentFBO = ( mCurrentFBO + 1 ) % 2;    
        mOtherFBO   = ( mCurrentFBO + 1 ) % 2;    
            
        //CINDER equivalen? mFBOs[ mCurrentFBO ].bindFramebuffer();    
        mFBOs[mCurrentFBO].begin();    
            
        glEnable(GL_TEXTURE);    
        //CINDER equivalen? mFBOs[ mOtherFBO ].bindTexture();    
        glActiveTexture( GL_TEXTURE0 );    
        mFBOs[mOtherFBO].getTexture(0).bind();      
        glBindTexture(GL_TEXTURE_2D, mFBOs[mOtherFBO].getTexture().getTextureData().textureID);     
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );    
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );    
            
        glActiveTexture( GL_TEXTURE1);    
        mTexture.bind();    
            
        mShader.begin();    
        mShader.setUniform1f("texture",0);    
        mShader.setUniform1f("srcTexture",1);    
        mShader.setUniform1f( "width", (float)width );    
        mShader.setUniform1f( "ru", mReactionU );    
        mShader.setUniform1f( "rv", mReactionV );    
        mShader.setUniform1f( "k", mReactionK );    
        mShader.setUniform1f( "f", mReactionF );    
            
        glColor4f( 1.0f,1.0f,1.0f,1.0f);    
        glBegin(GL_QUADS);    
        glTexCoord3f(0.0f, 0.0f, 0.0f); glVertex3f( 0.0f, 0.0f, 0.0f);      
        glTexCoord3f(1.0f, 0.0f, 0.0f); glVertex3f( width, 0.0f, 0.0f);      
        glTexCoord3f(1.0f, 1.0f, 0.0f); glVertex3f( width,height, 0.0f);      
        glTexCoord3f(0.0f, 1.0f, 0.0f); glVertex3f( 0.0f, height, 0.0f);      
        glEnd();    
            
        mShader.end();    
            
        glActiveTexture( GL_TEXTURE1);    
        mTexture.unbind();    
            
        glActiveTexture( GL_TEXTURE0);    
        mFBOs[mOtherFBO].getTexture(0).unbind();        
            
        if( mMousePressed ){    
            glColor3f( 1.0f,1.0f,1.0f);    
            ofSetColor(255, 255);    
            ofCircle(mouseX, mouseY, 10);    
        }    
             
        mFBOs[ mCurrentFBO ].end();    
    }    
}    
    
//--------------------------------------------------------------    
void testApp::draw(){    
    glClearColor( 1.0f,1.0f,1.0f,1.0f);    
    mFBOs[mCurrentFBO].draw(0, 0, ofGetWidth(), ofGetHeight());    
}    
    
     

testApp.h:

  
  
class testApp : public ofBaseApp{    
public:    
    void        setup();    
    void        resetFBO();    
    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);    
    void        dragEvent(ofDragInfo dragInfo);    
    void        gotMessage(ofMessage msg);    
        
    ofImage     image;    
    int         width,height;    
        
    ofShader    mShader;    
    ofFbo       mFBOs[2];    
    ofTexture   mTexture;    
        
    float       mReactionU;    
    float       mReactionV;    
    float       mReactionK;    
    float       mReactionF;    
        
    int         mCurrentFBO, mOtherFBO;    
        
    bool        mMousePressed;    
};    

Frag shader:

  
  
// Based on a Gray Scott Frag shader from rdex-fluxus    
// [https://code.google.com/p/rdex-fluxus/source/browse/trunk/reactiondiffusion.frag-](https://code.google.com/p/rdex-fluxus/source/browse/trunk/reactiondiffusion.frag-)   
    
    
#version 120    
#define KERNEL_SIZE 9    
    
float kernel[KERNEL_SIZE];    
uniform float width;    
    
vec2 offset[KERNEL_SIZE];    
    
uniform sampler2D srcTexture;    
uniform sampler2D texture; // U := r, V := g, other channels ignored    
uniform float ru;          // rate of diffusion of U    
uniform float rv;          // rate of diffusion of V    
uniform float f;           // some coupling parameter    
uniform float k;           // another coupling parameter    
    
void main(void)    
{    
    vec2 texCoord   = gl_TexCoord[0].st;        // center coordinates    
    float w         = 1.0/width;    
    float h         = 1.0/width;    
    float w2        = w*2.0;    
    float h2        = h*2.0;    
        
    kernel[0] = 0.707106781;    
    kernel[1] = 1.0;    
    kernel[2] = 0.707106781;    
    kernel[3] = 1.0;    
    kernel[4] =-6.82842712;    
    kernel[5] = 1.0;    
    kernel[6] = 0.707106781;    
    kernel[7] = 1.0;    
    kernel[8] = 0.707106781;    
        
    offset[0] = vec2( -w, -h);    
    offset[1] = vec2(0.0, -h);    
    offset[2] = vec2(  w, -h);    
        
    offset[3] = vec2( -w, 0.0);    
    offset[4] = vec2(0.0, 0.0);    
    offset[5] = vec2(  w, 0.0);    
    
    offset[6] = vec2( -w, h);    
    offset[7] = vec2(0.0, h);    
    offset[8] = vec2(  w, h);    
        
    
    vec2 texColor       = texture2D( texture, texCoord ).rb;    
    float srcTexColor   = texture2D( srcTexture, texCoord ).r;    
        
    vec2 sum            = vec2( 0.0, 0.0 );    
        
    for( int i=0; i<KERNEL_SIZE; i++ ){    
        vec2 tmp    = texture2D( texture, texCoord + offset[i] ).rb;    
        sum         += tmp * kernel[i];    
    }    
        
        
    float F     = f + srcTexColor * 0.025 - 0.0005;    
    float K     = k + srcTexColor * 0.025 - 0.0005;    
        
    float u     = texColor.r;    
    float v     = texColor.g;    
    float uvv   = u * v * v;    
//============================================================================    
    float du    = ru * sum.r - uvv + F * (1.0 - u);     // Gray-Scott equation    
    float dv    = rv * sum.g + uvv - (F + K) * v;       // diffusion+-reaction    
//============================================================================    
    u += du*0.6;    
    v += dv*0.6;    
    gl_FragColor = vec4( clamp( u, 0.0, 1.0 ), 1.0 - u/v, clamp( v, 0.0, 1.0 ), 1.0 );    
}    

Any help it will be appreciated
Thanks!

Hi Patricio,

yes, i am kind of lost too, but you can go here and check:

http://forum.openframeworks.cc/t/projective-texturing-in-opengl/5573/0

you will see that “joshuajnoble” had to change
sample2D to sample2DRect , and other things,

he is using fbos:

  
    
    glActiveTexture(GL_TEXTURE0);    
    fbo1.getTexture(0).bind();   
  

and

  
shader.setUniform1i("tex0", 0);    
shader.setUniform1i("tex1", 1);  

and in the shader:

  
uniform sampler2DRect tex0;  
uniform sampler2DRect tex1;  
varying vec4 ProjTexCoord;  
  
void main()  
{  
   vec4 color;  
   vec4 colProj;  
   color = texture2DRect(tex0, gl_TexCoord[0].xy);  
   colProj = texture2DRectProj(tex1, ProjTexCoord);  
   color = color * colProj;  
   gl_FragColor = color;  
}  

hope this helps!!!

Thanks Miguel! Yes It helps a lot!!
Also width new oF007 improves and the readToPixels() funtion I´m geting this stuff working.

I already check your website. Really nice projects! It´s great to see more people integrating organic and raw art width new technologies! I just change the source codes to a github repository http://github.com/patriciogonzalezvivo/joyOfLight

Any improvements are welcome!

Let´s stay in contact!

Patricio

Hi Patricio,

great that helped.
Thanks for the link. I am just doing the same concept (light-painting app), and liked you superFastBlur… :slight_smile:
My approach is to blend pixels using custom equations in a float based array. That gives you sooo many possibilities… but now i want to make those equations in the shaders, and after apply other shaders to blur, glow, etc. , speeding up so much the app.

I will put the code once it is improved.
So did you solve your FBO ping pong code?
Could you share it? because i also try to use that, but no good solutions until now…
thanks !

Sorry I didn’t catch that you’re using the sampler2D vs sampler2DRect. That’s because OF uses the ARB enabled textures which can be non-power of two sized (i.e. other than 256x256, 512x512, etc) but those need to be passed to the shader as sampler2DRect.

As for code for ping-ponging FBOs, this post has some fairly easy to follow code: http://forum.openframeworks.cc/t/binding-fbo-as-texture-for-shader/4834/0 though it will be different than the 007 version. I’ll try to write one up w/the 007 style and post it here (need it for the book anyways :slight_smile: