Thread: [PyOpenGL-Users] Controlling vertical sync on Mac OS X / crashes when trying to access platform-spe
Brought to you by:
mcfletch
From: Nathaniel V. <nat...@gm...> - 2013-06-14 10:19:06
|
Hi all I need to turn on vsync. Does anyone have a way to do this on OS X? I found the following code on the web, but when I run it (after creating a Glut window) it always causes a segmentation fault: import sys def enable_vsync(): if sys.platform != 'darwin': return try: import ctypes import ctypes.util ogl = ctypes.cdll.LoadLibrary(ctypes.util.find_library("OpenGL")) # set v to 1 to enable vsync, 0 to disable vsync v = ctypes.c_int(1) ogl.CGLSetParameter(ogl.CGLGetCurrentContext(), ctypes.c_int(222), ctypes.pointer(v)) except: print "Unable to set vsync mode, using driver defaults" My (very uneducated) guess is that this is because CGLGetCurrentContext returns an int, whereas CGLSetParameter expects a pointer to a struct as its first argument. I have tried many permutations of the above code, but I don't know enough about ctypes to be able to fix it. >From looking at the PyOpenGL source, it looks like there's some stuff in there that's aimed at exposing this kind of platform-specific stuff, but I couldn't find any documentation for it. Is there a "correct" way to call CGLSetParameter and similar functions? By the way, I think it would be really great if a specific platform-independent way to control vsync could be added to PyOpenGL. It's a pretty important thing to be able to control. Best regards, Nathaniel -- Nathaniel Virgo http://nathanielvirgo.com |
From: Ian M. <ia...@ge...> - 2013-06-14 19:57:26
|
On Fri, Jun 14, 2013 at 3:18 AM, Nathaniel Virgo <nat...@gm...>wrote: > Hi all > > I need to turn on vsync. Does anyone have a way to do this on OS X? I > found the following code on the web, but when I run it (after creating a > Glut window) it always causes a segmentation fault: > > import sys > > def enable_vsync(): > if sys.platform != 'darwin': > return > try: > import ctypes > import ctypes.util > ogl = ctypes.cdll.LoadLibrary(ctypes.util.find_library("OpenGL")) > # set v to 1 to enable vsync, 0 to disable vsync > v = ctypes.c_int(1) > ogl.CGLSetParameter(ogl.CGLGetCurrentContext(), ctypes.c_int(222), > ctypes.pointer(v)) > except: > print "Unable to set vsync mode, using driver defaults" > > My (very uneducated) guess is that this is because CGLGetCurrentContext > returns an int, whereas CGLSetParameter expects a pointer to a struct as > its first argument. I have tried many permutations of the above code, but I > don't know enough about ctypes to be able to fix it. > > From looking at the PyOpenGL source, it looks like there's some stuff in > there that's aimed at exposing this kind of platform-specific stuff, but I > couldn't find any documentation for it. Is there a "correct" way to call > CGLSetParameter and similar functions? > This seems relevant to GLUT VSync-ing: www.opengl.org/discussion_boards/showthread.php/173017-Vsync-with-glut Ian |
From: Nathaniel V. <nat...@gm...> - 2013-06-15 03:04:20
|
On 15 June 2013 04:57, Ian Mallett <ia...@ge...> wrote: > > This seems relevant to GLUT VSync-ing: > www.opengl.org/discussion_boards/showthread.php/173017-Vsync-with-glut > > Ian > Hi Ian As far as I can tell, the glX* functions referred to in that link are the platform-specific stuff for X Windows, whereas the CGL* functions used in the code I posted are the equivalent for a Mac. However, the problem is that I can't seem to call any of these platform specific functions from within Python without causing a segmentation fault. Of course, if you or anyone else has any code for calling glX* functions on linux from PyOpenGL it would really help a lot, because maybe I can modify it to use the CGL* functions that I need to use on OS X. Kind regards, Nathaniel -- Nathaniel Virgo http://nathanielvirgo.com |
From: Ian M. <ia...@ge...> - 2013-06-15 07:14:15
|
On Fri, Jun 14, 2013 at 8:03 PM, Nathaniel Virgo <nat...@gm...>wrote: > Hi Ian > > As far as I can tell, the glX* functions referred to in that link are the > platform-specific stuff for X Windows, whereas the CGL* functions used in > the code I posted are the equivalent for a Mac. However, the problem is > that I can't seem to call any of these platform specific functions from > within Python without causing a segmentation fault. > > Of course, if you or anyone else has any code for calling glX* functions > on linux from PyOpenGL it would really help a lot, because maybe I can > modify it to use the CGL* functions that I need to use on OS X. > > Kind regards, > Nathaniel > I meant, that link has some of the information to get you started. Getting started with double-buffering instead of tweaking VSync is probably the solution to most problems. Because of the way displays work, a completely rendered graphics frame is much more important than synchronizing display blit to the actual rendering. Many windowing systems automatically enable VSync initially. SDL (PyGame in Python) is one example. GLUT is not one, as I remember. Ultimately any solution is platform specific--though it may be masked in a platform independent layer. GLUT apparently doesn't provide such a platform independent layer for you, so any solution is going to be platform specific. But that's already been established. GLUT has other problems. Its callback methods are crude and inflexible. Its support for context creation is lacking. It's built on ancient technology and is semi-proprietary. It supports only one window and has a restricted set of controller inputs and, as you see, poor platform abstraction for some tasks. I don't know what's wrong with your ctypes code, but I *can* tell you that there are much better options than GLUT. PyGame, which I mentioned earlier is an excellent choice. It is better than or equal to GLUT in literally every way, including VSync support--which you can toggle when creating a window. I know it's not really what you asked for, but it's my recommendation. Ian |
From: Nathaniel V. <nat...@gm...> - 2013-06-16 06:24:28
|
On 15 June 2013 16:13, Ian Mallett <ia...@ge...> wrote: > >> >> I meant, that link has some of the information to get you started. > Getting started with double-buffering instead of tweaking VSync is probably > the solution to most problems. Because of the way displays work, a > completely rendered graphics frame is much more important than > synchronizing display blit to the actual rendering. > > Many windowing systems automatically enable VSync initially. SDL (PyGame > in Python) is one example. GLUT is not one, as I remember. Ultimately any > solution is platform specific--though it may be masked in a platform > independent layer. GLUT apparently doesn't provide such a platform > independent layer for you, so any solution is going to be platform specific. > > But that's already been established. GLUT has other problems. Its callback > methods are crude and inflexible. Its support for context creation is > lacking. It's built on ancient technology and is semi-proprietary. It > supports only one window and has a restricted set of controller inputs and, > as you see, poor platform abstraction for some tasks. > > I don't know what's wrong with your ctypes code, but I *can* tell you > that there are much better options than GLUT. PyGame, which I mentioned > earlier is an excellent choice. It is better than or equal to GLUT in > literally every way, including VSync support--which you can toggle when > creating a window. I know it's not really what you asked for, but it's my > recommendation. > Thank you for the pygame recommendation. I had looked into it already, but when searching for things like "pygame opengl vsync" all I saw was questions about how to turn vsync on, but no answers besides the code I already posted, which crashes. However, after your mail I played around with some example code, and it seems that vertical sync is enabled in pygame whenever you enable double buffering. I don't know whether this behaviour is cross-platform or not, but I'm only likely to run this code on my Mac in the near future, so I'm only slightly worried by this and will probably use this solution. Note that vertical sync and double buffering are separate issues. I'm using double buffering, of course. However, when using PyOpenGL/GLUT on OS X it doesn't wait for the vertical refresh before swapping the buffers. The result of this is tearing and inconsistent timing, and for what I'm doing these are things I absolutely need to avoid. I think most other people will also need to avoid these things in most other situations as well. IMHO, the only time you wouldn't want to wait for the vertical refresh is when profiling, so that you can accurately measure how many frames per second can be rendered. In just about any kind of production code there's no point in rendering faster than the display can handle, and it's much more important to have consistent timing and to avoid tearing. I had already worked around the issue by using pyglet to manage the windows. However, I don't like this solution because nobody seems to be developing it anymore and there's no official release that works on OS X Mountain Lion. I installed from the latest source, which does work, but I don't hold out much hope that it will continue to work after future OS upgrades - so now I will probably switch to pygame instead. I'm not a huge fan of GLUT either, but if you're going to go to the bother of wrapping it, it seems weird not to also provide a method for toggling VSync. Especially since (as far as I can gather) VSync is enabled on Windows/PyOpenGL/GLUT but disabled on Mac/PyOpenGL/GLUT, which basically guarantees that anyone who does develop using it will have unresolvable differences in behaviour between platforms. All I'm suggesting is that there should be a special OpenGL.platform.enableVerticalSync() function that wraps the platform-specific stuff for this task. Without it, the PyOpenGL wrapping of GLUT is quite limited in its usefulness in my opinion. Best regards, Nathaniel -- Nathaniel Virgo http://nathanielvirgo.com |
From: Ian M. <ia...@ge...> - 2013-06-16 19:11:43
|
On Sat, Jun 15, 2013 at 11:23 PM, Nathaniel Virgo <nat...@gm...>wrote: > Thank you for the pygame recommendation. I had looked into it already, but > when searching for things like "pygame opengl vsync" all I saw was > questions about how to turn vsync on, but no answers besides the code I > already posted, which crashes. However, after your mail I played around > with some example code, and it seems that vertical sync is enabled in > pygame whenever you enable double buffering. I don't know whether this > behaviour is cross-platform or not, but I'm only likely to run this code on > my Mac in the near future, so I'm only slightly worried by this and will > probably use this solution. > VSync is enabled by default in Windows as well in PyGame. When writing a windowing backend, it's something that the OpenGL context must disable. > Note that vertical sync and double buffering are separate issues. I'm > using double buffering, of course. However, when using PyOpenGL/GLUT on OS > X it doesn't wait for the vertical refresh before swapping the buffers. The > result of this is tearing and inconsistent timing, and for what I'm doing > these are things I absolutely need to avoid. I think most other people will > also need to avoid these things in most other situations as well. IMHO, the > only time you wouldn't want to wait for the vertical refresh is when > profiling, so that you can accurately measure how many frames per second > can be rendered. In just about any kind of production code there's no point > in rendering faster than the display can handle, and it's much more > important to have consistent timing and to avoid tearing. > In my limited experience with GLUT, VSync is always disabled on any platform. The situation is more complicated than you describe. In particular, disabling VSync can lead to much higher framerates if you're limited below the screen's refresh rate, and framerates higher than 60Hz *do* lead to better quality if triple buffering is available. VSync is enabled for applications that demand no tearing and disabled everywhere else for maximum performance. It does complicate timing, so I typically clamp to 60Hz and enable VSync. > I had already worked around the issue by using pyglet to manage the > windows. However, I don't like this solution because nobody seems to be > developing it anymore and there's no official release that works on OS X > Mountain Lion. I installed from the latest source, which does work, but I > don't hold out much hope that it will continue to work after future OS > upgrades - so now I will probably switch to pygame instead. > > I'm not a huge fan of GLUT either, but if you're going to go to the bother > of wrapping it, it seems weird not to also provide a method for toggling > VSync. Especially since (as far as I can gather) VSync is enabled on > Windows/PyOpenGL/GLUT but disabled on Mac/PyOpenGL/GLUT, which basically > guarantees that anyone who does develop using it will have unresolvable > differences in behaviour between platforms. All I'm suggesting is that > there should be a special OpenGL.platform.enableVerticalSync() function > that wraps the platform-specific stuff for this task. Without it, the > PyOpenGL wrapping of GLUT is quite limited in its usefulness in my opinion. > I agree. GLUT is useless. That's not PyOpenGL's fault, though--the C version of GLUT that PyOpenGL wraps is useless. Since GLUT does not provide a portable way to toggle VSync, neither does PyOpenGL's wrapper. Perhaps something could be added to help. Really though, the best solution is to just leave GLUT. The only place I ever see it used is in toy examples. > Best regards, > Nathaniel > Ian |