How does drawing/buffering work in OF?

I’ve been scouring documentation and forums for a while now, and I feel like I must be missing something. I learned C++ game programming using allegro and SDL, so when I draw, I’m used to drawing my frame to a back buffer, and then swapping the buffer. I can not figure out for the life of me how OF handles this, since everything is just like “draw” and then it draws. Where does it draw to? Directly to the screen? Does it do it right then and there? Do I need to pass anything to other objects if I want them to draw themselves? For example, do I just need to say “mUnit->draw()” in the testApp draw() function, and then in the Unit class’s draw() have it just do something like “mTexture->draw()”?

I’m trying to semi-port my “game engine” that was written using allegro for graphics and then switched over to SDL, but I’m having a tough time rewriting my graphics abstraction for OpenFrameworks, since I’m so confused about the stuff above :S

Any help would be appreciated :slight_smile:

~jak

I think effectively it uses opengl immediate mode under the hood, which imo makes reasonable sense for basic oF shape primitives. If you dig around the gl part of the source you can usually answer any questions, but yes you can just put your drawing code in your class’s draw().

You can use FBO’s which is very easy with ofFbo http://www.openframeworks.cc/documentation/gl/ofFbo.html and also check out ofVbo http://www.openframeworks.cc/documentation/gl/ofVbo.html if you want something away from immediate mode.

Thanks for the reply, it’s making more sense to me now. I was taught that it was bad to draw directly to the screen, but as I work with this more and more, it does just make it easier to code. Just got to be a little careful in places, but I’m getting the hang of it.

Can I ask how you’re supposed to use pixel shaders with OF though, if there isn’t really a backbuffer to pull from? Or does OF just kind of do “magic” and handle that for you if you use an ofShader?

Actually, unless you disable double buffering manually then the drawing is effectively drawn to a back buffer and swapped at the end of the draw loop. Take a look at this excerpt from the display method of ofAppGlutWindow: (the code that runs at the core of any openFrameworks app)

  
  
ofViewport(0, 0, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT));		// used to be glViewport( 0, 0, width, height );  
	float * bgPtr = ofBgColorPtr();  
	bool bClearAuto = ofbClearBg();  
  
    // to do non auto clear on PC for now - we do something like "single" buffering --  
    // it's not that pretty but it work for the most part  
  
    #ifdef TARGET_WIN32  
    if (bClearAuto == false){  
        glDrawBuffer (GL_FRONT);  
    }  
    #endif  
  
	if ( bClearAuto == true || nFrameCount < 3){  
		ofClear(bgPtr[0]*255,bgPtr[1]*255,bgPtr[2]*255, bgPtr[3]*255);  
	}  
  
	if( bEnableSetupScreen )ofSetupScreen();  
  
	ofNotifyDraw();  
  
    #ifdef TARGET_WIN32  
    if (bClearAuto == false){  
        // on a PC resizing a window with this method of accumulation (essentially single buffering)  
        // is BAD, so we clear on resize events.  
        if (nFramesSinceWindowResized < 3){  
        	ofClear(bgPtr[0]*255,bgPtr[1]*255,bgPtr[2]*255, bgPtr[3]*255);  
        } else {  
            if ( (nFrameCount < 3 || nFramesSinceWindowResized < 3) && bDoubleBuffered)    glutSwapBuffers();  
            else                                                     glFlush();  
        }  
    } else {  
        if(bDoubleBuffered){  
			glutSwapBuffers();  
		} else{  
			glFlush();  
		}  
    }  
    #else  
		if (bClearAuto == false){  
			// in accum mode resizing a window is BAD, so we clear on resize events.  
			if (nFramesSinceWindowResized < 3){  
				ofClear(bgPtr[0]*255,bgPtr[1]*255,bgPtr[2]*255, bgPtr[3]*255);  
			}  
		}  
		if(bDoubleBuffered){  
			glutSwapBuffers();  
		} else{  
			glFlush();  
		}  
    #endif  
  
    nFramesSinceWindowResized++;  
  
	//fps calculation moved to idle_cb as we were having fps speedups when heavy drawing was occuring  
	//wasn't reflecting on the actual app fps which was in reality slower.  
	//could be caused by some sort of deferred drawing?  
  
	nFrameCount++;		// increase the overall frame count  
  

Here you can see that if bDoubleBuffered is true then it swaps buffers. (This is after ofNotifyDraw() is called. That is when your draw() function is called) If you look further up in the same class you notice that bDoubleBuffered is set to true by default. So unless you call window.setDoubleBuffering(false); in your main method then in fact your window will be double buffered,

1 Like

Hmm, so it IS double buffered, but it just abstracts that all away from you. So every time you call a draw() it technically draws to the back buffer, and when the application’s draw() is complete, OF handles the buffer swap? That makes a bit more sense. Either way it looks like it’s not something I have to worry about now, but it’s good to know how this is actually functioning. Thanks for the reply bgstaal.

yeah thanks for clearing it up man