在 OpenGL (OpenGL ES 2.0) 中,我可以为不同的 GL_ARRAY_BUFFER 缓冲区使用多个 GL_ELEMENT_ARRAY_BUFFER 吗?我正在阅读“OpenGL ES 2.0 编程指南”,第 6 章“顶点属性、数组和缓冲区对象”,有源示例:有几个 GL_ARRAY_BUFFER(用于位置、法线、纹理坐标)和一个 GL_ELEMENT_ARRAY_BUFFER(“用于存储元素索引”)。
当我写问题时,我知道我不能向 glDrawElements 发送一个以上的索引数组,所以如果我使用缓冲区,可能只有最后绑定的 GL_ELEMENT_ARRAY_BUFFER 用于绘图。但是节省内存呢(glDrawElements 的目的是什么)?我将说明我面临的问题。
有 2 个数组(作为 GL_ARRAY_BUFFER) - 8 个顶点和 6 个法线
GLfloat gVertexPositions[] =
{
0.5f, 0.5f, 0.5f,
0.5f, -0.5f, 0.5f,
-0.5f, -0.5f, 0.5f,
-0.5f, 0.5f, 0.5f,
0.5f, 0.5f, -0.5f,
0.5f, -0.5f, -0.5f,
-0.5f, -0.5f, -0.5f,
-0.5f, 0.5f, -0.5f
};
GLfloat gVertexNormals[] =
{
1.0f, 0.0f, 0.0f, // top
-1.0f, 0.0f, 0.0f, // bottom
0.0f, 1.0f, 0.0f, // right
0.0f, -1.0f, 0.0f, // left
0.0f, 0.0f, 1.0f, // back
0.0f, 0.0f, -1.0f // front
};
2 个索引数组(作为 GL_ELEMENT_ARRAY_BUFFERs)
GLubyte gVertexPositionIndices[] =
{
0, 1, 2, // top
2, 3, 0,
0, 4, 1, // right
1, 4, 5,
5, 4, 7, // bottom
6, 5, 7,
2, 6, 7, // left
2, 7, 3,
1, 4, 2, // front
2, 4, 5,
0, 3, 4, // back
7, 4, 3
};
GLubyte gVertexNormalIndices[] =
{
0, 0, 0,
0, 0, 0,
2, 2, 2,
2, 2, 2,
1, 1, 1,
1, 1, 1,
3, 3, 3,
3, 3, 3,
5, 5, 5,
5, 5, 5,
4, 4, 4,
4, 4, 4
};
我设置顶点属性状态
glBindAttribLocation(program, ATTRIB_POSITION, "a_position");
glBindAttribLocation(program, ATTRIB_NORMAL, "a_normal");
//.....
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[VBO_POSITION_INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 36, gVertexPositionIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[VBO_POSITION_DATA]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 8, gVertexPositions, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[VBO_NORMAL_INDICES]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLubyte) * 36, gVertexNormalIndices, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[VBO_NORMAL_DATA]);
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * 3 * 6, gVertexNormals, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[VBO_POSITION_INDICES]);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[VBO_POSITION_DATA]);
glEnableVertexAttribArray(ATTRIB_POSITION);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[VBO_NORMAL_DATA]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[VBO_NORMAL_INDICES]);
glEnableVertexAttribArray(ATTRIB_NORMAL);
glVertexAttribPointer(ATTRIB_POSITION, 3, GL_FLOAT, GL_FALSE, 0, 0);
glVertexAttribPointer(ATTRIB_NORMAL, 3, GL_FLOAT, GL_FALSE, 0, 0);
然后画
glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0);
并且屏幕是空的(因为最后一个 GL_ELEMENT_ARRAY_BUFFER 用于“a_position”属性,其中所有三元组都有相同的数字)
所有我想要的 - 程序制作 36 个顶点,使用 gVertexPositionIndices 从 gVertexPositions 设置它们的位置,使用 gVertexNormalIndices 从 gVertexNormals 设置它们的法线。我怀疑这是可能的,但我想确切地知道。如果这是不可能的,那么正确的方法是什么?我必须使用 8*3 浮点数作为位置,36 字节作为索引,36*3 浮点数作为法线吗?所以我只能为位置属性节省内存?