Edited at

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

More than 1 year has passed since last update.


いきなり余談だが

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_())