如何在PyOpengl中启用vsync?

时间:2013-06-13 10:36:09

标签: python macos glut pyglet pyopengl

正如标题所说的那样。我想在PyOpenGL中启用垂直同步,但我该怎么做呢?一个相当详尽的网络搜索没有发现任何东西,但也许有人有一个聪明的解决方案?我在OS X上,我不介意使用哪个包来创建窗口和应用程序循环。但是,我宁愿远离开发一个完整的Cocoa应用程序,原因如下所述。

我研究过使用pyglet而不是PyOpenGL,但在64位操作系统上运行的唯一版本的pyglet是一个差不多一年的alpha版本,所以我不想使用它因为我害怕它可能是放弃软件。这太遗憾了,因为它实际上看起来比PyOpenGL好得多。

this page上,我找到了以下代码。该页面说它是针对pygame的,但看起来它应该也适用于Glut。但是,当我运行它(创建上下文后)时,它只会导致分段错误。如果任何人都可以了解为什么会发生这种情况,那就太棒了,因为这样的事情就是我正在寻找的。

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"

我可以尝试使用pygame,看看这段代码是否适用,但我在网上发现了一些报告,这段代码也与pygame崩溃,所以我猜它是以前的工作,但现在却没有。

最后,我知道一个可行的解决方案是使用PyObjC构建一个Cocoa应用程序。然而,那里有一个非常大的学习曲线,我最终会得到一些甚至不接近跨平台的东西。这段代码仅供我个人使用,但如果我在几年后在另一台机器上重新使用它,我非常关心最大化它再次运行的可能性。出于这些原因,我真的不认为构建Cocoa应用程序是我想要进入的。

4 个答案:

答案 0 :(得分:4)

我设法修复了您的细分错误。以下是在mac上启用vsync的工作代码: -

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"))
        v = ctypes.c_int(1)

        ogl.CGLGetCurrentContext.argtypes = []
        ogl.CGLGetCurrentContext.restype = ctypes.c_void_p

        ogl.CGLSetParameter.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_void_p]
        ogl.CGLSetParameter.restype = ctypes.c_int

        context = ogl.CGLGetCurrentContext()

        ogl.CGLSetParameter(context, 222, ctypes.pointer(v))
    except Exception as e:
        print("Unable to set vsync mode, using driver defaults: {}".format(e))

在创建和设置上下文后,只需调用此enable_vsync()函数。

答案 1 :(得分:2)

在pygame的2.0.0版本中,pygame.display.set_mode(...)中添加了一个名为vsync的新选项

它的用法应该类似于:-

pygame.display.set_mode((screen_size),DOUBLEBUF|OPENGL,vsync=1)

如果您不想要vsync,请写vsync = 0

但是,它对我来说还不起作用,在pygame官方网站上写道,它是实验性的,将来可能会改变。如果对我有用,我将编辑此答案。

如果找不到它,可以从这里查看该网站:-

https://www.pygame.org/docs/ref/display.html#pygame.display.set_mode

答案 2 :(得分:0)

我现在使用pyglet解决了这个问题。虽然很长时间没有签入代码,但似乎仍然存在主要开发人员参与的活动社区。它是跨平台的,很容易上手。我只是使用pyglet来管理窗口,而我正在使用PyOpenGL来处理OpenGL。如果需要的话,我可以使用pyglet更快但更低级别的OpenGL绑定,并且我可以利用pyglet提供的各种额外功能。

然而,情况感觉有点不稳定,因为没有适用于OS X Mountain Lion的正式版本(我从最新源安装),我担心我的代码可能会在一两个之后停止工作主要OS X升级。因此,如果有人有一个不使用pyglet的解决方案,我仍然会非常感激。

答案 3 :(得分:0)

尝试使用WinDLL加载OpenGL DLL并用函数名称中的GL或gl(无论哪个有效)替换CGL。 例如: ogl = ctypes.windll.LoadLibrary(ctypes.util.find_library(“OpenGL”)) 然后你的功能: [GL,GL(推荐)] GetCurrentContext()