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();
}

我的问题是,当这个函数被多次调用时,我在游戏中遇到了一些性能问题。

此函数平均每秒调用 50000 次,提供恒定的 60fps,但在某些地方,它被称为每秒 100000 次,提供 15fps。(我用今天的电脑降频到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 回答