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

obrazek

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
obrazek obrazek

 

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:

 

obrazek

 

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);

 

obrazek

 

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));

 

obrazek

 

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:

 

obrazek

 

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);
  }

 

obrazek

 


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

©2024 mgr Jerzy Wałaszek

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

Pytania proszę przesyłać na adres email: i-lo@eduinf.waw.pl

W artykułach serwisu są używane cookies. Jeśli nie chcesz ich otrzymywać,
zablokuj je w swojej przeglądarce.
Informacje dodatkowe