obj モデルを opengl プログラムにインポートしたいと考えています。属性データをシェーダーに渡すために使用するクラス/データ形式があります。
class CustomVertex : public IVtxFmt
{
public:
float m_Position[3]; // x, y, z offset 0, size = 3*sizeof(float)
float m_Normal[3]; // nx, ny, nz; offset 3
float m_TexCoords[2]; // u, v offset 6
float m_Colour[4]; // r, g, b, a offset 8
float m_Tangent[3]; // r, g, b offset 12
float m_Bitangent[3]; // r, g, b offset 15
};
インターネットからダウンロードした丸太小屋のモデルを使って作業しています。
丸太小屋には、いくつかの頂点、法線、およびテクスチャ座標の定義があり、その後に面定義のリストが続きます。
だから私の最初の本能は、objファイルを解析して最終的に
vector<vertex>
vector<Normal>
vector<TexCoord>
ファイルには 210 個の頂点、100 個の tex 座標、80 個の法線が定義されている可能性があるため、これを私の CustomVertex 形式に変換するのは簡単ではありません。
この形式の ~390 個の顔のリストの後:
f 83/42/1 67/46/1 210/42/1
ファイルに次のようなものがあります。
#
# object tile00
#
さらに頂点の定義が続きます。
このことから、モデルはいくつかのサブオブジェクトで構成され、それぞれがいくつかの面で定義されていると推測しました。3 x 頂点/法線/texcoord インデックス値で定義された各面。
したがって、CustomVertex のベクトルを取得するには、次のことを行う必要があると考えています。
作成して入力します。
vector <vertex>
vector <normal>
vector <texcoord>
vector <indices>
面の定義で一意の v/vn/vt トリプルごとに CustomVertex を作成する必要があります。
そこで、地図を作成することを考えました:
std::vector<CustomVertex> and
std::map< nHashId, CustomVertex_index >
したがって、私の考えでは、遭遇した v/vn/vt ごとに、この文字列のハッシュを作成します。たとえば、nHashId = hash("80/50/1")* を作成し、マップでハッシュを検索します。存在しない場合は、CustomVertex を作成してベクターに追加し、新しく作成したハッシュと CustomVertex_index をマップに追加します。
*: v/vn/vt 文字列のハッシュを作成することにより、その文字列に対応する一意の数値を作成しています。これにより、同等のテキストよりもマップで検索/比較する方が高速になると期待しています。
ハッシュに一致するものが見つかった場合、customvertex が既に存在すると見なし、新しい CustomVertex を作成する代わりに、CustomVertex_index エントリをインデックス ベクトルに追加して先に進みます。
これは計算コストが高い作業のように思えるので、毎回 obj ファイルを解析するのではなく、後で取得するために CustomVertex 配列 (および対応するインデックス配列) をディスクにダンプすることになると思います。
質問をする前に、時間の制約と、Vbo クラスを再設計する必要がないこと (重要なタスク) のために、CustomVertex 形式にこだわっていることを指摘してもよろしいですか?配列をシェーダーに分けていますが、CustomVertex のようにデータをインターリーブするとパフォーマンスが向上することを読んだことがあります。
だから私の質問に: 1. 私の方法は健全またはクレイジーに見えますか? 気が狂っている場合は、どこが間違っているかを指摘してください。
潜在的な問題を見つけることができますか?
誰かがこれを以前に行ったことがあり、私がやろうとしていることを達成するためのより簡単な方法を推奨できますか?