【问题标题】:OpenGL VBO VAO EBO can run without error but no graphicsOpenGL VBO VAO EBO 可以正常运行但没有图形
【发布时间】:2022-01-08 01:58:21
【问题描述】:

这是我的代码:

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(我的意思是没有新添加代码运行),它可以正常绘制。但我绑定后,不会出现任何图形。如何使它正常绘制? 我现在真的无话可说。拜托!拜托!拜托!拜托!拜托!拜托!

【问题讨论】:

    标签: python opengl pyopengl


    【解决方案1】:

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

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

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

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

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

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

    除此之外,您不能指定一个具有多个索引缓冲区的网格。见Why does OpenGL not support multiple index buffering?。您可以只指定 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()
    

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 1970-01-01
      • 2018-11-05
      • 2021-11-21
      • 1970-01-01
      • 2019-12-25
      • 2012-07-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多