В отложенных задачах у меня скопилось много работы по движку. Нужно было сделать направленный зум и улучшить перетаскивание карты, чтобы курсор не отставал от того места где ты ухватился за карту. Также нужно было доделать механизм автоматического перемещения камеры. На это у меня ушел целый день, половину из которого я потратил на то чтобы восстановить в голове линейную алгебру, работу с векторами и матрицами :)
И наконец дошли руки до реализации общего шейдерного uniform буфера, чтобы не посылать каждому шейдеру отдельные uniform.
Но даже после этих задач не хотелось браться за геймплей, очень уж меня он вымотал. И я решил сделать еще одну задачу, которая теоретически должна была повысить FPS.
В процессе решения задачи, FPS немного повысилось, но я заметил странный баг - при покое камеры FPS прыгал в приделах 10-15%. Это стало сильнее заметно при возросшем показателе.
Начал копать. Что-то сильно мусорило память.... И просадка происходила при запуске сборщика мусора...
На рисунке видна "пила" потребления памяти.
Анализ показывал что все это происходит в рендере...Начал искать… Обратите внимание на FPS - порядка 310-340 кадров, хотя отключено все в рендере кроме интерфейса!
Когда я нашел место где происходило это безобразие я был зол на себя что забыл про это место. Код был временный и выводил нужную мне для отладки информацию! Вывод осуществлялся в текстуру и все бы ничего но это происходило каждый кадр!
Память выровнялась!!!!!!!!
При тех же условиях теперь рендер интерфейса в 1930 FPS!!!!!!!!!!!!!
АААААААААААААААА это жесть!!!!!!!!! Это в 6 с лишним раз быстрее!!!
После того как все вернул в рендер:
Прирост FPS составил порядка 30%. Неплохо. Но что-то продолжало жрать память и тормозить рендер с большими просадками при срабатывании сборщика мусора. Дальнейший анализ позволил выявить узкое место — это был просто тихий ужас!!!
У меня есть класс ShaderProgram который отвечал за загрузку шейдеров их валидацию и привязку различных uniform переменных. Этот код был написан в далекие времена, когда мои познания OpenGL были еще очень скудны. Код был написан по какому-то уроку из первого попавшегося гайда и впоследствии немного расширен для своих целей.
Ох как мне стыдно за этот кусок кода, пытаюсь себя оправдать тем что моя голова тогда была занята осмысливанием OpenGL и я даже не подумал о том какая это дичь.
Для тех кто не разбирается в программировании — каждый кадр тысячи раз вызывались эти методы в которых происходило объединение строк и соответственно в памяти плодились новые сущности.
Быстро все было переведено на рельсы OpenGl 4.3. с указанием расположения всех uniform переменных.
Прошерстил весь код на подобные казусы, каюсь было еще пару неприятных мест.
Ух и результат получился! Но на этом работы по оптимизации не закончились, я полностью переделал структуру карты и ввел двойную буферизацию при передвижении карты, что позволило снизить фризы при перестроении карты для ее зацикливания.
Сейчас карта строиться по принципу:
Где вертикальные чанки служат для быстрого перестроения карты и переноса тайлов с одной стороны на другую. А горизонтальные чанки ускоряют отсечение невидимых тайлов.
Все эти манипуляции позволили достичь отличных результатов и показатели FPS достигли значений 700+! Правда это показатели RTX2080.
Тяжеловат малость туман войны! Но, теперь я набрался вдохновения и опять взялся за геймплей!
До новых встреч!!!