Here is a basic example that I hope will get you going:
import sys
from OpenGL import GL
from PySide6.QtCore import QTimer
from PySide6.QtGui import QMatrix4x4
from PySide6.QtGui import QOpenGLFunctions
from PySide6.QtGui import QSurfaceFormat
from PySide6.QtOpenGL import QOpenGLShader
from PySide6.QtOpenGL import QOpenGLShaderProgram
from PySide6.QtOpenGLWidgets import QOpenGLWidget
from PySide6.QtWidgets import QApplication
vertext_shader_source = """
attribute highp vec4 posAttr;
attribute lowp vec4 colAttr;
varying lowp vec4 col;
uniform highp mat4 matrix;
void main() {
col = colAttr;
gl_Position = matrix * posAttr;
}
"""
fragment_shader_source = """
varying lowp vec4 col;
void main() {
gl_FragColor = col;
}
"""
class OpenGLWidget(QOpenGLWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.gl = QOpenGLFunctions()
self._animating = False
self._posAttr = 0
self._colAttr = 0
self._matrix_uniform = 0
self._program = None
self._frame = 0
self._timer = QTimer()
self._timer.timeout.connect(self.update)
def initializeGL(self):
self.gl.initializeOpenGLFunctions()
self._program = QOpenGLShaderProgram(self)
success = self._program.addShaderFromSourceCode(
QOpenGLShader.Vertex, vertext_shader_source
)
assert success
success = self._program.addShaderFromSourceCode(
QOpenGLShader.Fragment, fragment_shader_source
)
assert success
success = self._program.link()
assert success
self._posAttr = self._program.attributeLocation("posAttr")
assert self._posAttr != -1
self._colAttr = self._program.attributeLocation("colAttr")
assert self._colAttr != -1
self._matrix_uniform = self._program.uniformLocation("matrix")
assert self._matrix_uniform != -1
def paintGL(self):
retinaScale = self.devicePixelRatio()
self.gl.glViewport(
0, 0, self.width() * retinaScale, self.height() * retinaScale
)
self.gl.glClear(GL.GL_COLOR_BUFFER_BIT)
self._program.bind()
matrix = QMatrix4x4()
matrix.perspective(60.0, 4.0 / 3.0, 0.1, 100.0)
matrix.translate(0, 0, -2)
matrix.rotate(100.0 * self._frame / self.screen().refreshRate(), 0, 1, 0)
self._program.setUniformValue(self._matrix_uniform, matrix)
vertices = [0.0, 0.707, -0.5, -0.5, 0.5, -0.5]
colors = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
GL.glVertexAttribPointer(
self._posAttr, 2, GL.GL_FLOAT, GL.GL_FALSE, 0, vertices
)
GL.glVertexAttribPointer(self._colAttr, 3, GL.GL_FLOAT, GL.GL_FALSE, 0, colors)
self.gl.glEnableVertexAttribArray(self._posAttr)
self.gl.glEnableVertexAttribArray(self._colAttr)
self.gl.glDrawArrays(GL.GL_TRIANGLES, 0, 3)
self.gl.glDisableVertexAttribArray(self._colAttr)
self.gl.glDisableVertexAttribArray(self._posAttr)
self._program.release()
self._frame += 1
def setAnimating(self, animating: bool):
self._animating = animating
if animating:
self._timer.start(25)
if __name__ == "__main__":
app = QApplication(sys.argv)
format = QSurfaceFormat()
format.setSamples(16)
QSurfaceFormat.setDefaultFormat(format)
widget = OpenGLWidget()
widget.setAnimating(True)
widget.show()
sys.exit(app.exec())