PDA

View Full Version : Interleaved VBO question



Lefteris
11-22-2010, 09:04 PM
Hello all,

I have trouble understanding some things about interleaving per vertex information in one VBO. Initially I tried it with my .3ds models but it was too complicated to debug so I went with the old trusty cube.

I have a reduced example of a cube which worked if I only had vertices coordinates in the array. When I added "dummy normals" to see if it would render correctly, it did not. Well here is some code.





/**--All the VBO initializations--**/
//Generate buffer object identifiers, this creates the buffer object
glGenBuffers(BUFFER_OBJECTS_NUM, getVboID());

//Bind the first buffer saying it will be used for vertices (GL_ARRAY_BUFFER), also states which VBO is active atm
glBindBuffer(GL_ARRAY_BUFFER,getVboID()[VERTICES_BUFFER_OBJECT ]);
//pointer is NULL, which means we want GL to allocate memory but not initialize it.
glBufferData(GL_ARRAY_BUFFER, VERTEX_BUFFER_SIZE, NULL, GL_STATIC_DRAW);


//If not using shaders (since this is just an example)
//specifying how our data must be read from the VBO

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), BUFFER_OFFSET(0));
glNormalPointer(GL_FLOAT,sizeof(Vertex), BUFFER_OFFSET(12));

//Bind the second buffer saying it will be used for indices (GL_ELEMENT_BUFFER)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getVboID()[INDICES_BUFFER_OBJECT]);
//pointer is NULL, which means we want GL to allocate memory but not initialize it.
glBufferData(GL_ELEMENT_ARRAY_BUFFER, INDICES_BUFFER_SIZE, NULL, GL_STATIC_DRAW);


Okay, this was the part of the code which initialized the VBOs. Did you see the glVertexPointer and the glNormalPointer? I fear that my mistake must be there.

*Is this the correct way to use them?
*In case we used shaders what we need is the glVertexAttribPointer and glEnableVertexAttribArray?

Below you can see the simple arrays I made to test the vbo loading and drawing. If I don't have the dummy normals inside, then the cube renders fine. But it seems that with the dummy normals instead of just using the stride to go over them, they are used as vertices coords and I get a very funny shape ^^



float vertss[] = {1.0,1.0,1.0, 0,0,0, -1.0,1.0,1.0, 0,0,0, -1.0,-1.0,1.0, 0,0,0, 1.0,-1.0,1.0, 0,0,0,
1.0,-1.0,-1.0, 0,0,0, 1.0,1.0,-1.0, 0,0,0,
-1.0,1.0,-1.0, 0,0,0,
-1.0,-1.0,-1.0, 0,0,0};

unsigned short indcss[] = {0,1,2,3, // v0-v1-v2-v3
0,3,4,5, // v0-v3-v4-v5
0,5,6,1, // v0-v5-v6-v1
1,6,7,2, // v1-v6-v7-v2
7,4,3,2, // v7-v4-v3-v2
4,7,6,5}; // v4-v7-v6-v5

And finally here you can see the drawing code. It is very crude, just for testing purposes.


//TESTING Small cube drawing

glUseProgram(0);//shaders off, for simplicity

glBindBuffer(GL_ARRAY_BUFFER, getVboID()[VERTICES_BUFFER_OBJECT]);
float* ptr2 = (float*)glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(ptr2,vertss,8*6*sizeof(float));//ADDDED dummy normals, hence 8 vertices, 6 floats each vertices
//@problem for some reason interleaved normals don't seem to work
//after usage it needs to be unmapped
glUnmapBuffer(GL_ARRAY_BUFFER);


glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getVboID()[INDICES_BUFFER_OBJECT]);
unsigned short* ptr = (unsigned short*)glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY);
memcpy(ptr,indcss,24*sizeof(unsigned short)); //24 indices

//after usage it needs to be unmapped
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);




//make sure the elements array buffer is bound
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, getVboID()[INDICES_BUFFER_OBJECT]);

//finally draw it!
glDrawElements(GL_QUADS, 24, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));


I am wondering, could it be that since I have an interleaved VBO for per-vertex data my indices array should take that also into account? And point to the correct indices inside the interleaved array? Could that be the problem? I just assumed that since openGL knows I use an interleaved VBO and knows the offset of each vertex coord it can go there when traversing the array with glDrawElements. So could that be the problem?

Any help or tips would be realy appreciated!

Lefteris
11-23-2010, 05:55 AM
Actually managed to figure it out!
glvertex and glNormal pointer were indeed at fault! But I realized the stride value I was giving was wrong. Since I interleaved vertex coords and normals it should be


glVertexPointer(3, GL_FLOAT, sizeof(Vertex*2, BUFFER_OFFSET(0));
glNormalPointer(GL_FLOAT,sizeof(Vertex)*2, BUFFER_OFFSET(12));


Because my Vertex struct is just a generic {x,y,z} vertex.
Now everything gets drawn fine.