Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?
Autor: 'kubawal'
Biblioteki C++

Renderowanie figur geometrycznych na scenie

[lekcja] Rozdział opisuje w jaki sposób renderuje się na scenie proste i złożone figury geometryczne w SFML.

Wprowadzenie

W poprzednich rozdziałach dowiedziałeś się, jak wyświetlać obrazki, oraz jakie można na nich wykonać transformacje.
W tym rozdziale dowiesz się, jak wyświetlać figury geometryczne, fachowo zwane prymitywami.
Biblioteka SFML posiada wbudowaną obsługę prymitywów.
Klasą bazową dla wszystkich prymitywów jest sf::Shape.
Dziedziczy ona po sf::Drawable(czyli można ją wyświetlać) oraz po sf::Transformable(czyli można zmieniać jej pozycję, obrót, skalowanie, itd.).

Figury w SFML

Prostokąty

Prostokąty to chyba najprostsze figury jakie istnieją. Ich tworzenie implementuje klasa sf::RectangleShape.
C/C++
sf::RectangleShape rectangle( sf::Vector2f( rozmiarX, rozmiarY ) ); // tworzymy prostokąt
rectangle.setPosition( pozcjaX, pozycjaY ); // i ustawiamy mu pozycję

Prostokąt
Prostokąt

Linie

W SFML nie ma osobnej klasy dla linii. Dlaczego? Dlatego, że linia, to po prostu prostokąt o szerokości 1.
C/C++
sf::RectangleShape line1( dlugosc, 1.0f ); // tworzymy linię poziomą
sf::RectangleShape line2( 1.0f, dlugosc ); // i pionową
line1.setPosition( pozycjaX, pozycjaY ); // a teraz ustawiamy jej pozycję

Linia
Linia

Jest pewna sztuczka pozwalająca rysować linie od jednego do drugiego punktu. Polega ona na tym, że metoda draw() klasy sf::RenderWindow potrafi rysować tablice wierzchołków.

C/C++
sf::RenderWindow win;
//...
sf::Vertex line[ 2 ] = // definiujemy linię za pomocą 2 wierzchołków
{
    sf::Vertex( sf::Vector2f( poczatekX, poczatekY ) ),
    sf::Vertex( sf::Vector2f( koniecX, koniecY ) )
};
win.draw( line, 2, sf::Lines ); // i ją rysujemy

Koła

Do tworzenia kół używamy klasy sf::CircleShape. Kółko tworzymy podając jego promień.
C/C++
sf::CircleShape circle( promien ); // tworzymy koło
circle.setPosition( pozycjaX, pozycjaY ); // a teraz ustawiamy jego pozycję

Koło
Koło

Trójkąty

Nie, nie ma w SFML nie ma klasy dla trójkątów, a to dlatego, że trójkąt to wielokąt regularny, a te tworzy się za pomocą klasy sf::CircleShape.
Ma ona możliwość tworzenia koła, bądź wielokąta regularnego podając promień(czyli odległość najdalszego punktu od środka) i ilość boków.
C/C++
sf::CircleShape triangle( promien, 3 ); // tworzymy trójkąt(wielokąt regularny o 3 bokach)
triangle.setPosition( pozycjaX, pozycjaY ); // i ustawiamy jego pozycję

Trójkat
Trójkat

Wielokąty

Do tworzenia wielokątów używamy klasy sf::ConvexShape. Tworzymy je podając liczbę i położenie kolejnych wierzchołków.
Uwaga:
Klasa sf::ConvexShape ma kilka ograniczeń.
Po pierwsze, za jej pomocą można rysować tylko wielokąty wypukłe(jeśli nie wiesz co to znaczy zerknij do Wikipedii)
Po drugie, wierzchołki musisz deifniować po kolei(tzn. zgodnie lub przeciwnie do ruchu wskazówek zegara).
Jeśli je zdefiniujesz byle jak, to mogą wystąpić dziwne problemy.
C/C++
sf::ConvexShape convex; // tworzymy pusty wielokąt
convex.setPointCount( liczba_wierzcholkow ); // najpierw musimy ustalić liczbę wierzchołków

convex.setPoint( 0, sf::Vector2f( pozycja_1wierzcholkaX, pozycja_1wierzcholkaY ) );
convex.setPoint( 1, sf::Vector2f( pozycja_2wierzcholkaX, pozycja_2wierzcholkaY ) );
// itd.

Wielokąt
Wielokąt

Własności kształtów

Rysowanie

sf::Shape dziedziczy po klasie sf::Drawable, więc można je rysować, tak jak inne rzeczy w SFML
C/C++
win.draw( ksztalt );

Transformacje

Klasa sf::Shape dziedziczy po sf::Transformable, więc można na niej wykonywać wszystkie transformacje, takie jak ustawianie pozycji, obrót, skalowanie itp.
Więcej info w poprzednim rozdziale

Wypełnianie kolorem

Wypełnianie kolorem jest proste: wystarczy ustawić kolor za pomocą metody setFillColor()
C/C++
sf::CircleShape circle( 50 ); // tworzymy przykładowy kształt
circle.setFillColor( kolor ); // i wypełniamy kolorem

Wypełnianie teksturą

Teraz czas na bardzo fajny efekt: Kształt można wypełnić teksturą prawie bez żadnej pracy(kolejna zasługa OpenGL)
C/C++
sf::Texture texture;
// tutaj ładujemy teksturę, info w poprzednich rozdziałach
//...
sf::CircleShape circle( 50 ); // tworzymy przykładowy kształt
circle.setTexture( & texture ); // i wypełniamy teksturą
Proste, co nie? Proste, fajne i skuteczne. Żeby z powrotem ustawić brak tekstury wystarczy wywołać setTexture() z parametrem NULL.

Brzegi kształtu

Możemy ustawić kolor i grubość brzegu kształtu za pomocą metod setOutlineColor() i setOutlineThickness()
C/C++
sf::CircleShape circle( 50 ); // przykładowy kształt
circle.setOutlineColor( kolor ) // ustawiamy kolor brzegu
circle.setOutlineThickness( grubosc ) // i ustawiamy grubość brzegu
Brzegi nie są teksturowane.

Przykład

C/C++
#include <iostream>
#include <SFML/Graphics.hpp>

using namespace std;
using namespace sf;

int main()
{
    RenderWindow win( VideoMode( 800, 800 ), L"Rozdział 1" );
    CircleShape circle( 50 );
    circle.setPosition( 0, 0 );
    circle.setOutlineColor( Color::Red );
    circle.setOutlineThickness( 2 );
    Texture texture;
    if( !texture.loadFromFile( "textura.png" ) )
         cerr << "Nie można załadować grafiki\n";
   
    circle.setTexture( & texture );
   
    while( win.isOpen() )
    {
        win.clear( Color::White );
        Event e;
        while( win.pollEvent( e ) )
        {
            if( e.type == Event::Closed )
                 win.close();
           
        }
       
        win.draw( circle );
        win.display();
    }
}
Przykład
Przykład