Я использую следующий код, чтобы нарисовать несколько полигональных сеток в 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 раз в секунду, что дает постоянные 60 кадров в секунду, но в некоторых местах она вызывается 100000 раз в секунду, что дает 15 кадров в секунду. (Я использую современный компьютер, разогнанный до 1 ГГц, чтобы имитировать производительность современного телефона)
Я слышал, что немедленный режим может быть медленным, поэтому я попытался использовать 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);
}
Но результаты производительности точно такие же.
Как я могу оптимизировать мой код, чтобы получить немного кадров в секунду?
Обратите внимание, что моя конечная цель — использовать этот код на устройствах Android, поэтому glBegin и glEnd больше не разрешены.
Я думаю, что glDrawArray может быть лучшим вариантом. Если я правильно помню, данные из массивов будут отправляться с клиента на сервер в каждой итерации. Если данные меняются на каждой итерации, то это на самом деле не проблема, так как клиент должен отправлять данные на сервер каждый раз, когда они меняются в любом случае. Это означает, что благодаря внедрению VBO, хранение больших кусков данных в памяти сервера, на самом деле не даст вам никакого выигрыша в производительности, поскольку вам все равно придется повторно отправлять эти данные.
Вы используете большие объекты или много маленьких?
Я довольно уверен, что glDrawArrays наиболее оптимальны в ситуациях с большими объектами.
Что именно вы имеете в виду под «результатами производительности одинаковы»? это очень очень похоже или есть какая-то разница? Это звучит немного подозрительно для меня, если производительность точно такая же.
Если ваша сетка не меняется (т.е. это статическая модель), то вы можете использовать список отображения
Это позволяет вам предварительно скомпоновать все ваши вершинные / текстурные / нормальные вызовы в список, который вы затем визуализируете с помощью одного вызова функции glCallList.