VBO必须在VAO之后绑定
Posted
技术标签:
【中文标题】VBO必须在VAO之后绑定【英文标题】:VBO must be bound after VAO 【发布时间】:2018-09-09 13:53:09 【问题描述】:代码:
void render()
glClear(GL_COLOR_BUFFER_BIT);
GLfloat vertices[6][4] =
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f
;
glUseProgram(shadptr->progGraphics);
glBindVertexArray(vao_g);
glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLES, 0, 6);
glUseProgram(shadptr->progText);
glBindVertexArray(vao_t);
glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(winptr->window);
void set_buffers()
glGenVertexArrays(1, &vao_g);
glBindVertexArray(vao_g);
glGenBuffers(1, &vbo_g);
glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
glGenVertexArrays(1, &vao_t);
glBindVertexArray(vao_t);
glGenBuffers(1, &vbo_t);
glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr);
我有问题。不知道为什么在render函数中绑定vao后还要绑定vbo。当我不绑定 vbo 时,在 RenderDoc 中出现错误“glDrawArrays 已生成错误 (GL_OUT_OF_MEMORY)”,在网格输出中,在 VS 输入中我看到错误的值或 --- 值。
【问题讨论】:
“我不知道为什么我必须在渲染函数中绑定 vao 后绑定 vbo” - 因为您尝试通过以下方式创建和初始化缓冲区对象的数据存储glBufferData
,为此必须绑定缓冲区。将此代码移至set_buffers
,即可绑定顶点数组对象。
@Rabbid76 这可能应该作为答案而不是评论发布。
【参考方案1】:
不知道为什么在render函数中绑定vao后还要绑定vbo"
因为您尝试通过glBufferData
创建和初始化缓冲区对象的数据存储,因此必须绑定缓冲区。
我建议移动代码,它将创建缓冲区并将其初始化为set_buffers
。那么只绑定顶点数组对象就足够了,在函数render
中:
void render()
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shadptr->progGraphics);
glBindVertexArray(vao_g);
glDrawArrays(GL_TRIANGLES, 0, 6);
glUseProgram(shadptr->progText);
glBindVertexArray(vao_t);
glDrawArrays(GL_TRIANGLES, 0, 6);
SDL_GL_SwapWindow(winptr->window);
void set_buffers()
....
GLfloat vertices[6][4] =
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f ,
1.0f, 1.0f, 1.0f, 1.0f
;
glBindBuffer(GL_ARRAY_BUFFER, vbo_g);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vbo_t);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * 6 * 4, vertices, GL_DYNAMIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, 0);
我建议使用glBufferSubData
来更改缓冲区的内容。这将更新缓冲区,但不会创建和初始化全新的数据存储,因此效率会更高。
【讨论】:
以上是关于VBO必须在VAO之后绑定的主要内容,如果未能解决你的问题,请参考以下文章