2016-07-15 10 views
0

Ich versuche, PyQT und die Python-Bindung für OpenGL zu verwenden, um ein Bild auf einem Rechteck anzuzeigen. Bisher ist hier mein Code:OpenGL (Python) - ein Bild anzeigen?

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) 

nicht sicher, was ich hier falsch mache, aber ich bin immer wieder ein schwarzes Rechteck. irgendwelche Ideen?

Antwort

1

Ihre Textur ist incomplete. Sie legen Filter- und Umbruchmodi nicht fest. Fügen Sie diese nach 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) 
+0

... oder laden Sie einen vollständigen Satz von Mipmaps. – genpfault

+0

Es hat funktioniert, danke! Aber egal, warum es vertikal angezeigt wird (vielleicht sind die Koordinaten, die ich in das Array sende, in der falschen Reihenfolge?) Und der Farbraum ist ein bisschen aus? – YaronGh

+0

Sie können die V-Koordinate im Shader spiegeln: 'v_texture_coordinates.y = 1.0 - v_texture_coordinates.y' – SurvivalMachine