我有两种方法:
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);
}
1条答案
按热度按时间gc0ot86w1#
glBufferSubData
要求将GL_ARRAY_BUFFER
绑定到缓冲区。glBindBuffer(GL_ARRAY_BUFFER, 0);
将其绑定为空。假设这段代码中没有其他内容触及
GL_ARRAY_BUFFER
,注解该行将使其绑定到vbo
,这意味着glBufferSubData
调用知道要更新哪个缓冲区。最好是显式显示,并在接触之前绑定正确的缓冲区。在这种情况下,在
opengl_draw
内。如果您对所有这些感到困惑,请了解现代OpenGL也具有直接状态访问,这不需要单独的
glBindBuffer
: