I'm working on a pyside application that will use OpenGL to display a mesh. I'm
new to OpenGL, but there are a variety of tutorials online to help with that.
However, there's precious little dealing with PySide.
I can make things "work" by putting the mesh information in the paintGL()
function, but that seems very ugly and likely to be slow -- particularly with a
real mesh of several thousand (or many more) polygons.
It looked like glGenLists was the solution to the problem, but using it results
in an error. Specifically, the code between glBegin() and glEnd() that works in
the paintGL() function causes an error* when called elsewhere. If the code is
called in __init__() or initializeGL() (in either case as the final call in the
function) an error occurs at glEnd() and the list is never populated so nothing
is drawn.
I'm missing something, obviously.
The error is as follows and I've attached the (somewhat) minimal file that
demonstrates the problem.
#!/usr/bin/python
# -*- coding: utf-8 -*-
import PySide
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtOpenGL import *
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *
import sys
__haveOpenGL__ = True
class GLWidget(QGLWidget):
xRotationChanged = Signal(int)
yRotationChanged = Signal(int)
zRotationChanged = Signal(int)
def __init__(self, parent=None):
super(GLWidget, self).__init__(parent)
self.mesh = None
self.xRot = 0
self.yRot = 0
self.zRot = 0
self.lastPos = QPoint()
#
self.trolltechGreen = QColor.fromCmykF(0.40, 0.0, 1.0, 0.0)
self.trolltechPurple = QColor.fromCmykF(0.39, 0.39, 0.0, 0.0)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_ALPHA | GLUT_DEPTH)
def xRotation(self):
return self.xRot
def yRotation(self):
return self.yRot
def zRotation(self):
return self.zRot
def minimumSizeHint(self):
return QSize(50, 50)
def sizeHint(self):
return QSize(400, 400)
def setXRotation(self, angle):
angle = self.normalizeAngle(angle)
if angle != self.xRot:
self.xRot = angle
self.xRotationChanged.emit(angle)
self.updateGL()
def setYRotation(self, angle):
angle = self.normalizeAngle(angle)
if angle != self.yRot:
self.yRot = angle
self.yRotationChanged.emit(angle)
self.updateGL()
def setZRotation(self, angle):
angle = self.normalizeAngle(angle)
if angle != self.zRot:
self.zRot = angle
self.zRotationChanged.emit(angle)
self.updateGL()
def initializeGL(self):
glClearColor(0.0, 0.0, 0.0, 0.0)
glClearDepth(1.0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, 1.3333, 0.1, 100.0)
glMatrixMode(GL_MODELVIEW)
self.mesh = self.makeObject()
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
glTranslatef(-1.5, 0.0, -6.0)
if self.mesh:
glCallList(self.mesh)
else:
print "error: self.mesh not found!"
glutSwapBuffers()
def resizeGL(self, width, height):
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluPerspective(45.0, float(width)/float(height), 0.1, 100)
glMatrixMode(GL_MODELVIEW)
def mousePressEvent(self, event):
self.lastPos = QPoint(event.pos())
def mouseMoveEvent(self, event):
dx = event.x() - self.lastPos.x()
dy = event.y() - self.lastPos.y()
if event.buttons() & Qt.LeftButton:
self.setXRotation(self.xRot + 8 * dy)
self.setYRotation(self.yRot + 8 * dx)
elif event.buttons() & Qt.RightButton:
self.setXRotation(self.xRot + 8 * dy)
self.setZRotation(self.zRot + 8 * dx)
self.lastPos = QPoint(event.pos())
def makeObject(self):
genList = glGenLists(1)
glNewList(genList, GL_COMPILE_AND_EXECUTE)
glBegin(GL_TRIANGLES)
glColor3f(1.0, 0.0, 0.0)
glVertex3f(0.0, 1.0, 0.0)
glColor3f(0.0, 1.0, 0.0)
glVertex3f(1.0, -1.0, 0.0)
glColor3f(0.0, 0.0, 1.0)
glVertex3f(-1.0, -1.0, 0.0)
glEnd()
return genList
def normalizeAngle(self, angle):
while angle < 0:
angle += 360 * 16
while angle > 360 * 16:
angle -= 360 * 16
return angle
class MainWindow(QMainWindow):
def __init__(self, args=None, parent=None):
super(MainWindow, self).__init__(parent)
self.setAttribute(Qt.WA_DeleteOnClose)
layout = QVBoxLayout()
if __haveOpenGL__:
self.glWidget = GLWidget(self)
layout.addWidget(self.glWidget)
else:
layout.addWidget(QLabel('PyOpenGL is missing'))
self.setLayout(layout)
def closeApplication(self):
QApplication.closeAllWindows()
def main():
app = QApplication(sys.argv)
form = MainWindow()
form.show()
form.raise_()
app.exec_()
if __name__ == "__main__":
main()
Traceback (most recent call last):
File "./reduced.py", line 68, in initializeGL
self.mesh = self.makeObject()
File "./reduced.py", line 106, in makeObject
glEnd()
File "/Library/Python/2.7/site-packages/OpenGL/latebind.py", line 61, in
__call__
return self.wrapperFunction( self.baseFunction, *args, **named )
File "/Library/Python/2.7/site-packages/OpenGL/GL/exceptional.py", line 57,
in glEnd
return baseFunction( )
File "/Library/Python/2.7/site-packages/OpenGL/error.py", line 208, in
glCheckError
baseOperation = baseOperation,
OpenGL.error.GLError: GLError(
err = 1286,
description = 'invalid framebuffer operation',
baseOperation = glEnd,
cArguments = ()
)
_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside