Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiling shaders in PyQt

I can't get a basic shader program working in PyQt. I think this should at least compile the shader code correctly (I'm no expert here), but addShaderFromSourceFile() always returns false no matter what I try. The shader program log is always empty too.

I'm on Ubuntu 12.04, and I can compile and run GLSL shader programs in C++. So I don't think it's a system issue.

File shader.vert

void main(void)
{
    gl_Position = ftransform();
}

File shader.frag

void main(void)
{
    gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}

File 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_()
like image 833
YXD Avatar asked Jun 25 '12 16:06

YXD


1 Answers

The OpenGL context isn't setup inside the constructor, it's only valid and current inside the paintGL, resizeGL and initializeGL methods, so you should load and compile shaders inside the initializeGL method, and not anywhere else.

like image 89
Dr. Snoopy Avatar answered Oct 13 '22 00:10

Dr. Snoopy