Много квадроциклов, мало кадров в секунду, несмотря на VBO

StackOverflow https://stackoverflow.com/questions/6330851

Вопрос

У меня есть время, я читал о VBO, и вот что у меня есть:

http://img64.imageshack.us/img64/5733/fps8.jpg

Хорошо, теперь намного лучше, чем раньше. Он скомпилирован в Release. Для рисования я использую VBO (возможно, если все в порядке) и glDrawArrays.

Вот код для рисования. Подскажите, пожалуйста, как его оптимизировать. Я хотел с ландшафтом ... несколько тысяч FPS, это реально?

родовое слово

Так что я могу с этим сделать? (Код выше - это основная функция рисования)

редактировать

Я переместил это:

родовое слово

к моей основной функции. Наверное, без улучшений.

edit2

Теперь я также вижу, что он пожирает память. Каждые несколько секунд использование программной памяти растет все больше и больше ... Что не так? Что я не удаляю?

edit3

Хорошо, спасибо большое. Я переместил код за пределы функции рисования и ... намного больше кадров в секунду! Большое спасибо!

http://img197.imageshack.us/img197/5193/fpsfinal.jpg

Это карта размером 640x640 блоков (то есть в 40 раз больше) с 650'000 квадратов (примерно в 70 раз больше) и все еще ~ 170 fps. Большой ! И никаких утечек памяти. Еще раз спасибо!

Это было полезно?

Решение

Ваша функция DrawVBO должна содержать только:

родовое слово

Остальные нужно переместить в отдельную функцию, вызываемую только один раз при запуске (или при изменении ландшафта).

Другие советы

Вы перезагружаете все свои буферы и снова освобождаете их в каждом кадре?Прекратите это делать, и ваша частота кадров увеличится.

Обратите внимание, что в вашем текущем коде в конечном итоге закончатся идентификаторы VBO, поскольку вы никогда не удаляете созданные VBO.

Связывание функций расширения определенно тоже не нужно делать в каждом кадре.

Следует выделить несколько моментов:

В функции рисования вы выделяете память для геометрических данных

родовое слово

Выделение памяти - чрезвычайно дорогостоящая операция, это одна из тех вещей, которые следует выполнять только один раз. OpenGL не предназначен для «инициализации» - но структуры данных, которые вы собираетесь передать ему, являются!

Здесь вы снова и снова копируете вновь выделенные буферы в OpenGL с каждым кадром. Это прямо противоположно тому, что нужно делать.

родовое слово

Вся идея VBO состоит в том, чтобы загрузить данные только один раз, скопировать их в OpenGL и никогда больше не перераспределять. Обратите внимание, что это не инициализация OpenGL, это инициализация данных, что-то вполне разумное. Я вижу, что вы назвали свои переменные m_pVertices и m_pTexCoords, указывая, что это переменные-члены класса. Тогда решение простое: переместите весь код инициализации в какую-нибудь функцию загрузчика. Также вместо голых массивов C ++ я настоятельно рекомендую использовать std::vector.

Итак, давайте исправим это:

родовое слово

Примечание: комментарии, такие как // Generate And Bind The Vertex Buffer или // Set The Vertex Pointer To The Vertex Buffer, не очень полезны. Эти комментарии просто избыточно говорят о том, что в любом случае можно прочитать из кода. К коду следует добавлять комментарии, внутренняя работа которых не сразу понятна, или если вам нужно было что-то исправить, и этот взлом озадачил бы кого-то другого или вас через несколько месяцев.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top