繁体   English   中英

OpenGL 无法使用 VAO 程序更新顶点缓冲区

[英]OpenGL can't update vertex buffer with VAO procedure

我试图通过修改它的位置顶点属性来移动一个顶点。 作为测试,我添加了行vertices[0] = 0.4f; 在创建我的 VAO 程序之前和之后,查看我是否能够在初始渲染后修改顶点数组。 当我在创建 VAO 之前添加它时,它会修改顶点的位置,而在之后添加它时不会。 这让我相信我的渲染过程:

glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

glfwSwapBuffers(window);
glfwPollEvents();

不知何故,实际上并没有用 memory 中的当前float[]更新缓冲区。 但是,我可以替换行glBindVertexArray(VAO); 整个渲染过程:

    // 2. copy our vertices array in a buffer for OpenGL to use
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    // 2. copy our vertex indices in a buffer for OpenGL to use
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);
    // 3. then set our vertex attributes pointers:
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0); // Pos vec3
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3* sizeof(float))); // Col vec4
    glEnableVertexAttribArray(1);

以此作为我的渲染过程,我可以更新顶点数组,并将此更改传递到 GPU,更新屏幕上顶点的 position。 这是我的 VAO 创建代码:

    // Generate a Vertex Array Object to store our rendering procedure.
    unsigned int VAO;
    glGenVertexArrays(1, &VAO);
    // 1. bind Vertex Array Object, Element Buffer Object
    glBindVertexArray(VAO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    // 2. copy our vertices array in a buffer for OpenGL to use
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
    // 2. copy our vertex indices in a buffer for OpenGL to use
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(indices), indices);
    // 3. then set our vertex attributes pointers:
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)0); // Pos vec3
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, 7 * sizeof(float), (void*)(3* sizeof(float))); // Col vec4
    glEnableVertexAttribArray(1);

所以当我明确表达渲染过程时它可以工作,但当我将它存储在 VAO 中时它不起作用? 据我了解,VAO 是用于存储渲染过程的构造,然后当我们运行glBindVertexArray(VAO); ,执行此渲染过程。 我理解错了吗? 在创建 VAO 或渲染时是否需要另一条线?

这是 C++ 中的完整源代码: https://pastebin.com/DgZuZt4K

和用 OpenTK 写的一样,C#: https://pastebin.com/DHj9UN16

[...] 据我了解,VAO 是一种用于存储渲染过程的构造,[...]

不它不是。 顶点数组 Object存储状态。

glBufferData / glBufferSubData时,缓冲区对象的数据存储被初始化,分别更新。

当调用glVertexAttribPointer时,状态会在 VAO 的 state 向量中设置。 当前绑定到目标GL_ARRAY_BUFFER的缓冲区 object 与当前绑定的 VAO 中的指定顶点属性相关联。
VAO 存储有关如何解释每个属性的顶点信息和 VBO 的 id 的信息。

但是VAO不存储过程甚至进程。 更改顶点后,您必须通过glBufferSubData或缓冲区映射更新顶点缓冲区 Object

相关: 修改 OpenGL 顶点缓冲区的正确方法是什么?


如果要指定并启用顶点属性( glVertexAttribPointer / glEnableVertexAttribArray ),则必须绑定 VAO 和 VBO。 VAO 存储规范,VBO 的 id 存储在 VAO 中。

如果要更新顶点坐标和属性(例如glBufferSubData ),则必须绑定 VBO。

如果你想绘制网格(例如glDrawArrays ),那么绑定 VAO 就足够了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM