How does GLFlush() works?
#2 Members - Reputation: 3831
Posted 17 March 2012 - 01:27 AM
The problem with this is that your drawcalls might not get sent immediatly, Most of the time this is a good thing (Buffering is good) but in some situations you might want the implementation to flush its buffers early.
The main usecase i can think of for this is if you have a render function that looks something like this:
1) bunch of opengl drawcalls
2) do some time consuming calculations or i/o
3) more drawcalls
4) more time consuming cpu stuff
4) swap the buffers
In this case it can be a good idea to flush the buffers before you do the time consuming calculations to get the GPU working on the drawcalls. (if you don't flush then the implementation might keep some or all commands buffered until you try to swap the buffers as it is expecting you to send more data its way).
Its important to note that the buffer swap will not only flush the buffers, it will also stall until all rendering is complete and thus it can be beneficial to have a game loop that does something like:
1) issue render calls
2) flush
3) update gamestate (This can take quite some time in complex games)
4) swap buffers
This way the GPU will process the drawcalls while you update the gamestate. (Some implementations will use triple buffering or pre-rendered frames to get a similar effect with a update->render->swap loop but you can't always count on that)
(With double buffering and no pre-rendering a update->render->swap loop will leave the GPU idle while you update the gamestate and the CPU idle while the GPU finishes rendering and swapping which is fairly inefficient)
The voices in my head may not be real, but they have some good ideas!
#3 Members - Reputation: 108
Posted 17 March 2012 - 06:16 AM
1) Issue render calls
2) Swap buffers
3) Update game state
, which is pretty much what you'd do if you didn't know glFlush existed.
#4 Members - Reputation: 3831
Posted 17 March 2012 - 10:36 PM
I don't think you'll ever need to use glFlush. When you call swap buffers, it automatically does a flush in any case, so if you're double buffering (as almost all use cases do these days), calling glFlush won't gain you anything. So in Simon's example, you can replace 4 steps with 3:
1) Issue render calls
2) Swap buffers
3) Update game state
, which is pretty much what you'd do if you didn't know glFlush existed.
The problem with a render->swap->update or update->render->swap loop (they are identical really) is that the swap waits for the render to finish completely which in turn means that the GPU will be idle during the update (after the swap all drawcalls will be completely processed) glFlush doesn't wait for the render to finish, it returns immediatly allowing you to send off all commands to the GPU without swapping the buffers. (This way you can squeeze in all non-rendering related CPU work while the GPU is working by putting it between a flush and the swap)
Once you start pushing the limits of the hardware a bit it will pay off to have the GPU and CPU work at the same time instead of constantly waiting for eachother. (a multithreaded approach is even better these days but also significantly more complex and thus error prone)
The voices in my head may not be real, but they have some good ideas!
#5 Members - Reputation: 100
Posted 19 March 2012 - 12:34 PM
but still i am unable to understand how GLFlush works,
is it mandatory to write GLFlush after all the drawing functions between glBegin and glEnd?
i've written a sample code please go through it
#include<GL/gl.h>
#include<GL/glu.h>
#include<GL/glut.h>
#include<stdio.h>
#include<stdlib.h>
void display1()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glBegin(GL_POLYGON);
glVertex3f(0.25,0.25,0.0);
glVertex3f(0.75,0.25,0.0);
glVertex3f(0.75,0.75,0.0);
glVertex3f(0.25,0.75,0.0);
glEnd();
glFlush();
}
void display2()
{
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 0.0);
glBegin(GL_LINE);
glVertex3f(0.25,0.25,0.0);
glVertex3f(0.75,0.25,0.0);
glVertex3f(0.75,0.75,0.0);
glVertex3f(0.25,0.75,0.0);
glEnd();
glFlush();
}
void display3()
{
glColor3f(0.0,1.0,1.0);
glBegin(GL_TRIANGLES);
glVertex3f(0.25,0.25,0.0);
glVertex3f(0.75,0.25,0.0);
glVertex3f(0.75,0.75,0.0);
glEnd();
//glClear(GL_COLOR_BUFFER_BIT);
glFlush();
}
void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0);
}
int main(int argc,char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
glutInitWindowSize(500 , 500);
glutCreateWindow("My First OpenGL program");
init();
glutDisplayFunc(display1);
glutDisplayFunc(display2);
glutDisplayFunc(display3);
glutMainLoop();
return 0;
}
In the above code in 3 functions display1,2 and 3,
when i specify GLFlush then only i am able to see the object
or else i am unable to see anything why is it like that?
can you explain me in detail why GLFLUSH is being used here
with a small lucid example?
thanks in advance
#6 Moderators - Reputation: 4933
Posted 19 March 2012 - 12:54 PM
Unless you're using single buffering, you should never have to use glFlush or glFinish.
#8 Members - Reputation: 108
Posted 19 March 2012 - 01:08 PM
And no, I have no idea why flush is being used in that example, unless it isn't double buffering and needs to draw something directly to a front buffer, i.e. no swap buffers.
#9 Members - Reputation: 3831
Posted 19 March 2012 - 01:11 PM
Unless you're using single buffering, you should never have to use glFlush or glFinish.
Thankyou all for replying,
but still i am unable to understand how GLFlush works,
is it mandatory to write GLFlush after all the drawing functions between glBegin and glEnd?
i've written a sample code please go through it#include<GL/gl.h> #include<GL/glu.h> #include<GL/glut.h> #include<stdio.h> #include<stdlib.h> void display1() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex3f(0.25,0.25,0.0); glVertex3f(0.75,0.25,0.0); glVertex3f(0.75,0.75,0.0); glVertex3f(0.25,0.75,0.0); glEnd(); glFlush(); } void display2() { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 1.0, 0.0); glBegin(GL_LINE); glVertex3f(0.25,0.25,0.0); glVertex3f(0.75,0.25,0.0); glVertex3f(0.75,0.75,0.0); glVertex3f(0.25,0.75,0.0); glEnd(); glFlush(); } void display3() { glColor3f(0.0,1.0,1.0); glBegin(GL_TRIANGLES); glVertex3f(0.25,0.25,0.0); glVertex3f(0.75,0.25,0.0); glVertex3f(0.75,0.75,0.0); glEnd(); //glClear(GL_COLOR_BUFFER_BIT); glFlush(); } void init() { glClearColor(0.0,0.0,0.0,0.0); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0,1.0,0.0,1.0,-1.0,1.0); } int main(int argc,char *argv[]) { glutInit(&argc,argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(500 , 500); glutCreateWindow("My First OpenGL program"); init(); glutDisplayFunc(display1); glutDisplayFunc(display2); glutDisplayFunc(display3); glutMainLoop(); return 0; }
In the above code in 3 functions display1,2 and 3,
when i specify GLFlush then only i am able to see the object
or else i am unable to see anything why is it like that?
can you explain me in detail why GLFLUSH is being used here
with a small lucid example?
thanks in advance
In this case its used because you are using a single buffer (and thus no buffer swap that forces a flush), if you switch
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
to
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
you no longer have to flush to get things on screen (as a glFinish is implied on the swap). (As i said above though, flushing can still be useful for performance reasons if you run a single threaded application)
The voices in my head may not be real, but they have some good ideas!






