tags:

views:

70

answers:

2

Here is my issue. I have a std::vector<POINTFLOAT> Which stores verticies. The issue is that Vertex buffer objects take in a pointer to an array of float. Therein lies my problem. I cannot give it an array of pointfloat. Is there a way that I could instead push pointers to the individual components of each vertex without pushing in copies?

basically instead of it being:

vec[0].x
vec[0].y
vec[1].x
vec[1].y

It becomes

newvec[0]
newvec[1]
newvec[2]
newvec[3]

I thought of making a std::vector<float*> but I don't think opengl would like this. Is there a way to do this without copying data?

Thanks

Instead of having to copy data for point.x, point.y, I want OpenGL to get its data from the original vector so basically when openGL would get vec[0] it would actually get pointvec[0].x but it needs to act like when passing by reference, no pointed members

so Opengl cant do *vec[0]

+1  A: 

You can write something like this, ie you have a std::vector which you fill with vertices, and then you call a function (eg an openGL function) which takes a float*. Is that what you want?

void some_function(float* data)
{

}

...

std::vector<float> vec;
vec.push_back(1.2); // x1
vec.push_back(3.4); // y1
vec.push_back(5.6); // x2
vec.push_back(7.8); // y2

some_function(&vec[0]);

EDIT: This will also work, because the floats are laid out the same in memory:

struct POINTFLOAT
{
    float x;
    float y;
};

void some_function(float* data)
{

}

...

std::vector<POINTFLOAT> vec;
vec.resize(2);
vec[0].x = 1.2; // x1
vec[0].y = 3.4; // y1
vec[1].x = 5.6; // x2
vec[1].y = 7.8; // y2

some_function((float*)(&vec[0]));
Saxon Druce
Yes this works but it envolves copying the data from the point vector see my edit
Milo
What if my pointfloat looks like float Point[2];
Milo
Yes that will also work, as it's also laid out the same in memory, but as Peter said it's a bit hacky :)
Saxon Druce
What can go wrong?
Milo
Because there can be padding between members or at the end of a struct, this is really not safe (`reinterpret_cast`, which is what the C-style cast will end up performing, is almost never safe).
James McNellis
If you changed your POINTFLOAT structure, or your compiler changed it for you - both of which are unlikely.
Saxon Druce
But I only have 1 member, Point[2]
Milo
Yes, at the moment - like I said you're unlikely to change your POINTFLOAT structure, but if you do in the future, your compiler won't catch the error - it will instead fail with some kind of obscure runtime error. Also by default the compiler will pack 2 floats with no padding in between or at the end, but a `pragma pack` or a compiler setting could change this.
Saxon Druce
Okay, well I'm glad to be aware of it, I'll try it ad if it causes too much trouble I'll implement a more proper solution, thanks!
Milo
You could try putting `assert(sizeof(POINTFLOAT) == 8)` somewhere in the startup for your code, which will catch some of these possible issues (still at runtime, although only in debug), but not all possible issues (eg if you change POINTFLOAT to two ints).
Saxon Druce
A: 

I think you mean std::vector<float>, not std::vector<float*>; a vector of pointers to floats is something different, and while I'm not intimately familiar with OpenGL VBO's, I assume they want an array of floats, not an array of pointers.

The only proper solution is to change your std::vector<POINTFLOAT> into a std::vector<float>. However, that's kind of obvious, so I assume the reason you asked is that you don't want to do that. If you wanted a hacky way around this, you could do:

std::vector<POINTFLOAT> v;
v.push_back(2.3);
v.push_back(3.4);
v.push_back(4.5);
v.push_back(5.6);
float* p = reinterpret_cast<float*>(&v[0]);

But that is a wee bit awful; among other things it relies on the internal layout of your POINTFLOAT class (which I assume is just storing an x and y coordinate?). reinterpret_cast pretty much screams hack, so you really should change the type of the vector if at all possible...

Peter
I might just try t hack because I have other functions that depend on it being a POINTFLOAT
Milo
What if my pointfloat struct looks like float Point[2];
Milo
Yes, I was thinking of `struct POINTFLOAT { float x; float y; }` or something along those lines. The two should be pretty much equivalent for these purposes, I think.
Peter