GlBufferSubData()和glBindArray()

sqxo8psd  于 2022-09-26  发布在  其他
关注(0)|答案(1)|浏览(141)

我有两种方法:

1.opengl_init()
1.opengl_draw()

在第一个例子中,我初始化了一个空的GL_ARRAY_BUFFER,因为我想要在每一帧中更新点坐标。

如果在opengl_draw()方法中,我将//glBindBuffer(GL_ARRAY_BUFFER, 0)注解掉,则一切正常

通常,当我在opengl_init()方法的最后一行静态绘制元素时,我会使用此函数。

问题:

你能解释为什么注解掉glBindBuffer()函数的位置每帧都更新,如果我使用glBindBuffer()函数对象是静态绘制的(不改变y坐标),即使我每帧在While循环中使用glBufferSubData()也是如此?

我也不明白为什么我需要在opengl_init()方法的最后一行编写glBindVertex数组(0);。我使用了learnopengl教程中的这句话。

我的工作代码:

void opengl_init()
    {
        //vertex array
        glGenVertexArrays(1, &vao);
        glBindVertexArray(vao);

        //vertex buffer
        glGenBuffers(1, &vbo);
        glBindBuffer(GL_ARRAY_BUFFER, vbo);
        //-> keep this function NULL to dynamically draw vertices glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertex), &vertices[0], GL_STATIC_DRAW); // target | size | data (poinnting to first element e.g. glm::value_ptr(vertices[0])) | usage
        glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(vertex), NULL, GL_STATIC_DRAW);

        //set attributes that corresponds to layout id in the vertex shader
        // set the vertex attribute pointers
        // vertex Positions
        glEnableVertexAttribArray(0);
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)0);
        // vertex normals
        glEnableVertexAttribArray(1);
        glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), (void*)offsetof(vertex, color));

        //bind buffers vao | vbo | ibo
        glBindVertexArray(0);
        //glBindBuffer(GL_ARRAY_BUFFER, 0);
    }

    // render the mesh
    void opengl_draw(opengl_shaders::shader& shader)
    {
        for (auto& v : vertices)
            v.position.y += 0.001;
        glBufferSubData(GL_ARRAY_BUFFER, 0, vertices.size() * sizeof(vertex), &vertices[0]);
        glBindBuffer(GL_ARRAY_BUFFER, 0);

        glBindVertexArray(vao);
        glDrawArrays(GL_POINTS, 0, vertices.size());
        glBindVertexArray(0);
    }
gc0ot86w

gc0ot86w1#

glBufferSubData要求将GL_ARRAY_BUFFER绑定到缓冲区。glBindBuffer(GL_ARRAY_BUFFER, 0);将其绑定为空。

假设这段代码中没有其他内容触及GL_ARRAY_BUFFER,注解该行将使其绑定到vbo,这意味着glBufferSubData调用知道要更新哪个缓冲区。

最好是显式显示,并在接触之前绑定正确的缓冲区。在这种情况下,在opengl_draw内。

如果您对所有这些感到困惑,请了解现代OpenGL也具有直接状态访问,这不需要单独的glBindBuffer

// Note we pass vbo directly instead of GL_ARRAY_BUFFER
glNamedBufferSubData(vbo, 0, vertices.size() * sizeof(vertex), &vertices[0]);

相关问题