В предишна публикация говорих за Brew Game Tools (или BGT), което е моята 2D рамка за бързо създаване на прототипи (или може би дори за пълноценни игри!). Начинът, по който рендирането работи в BGT, е чрез преливане на спрайтове към буфер на кадри, който е подкрепен от OpenGL текстура. След като всички спрайтове са изчертани, текстурата се прилага към четворка и се показва. Това е доста прост и гъвкав начин за правене на софтуерно изобразено 2D. Въпреки това, в зависимост от броя на изображенията и разделителната способност, производителността може да варира много! Освен това, преливащи изображения, които поддържат трансформация (т.е. транслация, ротация и мащаб), са добавили допълнителни разходи. В хардуерно ускорен рендър трансформацията се извършва от GPU. Но в нашия случай трябва да го направим на процесора. Подробностите за това как работи блитингът на изображения в BGT са извън обхвата на тази история, но ще се опитам да напиша нещо в близко бъдеще!

Като казахме това, бихме искали да получим всички ускорявания, които можем да получим от процесора. За щастие, повечето процесори в днешно време имат множество физически ядра. Популярен начин за увеличаване на скоростта е чрез разделяне на задачата за изобразяване на множество нишки въз основа на 4-те квадранта на екрана. Ще имаме по една нишка за всеки от четирите квадранта на екрана. Една нишка ще изобрази само спрайт (или част от спрайт), който попада в този квадрант.

Ще създадем една нишка и една опашка от команди за изобразяване (не е показано на илюстрацията) за всеки от четирите квадранта на екрана. Всяка нишка ще отговаря за изобразяването на свързания с нея квадрант.

Сега във всеки кадър ще се случи следното:

  1. Когато искаме да начертаем спрайт, няма да го изобразим веднага. Вместо това първо ще разберем в кой екранен квадрант попадат границите на спрайта.
  2. След това ще създадем команда за изобразяване и ще я поставим в опашката на квадранта. Командата за изобразяване е основно описание на това какво да нарисувате, къде да нарисувате и как да нарисувате. Можем да съхраним команда за изобразяване в паметта (в нашия случай в опашка в паметта) и да я изпълним по-късно.
  3. Четирите нишки ще продължат да проверяват опашката за всяка налична команда за изобразяване. Всеки път, когато дадена команда бъде намерена в опашката, свързаната с нея нишка ще я извади от опашката и ще я изпълни (т.е. начертайте свързания спрайт по начина, описан в командата за изобразяване).
  4. Нашата основна нишка ще изчака всички нишки да завършат изпълнението на командите за изобразяване в своите опашки. След като всички опашки са празни и всички спрайтове са изобразени в буфера на кадрите, буферът на кадрите ще бъде изобразен на екрана.

Ако сте правили многопоточно програмиране преди, това трябва да изглежда като общ модел. След внедряването на това получих добър 2 до 3 пъти тласък на моя рендър. Все още има много начини за подобряване на скоростта. Функциите ми за трансформация на спрайтове не са изпълнени по най-оптималния начин. Това е един път, който възнамерявам да разгледам следващия.

Надяваме се, че това беше донякъде проницателно. До следващия път!