Вот часть кода SDL2
Основная функция SDL
int main(int argc,char *argv[])
{
...
...
bool quit=false;
SDL_Event e;
while(!quit) ///First while (say)
{
while(SDL_PollEvent(&e)) ///Second while (say)
{
if(e.type==SDL_QUIT)
{
quit=true;
}
handleEvent(e) ;///Function for executing certain event
}
...
SDL_RenderPresent((SDL_Renderer)renderer);
}
}
Мой вопрос: что делает этот SDL_PollEvent() на самом деле, и предположим, что произошло событие, выполнение выходит за второе время() и вызывает SDL_RenderPresent() или ожидает, что все события будут принимать опрос, а затем SDL_RenderPresent() называется, я совершенно смущен?
Вышеприведенное является очень распространенным однопоточным циклом событий:
В основном приложение постоянно находится внутри внешнего цикла while. Чтобы получить самый гладкий пользовательский интерфейс, мы стараемся сохранить этот цикл до 17 мс (для скорости 60 кадров в секунду)
Каждый "кадр" начинается с ответа на все события, которые ждут в очереди (внутреннее время):
while(SDL_PollEvent(&e)) ///Second while (say)
{
if(e.type==SDL_QUIT)
{
quit=true;
}
handleEvent(e) ;///Function for executing certain event
}
События - это уведомления из операционной системы, что что-то произошло. Возможно, окно закрывает SDL_QUIT или перемещается мышь. Вы должны отвечать на эти события, чтобы приложение реагировало. Обычно ответ заключается в изменении состояния приложения.
Например, мы можем видеть, что событие "левое-мышь" - "вниз", мы можем найти "под" кнопкой мыши и указать, что он теперь выбран. Обычно это просто поиск объекта и вызов функции, которая изменит его состояние. Все, что изменяется, - это логическое значение, которое указывает, что объект теперь выбран.
Возможно, перемещение мыши должно изменить точку зрения следующего кадра, чтобы мы обновили вектор, в котором хранится направление, на которое мы смотрим. Поэтому мы обновляем вектор в памяти.
Вы можете иметь длинные отрезки, где очередь событий пуста, и приложение не имеет каких-либо событий для обработки. И могут возникнуть проблемы активности (например, пользователь, перемещающий мышь), где вы получите много событий для ответа.
SDL_PollEvent
не будет "ждать" событий. Если в очереди есть событие, вы получите информацию. Если нет события, он вернет false.
Обработка событий должна выполняться быстро (помните, что мы должны быть завершены в 17 мс), не беспокойтесь, это довольно много времени на ПК.
Когда вы закончите со всеми событиями и вне внутреннего цикла, вы готовы перейти к обновлению мира и рендеринга. На данный момент вы обычно будете делать такие вещи, как AI. Вызов физического движка. Например, вы можете перебирать объекты и изменять их положение в зависимости от их скорости.
Следующий шаг - фактически сделать рисунок.
SDL_RenderClear(renderer);
...
SDL_RenderPresent((SDL_Renderer)renderer);
Первый вызов очистит экран. Затем вы переходите и на основе состояния разных объектов выполняете рендеринг. Например, возможно, потому, что мы изменили состояние объекта на выбранное, теперь мы будем рисовать вокруг него светящуюся границу.
Ваш последний вызов - для SDL_RenderPresent (renderer), чтобы представить новый экран пользователю
Если вы используете Vsync (довольно часто), то этот последний вызов скроет небольшое время ожидания, чтобы синхронизировать обновление экрана с возможностями графической карты. Это создаст более плавную графику. Предполагая частоту обновления 60 Гц (60 кадров в секунду) и предполагая, что вы используете в своей логике рендеринга менее 16,6 мс, приложение будет ждать оставшееся время.
Теперь приложение готово вернуться к началу цикла и проверить, есть ли какие-либо события в SDL_PollEvent. Поскольку весь цикл обычно занимает всего несколько миллисекунд, приложение всегда будет чувствовать себя отзывчивым.