The Render Loop

At its simplest, the algorithm for rendering objects on the screen requires the creation of a rendering loop, such as the following:

while(doRender) {  clear the screen  update object (sprite) positions  draw all objects }

Fundamentally, this code is sound, but a few problems exist with this algorithm. Because image updates are happening directly, the updates will be visible and will result in a strobe effect, sometimes called flashing. Flashing occurs because of direct updates and because the entire screen image is being cleared before the sprites are redrawn. The diagram depicted in Figure 3.4 shows the sequence of draw events. The flashing occurs each time the screen is cleared.

image from book
Figure 3.4: The drawing process.

The second problem with this rendering method is called image tearing. Tearing occurs when an object is moving on the screen and the direct updating of the screen image allows the user to see part of the new frame and part of the old frame. This situation is illustrated in Figure 3.5.

image from book
Figure 3.5: Image tearing.

The main technique to correct image tearing is using a buffering algorithm. The most common buffering technique is called double buffering.

Double Buffering

Double buffering helps to remove the flashing problem and, with some slight adjustments, can fix the tearing issue as well. When you use double buffering, the direct updates of the video RAM that the monitor is currently displaying are avoided. To enable this technique the application must first render to a chunk of memory called a buffer, and then display that buffer on screen after the entire image has been rendered. This buffer is called the back buffer, or secondary buffer. The buffer that contains the image currently displayed on the screen is called the front buffer, or primary buffer. An updated version of the rendering algorithm that includes changes to accommodate the double-buffering technique follows:

while(doRender) { clear back buffer update object (sprite) positions draw all objects to the back buffer copy the back buffer to the front buffer display the front buffer }

When this algorithm is implemented, the flashing will be gone. When the back buffer is moved onto the screen, however, the tearing effect may still be present because a direct update to the video RAM being displayed by the monitor is still being performed. To remove the tearing effect, the back buffer must be moved onto the screen only when the monitor is not actually drawing a frame and only after a frame has been completely displayed. This means that the back buffer must be moved onto the screen during the monitor’s vertical retrace. Another update to the existing rendering illustrates this concept as follows:

while(doRender) { clear back buffer update object (sprite) positions draw all objects to the back buffer wait for the vertical retrace copy the back buffer to the front buffer display the front buffer } 

After doing all the work to remove the flashing and the tearing problem, there is still one last concern. During each vertical retrace, the entire back buffer image is being copied to the front buffer. This wholesale copy is very slow and to be avoided if possible.

The current version of the rendering loop is set up to wait for the vertical retrace of each frame before continuing with the loop. With this structure, all of the game logic and rendering is being attempted in the time it takes the monitor to draw a single frame to the screen. The faster the refresh rate of the video mode, the shorter this period will be and the less time left to perform the game logic.

If the video mode’s refresh rate is 60Hz, the monitor is redrawing the screen 60 times every second. Given that there are 1,000 milliseconds in a second, the amount of time to process everything can be surmised by dividing 1,000 by 60. This evaluates to around 16.7 milliseconds to do everything between frames. A large amount of time is being used to copy the back buffer to the front buffer, leaving less time to run the game logic and rendering. If this slow copying of the buffers were removed, more time would be available for game logic.

Page Flipping

The solution to the slow copying of the back buffer to the front buffer is to use a method called page flipping. With page flipping the pointer to the video RAM that is to be displayed by the monitor is changed to a new location in the video RAM (Figure 3.6). This solution is far faster than copying an entire screen image. For example:

image from book
Figure 3.6: Page flipping.

while(doRender) { clear back buffer update object (sprite) positions draw all objects to the back buffer wait for the vertical retrace move the video pointer to the back buffer to make it the front buffer display the front buffer }

Page flipping is not always available on all systems. If page flipping is not available, the game code must be structured so as to respond accordingly in this event. Page flipping is also not a choice when the program is running in windowed mode.

An interesting side effect of page flipping is that the frame rate of the game is capped, meaning that the game can’t display more frames per second than the refresh rate of the video mode you are using, in a similar fashion to the blocking loop referenced in Chapter 2. Because windowed mode isn’t using page flipping, frame rates are generally extremely high because the game doesn’t have to wait for the vertical refresh to display a new frame each time through the loop. In windowed mode, the tearing effects seen earlier will likely return. The amount of time the render method sleeps in each loop should be adjusted up, using the setRenderLoopSpeed method, to slow the frame rate and prevent tearing. You may wonder how the game can know when to use page flipping and when not to. This information comes from the BufferStrategy class, which handles all of the details.



Practical Java Game Programming
Practical Java Game Programming (Charles River Media Game Development)
ISBN: 1584503262
EAN: 2147483647
Year: 2003
Pages: 171

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net