glVertexPointer and stl...

After experimenting for awhile, i have come to the conclusion that there is either a) no answer to my question , or b) an answer and it’s soooo simple i missed it .

I am using glVertexPointer() to send vertex data etc…

BUT… i would like to have my vertex data stored in a stl vector… I had reserved memory by resizing it before use to the amount of vertices needed.

My question is… what is the correct stride for the function?

I have a vertex data structure that has a position, normal and text (all vectors)

glVertexPointer(3, GL_FLOAT, sizeof(???), &(m_Verts[0].vPosition));

any ideas??

thanks

stride = (char *) &(m_Verts[1].vPosition) - (char *) &(m_Verts[0].vPosition);

Wait a minute, you say the struct contains vectors to the data?
Then forget the above. You won’t be able to calculate a stride from the struct’s data, but from the vertex pool they are pointing to.

[This message has been edited by Relic (edited 07-17-2002).]

There is no guarantee that the memory layout of a std::vector is contigous although most (all I know of) implementations are. Might be useful to know the day you’re compiling on the stl implementation from hell.

thanks for you help, i have solved it based on what relic said

the vectors are data stored in the struct, so what you said did work

thanks!

Originally posted by harsman:
There is no guarantee that the memory layout of a std::vector is contigous although most (all I know of) implementations are. Might be useful to know the day you’re compiling on the stl implementation from hell.

No, AFAIK there is a requirement for std::vectors to occupy contiguous memory. That is why push_back() can cause a re-allocation of the entire vector once the available room is exhausted: a new and larger contiguous memory block has to be allocated and all original vector elements are copied into the new area (invalidating all iterators etc.).

Just my .02

Jean-Marc.

Nope, the standard doesn’t guarantee that the memory in a vector is contiguous. Read this (the section titled “A fly in the ointment”). But this really isn’t something to worry about, it should work in practice everywhere and a future version of the standard will probably guarantee that the memory is contiguous. So it’s nothing to worry about, but it’s still good to be aware of.

Don’t take my workd for it, but it’s not written in the specification that the memory of a vector has to be contiguous. The intention was that is should be contiguous, and it will be in the next release of the specificaion. Assuming that “the next” release already haven’t been released of course.

Anyways, here’s a potential problem with the vector and the way you use it to pass the pointer to glVertexPointer.

glVertexPointer(3, GL_FLOAT, sizeof(???), &(m_Verts[0].vPosition));

If m_Verts[0].vPosition is an std::vector object, then &(m_Verts[0].vPosition) will give you the address of the vector object, which may not be the address of the first element in the vector. There may be some extra information about the vector in the beginning, like implementation specific information. You should do it like this instead, which will give you a pointer to the first element.

glVertexPointer(3, GL_FLOAT, sizeof(???), m_Verts[0].vPosition.begin());

Originally posted by harsman:
Nope, the standard doesn’t guarantee that the memory in a vector is contiguous. Read this (the section titled “A fly in the ointment”). But this really isn’t something to worry about, it should work in practice everywhere and a future version of the standard will probably guarantee that the memory is contiguous. So it’s nothing to worry about, but it’s still good to be aware of.

OK, thanks for the update, I didn’t know that.

However in this quote:

… assumes that the internal contents of the vector are stored contiguously in the same format as is an array, but today’s Standard doesn’t require vendors to implement vector that way. If, for example, a vector implementation were to play games and store its contents in some other way (such as contiguously but in backwards order, or in sequential order but with an extra byte of housekeeping information between elements), then Example 1(c) would in fact fail miserably

I do read that the total memory area occupied by the vector is to be contiguous, only that the way that memory is traversed from [0] to [1] may or may not be ascending and skipping ‘internal’ space in between.
And further on in your link, it is said that vector should be used whenever there is a requirement for the data stored in the vector to occupy a contiguous area in memory – that is arranged in a way compatible with C-style array traversing:

It will be guaranteed to work in practice tomorrow. The standards committee agrees that this is a natural thing to want to do, and it intends to put wording in the first Technical Corrigendum to the effect that the elements inside a vector must indeed be stored contiguously and so will be usable with code that expects an array.

Jean-Marc.

This is just creepy, but even though all of these messages are dated today, I feel like I have read this entire thread before. Does anyone remember if we have had this discussion recently (even though I didn’t find it in a search)?

Anyway, the way I recall it, the current STL spec doesn’t guarantee the memory to be contiguous (I think it was intended but overlooked). However, all known current implementations of STL do use contiguous memory. This issue has been raised and is going to be added to the standard at a later date.

[This message has been edited by LordKronos (edited 07-17-2002).]

Since I have all your attention , how about this question.

I have an octree. in the octree class (this class holds the nodes/sub nodes), in this octree class there is a fixed (at the moment) number of verts. Each node is subdivided and the end nodes contain face infomation that ‘lookup’ the vertices from that class.

Do you think this is a optimal solution? As opposed to storing seperate vert information in each node then using glVertexPointer* at each node instead of the one call at the beginning?

whew, that is confusing

I guess it comes down to… do you think calling glVertPointer once with a lot of data would be faster than calling glVertPointer x number of times with small amounts of data?

thanks

I guess it comes down to… do you think calling glVertPointer once with a lot of data would be faster than calling glVertPointer x number of times with small amounts of data?

If I recall, there is a certain unofficial maximum for the number of verts you should try to put in a single vertex array. I think it’s something like 4096 or so. So if your large array will be longer than this, then you have an issue that needs to be worked out.

well there is more than 4096 (in order of at least 3times as much) , guess i better try something else… It seems to work ok though

Originally posted by Korval:
[b]I think it’s something like 4096 or so. [b]

Err, I don’t think so Korval!
There’s no maximum, in standard vertex arrays, that I’m aware of. There are limits when using VAR though - on a geforce2 it’s something like 65535 (max value storable in an unsigned short). But I think it’s greater on gf3 - you can query this information anyway.

I don’t think there is a maximum you can put in the array, it only matters when you call glDraw*() on the array.

You can query that limit as it’s implementation dependent.
See this thread which discussed it:
http://www.opengl.org/discussion_boards/ubb/Forum3/HTML/006248.html

-Mezz

Robert,

How about running through your octree during a “pre-render” phase and building an stl vector out of the elements determined to be visible in the next frame? That way, come render time, you can pass your one large chunk (or several large chunks, if there’s really a max size problem).

Optimally, you could have several such temporary buffers… some fancy footwork would allow you to determine whether the buffer you’re building is already in your “cache”.

Haven’t tried it myself - octrees et al. are way more sophisticated than my projects have needed. But I’m thinking for complex scenes where the geometry may change between frames, but in predictable ways (LOD for instance), it might save you some time.

Heck, you might even be able to determine that a portion of the next frame was already built and just do a memcpy rather than traverse that octree branch…?

-Chris Bond

Originally posted by knackered:
Err, I don’t think so Korval!
There’s no maximum, in standard vertex arrays, that I’m aware of. There are limits when using VAR though - on a geforce2 it’s something like 65535 (max value storable in an unsigned short). But I think it’s greater on gf3 - you can query this information anyway.

Generally unsigned shorts for indices are processed quicker (on most hardware) for vertex arrays (not to mention less memory requirement, less to send to the card etc). This has lead to the idea of a maximum vertex array size that should be used being 65536 entries. There is no maximum index size for vertex arrays (except for certain extensions as mentioned above).

Thanks ChrisBond, i will give that a go .