Trying to time something in your OpenGL application? I know I was! My goal was to time my glDrawArrays function call to see how long it would take to post n point sprites to the screen. How did I accomplish this in a cross-platform way (without using the C time library?) I did this by constructing a GL_TIME_ELAPSED query, and I was able to receive the time required for my function calls with precision to the nanosecond!
You’ll need to make sure that you’ve loaded the EXT_timer_query extension. I’d recommend just using the GLEW library as I did. You’ll also want to make sure you’ve included glext.h, and that your glext.h supports GLuint64EXT.
First of all, we want to declare a GLuint to hold the ID of our query. That’s simple enough!
GLuint timeQuery;
Next on our agenda is to have OpenGL reserve memory to store our query. In my code, I’m requesting that OpenGL allocate space for one query and am passing the memory address of my timeQuery GLuint.
glGenQueries(1,&timeQuery);
We now have the set up we need to use our timer. Let’s put that to good use, shall we? Let’s begin by declaring a GLuint64EXT variable to store the time.
GLuint64EXT timeElapsed;
Next, we can begin the timing using the glBeginQuery function.
//Begin the timing.
glBeginQuery(GL_TIME_ELAPSED_EXT,timeQuery);
We’ll now do whatever it is we would like to time. That can be an iteration of your program or the draw time of something specific. I wanted to time how long it took to render my point sprite particle system from a Vertex Buffer Object, so I’m only timing my glDrawArrays function and calling glFinish to make sure that all of the drawing is finished before I stop the timer.
// Draw the point sprites and ensure that there is no more drawing to be done.
glDrawArrays(GL_POINTS,0,alive);
glFinish();
We now want to stop the timer by ending the query. We do this by calling the glEndQuery function.
// Stop the timing.
glEndQuery(GL_TIME_ELAPSED_EXT);
If the query is not complete, then the results will not be available (obvious statement much?) We’ll add some code to cause the program to wait until the query is complete. Note that you can simply continue with other processing or whatever you like if the query is not ready. My example just waits. We’ll use glGetQueryObjectiv to ask if the query is ready and report our answer back to our integer available.
//Find out the results of the timing as soon as they are made available by the graphics card.
int available = 0;
while (!available) {
glGetQueryObjectiv(timeQuery, GL_QUERY_RESULT_AVAILABLE, &available);
}
Once our result is available, we’ll grab the result and store it into our timeElapsed GLuint64EXT variable!
glGetQueryObjectui64vEXT(timeQuery, GL_QUERY_RESULT,&timeElapsed);
After you’re finished with your query object, make sure to free your query space!
glDeleteQueries(1, &timeQuery);
Printing the time is as simple as a printf statement! Recall that a GL_TIME_ELAPSED query returns the time in nanoseconds, so the code below actually converts this to seconds.
printf("Time for Render: %.9f seconds\n", timeElapsed*(1e-9));
So, here’s a GL_TIME_ELAPSED query in a nutshell. I hope this you in some way dear reader!
0 Responses
Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.