1

頂点データを保存するための次の構造体があります。

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
};

頂点のリストを次のようにSTLベクトルに格納します。

std::vector < Rz3DContourNode >  nodes;

これをOPEGLの頂点配列として使用しようとすると、inが正しくレンダリングされません。

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

そこで、次のようにポインタ演算を使用して値を確認しようとしました(OPENGLがデータを処理する方法を想定しています)。

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++;

}

構造体から値に直接アクセスする場合、値は等しくありません。

これは、構造体が値を連続して保存しないことを意味しますか?

[編集]12の代わりにsizeof()を使用すると、次のように問題が修正されることに気づきました。

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

しかし、それでも、ハックがメモリ内を正しくトラバースしなかった理由がわかりません(qDebugが同じ値を出力しないのはなぜですか?)

4

1 に答える 1

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

ストライドは、パディングではなく、各頂点の開始間のバイト数です。0は、密集したデータを示す特別な値ですが。

したがって、頂点データとして3つのフロートを使用している場合、0と12のストライドに違いはありません(3つのフロートは12バイトであるため)。あなたの場合、あなたの構造体は24バイトなので、それを置くべきです。

この規則(ストライド=ステップサイズ、パディングではない)により、sizeofを簡単に使用できるため、直感的に正しいことを行うことができます。それはあなたにとって良いAPI設計です。:)

glVertexPointerのドキュメントを参照してください:

ストライド

連続する頂点間のバイトオフセットを指定します。ストライドが0の場合、頂点は配列に密に詰め込まれていると理解されます。初期値は0です。

于 2011-09-05T07:07:37.223 に答える