绘制多边形网格时的Opengl性能问题

时间:2012-10-15 11:12:07

标签: c++ performance opengl optimization opengl-es

我正在使用以下代码在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。

2 个答案:

答案 0 :(得分:4)

我认为glDrawArray可能是最佳选择。如果我没记错的话,数组中的数据将在每次迭代中从客户端发送到服务器。如果在每次迭代中更改数据,那么这实际上不是问题,因为客户端需要在每次更改数据时将数据发送到服务器。这意味着由于VBO的实现,在服务器内存中存储大块数据,实际上不会给你带来任何性能提升,因为无论如何你都必须重新发送这些数据。

您使用的是大型物品还是许多小物件? 我相信glDrawArrays在具有大对象的情况下是最佳的。

“你的表现结果是完全一样的”是什么意思?是非常相似还是有什么区别?如果表现完全相同,我觉得有点怀疑。

答案 1 :(得分:0)

如果您的网格没有改变(即它是静态模型),那么您可以使用display list

这允许您将所有顶点/纹理/普通调用预先组合成一个列表,然后使用单个函数调用glCallList进行渲染。