简体   繁体   中英

Vbo - drawing normals with obj file

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?

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:

  • Allocate big array[s] so it can hold all vertex data even without indices.
  • For each triangle, fetch data to new arrays using your independent indices. As the result, your vertices are now don't have independent attributes indices - but they don't have indices at all! You already could draw though - with DrawArrays().
  • If you want indices, now you can recreate them. Remove duplicates from new vertices arrays (duplicates have entire vertices equal, not only positions), and for each triangle find index of vertex in new array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM