В настоящее время я использую режим непосредственного рисования, но, очевидно, он слишком медленный для всего, кроме самых простых сцен.
Я не согласен.Если вы не рисуете лот плиток (десятки тысяч на кадр), немедленный режим должен подойти вам.
Ключ - это то, что вам нужно будет сделать, чтобы стать хорошимпроизводительность в любом случае: текстурные атласы.Все ваши плитки должны храниться в одной текстуре.Вы используете координаты текстуры, чтобы вытягивать различные плитки из этой текстуры при рендеринге.Так что если ваш рендеринг выглядит следующим образом:
for(tile in tileList) //Pseudocode. Not actual C++
{
glBindTexture(GL_TEXTURE_2D, tile.texture);
glBegin(GL_QUADS);
glTexCoord2f(0.0f, 0.0f);
glVertex2fv(tile.lowerLeft);
glTexCoord2f(0.0f, 1.0f);
glVertex2fv(tile.upperLeft);
glTexCoord2f(1.0f, 1.0f);
glVertex2fv(tile.upperRight);
glTexCoord2f(1.0f, 0.0f);
glVertex2fv(tile.lowerRight);
glEnd();
}
Вы можете преобразовать его в это:
glBindTexture(GL_TEXTURE_2D, allTilesTexture);
glBegin(GL_QUADS);
for(tile in tileList) //Still pseudocode.
{
glTexCoord2f(tile.texCoord.lowerLeft);
glVertex2fv(tile.lowerLeft);
glTexCoord2f(tile.texCoord.upperLeft);
glVertex2fv(tile.upperLeft);
glTexCoord2f(tile.texCoord.upperRight);
glVertex2fv(tile.upperRight);
glTexCoord2f(tile.texCoord.lowerRight);
glVertex2fv(tile.lowerRight);
}
glEnd();
Если вы уже используете атлас текстуры и все еще не используетеполучив приемлемую производительность, вы можете перейти к буферизации объектов и тому подобное.Но вы не получите большей производительности от буферных объектов, если не сделаете это в первую очередь.
Если все ваши плитки не могут уместиться в одну текстуру, то вам нужно будет сделать одну из двух вещей:используйте несколько текстур (рендеринг как можно большего количества плиток с каждой текстурой в одной паре glBegin / glEnd) или используйте массив текстур.Текстурные массивы доступны только на оборудовании уровня OpenGL 3.0.Это означает, что любой Radeon HDxxxx или GeForce 8xxxx или лучше.
Вы упомянули, что иногда вы визуализируете «элементы» поверх плиток.Эти функции, вероятно, используют смешивание и режимы glTexEnv, отличающиеся от обычных плиток.В этом случае вам нужно найти способы сгруппировать аналогичные функции в одну пару glBegin / glEnd.
Как вы уже поняли, ключом к производительности является минимизация количества вызовов glBindTexture и glBegin./ glEnd.Делайте как можно больше работы в каждом glBegin / glEnd.
Если вы хотите продолжить использование подхода, основанного на буфере (и вам следует беспокоиться, только если подход с текстурным атласом не повысил вашу производительность)это довольно просто.Поместите все свои куски плитки в один буферный объект.Не делайте буфер для каждого;для этого нет никакой реальной причины, а данные вершин размером 40x40 имеют размер только 12 800 байт.Вы можете поместить 81 такой блок в один буфер размером 1 МБ.Таким образом, вам нужно только вызвать glBindBuffer для вашей местности.Что, опять же, экономит вашу производительность.
Мне нужно было бы узнать больше об этих «функциях», которые вы иногда используете, чтобы предложить способ их оптимизации.Но что касается динамических буферов, я бы не волновался.Просто используйте glBufferSubData, чтобы обновить часть рассматриваемого буфера.Если это оказывается медленным, есть несколько вариантов сделать это быстрее, что вы можете использовать.Но вам не стоит беспокоиться, если вы не знаете , что это необходимо, поскольку они сложные.
Спрайты, вероятно, приносят абсолютную минимум из буфераобъектный подход.Там действительно ничего не может быть получено по немедленному режиму.Даже если вы рендерите сотни из них, у каждого будет своя собственная матрица преобразования.Это означает, что каждый из них должен быть отдельным вызовом розыгрыша.Так что это может быть glBegin / glEnd.