4
\$\begingroup\$

If I make a call to http://developer.android.com/reference/android/opengl/GLSurfaceView.html#requestRender() from my game loop, how can I tell when OpenGL has finished rendering?

I don't want to make a call to requestRender() again in the next frame until the previous frame has finished rendering.

Sorry for the basic question I'm new to opengl and trying to switch to it from canvas.

Also, is GLSurfaceView.requestRender() a blocking call?

\$\endgroup\$
10
  • 2
    \$\begingroup\$ "I don't want to make a call to requestRender() again in the next frame until the previous frame has finished rendering." Can you explain why? Its probably better to let OpenGL handle the draw queue and frame dropping. \$\endgroup\$
    – Roy T.
    Commented Apr 3, 2013 at 19:46
  • \$\begingroup\$ @RoyT. My (probably naive) thinking was that I want to ensure that the whole frame is drawn in a consistent state. My updateGameState() call is made in the main game loop thread, and I only want OpenGL to draw when all sprites have been updated to the current time. I was planning to store the positions and rotations of sprites before drawing them asynchronously with OpenGL (and then recalling updateGameState() on the CPU while the current frame is being rendered on the GPU). \$\endgroup\$
    – magritte
    Commented Apr 3, 2013 at 20:11
  • 1
    \$\begingroup\$ Sounds like a good way to have choppy frame rates. \$\endgroup\$
    – House
    Commented Apr 3, 2013 at 20:43
  • \$\begingroup\$ @Byte56 Could you please elaborate? \$\endgroup\$
    – magritte
    Commented Apr 3, 2013 at 20:57
  • 5
    \$\begingroup\$ "I only want OpenGL to draw when all sprites have been updated to the current time" - just create a double-buffered context and this will be handled automatically for you. Update all sprites, draw them, swap buffers. GL drivers are asynchronous and pipelined to begin with, so you don't need any software tricks to get this behaviour; it just happens for free (in fact a surefire way to break it is by trying software tricks that go outside of the way it's designed to work). \$\endgroup\$ Commented Apr 3, 2013 at 23:58

1 Answer 1

3
\$\begingroup\$

Jimmy Shelter is right. When you implement a GLSurfaceView.Renderer the onDrawFrame() handles the game loop for you. See this link: http://www.javacodegeeks.com/2011/09/android-game-development-switching-from.html

If you need data on the progression of the loop put a counter within your Renderer class in your onDrawFrame() method:

public class GlRender implements GLSurfaceView.Renderer {

 private int counter = 0;
 @Override
 public void onDrawFrame(GL10 gl)
{
      counter++;
}}

Depending on the amount of calculations you have going on in your loop you may need to slow it down to 60fps otherwise your animations may be occurring too frequently.

public class GlRender implements GLSurfaceView.Renderer {

 private long loopStart =0;
 private long loopEnd = 0;
 private long loopRunTime = 0;
 private final int FPS = (1000/60);

 @Override
 public void onDrawFrame(GL10 gl)
{
      loopStart = System.currentTimeMillis();
  if(loopRunTime < FPS )
 {
 Thread.sleep(FPS - loopRunTime);
  }

 loopEnd = System.currentTimeMillis();
 loopRunTime = ((loopEnd - loopStart));
}
}
\$\endgroup\$
1
  • 2
    \$\begingroup\$ Depending on what platform you're on the timer used by Thread.Sleep may not be accurate enough to get smooth frame rates. I'd go with enabling vsync instead if possible. opengl.org/wiki/Swap_Interval \$\endgroup\$
    – Adam
    Commented Aug 30, 2013 at 8:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .