vertical sync under linux

I’ve found a function that implements vertical sync under linux with only one call, it have dependencies on two gdk functions, it’s implemented in the gtk port i’ve posted in the extend section in the file ofAppRunner.cpp from line 428 plus two typedefs at the begining of the file: http://forum.openframeworks.cc/t/of-gtk±port/560/0

I don’t understand very much about opengl so I don’t know if it can be used with glut but just in case:

  
  
typedef GLvoid  
(*glXSwapIntervalSGIFunc) (GLint);  
  
typedef GLvoid  
(*glXSwapIntervalMESAFunc) (GLint);  
  
//--------------------------------------  
void ofSetVerticalSync(bool bSync){  
	//----------------------------  
	#ifdef TARGET_WIN32  
	//----------------------------  
		if (bSync) {  
			if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (1);  
		} else {  
			if (GLEE_WGL_EXT_swap_control) wglSwapIntervalEXT (0);  
		}  
	//----------------------------  
	#endif  
	//----------------------------  
  
	//--------------------------------------  
	#ifdef TARGET_OSX  
	//--------------------------------------  
		long sync = bSync == true ? 1 : 0;  
		CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &sync);  
	//--------------------------------------  
	#endif  
	//--------------------------------------  
  
    //--------------------------------------  
    #ifdef TARGET_LINUX  
    //--------------------------------------  
        gint iInterval = bSync == true ? 2 : 0;  
        const gchar* pcDummy = NULL;  
        glXSwapIntervalSGIFunc glXSwapIntervalSGI = 0;  
        glXSwapIntervalMESAFunc glXSwapIntervalMESA = 0;  
  
        pcDummy = glXQueryExtensionsString (GDK_DISPLAY_XDISPLAY  
            (gdk_display_get_default ()), 0);  
  
        if (g_strrstr (pcDummy, "GLX_SGI_swap_control") != NULL)  
        {  
            glXSwapIntervalSGI = (glXSwapIntervalSGIFunc)  
                gdk_gl_get_proc_address ("glXSwapIntervalSGI");  
  
            if (glXSwapIntervalSGI)  
                glXSwapIntervalSGI (iInterval);  
            else  
                g_print ("Could not get glXSwapIntervalSGI()\n");  
        }  
        else if (g_strrstr (pcDummy, "GLX_MESA_swap_control") != NULL)  
        {  
            glXSwapIntervalMESA = (glXSwapIntervalMESAFunc)  
                gdk_gl_get_proc_address ("glXSwapIntervalMESA");  
  
            if (glXSwapIntervalMESA)  
                glXSwapIntervalMESA (iInterval);  
            else  
                g_print ("Could not get glXSwapIntervalMESA()\n");  
        }  
        else  
            g_print ("Unable to switch sync-to-vblank on.\n");  
    //--------------------------------------  
    #endif  
    //--------------------------------------  
}  
  

I’ve just successfully set VSync using GLUT in Linux using a simplified version of the above:

  
  
//--------------------------------------  
void ofSetVerticalSync(bool bSync){  
  
  
    #ifdef TARGET_LINUX  
	//--------------------------------------  
        if (GLEE_GLX_SGI_swap_control) glXSwapIntervalSGI(bSync ? 1 : 0);  
	//--------------------------------------  
    #endif  
}  
  

This works fine, and I think is reasonably well supported. MESA VSync should be included as well I guess, but I’m not sure how much point there is in setting VSync for a non-hardware accelerated openGL…does this happen in OSX/Win32?

It would be great to see this in the next OF release.

For more details on glXSwapIntervalSGI, info in the following posts:
http://www.mail-archive.com/dri-devel@l-…-28251.html

For linux users, you can also do this to get VSync enabled:

  
  
export __GL_SYNC_TO_VBLANK=1  
  

Note that there are problems when using multiple monitors:
(From the NVIDIA Linux driver notes)

Vblank syncing

Setting the environment variable __GL_SYNC_TO_VBLANK to a non-zero value will force glXSwapBuffers to sync to your monitor’s vertical refresh (perform a swap only during the vertical blanking period).

When using __GL_SYNC_TO_VBLANK with TwinView, OpenGL can only sync to one of the display devices; this may cause tearing corruption on the display device to which OpenGL is not syncing. You can use the environment variable __GL_SYNC_DISPLAY_DEVICE to specify to which display device OpenGL should sync. You should set this environment variable to the name of a display device; for example “CRT-1”.

[quote author=“grimus”]I’ve just successfully set VSync using GLUT in Linux using a simplified version of the above:

  
  
//--------------------------------------  
void ofSetVerticalSync(bool bSync){  
  
  
    #ifdef TARGET_LINUX  
	//--------------------------------------  
        if (GLEE_GLX_SGI_swap_control) glXSwapIntervalSGI(bSync ? 1 : 0);  
	//--------------------------------------  
    #endif  
}  
  

Thanks, this works for me too, even switching it on and off per app when I run the app multiple times side by side in separate windows. Using a PC witn Ubuntu 9.04 and an nVidia 6600.

totally missed this, will be in 0061