使用 EBO 时 OpenGL 崩溃

OpenGL crashing when using EBOs

所以,这个有点特别,因为我不知道错误实际上来自哪里。我有一个 PyOpenGL 脚本,它应该使用 VBO、VAO 和 EBO 绘制带纹理的矩形。当我尝试 运行 终端中的程序时(我在 Ubuntu 16.04),它会创建一个空的、透明的 window,暂停一会儿,然后关闭 window 并在终端中发送一条 'Aborted' 消息。没有别的。

所以我想这可能是我这边的一个错误,所以这里有一些代码:

import math
import ctypes
import numpy as np
import glfw
from packages import shaderUtils
from PIL import Image
from OpenGL.GL import *

vert_shader_file = 'somename.vs'
frag_shader_file = 'somename.fs'

def main():

    glfw.init()
    glfw.window_hint(glfw.CONTEXT_VERSION_MAJOR, 4)
    glfw.window_hint(glfw.CONTEXT_VERSION_MINOR, 5)
    glfw.window_hint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)

    window = glfw.create_window(800, 600, "helo wold", None, None)

    glfw.make_context_current(window)

    #----------TEXTURE STUFF-----------#

    texture = glGenTextures(1)
    glBindTexture(GL_TEXTURE_2D, texture)

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_MIRRORED_REPEAT)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT)

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    textureFile = Image.open('container.jpg')
    textureWidth, textureHeight, textureData = textureFile.size[0], textureFile.size[1], np.array(list(textureFile.getdata()), np.int8) 

    if textureData.any():
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, textureWidth, textureHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData)
        glGenerateMipmap(GL_TEXTURE_2D)
    else:
        print('Failed to load texture')
    del textureData

    vertices = np.array([
         0.5, 0.5, 0,  1, 0, 0,  1, 1,
         0.5,-0.5, 0,  0, 1, 0,  1, 0,
        -0.5,-0.5, 0,  0, 0, 1,  0, 0,
        -0.5, 0.5, 0,  1, 1, 0,  0, 1], dtype = 'float32')
    indices = np.array([0, 1, 3,
                        1, 2, 3], dtype = 'int8')

    shaderProgram = shaderUtils.shader(vert_shader_file, frag_shader_file)
    shaderProgram.compile()

    vbo, vao, ebo = glGenBuffers(1), glGenVertexArrays(1), glGenBuffers(1)

    glBindVertexArray(vao)

    glBindBuffer(GL_ARRAY_BUFFER, vbo)
    glBufferData(GL_ARRAY_BUFFER, vertices, GL_STATIC_DRAW)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo)
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices, GL_STATIC_DRAW)

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
    glEnableVertexAttribArray(0)

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
    glEnableVertexAttribArray(1)

    glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(24))
    glEnableVertexAttribArray(2)

    glBindBuffer(GL_ARRAY_BUFFER, 0)
    glBindVertexArray(0)

     while not glfw.window_should_close(window):

        glClearColor(0.2, 0.3, 0.3, 1.0)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)

        shaderProgram.use()

        glBindTexture(GL_TEXTURE_2D, texture)
        glBindVertexArray(vao)

        glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

        glfw.swap_buffers(window)
        glfw.poll_events()

    glDeleteVertexArrays(1, vao)
    glDeleteBuffers(1, vbo)
    glDeleteBuffers(1, ebo)


    glfw.terminate()

if __name__ == '__main__':
    main()

这是我的顶点和片段着色器:

#version 450 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aColor;
layout (location = 2) in vec2 aTexCoord;

out vec3 ourColor;
out vec2 TexCoord;

void main() {
    gl_Position = vec4(aPos, 1.0);
    ourColor = aColor;
    TexCoord = aTexCoord;
}
#version 450 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform sampler2D ourTexture;

void main()
{
    FragColor = texture(ourTexture, TexCoord);
}

我想知道我做错了什么,因为这是我第一次使用 EBO。谢谢!

glDrawElements 的最后一个参数是 const GLvoid * 类型,因此它必须是 None 而不是 0:

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None)

此外,索引数组中的数据类型必须与 type 参数对应 glDrawElements.

'int32'GL_UNSIGNED_INT 之一:

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int32')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, None) 

'int8'GL_UNSIGNED_BYTE

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int8')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, None) 

当然 'int16'GL_UNSIGNED_SHORT 也可以:

indices = np.array([0, 1, 3, 1, 2, 3], dtype = 'int16')
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, None)