我有一个带有着色器的 OpenGL 应用程序,可以渲染带有纹理的对象。
当我创建具有“交错”属性的简单矩形时,如下所示:
GLuint createRectInterleaved(float fW, float fH) {
GLuint vao;
GLuint rect_buffer;
float vertex_data[] = {
// position normal texture coords
-fW/2, -fH/2, 0, 0, 0, 1, 0, 0,
fW/2, -fH/2, 0, 0, 0, 1, 1, 0,
fW/2, fH/2, 0, 0, 0, 1, 1, 1,
-fW/2, -fH/2, 0, 0, 0, 1, 0, 0,
fW/2, fH/2, 0, 0, 0, 1, 1, 1,
-fW/2, fH/2, 0, 0, 0, 1, 0, 1};
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(1, &rect_buffer);
glBindBuffer(GL_ARRAY_BUFFER, rect_buffer);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_data),
vertex_data,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) 0);
glEnableVertexAttribArray(0);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (3*sizeof(float)));
glEnableVertexAttribArray(1);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*) (6*sizeof(float)));
glEnableVertexAttribArray(2);
return vao;
}
然后应用程序工作,正方形按预期使用其纹理进行渲染。
但是如果我使用顶点属性的顺序排列:
GLuint createRectSequential(float fW, float fH) {
GLuint vao;
GLuint rect_buffers[3];
float vertex_positions[18] = {
-fW/2, -fH/2, 0,
fW/2, -fH/2, 0,
fW/2, fH/2, 0,
-fW/2, -fH/2, 0,
fW/2, fH/2, 0,
-fW/2, fH/2, 0};
float vertex_normals[18] = {
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1,
0, 0, 1};
float vertex_tc[12] = {
0, 0,
1, 0,
1, 1,
0, 0,
1, 1,
0, 1};
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
glGenBuffers(3, rect_buffers);
glBindBuffer(GL_ARRAY_BUFFER, rect_buffers[0]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_positions),
vertex_positions,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, rect_buffers[1]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_normals),
vertex_normals,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER, rect_buffers[2]);
glBufferData(GL_ARRAY_BUFFER,
sizeof(vertex_tc),
vertex_tc,
GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, (void*) 0);
glEnableVertexAttribArray(2);
return vao;
}
然后我的应用程序在调用中崩溃
glDrawArrays(GL_TRIANGLES, 0, 6);
两个 VAO 的处理方式完全相同 - 唯一的区别是 glBindVertexArray() 在绘制之前的参数:交错或顺序 VAO。
如果我注释掉纹理属性的创建,则顺序 VAO 不会导致崩溃。
我在“顺序”版本中做错了什么?
(编辑:拼写错误)