Macbook视网膜显示器上的PyOpenGL [英] PyOpenGL on a Macbook retina display

查看:96
本文介绍了Macbook视网膜显示器上的PyOpenGL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码可以在glut窗口中使用PyOpenGL显示图形.在视网膜Macbook Pro上,此窗口以低分辨率模式显示,其中一个OpenGL像素由四个物理像素表示.如果能以完整的本机分辨率显示,那就更好了.

我的问题
是否有任何方法可以使用glut或其他方式在Retina显示器上的Python中获取本机分辨率OpenGL上下文?

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

这是代码:

从OpenGL.GL导入

  *从OpenGL.GLUT导入*从OpenGL.GLU导入*导入操作系统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()如果__name__ =='__main__':glutInit()glutInitWindowSize(400,400)glutCreateWindow("GL测试")glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)glutDisplayFunc(displayFunc)initFunc()os.system('''/'usr/bin/osascript -e'告诉应用程序"Finder"将进程"Python"的最前面设置为true'''')#防止GL窗口出现在其他应用程序后面glutMainLoop() 

解决方案

要正确地获得所需的分辨率,您将需要使用 NSView ,然后指示视图应使用最佳分辨率.分辨率(这也意味着您不再应该使用GLUT).由于这不在OpenGL的范围之内,并且您想使用Python,因此您将需要使用一些与py2app一起访问此类对象的包(但不需要完整的py2app build )./p>

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

 导入可可从OpenGL.GL导入*从OpenGL.GLU导入*GLView(Cocoa.NSOpenGLView)类:def initWithFrame_(self,frame):格式= Cocoa.NSOpenGLPixelFormat.alloc().initWithAttributes _((0,))view =超级(GLView,self).initWithFrame_pixelFormat_(frame,format)view.setWantsBestResolutionOpenGLSurface_(真)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)返回视图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()AppDelegate(Cocoa.NSObject)类:def windowWillClose_(自己,通知):app.terminate_(个体)应用= Cocoa.NSApplication.sharedApplication()rect =可可.NSMakeRect(0,0,300,300)winflags = Cocoa.NSTitledWindowMask |可可NSClosableWindowMask赢= Cocoa.NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(rect,winflags,Cocoa.NSBackingStoreBuffered,False)委托= AppDelegate.alloc().init()win.setDelegate_(委托)视图= GLView.alloc().initWithFrame_(rect)win.setContentView_(视图)win.makeKeyAndOrderFront_(无)app.run() 

如果您尝试运行此代码,它将可以正常运行,但是您不会注意到有关分辨率问题的任何区别.为了解决这个问题,您需要构造一个简单的 setup.py ,假设上面的代码保存在名为 test1.py 的文件中:

来自distutils.core导入设置的

 导入py2app设置(app = ["test1.py"]) 

然后运行 mypythonexecutable setup.py py2app -A (当然,其中的 mypythonexecutable 会被替换为 python 或例如 python2.7 ).现在,您执行 open dist/test1.app 并解决了问题(在执行较早的命令后将创建 dist/test1.app ).

I have some code that displays graphics using PyOpenGL in a glut window. On a retina Macbook Pro this window appears in a low-resolution mode, with one OpenGL pixel being represented by four physical pixels. It would be much nicer if it would display in the full native resolution.

My Question
Is there any way to obtain a native resolution OpenGL context in Python on Retina displays, using glut or otherwise?

Example of the issue
Below is a minimal working example of a PyOpenGL program. There is nothing special about it - this issue will be exhibited by any working PyOpenGL code. Here is a zoomed-in detail of a screenshot. Notice that the pixels making up the white triangle are four times the size of the pixels of the OS X widgets. This is the default for programs that aren't specifically designed for Retina devices. I want to know how to turn it off for PyOpenGL programs.

Here is the code:

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()

解决方案

To properly achieve the resolution you are after, you will need to use a NSView and then indicate that the view should use the best resolution (this also means you are no longer supposed to use GLUT). Since this is outside of OpenGL's scope, and you want to use Python, you will need to use some package that access these kind of objects together with py2app (but the full py2app build is not required).

In order to access an NSView, or more specifically a NSOpenGLView for your needs, pyobjc is required. The following code imports Cocoa (provided by pyobjc) just for clarity, the same objects can be accessed through AppKit. The code creates a NSWindow, then a view which defines the drawRect to be called whenever required. The single line that solves the resolution issue is: 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()

If you try running this code, it will run just fine but you won't notice any difference regarding the resolution problem. To solve that, you need to construct a simple setup.py assuming the code above was saved in a file called test1.py:

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

Then run mypythonexecutable setup.py py2app -A (where, of course, mypythonexecutable is replaced by something that makes sense like python or python2.7, for example). Now you do open dist/test1.app and the issue is solved (dist/test1.app will be created after the earlier command is executed).

这篇关于Macbook视网膜显示器上的PyOpenGL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆