【问题标题】:How to enable vsync in PyOpengl?如何在 PyOpengl 中启用 vsync?
【发布时间】:2013-06-09 17:05:41
【问题描述】:

正如标题所说的那样。我想在 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 应用程序是我想要的。

【问题讨论】:

  • 似乎使用除CGLGetCurrentContext 之外的ctypes 的任何CGL 方法都会导致分段错误。

标签: python macos glut pyglet pyopengl


【解决方案1】:

我设法修复了您的分段错误。这是在 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() 函数。

【讨论】:

  • 这太棒了。复制粘贴并像魅力一样工作。
【解决方案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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多