Давайте подумаємо платформно-агностично: я хочу завантажити деякі графічні ресурси, поки решта гри працює.
В принципі, я можу завантажувати фактичні файли в окремий потік або використовуючи async I / O. Але з графічними об'єктами мені доведеться завантажувати їх у GPU, і це можна (як правило) робити лише в основному потоці.
Я можу змінити цикл гри, щоб виглядати приблизно так:
while true do
update()
for each pending resource do
load resource to gpu
end
draw()
end
маючи окремі потокові ресурси завантаження з диска в оперативну пам'ять.
Однак якщо є багато великих ресурсів для завантаження, це може змусити мене пропустити рамковий термін і в кінцевому підсумку отримати скинуті кадри. Тож я можу змінити цикл на це:
while true do
update()
if there are pending resources then
load one resource to gpu
remove that resource from the pending list
end
draw()
end
Ефективно завантажуючи лише один ресурс на кадр. Однак, якщо для завантаження є багато невеликих ресурсів, завантаження їх забирає багато кадрів, і витрачається багато часу.
Оптимально, я хотів би виконати завантаження таким чином:
while true do
time_start = get_time()
update()
while there are pending resources then
current_time = get_time()
if (current_time - time_start) + time_to_load(resource) >= 1/60 then
break
load one resource to gpu
remove that resource from the pending list
end
draw()
end
Таким чином, я б завантажував ресурс лише тоді, коли зможу це зробити протягом часу, який я маю для цього кадру. На жаль, для цього потрібен спосіб оцінити кількість часу, необхідне для завантаження певного ресурсу, і, наскільки я знаю, зазвичай це не існує.
Що я тут пропускаю? Як багато ігор змушують завантажувати всі свої речі повністю асинхронно і без опущених кадрів або надзвичайно тривалих періодів завантаження?