我正在使用以下代码在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。
答案 0 :(得分:4)
我认为glDrawArray可能是最佳选择。如果我没记错的话,数组中的数据将在每次迭代中从客户端发送到服务器。如果在每次迭代中更改数据,那么这实际上不是问题,因为客户端需要在每次更改数据时将数据发送到服务器。这意味着由于VBO的实现,在服务器内存中存储大块数据,实际上不会给你带来任何性能提升,因为无论如何你都必须重新发送这些数据。
您使用的是大型物品还是许多小物件? 我相信glDrawArrays在具有大对象的情况下是最佳的。
“你的表现结果是完全一样的”是什么意思?是非常相似还是有什么区别?如果表现完全相同,我觉得有点怀疑。
答案 1 :(得分:0)
如果您的网格没有改变(即它是静态模型),那么您可以使用display list
这允许您将所有顶点/纹理/普通调用预先组合成一个列表,然后使用单个函数调用glCallList进行渲染。