Проблема производительности OpenGL при рисовании полигональных сеток

Я использую следующий код, чтобы нарисовать несколько полигональных сеток в 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 больше не разрешены.

2

Решение

Я думаю, что glDrawArray может быть лучшим вариантом. Если я правильно помню, данные из массивов будут отправляться с клиента на сервер в каждой итерации. Если данные меняются на каждой итерации, то это на самом деле не проблема, так как клиент должен отправлять данные на сервер каждый раз, когда они меняются в любом случае. Это означает, что благодаря внедрению VBO, хранение больших кусков данных в памяти сервера, на самом деле не даст вам никакого выигрыша в производительности, поскольку вам все равно придется повторно отправлять эти данные.

Вы используете большие объекты или много маленьких?
Я довольно уверен, что glDrawArrays наиболее оптимальны в ситуациях с большими объектами.

Что именно вы имеете в виду под «результатами производительности одинаковы»? это очень очень похоже или есть какая-то разница? Это звучит немного подозрительно для меня, если производительность точно такая же.

4

Другие решения

Если ваша сетка не меняется (т.е. это статическая модель), то вы можете использовать список отображения

Это позволяет вам предварительно скомпоновать все ваши вершинные / текстурные / нормальные вызовы в список, который вы затем визуализируете с помощью одного вызова функции glCallList.

0

По вопросам рекламы [email protected]