【问题标题】:PyOpenGL not drawing big VAOPyOpenGL 没有画大 VAO
【发布时间】:2020-09-09 11:34:34
【问题描述】:

我想渲染一个由许多立方体组成的大场景。我的第一个想法是创建一个单一的立方体 VBO,然后使用统一的模型矩阵多次绘制它来翻译它。这很慢,因为我每帧多次调用glDrawArrays

所以我决定改用一个巨大的 VBO,它带有每个立方体顶点和一个额外的平移向量。基本上,我把我的旧通用立方体 VBO 加上平移向量,并将该列表附加到我想要绘制的每个立方体的 VBO 列表中。然后我绑定一个 VAO 并绘制它。我还更改了我的顶点着色器,使其接受该平移向量作为顶点属性,并在着色器内生成一个模型矩阵。

现在,这不会返回任何错误,这很好,但它实际上并没有绘制任何东西,这不是很好,即使该过程与我之前所做的非常相似。

这里有一些代码:

  • Whopper VBO 创建者:

    class render:
        def __init__(self, coords_list):
    
            self.render_list = []
            for i in coords_list:
                self.render_list.append([
                    # Cube model       Texture     Translation
                    0.0,  0.0,  0.0,  1.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  1.0,  0.0,  0.0, 0.0, i[0], i[1], i[2],
                    1.0,  1.0,  0.0,  0.0, 0.0, i[0], i[1], i[2],
                    0.0,  1.0,  0.0,  1.0, 0.0, i[0], i[1], i[2],
                    0.0,  0.0,  0.0,  1.0, 1.0, i[0], i[1], i[2],
    
                    0.0,  0.0,  1.0,  1.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  1.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  1.0,  1.0,  0.0, 0.0, i[0], i[1], i[2],
                    1.0,  1.0,  1.0,  0.0, 0.0, i[0], i[1], i[2],
                    0.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    0.0,  0.0,  1.0,  1.0, 1.0, i[0], i[1], i[2],
    
                    0.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    0.0,  1.0,  0.0,  0.0, 0.0, i[0], i[1], i[2],
                    0.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    0.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    0.0,  0.0,  1.0,  1.0, 1.0, i[0], i[1], i[2],
                    0.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
    
                    1.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    1.0,  1.0,  0.0,  0.0, 0.0, i[0], i[1], i[2],
                    1.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  1.0,  1.0, 1.0, i[0], i[1], i[2],
                    1.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
    
                    0.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  0.0,  1.0, 1.0, i[0], i[1], i[2],
                    1.0,  0.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    1.0,  0.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    0.0,  0.0,  1.0,  0.0, 0.0, i[0], i[1], i[2],
                    0.0,  0.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
    
                    0.0,  1.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                    1.0,  1.0,  0.0,  1.0, 1.0, i[0], i[1], i[2],
                    1.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    1.0,  1.0,  1.0,  1.0, 0.0, i[0], i[1], i[2],
                    0.0,  1.0,  1.0,  0.0, 0.0, i[0], i[1], i[2],
                    0.0,  1.0,  0.0,  0.0, 1.0, i[0], i[1], i[2],
                ])
                print('Cube added!')
    
        def create_buffers(self):
            render_vbo, self.render_vao = glGenBuffers(1), glGenVertexArrays(1)
            glBindVertexArray(self.render_vao)
            glBindBuffer(GL_ARRAY_BUFFER, render_vbo)
            glBufferData(GL_ARRAY_BUFFER, np.array(self.render_list), GL_STATIC_DRAW)
    
            glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(0))
            glEnableVertexAttribArray(0)
            glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(12))
            glEnableVertexAttribArray(1)
            glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 32, ctypes.c_void_p(20))
            glEnableVertexAttribArray(2)
    
        def draw_buffer(self, program, texture):
            program.use()
            glBindTexture(GL_TEXTURE_2D, texture)
            glBindVertexArray(self.render_vao)
            glDrawArrays(GL_TRIANGLES, 0, int(len(self.render_list)/8))
    
  • 初始化和渲染循环:

    def main():
    
        global delta_time, last_frame
    
        test_chunk = chunk.chunk((0,0,0)) #Creates a 16x16x16 cube of cubes
        test_chunk.fill_layers(0, 16, 1)  #Works fine
    
        window = utilities.window()
        camera.setup_window(window)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
    
        shader_program = utilities.shader(vertex_source_3d, fragment_source_3d, '330')
        shader_program.compile()
    
        #Check which cubes are exposed and should be rendered
        #Works fine
        exposed_list = [i for i, blocktype in np.ndenumerate(test_chunk.data) if test_chunk.return_if_exposed(i) == True and blocktype != 0]
    
        shader_program.use()
        shader_program.set_int('texture0', 0)
    
        camera_direction = glm.vec3()
        yaw = -90.0
        second_counter = 0
        frame_counter = 0
    
        render = cube.render(exposed_list)
        render.create_buffers()
    
        while not window.check_if_closed():
    
            current_frame = glfw.get_time()
            delta_time = current_frame - last_frame
            last_frame = current_frame
            second_counter += delta_time
            frame_counter += 1
    
            window.refresh(0)
    
            camera.process_input(window, delta_time)
            camera.testing_commands(window)
    
            glActiveTexture(GL_TEXTURE0)
    
            shader_program.use()
    
            pos, looking, up = camera.return_vectors()
            view = glm.lookAt(pos, looking, up)
            projection = glm.perspective(glm.radians(45), window.size[0]/window.size[1], 0.1, 100)
            shader_program.set_mat4('view', glm.value_ptr(view))
            shader_program.set_mat4('projection', glm.value_ptr(projection))
    
            render.draw_buffer(shader_program, cobble_tex_ID)
    
            glBindVertexArray(0)
    
            if second_counter >= 1:
                print(frame_counter)
                second_counter, frame_counter = 0, 0
    
            window.refresh(1)
    
        window.close()
    
    if __name__ == '__main__':
        main()
    
  • 顶点着色器:

    #version %s core
    
    layout (location = 0) in vec3 aPos;
    layout (location = 1) in vec2 aTexCoord;
    layout (location = 2) in vec3 cube_coord;
    
    out vec2 TexCoord;
    
    uniform mat4 view;
    uniform mat4 projection;
    
    mat4 model = mat4(1.0);
    
    void main() {
        model[0].w = cube_coord.x;
        model[1].w = cube_coord.y;
        model[2].w = cube_coord.z;
        gl_Position = projection * view * model * vec4(aPos, 1.0);
        TexCoord = aTexCoord;
    }
    
  • 片段着色器:

    version %s core
    
    out vec4 FragColor;
    in vec2 TexCoord;
    
    uniform sampler2D texture0;
    
    void main()
    {
        FragColor = texture(texture0, TexCoord);
    }
    

【问题讨论】:

    标签: python opengl glsl vbo pyopengl


    【解决方案1】:

    将平移分配给模型矩阵是错误的。 glsl 矩阵按列主要顺序存储。翻译是第 4 列。一个典型的模型矩阵如下所示:

    mat4 m44 = mat4(
        vec4( Xx, Xy, Xz, 0.0),
        vec4( Yx, Xy, Yz, 0.0),
        vec4( Zx  Zy  Zz, 0.0),
        vec4( Tx, Ty, Tz, 1.0) );
    

    你必须改变模型矩阵初始化:

    mat4 model = mat4(1.0);
    
    void main() {
        model[3] = vec4(cube_coord.xyz, 1.0);
    
        // [...]
    }
    

    此外,您还必须为numpy.array (numpy.float32) 指定数据类型:

    glBufferData(GL_ARRAY_BUFFER, np.array(self.render_list), GL_STATIC_DRAW)

    glBufferData(GL_ARRAY_BUFFER, np.array(self.render_list, np.float32), GL_STATIC_DRAW)
    

    顶点数组是二维的,因此len(self.render_list)/8不是顶点数:

    glDrawArrays(GL_TRIANGLES, 0, int(len(self.render_list)/8))

    no_of_verices = len(self.render_list) * 36
    glDrawArrays(GL_TRIANGLES, 0, no_of_verices)
    

    分别

    no_of_verices = len(self.render_list) * len(self.render_list[0]) // 8
    glDrawArrays(GL_TRIANGLES, 0, no_of_verices)
    

    【讨论】:

    • 这确实画了一些东西,但是形状完全被破坏了,并且没有应用纹理,而是在一些三角形上只有原始纹理的随机颜色条纹。此外,事物只能从一定数量的立方体坐标开始绘制。
    • @Parashoo 我已经扩展了答案。
    猜你喜欢
    • 2021-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-05
    相关资源
    最近更新 更多