Sprite’y i tekstury

Na początku lekcji warto sobie uzmysłowić czym jest tekstura oraz czym jest sprite. Tekstura to jakiś obraz (np wczytany z pliku), a nazywamy go teksturą (Texture), a nie obrazem (Image) ponieważ my go będziemy mapowali do obiektów 2D. Sprite to nic innego jak „teksturowany” kwadrat.

W SFML do przechowywania tekstur służy sf::Texture, a do sprite’ów sf::Sprite.

 

Wczytywanie tekstur


Możemy wczytywać tekstury na 3 sposoby: z pliku (loadFromFile), z pamięci (loadFromMemory) oraz z jakiegoś napisanego przez nas strumienia danych (loadFromStream). Jednak my podczas tego tutoriala zajmiemy się najbardziej popularnym wczytywaniem z pliku.

W przypadku gdy nie uda nam się wczytać pliku (np. jest nieprawidłowe rozszerzenie lub zła nazwa pliku) funkcja zwraca false. Listę wspieranych przez SFML formatów obrazów znajdziesz w dokumentacji.

Wszystkie funkcje do wczytywania posidają także opcjonalny argument, który pozwala nam wczytać fragment tekstury.

sf::IntRect to klasa, która w matematyczny sposób reprezentuje kwadrat. Pierwsze 2 argumenty to pozycja na której się zaczyna, kolejne dwa to szerokość i wysokość.

 

Jeżeli nie chcesz wczytywać tekstury, a raczej wolisz wypełnić ją bezpośrednio z jakiejś tablicy pikseli możesz to zrobić. Na początku musisz stworzyć teksturę, którą możesz wypełnić później.

Pamiętaj, że teraz zawartość tekstury jest niezdefiniowana. Aby ją uzupełnić możesz to zrobić na kilka sposobów:

Te sposoby przedstawiają sposób zaktualizowania całej tektury, możesz także zaktualizować fragment, ale o tym informacje znajdziesz w dokumentacji.

Istnieją 2 właściwości, które decydują o tym w jaki sposób będzie renderowana tekstura.

Pierwszą z nich jest wygładzenie (smooth), dzięki któremu piksele są mniej widoczne. Można to włączyć używając:

Druga właściwość to powtarzanie, które działa tylko wtedy gdy obrazek który ma być wyświetlany jest większy niż tekstura, czyli np wyświetlany kwadrat o wymiarach 100×100, a nasza tekstura ma wymiary 25×25, wtedy może zostać powtórzona.

Sprite’y


Skopiowanie tekstury do sprite’a jest proste. Możemy podać teksturę w konstruktorze sprite’a lub poprzez użycie metody:

sf::Sprite sprite(texture);
sprite.setTexture(texture);

Rysowanie wygląda w ten sposób:

Możesz wczytać także fragment tekstury:

Możesz także zmieniać kolor sprite’a, ewentualnie możesz też tego użyć do zmiany przezroczystości.

Sprite’y poniżej mają tę samą teksturę, lecz różne kolory:

Sprite’y możesz także przekształcać:

Standardowo przekształcenia pokazane powyżej są dokonywane względem lewego górnego rogu, jeżeli chcesz je wykonywać względem innego punktu np środa sprite’a musisz skorzystać z:

 

Problem białego kwadratu


Jeżeli ci się zdarzyło, że mimo wczytania tekstury bezproblemowo i ustawienia jej sprite’owi, po wyświetleniu masz biały kwadrat to ten paragraf poradnika jest skierowany dla ciebie.

Jest to bardzo często spotykany błąd, problem leży w tym, że gdzieś w kodzie przestał istnieć wskaźnik do twojej tekstury, bo sprite nie kopiuje jej lecz pobiera wskaźnik do niej. W momencie gdy tekstura jest niszczona wskaźnik wskazuje na puste bity w pamięci. Prawdopodobnie twoja funkcja wygląda mniej więcej tak:

Musisz zawsze posiadać swoją teksturę w pamięci inaczej ten błąd będzie się powtarzał.

 

Używaj jak najmniej tekstur


Staraj się używać jak najmniejszej liczby tekstur jak to możliwe, pamiętaj że zmiana tekstury to ciężka operacja dla karty graficznej. Rysowanie wielu sprite’ów używających tej samej tekstury przynosi lepsze efekty. Dlatego lepiej jest korzytsać np. z tzw. tilesets (atlasów tekstur). Jest to zdecydowanie wydajniejsze.

Oryginalny artykuł