Tworzenie grafiki SDL

Poprzednie tematy, które należy przerobić przed przystąpieniem do tej lekcji:

01 - Instalacja biblioteki SDL dla Dev-C++
02 - Powierzchnia graficzna w SDL - stawianie punktów
03 - Tworzenie biblioteki graficznej mylib
04 - Stawianie punktów i rysowanie linii poziomych oraz pionowych

Pliki biblioteczne i projektowe do pobrania: Parametry dla konsolidatora
mylib.h
mylib.cpp
main.cpp
-lmingw32
-mwindows
-lSDLmain
-lSDL

Opis funkcji bibliotecznych

Na tej lekcji poznasz sposoby pracy z pikselami na powierzchni graficznej. Przy okazji utworzysz ciekawą grafikę komputerową.

Zabawa z pikselami

SDL

Przed przystąpieniem do ćwiczeń utwórz nowy katalog. W katalogu utwórz nowy projekt SDL. Jako główny plik programu wybierz main.cpp z linku powyżej. Na początku programu dodaj wpis:

        #include <cmath>

 

W naszej bibliotece mamy do dyspozycji funkcje stawiające punkt na powierzchni graficznej plot(x,y,color) oraz wyliczającej kolor ze składowych rgb(R,G,B).

Wykorzystamy te funkcje do otrzymania różnych ciekawych efektów. Na pierwszy ogień idzie funkcja sinus. Co o niej wiesz?

  1. Jest to funkcja okresowa, tzn. jej wartości powtarzają się dla argumentów różniących się wielokrotnością okresu 2π:
            sin(x) = sin(x ± 2π) = sin(x ± 2 • 2π) = sin(x ± 3 • 2π) = sin(x ± 4 • 2π) = ... = sin(x ± k • 2π).

  2. Wartości funkcji mieszczą się w przedziale <-1,1>.

Załóżmy, iż chcielibyśmy otrzymać w oknie SDL wykres jednego okresu funkcji sinus. Wykres musimy odpowiednio przeskalować, aby objął całe okno:

 

Oryginalny wykres funkcji sinus Wykres przeskalowany do okna SDL

 

W oknie SDL będziemy używali współrzędnych okna. Współrzędne wykresu muszą być zatem odwzorowane we współrzędne okna SDL:

Dodatkowo zwróć uwagę, iż układ współrzędnych SDL jest odwrócony do góry nogami w stosunku do układu współrzędnych kartezjańskich. Musimy ten fakt uwzględnić w naszych obliczeniach. Zastosujemy następujące wzory przeliczeniowe:

x = 2π • i / (w - 1), gdzie i przebiega wartości od 0 do w-1.

Wyliczoną wartość x podstawiamy do funkcji sinus i otrzymujemy jej wartość y. Wartość y przeliczamy na współrzędną ekranową ye wg wzoru:

ye = (1 - y) / 2 • (h - 1)

 

Ostatecznie do szablonu aplikacji SDL wstawiamy następujący fragment kodu:

 

for(int i = 0; i < screen->w; i++)
  plot(i,(Uint32)((1 - sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)),0xFFFFFF);

 

Rzutowanie (Uint32) ma na celu konwersję wyniku z typu double na typ argumentu Uint32. Pominięcie go spowoduje wygenerowanie ostrzeżenia przez kompilator, a ja lubię, gdy kompilacja przebiega bez żadnych komunikatów ostrzegawczych.

Efektem programu jest okno SDL z wykresem jednego okresu funkcji sinus:

 

 

Teraz dokonajmy prostej modyfikacji programu. Rysowanie sinusoidy powtórzymy 100 razy skalując wartość funkcji kolejno przez współczynniki od 0,01 do 1 co 1/100. W tym celu kod obejmujemy kolejną pętlą, w której będziemy generować wartość współczynnika f.  Instrukcję plot musimy nieco zmodyfikować, aby uwzględniała współczynnik f:

 

for(double f = 0.01; f <= 1; f += 0.01)
  for(int i = 0; i < screen->w; i++)
    plot(i,(Uint32)((1 - f * sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)),0xFFFFFF);

 

 

Wykorzystajmy współczynnik f do modyfikacji koloru kolejnych sinusoid. W tym celu wykorzystamy funkcję rgb() z odpowiednimi składowymi koloru:

 

for(double f = 0.01; f <= 1; f += 0.01)
  for(int i = 0; i < screen->w; i++)
    plot(i,(Uint32)((1 - f * sin(6.28 * i / (screen->w - 1))) / 2 * (screen->h - 1)),
            rgb((Uint32)(f*255),255-(Uint32)(f*255),255));

 

 

Poeksperymentuj z różnymi wartościami kolorów. Uzależnij je również od współrzędnej na osi x. Można w ten sposób otrzymać ciekawe efekty graficzne:

 

 

A tutaj mamy nieco zaawansowany przykład - skalujemy wykres funkcji sin(x + fx2) również względem współrzędnej x. Otrzymany wykres odbijamy w pionie i poziomie i otrzymujemy interesującą grafikę - spróbuj zmienić wymiary okna oraz zagęścić zmiany współczynnika f:

 

double x,y;
Uint32 color;

for(double f = 0.005; f <= 1; f += 0.005)
  for(int i = 0; i < screen->w; i++)
  {
    x = 6.28 * i / (screen->w - 1);
    y = (1 - f * sin(x + f * x * x / 2)) / 2 * (screen->h - 1);
    color = rgb(255-(Uint32)((double)(i * 255)/(screen->w - 1)),
               (Uint32)(f * 255),
               (Uint32)((double)(i * 255)/(screen->w - 1)));
    plot(i,(Uint32)((i * y)/(screen->w - 1)),color);
    plot(i,screen->h - 1 - (Uint32)((i * y)/(screen->w - 1)),color);
    plot(screen->w - i - 1,(Uint32)((i * y)/(screen->w - 1)),color);
    plot(screen->w - i - 1,screen->h - 1 - (Uint32)((i * y)/(screen->w - 1)),color);
  }

 

 



List do administratora Serwisu Edukacyjnego Nauczycieli I LO

Twój email: (jeśli chcesz otrzymać odpowiedź)
Temat:
Uwaga: ← tutaj wpisz wyraz  ilo , inaczej list zostanie zignorowany

Poniżej wpisz swoje uwagi lub pytania dotyczące tego rozdziału (max. 2048 znaków).

Liczba znaków do wykorzystania: 2048

 

W związku z dużą liczbą listów do naszego serwisu edukacyjnego nie będziemy udzielać odpowiedzi na prośby rozwiązywania zadań, pisania programów zaliczeniowych, przesyłania materiałów czy też tłumaczenia zagadnień szeroko opisywanych w podręcznikach.



   I Liceum Ogólnokształcące   
im. Kazimierza Brodzińskiego
w Tarnowie

©2017 mgr Jerzy Wałaszek

Dokument ten rozpowszechniany jest zgodnie z zasadami licencji
GNU Free Documentation License.