2

次のコードを使用して、3D ゲームでいくつかのポリゴン メッシュを描画しています。

void drawModelFace(const MeshFace *face, float *vertices, float *vertNormals, float *textureVerts)
{   
    glBegin(GL_POLYGON);
    for (int i = 0; i < face->_numVertices; i++) 
    {
       glNormal3fv(&vertNormals[3 * face->_vertices[i]]);

       if (face->_texVertices)
       {
           glTexCoord2fv(&textureVerts[2 * face->_texVertices[i]]);
       }

       glVertex3fv(&vertices[3 * face->_vertices[i]]);
    }
    glEnd();
}

私の問題は、この関数が何度も呼び出されると、ゲーム内でパフォーマンスの問題が発生することです。

この関数は 1 秒あたり平均 50000 回呼び出され、一定の 60 fps が得られますが、場所によっては 1 秒あたり 100000 回呼び出されて 15 fps になります。(今日の電話のパフォーマンスをシミュレートするために、1Ghz にアンダークロックされた今日のコンピューターを使用しています)

即時モードは遅くなる可能性があると聞いたので、代わりに glDrawArrays を使用してみました。コードは次のとおりです。

void drawModelFace(const MeshFace *face, float *vertices, float *vertNormals, float *textureVerts)
{   
    GLfloat vert[3*face->_numVertices];
    GLfloat normal[3*face->_numVertices];
    GLfloat tex[2*face->_numVertices];

    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vert);
    glTexCoordPointer(2, GL_FLOAT, 0, tex);
    glNormalPointer(GL_FLOAT, 0, normal);

    for (int i = 0; i < face->_numVertices; i++) 
    {
        vert[0 + (i*3)] = vertices[3 * face->_vertices[i]];
        vert[1 + (i*3)] = vertices[3 * face->_vertices[i]+1];
        vert[2 + (i*3)] = vertices[3 * face->_vertices[i]+2];

        normal[0 + (i*3)] = vertNormals[3 * face->_vertices[i]];
        normal[1 + (i*3)] = vertNormals[3 * face->_vertices[i]+1];
        normal[2 + (i*3)] = vertNormals[3 * face->_vertices[i]+2];

            if (face->_texVertices)
            {
                tex[0 + (i*2)] = textureVerts[2 * face->_texVertices[i]];
                tex[1 + (i*2)] = textureVerts[2 * face->_texVertices[i]+1];
            }
    }

    glDrawArrays(GL_TRIANGLE_FAN ,0, face->_numVertices);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY); 
}

しかし、パフォーマンスの結果はまったく同じです。

コードを最適化して fps を得るにはどうすればよいですか?

私の最終的な目標は、このコードを Android デバイスで使用することであるため、glBegin と glEnd はもう許可されていないことに注意してください。

4

2 に答える 2

4

glDrawArray が最良の選択肢かもしれないと思います。私の記憶が正しければ、配列のデータは反復ごとにクライアントからサーバーに送信されます。反復ごとにデータが変更されても、クライアントはデータが変更されるたびにデータをサーバーに送信する必要があるため、実際には問題になりません。これは、VBO の実装により、大量のデータをサーバー メモリに保存しても、そのデータを再送信する必要があるため、実際にはパフォーマンスが向上しないことを意味します。

大きなオブジェクトを使用していますか、それとも小さなオブジェクトを多数使用していますか? 大きなオブジェクトを扱う状況では、glDrawArrays が最適であると確信しています。

「パフォーマンス結果がまったく同じ」とは、正確にはどういう意味ですか? それは非常によく似ていますか、それとも違いはありますか?パフォーマンスがまったく同じかどうかは、私には少し疑わしいように思えます。

于 2012-10-15T13:06:12.887 に答える
0

メッシュが変更されない場合 (つまり、静的モデルの場合)、表示リストを使用できます

これにより、すべての頂点/テクスチャ/法線呼び出しを事前にリストに構成し、glCallList への単一の関数呼び出しでレンダリングすることができます。

于 2012-10-15T11:48:46.223 に答える