5

過剰なウィンドウで PyOpenGL を使用してグラフィックを表示するコードがいくつかあります。Retina Macbook Pro では、このウィンドウは低解像度モードで表示され、1 つの OpenGL ピクセルが 4 つの物理ピクセルで表されます。完全なネイティブ解像度で表示されると、はるかに優れたものになります。

私の質問
glut などを使用して、Retina ディスプレイ上の Python でネイティブ解像度の OpenGL コンテキストを取得する方法はありますか?

問題の例
以下は、PyOpenGL プログラムの最小限の動作例です。特別なことは何もありません。この問題は、動作中の PyOpenGL コードで発生します。これは、スクリーンショットの拡大された詳細です。白い三角形を構成するピクセルは、OS X ウィジェットのピクセルのサイズの 4 倍であることに注意してください。これは、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

目的の解像度を適切に実現するには、 a を使用してNSViewから、ビューが最適な解像度を使用する必要があることを示す必要があります (これは、GLUT を使用する必要がなくなったことも意味します)。これは OpenGL の範囲外であり、Python を使用したいので、これらの種類のオブジェクトにアクセスするパッケージを py2app と共に使用する必要があります (ただし、完全な py2appbuildは必要ありません)。

にアクセスするにはNSView、またはより具体的NSOpenGLViewには必要に応じてpyobjcが必要です。次のコード インポートCocoa(によって提供されるpyobjc) は、わかりやすくするために、同じオブジェクトに からアクセスできますAppKit。コードは を作成し、必要に応じて呼び出されるNSWindowを定義するビューを作成します。drawRect解決の問題を解決する 1 行は次のとおり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ような意味のあるものに置き換えられます)。これで問題は解決しました(以前のコマンドが実行された後に作成されます)。pythonpython2.7open dist/test1.appdist/test1.app

于 2013-02-15T16:11:35.913 に答える
1

Glut が作成する NSWindow を取得するには、いくつかの PyObjC バインディングを使用してから、スケール ファクターをいじる必要があると思います。Objective C のパーツに関する情報は次のとおりです

于 2013-02-14T12:45:56.180 に答える