OpenGL VBO VAO EBO 可以 运行 没有错误但没有图形

OpenGL VBO VAO EBO can run without error but no graphics

这是我的代码:

block_VAO=0
draw=False
block_EBO_buffer_len=0
def print_blocks(x:int,y:int,z:int):
    global draw,block_VAO,block_EBO_buffer_len
    if not draw:
        block_point_buffer=[]
        block_color_buffer=[]
        block_EBO_buffer=[]
        block_point_buffer+=[x-0.5,y+0.5,z-0.5,#V0
                            x+0.5,y+0.5,z-0.5,#V1
                            x+0.5,y-0.5,z-0.5,#V2
                            x-0.5,y-0.5,z-0.5,#V3
                            x-0.5,y+0.5,z+0.5,#V4
                            x+0.5,y+0.5,z+0.5,#V5
                            x+0.5,y-0.5,z+0.5,#V6
                            x-0.5,y-0.5,z+0.5]#V7
        block_EBO_buffer+=[0,1,5,4,
                          3,2,6,7,
                          0,3,7,4,
                          1,2,6,5,
                          0,1,2,3,
                          4,5,6,7]

        #ADD
        block_color_buffer+=[1.0,0.0,1.0,1.0]*24
        color_EBO_buffer+=[0]*24
        #ADD END

        block_VBO=glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
        a=numpy.array(block_point_buffer,dtype='float32')
        glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)

        block_EBO=glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
        a=numpy.array(block_EBO_buffer,dtype='uint32')
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
        block_EBO_buffer_len=len(a)

        #ADD
        color_VBO=glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
        a=numpy.array(block_color_buffer,dtype='uint32')
        glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)

        color_EBO=glGenBuffers(1)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,color_EBO)
        a=numpy.array(color_EBO_buffer,dtype='uint32')
        glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
        #ADD END

        block_VAO=glGenVertexArrays(1)
        glBindVertexArray(block_VAO)
        glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
        glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
        glVertexPointer(3,GL_FLOAT,0,None)
        glEnableClientState(GL_VERTEX_ARRAY)
        
        #ADD
        glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
        glColorPointer(4,GL_FLOAT,0,None)
        glEnableClientState(GL_COLOR_ARRAY)
        #ADD END
        glBindVertexArray(0)
        draw=True
    glBindVertexArray(block_VAO)
    glDrawElements(GL_QUADS,block_EBO_buffer_len,GL_UNSIGNED_INT,None)
    glBindVertexArray(0)

函数print_blocks在主循环中。如果我不绑定颜色到 VAO(我的意思是 运行 没有新的添加代码),它可以在我绑定后绘制 normally.But,没有图形 appear.How 我可以做它吗正常画? 我真的无话可说now.Please!拜托!拜托!拜托!拜托!拜托!

Index Buffer (ELEMENT_ARRAY_BUFFER) binding is stored within the Vertex Array Object。当调用 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO) 时,元素缓冲区对象 ID 存储在当前绑定的顶点数组对象中。因此 VAO 必须在元素缓冲区之前绑定 glBindVertexArray(VAO).

Index Buffer, the Vertex Buffer 绑定 (ARRAY_BUFFER) 相比,它是一个全局状态。
VAOs 状态向量中声明的每个属性可能引用不同的 ARRAY_BUFFER。当调用 glVertexAttribPointer 时,当前绑定到目标 ARRAY_BUFFER 的缓冲区与指定的属性索引相关联,对象的 ID 存储在当前绑定的 VAO 的状态向量中。

因此在绑定和创建元素缓冲区之前需要绑定 VAO。

另外颜色属性的类型需要是浮点数:

a=numpy.array(block_color_buffer,dtype='uint32')

a=numpy.array(block_color_buffer,dtype='float32')

除此之外,您不能指定一个网格具有多个索引缓冲区。参见 。您可以只指定 1 个索引数组。

基于您的原始代码的最小示例:

from OpenGL.GLUT import *
from OpenGL.GLU import *
from OpenGL.GL import *
import numpy

rotate = [33, 40, 20]

block_VAO=0
draw=False
block_EBO_buffer_len=0
def create_blocks(x:int, y:int, z:int):
    global draw, block_VAO, block_EBO_buffer_len
    if draw:
        return
    draw = True    
    block_point_buffer=[]
    block_color_buffer=[]
    block_EBO_buffer=[]
    block_point_buffer+=[x-0.5,y+0.5,z-0.5,#V0
                        x+0.5,y+0.5,z-0.5,#V1
                        x+0.5,y-0.5,z-0.5,#V2
                        x-0.5,y-0.5,z-0.5,#V3
                        x-0.5,y+0.5,z+0.5,#V4
                        x+0.5,y+0.5,z+0.5,#V5
                        x+0.5,y-0.5,z+0.5,#V6
                        x-0.5,y-0.5,z+0.5]#V7
    block_EBO_buffer+=[0,1,5,4,
                        3,2,6,7,
                        0,3,7,4,
                        1,2,6,5,
                        0,1,2,3,
                        4,5,6,7]

    block_color_buffer+=[1.0,0.0,1.0,1.0]*8

    block_VBO=glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
    a=numpy.array(block_point_buffer,dtype='float32')
    glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)

    color_VBO=glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
    a=numpy.array(block_color_buffer,dtype='float32')
    glBufferData(GL_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)

    block_VAO=glGenVertexArrays(1)
    glBindVertexArray(block_VAO)

    block_EBO=glGenBuffers(1)
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,block_EBO)
    a=numpy.array(block_EBO_buffer,dtype='uint32')
    glBufferData(GL_ELEMENT_ARRAY_BUFFER,sys.getsizeof(a),a,GL_STATIC_DRAW)
    block_EBO_buffer_len=len(a)

    glBindBuffer(GL_ARRAY_BUFFER,block_VBO)
    glVertexPointer(3,GL_FLOAT,0,None)
    glEnableClientState(GL_VERTEX_ARRAY)

    glBindBuffer(GL_ARRAY_BUFFER,color_VBO)
    glColorPointer(4,GL_FLOAT,0,None)
    glEnableClientState(GL_COLOR_ARRAY)

    glBindVertexArray(0)

def display():
    glMatrixMode(GL_MODELVIEW)
    glClear(GL_COLOR_BUFFER_BIT)
    glLoadIdentity()
    glTranslatef(0, 0, -4.5)
    glRotatef(rotate[0], 1, 0.0, 0)
    glRotatef(rotate[1], 0, 1, 0)
    glRotatef(rotate[2], 0, 0, 1)
    glScalef(1, 1, 1)

    glBindVertexArray(block_VAO)
    glDrawElements(GL_QUADS,block_EBO_buffer_len,GL_UNSIGNED_INT,None)
    glBindVertexArray(0)
    rotate[1] += 0.1
    
    glutSwapBuffers()
    glutPostRedisplay()

def reshape(width, height):
    glViewport(0, 0, width, height)
    glMatrixMode(GL_PROJECTION)
    glLoadIdentity()
    gluPerspective(40.0, width / height, 0.5, 20.0)
    glMatrixMode(GL_MODELVIEW)

glutInit(sys.argv)
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB)
glutInitWindowSize(400, 350)
glutCreateWindow(b"OpenGL Window")
create_blocks(0, 0, 0)
glClearColor(0.0, 0.0, 0.0, 0.0)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
glutDisplayFunc(display)
glutReshapeFunc(reshape)
glutMainLoop()