1

I'm trying to use PyQT and the Python binding for OpenGL to display an image on a rectangle. So far, here's my code:

gVShader = """
              attribute vec4 position;
              attribute vec2 texture_coordinates;   
             varying vec4 dstColor;
             varying vec2 v_texture_coordinates;

            void main() {    
                v_texture_coordinates = texture_coordinates;
                gl_Position = position;    
            }"""

gFShader = """   
            uniform sampler2D texture1;
            varying vec2 v_texture_coordinates;

            void main() {

                gl_FragColor = texture2D(texture1, v_texture_coordinates);
            }"""   
class ProjectiveGLViewer(QtOpenGL.QGLWidget):

    def __init__(self, parent=None):
        super(ProjectiveGLViewer, self).__init__(parent)


    def initializeGL(self):

    # load the shaders source code

        vshader = QtOpenGL.QGLShader(QtOpenGL.QGLShader.Vertex, self)
        if not vshader.compileSourceCode(gVShader):
            print vshader.log()

        fshader = QtOpenGL.QGLShader(QtOpenGL.QGLShader.Fragment, self)
        if not fshader.compileSourceCode(gFShader):
            print fshader.log()

    # create the shader program, compile, attach shaders to the program, link and use the program

        self._program = QtOpenGL.QGLShaderProgram()
        self._program.addShader(vshader)
        self._program.addShader(fshader)
        self._program.link()
        self._program.bind()

    # data array (2 [position], 2 [texture coordinates])

        data = np.array([-1.0, -1.0, 0.0, 0.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0], dtype=np.float32)

    # create a buffer and bind it to the 'data' array

        self.bufferID = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.bufferID)
        glBufferData(GL_ARRAY_BUFFER, data.nbytes, data, GL_DYNAMIC_DRAW)

    # tell OpenGL how to handle the buffer of data that is already on the GPU

        loc = self._program.attributeLocation("position")
        glEnableVertexAttribArray(loc)
        glVertexAttribPointer(loc, 2, GL_FLOAT, False, 16, ctypes.c_void_p(0))

        loc = self._program.attributeLocation("texture_coordinates")
        glEnableVertexAttribArray(loc)
        glVertexAttribPointer(loc, 2, GL_FLOAT, False, 16, ctypes.c_void_p(8))    

        self._imageTextureID = glGenTextures(1)

        image = QtGui.QImage("image.jpg")
        ptr = image.bits()
        ptr.setsize(image.byteCount())
        image_data = np.asarray(ptr).reshape(image.width(), image.height(), 4)

        glBindTexture(GL_TEXTURE_2D,  self._imageTextureID)
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image_data)

        glActiveTexture(GL_TEXTURE0)
        glBindTexture(GL_TEXTURE_2D, self._imageTextureID)

        self._program.setUniformValue('texture1', 0)


    def paintGL(self):
        glBindBuffer(GL_ARRAY_BUFFER, self.bufferID)
        glClearColor(0, 0.2, 0.3, 1.0)
        glClearDepth(1.0)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 6)

    def resizeGL(self, w, h):
        glViewport(0, 0, w, h)

Not too sure what i'm doing wrong here, but i'm getting back a black rectangle. any ideas?

1 Answer 1

1

Your texture is incomplete. You are not setting filtering and wrap modes. Add these after glTexImage2D:

    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST )
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST )
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT )
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT )
Sign up to request clarification or add additional context in comments.

6 Comments

...or upload a complete set of mipmaps.
It worked, thanks! But any reason it's being displayed vertically flipped (maybe to coordinates i'm sending in the array are in the wrong order?) and the color space is a bit off?
You could flip the v-coordinate in the shader: v_texture_coordinates.y = 1.0 - v_texture_coordinates.y
Thanks! any idea why the color space changed?
If the colors are inverted, replacing the second GL_RGBA in glTexImage2D with GL_BGRA could help. Depends on the prescence of an alpha channel in the texture.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.