2016-07-15 54 views
0

我正在尝试使用PyQT和OpenGL的Python绑定在矩形上显示图像。到目前为止,这是我的代码:我做OpenGL(python) - 显示图像?

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) 

不太清楚什么错在这里,但我取回一个黑色的矩形。有任何想法吗?

回答

1

您的纹理是incomplete。您不设置过滤和包装模式。添加这些后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

...或上传一套完整的mipmap。 – genpfault

+0

它工作,谢谢!但是任何垂直显示的原因(可能是我在数组中发送的坐标都是错误的顺序?),并且颜色空间有点偏差? – YaronGh

+0

您可以翻转着色器中的v坐标:'v_texture_coordinates.y = 1.0 - v_texture_coordinates.y' – SurvivalMachine