Search code examples
pythonopenglpyqtvbopyopengl

PyOpenGL: glDrawArrays() - WindowsError: exception: access violation reading 0x0000000000000000


I am having problems with PyOpenGL function glDrawArrays() when drawing VBO. I have an object (class) ContactGeometry and I create VBO with method create_VBO() and display VBO with method paintGL_VBO():

class ContactGeometry(object):
    def __init__(self, _area=None, body=None, filename=None, uP=None, parent=None):
        ...
        self.VBO_created = False

    def create_VBO(self):
        if not self.VBO_created:
            #    generate a new VBO and get the associated vbo_id
            num_of_VBOs = 1
            #    create buffer name
            self.vbo_id = GLuint()
            self.vbo_id = glGenBuffers(num_of_VBOs)
            #    bind name to buffer
            glBindBuffer(GL_ARRAY_BUFFER, self.vbo_id)
            self.vbo_data = np.hstack((self.contact_nodes))
            self.N = len(self.contact_nodes)
            self.vbo_data = np.array(self.vbo_data, dtype='float32').flatten()
            #    VBO_data size in bytes
            self.VBO_data_size_in_bytes = arrays.ArrayDatatype.arrayByteCount(self.vbo_data)
            #    add VBO data to buffer
            glBufferData(GL_ARRAY_BUFFER, self.VBO_data_size_in_bytes, self.vbo_data, GL_STATIC_DRAW)
            self.VBO_created = True

    def paintGL_VBO(self):
        if self._visible and self.VBO_created:
            glBindBuffer(GL_ARRAY_BUFFER, self.vbo_id)
            #   pointers
            v_pointer = ctypes.c_void_p(0
            #    stride in bits (1 float = 4 bits)
            stride_in_bits = 0
            glVertexPointer(3, GL_FLOAT, stride_in_bits, v_pointer)
            glDisable(GL_LIGHTING)
            glDrawArrays(GL_LINE_STRIP,  0, self.N)
            glEnable(GL_LIGHTING)
            glBindBuffer(GL_ARRAY_BUFFER, 0)

The problem is that the program runs OK on platform with properties:

PyOpenGL_version = 3.1.0a1
GL Version: 4.2.12217 Compatibility Profile Context 12.104.0.0
GL Vendor: ATI Technologies Inc.
GL Renderer: AMD Radeon HD 6300M Series

But NOT OK on platform with properties:

PyOpenGL_version = 3.0.2
GL Version: 4.3.0
GL Vendor: NVIDIA Corporation
GL Renderer: Quadro 600/PCIe/SSE2

As it returns the following error:

WindowsError: exception: access violation reading 0x0000000000000000

Any ideas how to fix this as I would like to run the code on multiple platforms (with different GPU). It is very irrational as the code works on older version software, but not on newer version...

In init() of class OpenGLWidget I set:

class OpenGLWidget(QtOpenGL.QGLWidget):
    def __init__(self, parent=None):
        ...
        # core profile
        glformat = QtOpenGL.QGLFormat()
        glformat.setProfile(QtOpenGL.QGLFormat.CompatibilityProfile)

Solution

  • I think I have found a problem and solved it... The problem was that I have enabled normal pointer:

    glEnableClientState(GL_NORMAL_ARRAY)
    

    but have not defined any normal pointer. The solution is to dissable normal pointer:

    glDisableClientState(GL_NORMAL_ARRAY)
    

    or to add pointer to normal like:

    glNormalPointer(GL_FLOAT, 0, ctypes.c_void_p(0))