1

I have following struct to store my vertex data.

struct Rz3DContourNode {
  float x; //pos x
  float y;   //pos y
  float z;  //pos z
  float nx;  //normal x
  float ny;  //normal y
  float nz;  //normal z
};

I store list of vertices in STL vector as follows :

std::vector < Rz3DContourNode >  nodes;

When I try to use this as as vertex-array in OPEGL ,in does not render incorrectly.

glVertexPointer(3, GL_FLOAT, 12, &nodes[0]);
glDrawArrays(GL_POINTS,0,nodes.size());

So, I tried to confirm the values using pointer arithmetic (assuming thats the way OPENGL handle data) as follows:

float *ptr=(float*) &nodes[0];

for(int i=0;i<nodes.size();i++)
{

   Rz3DContourNode confirmNode=nodes[i];  

  float x=*ptr;
    ptr++;

  float y=*ptr;
    ptr++;

  float z=*ptr;
     ptr++;


  //Confirm values !!! Do not equal ??
  qDebug("x=%4.2f  y=%4.2f z=%4.2f  | nx=%4.2f ny=%4.2f nz=%4.2f
        ",confirmNode.x,confirmNode.y,confirmNode.z,x,y,z);



  //Skip normal positions
  ptr++;
  ptr++;
  ptr++;

}

The values does not equal if I directly access values from the struct.

Does this means struct does not save the values contiguously ?

[EDIT] I Just noticed that using sizeof() instead of 12 fix the problem as follows:

glVertexPointer(3, GL_FLOAT, sizeof(Rz3DContourNode), &nodes[0]);

But still I am confused why my hack didnt traverse correctly in memory?(why qDebug doesnt print identical values ?)

Ashika Umanga Umagiliya
  • 8,988
  • 28
  • 102
  • 185
  • While the technique you are trying to use is formally a "hack", it should "work" as is in practice. Are you by any chance forcing some excessive alignment requirements on your struct type? If not, then the problem is in something you are not showing us. Are all values (x, y and z) different for all nodes? – AnT stands with Russia Sep 05 '11 at 06:31
  • hi ,I just noticed that using glVertexPointer(3, GL_FLOAT, sizeof(Rz3DContourNode), &nodes[0]); fix the problem !!! – Ashika Umanga Umagiliya Sep 05 '11 at 06:34
  • 1
    @AndreyT: IIRC, the standard should ensure that a `std::vector` should be contiguous in memory. I don't see what's really hacky about that. Alignment could be an issue though, as you say. – Mike Bailey Sep 05 '11 at 06:37
  • 1
    @Mike Bantegui: It is not about the vector. The hack in this case is the attempt to re-interpert a struct of 6 consecutive floats as an array `float[6]`. In OpenGL vertices are represented by *arrays* of coordinates. For some reason people insist in representing them as *structs* in their user code and then reinterpreting these structs as arrays before passing to OpenGL functions, which is a hack. – AnT stands with Russia Sep 05 '11 at 06:42
  • @umanga: Why did you say `12` originally? What did `12` stand for? – AnT stands with Russia Sep 05 '11 at 06:44
  • @AndreyT: thats the byte offset between consecutive vertices. (http://www.opengl.org/sdk/docs/man/xhtml/glVertexPointer.xml) – Ashika Umanga Umagiliya Sep 05 '11 at 06:49
  • @umanga: Er... But what is the "vertex" in this case? Each of your "vertices" (the way I understood it) has 6 floats in it, which is 24 bytes total, not 12. You said it yourself that it started working once you used `sizeof(Rz3DContourNode)` in the call. `sizeof(Rz3DContourNode)` is 24. – AnT stands with Russia Sep 05 '11 at 06:56
  • yes i mistook that one,it should be 24. But still my question is why qDebug() doesnt display the identical values. – Ashika Umanga Umagiliya Sep 05 '11 at 07:04
  • @umanga: Could you add some example printout? – Macke Sep 05 '11 at 09:04

1 Answers1

3
sizeof(Rz3DContourNode) == 6*4 = 24 bytes ... not 12!

The stride is the # of bytes between the start of each vertex, not the padding. Although 0 is a special value that indicates tightly packed data.

So, if you're using 3 floats as vertex data, there's no difference between a stride of 0 and 12 (because 3 floats are 12 bytes). In your case, your struct is 24 bytes, so you should put that.

This convention (stride = step size, not padding) allows the simple use of sizeof, so you ended up doing the the right thing intuitively. That's good API design for you. :)

See glVertexPointer docs:

stride

Specifies the byte offset between consecutive vertices. If stride is 0, the vertices are understood to be tightly packed in the array. The initial value is 0.

Macke
  • 24,812
  • 7
  • 82
  • 118