5

我有一些代码在 glut 窗口中使用 PyOpenGL 显示图形。在视网膜 Macbook Pro 上,此窗口以低分辨率模式显示,一个 OpenGL 像素由四个物理像素表示。如果它以完整的原始分辨率显示会更好。

我的问题
有什么方法可以在 Retina 显示器上使用 glut 或其他方式在 Python 中获得原生分辨率的 OpenGL 上下文?

问题示例
下面是 PyOpenGL 程序的最小工作示例。它没有什么特别之处——任何工作的 PyOpenGL 代码都会出现这个问题。这是屏幕截图的放大细节。请注意,构成白色三角形的像素是 OS X 小部件像素大小的四倍。这是不是专门为 Retina 设备设计的程序的默认设置。我想知道如何为 PyOpenGL 程序关闭它。

在此处输入图像描述

这是代码:

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

import os

def initFunc():
    glDisable(GL_DEPTH_TEST)
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluOrtho2D(0.0, 400.0, 0.0, 400.0)

def displayFunc():
    glClear(GL_COLOR_BUFFER_BIT)
    glColor3f(1.0, 1.0, 1.0)
    glBegin(GL_TRIANGLES)
    glVertex2f(10.0, 10.0)
    glVertex2f(10.0, 100.0)
    glVertex2f(100.0, 100.0)
    glEnd()
    glFlush()

if __name__ == '__main__':
    glutInit()
    glutInitWindowSize(400,400)
    glutCreateWindow("GL test")
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
    glutDisplayFunc(displayFunc)
    initFunc()
    os.system('''/usr/bin/osascript -e 'tell app "Finder" to set frontmost of process "Python" to true' ''')
        # prevent GL window from appearing behind other applications
    glutMainLoop()
4

3 回答 3

5

要正确实现您所追求的分辨率,您需要使用 aNSView然后指示视图应该使用最佳分辨率(这也意味着您不再应该使用 GLUT)。由于这超出了 OpenGL 的范围,并且您想使用 Python,您将需要使用一些包来访问这些类型的对象以及 py2app(但build不需要完整的 py2app)。

为了访问一个NSView,或者更具体地说是NSOpenGLView满足您的需要,pyobjc是必需的。以下代码导入Cocoa(由 提供pyobjc)只是为了清楚起见,可以通过 访问相同的对象AppKit。代码创建一个NSWindow,然后是一个定义在drawRect需要时调用的视图。解决分辨率问题的单行是:view.setWantsBestResolutionOpenGLSurface_(True).

import Cocoa
from OpenGL.GL import *
from OpenGL.GLU import *

class GLView(Cocoa.NSOpenGLView):
    def initWithFrame_(self, frame):
        format = Cocoa.NSOpenGLPixelFormat.alloc().initWithAttributes_((0, ))
        view = super(GLView, self).initWithFrame_pixelFormat_(frame, format)
        view.setWantsBestResolutionOpenGLSurface_(True)

        view.openGLContext().makeCurrentContext()
        glDisable(GL_DEPTH_TEST)
        glClearColor(0.0, 0.0, 0.0, 0.0)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        gluOrtho2D(0.0, 1.0, 0.0, 1.0)
        return view

    def drawRect_(self, bounds):
        glClear(GL_COLOR_BUFFER_BIT)
        glColor3f(1.0, 1.0, 1.0)
        glBegin(GL_TRIANGLES)
        glVertex2f(0.1, 0.1)
        glVertex2f(0.1, 0.9)
        glVertex2f(0.9, 0.9)
        glEnd()
        glFlush()


class AppDelegate(Cocoa.NSObject):
    def windowWillClose_(self, notification):
        app.terminate_(self)

app = Cocoa.NSApplication.sharedApplication()

rect = Cocoa.NSMakeRect(0, 0, 300, 300)
winflags = Cocoa.NSTitledWindowMask | Cocoa.NSClosableWindowMask
win = Cocoa.NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
        rect, winflags, Cocoa.NSBackingStoreBuffered, False)
delegate = AppDelegate.alloc().init()
win.setDelegate_(delegate)
view = GLView.alloc().initWithFrame_(rect)
win.setContentView_(view)
win.makeKeyAndOrderFront_(None)

app.run()

如果您尝试运行此代码,它会运行得很好,但您不会注意到有关分辨率问题的任何差异。为了解决这个问题,您需要构建一个简单setup.py的假设,假设上面的代码保存在一个名为的文件中test1.py

from distutils.core import setup
import py2app
setup(app=["test1.py"])

然后运行mypythonexecutable setup.py py2app -A(当然,mypythonexecutable这里被一些有意义的东西代替,例如pythonor python2.7)。现在你这样做open dist/test1.app了,问题就解决了(dist/test1.app将在前面的命令执行后创建)。

于 2013-02-15T16:11:35.913 回答
3

您可以从此处获取可选支持 HiDPI 的 GLUT 修补版本:http: //iihm.imag.fr/blanch/software/glut-macosx/

如果您使用此 GLUT 框架,您的应用程序可能会选择以实际屏幕像素分辨率获取 OpenGL 上下文。您只需要更改代码(无论是 C、Python/PyOpenGL 还是任何与 GLUT 框架链接的东西)中的显示初始化:

glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE)

至:

glutInitDisplayString("rgba double hidpi")

修补后的版本优雅地处理具有不同后备存储比例因子的多个屏幕,并为期望以像素指定大小或尺寸(即,glutInitWindowSize, glutReshapeWindow, glutGet(GLUT_WINDOW_WIDTH), glutGet(GLUT_WINDOW_HEIGHT)传递给事件回调的光标位置)的各种函数提供一致的行为。

此版本的 GLUT 还完全向后兼容其他决定不选择加入 HiDPI 支持的应用程序。如果您更喜欢构建自己的版本,还提供了补丁和自行构建框架的说明。

如果您需要,补丁版本还增加了鼠标滚轮支持。

于 2013-07-05T13:26:01.683 回答
1

我想你必须使用一些 PyObjC 绑定来获取 Glut 创建的 NSWindow ,然后摆弄比例因子。以下是有关 Objective C 部分的一些信息:http: //supermegaultragroovy.com/2012/10/24/coding-for-high-resolution-on-os-x-read-this/

于 2013-02-14T12:45:56.180 回答