aboutsummaryrefslogtreecommitdiffstats
path: root/examples/opengl/contextinfo/contextinfo.py
diff options
context:
space:
mode:
Diffstat (limited to 'examples/opengl/contextinfo/contextinfo.py')
-rw-r--r--examples/opengl/contextinfo/contextinfo.py229
1 files changed, 106 insertions, 123 deletions
diff --git a/examples/opengl/contextinfo/contextinfo.py b/examples/opengl/contextinfo/contextinfo.py
index 0a686d388..233636853 100644
--- a/examples/opengl/contextinfo/contextinfo.py
+++ b/examples/opengl/contextinfo/contextinfo.py
@@ -1,43 +1,6 @@
-
-#############################################################################
-##
-## Copyright (C) 2017 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$
-##
-#############################################################################
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+from __future__ import annotations
"""PySide6 port of the opengl/contextinfo example from Qt v5.x"""
@@ -47,25 +10,25 @@ import sys
from textwrap import dedent
-from PySide6.QtCore import QCoreApplication, QLibraryInfo, QSize, QTimer, Qt
+from PySide6.QtCore import (QCoreApplication, QLibraryInfo, QSize, QTimer, Qt,
+ Slot)
from PySide6.QtGui import (QMatrix4x4, QOpenGLContext, QSurfaceFormat, QWindow)
from PySide6.QtOpenGL import (QOpenGLBuffer, QOpenGLShader,
QOpenGLShaderProgram, QOpenGLVertexArrayObject)
from PySide6.QtWidgets import (QApplication, QHBoxLayout, QMessageBox, QPlainTextEdit,
- QWidget)
+ QWidget)
from PySide6.support import VoidPtr
try:
from OpenGL import GL
except ImportError:
app = QApplication(sys.argv)
- messageBox = QMessageBox(QMessageBox.Critical, "ContextInfo",
- "PyOpenGL must be installed to run this example.",
- QMessageBox.Close)
- messageBox.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate")
- messageBox.exec_()
+ message_box = QMessageBox(QMessageBox.Critical, "ContextInfo",
+ "PyOpenGL must be installed to run this example.", QMessageBox.Close)
+ message_box.setDetailedText("Run:\npip install PyOpenGL PyOpenGL_accelerate")
+ message_box.exec()
sys.exit(1)
-vertexShaderSource110 = dedent("""
+vertex_shader_source_110 = dedent("""
// version 110
attribute highp vec4 posAttr;
attribute lowp vec4 colAttr;
@@ -77,7 +40,7 @@ vertexShaderSource110 = dedent("""
}
""")
-fragmentShaderSource110 = dedent("""
+fragment_shader_source_110 = dedent("""
// version 110
varying lowp vec4 col;
void main() {
@@ -85,7 +48,7 @@ fragmentShaderSource110 = dedent("""
}
""")
-vertexShaderSource = dedent("""
+vertex_shader_source = dedent("""
// version 150
in vec4 posAttr;
in vec4 colAttr;
@@ -97,7 +60,7 @@ vertexShaderSource = dedent("""
}
""")
-fragmentShaderSource = dedent("""
+fragment_shader_source = dedent("""
// version 150
in vec4 col;
out vec4 fragColor;
@@ -106,20 +69,25 @@ fragmentShaderSource = dedent("""
}
""")
-vertices = numpy.array([0, 0.707, -0.5, -0.5, 0.5, -0.5], dtype = numpy.float32)
-colors = numpy.array([1, 0, 0, 0, 1, 0, 0, 0, 1], dtype = numpy.float32)
+vertices = numpy.array([0, 0.707, -0.5, -0.5, 0.5, -0.5], dtype=numpy.float32)
+colors = numpy.array([1, 0, 0, 0, 1, 0, 0, 0, 1], dtype=numpy.float32)
def print_surface_format(surface_format):
- profile_name = 'core' if surface_format.profile() == QSurfaceFormat.CoreProfile else 'compatibility'
- return "{} version {}.{}".format(profile_name,
- surface_format.majorVersion(), surface_format.minorVersion())
+ if surface_format.profile() == QSurfaceFormat.CoreProfile:
+ profile_name = 'core'
+ else:
+ profile_name = 'compatibility'
+ major = surface_format.majorVersion()
+ minor = surface_format.minorVersion()
+ return f"{profile_name} version {major}.{minor}"
+
class RenderWindow(QWindow):
- def __init__(self, format):
- super(RenderWindow, self).__init__()
+ def __init__(self, fmt):
+ super().__init__()
self.setSurfaceType(QWindow.OpenGLSurface)
- self.setFormat(format)
+ self.setFormat(fmt)
self.context = QOpenGLContext(self)
self.context.setFormat(self.requestedFormat())
if not self.context.create():
@@ -128,53 +96,58 @@ class RenderWindow(QWindow):
self.timer = None
self.angle = 0
- def initGl(self):
+ def init_gl(self):
self.program = QOpenGLShaderProgram(self)
self.vao = QOpenGLVertexArrayObject()
self.vbo = QOpenGLBuffer()
- format = self.context.format()
- useNewStyleShader = format.profile() == QSurfaceFormat.CoreProfile
+ fmt = self.context.format()
+ use_new_style_shader = fmt.profile() == QSurfaceFormat.CoreProfile
# Try to handle 3.0 & 3.1 that do not have the core/compatibility profile
# concept 3.2+ has. This may still fail since version 150 (3.2) is
# specified in the sources but it's worth a try.
- if (format.renderableType() == QSurfaceFormat.OpenGL and format.majorVersion() == 3
- and format.minorVersion() <= 1):
- useNewStyleShader = not format.testOption(QSurfaceFormat.DeprecatedFunctions)
-
- vertexShader = vertexShaderSource if useNewStyleShader else vertexShaderSource110
- fragmentShader = fragmentShaderSource if useNewStyleShader else fragmentShaderSource110
- if not self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertexShader):
- raise Exception("Vertex shader could not be added: {} ({})".format(self.program.log(), vertexShader))
- if not self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragmentShader):
- raise Exception("Fragment shader could not be added: {} ({})".format(self.program.log(), fragmentShader))
+ if (fmt.renderableType() == QSurfaceFormat.OpenGL and fmt.majorVersion() == 3
+ and fmt.minorVersion() <= 1):
+ use_new_style_shader = not fmt.testOption(QSurfaceFormat.DeprecatedFunctions)
+
+ vertex_shader = vertex_shader_source if use_new_style_shader else vertex_shader_source_110
+ fragment_shader = (fragment_shader_source
+ if use_new_style_shader
+ else fragment_shader_source_110)
+ if not self.program.addShaderFromSourceCode(QOpenGLShader.Vertex, vertex_shader):
+ log = self.program.log()
+ raise Exception("Vertex shader could not be added: {log} ({vertexShader})")
+ if not self.program.addShaderFromSourceCode(QOpenGLShader.Fragment, fragment_shader):
+ log = self.program.log()
+ raise Exception(f"Fragment shader could not be added: {log} ({fragment_shader})")
if not self.program.link():
- raise Exception("Could not link shaders: {}".format(self.program.log()))
+ log = self.program.log()
+ raise Exception(f"Could not link shaders: {log}")
- self.posAttr = self.program.attributeLocation("posAttr")
- self.colAttr = self.program.attributeLocation("colAttr")
- self.matrixUniform = self.program.uniformLocation("matrix")
+ self._pos_attr = self.program.attributeLocation("posAttr")
+ self._col_attr = self.program.attributeLocation("colAttr")
+ self._matrix_uniform = self.program.uniformLocation("matrix")
self.vbo.create()
self.vbo.bind()
- self.verticesData = vertices.tobytes()
- self.colorsData = colors.tobytes()
- verticesSize = 4 * vertices.size
- colorsSize = 4 * colors.size
- self.vbo.allocate(VoidPtr(self.verticesData), verticesSize + colorsSize)
- self.vbo.write(verticesSize, VoidPtr(self.colorsData), colorsSize)
+ self._vertices_data = vertices.tobytes()
+ self._colors_data = colors.tobytes()
+ vertices_size = 4 * vertices.size
+ colors_size = 4 * colors.size
+ self.vbo.allocate(VoidPtr(self._vertices_data), vertices_size + colors_size)
+ self.vbo.write(vertices_size, VoidPtr(self._colors_data), colors_size)
self.vbo.release()
- vaoBinder = QOpenGLVertexArrayObject.Binder(self.vao)
- if self.vao.isCreated(): # have VAO support, use it
- self.setupVertexAttribs()
+ with QOpenGLVertexArrayObject.Binder(self.vao):
+ if self.vao.isCreated(): # have VAO support, use it
+ self.setup_vertex_attribs()
- def setupVertexAttribs(self):
+ def setup_vertex_attribs(self):
self.vbo.bind()
- self.program.setAttributeBuffer(self.posAttr, GL.GL_FLOAT, 0, 2)
- self.program.setAttributeBuffer(self.colAttr, GL.GL_FLOAT, 4 * vertices.size, 3)
- self.program.enableAttributeArray(self.posAttr)
- self.program.enableAttributeArray(self.colAttr)
+ self.program.setAttributeBuffer(self._pos_attr, GL.GL_FLOAT, 0, 2)
+ self.program.setAttributeBuffer(self._col_attr, GL.GL_FLOAT, 4 * vertices.size, 3)
+ self.program.enableAttributeArray(self._pos_attr)
+ self.program.enableAttributeArray(self._col_attr)
self.vbo.release()
def exposeEvent(self, event):
@@ -182,7 +155,7 @@ class RenderWindow(QWindow):
self.render()
if self.timer is None:
self.timer = QTimer(self)
- self.timer.timeout.connect(self.slotTimer)
+ self.timer.timeout.connect(self.slot_timer)
if not self.timer.isActive():
self.timer.start(10)
else:
@@ -196,11 +169,11 @@ class RenderWindow(QWindow):
if self.program is None:
functions.glEnable(GL.GL_DEPTH_TEST)
functions.glClearColor(0, 0, 0, 1)
- self.initGl()
+ self.init_gl()
- retinaScale = self.devicePixelRatio()
- functions.glViewport(0, 0, self.width() * retinaScale,
- self.height() * retinaScale)
+ retina_scale = self.devicePixelRatio()
+ functions.glViewport(0, 0, self.width() * retina_scale,
+ self.height() * retina_scale)
functions.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
self.program.bind()
@@ -208,12 +181,12 @@ class RenderWindow(QWindow):
matrix.perspective(60, 4 / 3, 0.1, 100)
matrix.translate(0, 0, -2)
matrix.rotate(self.angle, 0, 1, 0)
- self.program.setUniformValue(self.matrixUniform, matrix)
+ self.program.setUniformValue(self._matrix_uniform, matrix)
if self.vao.isCreated():
self.vao.bind()
- else: # no VAO support, set the vertex attribute arrays now
- self.setupVertexAttribs()
+ else: # no VAO support, set the vertex attribute arrays now
+ self.setup_vertex_attribs()
functions.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
@@ -225,7 +198,8 @@ class RenderWindow(QWindow):
self.context.swapBuffers(self)
self.context.doneCurrent()
- def slotTimer(self):
+ @Slot()
+ def slot_timer(self):
self.render()
self.angle += 1
@@ -233,33 +207,42 @@ class RenderWindow(QWindow):
if not self.context.makeCurrent(self):
raise Exception("makeCurrent() failed")
functions = self.context.functions()
- text = """Vendor: {}\nRenderer: {}\nVersion: {}\nShading language: {}
-\nContext Format: {}\n\nSurface Format: {}""".format(
- functions.glGetString(GL.GL_VENDOR), functions.glGetString(GL.GL_RENDERER),
- functions.glGetString(GL.GL_VERSION),
- functions.glGetString(GL.GL_SHADING_LANGUAGE_VERSION),
- print_surface_format(self.context.format()),
- print_surface_format(self.format()))
+ gl_vendor = functions.glGetString(GL.GL_VENDOR)
+ gl_renderer = functions.glGetString(GL.GL_RENDERER)
+ gl_version = functions.glGetString(GL.GL_VERSION)
+ gl_lang_version = functions.glGetString(GL.GL_SHADING_LANGUAGE_VERSION)
+ context_surface_format = print_surface_format(self.context.format())
+ surface_format = print_surface_format(self.format())
+
+ text = (f"Vendor: {gl_vendor}\n"
+ f"Renderer: {gl_renderer}\n"
+ f"Version: {gl_version}\n"
+ f"Shading language: {gl_lang_version}\n"
+ f"Context Format: {context_surface_format}\n\n"
+ f"Surface Format: {surface_format}")
self.context.doneCurrent()
return text
+
class MainWindow(QWidget):
def __init__(self):
- super(MainWindow, self).__init__()
- hBoxLayout = QHBoxLayout(self)
- self.plainTextEdit = QPlainTextEdit()
- self.plainTextEdit.setMinimumWidth(400)
- self.plainTextEdit.setReadOnly(True)
- hBoxLayout.addWidget(self.plainTextEdit)
- self.renderWindow = RenderWindow(QSurfaceFormat())
- container = QWidget.createWindowContainer(self.renderWindow)
+ super().__init__()
+ h_box_layout = QHBoxLayout(self)
+ self._plain_text_edit = QPlainTextEdit()
+ self._plain_text_edit.setMinimumWidth(400)
+ self._plain_text_edit.setReadOnly(True)
+ h_box_layout.addWidget(self._plain_text_edit)
+ self._render_window = RenderWindow(QSurfaceFormat())
+ container = QWidget.createWindowContainer(self._render_window)
container.setMinimumSize(QSize(400, 400))
- hBoxLayout.addWidget(container)
+ h_box_layout.addWidget(container)
+
+ def update_description(self):
+ build = QLibraryInfo.build()
+ gl = self._render_window.glInfo()
+ text = f"{build}\n\nPython {sys.version}\n\n{gl}"
+ self._plain_text_edit.setPlainText(text)
- def updateDescription(self):
- text = "{}\n\nPython {}\n\n{}".format(QLibraryInfo.build(), sys.version,
- self.renderWindow.glInfo())
- self.plainTextEdit.setPlainText(text)
if __name__ == '__main__':
parser = ArgumentParser(description="contextinfo", formatter_class=RawTextHelpFormatter)
@@ -278,7 +261,7 @@ if __name__ == '__main__':
QCoreApplication.setAttribute(Qt.AA_UseDesktopOpenGL)
app = QApplication(sys.argv)
- mainWindow = MainWindow()
- mainWindow.show()
- mainWindow.updateDescription()
- sys.exit(app.exec_())
+ main_window = MainWindow()
+ main_window.show()
+ main_window.update_description()
+ sys.exit(app.exec())