多网格、多VBO、多VAO、OpenGL 4.1
我正在尝试使用OpenGL4.1绘制两个不同的网格。在任何给定的时间,只会绘制一个网格,我的目标是在它们之间切换。我将网格的顶点和索引数据存储在一个对象中,下面称为g_obj。因此,第一个网格的数据通过g_obj->顶点和g_obj->索引获得,第二个网格的数据通过g_obj->顶点和g_obj->索引获得 我可怕的想法是对每个网格使用不同的VBO和VAO。然后在draw调用中,我只需绑定适当的VAO,然后执行glDraw*。但是,我的代码在第一次draw调用时出错,请参见下文多网格、多VBO、多VAO、OpenGL 4.1,opengl,Opengl,我正在尝试使用OpenGL4.1绘制两个不同的网格。在任何给定的时间,只会绘制一个网格,我的目标是在它们之间切换。我将网格的顶点和索引数据存储在一个对象中,下面称为g_obj。因此,第一个网格的数据通过g_obj->顶点和g_obj->索引获得,第二个网格的数据通过g_obj->顶点和g_obj->索引获得 我可怕的想法是对每个网格使用不同的VBO和VAO。然后在draw调用中,我只需绑定适当的VAO,然后执行glDraw*。但是,我的代码在第一次draw调用时出错,请参见下文 enum VAO
enum VAO_ID
{
VAO,
VAO_LINEAR,
NUM_VAOS
};
enum BUFFER_ID
{
VERTEX_BUFFER,
VERTEX_BUFFER_LINEAR,
INDEX_BUFFER,
INDEX_BUFFER_LINEAR,
NUM_BUFFERS
};
enum ATTRIBUTE_ID
{
VERTEX_POSITION,
VERTEX_COLOR
};
GLuint g_vaos[NUM_VAOS];
GLuint g_buffers[NUM_BUFFERS];
接下来,我创建顶点/索引缓冲区和顶点数组对象:
void bufferGeometry()
{
// create vertex buffers and vertex array object
glGenVertexArrays(NUM_VAOS, g_vaos);
glGenBuffers(NUM_BUFFERS, g_buffers);
// rotational grating
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_ * sizeof(vertex2D),
g_obj->vertices_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_ * sizeof(GLushort),
g_obj->indices_,
GL_STATIC_DRAW);
glBindVertexArray(g_vaos[VAO]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
// linear grating
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_linear_ * sizeof(vertex2D),
g_obj->vertices_linear_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_linear_ * sizeof(GLushort),
g_obj->indices_linear_,
GL_STATIC_DRAW);
glBindVertexArray(g_vaos[VAO_LINEAR]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
}
然后,这里是抽签通知:
glBindVertexArray(g_vaos[VAO]);
g_obj = &g_grating_uno;
glUseProgram(g_program);
glUniform3fv(g_trans_scale_location, 1, g_obj->trans_scale_);
glDrawElements(GL_TRIANGLES, g_obj->num_indices_,
GL_UNSIGNED_SHORT, (const GLvoid *)0);
在GLD元件线路上出现故障
我知道一般的性能策略是将来自两个网格的数据打包到单个VBO中,由于两个网格之间的数据格式相同,因此我只需要一个VAO。但是,由于我懒惰,我想知道是否有人能理解为什么我现有的策略不起作用或不起作用,或者你是否认为问题出在别处。我猜这和我的几何函数有关。我对VAO与特定VBO(如果有的话)之间的联系的理解有点薄弱。谢谢,很抱歉我这么笨 啊,我想通过在绑定VBO之前绑定VAO来修复它:
void bufferGeometry()
{
// create vertex buffers and vertex array object
glGenVertexArrays(NUM_VAOS, g_vaos);
glGenBuffers(NUM_BUFFERS, g_buffers);
// rotational grating
glBindVertexArray(g_vaos[VAO]);
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_ * sizeof(vertex2D),
g_obj->vertices_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_ * sizeof(GLushort),
g_obj->indices_,
GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
// linear grating
glBindVertexArray(g_vaos[VAO_LINEAR]);
glBindBuffer(GL_ARRAY_BUFFER, g_buffers[VERTEX_BUFFER_LINEAR]);
glBufferData(GL_ARRAY_BUFFER,
g_obj->num_vertices_linear_ * sizeof(vertex2D),
g_obj->vertices_linear_,
GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER_LINEAR]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
g_obj->num_indices_linear_ * sizeof(GLushort),
g_obj->indices_linear_,
GL_STATIC_DRAW);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindVertexArray(0);
}
您应该重复调用以在glBindVertexArray之间绑定元素缓冲区:
glBindVertexArray(g_vaos[VAO]);
glEnableVertexAttribArray(VERTEX_POSITION);
glVertexAttribPointer(VERTEX_POSITION, 2, GL_FLOAT, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, position));
glEnableVertexAttribArray(VERTEX_COLOR);
glVertexAttribPointer(VERTEX_COLOR, 4, GL_UNSIGNED_BYTE, GL_FALSE,
sizeof(vertex2D),
(const GLvoid *)offsetof(vertex2D, color));
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, g_buffers[INDEX_BUFFER]);
glBindVertexArray(0);
元素缓冲区绑定是VAO状态的一部分,在绑定新VAO时会重置。Ah,好的,我也会尝试。谢谢