現代の基準では、ポリゴン メッシュをレンダリングする好ましい方法は、インデックス バッファー (最終的には への呼び出しによって描画される) と組み合わせた頂点バッファー オブジェクトの使用を伴うようです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
- 上記のプログラムによって作成されたものを次に示します。
VBO の処理で何かおかしなことはありますか?