Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: Piotr Szawdyński
Biblioteki C++

Okno renderujące grafikę

[lekcja] Rozdział 5. Omówienie klasy sf::RenderWindow dedykowanej do renderowania grafiki 2D. Ponadto omówienie klasy sf::Color służącej do nadawania kolorów.

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:
C/C++
#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:
C/C++
oknoAplikacji.Clear(); //Wyczyści na kolor czarny

oknoAplikacji.Clear( sf::Color( 255, 0, 0 ) ); //Wyczyści na kolor czerwony

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

C/C++
#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 :)
Poprzedni dokument Następny dokument
Bezpośredni dostęp do klawiatury, myszy i joysticka Wczytywanie i zapisywanie plików graficznych