0

現代の基準では、ポリゴン メッシュをレンダリングする好ましい方法は、インデックス バッファー (最終的には への呼び出しによって描画される) と組み合わせた頂点バッファー オブジェクトの使用を伴うようですglDrawElements()。これがまさに、私がこれらの概念に頭を悩ませようとしている理由です。また、非推奨などglVertexAttribPointer()の代わりに使用することを主張します。 glVertexPointer()glNormalPointer()

カスタムのバイナリ3D ファイル形式 (Wavefront .OBJ の派生物) を使用しています。その内容は多かれ少なかれ直接memcpy()頂点配列に変換できます。vertex構造を宣言した方法は次のとおりです。

   typedef struct vertex_ {

            float vx,vy,vz;
            float nx,ny,nz;
            float padding[2];  // align to 32 bytes 
   
   } vertex; 

この関数はインデックス バッファ(s の単純な配列として実装) をloadBObj()返し、関連付けられた頂点/法線データで頂点配列を埋めます (使用されるすべてのモデルは、よりスムーズなシェーディング結果のために頂点ごとの法線を持つようにエクスポートされています)。 .unsigned short int

indices = loadBObj("pharaoh.bobj", false, &VBOid);

ローディング コード自体は、適切に動作することが検証されています。

現在、次のようloadBObj()に新しい VBO が作成されています。

    glGenBuffers(1, VBOid);
    glBindBuffer(GL_ARRAY_BUFFER, *VBOid);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex)*vcount, &vertarray[0].vx, GL_STATIC_DRAW);

loadBObj()が呼び出された後、次のようにインデックス バッファ オブジェクト(おそらくそのように参照されるべきではありません) が作成されます。

    glGenBuffers(1, &IBOid);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short int)*qfcount*4, indices, GL_STATIC_DRAW);

わかった。実際にメッシュをレンダリングするときは、次のコードを使用しました。

    #define BUFFER_OFFSET(i) ((char *)NULL + (i))
    ...
    glBindBuffer(GL_ARRAY_BUFFER, VBOid);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(0));
    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(vertex), BUFFER_OFFSET(3*sizeof(float)));

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBOid);
    glDrawElements(GL_QUADS, qfcount*4, GL_UNSIGNED_SHORT, BUFFER_OFFSET(0));

これにより、完全に正しいジオメトリが得られますが、シェーディングは完全には正しくありません。

  • 即時モードでレンダリングされたモデルのイメージを次に示します。

img http://i44.tinypic.com/i36zcg.png

  • 上記のプログラムによって作成されたものを次に示します。

img2

VBO の処理で何かおかしなことはありますか?

4

3 に答える 3

2

法線が正しく渡されていないようです

これはおそらく、あなたが持っているべきであるという事実によって引き起こされます

glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);

0 と 1 の両方のポインターを指定しているためです。(現在、最初の行しかありません)

于 2012-03-02T19:49:45.303 に答える
1

シェーダーを使用していますか?glVertexAttribPointerはシェーダーでのみ使用することになっているため、どの属性配列がどの入力変数に対応するかを明示的に指定する必要があります。(glGetAttribLocation / glBindAttribLocation)。

固定パイプラインを使用している場合は、glVertexPointer/glNormalPointerに固執する必要があります。

于 2012-03-02T23:30:36.703 に答える
0

ここで起こった可能性があるのは、三角形*が逆になっていることだと思います. 最初の各頂点を 3 番目の頂点ごとに交換するだけで、それをテストできます。

  • クワッドを使用しているので、それは明らかにエラーではありません。ただし、1 秒ごとに 3 番目の頂点を交換してみることができます。
于 2012-03-02T19:54:05.020 に答える