Archived

This topic is now archived and is closed to further replies.

Eber Kain

vertex array vs display list Just Talk

Recommended Posts

i know how to use either method fairly well, but here is my delima. I want to try a terrain engine, so i lay out a grid or floats like float terrain_height[100][100]; I then write up some algorithams for slopes and hills or what not, but i get stuck on drawing the data. I could simply use a quad or triangle strip, but i need to stick it on a display list to get good speed out of it, but i want the terrain to be deformable too, so a display list is no good. I cant figure out how to do a 2d array with vertex array, also, vertex arrays require that the vertex info is either 2 3 or 4 elements. I had the idea of stringing the whole thing into one long array, but that seems a bit complex. Im not out to make a visually stunning game(im only going to use simple models and small textures), so do i have the compute time to spare, and just use a strip. or is there some way to change data in a display list? or is there a different way of drawing that i have missed?

Share this post


Link to post
Share on other sites
A vertex array is just that, an array of vertices
Each vertex can have as many components as you want, eg x, y, z, s, t, nx, ny, nz which is a position, texture coordinates and a normal. This would require 8 floats(or whatever you are using) per vertex, so an array of 100 vertices would actually be an array of 800 floats.....get it ??

Vertex arrays do not require the whole vertex data to be 2, 3 or 4 elements, that applies to the actual position of the vertex, eg the x, y and z values. So the array above would have 3. The texture coordinate data is specified with glTexCoordPointer(), and the normal data with glNormalPointer().

Note that you do not have to have this data in the same array, you could have one tex coord array, one normal array, one tex coord array, it just depends on how you want to do it. Accessing memory linearly is faster though, so generally it is a good idea, though often it is not practical to only have one array.

The arrays you specify with glVertexPointer() etc... can be changed by your app whenever you want to. When you draw from that array, OpenGL looks up the data you gave it a pointer to and reads that, it doesn''t store the data itself, thats called client data. This makes vertex arrays perfect for deformable meshes etc... cos you only have to alter an array.

Look up the OpenGL docs for more info, they are suprisingly good

Hope that has explained a few things,

FatalXC

Share this post


Link to post
Share on other sites
Ok, so you think i should use a vertex array for my terrain then. Lets say i want to lay out a 500x500 grid, but if i do it in a vertex array i have to put it all in a single dimension array. What is a sure way to get to the correct element in the array when you want to move just one point. And for doing terrain all you really need is one float for each vertex, but useing vertex arrays you sould have to supply 3, dosent that seem like a waste?

Share this post


Link to post
Share on other sites
i dont know where u get 3 from hopefully not from v.x,.v.y,v.z
anyways with vertex arrays + display lists youre limited to how many tris u can draw at once eg a 500x500 array will not fit in memory thus will get broken up into smaller amounts affecting performace. best is to use lots of samller arrays eg 16x16 this enabled u also the huge benifit of performing your own culling

Share this post


Link to post
Share on other sites
Yes, i was thinking of chopping the whole thing up into smaller grids anyhow, and as for where i got the 3 from.

void glVertexPointer(GLint size, GLenum type, GLsizei stride,
const GLvoid *pointer);
Specifies where spatial coordinate data can be accessed. pointer is the memory address of the first
coordinate of the first vertex in the array. type specifies the data type (GL_SHORT, GL_INT,
GL_FLOAT, or GL_DOUBLE) of each coordinate in the array. size is the number of coordinates
per vertex, which must be 2, 3, or 4. stride is the byte offset between consecutive vertexes. If stride
is 0, the vertices are understood to be tightly packed in the array.

thats from the redbook, and it plainly says that each vertex needs to have 2 3 or 4 members. Best i could think of is to use 3. And supply all 3 members togather even though 2 will be static integers.

Share this post


Link to post
Share on other sites
quote:
Original post by Eber Kain
thats from the redbook, and it plainly says that each vertex needs to have 2 3 or 4 members. Best i could think of is to use 3. And supply all 3 members togather even though 2 will be static integers.


if you remeber that float and in are both the same size it won''t make a difference for memory use. What I do is use a struct to hold the data.
struct vertex_data{
float x,y,z;
};

then I just create an array of the grid size squared.

vertex_data vertex[16 * 16];

then access the vertex data by the index generated from (row * size) + column.

Use the vertex data for a vertex array then draw the mesh as triangle strips.

hope this helps

Share this post


Link to post
Share on other sites
If you are drawing it as triangle strips, then your not useing a vertex array are you. I mean you may have an array of vertices, but your not drawing it with glDrawElements(); or anything.

Share this post


Link to post
Share on other sites
>>thats from the redbook, and it plainly says that each vertex needs to have 2 3 or 4 members. Best i could think of is to use 3. And supply all 3 members togather even though 2 will be static integers<<

i think youve misunderstood that sentence, the 3 states how many coordinates each vertice has. eg in 3d this is normally 3 ie v.x v.y v.z in 2d its v.x,v.y

typedef float vertex[3];
vertex verts[] = { {0,0,0}, {1,0,0}, {1,89,0}, {0,1,0} };
printf("%f\n", verts[2][1] ); // should print 89

ok here ive defined 4 vertices (verts)

glVertexPointer( 3 (cause each vertice has 3 coordinates ie x,y,z ,.....)

Share this post


Link to post
Share on other sites
yes i understand it like that.

What im getting at is that to do a terrain grid you only need one value for each vertex(the one that tells you the height). So by useing a vertex array im haveing to use 3 times as many variables as i need.

Is the tradeoff you get from not haveing all those extra variables, and drawing with strips equil? Or are vertex Arrays still faster?

Share this post


Link to post
Share on other sites
Because you want deformable geometry, a vertex array makes the most sense. Yes, the x,y (or x,z depending on your axes) that are implicit in your data array are not so with the vertex array -- they need to be allocated and assigned. I''ve never really bothered to use vertex arrays because my understanding is that display lists are faster as they are completely stored on the card.

The only benefit you''re getting from using a vertex array in your case is that you''ll not have to re-specify vertex connectivity or texture coordinates, but everything else would need to be sent to the gfx card (the normals and vertices). I''ve never been clear exactly how this is a good thing. Resubmitting your coordinates every time you draw seems like a real major bottleneck...

At least, that how I understand things...

Share this post


Link to post
Share on other sites
what about using wglAllocateMemoryNV ... which i beleive allocates AGP memory in many cases. this should vastly improve vertex performance, because the graphics card can DMA the data from the memory ... although i guess that that only works for NV cards - but maybe other vendors have a similar function.

I maybe wrong there, i have only just discovered that particular function, and haven''t relly looked into it yet ... just a thought though

Share this post


Link to post
Share on other sites
Vertex arrays draw fast because they cache the vertex data in the cards memory as long as possable, and any duplicate calls to the same vertes are not repeated, just pulled from the cached ones. Like if i was just drawing quads for my terrain every coord would be supplied 4 times. With a strip every coord is supplied 2 times.

Share this post


Link to post
Share on other sites
quote:
Original post by Eber Kain
If you are drawing it as triangle strips, then your not useing a vertex array are you. I mean you may have an array of vertices, but your not drawing it with glDrawElements(); or anything.


Yes I am! here''s how...

glDrawElements(GL_TRIANGLE_STRIP, 2*Width, GL_UNSIGNED_INT, &trianglestrip[0]);

Something else that I learned is that depending on the video card, drivers, display mode, etc... the efficency of using vertex arrays or display lists or the two together was different. But generally vertex arrays were the way to go with display list being a close second and putting a vertex array in a display list provided horible performance.

Share this post


Link to post
Share on other sites