7

wavefront .objファイルを解析しようとしているときに、次の2つのアプローチを考えました。

  1. 頂点の数のサイズの2D配列を作成します。面が頂点を使用する場合、配列からその座標を取得します。
  2. 頂点リストの開始位置を取得し、面が頂点を使用する場合は、頂点に到達するまで線をスキャンします。

IMO、オプション1は非常にメモリを消費しますが、はるかに高速です。オプション2には大量のファイル読み取りが含まれるため(そしてほとんどのオブジェクトの頂点の数が非常に多くなるため)、これははるかに遅くなりますが、メモリの集中度は低くなります。

問題は、メモリと速度のトレードオフを比較することです。平均的なコンピュータに適したオプションはどれですか。そして、別の方法はありますか?

オブジェクトをレンダリングするために、GLFWと一緒にOpenGLを使用する予定です。

4

5 に答える 5

6

IMO、オプション 1 は非常にメモリを集中的に使用しますが、はるかに高速です。

とにかく、これらの頂点をメモリに取得する必要があります。ただし、2D 配列は必要ありません。これは、2 つのポインターの間接参照を引き起こすため、パフォーマンスが大幅に低下します。シンプルなstd::vector<Vertex>データを使用するだけです。ベクトル インデックスは、付随する顔リストのインデックスです。

コメントによる編集

class Vertex
{
    union { struct { float x, y, z }; float pos[3] };
    union { struct { float nx, ny, nz }; float normal[3] };
    union { struct { float s, t }; float pos[2] };
    Vertex &operator=();
}

std::vector<Vertex>;
于 2011-10-17T15:57:11.130 に答える
4

通常、頂点のリストを配列に読み込みます。ASCII テキストの解析は非常に遅くなります。ファイルをロードするときに一度だけ実行し、すべてをメモリ内の配列に格納します。

同じことが三角形/面にも当てはまります。各三角形は通常、3 つの頂点インデックスのリストで構成されます。これも配列に格納する必要があります。

VTK オープン ソース ライブラリの OBJ リーダーが役立つ場合があります: http://www.vtk.org/doc/nightly/html/classvtkOBJReader.html。私たちはそれを使用しており、独自に作成する理由はありません... VTK を直接使用するか、ソース コードを調べて、読者のさらなるインスピレーションを得ることができます。

私の意見では、OBJ ファイルの主な欠点の 1 つは ASCII の使用です。3D ASCII ファイル (STL、PLY、OBJ など) が ASCII の場合、文字列の解析が原因で読み込みが非常に遅くなります。バイナリ形式のファイルははるかに高速であり、パフォーマンスが問題になる場合は常に使用する必要があります。優れたバイナリ形式の読み込み時間は瞬時です。

于 2011-10-17T15:41:21.353 に答える
2

それらを配列にロードするだけです。メモリは問題になりません。システムには (通常) GPU よりも多くのメモリがあります。メモリの問題が発生している場合は、詳細すぎるモデルをロードしている可能性があります。(私は、あなたが OpenGL でゲームを作成しようとしていると仮定しています。そのような大きなモデル ファイルが必要な場合でも、適切なチャンクをロードする方法を考え出す必要があります。)

于 2011-10-17T16:42:56.673 に答える
0

2次元配列は必要ありません。モデルを三角測量する必要があります。その後、glutsobjloaderを使用してobjファイルをロードできます。ポイント、面、法線を3つの別々の配列/バッファに保存するだけです。ここにそれを行う方法の例がありますが、それを速くしたい場合は、バイナリ形式を選択する必要があります。

于 2011-10-17T15:44:39.837 に答える
0

これは、OpenGL または好みのレンダリング API で使用する配列を生成するスクリプトを実行して、プロトタイプを作成するためのかなり適切なソリューションです。obj2opengl.pl は perl スクリプトです。ここにある perl をインストールする必要があります。GitHub リンクはこちらです。

perl スクリプトの実行中に、154 行目で実行時エラーが発生する場合がありますif(defined(@center))。に置き換えますif(@center)

例から、ヘッダー ファイルがデータで生成されると、次のように使用できます。

/*
created with obj2opengl.pl

source file    : ./banana.obj
vertices       : 4032
faces          : 8056
normals        : 4032
texture coords : 4420


// include generated arrays
#import "./banana.h"

// set input data to arrays
glVertexPointer(3, GL_FLOAT, 0, bananaVerts);
glNormalPointer(GL_FLOAT, 0, bananaNormals);
glTexCoordPointer(2, GL_FLOAT, 0, bananaTexCoords);

// draw data
glDrawArrays(GL_TRIANGLES, 0, bananaNumVerts);
*/
于 2015-08-25T22:09:20.150 に答える