Python
OpenGL
PyQt5
pyside2

Pyside2.QtOpenGL.QGLWidgetを拡張しないで書いてみる。

いきなり余談だが

from PySide2 import QtCore,QtGui,QtWidgets,QtOpenGL

from PyQt5 import QtCore,QtGui,QtWidgets,QtOpenGL

と書いても問題なく動く。ライセンスが絡んでいるらしいが、よくわからない。

QGLWidgetを拡張しないで書いてみる

makeCurrent(), swapBuffers() この2つ関数を使えば解決でした。
QOpenGLContext::swapBuffers() called with non-exposed window, behavior is undefined
というエラーが出るけど、contextを作るのが間に合わないのにswapBuffers()している感じかな。別に問題なさそうです。

from PySide2 import QtCore,QtGui,QtWidgets,QtOpenGL
from OpenGL.GL import *
import sys
import time

frag_src = """
#version 330
out vec4 fragColor;
uniform float time;
uniform vec2 resolution;

void main()
{
    vec2 uv = (2.0*gl_FragCoord.xy-resolution) / resolution.y;
    vec3 col = 0.5 + 0.5*cos(time+uv.xyx+vec3(0,2,4));
    fragColor = vec4(col,1);
}
"""

class Window(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.resize(450,300)
        self.gl = QtOpenGL.QGLWidget()
        self.setCentralWidget(self.gl)
        self.gl.makeCurrent()
        self.program = glCreateProgram()
        for (src, type) in zip(("void main(){gl_Position=gl_Vertex;}", frag_src), (GL_VERTEX_SHADER,GL_FRAGMENT_SHADER)):
            shader = glCreateShader(type)
            glShaderSource(shader, src)
            glCompileShader(shader)
            if glGetShaderiv(shader, GL_COMPILE_STATUS) != GL_TRUE:
                raise RuntimeError(glGetShaderInfoLog(shader).decode())
            glAttachShader(self.program, shader)
            glDeleteShader(shader)
        glLinkProgram(self.program)
        glUseProgram(self.program)
        glUniform2f(glGetUniformLocation(self.program, "resolution"),self.width(), self.height())
        self.zeroTime = time.time()
        self.startTimer(1000//60)

    def timerEvent(self, event):
        glUniform1f(glGetUniformLocation(self.program, "time"), time.time() - self.zeroTime)
        glRects(1, 1, -1, -1)
        self.gl.swapBuffers()

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())