【问题标题】:PyOpenGL: glDrawArrays() - WindowsError: exception: access violation reading 0x0000000000000000PyOpenGL:glDrawArrays() - WindowsError:异常:访问冲突读取 0x0000000000000000
【发布时间】:2015-11-19 09:36:04
【问题描述】:

我在绘制 VBO 时遇到了 PyOpenGL 函数 glDrawArrays() 的问题。我有一个对象(类)ContactGeometry,我使用方法 create_VBO() 创建 VBO,并使用方法 paintGL_VBO() 显示 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)

问题是程序在具有属性的平台上运行正常:

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

但在具有属性的平台上不行:

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

因为它返回以下错误:

WindowsError: exception: access violation reading 0x0000000000000000

任何想法如何解决这个问题,因为我想在多个平台(使用不同的 GPU)上运行代码。这是非常不合理的,因为代码适用于旧版本软件,但不适用于新版本......

init()OpenGLWidget 我设置:

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

【问题讨论】:

  • 检查 self.contact_nodes 是否正确分配。您收到的错误表明您正在尝试读取空指针的值。
  • @Xirema 如果我打印指向self.contact_nodes 的指针,则打印正确的数据。此外,如果我在两个平台上运行glIsBuffer(self.vbo_id),它会返回1
  • 在 glDrawArrays() 之前的前一行将 'length' 分配为变量,如下所示:“int length = len(self.contact_nodes)” 然后使用“glDrawArrays(GL_TRIANGLES, 0, length)”让我知道这是否会改变错误的位置。
  • 几分钟前我正在尝试这个,正如我所说,我成功绘制了 3D 三角形网格,并在那里输入了长度作为对象属性,例如 self.N。虽然在这里没有任何成功。你能看看整个代码吗?我还添加了我构建和绘制 VBO 的整个类。

标签: python opengl pyqt vbo pyopengl


【解决方案1】:

看起来 glEnableClientState 在现代版本的 OpenGL 中已被弃用。 AMD 卡肯定会为您提供兼容性配置文件,这意味着它不会关心您是否尝试使用已弃用的功能,但 NVidia 卡并未指示您的配置文件是核心还是兼容性。您应该确保您的代码明确请求兼容性配置文件。

【讨论】:

  • 请查看主要问题,因为我添加了设置配置文件的代码并且问题未解决。我忘了说,主要使用相同的代码逻辑,我可以毫无问题地显示 3D 三角形网格。但是我遇到了这个问题......
【解决方案2】:

我想我发现了一个问题并解决了它......问题是我启用了普通指针:

glEnableClientState(GL_NORMAL_ARRAY)

但没有定义任何普通指针。解决方法是禁用普通指针:

glDisableClientState(GL_NORMAL_ARRAY)

或添加指向正常的指针,例如:

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

【讨论】:

    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    • 2013-03-06
    • 2014-11-01
    • 1970-01-01
    • 2018-05-19
    相关资源
    最近更新 更多