Reputation: 524
On general my question is how can I provide 2 indices for the vbo. One for the vertices and one for the normals? I got the next Obj file:
mtllib cube.mtl
v 1.000000 -1.000000 -1.000000
v 1.000000 -1.000000 1.000000
v -1.000000 -1.000000 1.000000
v -1.000000 -1.000000 -1.000000
v 1.000000 1.000000 -0.999999
v 0.999999 1.000000 1.000001
v -1.000000 1.000000 1.000000
v -1.000000 1.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 0.000000 1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -0.000000 -0.000000 1.000000
vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000
usemtl Material
f 1//1 2//1 3//1 4//1
f 5//2 8//2 7//2 6//2
f 1//3 5//3 6//3 2//3
f 2//4 6//4 7//4 3//4
f 3//5 7//5 8//5 4//5
f 5//6 1//6 4//6 8//6
As you can see there are 8 vertices and 6 normals. On the faces lines the file connects each vertex to the next vertex by indices and connects the normals too by different indices.
I am trying to draw with cube model with vbo. I have written the following code:
float vertex[] = {1, -1, -1,
1, -1, 1,
-1, -1, 1,
-1, -1, -1,
1, 1, -1,
1, 1, 1,
-1, 1, 1,
-1, 1, -1};
float normals[] = {0, -1, 0,
0, 1, 0,
1, 0, 0,
0, 0, 1,
-1, 0, 0,
0, 0, -1};
int index[] = {0, 1, 2, 3,
4, 7, 6, 5,
0, 4, 5, 1,
1, 5, 6, 2,
2, 6, 7, 3,
4, 0, 3, 8};
GLuint buffer, ind;
int offset = 0;
void vboInit()
{
glGenBuffers(1, &buffer);
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertex) + sizeof(normals), 0, GL_STATIC_DRAW);
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(vertex), vertex); offset+= sizeof(vertex);
glBufferSubData(GL_ARRAY_BUFFER, offset, sizeof(normals), normals); offset+= sizeof(normals);
glGenBuffers(1, &ind);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(index), index, GL_STATIC_DRAW);
}
void vboDraw()
{
glBindBuffer(GL_ARRAY_BUFFER, buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ind);
glNormalPointer(GL_FLOAT, 0, (GLvoid*)(sizeof(vertex)));
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
for (int i = 0; i < 6; i++)
glDrawElements(GL_TRIANGLE_FAN, 4 + i*4, GL_UNSIGNED_INT, (GLvoid*)(i*4));
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, NULL);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, NULL);
}
This code uses the indices of the vertices for the normals. Therefore the normals does not loading well and I need different indices to the normals. The question is how can I provide 2 indices for the vbo. One for the vertices and one for the normals?
Upvotes: 2
Views: 849
Reputation: 18399
Short answer it that you can't. But if you want long one:
DrawElements takes indices arrays of vertices. Vertex is not a position; it is assembly of all attributes at once. When you fetching vertex by index, you must take it from the very same index from every attribute array. Good side of indices is that they enables usage of post-TNL cache (however, utilisation of cache depends upon actual indices values) and reduces memory usage.
If your data saved in OBJ-like layout where attribute arrays indexed in independent way, you have to convert your arrays to more friendly representation. Simple approach would be:
Upvotes: 0