diff options
Diffstat (limited to 'examples/opengl/grabber.py')
-rw-r--r-- | examples/opengl/grabber.py | 435 |
1 files changed, 0 insertions, 435 deletions
diff --git a/examples/opengl/grabber.py b/examples/opengl/grabber.py deleted file mode 100644 index d4b625718..000000000 --- a/examples/opengl/grabber.py +++ /dev/null @@ -1,435 +0,0 @@ - -############################################################################ -## -## Copyright (C) 2013 Riverbank Computing Limited. -## Copyright (C) 2016 The Qt Company Ltd. -## Contact: http://www.qt.io/licensing/ -## -## This file is part of the Qt for Python examples of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:BSD$ -## You may use this file under the terms of the BSD license as follows: -## -## "Redistribution and use in source and binary forms, with or without -## modification, are permitted provided that the following conditions are -## met: -## * Redistributions of source code must retain the above copyright -## notice, this list of conditions and the following disclaimer. -## * Redistributions in binary form must reproduce the above copyright -## notice, this list of conditions and the following disclaimer in -## the documentation and/or other materials provided with the -## distribution. -## * Neither the name of The Qt Company Ltd nor the names of its -## contributors may be used to endorse or promote products derived -## from this software without specific prior written permission. -## -## -## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -## "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -## LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -## A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -## OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -## DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -## THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -## (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -## OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." -## -## $QT_END_LICENSE$ -## -############################################################################ - -"""PySide2 port of the opengl/legacy/grabber example from Qt v5.x""" - -import sys -import math - -from PySide2 import QtCore, QtGui, QtWidgets, QtOpenGL - -try: - from OpenGL.GL import * -except ImportError: - app = QtWidgets.QApplication(sys.argv) - messageBox = QtWidgets.QMessageBox(QtWidgets.QMessageBox.Critical, "OpenGL grabber", - "PyOpenGL must be installed to run this example.", - QtWidgets.QMessageBox.Close) - messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate") - messageBox.exec_() - sys.exit(1) - - -class GLWidget(QtOpenGL.QGLWidget): - xRotationChanged = QtCore.Signal(int) - yRotationChanged = QtCore.Signal(int) - zRotationChanged = QtCore.Signal(int) - - def __init__(self, parent=None): - super(GLWidget, self).__init__(parent) - - self.gear1 = 0 - self.gear2 = 0 - self.gear3 = 0 - self.xRot = 0 - self.yRot = 0 - self.zRot = 0 - self.gear1Rot = 0 - - timer = QtCore.QTimer(self) - timer.timeout.connect(self.advanceGears) - timer.start(20) - - def freeResources(self): - self.makeCurrent() - glDeleteLists(self.gear1, 1) - glDeleteLists(self.gear2, 1) - glDeleteLists(self.gear3, 1) - - def setXRotation(self, angle): - self.normalizeAngle(angle) - - if angle != self.xRot: - self.xRot = angle - self.xRotationChanged.emit(angle) - self.updateGL() - - def setYRotation(self, angle): - self.normalizeAngle(angle) - - if angle != self.yRot: - self.yRot = angle - self.yRotationChanged.emit(angle) - self.updateGL() - - def setZRotation(self, angle): - self.normalizeAngle(angle) - - if angle != self.zRot: - self.zRot = angle - self.zRotationChanged.emit(angle) - self.updateGL() - - def initializeGL(self): - lightPos = (5.0, 5.0, 10.0, 1.0) - reflectance1 = (0.8, 0.1, 0.0, 1.0) - reflectance2 = (0.0, 0.8, 0.2, 1.0) - reflectance3 = (0.2, 0.2, 1.0, 1.0) - - glLightfv(GL_LIGHT0, GL_POSITION, lightPos) - glEnable(GL_LIGHTING) - glEnable(GL_LIGHT0) - glEnable(GL_DEPTH_TEST) - - self.gear1 = self.makeGear(reflectance1, 1.0, 4.0, 1.0, 0.7, 20) - self.gear2 = self.makeGear(reflectance2, 0.5, 2.0, 2.0, 0.7, 10) - self.gear3 = self.makeGear(reflectance3, 1.3, 2.0, 0.5, 0.7, 10) - - glEnable(GL_NORMALIZE) - glClearColor(0.0, 0.0, 0.0, 1.0) - - def paintGL(self): - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) - - glPushMatrix() - glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0) - glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0) - glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0) - - self.drawGear(self.gear1, -3.0, -2.0, 0.0, self.gear1Rot / 16.0) - self.drawGear(self.gear2, +3.1, -2.0, 0.0, - -2.0 * (self.gear1Rot / 16.0) - 9.0) - - glRotated(+90.0, 1.0, 0.0, 0.0) - self.drawGear(self.gear3, -3.1, -1.8, -2.2, - +2.0 * (self.gear1Rot / 16.0) - 2.0) - - glPopMatrix() - - def resizeGL(self, width, height): - side = min(width, height) - if side < 0: - return - - glViewport(int((width - side) / 2), int((height - side) / 2), side, side) - - glMatrixMode(GL_PROJECTION) - glLoadIdentity() - glFrustum(-1.0, +1.0, -1.0, 1.0, 5.0, 60.0) - glMatrixMode(GL_MODELVIEW) - glLoadIdentity() - glTranslated(0.0, 0.0, -40.0) - - def mousePressEvent(self, event): - self.lastPos = event.pos() - - def mouseMoveEvent(self, event): - dx = event.x() - self.lastPos.x() - dy = event.y() - self.lastPos.y() - - if event.buttons() & QtCore.Qt.LeftButton: - self.setXRotation(self.xRot + 8 * dy) - self.setYRotation(self.yRot + 8 * dx) - elif event.buttons() & QtCore.Qt.RightButton: - self.setXRotation(self.xRot + 8 * dy) - self.setZRotation(self.zRot + 8 * dx) - - self.lastPos = event.pos() - - def advanceGears(self): - self.gear1Rot += 2 * 16 - self.updateGL() - - def xRotation(self): - return self.xRot - - def yRotation(self): - return self.yRot - - def zRotation(self): - return self.zRot - - def makeGear(self, reflectance, innerRadius, outerRadius, thickness, toothSize, toothCount): - list = glGenLists(1) - glNewList(list, GL_COMPILE) - glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, reflectance) - - r0 = innerRadius - r1 = outerRadius - toothSize / 2.0 - r2 = outerRadius + toothSize / 2.0 - delta = (2.0 * math.pi / toothCount) / 4.0 - z = thickness / 2.0 - - glShadeModel(GL_FLAT) - - for i in range(2): - if i == 0: - sign = +1.0 - else: - sign = -1.0 - - glNormal3d(0.0, 0.0, sign) - - glBegin(GL_QUAD_STRIP) - - for j in range(toothCount+1): - angle = 2.0 * math.pi * j / toothCount - glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), sign * z) - glVertex3d(r1 * math.cos(angle), r1 * math.sin(angle), sign * z) - glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), sign * z) - glVertex3d(r1 * math.cos(angle + 3 * delta), r1 * math.sin(angle + 3 * delta), sign * z) - - glEnd() - - glBegin(GL_QUADS) - - for j in range(toothCount): - angle = 2.0 * math.pi * j / toothCount - glVertex3d(r1 * math.cos(angle), r1 * math.sin(angle), sign * z) - glVertex3d(r2 * math.cos(angle + delta), r2 * math.sin(angle + delta), sign * z) - glVertex3d(r2 * math.cos(angle + 2 * delta), r2 * math.sin(angle + 2 * delta), sign * z) - glVertex3d(r1 * math.cos(angle + 3 * delta), r1 * math.sin(angle + 3 * delta), sign * z) - - glEnd() - - glBegin(GL_QUAD_STRIP) - - for i in range(toothCount): - for j in range(2): - angle = 2.0 * math.pi * (i + (j / 2.0)) / toothCount - s1 = r1 - s2 = r2 - - if j == 1: - s1, s2 = s2, s1 - - glNormal3d(math.cos(angle), math.sin(angle), 0.0) - glVertex3d(s1 * math.cos(angle), s1 * math.sin(angle), +z) - glVertex3d(s1 * math.cos(angle), s1 * math.sin(angle), -z) - - glNormal3d(s2 * math.sin(angle + delta) - s1 * math.sin(angle), s1 * math.cos(angle) - s2 * math.cos(angle + delta), 0.0) - glVertex3d(s2 * math.cos(angle + delta), s2 * math.sin(angle + delta), +z) - glVertex3d(s2 * math.cos(angle + delta), s2 * math.sin(angle + delta), -z) - - glVertex3d(r1, 0.0, +z) - glVertex3d(r1, 0.0, -z) - glEnd() - - glShadeModel(GL_SMOOTH) - - glBegin(GL_QUAD_STRIP) - - for i in range(toothCount+1): - angle = i * 2.0 * math.pi / toothCount - glNormal3d(-math.cos(angle), -math.sin(angle), 0.0) - glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), +z) - glVertex3d(r0 * math.cos(angle), r0 * math.sin(angle), -z) - - glEnd() - - glEndList() - - return list - - def drawGear(self, gear, dx, dy, dz, angle): - glPushMatrix() - glTranslated(dx, dy, dz) - glRotated(angle, 0.0, 0.0, 1.0) - glCallList(gear) - glPopMatrix() - - def normalizeAngle(self, angle): - while (angle < 0): - angle += 360 * 16 - - while (angle > 360 * 16): - angle -= 360 * 16 - - -class MainWindow(QtWidgets.QMainWindow): - def __init__(self): - super(MainWindow, self).__init__() - - centralWidget = QtWidgets.QWidget() - self.setCentralWidget(centralWidget) - - self.glWidget = GLWidget() - self.pixmapLabel = QtWidgets.QLabel() - - self.glWidgetArea = QtWidgets.QScrollArea() - self.glWidgetArea.setWidget(self.glWidget) - self.glWidgetArea.setWidgetResizable(True) - self.glWidgetArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.glWidgetArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) - self.glWidgetArea.setSizePolicy(QtWidgets.QSizePolicy.Ignored, - QtWidgets.QSizePolicy.Ignored) - self.glWidgetArea.setMinimumSize(50, 50) - - self.pixmapLabelArea = QtWidgets.QScrollArea() - self.pixmapLabelArea.setWidget(self.pixmapLabel) - self.pixmapLabelArea.setSizePolicy(QtWidgets.QSizePolicy.Ignored, - QtWidgets.QSizePolicy.Ignored) - self.pixmapLabelArea.setMinimumSize(50, 50) - - xSlider = self.createSlider(self.glWidget.xRotationChanged, - self.glWidget.setXRotation) - ySlider = self.createSlider(self.glWidget.yRotationChanged, - self.glWidget.setYRotation) - zSlider = self.createSlider(self.glWidget.zRotationChanged, - self.glWidget.setZRotation) - - self.createActions() - self.createMenus() - - centralLayout = QtWidgets.QGridLayout() - centralLayout.addWidget(self.glWidgetArea, 0, 0) - centralLayout.addWidget(self.pixmapLabelArea, 0, 1) - centralLayout.addWidget(xSlider, 1, 0, 1, 2) - centralLayout.addWidget(ySlider, 2, 0, 1, 2) - centralLayout.addWidget(zSlider, 3, 0, 1, 2) - centralWidget.setLayout(centralLayout) - - xSlider.setValue(15 * 16) - ySlider.setValue(345 * 16) - zSlider.setValue(0 * 16) - - self.setWindowTitle("Grabber") - self.resize(400, 300) - - def renderIntoPixmap(self): - size = self.getSize() - - if size.isValid(): - pixmap = self.glWidget.renderPixmap(size.width(), size.height()) - self.setPixmap(pixmap) - - def grabFrameBuffer(self): - image = self.glWidget.grabFrameBuffer() - self.setPixmap(QtGui.QPixmap.fromImage(image)) - - def clearPixmap(self): - self.setPixmap(QtGui.QPixmap()) - - def about(self): - QtWidgets.QMessageBox.about(self, "About Grabber", - "The <b>Grabber</b> example demonstrates two approaches for " - "rendering OpenGL into a Qt pixmap.") - - def createActions(self): - self.renderIntoPixmapAct = QtWidgets.QAction("&Render into Pixmap...", - self, shortcut="Ctrl+R", triggered=self.renderIntoPixmap) - - self.grabFrameBufferAct = QtWidgets.QAction("&Grab Frame Buffer", self, - shortcut="Ctrl+G", triggered=self.grabFrameBuffer) - - self.clearPixmapAct = QtWidgets.QAction("&Clear Pixmap", self, - shortcut="Ctrl+L", triggered=self.clearPixmap) - - self.exitAct = QtWidgets.QAction("E&xit", self, shortcut="Ctrl+Q", - triggered=self.close) - - self.aboutAct = QtWidgets.QAction("&About", self, triggered=self.about) - - self.aboutQtAct = QtWidgets.QAction("About &Qt", self, - triggered=qApp.aboutQt) - - def createMenus(self): - self.fileMenu = self.menuBar().addMenu("&File") - self.fileMenu.addAction(self.renderIntoPixmapAct) - self.fileMenu.addAction(self.grabFrameBufferAct) - self.fileMenu.addAction(self.clearPixmapAct) - self.fileMenu.addSeparator() - self.fileMenu.addAction(self.exitAct) - - self.helpMenu = self.menuBar().addMenu("&Help") - self.helpMenu.addAction(self.aboutAct) - self.helpMenu.addAction(self.aboutQtAct) - - def createSlider(self, changedSignal, setterSlot): - slider = QtWidgets.QSlider(QtCore.Qt.Horizontal) - slider.setRange(0, 360 * 16) - slider.setSingleStep(16) - slider.setPageStep(15 * 16) - slider.setTickInterval(15 * 16) - slider.setTickPosition(QtWidgets.QSlider.TicksRight) - - slider.valueChanged.connect(setterSlot) - changedSignal.connect(slider.setValue) - - return slider - - def setPixmap(self, pixmap): - self.pixmapLabel.setPixmap(pixmap) - size = pixmap.size() - - if size - QtCore.QSize(1, 0) == self.pixmapLabelArea.maximumViewportSize(): - size -= QtCore.QSize(1, 0) - - self.pixmapLabel.resize(size) - - def getSize(self): - text, ok = QtWidgets.QInputDialog.getText(self, "Grabber", - "Enter pixmap size:", QtWidgets.QLineEdit.Normal, - "%d x %d" % (self.glWidget.width(), self.glWidget.height())) - - if not ok: - return QtCore.QSize() - - regExp = QtCore.QRegExp("([0-9]+) *x *([0-9]+)") - - if regExp.exactMatch(text): - width = int(regExp.cap(1)) - height = int(regExp.cap(2)) - if width > 0 and width < 2048 and height > 0 and height < 2048: - return QtCore.QSize(width, height) - - return self.glWidget.size() - - -if __name__ == '__main__': - - app = QtWidgets.QApplication(sys.argv) - mainWin = MainWindow() - mainWin.show() - res = app.exec_() - mainWin.glWidget.freeResources() - sys.exit(res) |