尝试渲染三角形时,PyOpenGL 中的应用程序崩溃

Posted

技术标签:

【中文标题】尝试渲染三角形时,PyOpenGL 中的应用程序崩溃【英文标题】:Application crashes in PyOpenGL when trying to render Triangle 【发布时间】:2022-01-08 21:12:04 【问题描述】:

我很难处理这个问题。我已经为此度过了一夜,我确实需要帮助。 我想用 PyOpenGL 绑定显示一个简单的三角形,但是我的应用程序崩溃了,而且什么也没有渲染。 我在项目中使用了一个 glfw 窗口——它没有做任何特别的事情——这些是我的 initGL 函数中的设置。

glViewport(0, 0, 500, 500)
glClearColor(0, 0, 0, 1)
glClearDepth(1)

glEnable(GL_BLEND); # activates blending mode
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

glEnable(GL_DEPTH_TEST) # enables depth testing

glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)

这是我的游戏循环的样子:

while not window.shouldClose 
   window.clear()
   render()
   window.swap_buffers()
   window.poll_events()

但我认为需要修复的问题在以下代码中。 这是游戏循环中调用的渲染函数:

def render(self):
   glUseProgram(self.shader_program)
   self.mesh_filter.bind()
   self.mesh_filter.render() <- this line make the applicaion crash after few loops
   self.mesh_filter.unbind()
   glUseProgram(0)

还有我的MeshFilter类的代码:

class MeshFilter():
    def __init__(self, vertices: list, indices: list):
        self.vaoId = glGenVertexArrays(1)
        glBindVertexArray(self.vaoId)
        
        self.count = len(indices)
        self.__allocateIndexBuffer(indices)
        
        self.vbosId = []
        self.__allocateAttributeBuffer(0, 4, vertices)
        
        glBindVertexArray(0)
    
    def __allocateIndexBuffer(self, indices):
        self.eboId = glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.eboId)
        
        self.count = len(indices)
        indices = uint32(indices)
        glBufferData(GL_ELEMENT_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(indices), indices, GL_STATIC_DRAW)
    
    def __allocateAttributeBuffer(self, attribute_index, attribute_size, buffer):
        vboId = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, vboId)
        self.vbosId.insert(attribute_index, vboId)
        
        buffer = float32(buffer)
        glBufferData(GL_ARRAY_BUFFER, ArrayDatatype.arrayByteCount(buffer), buffer, GL_STATIC_DRAW)
        glVertexAttribPointer(attribute_index, attribute_size, GL_FLOAT, GL_FALSE, 0, None)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        
    def bind(self):
        glBindVertexArray(self.vaoId);
        for attribute in range(len(self.vbosId)):
            glEnableVertexAttribArray(attribute)
    
    def unbind(self):
        for attribute in range(len(self.vbosId)):
            glDisableVertexAttribArray(attribute)
        glBindVertexArray(0)
        
    def render(self):
        glDrawElements(GL_TRIANGLES, self.count, GL_UNSIGNED_INT, 0)
        
    def destroy(self):
        glDeleteBuffers(1, [self.eboId])
        glDeleteBuffers(len(self.vbosId), self.vbosId)
        glDeleteVertexArrays(1, [self.vaoId])

使用以下参数调用meshFilter

索引 = [0, 1, 2] 三角形 = [0.6, 0.6, 0, 1.0, -0.6, 0.6, 0, 1.0, 0.0, -0.6, 0, 1.0]

请随时向我询问代码或进一步解释。

编辑如果我用 glDrawArrays(GL_TRIANGLES, 0, 3) 替换 drawElements,它工作得很好。所以我强调,错误在于索引存储。

【问题讨论】:

【参考方案1】:

编辑:解决方案

glDrawElements 需要 None 或 ctypes 中的 nullptr 作为最后一个参数,而不是我之前的 Java 代码中的 0。

像这样,glDrawElements(GL_TRIANGLES, self.count, GL_UNSIGNED_INT, None)

【讨论】:

以上是关于尝试渲染三角形时,PyOpenGL 中的应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

PyOpenGL 无头渲染

Pyglet VBOs glVertexPointer

在pyopengl中无限渲染透明图像

如何从PyOpenGL中的单个数组中提取glVertexPointer()和glColorPointer()的数据?

Python OpenGL第一个三角形(Pyopengl)

在窗口中渲染时,OpenGL 中的第三个三角形顶点显示为 0.0