tags:

views:

443

answers:

4
+2  Q: 

openGL and STL?

hi, I am using openGL and am currently passing it a vertex array. The problem is that I have to create many vertices, and add them in between one another (for order). This means that using a regular array is pretty annoying/inefficient.

I want to use a data structure from STL so that I can efficiently (and easily) put new vertices at any index. The problem is that openGL expects a regular array.

Does anyone know how to go about this? Is there an easy way to convert from an STL vector to an array?

I am using openGL 1.1

Thanks

+1  A: 
vector<int> array;
.....
functionThatAcceptsArray(&array[0]); // yes, this is standard
AraK
+11  A: 

You can use a pointer to the first address of the vector as an array pointer. STL vectors are guaranteed to keep their elements in contiguous memory. So you can just do something like:

&vertices[0]

where vertices is your vector.

Laurence Gonsalves
+2  A: 

OpenGL requires a contiguous array of elements. For hopefully obvious reasons, there is no efficient way to insert a single element into a contiguous array. It is necessarily at least O(N).

However, you potentially could add N elements in less than the O(N^2) that the vector achieves for N random insertions.

For example, if you don't actually add new vertices "at any index", but always close to the previous one, you could add all the elements to a std::list (O(1) per element, O(N) total), then copy the std::list to a std::vector. In fact it doesn't have to be the previous element, just a previous element, so if the order is based on a recursive traversal of some tree then you might still be able to do this.

If new vertices are added at an index determined by some linear order, then add all the elements to a std::map or std::multi_map (O(log N) per element, O(N log N) total), then copy that to a vector.

So, the lowest-complexity way of doing it depends on how the order is determined. Whether these lower-complexity solutions are actually faster than the vector depends on N. They have much higher overheads (O(N) allocations instead of O(log N) for the vector), so N might have to be pretty big before the asymptotic behaviour kicks in.

If you do use either of the solutions I describe, then the easy/efficient way to copy either a list or a map to a vector is like this:

std::vector<glVertex3f> vec;
vec.reserve(listormap.size());
vec.insert(vec.begin(), listormap.begin(), listormap.end());
Steve Jessop
+1  A: 

It depends on how much control you need over your intermediate data representations, and how much you are able to precalculate.
For a compromise between freedom and memory usage, read about the Winged Edge data structure. The structure allows quick access and traversal between vertices, edges and faces and works like a doubled linked-list. If you implement the concept and make an iterator implementation for it, you can use std::copy to copy the data into any STL container.
As the rest of the folks have already mentioned, use std::vector as the final representation when OpenGL needs the data. And lastly:
Don't be afraid to have several instances of the same data!

Mads Elvheim