TUTORIAL ::: FBOS, TEXTURES, SHADERS in of 007...

Hi all of Lovers…
so after receiving help from you, reading, coding, etc. i can now play with fbos, shaders, textures inside shaders, etc. etc.

it has been a long path to know how to do it, and as usual, the solution is a simple one.
So i want to share a working code example of this:
apply several shader into fbos, passing textures to shaders, displaying results, etc.

this is the code in testApp.cpp:

  
  
//--------------------------------------------------------------  
void testApp::setup(){  
  
	ofSetLogLevel(OF_LOG_VERBOSE);  
	ofBackground(34, 34, 34);  
	ofSetVerticalSync(false);  
	ofEnableAlphaBlending();  
  
	  
	// using the shader that passes through 10 blending modes "a la photoshop".   
	// taken from   
	// [http://www.ruudbijnen.nl/blog/2010/09/blending-textures-in-a-shader/](http://www.ruudbijnen.nl/blog/2010/09/blending-textures-in-a-shader/)  
	//  
	  
	shader2.load("shaders/noise");  
	shader.load("shaders/myShader");  
	  
	image1.loadImage("images/cat512.png");  
	image2.loadImage("images/grass512.png");  
	  
	w = image1.getWidth();  
	h = image2.getHeight();  
		  
	// lets allocate for the fbos. Check this: GL_RGBA....  
	fbo1.allocate(512, 512, GL_RGBA);  
	fbo2.allocate(512, 512, GL_RGBA);  
	fbo3.allocate(512, 512, GL_RGBA);  
	  
	// some parameters for the shader.   
	 shadeContrast = 0.8;  
	 shadeBrightness = 0.4;  
	 shadeBlendMix = 0.5;  
	// there are 10 diff. blend modes, you can swith them with key '.' and '-'    
	 shadeBlendMode = 0;  
	  
	// if we want to do the second "pass" in shaders-fbo.  
	// switch with key 's'.  
	  
	doShader = true;	  
}  
  
//--------------------------------------------------------------  
void testApp::update(){  
  
}  
  
//--------------------------------------------------------------  
void testApp::draw(){  
  
	ofSetColor(225);  
	ofDrawBitmapString("'s' toggles shader number 2", 10, 20);  
	ofDrawBitmapString("'.' and '-' to switch between blendmodes", 10, 40);  
  
  
	ofSetColor(245, 58, 135);  
	ofFill();  
	  
	  
	// we begin fbo1 and draw the image.   
	fbo1.begin();  
	ofSetColor(255);  
	image2.draw(0, 0);  
	fbo1.end();  
	  
	// fbo2: image2.   
	fbo2.begin();  
	ofSetColor(255);  
	image1.draw(0, 0);  
	fbo2.end();  
	  
	// set tex1 and tex2: textures from fbos.   
	ofTexture tex1 = fbo1.getTextureReference();  
	ofTexture tex2 = fbo2.getTextureReference();  
		  
	fbo3.begin();  
	ofClear(0, 0, 0, 1); // we clear the fbo.   
	  
	shader.begin(); // shader begin: set values.   
	  
	shader.setUniform1f( "contrast",	shadeContrast );  
    shader.setUniform1f( "brightness",	shadeBrightness );  
    shader.setUniform1f( "blendmix",	shadeBlendMix );  
    shader.setUniform1i( "blendmode",	shadeBlendMode );  
	  
	  
	// so here is the trick, important one:   
	// tex1 is the texture from fbo1.   
	// we assign this to texture 0 , i.e. "textBase" in the shader.   
	// this is as drawing into the fbo  image1. (from shader point of view)   
	// so instead of making :   
	// fbo2.draw(0,0) after shader parameters we make this line:    
	shader.setUniformTexture("texBase",   tex1, 0 ); //look that is number 0: and   
													// textures 0 are the ones used do "draw".   
													// so we could do this making fbo1.draw.  
	  
	// now we have another texture in the shader: it will be number 1:   
    shader.setUniformTexture("texBlend",  tex2, 1 );  
  
	// we did not draw anything into fbo3, so to make the shader draw, we need to make our quad.  
	// coord for the texture and for the display.   
	// it could be a non-rectangle shape, or whatever...  
	  
	glBegin(GL_QUADS);  
	glTexCoord2f(0, 0); glVertex3f(0, 0, 0);  
	glTexCoord2f(w, 0); glVertex3f(w, 0, 0);  
	glTexCoord2f(w, h); glVertex3f(w, h, 0);  
	glTexCoord2f(0,h);  glVertex3f(0,h, 0);  
	glEnd();  
	  
	  
	// we do not need this:  
	// fbo1.draw(0, 0);	  
	// because we did this:   
	// shader.setUniformTexture("texBase",   tex1, 0 );   
	  
	  
	shader.end(); // shader's end.   
	  
	  
	fbo3.end(); // end of the "containing" fbo.   
	  
	  
	// now we want to apply another shader, taking texture from this previous fbo3:   
	if(doShader){  
		  
	fbo3.begin();  
	  
	// texture tex3 == fbo3 (shaded)  
	ofTexture tex3 = fbo3.getTextureReference();  
  
	shader.begin();  
	  
	shader.setUniform1f( "contrast",	0.7 );  
    shader.setUniform1f( "brightness",	0.5 );  
    shader.setUniform1f( "blendmix",	0.7 );  
    shader.setUniform1i( "blendmode",	shadeBlendMode);  
	  
	shader.setUniformTexture("texBase",   tex1, 0 );  // tex base is the same...  
    shader.setUniformTexture("texBlend",  tex3, 1 ); //now the texture to blend is fbo3., so we apply shader 2 times....  
	  
	glBegin(GL_QUADS);  
	glTexCoord2f(0, 0); glVertex3f(0, 0, 0);  
	glTexCoord2f(w, 0); glVertex3f(w, 0, 0);  
	glTexCoord2f(w, h); glVertex3f(w, h, 0);  
	glTexCoord2f(0,h);  glVertex3f(0,h, 0);  
	glEnd();	  
	  
	//image1.draw(0, 0);	  
	  
	shader.end();   
	fbo3.end();  
		  
		  
	}  
	  
	ofSetColor(255);  
	//now we want to see the result:   
	fbo3.draw(0,50);  
	  
	  
}  
// -------------------  
  

i hope it helps you…
now we can do sooo many things, using sooo less cpu… :slight_smile:

i give you the of 007 xcode project in a .zip file:

http://www.tangiblex.net/of/fbos-textures-shaders-of007.zip


miguel.
www.tangiblex.net
www.gatodante.com/portfolio/

2 Likes

Many thanks for sharing this code, I was just looking for such code!

I have tried with a fresh download of OF007 (today), on windows xp with an Intel GMA HD and experienced a trap. The Intel driver was not at the latest level, but after upgrading, the example worked nice.

Thanks again

Jean-Pierre

thanks! been looking for a texturing example with GL_QUADS as well - much appreciated!

Hello Miguel, I´m working on your example. It´s a wonderful help to understand some important stuff of openGL on oF . Thanks!

:o
Let me at the very least buy you a drink!!!
This is GREAT! I’ve been needing this for a while now!

Thanks you very much!

Edit----
Code Blocks 10.05 x86 compiles no problem in Windows 7 x64, but when I run the program the Console says this, the program loads but it only shows 2 lines of text and no graphics. I know very little about shaders so, any help on this?

OF: OF_VERBOSE: Creating GLSL Program
OF: OF_VERBOSE: GL_VERTEX_SHADER shader compiled.
OF: OF_VERBOSE: GL_FRAGMENT_SHADER shader compiled.
OF: OF_VERBOSE: Attaching shader of type GL_FRAGMENT_SHADER
OF: OF_VERBOSE: Attaching shader of type GL_VERTEX_SHADER
OF: OF_VERBOSE: Creating GLSL Program
OF: OF_VERBOSE: GL_VERTEX_SHADER shader compiled.
OF: OF_VERBOSE: GL_FRAGMENT_SHADER shader compiled.
OF: OF_VERBOSE: Attaching shader of type GL_FRAGMENT_SHADER
OF: OF_VERBOSE: Attaching shader of type GL_VERTEX_SHADER
OF: OF_LOG_ERROR: Shader program reports:
Fragment info


(0) : fatal error C9999: *** exception during compilation ***

OF: OF_VERBOSE: FBO supported
OF: OF_LOG_NOTICE: ofFbo::checkGLSupport()
maxColorAttachments: 8
maxDrawBuffers: 8
maxSamples: 16

Hi,

thank you for the virtual drink… :slight_smile:

So, i see that your shader is having problems while compiling…
do not know the possible issue.
You could use another simple shader, try to look for a very simple one as blur…
you could also try the shader example in of 007. Is that running ok?
Are you using 007?

best,
miguel.

;D
I’m currently using the 0.07 from the homepage (the prerelease), but I read this:
http://forum.openframeworks.cc/t/offbo-maxsamples:–1-in-0.07/6824/0
So I will try getting the latest release from github (something I’ve always avoided) and I’ll try every fix on that thread.

Thanks again! :smiley:

miguelvb:
Nope, I’ve tried many times… I can compile the code but when I run the exe file it gives me the following error and window with lots of white color (which I edited in the attachment). This happens on a Windows 7 x64 using Code Blocks 10.05 (32 bit). I mention it because the code you posted is exactly what I’m trying to learn right now! =D
Thank you for the example, since I’ve still learnt much from it.

  
OF: OF_VERBOSE: Creating GLSL Program  
OF: OF_VERBOSE: GL_VERTEX_SHADER shader compiled.  
OF: OF_VERBOSE: GL_FRAGMENT_SHADER shader compiled.  
OF: OF_VERBOSE: Attaching shader of type GL_FRAGMENT_SHADER  
OF: OF_VERBOSE: Attaching shader of type GL_VERTEX_SHADER  
OF: OF_VERBOSE: Creating GLSL Program  
OF: OF_VERBOSE: GL_VERTEX_SHADER shader compiled.  
OF: OF_VERBOSE: GL_FRAGMENT_SHADER shader compiled.  
OF: OF_VERBOSE: Attaching shader of type GL_FRAGMENT_SHADER  
OF: OF_VERBOSE: Attaching shader of type GL_VERTEX_SHADER  
OF: OF_LOG_ERROR: Shader program reports:  
Fragment info  
-------------  
(0) : fatal error C9999: *** exception during compilation ***  
  
OF: OF_VERBOSE: FBO supported  
OF: OF_LOG_NOTICE: ofFbo::checkGLSupport()  
maxColorAttachments: 8  
maxDrawBuffers: 8  
maxSamples: 16  
OF: OF_LOG_NOTICE: FRAMEBUFFER_COMPLETE - OK  
OF: OF_VERBOSE: FBO supported  
OF: OF_LOG_NOTICE: ofFbo::checkGLSupport()  
maxColorAttachments: 8  
maxDrawBuffers: 8  
maxSamples: 16  
OF: OF_LOG_NOTICE: FRAMEBUFFER_COMPLETE - OK  
OF: OF_VERBOSE: FBO supported  
OF: OF_LOG_NOTICE: ofFbo::checkGLSupport()  
maxColorAttachments: 8  
maxDrawBuffers: 8  
maxSamples: 16  
OF: OF_LOG_NOTICE: FRAMEBUFFER_COMPLETE - OK  
  

Thanks a bundle! Very helpful.

This tutorial looks excellent!
But, the shader it uses is no longer available at
http://www.ruudbijnen.nl/blog/2010/09/blending-textures-in-a-shader/-

Can someone share this shader?
It’s a shame to let a good tutorial go to waste…

My mistake: the shader files are included in the project, in /bin/data/shaders.
It doesn’t matter that the original URL is not active.

miguel – thank you for an excellent tutorial !

@miguelvb - Thanks very much for this tutorial :slight_smile: PS: Friendly suggestion; maybe make shorter path/file names next time otherwise issues arise due to naming conventions being too long (my issues).

@irregular - I have the same results as you (winXP, specs in signature). However, I’m receiving these errors:
(fragment info) Error C1067: too little data in type constructor, fatal error C9999: can’t convert to expression @TMP0, @TMP1 (FBO supported). Searching on the web, I found this for my issue: http://www.gamedev.net/topic/402343-strange-glsl-problem/- …thus maybe it’s also related to Nvidia’s GLSL parser (??)

PS: No need to reply to this post, just wanted to share my experience :wink:

i was trying the code in ubuntu 11.10 in terminal i am getting segmentation fault.
my glxinfo is

  
name of display: :0.0  
display: :0  screen: 0  
direct rendering: Yes  
server glx vendor string: SGI  
server glx version string: 1.4  
  

is this the problem