Jump to content
  • Advertisement
Sign in to follow this  
Mr Lane

Vertex Array Format

This topic is 4719 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have been looking through thread and tutorials and whilst I have learned alot, there is still have some basic questions I dont have an answer for regarding vertex arrays. void glVertexPointer(size, type, stride, *pointer); Now the way i understand it, size is the amount of array elements per vertex. So if i was just storing x y and z coordinate, size would have to be 3, and each new vertex in the array would begin every 3 array elements, if stride is set to 0? So for example this array with 6 elements: [1,2,3,4,5,6] would be 2 vertexes with the coords X=1,Y=2,Z=3 and X=4,Y=5,Z=6 each? I am guessing I have this wrong? What is the point of stride then? Wont it just create gaps in array? Now if I then want to define vertex normals and have an array of normals...I know that there is no size argument as normals are always represented with x,y,z components, so size is always 3...does the first normal in the array match up with the first vertex in the vertex array? What if the stride values are different? Finally, what I am trying to achieve is to have multiple pieces of geomerty (that are all uniuqe, they are not like static meshes in Unreal) being stored and rendered via Vertex arrays. Is the following rendering loop way off or just bad for efficiency (I have not got it running yet).
if(world->bm.numNodes != 0)    //Does the world contain geometry
{
    int i, j;
    Brush *currentNode;
    currentNode = world->bm->head;
    for(i = 0; i < world->bm.numNodes; i++)
    {
        glVertexPointer(3, DOUBLE, 0, currentNode->data.vertexArray;
    	glEnableClientState(VERTEX_ARRAY);
        glDrawArrays(GL_POINTS, 0, currentNode->data.numVertex);
        currentNode = currentNode->next;
        glDisableClientState(VERTEX_ARRAY);
    }
}
What I am doing is changing glVertexPointer to point at a new vertex array each loop, but do I need to enable and disable VERTEX_ARRAY each time? Finally, this may be a confusing question: If I am drawing lines rather than points...how does it know which vertexes should be connected with lines...? For example: If I want to draw a mesh as triangles I can specify 3 vertexes for a triangle, if I am drawing a mesh wireframe and using lines, I have to specificy 3 lines per tirangle, each with 2 vertexes...6 per triangle...is this right? Does this mean I need to reformat the data in the vertex arrays each time I change from points to lines to trianges rendering mode...? Thats a little inconvenient. Thanks for the help

Share this post


Link to post
Share on other sites
Advertisement
Quote:
Original post by Mr Lane
Now the way i understand it, size is the amount of array elements per vertex. So if i was just storing x y and z coordinate, size would have to be 3, and each new vertex in the array would begin every 3 array elements, if stride is set to 0?

Correct.

Quote:
So for example this array with 6 elements: [1,2,3,4,5,6] would be 2 vertexes with the coords X=1,Y=2,Z=3 and X=4,Y=5,Z=6 each?

Correct.

Quote:
What is the point of stride then? Wont it just create gaps in array?

You can use the stride to store other information in the same array.

Quote:
Now if I then want to define vertex normals and have an array of normals...I know that there is no size argument as normals are always represented with x,y,z components, so size is always 3...does the first normal in the array match up with the first vertex in the vertex array? What if the stride values are different?

The normals should match up, but it won't if the strides are different. An example of how to use the stride.

// Two vertices with normals. The first vertex is at (1,2,3) and has normal
// (1,0,0), the second vertex is at (4,5,6) with normal (0,1,0)
float myData = { 1,2,3, 1,0,0,
4,5,6, 0,1,0 };
glNormalPointer(GL_FLOAT, 6*sizeof(float), &myData[3]);
glVertexPointer(3, GL_FLOAT, 6*sizeof(float), &myData[0]);

Because going from the x of the first vertex to the x of the second vertex you pass over 6 values, the stride is 6. To go from the first normal to the second, you naturally have to pass over the same amount of element (6) so the stride is the same. If you use a different stride, the number will of course not match up and you'll get garbage.

Quote:
Is the following rendering loop way off or just bad for efficiency (I have not got it running yet).

It seems fine to me.

Quote:
... but do I need to enable and disable VERTEX_ARRAY each time?

You needn't enable/disable them every time, and it is indeed better to NOT do so. Just leave it on.

Quote:

Finally, this may be a confusing question:
If I am drawing lines rather than points...how does it know which vertexes should be connected with lines...? For example: If I want to draw a mesh as triangles I can specify 3 vertexes for a triangle, if I am drawing a mesh wireframe and using lines, I have to specificy 3 lines per tirangle, each with 2 vertexes...6 per triangle...is this right? Does this mean I need to reformat the data in the vertex arrays each time I change from points to lines to trianges rendering mode...? Thats a little inconvenient.

You can solve this by using Indexed mode. You create an additional array of unsigned int/short which tells OpenGL which vertex you want to use. In your example you then have three vertices. If you draw the triangle you have an index array of (0,1,2). If you draw the lines as GL_LINES it's (0,1,1,2,2,0), but if you use GL_LINE_LOOP it's (0,1,2). You'll need to use glDrawElements for this.

Share this post


Link to post
Share on other sites
Original post by rick_appleton
Quote:
Original post by Mr Lane
Quote:
... but do I need to enable and disable VERTEX_ARRAY each time?

You needn't enable/disable them every time, and it is indeed better to NOT do so. Just leave it on.


yes, this was the one point I was going to make, just enable it outside of the drawing loop you have there and disable it once the loop has completed.

Share this post


Link to post
Share on other sites
This is useful for me too! :P I had the same question, and this answer suits perfectly! :D

Just tested it out... there is a good performance boost, in this way (and moreover it's the correct way! :D)

Share this post


Link to post
Share on other sites
Thankyou, thankyou, thankyou! This all makes sence now. Its actually hard to find straightforward information about vertex arrays like this.

Is there any advantage to using stride >0 to combine arrays? I personally would rather keep things simple and keep vertex arrays seperate from normal arrays and so on.

I also know what indexes are now, and I will be making use of them for sure (I forgot about LINE_LOOP, but I dont think it will be much good anyway as for more than one triange I will need to make a sperate index array for it anyway).

Again thanks for the help.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mr Lane
Is there any advantage to using stride >0 to combine arrays? I personally would rather keep things simple and keep vertex arrays seperate from normal arrays and so on.


yes and no, it depends on what you are doing [smile]

By using a stride >0 you can interleave arrays as Rick pointed out earlier. If all your data is static or you update it all at once then interleaved arrays can be more optimal for the gfx card to deal with as it doesnt have to hop over memory to retive the data, instead it can read it all in one shot. When you transfer data to the gfx card it transfers in at least multiples of 32bytes, therefore if you can get all your data into a multiple of 32bytes the gfx card can read it all over in one go, if it has to hop around it will still read 32bytes worth of data, however it will cache some (or possibly discard some, depending on how things go) before going off to read the next bit of data and doing the same.

Dont worry too much about hitting muiples of 32bytes, the pre-T&L cache will hold data to be combined next read-around, however if you are close to the limit then it might be worth padding it.

Now, if you have data of which bits are updated seperately and reasonable often it might make sense not to interleave the arrays, or interleave the bits which dont change and supply the bits which do in their own chunk of memory.

Ofcourse, if your bottleneck isnt data transfer then you probably wont see any gain from this anyways [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Mr Lane
Finally, this may be a confusing question:
If I am drawing lines rather than points...how does it know which vertexes should be connected with lines...? For example: If I want to draw a mesh as triangles I can specify 3 vertexes for a triangle, if I am drawing a mesh wireframe and using lines, I have to specificy 3 lines per tirangle, each with 2 vertexes...6 per triangle...is this right? Does this mean I need to reformat the data in the vertex arrays each time I change from points to lines to trianges rendering mode...? Thats a little inconvenient.
For wireframe rendering, just use glPolygonMode to change between regular, wireframe, and point rendering. Then you can use the same data and not have to worry about filling separate arrays for the different modes.

Share this post


Link to post
Share on other sites
Thanks for that.

Anyway, rather than make a brand new thread, can someone tell me why this does not work:


if(world->bm.head != NULL)
{
int i, j;
LLNode<Brush> *currentNode;
currentNode = world->bm.head;
glEnableClientState(GL_VERTEX_ARRAY);
for(i = 0; i < world->bm.numNodes; i++)
{
glVertexPointer(3, GL_DOUBLE, 0, currentNode->data->vertexArray);
glDrawArrays(GL_LINES, 0, currentNode->data->numVertex);
currentNode = currentNode->next;
}
glDisableClientState(GL_VERTEX_ARRAY);
}

vertexArray holds tha values [0,0,0,1,1,0]. I have tested these values are correct using immediate mode, but when I feed them into the above, nothing is rendered. Have I overlooked something simple here?

Thanks

EDIT: Yes the if statement gets executed

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!