SDL_RenderPresent () не ждет vsync — как ждать?

Я инициализирую SDL с этим кодом:

SDL_Init(SDL_INIT_VIDEO);

SDL_Window* win = SDL_CreateWindow(
"SDL Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH,
HEIGHT,
SDL_WINDOW_SHOWN
);

SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
SDL_GL_SetSwapInterval(1); // probably has no effect since it's not using GL

Затем я рендеринг с программным рендерером не SDL и представить его в окне с этим кодом:

SDL_UpdateTexture(screenBuffer, NULL, screenData, WIDTH*4);

SDL_RenderClear(ren);
SDL_RenderCopy(ren, screenBuffer, NULL, NULL);
SDL_RenderPresent(ren);

Частота кадров полностью не ограничена, и я понятия не имею, почему.

Добавление | SDL_RENDERER_PRESENTVSYNC для флагов SDL_CreateRenderer просто делает окно пустым белым экраном. Хотя мне нужно использовать SDL_RENDERER_SOFTWARE флаг (даже если я не использую программный рендер SDL, кроме как для отображения экрана), иначе SDL_RenderPresent() будет зависать в течение очень и очень долгого времени, приводя к примерно 1 кадру в секунду.

Как я могу сделать SDL_RenderPresent() подождать vsync или подождать (точно) сам?

2

Решение

VSync — это аппаратная функция. Когда VSync включен, видеокарта останавливает рендерер от представления кадра до тех пор, пока не поступит сигнал от монитора, указывающий на вертикальную синхронизацию (что означает, что он завершил отображение последнего кадра).

Если вы используете программный рендер, вы не сможете обнаружить этот сигнал, так как вы не используете видеокарту для рендеринга. Это зависит от вас, чтобы установить частоту кадров и ждать следующего кадра.

Пример для 60 кадров в секунду:

#define TICKS_FOR_NEXT_FRAME (1000 / 60)

int lastTime = 0;

void update() {
while (lastTime - SDL_GetTicks() < TICKS_FOR_NEXT_FRAME) {
SDL_Delay(1);
}

... // SDL_RenderCopy...

SDL_RenderPresent(renderer);
lastTime = SDL_GetTicks();
}

Вызов update будет представлять кадр, только если по крайней мере 15 мс прошло. 15 мс — время, необходимое для частоты кадров 60 кадров в секунду.

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

РЕДАКТИРОВАТЬ

Как указано в комментариях, это не предотвратит разрыв, поскольку вы не синхронизируете сигнал vblank. Этот код помогает только при ограничении частоты кадров. Насколько я знаю, нет способа предотвратить разрыв при использовании программного рендерера (потому что вы не можете обнаружить сигнал vblank).

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]