[PYTHON] PyOpenGL GUI Auswahl und Trennung von Zeichnung und GUI

Bevor Sie zu Shader oder VBO wechseln, organisieren Sie die Verbindung zwischen GUI und PyOpenGL. PyOpenGL kann mit verschiedenen GUIs ausgeführt werden, aber wenn es sich um ein Beispiel handelt, stoppt es bei Überlastung, sodass ich diesen Bereich organisieren werde. Wenn es sich um eine etwas komplizierte App handelt, möchten Sie eine Liste oder einen Baum daneben anzeigen.

Die Umgebung ist Windows 10 (64 Bit) + Anacondas Python 3.5 (64 Bit)

glut Aus irgendeinem Grund startet OpenGL hier. Da das Thema darin besteht, Zeichnung und GUI zu trennen, lautet der Teil, der nur OpenGL zeichnet, wie folgt.

simple_renderer.py


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

def initialize():
    glClearColor(0.0, 0.0, 0.0, 0.0)
    glClearDepth(1.0)
    glDepthFunc(GL_LESS)
    glEnable(GL_DEPTH_TEST)

def resize(Width, Height):
    # viewport
    if Height == 0:
        Height = 1
    glViewport(0, 0, Width, Height)
    # projection
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(45.0, float(Width)/float(Height), 0.1, 100.0)

def draw():
    # clear
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

    # view
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()

    # model
    glTranslatef(0.0, 0.0, -6.0)
    glBegin(GL_POLYGON)
    glVertex3f(0.0, 1.0, 0.0)
    glVertex3f(1.0, -1.0, 0.0)
    glVertex3f(-1.0, -1.0, 0.0)
    glEnd()

    glFlush()

Code, der simple_renderer von glut aufruft.

simple_glut.py


from OpenGL.GLUT import *
import sys
import simple_renderer


def reshape_func(w, h):
    simple_renderer.resize(w, h == 0 and 1 or h)

def disp_func():
    simple_renderer.draw()
    glutSwapBuffers()

if __name__=="__main__":
    glutInit(sys.argv)
    glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
    glutInitWindowSize(256, 256)
    glutCreateWindow(b"triangle")
    glutDisplayFunc(disp_func)
    glutIdleFunc(disp_func)
    glutReshapeFunc(reshape_func)

    simple_renderer.initialize()

    glutMainLoop()

simple_glut.png

Drawing (simple_renderer.py) kennt sich mit Glut nicht aus, und GUI (simple_gtlut.py) kennt sich mit OpenGL nicht aus. Daher möchte ich den Teil simple_renderer.py mit jeder GUI teilen.

Leim Bibliothek

Ich habe eine Bibliothek erstellt, die simple_renderer.py erweitert und wie folgt beschrieben werden kann.

https://github.com/ousttrue/glglue

controller_sample.py


# coding: utf-8
from OpenGL.GL import *


class Controller(object):
    def __init__(self):
        pass

    def onResize(self, w, h):
        glViewport(0, 0, w, h)

    def onLeftDown(self, x, y):
        print('onLeftDown', x, y)

    def onLeftUp(self, x, y):
        print('onLeftUp', x, y)

    def onMiddleDown(self, x, y):
        print('onMiddleDown', x, y)

    def onMiddleUp(self, x, y):
        print('onMiddleUp', x, y)

    def onRightDown(self, x, y):
        print('onRightDown', x, y)

    def onRightUp(self, x, y):
        print('onRightUp', x, y)

    def onMotion(self, x, y):
        print('onMotion', x, y)

    def onWheel(self, d):
        print('onWheel', d)

    def onKeyDown(self, keycode):
        print('onKeyDown', keycode)

    def onUpdate(self, d):
        print('onUpdate', d)

    def draw(self):
        glClearColor(0.9, 0.5, 0.0, 0.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        glBegin(GL_TRIANGLES)
        glVertex(-1.0,-1.0)
        glVertex( 1.0,-1.0)
        glVertex( 0.0, 1.0)
        glEnd()

        glFlush()


if __name__=="__main__":
    controller=Controller()
    import glglue.glut
    glglue.glut.mainloop(controller, width=640, height=480, title=b"sample")    

Rufen Sie die Win32-API direkt auf

Sie sollten nicht nur ein Fenster mit ctypes erstellen. Python hat die Möglichkeit, DLL mit ctypes aufzurufen. Es war die einzige Methode unter Windows, für die keine zusätzliche Installation erforderlich war. Wenn Sie Anaconda verwenden, ist PyQt4 in Ordnung. Es ist ein Vorteil, dass Sie die Hauptschleife selbst partitionieren können.

wgl_sample.py


import controller_sample
import glglue.wgl

if __name__=="__main__":
    controller=controller_sample.Controller()
    glglue.wgl.mainloop(controller, width=640, height=480, title=b"sample")

tkinter Ein Tcl / TK-Python-Wrapper, der nüchtern mit Python geliefert wird. Leider muss ich eine zusätzliche DLL (TOGL) für das OpenGL-Widget installieren Daher kann es nicht sofort verwendet werden, ohne etwas zu tun. Wenn Sie Anaconda nicht verwenden und Speicherplatz sparen möchten, können Sie es verwenden.

Nachtrag

Ich habe (↓) geändert, um die 3D-Ansicht von PMCA durch TOGL zu ersetzen, aber ich habe festgestellt, dass TOGL nicht mehr als erwartet unterstützt wird.

http://togl.sourceforge.net/

Sie können die 32-Bit-Version von TOGL2.0.dll mit TCL / TK herunterladen, die mit TCL / TK bis 3.3 kompatibel ist. Es funktioniert nicht nach 3.4. Es gibt überhaupt keine 64-Bit-Version der DLL.

Außerdem PyOpenGLs Zuhause Hatte die folgenden Vorsichtsmaßnahmen. TOGL scheint umständlich zu kompilieren.

Note that Togl support is deprecated, it's there for legacy code (once you compile Togl), but you should choose a GUI library that has OpenGL support built-in for any new development. Togl support has been dropped due to the complexity of compilation and the headache of maintenance. There are projects which attempt to provide Togl support, feel free to install those into your Python's Tk installation if you need Togl under Python.

Das rote Symbol ist der Beweis für TOGL.

pmca_ss.png

TOGL war eine mögliche Option angesichts des Installationsaufwands und der plattformübergreifenden Nutzung. Es ist aus Unterstützung.

Wurde der folgende Python3-Inkompatibilitätsfehler unbeaufsichtigt gelassen, um anzuzeigen, dass TOGL nicht unterstützt wird?

glglue> c:\Anaconda3\python.exe tkinter_sample.py
Traceback (most recent call last):
  File "tkinter_sample.py", line 3, in <module>
    import glglue.togl
  File "D:\dev\_python\glglue\glglue\togl.py", line 4, in <module>
    import OpenGL.Tk
  File "c:\Anaconda3\lib\site-packages\OpenGL\Tk\__init__.py", line 102, in <mod
ule>
    if sys.maxint > 2**32:
AttributeError: module 'sys' has no attribute 'maxint'

Ändern Sie sys.maxint in sys.maxsize.

PyQt4 Es war in Anaconda enthalten. PyQt5 ist sowieso gut, Dies ist vorerst mein Favorit.

pyqt4_sample.py


from PyQt4 import Qt
import controller_sample
import glglue.qgl
class Window(Qt.QWidget):
    def __init__(self, parent=None):
        Qt.QWidget.__init__(self, parent)
        # setup opengl widget
        self.controller=controller_sample.Controller()
        self.glwidget=glglue.qgl.Widget(self, self.controller)
        # packing
        mainLayout = Qt.QHBoxLayout()
        mainLayout.addWidget(self.glwidget)
        self.setLayout(mainLayout)

import sys
app = Qt.QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())

Zusammenfassung

Ich mag PyQt4 bei Anaconda.

In Zukunft werden VBO und Shader mit Numpy geplant.

Recommended Posts

PyOpenGL GUI Auswahl und Trennung von Zeichnung und GUI
Trennung von Design und Daten in matplotlib
Trennung von japanischem Nachnamen und Vornamen mit BERT
Auswahl der Messdaten