aboutsummaryrefslogtreecommitdiffstats
path: root/examples/opengl/hellogl2/hellogl2.py
diff options
context:
space:
mode:
authorFriedemann Kleint <Friedemann.Kleint@qt.io>2021-03-24 13:56:15 +0100
committerFriedemann Kleint <Friedemann.Kleint@qt.io>2021-03-25 12:31:52 +0100
commit3c499d528bea663ee3ddfeedb101fca505e7e4d6 (patch)
tree76ce020e47381d05ee6ae6143e3416a1cd534ded /examples/opengl/hellogl2/hellogl2.py
parent9afc6a8ed1a717c1f153e190ba5d6237451c42a2 (diff)
Brush up the hellogl2 example
- Use snake case - Use Argument parser - Fix the transparent option to work - Port away from string-based signal/slot connections Task-number: PYSIDE-1112 Change-Id: I104363b35db59fc9e4626d85ebae886c73abfd8a Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'examples/opengl/hellogl2/hellogl2.py')
-rw-r--r--examples/opengl/hellogl2/hellogl2.py264
1 files changed, 137 insertions, 127 deletions
diff --git a/examples/opengl/hellogl2/hellogl2.py b/examples/opengl/hellogl2/hellogl2.py
index 56301e047..c4e6d64c4 100644
--- a/examples/opengl/hellogl2/hellogl2.py
+++ b/examples/opengl/hellogl2/hellogl2.py
@@ -2,7 +2,7 @@
############################################################################
##
## Copyright (C) 2013 Riverbank Computing Limited.
-## Copyright (C) 2018 The Qt Company Ltd.
+## Copyright (C) 2021 The Qt Company Ltd.
## Contact: http://www.qt.io/licensing/
##
## This file is part of the Qt for Python examples of the Qt Toolkit.
@@ -42,10 +42,11 @@
"""PySide6 port of the opengl/hellogl2 example from Qt v5.x"""
-import sys
+from argparse import ArgumentParser, RawTextHelpFormatter
+import ctypes
import math
import numpy
-import ctypes
+import sys
from PySide6.QtCore import QCoreApplication, Signal, SIGNAL, SLOT, Qt, QSize, QPointF
from PySide6.QtGui import (QVector3D, QOpenGLFunctions,
QMatrix4x4, QOpenGLContext, QSurfaceFormat)
@@ -61,41 +62,50 @@ try:
from OpenGL import GL
except ImportError:
app = QApplication(sys.argv)
- messageBox = QMessageBox(QMessageBox.Critical, "OpenGL hellogl",
+ message_box = QMessageBox(QMessageBox.Critical, "OpenGL hellogl",
"PyOpenGL must be installed to run this example.",
QMessageBox.Close)
- messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate")
- messageBox.exec_()
+ message_box.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate")
+ message_box.exec_()
sys.exit(1)
class Window(QWidget):
- def __init__(self, parent=None):
+ def __init__(self, transparent, parent=None):
QWidget.__init__(self, parent)
- self.glWidget = GLWidget()
+ if transparent:
+ self.setAttribute(Qt.WA_TranslucentBackground)
+ self.setAttribute(Qt.WA_NoSystemBackground, False)
+
+ self._gl_widget = GLWidget(transparent)
+
+ self._x_slider = self.create_slider()
+ self._x_slider.valueChanged.connect(self._gl_widget.set_xrotation)
+ self._gl_widget.x_rotation_changed.connect(self._x_slider.setValue)
- self.xSlider = self.createSlider(SIGNAL("xRotationChanged(int)"),
- self.glWidget.setXRotation)
- self.ySlider = self.createSlider(SIGNAL("yRotationChanged(int)"),
- self.glWidget.setYRotation)
- self.zSlider = self.createSlider(SIGNAL("zRotationChanged(int)"),
- self.glWidget.setZRotation)
+ self._y_slider = self.create_slider()
+ self._y_slider.valueChanged.connect(self._gl_widget.set_yrotation)
+ self._gl_widget.y_rotation_changed.connect(self._y_slider.setValue)
- mainLayout = QHBoxLayout()
- mainLayout.addWidget(self.glWidget)
- mainLayout.addWidget(self.xSlider)
- mainLayout.addWidget(self.ySlider)
- mainLayout.addWidget(self.zSlider)
- self.setLayout(mainLayout)
+ self._z_slider = self.create_slider()
+ self._z_slider.valueChanged.connect(self._gl_widget.set_zrotation)
+ self._gl_widget.z_rotation_changed.connect(self._z_slider.setValue)
- self.xSlider.setValue(15 * 16)
- self.ySlider.setValue(345 * 16)
- self.zSlider.setValue(0 * 16)
+ main_layout = QHBoxLayout()
+ main_layout.addWidget(self._gl_widget)
+ main_layout.addWidget(self._x_slider)
+ main_layout.addWidget(self._y_slider)
+ main_layout.addWidget(self._z_slider)
+ self.setLayout(main_layout)
+
+ self._x_slider.setValue(15 * 16)
+ self._y_slider.setValue(345 * 16)
+ self._z_slider.setValue(0 * 16)
self.setWindowTitle(self.tr("Hello GL"))
- def createSlider(self, changedSignal, setterSlot):
+ def create_slider(self):
slider = QSlider(Qt.Vertical)
slider.setRange(0, 360 * 16)
@@ -103,10 +113,6 @@ class Window(QWidget):
slider.setPageStep(15 * 16)
slider.setTickInterval(15 * 16)
slider.setTickPosition(QSlider.TicksRight)
-
- self.glWidget.connect(slider, SIGNAL("valueChanged(int)"), setterSlot)
- self.connect(self.glWidget, changedSignal, slider, SLOT("setValue(int)"))
-
return slider
def keyPressEvent(self, event):
@@ -141,17 +147,16 @@ class Logo():
self.extrude(x4, y4, y4, x4)
self.extrude(y4, x4, y3, x3)
- Pi = 3.14159265358979323846
- NumSectors = 100
+ NUM_SECTORS = 100
- for i in range(NumSectors):
- angle = (i * 2 * Pi) / NumSectors
+ for i in range(NUM_SECTORS):
+ angle = (i * 2 * math.pi) / NUM_SECTORS
x5 = 0.30 * math.sin(angle)
y5 = 0.30 * math.cos(angle)
x6 = 0.20 * math.sin(angle)
y6 = 0.20 * math.cos(angle)
- angle = ((i + 1) * 2 * Pi) / NumSectors
+ angle = ((i + 1) * 2 * math.pi) / NUM_SECTORS
x7 = 0.20 * math.sin(angle)
y7 = 0.20 * math.cos(angle)
x8 = 0.30 * math.sin(angle)
@@ -162,13 +167,13 @@ class Logo():
self.extrude(x6, y6, x7, y7)
self.extrude(x8, y8, x5, y5)
- def constData(self):
+ def const_data(self):
return self.m_data.tobytes()
def count(self):
return self.m_count
- def vertexCount(self):
+ def vertex_count(self):
return self.m_count / 6
def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
@@ -219,44 +224,45 @@ class Logo():
self.m_count += 6
class GLWidget(QOpenGLWidget, QOpenGLFunctions):
- xRotationChanged = Signal(int)
- yRotationChanged = Signal(int)
- zRotationChanged = Signal(int)
+ x_rotation_changed = Signal(int)
+ y_rotation_changed = Signal(int)
+ z_rotation_changed = Signal(int)
- def __init__(self, parent=None):
+ def __init__(self, transparent, parent=None):
QOpenGLWidget.__init__(self, parent)
QOpenGLFunctions.__init__(self)
- self.core = "--coreprofile" in QCoreApplication.arguments()
- self.xRot = 0
- self.yRot = 0
- self.zRot = 0
- self.lastPos = QPointF()
+ self._transparent = transparent
+ self._core = QSurfaceFormat.defaultFormat().profile() == QSurfaceFormat.CoreProfile
+
+ self._x_rot = 0
+ self._y_rot = 0
+ self._z_rot = 0
+ self._last_pos = QPointF()
self.logo = Logo()
self.vao = QOpenGLVertexArrayObject()
- self.logoVbo = QOpenGLBuffer()
+ self._logo_vbo = QOpenGLBuffer()
self.program = QOpenGLShaderProgram()
- self.projMatrixLoc = 0
- self.mvMatrixLoc = 0
- self.normalMatrixLoc = 0
- self.lightPosLoc = 0
+ self._proj_matrix_loc = 0
+ self._mv_matrix_loc = 0
+ self._normal_matrix_loc = 0
+ self._light_pos_loc = 0
self.proj = QMatrix4x4()
self.camera = QMatrix4x4()
self.world = QMatrix4x4()
- self.transparent = "--transparent" in QCoreApplication.arguments()
- if self.transparent:
+ if transparent:
fmt = self.format()
fmt.setAlphaBufferSize(8)
self.setFormat(fmt)
- def xRotation(self):
- return self.xRot
+ def x_rotation(self):
+ return self._x_rot
- def yRotation(self):
- return self.yRot
+ def y_rotation(self):
+ return self._y_rot
- def zRotation(self):
- return self.zRot
+ def z_rotation(self):
+ return self._z_rot
def minimumSizeHint(self):
return QSize(50, 50)
@@ -264,42 +270,42 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
def sizeHint(self):
return QSize(400, 400)
- def normalizeAngle(self, angle):
+ def normalize_angle(self, angle):
while angle < 0:
angle += 360 * 16
while angle > 360 * 16:
angle -= 360 * 16
return angle
- def setXRotation(self, angle):
- angle = self.normalizeAngle(angle)
- if angle != self.xRot:
- self.xRot = angle
- self.emit(SIGNAL("xRotationChanged(int)"), angle)
+ def set_xrotation(self, angle):
+ angle = self.normalize_angle(angle)
+ if angle != self._x_rot:
+ self._x_rot = angle
+ self.x_rotation_changed.emit(angle)
self.update()
- def setYRotation(self, angle):
- angle = self.normalizeAngle(angle)
- if angle != self.yRot:
- self.yRot = angle
- self.emit(SIGNAL("yRotationChanged(int)"), angle)
+ def set_yrotation(self, angle):
+ angle = self.normalize_angle(angle)
+ if angle != self._y_rot:
+ self._y_rot = angle
+ self.y_rotation_changed.emit(angle)
self.update()
- def setZRotation(self, angle):
- angle = self.normalizeAngle(angle)
- if angle != self.zRot:
- self.zRot = angle
- self.emit(SIGNAL("zRotationChanged(int)"), angle)
+ def set_zrotation(self, angle):
+ angle = self.normalize_angle(angle)
+ if angle != self._z_rot:
+ self._z_rot = angle
+ self.z_rotation_changed.emit(angle)
self.update()
def cleanup(self):
self.makeCurrent()
- self.logoVbo.destroy()
+ self._logo_vbo.destroy()
del self.program
self.program = None
self.doneCurrent()
- def vertexShaderSourceCore(self):
+ def vertex_shader_source_core(self):
return """#version 150
in vec4 vertex;
in vec3 normal;
@@ -314,7 +320,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
gl_Position = projMatrix * mvMatrix * vertex;
}"""
- def fragmentShaderSourceCore(self):
+ def fragment_shader_source_core(self):
return """#version 150
in highp vec3 vert;
in highp vec3 vertNormal;
@@ -329,7 +335,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
}"""
- def vertexShaderSource(self):
+ def vertex_shader_source(self):
return """attribute vec4 vertex;
attribute vec3 normal;
varying vec3 vert;
@@ -343,7 +349,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
gl_Position = projMatrix * mvMatrix * vertex;
}"""
- def fragmentShaderSource(self):
+ def fragment_shader_source(self):
return """varying highp vec3 vert;
varying highp vec3 vertNormal;
uniform highp vec3 lightPos;
@@ -358,48 +364,48 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
def initializeGL(self):
self.context().aboutToBeDestroyed.connect(self.cleanup)
self.initializeOpenGLFunctions()
- self.glClearColor(0, 0, 0, 1)
+ self.glClearColor(0, 0, 0, 0 if self._transparent else 1)
self.program = QOpenGLShaderProgram()
- if self.core:
- self.vertexShader = self.vertexShaderSourceCore()
- self.fragmentShader = self.fragmentShaderSourceCore()
+ if self._core:
+ self._vertex_shader = self.vertex_shader_source_core()
+ self._fragment_shader = self.fragment_shader_source_core()
else:
- self.vertexShader = self.vertexShaderSource()
- self.fragmentShader = self.fragmentShaderSource()
+ self._vertex_shader = self.vertex_shader_source()
+ self._fragment_shader = self.fragment_shader_source()
- self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, self.vertexShader)
- self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, self.fragmentShader)
+ self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, self._vertex_shader)
+ self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, self._fragment_shader)
self.program.bindAttributeLocation("vertex", 0)
self.program.bindAttributeLocation("normal", 1)
self.program.link()
self.program.bind()
- self.projMatrixLoc = self.program.uniformLocation("projMatrix")
- self.mvMatrixLoc = self.program.uniformLocation("mvMatrix")
- self.normalMatrixLoc = self.program.uniformLocation("normalMatrix")
- self.lightPosLoc = self.program.uniformLocation("lightPos")
+ self._proj_matrix_loc = self.program.uniformLocation("projMatrix")
+ self._mv_matrix_loc = self.program.uniformLocation("mvMatrix")
+ self._normal_matrix_loc = self.program.uniformLocation("normalMatrix")
+ self._light_pos_loc = self.program.uniformLocation("lightPos")
self.vao.create()
- vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)
+ vao_binder = QOpenGLVertexArrayObject.Binder(self.vao)
- self.logoVbo.create()
- self.logoVbo.bind()
+ self._logo_vbo.create()
+ self._logo_vbo.bind()
float_size = ctypes.sizeof(ctypes.c_float)
- self.logoVbo.allocate(self.logo.constData(), self.logo.count() * float_size)
+ self._logo_vbo.allocate(self.logo.const_data(), self.logo.count() * float_size)
- self.setupVertexAttribs()
+ self.setup_vertex_attribs()
self.camera.setToIdentity()
self.camera.translate(0, 0, -1)
- self.program.setUniformValue(self.lightPosLoc, QVector3D(0, 0, 70))
+ self.program.setUniformValue(self._light_pos_loc, QVector3D(0, 0, 70))
self.program.release()
- vaoBinder = None
+ vao_binder = None
- def setupVertexAttribs(self):
- self.logoVbo.bind()
+ def setup_vertex_attribs(self):
+ self._logo_vbo.bind()
f = QOpenGLContext.currentContext().functions()
f.glEnableVertexAttribArray(0)
f.glEnableVertexAttribArray(1)
@@ -409,7 +415,7 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
pointer = VoidPtr(3 * float_size)
f.glVertexAttribPointer(0, 3, int(GL.GL_FLOAT), int(GL.GL_FALSE), 6 * float_size, null)
f.glVertexAttribPointer(1, 3, int(GL.GL_FLOAT), int(GL.GL_FALSE), 6 * float_size, pointer)
- self.logoVbo.release()
+ self._logo_vbo.release()
def paintGL(self):
self.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
@@ -417,61 +423,65 @@ class GLWidget(QOpenGLWidget, QOpenGLFunctions):
self.glEnable(GL.GL_CULL_FACE)
self.world.setToIdentity()
- self.world.rotate(180 - (self.xRot / 16), 1, 0, 0)
- self.world.rotate(self.yRot / 16, 0, 1, 0)
- self.world.rotate(self.zRot / 16, 0, 0, 1)
+ self.world.rotate(180 - (self._x_rot / 16), 1, 0, 0)
+ self.world.rotate(self._y_rot / 16, 0, 1, 0)
+ self.world.rotate(self._z_rot / 16, 0, 0, 1)
- vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)
+ vao_binder = QOpenGLVertexArrayObject.Binder(self.vao)
self.program.bind()
- self.program.setUniformValue(self.projMatrixLoc, self.proj)
- self.program.setUniformValue(self.mvMatrixLoc, self.camera * self.world)
- normalMatrix = self.world.normalMatrix()
- self.program.setUniformValue(self.normalMatrixLoc, normalMatrix)
+ self.program.setUniformValue(self._proj_matrix_loc, self.proj)
+ self.program.setUniformValue(self._mv_matrix_loc, self.camera * self.world)
+ normal_matrix = self.world.normalMatrix()
+ self.program.setUniformValue(self._normal_matrix_loc, normal_matrix)
- self.glDrawArrays(GL.GL_TRIANGLES, 0, self.logo.vertexCount())
+ self.glDrawArrays(GL.GL_TRIANGLES, 0, self.logo.vertex_count())
self.program.release()
- vaoBinder = None
+ vao_binder = None
def resizeGL(self, width, height):
self.proj.setToIdentity()
self.proj.perspective(45, width / height, 0.01, 100)
def mousePressEvent(self, event):
- self.lastPos = event.position()
+ self._last_pos = event.position()
def mouseMoveEvent(self, event):
pos = event.position()
- dx = pos.x() - self.lastPos.x()
- dy = pos.y() - self.lastPos.y()
+ dx = pos.x() - self._last_pos.x()
+ dy = pos.y() - self._last_pos.y()
if event.buttons() & Qt.LeftButton:
- self.setXRotation(self.xRot + 8 * dy)
- self.setYRotation(self.yRot + 8 * dx)
+ self.set_xrotation(self._x_rot + 8 * dy)
+ self.set_yrotation(self._y_rot + 8 * dx)
elif event.buttons() & Qt.RightButton:
- self.setXRotation(self.xRot + 8 * dy)
- self.setZRotation(self.zRot + 8 * dx)
+ self.set_xrotation(self._x_rot + 8 * dy)
+ self.set_zrotation(self._z_rot + 8 * dx)
- self.lastPos = pos
+ self._last_pos = pos
if __name__ == '__main__':
app = QApplication(sys.argv)
+ parser = ArgumentParser(description="hellogl2", formatter_class=RawTextHelpFormatter)
+ parser.add_argument('--multisample', '-m', action='store_true',
+ help='Use Multisampling')
+ parser.add_argument('--coreprofile', '-c', action='store_true',
+ help='Use Core Profile')
+ parser.add_argument('--transparent', '-t', action='store_true',
+ help='Transparent Windows')
+ options = parser.parse_args()
fmt = QSurfaceFormat()
fmt.setDepthBufferSize(24)
- if "--multisample" in QCoreApplication.arguments():
+ if options.multisample:
fmt.setSamples(4)
- if "--coreprofile" in QCoreApplication.arguments():
+ if options.coreprofile:
fmt.setVersion(3, 2)
fmt.setProfile(QSurfaceFormat.CoreProfile)
QSurfaceFormat.setDefaultFormat(fmt)
- mainWindow = Window()
- if "--transparent" in QCoreApplication.arguments():
- mainWindow.setAttribute(Qt.WA_TranslucentBackground)
- mainWindow.setAttribute(Qt.WA_NoSystemBackground, False)
-
- mainWindow.resize(mainWindow.sizeHint())
- mainWindow.show()
+ main_window = Window(options.transparent)
+ main_window.resize(main_window.sizeHint())
+ main_window.show()
res = app.exec_()
sys.exit(res)