Много квадроциклов, мало кадров в секунду, несмотря на VBO
-
27-10-2019 - |
Вопрос
У меня есть время, я читал о 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
, не очень полезны. Эти комментарии просто избыточно говорят о том, что в любом случае можно прочитать из кода.
К коду следует добавлять комментарии, внутренняя работа которых не сразу понятна, или если вам нужно было что-то исправить, и этот взлом озадачил бы кого-то другого или вас через несколько месяцев.