0

DirectX エンジン用のモデル ファイル ローダーを作成しようとしています...

現時点では次のようになります。

irrFireMesh* irrFireDevice::loadModel(char* filename)
{

ifstream in_stream;
string line;
in_stream.open(filename);
int vertexCount = 0;
int vCount = -1;

irrFireMesh* triangleMesh = new irrFireMesh();
irrFireVertex* vertices;
unsigned long* indices;
irrFireMaterial* mat;

while(getline(in_stream, line, '\n'))
{
    std::string word;
    std::stringstream stream(line);
    std::string param[15];
    int i = 0;
    while( getline(stream, word, ' ') ){
    param[i] = word;
    i++;
    }

    then = timeGetTime();
    if(param[0] == "newbuf")
    {
        vertexCount = StI(param[1]);
        vertices = new irrFireVertex[vertexCount];
        if(!vertices) return NULL;
        indices = new unsigned long[vertexCount];
        if(!indices) return NULL;
        mat = new irrFireMaterial(this);
        cout<<"Begin buffer width "<<vertexCount<<" vertices"<<endl;
        vCount = -1;
        continue;
    }
    if(vertexCount <= 0) continue;

    if(param[0] == "endbuf")
    {
        irrFireMeshBuffer* mbuf = new irrFireMeshBuffer();

        mbuf->vertexCount = vertexCount;
        mbuf->indexCount = vertexCount;
        mbuf->vertices = vertices;
        mbuf->indices = indices;
        mat->INITIALIZE();
        mbuf->material = mat;
        triangleMesh->addMeshBuffer(mbuf);
        vertexCount = 0;
        cout<<"End buffer width "<<vCount+1<<" vertices."<<endl;
        continue;
    }

    if(param[0] == "v")
    {
        vCount++;
        vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));
        vertices[vCount].color = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
        vertices[vCount].uv = D3DXVECTOR2((StF(param[1]) + StF(param[3]))*10.0f, StF(param[2])*10.0f);
        indices[vCount] = vCount;
        if((vCount+1) % 3 == 0)
        {
            D3DXVECTOR3 NRML, D1, D2;
            D1 = vertices[vCount-2].position - vertices[vCount-1].position;
            D2 = vertices[vCount-1].position - vertices[vCount].position;
            D3DXVec3Cross(&NRML, &D1, &D2);
            D3DXVec3Normalize(&NRML, &NRML);

            vertices[vCount-2].normal = NRML;
            vertices[vCount-1].normal = NRML;
            vertices[vCount].normal = NRML;
        }
        continue;
    }
}

in_stream.close();
return triangleMesh;
}

三角形のモデル ファイルは次のようになります。

newbuf 3
v 0.0 0.0 0.0
v 0.5 1.0 0.0
v 1.0 0.0 0.0
endbuf

想定どおりに動作しますが、複雑なモデルをロードするときは遅すぎます...ボトルネックを指摘して、これをより速く解決する方法を指摘してもらえますか?

編集:わかりました、いくつかの関数に必要な時間をベンチマークしましたが、解析部分が

if(param[0] == "v")
{
.
.
.
}

23400 個の頂点を解析する場合、合計で約 4000 ミリ秒かかります。でも交換したら

vertices[vCount].position = D3DXVECTOR3(StF(param[1]), StF(param[3]), StF(param[2]));

vertices[vCount].position = D3DXVECTOR3(0.0f, 0.0f, 0.0f);

合計で約 300 ミリ秒しかかかりません。したがって、パフォーマンス キラーは次のような StF() のようです。

float StF(string in)
{
stringstream mystr("");
mystr<<in;
float res = 0;
mystr>>res;
return res;
}

アイデアはありますか?これは明らかに遅すぎるので...

4

1 に答える 1

1

「new」コマンドのオーバーヘッドは、検出された「newbuf」セクションの数によって異なりますが、各配列を保存する必要があるため、新しいコマンドが必要なようです。メッシュ クラスを変更できるかどうかによっては、ベクターに変換できない場合があります。

プロファイラーにアクセスできる場合は、それを使用して、どこで時間を費やしているかを確認することをお勧めします。コードのどの行が他の行よりも悪いかを示すことができます。多くの場合、これは最適化を試みるときの最初のステップです。多くの場合、単に目で見て判断しようとすると、推測が間違ってしまうだけです。

テキスト形式での読み取りは遅くなります。また、新しいコマンドだけでなく、文字列から浮動小数点数への変換にも少し時間がかかります。おそらく、各「newbuf」セクションを文字列の配列として読み取り、処理をマルチスレッド化できます(新しい処理と他の処理が並行して処理されます)。配列を目的のメッシュに戻す前に、同期する必要があります。

于 2013-06-01T14:03:09.517 に答える