SteinSOFT.net
  Vertical Syncronisation - VSync

First what is vertical syncronisation? This method is in fact rather old and was already used in old DOS games. When Vsync is turned on, the graphics card waits until the monitor has completely refreshed before it draws the next frame. The advantage of this is that the image doesn't flicker. A sideeffect is that this might cost speed.

With most old (approx. > 1999) and all new OpenGL graphics card you can set whether VSync should be turned on or not. As this functionality is optional you have to check whether the extension WGL_EXT_swap_control is supported. If it is supported you have to get the function address of wglSwapIntervalEXT(int) using wglGetProcAddress(char*). If you want to check whether VSync is on or not, use wglGetSwapIntervalEXT().

Notice that you can specify the interval of VSync'ing. If you set the interval to 1, the monitor is refreshed after one 'completed' frame. When the interval is set to 2 the monitor will be refreshed every two frames. But you will rarely need this 'precision'.

Let the coding begin!

#include <windows.h> //for wglGetProcAddress(..)
#include <GLgl.h> //for glGetString(..)
#include <string.h> //for strstr(..)
  
//function pointer typdefs
typedef void (APIENTRY *PFNWGLEXTSWAPCONTROLPROC) (int);
typedef int (*PFNWGLEXTGETSWAPINTERVALPROC) (void);
 
//declare functions
PFNWGLEXTSWAPCONTROLPROC wglSwapIntervalEXT = NULL;
PFNWGLEXTGETSWAPINTERVALPROC wglGetSwapIntervalEXT = NULL;
 
//init VSync func
void InitVSync()
{
   //get extensions of graphics card
   char* extensions = (char*)glGetString(GL_EXTENSIONS);
  
   //is WGL_EXT_swap_control in the string? VSync switch possible?
   if (strstr(extensions,"WGL_EXT_swap_control"))
   {
      //get address's of both functions and save them
      wglSwapIntervalEXT = (PFNWGLEXTSWAPCONTROLPROC)
          wglGetProcAddress("wglSwapIntervalEXT");
      wglGetSwapIntervalEXT = (PFNWGLEXTGETSWAPINTERVALPROC)
          wglGetProcAddress("wglGetSwapIntervalEXT");
  }
}
 
bool VSyncEnabled()
{
   //if interval is positif, it is not 0 so enabled ;)
   return (wglGetSwapIntervalEXT() > 0);
}
 
void SetVSyncState(bool enable)
{
    if (enable)
       wglSwapIntervalEXT(1); //set interval to 1 -> enable
    else
       wglSwapIntervalEXT(0); //disable
}

The first function is a bit more complicated. Here we check whether switching the state of VSync'ing is supported by the graphics card's driver. If yes, the string WGL_EXT_swap_control is contained in the extensions string. Then we simply save the addresses of the two extensions functions in the approporiate function pointers. The next two functions are very straight-forward. VSyncEnabled() checks whether VSync is turned on and SetVSyncState(..) turns it on or off. Here's a little code snippet how to use it:

//Don't forget to call this first (AND AFTER OPENGL CONTEXT CREATION!!!!!)
InitVSync();
 
//...
if (VSyncEnabled())
  MessageBox(NULL,"VSync is enabled","VSYNC ENABLED",MB_OK);
 
//..
//disable VSync
SetVSyncState(false);

Easy, eh? By the way I have programmed a little helper class that exactly does this, called SGLVsync. Check it out if you don't want to know the details :-). As always: Questions? Comments? Anything Else? Message Board! Happy Coding!

Copyright © by SteinSOFT