4

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

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

此页面上,我找到了以下代码。该页面说它适用于 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

4 回答 4

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() 函数。

于 2016-01-13T14:15:14.213 回答
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

于 2020-11-27T08:41:23.390 回答
0

我现在已经通过使用 pyglet 解决了这个问题。尽管很长一段时间都没有签入代码,但似乎仍然有一个活跃的社区,主要开发人员参与其中。它是跨平台的,而且很容易上手。我只是使用 pyglet 来管理窗口,而我使用 PyOpenGL 来管理 OpenGL 的东西。稍后,如果需要,我可以使用 pyglet 更快但级别更低的 OpenGL 绑定,并且可以利用 pyglet 提供的各种额外功能。

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

于 2013-06-15T02:32:35.040 回答
0

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

于 2013-07-03T08:00:27.213 回答