Wstęp
Choć niestety nadal nie potrafimy niczego rysować na ekranie to mimo wszystko wiedza, którą poznaliśmy do tej pory będzie nam potrzebna do tworzenia gier. Prawie na samym początku niniejszego kursu omawialiśmy klasę
sf::Window, która służyła nam do tworzenia aplikacji. Okno
sf::Window jest użyteczne gdy chcemy samodzielnie pracować np. z biblioteką OpenGL - jednak jeżeli chcemy korzystać z możliwości wbudowanych w bibliotekę SFML warto wówczas skorzystać z klasy
sf::RenderWindow, która jest dedykowana do renderowania grafiki 2D. W tym momencie prawdopodobnie przeszło Ci przez myśl stwierdzenie typu: 'to po co ja się tego wszystkiego do tej pory uczyłem?' - jeżeli tak jest to mimo wszystko nie masz się jednak o co pieklić, bowiem 100% wiedzy do tej pory nabytej jest nadal aktualne i użyteczne. Klasa
sf::RenderWindow dziedziczy klasę
sf::Window dzięki czemu posiada wszystkie cechy i własności klasy
sf::Window dodatkowo rozszerzając funkcjonalność klasy bazowej o nowe możliwości - w tym wsparcie do renderingu grafiki 2D. Technika tworzenia i obsługi okien pozostaje więc ta sama - jedyne co nam się zmieniło w budowie aplikacji to nazwa klasy tworzącej okno, czyli zamiast
sf::Window będziemy teraz mieli
sf::RenderWindow.
Wymagany plik nagłówkowy
Jak już wiemy, klasa
sf::RenderWindow jest dedykowana do renderowania grafiki 2D. Klasę tą umieszczono w module
Graphics biblioteki SFML. Aby móc korzystać z klasy
sf::RenderWindow najlepiej dołączyć następujący plik nagłówkowy:
#include <SFML/Graphics.hpp>
Powyższy plik nagłówowy dołącza nie tylko klasę
sf::RenderWindow ale również udostępnia nam cały szereg innych narzędzi wykorzystywanych przy pisaniu gier, takich jak np. ładowanie grafiki, rysowanie sprajtów czy też obsługa czcionek. Można oczywiście bawić się w dołączanie tylko niezbędnych plików do skompilowania projektu, niemniej jednak w przypadku biblioteki SFML nie ma to większego sensu, bowiem zazwyczaj korzysta się z większości komponentów należących modułów z których postanowiliśmy skorzystać w naszej aplikacji.
Efekt uboczny zastosowania nowej klasy
Jeżeli podmieniłeś w aplikacji, którą do tej pory pisaliśmy klasę
sf::Window na klasę
sf::RenderWindow to zapewne zauważyłeś, że ekran okna stał się kolorowy, a dokładniej wypełniony pikselami losowych kolorów. Dzieje się tak, bowiem została przydzielona pamięć dla okna renderującego, jednak pamięć ta nie została niczym przez nas zainicjalizowana, więc zawiera tzw. 'śmieci'. Śmieci tych można się pozbyć poprzez zwykłe zapełnienie ekranu jakąś grafiką, czyli chociażby poprzez wyczyszczenie ekranu.
Jeżeli nie dostałeś efektu opisanego w niniejszym paragrafie to nic się nie stało - u siebie nie zaobserwowałem tego efektu, niemniej jednak w oficjalnym anglojęzycznym kursie SFML zwracano na to uwagę, więc i ja tą informację przytoczyłem :)
|
Czyszczenie ekranu
Czyszczenie ekranu nie wymaga od nas specjalnej filozofii - jak już pisałem na początku klasa
sf::RenderWindow rozszerza możliwości klasy
sf::Window. Jednym z rozszerzeń jest metoda
Clear, która umożliwia czyszczenie ekranu na dowolny kolor. Domyślnym kolorem na który ekran zostanie wyczyszczony przez wspomnianą metodę jest kolor czarny. Jeżeli chcemy aby ekran został wyczyszczony na inny kolor to musimy podać poprzez argument metody
Clear kolor na jaki chcemy by został ekran zamalowany. W praktyce będzie więc to wyglądało tak:
oknoAplikacji.Clear();
oknoAplikacji.Clear( sf::Color( 255, 0, 0 ) );
Klasa sf::Color
Jak widać przy czyszczeniu ekranu pojawiła się nowość pt.
sf::Color.
sf::Color jest w rzeczywistości klasą, która umożliwia nam nadanie koloru tła za pomocą składowych RGBA. RGBA to skrót od: Red, Green, Blue, Alpha. Z angielskiego na nasze są to następujące składowe koloru: czerwony, zielony, niebieski i kanał przezroczystości. Kanał przeźroczystości nie został podany w przykładzie - domyślnie wynosi on 255, czyli podany kolor ma posiadać 100% krycie powierzchni (inaczej mówiąc: nic nie ma prześwitywać spod spodu). Każda składowa koloru jest wyrażona przez 8 bitową liczbę, co w praktyce oznacza, że minimalną wartością dla składowej koloru jest 0, a maksymalną jest 255. Stąd uzyskaliśmy intensywne czerwone tło w drugim przykładzie, który czyścił tło. W bibliotece SFML wszystkie barwy ustawiamy za pośrednictwem tej klasy. Dzięki temu nie musimy się przejmować o szczegóły techniczne związane poprawnym wsparciem dla barw w trybie 16bitowym - ta klasa zapewnia nam po prostu komfort pracy w której myślimy zawsze w jednolity sposób: Mamy 32bitowy opis koloru - 8 bitów na każdą składową: R, G, B oraz A.
Przykład
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow oknoAplikacji( sf::VideoMode( 800, 600, 32 ), "Kurs SFML - http://cpp0x.pl" );
while( oknoAplikacji.IsOpened() )
{
sf::Event zdarzenie;
while( oknoAplikacji.GetEvent( zdarzenie ) )
{
if( zdarzenie.Type == sf::Event::Closed )
oknoAplikacji.Close();
if( zdarzenie.Type == sf::Event::KeyPressed && zdarzenie.Key.Code == sf::Key::Escape )
oknoAplikacji.Close();
if( zdarzenie.Type == sf::Event::MouseButtonPressed && zdarzenie.MouseButton.Button == sf::Mouse::Middle )
oknoAplikacji.Close();
}
oknoAplikacji.Clear( sf::Color( 255, 0, 0 ) );
oknoAplikacji.Display();
}
return 0;
}
Podwójne buforowanie w SFML
Jeżeli znasz inne biblioteki wykorzystywane do tworzenia gier, a SFML jest kolejną z nich, którą zdecydowałeś się poznać to zapewne nie raz przewijał się tam wątek podwójnego buforowania. W SFML'u podwójne buforowanie jest zaszyte w oknie renderującym, więc nie musimy wykonywać żadnych dodatkowych kroków, by ekran nam nie mrugał. Naszą scenę tworzymy więc de'facto na buforze, którego zawartość jest kopiowana na ekran w chwili wywołania metody
Display, należącej do klasy okna renderującego
sf::RenderWindow. Fajnie, no nie? :)
Co to jest podwójne buforowanie?
Jeżeli nie jesteś obyty w świecie tworzenia gier to zapewne hasło pt. 'podwójne buforowanie' nic Ci nie mówi. Podwójne buforowanie polega na utworzeniu dodatkowego bufora pamięci o wymiarach okna, przeznaczonego do rysowania całej sceny gry. Po narysowaniu całej sceny kopiuje się zawartość tego bufora na ekran. Zabieg ten stosuje się w celu zapobiegania występowania nieprzyjemnych efektów, które pojawiają się podczas nanoszenia obiektów bezpośrednio na ekran. Dzięki temu aplikacje są przyjemne dla oka i nie mrugają nam co i rusz podczas czyszczenia każdej klatki i budowania jej od początku na oczach użytkownika.
Podsumowanie
Biblioteka jak widać jest dobrze przemyślana od podstaw i podstawy myślę, że mamy już za sobą. Teraz będzie można spokojnie przejść do omawiania mechanizmów związanych z obsługą plików graficznych jak również ich renderowaniem. Zapraszam do kolejnego rozdziału :)