Avant de passer à Shader ou VBO, organisez la connexion entre GUI et PyOpenGL. PyOpenGL peut être exécuté avec diverses interfaces graphiques, mais s'il s'agit d'un échantillon, il ne fera que surpasser, alors je vais organiser cette zone. S'il s'agit d'une application légèrement compliquée, vous souhaitez afficher une liste ou une arborescence à côté.
L'environnement est Windows 10 (64 bits) + python3.5 d'Anaconda (64 bits)
glut Pour une raison quelconque, OpenGL commence ici. Étant donné que le thème consiste à séparer le dessin et l'interface graphique, la partie qui dessine uniquement OpenGL est la suivante.
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 qui appelle simple_renderer depuis glut.
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()
Drawing (simple_renderer.py) ne connaît pas la surabondance, et GUI (simple_gtlut.py) ne connaît pas OpenGL. Donc, je veux partager la partie simple_renderer.py avec chaque interface graphique.
J'ai créé une bibliothèque qui étend simple_renderer.py et peut être décrite comme suit.
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")
Vous ne devriez pas simplement créer une fenêtre avec des ctypes. python a la capacité d'appeler dll avec ctypes, alors faites-le. C'était la seule méthode sous Windows qui ne nécessitait pas d'installation supplémentaire, Si vous utilisez Anaconda, PyQt4 convient. C'est un mérite que vous puissiez partitionner vous-même la boucle principale.
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 Un wrapper python Tcl / TK fourni avec Python sobrement. Malheureusement, j'ai besoin d'installer une DLL supplémentaire (TOGL) pour le widget OpenGL Par conséquent, il ne peut pas être utilisé immédiatement sans rien faire. Si vous n'utilisez pas Anaconda et que vous souhaitez économiser du stockage, vous pouvez l'utiliser.
J'étais en train de modifier (↓) pour remplacer la vue 3D de PMCA par TOGL, mais j'ai découvert que TOGL n'est pas supporté plus que prévu.
http://togl.sourceforge.net/
Vous pouvez télécharger la version 32 bits de TOGL2.0.dll avec TCL / TK, qui est compatible avec TCL / TK jusqu'à 3.3. Cela ne fonctionne pas après 3.4. Il n'y a pas de version 64 bits de dll en premier lieu.
De plus, Accueil de PyOpenGL Eu les mises en garde suivantes. TOGL semble difficile à compiler.
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.
L'icône rouge est la preuve de TOGL.
TOGL était une option possible compte tenu de l'effort d'installation et de la multiplateforme. C'est hors de support.
L'erreur d'incompatibilité Python3 suivante a-t-elle été laissée sans surveillance indique également que TOGL n'est pas pris en charge?
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'
Modifiez sys.maxint en sys.maxsize.
PyQt4 Il a été inclus dans Anaconda. PyQt5 est bon de toute façon, Pour le moment, c'est mon préféré.
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_())
J'aime PyQt4 chez Anaconda.
À l'avenir, VBO et Shader seront planifiés avec numpy.