Programowanie w C Biblioteka grafiki winbgim i tworzenie obiektów graficznych Artur Opaliński (pokój E112) e-mail: (p.wykład administracyjny) URL: (p.wykład administracyjny)
Treść wykładu Biblioteka winbgim Od C do C++ Otwieranie i wymiary okna graficznego Tworzenie i usuwanie graficznego Elementu prostego Elementu złożonego Z elementów prostych Z użyciem mapy Jako wielokąta Jako obrazu z pliku 2
Support for Yoda Master Slajdy nie były przygotowane z myślą o samodzielnej nauce. Przyjdź na wykład, żeby je lepiej zrozumieć! Zdobądź punkty bonusowe: Korzystając z informacji z wykładu, Internetu, własnych doświadczeń, itp. - opisz myśli z tej prezentacji dokładniej i złóż na Wiki! Zaznacz, które numery slajdów omawiasz 3
Biblioteka winbgim Biblioteka winbgim Nie należy do standardu C++ =Może nie być dostępna z każdym kompilatorem C++...jednak do większości kompilatorów istnieją jakieś biblioteki graficzne, o podobnym przeznaczeniu jest wzorowana na bibliotece Borland Graphics Interface Wymaga dodania do środowiska IDE Samej biblioteki, zawierającej m.in. skompilowane funkcje Definicji w pliku nagłówkowym Dość tradycyjna biblioteka... Nie wymaga znajomości programowania obiektowego Nie wprowadza złożonych pojęć Jest niewielka (ok. 100 funkcji) 4
Biblioteka winbgim od C do C++ winbgim jest napisana w C++ i tym samym wymaga programowania w C++ Gratuluję znajomości już dwóch języków (C i C++) Język C++ stanowi nadzbiór języka C Programy w C można kompilować jako progr. w C++ - wystarczy użyć kompilatora do C++ Każdy program w C jest programem poprawnym w C++ Oczywiście, program napisany w C jest ubogi - nie korzysta z dodatkowych cech oferowanych przez C++ 5
Od C do C++ Na większość platform kompilatory C i C++ są dystrybuowane razem Również kompilatory MinGW w naszym IDE Należy wskazać, którym kompilatorem ma być kompilowany kod źródłowy Najprostszą metodą wskazania jest wybór rozszerzenia nazwy pliku: Kod w pliku z rozszerzeniem *.C jest domyślnie kompilowany przez kompilator C Kod w pliku z rozszerzeniem *.CPP jest domyślnie kompilowany przez kompilator C++ 6
Wskazanie kompilatora Kod źródłowy (w dowolnym języku) W pliku o nazwie z rozszerzeniem *.C Kompilator C Kod wykonywalny (maszynowy) W pliku o nazwie z rozszerzeniem *.CPP Kompilator C++ Kod wykonywalny (maszynowy) Kod wykonywalny przeważnie dłuższy; przeważnie dodatkowe Warnings pomagające w kompilacji 7
Od C do C++ Stosowanie kompilatora C++ może wymagać pewnych zmian w programie, np: Plik powinien mieć rozszerzenie *.cpp, nie *.c Kompilatory C++ produkują bardziej precyzyjne Warnings Nie można upraszczać definicji main() pomijając jej typ: Poprawne w C: Poprawne w C++: main(){ int main() { /* */ tu kod programu /* */ tu kod programu } return 0; } // mozna pominąć w main() 8
Biblioteka winbgim Rozpoczęcie i zakończenie: Zanim program będzie mógł rozpocząć korzystanie z grafiki, musi otworzyć dodatkowe okno graficzne: int maxw, maxh; maxw = getmaxwidth(); maxh = getmaxheight(); initwindow( maxw, maxh ); //jaki szeroki jest ekran? //jaki wysoki jest ekran? //otwórz okno na cały ekran Ekran komputera składa się z punktów, tzw. pikseli, i stąd rozdzielczość, rozmiary, czy współrzędne 9 podawane są jako liczba punktów na ekranie.
Test Jak otworzyć okno zajmujące ¼ powierzchni ekranu? a) initwindow( getmaxwidth(), getmaxheight() ); b) initwindow( getmaxwidth()/4, getmaxheight()/4 ); c) initwindow( getmaxwidth()/2, getmaxheight()/2 ); d) initwindow( 1024/2, 768/2 ); 10
Test Jak otworzyć okno zajmujące ¼ powierzchni ekranu? a) initwindow( getmaxwidth(), getmaxheight() ); b) initwindow( getmaxwidth()/4, getmaxheight()/4 ); c) initwindow( getmaxwidth()/2, getmaxheight()/2 ); d) initwindow( 1024/2, 768/2 ); Nie wiadomo czy to okno w ogóle zmieści się na ekranie (w niektórych urządzeniach bywają mniejsze ekrany i rozdzielczości) jaką część powierzchni ekranu zajmie okno? 11
Biblioteka winbgim Rozpoczęcie i zakończenie: Po zakończeniu korzystania z grafiki, program powinien zamknąć okno graficzne: closegraph(); Nie jest to konieczne przy kończeniu programu wszystkie okna zostaną zamknięte przez system operacyjny Od chwili otwarcia okna graficznego, program ma do dyspozycji (co najmniej) dwa okna! 12 Jak wskazać, gdzie program ma wyświetlić animację?
Biblioteka winbgim Funkcje Operacje w oknie tekstowym: printf(), putchar(), puts(), scanf(), itd. z <stdio.h> Operacje w oknie graficznym: getmaxx() //zwraca rozmiar poziomy okna, w punktach getmaxy() //zwraca rozmiar pionowy okna, w punktach putpixel(x,y,kol) //punkt na współrzędnych (x,y) w kolorze o numerze kol getpixel(x,y) //zwraca kolor punktu na współrzędnych (x,y) line(xp,yp,xk,yk) // linia od punktu (xp,yp) do (xk,yx) circle(x,y,r) //koło o środku w (x,y) i promieniu r rectangle(xp,yp,xk,yk) // prostokąt od punktu (xp,yp) do (xk,yx) outtextxy(x,y,"tekst"); // napis tekst od współrzędnych (x,y) 13 getch(); // pobranie kodu klawisza; czeka na wciśnięcie
Biblioteka winbgim Test inicjalizacji grafiki Otwarcie okna graficznego wiąże się z tzw. inicjalizacją grafiki Zostaje przydzielona dodatkowo pamięć dla programu Zostają zainicjalizowane zmienne w bibliotece winbgim Żąda się od systemu operacyjnego otwarcia okna graficznego Każdy z powyższych kroków może zawieźć Brak pamięci Niemożliwe otwarcie okna graficznego Inne nieoczekiwane sytuacje Dlatego po zakończeniu działania initwindow() wcale nie należy zakładać w ciemno, ze program może już korzystać z pozostałych funkcji winbgim Skąd program może wiedzieć, czy udało mu się otworzyć okno 14 graficzne?
Biblioteka winbgim Test inicjalizacji grafiki #include <graphics.h> #include <stdio.h> int main() { int errorcode; Ten program musi być w pliku z rozszerzeniem nazwy *.CPP initwindow(getmaxwidth()/2, getmaxheight()/2); /* otwar cie okna graficznego */ errorcode = graphresult(); // czy inicjalizacja sie udala? if (errorcode!= grok) { // Inicjalizacja nieudana! :-( printf("blad BGI: %s\n", grapherrormsg(errorcode)); printf("wcisnij dowolny klawicz, zeby zakonczyc:"); getch(); } else 15
Biblioteka winbgim Test inicjalizacji grafiki (c.d.) { // zadziałało else, czyli inicjalizacja sie udala! :-) line(0, 0, getmaxx(), getmaxy()); //narysuj linie outtextxy(0,0," Udało się, widzisz grafikę!"); getch(); closegraph(); //zamknij okno graficzne } } 16
Biblioteka winbgim Test inicjalizacji grafiki (c.d.) Przydatne elementy podczas testu inicjalizacji grafiki: graphresult() - funkcja winbgim zwracająca liczbe typu int tzw. kod błędu, informujący czy winbgim nie natrafiła na problemy w ostatnio wykonywanej swojej funkcji. Zwrócenie wartości niezerowej oznacza problem. Po odczytaniu kodu błędu wartość przechowywana przez winb- GIm zostaje wyzerowana (wskazując, że wykonanie ostatniej funkcji t.j. graphresult() się powiodło). grapherrormsg() - funkcja winbgim zamieniająca liczbę typu int (kod błędu), podaną jako jej argument, na łańcuch znaków - komunikat w języku angielskim, który opisuje na czym polegał błąd. 17
Biblioteka winbgim Test inicjalizacji grafiki (c.d.) Przydatne elementy podczas testu inicjalizacji grafiki: grok stała liczbowa winbgim. Zwrócenie takiej liczby przez graphresult() oznaczająca brak problemów w winbgim. Jest zdefiniowana w graphics.h jako zero: # define grok 0 exit() - standardowa funkcja języka C/C++. Jej deklaracja jest jednak dołączana poprzez #include zawarte w pliku graphics.h nie trzeba zatem dodawać we własnym kodzie #include <stdlib.h>. Natrafienie na nią w programie oznacza natychmiastowe zakończenie całego programu. Wartość int przekazana jej jako argument jest wówczas wartością zwracaną przez cały program; zwyczajowo wartość niezerowa 18 oznacza błąd, ale w naszym projekcie nie gra ona roli.
Funkcja pomocnicza W dalszych przykładach dla uproszczenia będzie wykorzystywana funkcja: #include <graphics.h> #include <stdio.h> void initgrafiki(unsigned int x, unsigned int y) { int errorcode; initwindow(x, y); // proba otwar cia okna graficznego errorcode = graphresult(); // czy inicjalizacja sie udala? if (errorcode!= grok) { // Inicjalizacja nieudana! :-( printf("blad nr %d BGI przy otwieraniu okna (%d, %d): %s\n", errorcode, x, y, grapherrormsg(errorcode) ); printf("wcisnij dowolny klawicz, zeby zakonczyc:"); getch(); exit(-1); // zakończ program; koniec zabawy :-( } 19 }
TEST: Jakie są możliwe kody błędów winbgim? Jak sprawdzić wszystkie możliwe kody błędów winb- GIm? Czyli: co może w programie pójść nie tak podczas działania winbgim? 20
TEST: Jakie są możliwe kody błędów winbgim? Jak sprawdzić wszystkie możliwe kody błędów winb- GIm? Czyli: co może w programie pójść nie tak podczas działania winbgim? Odp 1: Zajrzyj w Internecie do dokumentacji funkcji graphresult() Odp2: Uruchom kod, który wyświetli wszystkie (16) możliwe komunikaty o błędach: #include <graphics.h> #include <stdio.h> int i; initgrafiki(getmaxwidth()/10, getmaxheight()/10); /*malutkie okno; konieczne tylko, żeby zainicjalizować winbgim */ for(i=0; i>-16; i--) 21 printf("%d = %s\n", i, grapherrormsg(i));
Biblioteka winbgim Rozmiary ekranu i współrzędne na nim getmaxwidth() Otwarte okno graficzne winbgim getmaxheight() 22
Biblioteka winbgim Rozmiary ekranu i współrzędne na nim getmaxwidth() getmaxx() Otwarte okno graficzne winbgim getmaxy() getmaxheight() 23
Biblioteka winbgim Rozmiary ekranu i współrzędne na nim Punkt o współrzędnych (0;0) Otwarte okno graficzne winbgim Tak rośnie wartość y Tak rośnie wartość x Punkt o współrzędnych 24 (getmaxx(); getmaxy())
WinBGIm: Tworzenie prostego elementu Punkt #include <graphics.h> #include <stdio.h> Pierwszy argument to współrzędna x; drugi argument to współrzędna y, trzeci argument to kolor. Nazwy stałych liczbowych do oznaczenia kolorów patrz dokumentacja winbgim initgrafiki(getmaxwidth()/3, getmaxheight()/3); putpixel(5,15,white); /* ten punkt będzie blisko lewego górnego narożnika okna */ putpixel(getmaxx()-5,getmaxy()-15,yellow); /* ten punkt będzie blisko prawego dolnego narożnika okna */ 25
WinBGIm: Tworzenie prostego elementu Linie i prostokąty #include <graphics.h> #include <stdio.h> Argument pierwszy i drugi to współrzędne (x,y) jednego końca linii. Argument trzeci i czwarty to współrzędne (x,y) drugiego końca linii. Domyślny kolor rysowania. initgrafiki(getmaxwidth()/3, getmaxheight()/3); line(getmaxx(),0,0,getmaxy()) ;//przekątna od prawego górnego rogu do lewego dolnego */ rectangle(20,20,100,40); //prostokąt poziomy setcolor(green); Zmień domyślny kolor rysowania. //zmiana koloru rectangle(20,50,40,150); //prostokąt pionowy Argument pierwszy i drugi to współrzędne (x,y) lewego górnego narożnika prosto- 26 kąta. Argument trzeci i czwarty to współrzędne (x,y) prawego dolnego narożnika.
WinBGIm: Tworzenie prostego elementu Linie i prostokąty (c.d.) Do rysowania linii niekiedy mogą być wygodniejsze funkcje: void linerel (int dx, int dy); void lineto (int x, int y); Ich przeznaczenie doczytaj w dokumentacji winbgim 27
WinBGIm: Tworzenie prostego elementu Tekst w oknie graficznym #include <graphics.h> #include <stdio.h> initgrafiki(getmaxwidth()/3, getmaxheight()/3); outtextxy(10,160,"oto tekst"); ; //napis oto tekst Argument pierwszy i drugi to współrzędne (x,y) tekstu, t.j. jego lewego górnego narożnika. Sprawdź w dokumentacji winbgim: Jak zmienić kolor tekstu? Jak zmienić wielkość i krój czcionki? x=10 Jak zmienić kierunek tekstu (np. napisać pionowo) Jak zmienić justyfikację (ang. justify) tekstu? Sprawdź, co będze, gdy tekst nie zmieści się na ekranie lub gdy ma wiele linii y=160 oto tekst 28
WinBGIm: Tworzenie prostego elementu Tekst w oknie graficznym Funkcja outtextxy(), oraz podobna do niej outtext() to jedyne funkcje do wyświetlania znaków na ekranie graficznym Jako argument wymagają napisu: albo jako stałej łańcuchowej, albo jaki zmiennej łańcuchowej: x=10; y=160; v=oblicz(); char napis[]="twoja predkosc to:"; outtextxy(x, y, napis); Jak wyświetlić wartość stałej czy zmiennej liczbowej (np. powyżej zmiennej v, opisującej prędkość)? Czyli znaki: 0,1,2,3,4 29
Test: Tekst w oknie graficznym x=10; y=160; v=oblicz(); char napis[]="twoja predkosc to:"; outtextxy(x, y, napis); Jak wyświetlić wartość stałej czy zmiennej liczbowej (np. powyżej zmiennej v, opisującej prędkość)? Czyli znaki: 0,1,2,3,...,8,9, może z kropką dziesiętną, może z minusem, może w notacji wykładniczej (np.. 3.4E-10) a) outtext(x,y,v); b) outtext(x,y,"v"); c) outtext(x,y,"\v"); d) outtext(x,y,char(v)); e) outtext(x,y,"%f",v); f) nie ma takiej możliwości 30
Test: Tekst w oknie graficznym x=10; y=160; v=oblicz(); char napis[]="twoja predkosc to:"; outtextxy(x, y, napis); Jak wyświetlić wartość stałej czy zmiennej liczbowej (np. powyżej zmiennej v, opisującej prędkość)? Czyli znaki: 0,1,2,3,...,8,9, może z kropką dziesiętną, może z minusem, może w notacji wykładniczej (np.. 3.4E-10) a) outtext(x,y,v); b) outtext(x,y,"v"); c) outtext(x,y,"\v"); d) outtext(x,y,char(v)); e) outtext(x,y,"%f",v); f) nie ma takiej możliwości Biblioteka winbgim drukuje wyłącznie gotowe łańcuchy. Wkrótce poznamy w C/C++ sposób zamiany dowolnej liczby 31 na łańcuch.
WinBGIm: Tworzenie prostego elementu Wypełnanie Dotychczas prostokąty były rysowane tylko w postaci boków Żeby wypełnić figurę kolorem: Można ją od razu narysować wypełnioną kolorem Można ją od pokolorować później W każdym wypadku kolorowanie odbędzie się zgodnie z aktualnymi wartościami dwóch wewnętrznych zmiennych winbgim: koloru wypełnienia wzoru wypełnienia 32
WinBGIm: Tworzenie prostego elementu Wypełnanie Dotychczas prostokąty były rysowane tylko w postaci boków Żeby wypełnić figurę kolorem: Można ją od razu narysować wypełnioną kolorem Można ją od pokolorować później W każdym wypadku kolorowanie odbędzie się zgodnie z aktualnymi wartościami dwóch wewnętrznych zmiennych winbgim: koloru wypełnienia wzoru wypełnienia 33
WinBGIm: Tworzenie prostego elementu Wypełnanie setcolor(green); circle(200, 300, 100); /* narysuj okrąg w kolorze GREEN; niewypelniony */ floodfill (200, 300, GREEN); /* pokoloruj domyślnymi ustawieniami wzoru i koloru wypełnienia wszystkie punkty: --- poczynając od punktu (200, 300) t.j. od środka okręgu, --- aż do natrafienia na kolor GREEN) */ 34
WinBGIm: Tworzenie prostego elementu Wypełnanie setcolor(green); circle(200, 300, 100); /* narysuj okrąg w kolorze GREEN; niewypelniony */ setfillstyle(solid_fill, BLUE); /* zmień aktualne ustawienia wzoru i koloru wypełnienia */ floodfill (200, 300, GREEN); /* pokoloruj aktualnymi ustawieniami wzoru i koloru wypełnienia wszystkie punkty: --- poczynając od punktu (200, 300) t.j. od środka okręgu, --- aż do natrafienia na kolor GREEN) */ 35
WinBGIm: Tworzenie prostego elementu Wypełnanie setcolor(black); setfillstyle(line_fill, RED); /* zmień aktualne ustawienia wzoru i koloru wypełnienia na wypełnianie czerwonymi liniami*/ fillellipse (100, 200, 50, 50); /* narysuj koło (elipsę o promieniach 50 i 50, i środku w punkcie (100,200)) o obrzeżu czarnym, w aktualnych ustawieniach wypełnienia */ Zachodzące słońce? 36
Tworzenie prostego elementu Podsumowanie Tworzenie prostego elementu w trybie graficznym wymaga: Ustalenia współrzędnych, które mieszczą się w otwartym oknie Uwzględnienia przy tym że element ma swoje rozmiary, i zapewne cały ma się mieścić na ekranie Wyboru koloru (zawsze) Wyboru wypełnienia (dla figur innych niż punkt i linia) Oczywiście zawsze najpierw trzeba zainicjalizować okno graficzne 37
Tworzenie elementu złożonego Najprostsze tworzenie elementów złożonych to komponowanie ich z elementów prostych Jeżeli komponenty proste będą miały odpowiednio dobrane kolory obwodu, to można łatwiej wypełnić złożony element przez floodfill() Podobnie jak przy otwieraniu okna należy uwzględnić, że ekrany miewają różną rozdzielczość. Najlepiej, żeby wielkość obiektów była zależna od wielkości aktualnie otwartego okna. Współrzędne poszczególnych prostych elementów powinny być sparametryzowane względem wybranego punktu odniesienia (np. środka głowy) jeżeli zmieni się współrzędne głowy, wówczas łatwo przemieścić cała postać 9 prostokątów i jedno koło 38
Tworzenie elementu złożonego Jak tworzyć bardziej skomplikowane elementy, złożone z wielu punktów? Skoro można narysować punkt, to w czym problem z wieloma punktami? Rozwiązanie 1: skoro element składa się ze 100 punktów, to założyć zmienne x1..x100 i y1..y100 Wiele punktów, to Wiele np. współrzędnych do przechowywania...które trzeba aktualizować...które trzeba sprawdzać (mieszczą się na ekranie? Czy ich wyświetlenie nie zakryje innego elementu? Rozwiązanie 2: Przechowywać tylko współrzędne jednego narożnika elementu, zaś punkty składowe opisać mapą (tablicą dwuwymiarową) 39
Tworzenie elementu złożonego (c.d.) Ustalenie współrzędnych prowadzone tylko dla tego punktu Wszystkie pozostałe punkty elementu wyświetlane są zawsze na tych samych pozycjach względem lewego górnego narożnika Jak długo oba objęte czerwonym kółkiem punkty mieszczą się na ekranie, tak długo widać cały element 40
Tworzenie elementu złożonego z użyciem mapy #include <graphics.h> #define POKAZ 1 #define UKRYJ 0 #define SZER 18 #define WYS 22 41
Tworzenie elementu złożonego z użyciem mapy (c.d.) void samolot(int x, int y, int widzialny){ int w,k; char rys[wys][szer]={ {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1,1, 1,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1,1, 1,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,1,1,1, 1,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,1,1,1, 1,1,1,0,0,0,0,0,0}, {0,0,0,0,1,1,1,1,1, 1,1,1,1,1,0,0,0,0}, {0,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0}, {1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1}, {0,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,0}, {0,0,0,0,1,1,1,1,1, 1,1,1,1,1,0,0,0,0}, {0,0,0,0,0,0,1,1,1, 1,1,1,0,0,0,0,0,0}, {0,0,0,0,0,0,0,1,1, 1,1,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,1, 1,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,1,1,1, 1,1,1,0,0,0,0,0,0}, {0,0,0,0,1,1,1,1,1, 1,1,1,1,1,0,0,0,0}, {0,0,0,0,1,1,1,1,1, 1,1,1,1,1,0,0,0,0} }; Wartości 0 oznaczają, że dany piksel nie ma być rysowany; wartości 1 że dany piksel ma być rysowany. Ew. zamiast wartości 0 i 1 można podawać numery koloru piksela 42
Tworzenie elementu złożonego z użyciem mapy (c.d.) kontynuacja funkcji samolot() rysowanie elementu na pozycjach (w;k) względem lewego górnego narożnika (x;y): for(w=0;w<wys;w++) for(k=0;k<szer;k++) if(widzialny) { if(rys[w][k]==1) // jak uzyskać kolorowy obrazek? putpixel(x+k,y+w, YELLOW); } else { if(rys[w][k]==1) putpixel(x+k,y+w, BLACK); } } 43
Tworzenie elementu złożonego, z użyciem mapy: wady Powolność wywołanie funkcji samolot()...rysuje SZER*WYS punktów Oko ludzkie rejestruje momenty na ekranie, gdy element nie jest w całości narysowany Rozwiązania: Przyspieszyć realizację funkcji samolot()? Jak? :-( Zmniejszyć ilość punktów do rysowania np. zauwazyć, że w kolejnej klatce większość punktów i tak zostanie narysowanych tam, gdzie (inne) punkty były w poprzedniej klatce Zastosować szybszy język programowania Funkcje winbgim są częściowo napisane w assemblerze, i dobrze zoptymalizowane 44
Tworzenie elementu złożonego jako wielokąta: fillpolly() Funkcja fillpoly() o nagłówku: void fillpoly (int numpoints, int polypoints[] )...rysuje dowolny wielokąt (=dowolny kształt), i zamalowuje jego wnętrze Działa bardzo szybko, mimo że rysuje wiele punktów Parametr numpoints podaje, z ilu wierzchołków składa się wielokąt Parametr polypoints[] to tablica liczb int, zawierająca współrzędne wierzchołków w postaci: {x1,y1, x2,y2, x3,y3,...} Współrzędne (x,y) pierwszego punktu, współrzędne (x,y) drugiego punktu, itd.. 45
Tworzenie elementu złożonego jako wielokąta: fillpolly(), c.d. Przed fillpoly() wcześniej warto wskazać kolor, oraz linię obwodu, oraz sposób wypełnienia: Nagłówek funkcji do ustawienia koloru linii obwodu: void setcolor(int color) Nazwa: setcolor() Nic nie zwraca Pobiera jeden parametr: liczbę określającą numer koloru Nagłówek funkcji do ustawienia stylu linii obwodu: void setlinestyle (int linestyle, unsigned upattern, int thickness) Nazwa: setlinestyle(); Nic nie zwraca linestyle to np. SOLID_LINE, wówczas upattern jest pomijany (można podać dowolną wartość) thickness to NORM_WIDTH (1 pixel) lub THICK_WIDTH (3 pixele) 46
Tworzenie elementu złożonego jako wielokąta: fillpolly(), c.d. Nagłówek funkcji do ustawienia stylu wypełnienia wielokąta: void setfillstyle (int pattern, int color); Nazwa: setfillstyle() Nic nie zwraca Parametr pattern określa szraf, np. SOLID_FILL Parametr color to numer koloru (np. YELLOW) 47
Tworzenie elementu złożonego jako wielokąta (DEMO) #include <graphics.h> #define WIERZCHOLKI 3 int obrys[wierzcholki*2]={ /*Trójkat równoramienny. Każdy wierzchołek ma 2 współrzędne */ 10,0, 0,20, 20,20 }; setlinestyle(solid_line,0,norm_width); /* obwód linią ciągłą, normalnej szerokości */ setcolor(black); // czarny kolor linii obwodu setfillstyle(solid_fill, YELLOW); // wypełnienie żółte fillpoly(wierzcholki, obrys); //narysuj wypełniony wielokąt 48
Tworzenie elementu złożonego jako wielokąta (DEMO) Niezamalowany wielokąt można utworzyć funkcją o nagłówku: void drawpoly (int numpoints, int polypoints[]) Taki wielokąt może być wypełniony kolorem i szrafem w dowolnym momencie. Szczegóły w dokumentacji wingbim 49
Tworzenie elementu złożonego jako obrazu Biblioteka wingbim pozwala wyświetlić jako element gotowy obraz Z pliku Z pamięci komputera Do wyświetlenia obrazu z pliku służy funkcja o nagłówku: void readimagefile( const char* filename, int left, int top, int right, int bottom ) Szczegóły w dokumentacji winbgim 50
Tworzenie elementu złożonego jako obrazu Do manipulowania obrazami w pamięci komputera służą funkcje o nagłówkach: unsigned imagesize (int left, int top, int right, int bottom); Podaje, ile miejsca przygotować w pamięci na zadany fragment obrazu pobrany z ekranu komputera void getimage (int left, int top, int right, int bottom, void bitmap[]); Kopiuje do zadanego miejsca w pamięci zadany fragment obrazu, pobrany z ekranu komputera void putimage(int left, int top, void bitmap[], int op); Przenosi obraz z pamięci na ekran, i nakłada go na istniejący w tym miejscu obraz zgodnie z operacją op 51
Usuwanie elementu graficznego Tło jednolite Główną metodą usunięcia elementy graficznego z ekrany jest zamalowanie go w kolorze tła Np. na jednolitym, czarnym tle można wyświetlić elementy: putpixel(a,b,white); //współrzędne a,b powinny mieścić się na ekranie setcolor(white); //wybierz kolor do rysowania okręgu poniżej circle(x,y,r); //zmienne x,y,r powinny zapewniać zmieszczenie elementu na ekranie...i usunąć te elementy, poprzez narysowanie ich w tym samym miejscu, w kolorze tła: putpixel(a,b,black); // jeśli tło było czarne element zniknie setcolor(black); circle(x,y,r); // jeśli tło było czarne element zniknie 52
Usuwanie elementu graficznego Tło niejednolite W przypadku, gdy tło nie jest jednolite (np. narysowana trawa), trzeba jego poprzednią zawartość - która była w tym miejscy przed narysowaniem nowego elementu - narysować na nowo zamalowując w ten sposób usuwany element Czyli poprzednią zawartość obszaru trzeba zapamiętać, przed narysowaniem elementu To (względnie) łatwe, jeśli ten oobszar to stały element tła, i wiadomo, jak go narysować Jeśli trudno jest odtworzyć tło, przed narysowaniem elementu trzeba zapamiętać obszar, przykrywany przez ten element, np. używając: unsigned int getpixel(int x, int y); void getimage (int left, int top, int right, int bottom, void bitmap[]); 53
Co powinienem wiedzieć? Znać podstawowe podobieństwa i róznice przy programowaniu w C i C++ Znać podstawowe funkcje do tworzenia i zamykania okna grafiki w winbgim Znać podstawowe funkcje wykorzystujące okno grafiki Umieć tworzyć proste obiekty graficzne Umieć tworzyć złożone obiekty graficzne, Z elementów prostych Opisane mapą punktów Opisane jako wielokąt (wierzchołkami) Umieć sprawdzić, czy obiekt w całości mieści się na ekranie Umieć odczytywać podstawowe informacje z prototypów funkcji Znać sposoby wypełniania obiektów kolorem i szrafem 54 Rozumieć problem usuwania obiektów graficznych