Home c++ Why do you need double buffering

Why do you need double buffering

Author

Date

Category

First. I want to see the easiest example of double buffering in OpenGL Freeglut, on C++. With comments, please.

Second. What is the purpose of using double buffering? From Wikipedia, I realized that double buffering provides a smooth image and removes flicker, because Buffers change. One draws an image – another buffer watches the user. Do you recommend to constantly use double buffering in OpenGL? If not, why?


Answer 1, Authority 100%

Double buffering – one of the realizations vertical synchronization – method of combating the so-called Screen Tearing . This phenomenon is as follows: if the video card draws more frames per second, which can draw the monitor (for example, the frequency of the monitor is 60 hertz, that is, 60 frames per second, and the video card draws 100), the next frame begins to display the monitor until the end Recruitment of the previous one. As a result, with a quick movement of the camera, a picture seems like this:

Double buffering (and other vertical synchronization algorithms) allows you to deal with it. To do this, an image drawn by the video card is not immediately on the screen, but to a special buffer (memory area). As soon as the monitor draws the following frame, the contents of this buffer are transmitted to the monitor, and the next frame is written to the buffer. From a technical point of view, it is implemented as a change of pointer to the primary buffer (one from which the image enters the monitor): two buffers are changed in places, and while the image from the new buffer is displayed on the screen, the next frame is written into the old buffer. Then this operation is repeated.

Thus, the situation is excluded when several frames are displayed at the monitor. However, this approach works well only when the frequency of frames drawn by the video card significantly exceeds the frequency of the monitor expandment. If these frequencies are close or the frequency of drawing frames with a video card below the frequency of the monitor expandment, it will periodically happen situations when the monitor has already drawn the frame, and the video card is not yet. In this case (with the double buffering enabled), the previous frame will be re-displayed, even if the video card did not have time for the millisecond. This causes noticeable image to the image that can irritate the user. Therefore, it is always worth providing a selection: Disabled vertical synchronization and image breakdowns or enabled vertical synchronization and potential frame rate.

Simplest way to enable double buffering in GLUT – when initializing instead of

glutinitdisplaymode (glut_single);

Use

glutinitdisplaymode (glut_double);

And when drawing instead of

glflush ();

Use

glutswapbuffers ();

Full Example Code You can see here , documentation can be read on these links: glutinitdisplaymode , glutswapbuffers (I give links to the GLUT documentation, since Freeglut documentation argues that the scum between the implementations of these functions in Glut and Freeglut is not).

p. S. If you are interested in the topic of vertical synchronization technologies, you can watch the video with the presentation of technologies AMD freesync and NVIDIA G-SYNC . In addition to the presentation of a fairly promising technology, they clearly demonstrate the reasons for sending frame frequency when the vertical synchronization is turned on.


Answer 2

Here is an example for GLUT:

# include & lt; stdlib.h & gt;
# INCLUDE & LT; GLUT / GLUT.H & GT;
Static glfloat spin = 0.0;
Void Init (Void)
{
  glclearcolor (0.0, 0.0, 0.0, 0.0);
  GLShademodel (GL_FLAT);
}
// Kolbek for drawing scene
Void Display (Void)
{
  // Draw in the rear buffer
  glclear (GL_COLOR_BUFFER_BIT);
  glpushmatrix ();
  glrotatef (spin, 0.0, 0.0, 1.0);
  glcolor3f (1.0, 1.0, 1.0);
  glrectf (-25.0, -25.0, 25.0, 25.0);
  glpopmatrix ();
  glutswapbuffers (); // Switch buffers
}
Void Spindisplay (Void)
{
  spin = spin + 2.0;
  if (spin & gt; 360.0)
  spin = spin -360.0;
  glutpostredisplay ();
}
// Sollars when changing the size of the window
Void Reshape (int w, int h)
{
  glViewPort (0, 0, (glSizei) W, (glSizei) H);
  GlMatrixMode (GL_Projection);
  glloadidentity ();
  Glortho (-50.0, 50.0, -50.0, 50.0, -1.0, -1.0);
  glmatrixmode (GL_Modelview);
  glloadidentity ();
}
// Squake for Mouse Events
Void Mouse (int button, int state, int x, int y)
{
  Switch (Button)
  {
  Case glut_left_button: // Rotating the scene
    if (state == glut_down) glutidlefunc (spindisplay);
  Break;
  CASE GLUT_RIGHT_BUTTON: // Do not rotate the scene
    if (state == glut_down) glutidlefunc (null);
  Break;
  Default:
  Break;
  }
}
Int Main (int argc, char ** argv)
{
  // Mock Glut.
  glutinit (& amp; argc, argv);
  glutinitdisplaymode (glut_double | glut_rgb); // We want dual buffering
  glutinitwindowsize (250, 250);
  glutinitwindowposition (100, 100);
  glutcreatewindow (argv [0]);
  init (); // Clean the screen
  // Register Colives
  GlutDisplayFunc (display);
  GLUTRESHAPEFUNC (RESHAPE);
  glutmousefunc (mouse);
  glutmainloop (); // Start the main cycle
  Return 0;
}

Programmers, Start Your Engines!

Why spend time searching for the correct question and then entering your answer when you can find it in a second? That's what CompuTicket is all about! Here you'll find thousands of questions and answers from hundreds of computer languages.

Recent questions