1

小さなゲームの場合、openGL で使用するモデルをロードするための OBJ ファイル ローダーを作成しようとしています。

OBJ ファイル形式の優れた特徴の 1 つは、面を定義するときにインデックスで参照することにより、同じ頂点を再利用できることです。一方、OpenGL には、同様の方法で編成された頂点バッファー オブジェクト (VBO) があります。1 つのジオメトリ データ バッファーと 1 つのインデックス バッファーがあります。

VBO には無制限のスペースがないため、 までしか満たすことができませんGL_MAX_ELEMENTS_VERTICES

によって設定された制限を尊重しながら、OBJ からの再利用されたジオメトリ データを可能な限り維持しながら、これらの VBO バッファを満たすことができるアルゴリズムを探していました GL_MAX_ELEMENTS_VERTICES / GL_MAX_ELEMENTS_INDICES

これを行うための良い方法やアルゴリズムはありますか?

4

1 に答える 1

0

.obj頂点共有からのデータを保持できます。頂点バッファーからデータを読み込み、.obj頂点/面を生成するコードは次のとおりです。

int FaceIndex = 0;
int VertexIndex = 1;
int TextureVertexIndex = 1;

char Prefix[3];

float X, Y, Z;
int A1, A2, A3, B1, B2, B3, C1, C2, C3, D1, D2;

while ( !IStream->Eof() )
{
    std::string Line = IStream->ReadLine();

    int NumRead = sscanf( Line.c_str(), "%2s %f %f %f", Prefix, &X, &Y, &Z );

    if ( NumRead < 1 ) continue;

    switch ( Prefix[0] )
    {
    case '#':
        continue;

個々の頂点を生成します。これらは複数の顔で共有できます。

    case 'v':
        {
            switch ( Prefix[1] )
            {
            case 0:
                if ( NumRead != 4 ) continue;
                EmitVertex( VertexIndex++, vec3( X, Y, Z ), -1, -1 );
                break;
            case 't':
                if ( NumRead != 3 ) continue;
                EmitTextureVertex( TextureVertexIndex++, vec3( X, 1.0f-Y, 0.0f ) );
                break;
            case 'n':
                if ( NumRead != 4 ) continue;
                EmitNormal( VertexIndex, vec3( X, Y, Z ) );
                break;
            }
        }
        break;

インデックスを使用してテクスチャ座標で面を生成します。

    case 'f':
        {
            if ( sscanf( Line.c_str(), "%2s %d/%d %d/%d %d/%d %d/%d", Prefix, &A1, &A2, &B1, &B2, &C1, &C2, &D1, &D2 ) == 9 )
            {
                A3 = B3 = C3 = 0;
                EmitTextureFace( FaceIndex, A2, B2, D2 );
                EmitFace( FaceIndex++, A1, B1, D1, -1, -1 );
                EmitTextureFace( FaceIndex, B2, C2, D2 );
                EmitFace( FaceIndex++, B1, C1, D1, -1, -1 );
            }
            else if ( sscanf( Line.c_str(), "%2s %d/%d/%d %d/%d/%d %d/%d/%d", Prefix, &A1, &A2, &A3, &B1, &B2, &B3, &C1, &C2, &C3 ) == 10 )
            {
                EmitTextureFace( FaceIndex, A2, B2, C2 );
                EmitFace( FaceIndex++, A1, B1, C1, -1, -1 );
            }
            else if ( sscanf( Line.c_str(), "%2s %d//%d %d//%d %d//%d", Prefix, &A1, &A3, &B1, &B3, &C1, &C3 ) == 7 )
            {
                A2 = B2 = C2 = 0;
                EmitFace( FaceIndex++, A1, B1, C1, -1, -1 );
            }
            else if ( sscanf( Line.c_str(), "%2s %d/%d %d/%d %d/%d", Prefix, &A1, &A2, &B1, &B2, &C1, &C2 ) == 7 )
            {
                A3 = B3 = C3 = 0;
                EmitTextureFace( FaceIndex, A2, B2, C2 );
                EmitFace( FaceIndex++, A1, B1, C1, -1, -1 );
            }

        }
        break;
    }
}
于 2013-12-08T11:46:31.223 に答える