[osg-users] How change the vertical sync?

361 views
Skip to first unread message

Julio Jerez

unread,
Oct 15, 2013, 11:08:18 AM10/15/13
to osg-...@lists.openscenegraph.org

In my app I wrote this class function

 

void InitWindowsSystem (osgViewer::Viewer& viewer, const char* const title, int x, int y, int width, int height)

{

      viewer.setUpViewInWindow(x, y, width, height);

 

      //Get the traits of the current window

      osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->getTraits());

 

      //Set the title

      traits->windowName = title;

 

      // disable vertical sync

      traits->vsync = false;

 

      //Create a new graphics context with the modified traits

      osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext( traits.get() );

 

//test to see if vsync has changed, but vsyn is alway true

osg::ref_ptr< osg::GraphicsContext::Traits > traits1 = new osg::GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->getTraits());

 

 

I have searched on forum for a way to do this but no one seem to have a clear way.

can someone tell me how to do this, pleases?

 

Julio

 

 

 

Eric Sokolowsky

unread,
Oct 15, 2013, 8:55:03 PM10/15/13
to OpenSceneGraph Users
If you have an Nvidia card, you can set the environment variable __GL_SYNC_TO_VBLANK=1 or =0 to enable or disable vertical syncing, but this must be done before the graphics context is initialized. I'm not sure how to do it for ATI or Intel chips. A google search turned up this tip for ATI cards: http://www.stolk.org/debian/vblank-fglrx.html (I haven't tried it though).


_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org


PCJohn

unread,
Oct 17, 2013, 4:07:27 AM10/17/13
to OpenSceneGraph Users
Hi Julio,

this is the code I am using (you may need to reformat it, because email splits
many lines into two). Call it once you have active context.
You may still need some includes like
#include <osg/GLExtensions>
#if defined(__WIN32__) || defined(_WIN32)
# [...]
#else
# include <GL/glx.h>
#endif
and so on.
John


//
// vsync could be controlled by following OpenGL extensions:
//
// Swap control approaches:
// GLX_SGI_swap_control (1995) / WGL_EXT_swap_control (1999) /
GLX_EXT_swap_control (2009)
// GLX_EXT_swap_control_tear (2011) / WGL_EXT_swap_control_tear (2011)
//
// Synchronization approaches:
// GLX_SGI_video_sync (1995) / GLX_OML_sync_control (2001) /
WGL_OML_sync_control (2001)
//
// Swapping a group of drawables and windows:
// GLX_SGIX_swap_group (1996) / GLX_SGIX_swap_barrier (1996) /
GLX_NV_swap_group (2003) / WGL_NV_swap_group (2003)
//

const char* extensions = NULL;

#if defined(__WIN32__) || defined(_WIN32)

typedef const char* WINAPI WGLGETEXTENSIONSSTRINGARB( HDC );
WGLGETEXTENSIONSSTRINGARB* wglGetExtensionsStringARB;
osg::setGLExtensionFuncPtr( wglGetExtensionsStringARB,
"wglGetExtensionsStringARB" );

typedef const char* WINAPI WGLGETEXTENSIONSSTRINGEXT();
WGLGETEXTENSIONSSTRINGEXT* wglGetExtensionsStringEXT;
osg::setGLExtensionFuncPtr( wglGetExtensionsStringEXT,
"wglGetExtensionsStringEXT" );

if( wglGetExtensionsStringARB )
{
HDC dc = wglGetCurrentDC();
extensions = wglGetExtensionsStringARB( dc );
}
else if( wglGetExtensionsStringEXT )
{
extensions = wglGetExtensionsStringEXT();
}

#else
// get current display
// (glXGetCurrentDisplay() is supported since GLX 1.2)
Display *d = glXGetCurrentDisplay();

// (glXGetCurrentContext() is supported maybe since beginning? (1.0?),
// at least it is supported in GLX 1.2)
GLXContext c = glXGetCurrentContext();

// get current screen
// (glXQueryContext() is available since GLX 1.3)
int screen;
if( c == NULL || glXQueryContext( d, c, GLX_SCREEN, &screen ) != Success )
{
OSG_WARN << "GLX: failed to get screen number." << endl;
screen = DefaultScreen( d );
}

// get glx extension string
// (glXQueryExtensionsString is available since GLX 1.1)
extensions = glXQueryExtensionsString( d, screen );

#endif

if( extensions )
{
#if defined(__WIN32__) || defined(_WIN32)
if( osg::isExtensionInExtensionString( "WGL_EXT_swap_control",
extensions ) )
{
typedef BOOL WINAPI WGLSWAPINTERVALEXTPROC(int interval);
WGLSWAPINTERVALEXTPROC* wglSwapIntervalEXT =
(WGLSWAPINTERVALEXTPROC*)osg::getGLExtensionFuncPtr( "wglSwapIntervalEXT",
extensions );
bool adaptiveSwapSupported = osg::isExtensionInExtensionString(
"WGL_EXT_swap_control_tear", extensions );
#else
bool sgiSwapControl = osg::isExtensionInExtensionString(
"GLX_SGI_swap_control", extensions );
bool extSwapControl = osg::isExtensionInExtensionString(
"GLX_EXT_swap_control", extensions );
if( sgiSwapControl || extSwapControl )
{
typedef int (*PFNGLXSWAPINTERVALSGIPROC) (int interval);
typedef void (*PFNGLXSWAPINTERVALEXTPROC) (Display *dpy, GLXDrawable
drawable, int interval);
PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = sgiSwapControl ?
(PFNGLXSWAPINTERVALSGIPROC)osg::getGLExtensionFuncPtr(
"glXSwapIntervalSGI", extensions ) : NULL;
PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = extSwapControl ?
(PFNGLXSWAPINTERVALEXTPROC)osg::getGLExtensionFuncPtr(
"glXSwapIntervalEXT", extensions ) : NULL;
bool adaptiveSwapSupported = osg::isExtensionInExtensionString(
"GLX_EXT_swap_control_tear", extensions );
#endif

int value = _vsync ? ( adaptiveSwapSupported ? -1 : 1 ) : 0;
OSG_NOTICE << "OSGWiget: Setting vertical synchronization " << (
value != 0 ? "ON" : "OFF" )
<< " (swap interval set to " << value << ")." << endl;

#if defined(__WIN32__) || defined(_WIN32)
if( wglSwapIntervalEXT )
wglSwapIntervalEXT( value );
#else
// try glXSwapIntervalEXT in the first place as it supports
// adaptive swap ([WGL|GLX]_EXT_swap_control_tear) and zero value for
disabling v-sync
if( glXSwapIntervalEXT )
glXSwapIntervalEXT( d, glXGetCurrentDrawable(), value );
else
if( glXSwapIntervalSGI )
{
// glXSwapIntervalSGI does not support value 0 according to
documentation,
// only values >=1, but it seems to work for disabling v-sync
anyway
if( glXSwapIntervalSGI( value ) )
OSG_WARN << "glXSwapIntervalSGI() failed." << endl;
}
#endif
}
}



On Tuesday 15 of October 2013 20:55:03 Eric Sokolowsky wrote:
> If you have an Nvidia card, you can set the environment variable
> __GL_SYNC_TO_VBLANK=1 or =0 to enable or disable vertical syncing, but this
> must be done before the graphics context is initialized. I'm not sure how
> to do it for ATI or Intel chips. A google search turned up this tip for ATI
> cards: http://www.stolk.org/debian/vblank-fglrx.html (I haven't tried it
> though).
>
> On Tue, Oct 15, 2013 at 11:08 AM, Julio Jerez <jerez...@gmail.com> wrote:
> > In my app I wrote this class function****
> >
> > ** **
> >
> > void InitWindowsSystem (osgViewer::Viewer& viewer, const char* const
> > title,
> > int x, int y, int width, int height)****
> >
> > {****
> >
> > viewer.setUpViewInWindow(x, y, width, height);****
> >
> > ** **
> >
> > //Get the traits of the current window****
> >
> > osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::
> > GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->
> > getTraits());****
> >
> > ** **
> >
> > //Set the title****
> >
> > traits->windowName = title;****
> >
> > ** **
> >
> > // disable vertical sync****
> >
> > traits->vsync = false;****
> >
> > ** **
> >
> > //Create a new graphics context with the modified traits****
> >
> > osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::
> > createGraphicsContext( traits.get() );****
> >
> > ** **
> >
> > //test to see if vsync has changed, but vsyn is alway true****
> >
> > osg::ref_ptr< osg::GraphicsContext::Traits > traits1 = new osg::
> > GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->
> > getTraits());****
> >
> > ** **
> >
> > ** **
> >
> > I have searched on forum for a way to do this but no one seem to have a
> > clear way.****
> >
> > can someone tell me how to do this, pleases?****
> >
> > ** **
> >
> > Julio ****
> >
> > ** **
> >
> > ** **
> >
> > ** **

Julio Jerez

unread,
Oct 17, 2013, 6:35:05 AM10/17/13
to osg-...@lists.openscenegraph.org

No, I do not think that controlling  this at the driver level is the right way to do that.

I digged a litle and I think I found a better way, in case any anyone wants to know, here is how it can be done on initilaization

 

 

      //Get the traits of the current window

      osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->getTraits());

 

      // disable vertical sync

      traits->vsync = false;

 

      //Create a new graphics context with the modified traits

      osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext( traits.get() );

 

      // set vertical blank off by default

      osgViewer::Viewer::Windows windows;

      gc->makeCurrent();

      viewer.getWindows(windows);

      for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); itr != windows.end(); ++itr) {

            //(*itr)->setSyncToVBlank( !(*itr)->getSyncToVBlank() );

            (*itr)->setSyncToVBlank( traits->vsync );

      }

Julio Jerez

unread,
Oct 17, 2013, 8:11:58 AM10/17/13
to osg-...@lists.openscenegraph.org

Oh there is one more thing you need to first, you need create a new context so that you can realize it,  otherwise  the function make current do not take place

here is the final code

 

      viewer.setUpViewInWindow(x, y, width, height);

 

      //Get the traits of the current window

      osg::ref_ptr< osg::GraphicsContext::Traits > traits = new osg::GraphicsContext::Traits( *viewer.getCamera()->getGraphicsContext()->getTraits());

 

      // disable vertical sync

      traits->vsync = false;

 

      //Create a new graphics context with the modified traits

      osg::ref_ptr< osg::GraphicsContext > gc = osg::GraphicsContext::createGraphicsContext( traits.get() );

      gc->realize();

      gc->makeCurrent();

 

      // set the vertical black off by default

      osgViewer::Viewer::Windows windows;

      viewer.getWindows(windows);

      for(osgViewer::Viewer::Windows::iterator itr = windows.begin(); itr != windows.end(); ++itr) {

            //(*itr)->setSyncToVBlank( !(*itr)->getSyncToVBlank() );

            (*itr)->setSyncToVBlank (false);

      }

 

 

you would think that a simple function on the viewer would do that kind of thing without this kind of contorted code.

 

Julio

 

 

Reply all
Reply to author
Forward
0 new messages