1

I am having a little trouble getting my VBO to render normals correctly now that I am using indexing. I am pretty sure it is something wrong with my offset for the normal pointer, but the math seems to add up to me.

How I store the data:

struct MyVertex
{
    float x, y, z;        //Vertex
    float nx, ny, nz;     //Normal
};

Below is how I set up the VBO:

GLuint VertexVBOID, IndexVBOID;
glGenBuffers(1, &VertexVBOID);
glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
glBufferData(GL_ARRAY_BUFFER, sizeof(MyVertex)*NumOfV, &ModelV[0].x, GL_STATIC_DRAW);

glGenBuffers(1, &IndexVBOID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned int)*NumOfF*3, &ModelI[0], GL_STATIC_DRAW);

My render code:

if(UsingVBO == false)
{
    glRotatef(Timer.getElapsedTime().asSeconds() * 10, 0, 1, 0);
    glBegin(GL_TRIANGLES);
        for(int i = 0; i < NumOfF*3; i+=3)
        {
            glNormal3f(ModelV[ModelI[i]].nx, ModelV[ModelI[i]].ny, ModelV[ModelI[i]].nz);
            glVertex3f(ModelV[ModelI[i]].x, ModelV[ModelI[i]].y, ModelV[ModelI[i]].z);

            glNormal3f(ModelV[ModelI[i+1]].nx, ModelV[ModelI[i+1]].ny, ModelV[ModelI[i+1]].nz);
            glVertex3f(ModelV[ModelI[i+1]].x, ModelV[ModelI[i+1]].y, ModelV[ModelI[i+1]].z);

            glNormal3f(ModelV[ModelI[i+2]].nx, ModelV[ModelI[i+2]].ny, ModelV[ModelI[i+2]].nz);
            glVertex3f(ModelV[ModelI[i+2]].x, ModelV[ModelI[i+2]].y, ModelV[ModelI[i+2]].z);
        }
    glEnd();
}
else
{
    glRotatef(Timer.getElapsedTime().asSeconds() * 10, 0, 1, 0);

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);

    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);

    glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), 0);
    glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)(NumOfV*sizeof(float)));//Number of vertices times size of float
    glDrawElements(GL_TRIANGLES, NumOfF*3, GL_UNSIGNED_INT, 0);//number of indices

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
}

Rendering without VBO:

Pic1

Rendering with VBO:

Pic2

LucasS
  • 599
  • 1
  • 13
  • 23
  • possible duplicate of [Rendering meshes with multiple indices](http://stackoverflow.com/questions/11148567/rendering-meshes-with-multiple-indices) – Nicol Bolas Nov 16 '12 at 21:34
  • Isnt the point of indexing to reuse vertices though? Thats what I got from here: [link](http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-9-vbo-indexing/) - "In this tutorial, we introduce indexing, which enables to reuse the same vertex over and over again. This is done with an index buffer." – LucasS Nov 16 '12 at 21:51
  • A vertex is not a position. A vertex *contains* a position, but that's not all it is. It has normals, colors, texture coordinates, or whatever attributes you want. Sharing vertices is very possible, but *not* if you're rendering a faceted object. The way you're doing. You need per-vertex normals, not face normals. – Nicol Bolas Nov 16 '12 at 21:59
  • The normals are calculated to be vertex normals, not face normals. However, my non-VBO rendering code was rendering it in a normal-per-face fashion. I edited my post and fixed that. To sum up, there are the same amount of normals as vertices, with 1 normal to 1 vertex. – LucasS Nov 16 '12 at 22:14

1 Answers1

2
glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)(NumOfV*sizeof(float)));//Number of vertices times size of float

Your offset is wrong here. You're providing interleaved vertex data, so that the first three floats are your positions and the next three floats are the normals. Your base offset for normals is therefore 3 floats worth of bytes (to skip the position). NumOfV is the number of vertices in your entire model, not the number of floats for positions in your MyVertex data structure.

This is best done with the offsetof macro:

glVertexPointer(3, GL_FLOAT, sizeof(MyVertex), (void*)offsetof(MyVertex, x));
glNormalPointer(GL_FLOAT, sizeof(MyVertex), (void*)offsetof(MyVertex, nx));
Nicol Bolas
  • 378,677
  • 53
  • 635
  • 829