PyQt4 OpenGL:GL核心配置文件错误

问题描述:

下午好,我正在学习OpenGL - “红皮书”。我试图做的第一个例子(画两个三角形):PyQt4 OpenGL:GL核心配置文件错误

# PyQT4 imports 
from PyQt4 import QtGui, QtCore, QtOpenGL 
from PyQt4.QtOpenGL import QGLWidget 
# PyOpenGL imports 
from OpenGL.GL import * 
from OpenGL.GL.shaders import * 

class GLPlotWidget(QGLWidget): 
# default window size 
width, height = 600, 600 

def __init__(self, format = None): 
    super(GLPlotWidget, self).__init__(format, None) 

def set_data(self, data): 
    self.data = data 
    self.count = data.shape[0] 
    self.numVAOs = 2 
    self.VAOs = [0] * self.numVAOs 
    self.numVBOs = 2 
    self.VBOs = [0] * self.numVBOs 
    self.shader = None 
    self.vPositionLocation = 0 

def initializeGL(self): 
    glGenVertexArrays(self.numVAOs, self.VAOs) 
    glBindVertexArray(self.VAOs[0]) 

    glGenBuffers(self.numVBOs, self.VBOs) 
    glBindBuffer(GL_ARRAY_BUFFER, self.VBOs[0]) 
    glBufferData(GL_ARRAY_BUFFER, self.count, self.data, GL_STATIC_DRAW) 

    VERTEX_SHADER = compileShader(""" 
     #version 410 core 
     layout(location = 0) in vec4 vPosition; 
     void main() { 
      gl_Position = vPosition; 
     } 
    """, GL_VERTEX_SHADER) 

    FRAGMENT_SHADER = compileShader(""" 
     #version 410 core 
     out vec4 fColor; 
     void main() { 
      fColor = vec4(0.0, 0.0, 1.0, 1.0); 
     } 
    """, GL_FRAGMENT_SHADER) 

    self.shader = compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) 
    glUseProgram(self.shader) 

    glVertexAttribPointer(self.vPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0) 
    glEnableVertexAttribArray(self.vPositionLocation) 

def paintGL(self): 
    glClear(GL_COLOR_BUFFER_BIT) 

    glBindVertexArray(self.VAOs[0]) 
    glDrawArrays(GL_TRIANGLES, 0, self.count) 

    glFlush() 

def resizeGL(self, width, height): 
    # update the window size 
    self.width, self.height = width, height 

    # paint within the whole window 
    glViewport(0, 0, width, height) 

    # set orthographic projection (2D only) 
    glMatrixMode(GL_PROJECTION) 
    glLoadIdentity() 

    # the window corner OpenGL coordinates are (-+1, -+1) 
    glOrtho(-1, 1, -1, 1, -1, 1) 

if __name__ == '__main__': 
    # import numpy for generating random data points 
    import sys 
    import numpy as np 
    import numpy.random as rnd 

    # define a QT window with an OpenGL widget inside it 
    class TestWindow(QtGui.QMainWindow): 
     def __init__(self, parent = None): 
      super(TestWindow, self).__init__(parent) 

      # generate random data points 
      self.data = np.array([ 
       [ -0.90, -0.90 ], [ 0.85, -0.90 ], [ -0.90, 0.85 ], 
       [ 0.90, -0.85 ], [ 0.90, 0.90 ], [ -0.85, 0.90 ] 
      ], dtype = np.float32) 

      # initialize the GL widget 
      glformat = QtOpenGL.QGLFormat() 
      glformat.setVersion(4, 1) 
      glformat.setProfile(QtOpenGL.QGLFormat.CoreProfile) 
      glformat.setSampleBuffers(True) 
      QtOpenGL.QGLFormat.setDefaultFormat(glformat) 
      self.widget = GLPlotWidget(glformat) 
      self.widget.set_data(self.data) 

      # put the window at the screen position (100, 100) 
      self.setGeometry(100, 100, self.widget.width, self.widget.height) 
      self.setCentralWidget(self.widget) 
      self.show() 

    # create the QT App and window 
    app = QtGui.QApplication(sys.argv) 
    glutInitDisplayMode(GLUT_RGBA or GLUT_3_2_CORE_PROFILE) 
    window = TestWindow() 
    window.show() 
    app.exec_() 

我得到这个错误:

OpenGL.error.NullFunctionError: Attempt to call an undefined function glGenVertexArrays, check for bool(glGenVertexArrays) before calling 
OpenGL.error.NullFunctionError: Attempt to call an undefined function glBindVertexArray, check for bool(glBindVertexArray) before calling 
OpenGL.error.NullFunctionError: Attempt to call an undefined function glBindVertexArray, check for bool(glBindVertexArray) before calling 

我发现我必须启用GL核心配置文件,但即使我启用了它,它不工作...

# initialize the GL widget 
glformat = QtOpenGL.QGLFormat() 
glformat.setVersion(4, 1) 
glformat.setProfile(QtOpenGL.QGLFormat.CoreProfile) 
glformat.setSampleBuffers(True) 
QtOpenGL.QGLFormat.setDefaultFormat(glformat) 

同时如果我使用VBO从OpenGL.arrays.vbo它工作正常。

我怎样才能解决这个问题?我错在哪里?

加法:我使用的是Mac OS X 10.9.4,iMac电脑的NVIDIA GeForce GTX 660M 512 MB(OpenGL的4.1的支持和GLSL 4.1.0)

+0

这听起来很像您没有在您的系统上安装正确的OpenGL驱动程序。在Windows中,默认驱动程序和通过Windows更新机制安装的驱动程序被剥离了OpenGL支持,并且OpenGL-1.4只有软件回退功能。您应该做的第一件事是访问您的GPU供应商网站,从那里下载您的GPU的最新驱动程序并安装这些驱动程序。 – datenwolf 2014-09-06 18:38:57

+0

对问题做了补充 – 2014-09-06 19:04:27

从PyQt4的移动到PyQt5解决问题

完整源代码:

# PyQT5 imports 
from PyQt5 import QtGui, QtCore, QtOpenGL, QtWidgets 
from PyQt5.QtOpenGL import QGLWidget 
from ctypes import * 
# PyOpenGL imports 
from OpenGL.GL import * 
from OpenGL.GL.shaders import * 
from OpenGL.GLUT import * 

class GLPlotWidget(QGLWidget): 
    # default window size 
    width, height = 600, 600 

    def __init__(self, format = None): 
     super(GLPlotWidget, self).__init__(format, None) 

    def set_data(self, data): 
     self.data = data 
     self.count = self.data.nbytes 
     self.numVAOs = 2 
     self.VAOs = [0] * self.numVAOs 
     self.numVBOs = 2 
     self.VBOs = [0] * self.numVBOs 
     self.shader = None 
     self.vPositionLocation = 0 

    def initializeGL(self): 

     glClearColor(0.0, 0.0, 0.0, 1.0) 

     self.VAOs = glGenVertexArrays(self.numVAOs) 
     glBindVertexArray(self.VAOs[0]) 

     self.VBOs = glGenBuffers(self.numVBOs) 
     glBindBuffer(GL_ARRAY_BUFFER, self.VBOs[0]) 
     glBufferData(GL_ARRAY_BUFFER, self.count, self.data, GL_STATIC_DRAW) 

     VERTEX_SHADER = compileShader(""" 
      #version 410 core 
      layout(location = 0) in vec4 vPosition; 
      void main() { 
       gl_Position = vPosition; 
      } 
     """, GL_VERTEX_SHADER) 

     FRAGMENT_SHADER = compileShader(""" 
      #version 410 core 
      out vec4 fColor; 
      void main() { 
       fColor = vec4(1.0, 1.0, 0.0, 1.0); 
      } 
     """, GL_FRAGMENT_SHADER) 

     self.shader = compileProgram(VERTEX_SHADER, FRAGMENT_SHADER) 
     glUseProgram(self.shader) 

     glVertexAttribPointer(self.vPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, c_void_p(0)) 
     glEnableVertexAttribArray(self.vPositionLocation) 

    def paintGL(self): 
     glClear(GL_COLOR_BUFFER_BIT) 

     glBindVertexArray(self.VAOs[0]) 
     glDrawArrays(GL_TRIANGLES, 0, self.count) 

     glFlush() 

if __name__ == '__main__': 
    # import numpy for generating random data points 
    import sys 
    import numpy as np 
    import numpy.random as rnd 

    # define a QT window with an OpenGL widget inside it 
    class TestWindow(QtWidgets.QMainWindow): 
     def __init__(self, parent = None): 
      super(TestWindow, self).__init__(parent) 
      self.data = np.array([ 
       [ -0.90, -0.90 ], 
       [ 0.85, -0.90 ], 
       [ -0.90, 0.85 ], 
       [ 0.90, -0.85 ], 
       [ 0.90, 0.90 ], 
       [ -0.85, 0.90 ] 
      ], dtype = np.float32) 
      # initialize the GL widget 
      glformat = QtOpenGL.QGLFormat() 
      glformat.setVersion(4, 1) 
      glformat.setProfile(QtOpenGL.QGLFormat.CoreProfile) 
      glformat.setSampleBuffers(True) 
      self.widget = GLPlotWidget(glformat) 
      self.widget.set_data(self.data) 
      # put the window at the screen position (100, 100) 
      self.setGeometry(100, 100, self.widget.width, self.widget.height) 
      self.setCentralWidget(self.widget) 
      self.show() 

    # create the QT App and window 
    app = QtWidgets.QApplication(sys.argv) 
    window = TestWindow() 
    window.show() 
    app.exec_()