在 PyQt 中编译着色器

Posted

技术标签:

【中文标题】在 PyQt 中编译着色器【英文标题】:Compiling shaders in PyQt 【发布时间】:2012-06-25 16:03:55 【问题描述】:

我无法在 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_()

【问题讨论】:

【参考方案1】:

OpenGL 上下文不是在构造函数中设置的,它仅在paintGL、resizeGL 和initializeGL 方法中有效和当前,因此您应该在initializeGL 方法中加载和编译着色器,而不是在其他任何地方。

【讨论】:

【参考方案2】:

我相信其他答案现在可能已经过时了。至少从 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)
...

【讨论】:

以上是关于在 PyQt 中编译着色器的主要内容,如果未能解决你的问题,请参考以下文章

Emscripten 无法编译着色器

无法在 Maya 插件中编译顶点着色器

java lwjgl 2着色器错误

OpenGL 着色器无法编译

初识OpenGL 编译着色器

OpenGL着色器版本编译错误