我无法在PyQt中使用基本着色器程序。我认为这至少应该正确编译着色器代码(我不是这里的专家),但无论我尝试什么,addShaderFromSourceFile()
总是返回false。着色器程序日志也始终为空。
我在Ubuntu 12.04上,我可以用C ++编译和运行GLSL着色器程序。所以我不认为这是一个系统问题。
文件 shader.vert
void main(void)
{
gl_Position = ftransform();
}
文件 shader.frag
void main(void)
{
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
文件 test_shaders.py
from OpenGL.GL import *
from OpenGL.GLU import *
from PyQt4 import QtCore, QtGui
from PyQt4.QtOpenGL import *
class ExampleQGLWidget(QGLWidget):
def __init__(self, parent):
QGLWidget.__init__(self, parent)
self.shaderProgram = QGLShaderProgram()
print self.shaderProgram.addShaderFromSourceFile(QGLShader.Vertex, "shader.vert")
print self.shaderProgram.addShaderFromSourceFile(QGLShader.Fragment, "shader.frag")
print self.shaderProgram.log()
self.shaderProgram.link()
glViewport(0,0, 640, 480)
def paintGL(self):
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
self.shaderProgram.bind()
def resizeGL(self, w, h):
glViewport(0, 0, w, h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
def initializeGL(self):
glClearColor(0.0, 0.0, 0.0, 1.0)
glClearDepth(1.0)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
class TestContainer(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
widget = ExampleQGLWidget(self)
self.setCentralWidget(widget)
if __name__ == '__main__':
app = QtGui.QApplication(['Shader Example'])
window = TestContainer()
window.show()
app.exec_()
答案 0 :(得分:6)
OpenGL上下文不是在构造函数中设置的,它只在paintGL,resizeGL和initializeGL方法中有效且最新,所以你应该在initializeGL方法中加载和编译着色器,而不是在其他任何地方。
答案 1 :(得分:0)
我相信其他答案现在可能已经过时。至少自PyQt5以来,就有一种方法可以使小部件OpenGL上下文保持最新(并在随后进行清理)。
可以通过QGlWidget
上的makeCurrent()
和currentDone()
方法来实现。
解决方案如下:
...
class ExampleQGLWidget(QGLWidget):
def __init__(self, parent):
QGLWidget.__init__(self, parent)
self.shaderProgram = QGLShaderProgram()
self.makeCurrent()
print self.shaderProgram.addShaderFromSourceFile(QGLShader.Vertex, "shader.vert")
print self.shaderProgram.addShaderFromSourceFile(QGLShader.Fragment, "shader.frag")
print self.shaderProgram.log()
self.shaderProgram.link()
self.doneCurrent()
glViewport(0,0, 640, 480)
...