Grafika
Język C++ umożliwia graficzną prezentację danych za pomocą standardowych funkcji graficznych znajdujących się w pliku graphics.h. Funkcje te (jest ich ponad 80) pozwalają m.in. rysować na ekranie pracującym w trybie graficznym krzywe różnych kształtów i kolorów, wypełniać kontury określonym kolorem i deseniem, wyświetlać na ekranie napisy (poziomo i pionowo) w różnych krojach pisma, z możliwością skalowania kroju oraz justowania napisu.
Mikrokomputery klasy IBM PC mogą być wyposażone w różne karty graficzne, np. EGA, VGA, SVGA, VESA, obsługujące ekrany monitorów o różnej rozdzielczości. Rozdzielczość ekranu, czyli liczba wyświetlanych w poziomie i pionie punktów, jest ściśle związana z procedurami i funkcjami graficznymi. W celu uniezależnienia systemu C++ od kart graficznych komputerów, przewidziano dla najczęściej stosowanych kart sterowniki, tj. programy obsługujące związek funkcji graficznych z tymi kartami. Sterowniki są plikami z rozszerzeniem .BGI. Oprócz sterowników, programy graficzne korzystające z innych niż standardowy krojów pisma powinny mieć dostęp do plików zawierających definicje tych krojów. Są to pliki z rozszerzeniem .CHR.
Wykorzystanie funkcji graficznych z pliku graphics.h wymaga jego deklaracji w dyrektywie #include. Ponadto, przed wywołaniem pierwszej funkcji graficznej, tryb graficzny powinien być zainicjalizowany przez wywołanie funkcji detectgraph i initgraph. Na zakończenie wykonywania operacji graficznych należy zamknąć tryb graficzny za pomocą funkcji closegraph, która powoduje usunięcie z pamięci sterownika graficznego i powrót do trybu tekstowego.
Podczas pracy w trybie graficznym istnieje także możliwość przełączania trybu graficznego na tekstowy i odwrotnie (funkcje restorecrtmode i setgraphmode).
Ekran w trybie graficznym posiada inny układ współrzędnych niż w trybie tekstowym. Każdy punkt tego ekranu ma swoje współrzędne, przy czym punkt znajdujący się w lewym górnym narożniku ma współrzędne (0, 0), a punkt w dolnym prawym narożniku ma współrzędne zależne od karty graficznej , które mogą być określone za pomocą funkcji standardowych getmaxx i getmaxy. Przykładowo, dla karty graficznej VGA współrzędne ekranu graficznego ilustruje poniższy rysunek:
Karty graficzne, w zależności od trybu pracy, mogą mieć od jednej do kilku stron graficznych. Zwiększenie stron graficznych odbywa się kosztem pogorszenia rozdzielczości karty. Poniżej podano parametry graficzne karty VGA dla różnych trybów:
VGALO - 640×200 pkt., 16 kolorów, 4 strony graficzne;
VGAMed - 640×350 pkt., 16 kolorów, 2 strony graficzne;
VGAHI - 640×480 pkt., 16 kolorów, 1 strona graficzna.
Większa liczba stron graficznych może być wykorzystana do tworzenia animacji za pomocą manipulowania stronami aktywnymi i widocznymi.
Kursor w trybie graficznym, w odróżnieniu od trybu tekstowego, jest niewidoczny, ale w każdej chwili można określić jego współrzędne za pomocą funkcji getx i gety.
1. Predefiniowane stałe graficzne
Stałe są wykorzystywane przez standardowe funkcji z pliku graphics.h. Służą one do definiowania sterowników kart graficznych i trybów ekranu, oznaczania kolorów i wzorów wypełnień, określenia rodzaju i grubości linii, oznaczania krojów pisma, kierunku wyprowadzania napisów i sposobu ich justowania itd. Poniżej przytoczono najczęściej używane w programach stałe predefiniowane i ich wartości domyślne (kody).
Stałe oznaczania kolorów
nazwa kod
BLACK = 0; { czarny }
BLUE = 1; { niebieski }
GREEN = 2; { zielony }
CYAN = 3; { turkusowy }
RED = 4; { czerwony }
MAGENTA = 5; { karmazynowy }
BROWN = 6; { brązowy }
LIGHTGRAY = 7; { jasnoszary }
DARKGRAY = 8; {ciemnoszary }
LIGHTBLUE = 9; { jasnoniebieski }
LIGHTGREEN= 10; { jasnozielony }
LIGHTCYAN = 11; { jasnoturkusowy }
LIGHTRED = 12; { jasnoczerwony }
LIGHTMAGENTA = 13; { jasnokarmazynowy }
YELLOW = 14; { żółty }
WHITE = 15; { biały }
Stałe te mogą być wykorzystane np. w procedurach ustalających kolor pierwszoplanowy i kolor tła:
setcolor(YELLOW); (* kolor pierwszoplanowy - żółty *)
setbkcolor(BLUE); (* kolor tła - niebieski *)
Stałe określania rodzaju i grubości linii
Stałe predefiniowane należące do tej grupy służą do oznaczania rodzajów linii oraz ich grubości. Są one wykorzystywane w procedurze setlinestyle określającej sposób rysowania linii, a ich definicja jest następująca:
nazwa kod
SOLID_LINE = 0; (* linia ciągła *)
DOTTED_LINE = 1; (* linia kropkowana *)
CENTER_LINE = 2; (* linia symetrii *)
DASHED_LINE = 3; (* linia przerywana *)
USERBIT_LINE = 4; (* linia definiowana przez programistę *)
NORM_WIDTH = 1; (* linia o normalnej grubości
(pojedyncza) *)
THICK_WIDTH = 3; (* linia pogrubiona (potrójna grubość) *)
Stała USERBIT_LINE oznacza rodzaj linii definiowanej przez programistę za pomocą procedury setlinestyle.
Stałe wzorów wypełniających kontury
Stałe te służą do określania sposobu wypełniania konturów. Są one wykorzystywane w procedurze setfillstyle, a ich definicja jest następująca:
nazwa kod
EMPTY_FILL = 0; (* wypełnianie w kolorze tła *)
SOLID_FILL = 1; (* wypełnianie w kolorze pierwszoplanowym *)
LINE_FILL = 2; (* wzór - linie poziome *)
LTSLASH_FILL= 3; (* wzór - linie ukośne cienkie *)
SLASH_FILL = 4; (* wzór - linie ukośne pogrubione *)
BKSLASH_FILL= 5; (* wzór - linie ukośne prawostronne pogrub. *)
LTBKSLASH_FILL= 6; (* wzór - linie ukośne prawe; ciemne tło *)
HATCH_FILL = 7; (* wzór - siatka prostokątna *)
XHATCH_FILL = 8; (* wzór - siatka ukośna *);
INTERLEAVE_FILL = 9; (* wzór - linie pionowe; ciemne tło *)
WIDE_DOT_FILL = 10; (* wzór - kropki rzadkie *)
CLOSE_DOT_FILL = 11; (* wzór - kropki gęste *)
USER_FILL = 12; (* wzór definiowany przez programistę *)
Stała USER_FILL oznacza wypełnienie konturów wzorem definiowanym przez programistę za pomocą procedury setfillpattern.
Stałe krojów pisma, kierunku wyprowadzania tekstów i rozmiaru liter
W trybie graficznym dostępnych jest 11 różnych krojów pisma: standardowe, „triplex”, małe, bezszeryfowe, gotyckie i sześć innych krojów ponumerowanych od 5 do 10 o rozmiarach od 1 do 10, przy czym poza pierwszym krojem, którego matryca wynosi 8×8 bitów (pikseli), wszystkie pozostałe są krojami wektorowymi. Do określania krojów pisma służą następujące stałe predefiniowane:
nazwa kod
DEFAULF_FONT = 0;
TRIPLEX_FONT = 1;
SMALL_FONT = 2;
SANSSERIF_FONT = 3;
GOTHIC_FONT = 4;
SCRIPT_FONT = 5;
SIMPLEX_FONT = 6;
TRIPLEX_SCR_FONT = 7;
COMPLEX_FONT = 8;
EUROPEAN_FONT = 9;
BOLD_FONT = 10;
Podane stałe są wykorzystywane w procedurze settextstyle.
Z pismem wyprowadzanym na ekran związane są także stałe określające kierunek wyprowadzania tekstu:
nazwa kod
HORIZ_DIR = 0; (* wyprow. poziome od strony lewej do prawej *)
VERT_DIR = 1; (* wyprow. pionowe z góry na dół *)
Stałe justowania tekstu w poziomie i pionie
Do określenia sposobu justowania tekstu w poziomie i pionie służą stałe zdefiniowane następująco:
nazwa kod
CENTER_TEXT = 1; (* centrowanie tekstu *)
LEFT_TEXT = 0; (* wyrównanie w poziomie do lewej *)
RIGTH_TEXT = 2; (* wyrównanie w poziomie do prawej *)
BOTTOM_TEXT = 0; (* wyrównanie w pionie do dołu *)
TOP_TEXT = 2; (* wyrównanie w pionie do góry *)
Stałe te są wykorzystywane w procedurze settextstyle. Domyślnie wyprowadzany tekst jest wyrównywany w poziomie do lewej i w pionie do dołu.
2. Wybrane funkcje pliku graphics.h.
2.1. Rozdzielczość karty graficznej
getmaxx - funkcja zwraca rozdzielczość karty graficznej względem osi X;
getmaxy - funkcja zwraca rozdzielczość karty graficznej względem osi Y.
Przykładowo, dla karty graficznej VGA funkcja getmaxx zwraca wartość 640.
2.2. Kursor graficzny
getx - funkcja zwraca aktualną współrzędną X kursora;
gety - funkcja zwraca aktualną współrzędną Y kursora;
moveto(X,Y) - procedura przesuwa kursor do punktu ekranu o współrzędnych (X,Y);
moverel(dX, dY) - procedura przesuwa kursor graficzny do punktu ekranu
o współrzędnych zmienionych w stosunku do aktualnych
odpowiednio o dX i dY.
Przykład:
moveto(50, 130); (* ustawienie kursora graficznego w punkcie *)
(* o współrzędnych (50, 130) *)
moverel(60, 25); (* przesunięcie kursora graficznego z punktu *)
(* o współrzędnych (50, 130) do punktu *)
(* o współrzędnych (110, 155) *)
2.3. Teksty w trybie graficznym.
settextstyle(czcionka, kierunek_wyprowadzania, rozmiar_czcionki)
Procedura określa styl wyprowadzanego tekstu. Przykładowo:
settextstyle(SANS_SERIF_FONT, HORIZ_DIR, 5) - procedura ustala, że wyprowadzany na ekran monitora tekst będzie pisany czcionką SANS_SERIF_FONT, poziomo i będzie miał rozmiar 5.
Jeżeli nie określimy stylu za pomocą procedury settextstyle, to tekst będzie pisany czcionką domyślną, poziomo.
Sposób justowania tekstu względem aktualnej pozycji kursora określamy za pomocą procedury:
settextjustify (poziom, pion )
Przykładowo, procedura settextjustify (CENTER_TEXT, TOP_TEXT) spowoduje wyśrodkowanie tekstu w poziomie i wyrównanie do góry w pionie. Domyślny sposób justowania - wyrównanie do lewej w poziomie i do dołu w pionie.
Do wyprowadzania tekstów służą dwie procedury:
outtext(łańcuch_znaków) - wyprowadzenie podanego
łańcucha znaków poczynając
od aktualnej pozycji kursora;
outtextxy(X, Y, łańcuchz_znaków) - wyprowadzenie podanego
łańcucha znaków poczynając
od punktu (X, Y).
Przykłady:
outtextxy(320, 160, ″Ala ma kota″);
settextjustify (RIGHT_TEXT, TOP_TEXT);
outtextxy (320, 160, ″Ala ma kota″);
settextjustify(CENTER_TEXT, CENTER_TEXT);
outtextxy(320, 160, ″Ala ma kota″);
2.4. Struktura linii
setlinestyle(rodzaj_linii, wzór, grubość)
Procedura określa rodzaj linii i jej grubość. Wszystkie parametry muszą być typu całkowitego. Parametr wzór jest istotny tylko w przypadku, gdy rozdaj linii jest określony przez stałą USERBIT_LINE. W przeciwnym przypadku może przyjmować dowolną wartość typu całkowitego. Jeżeli linia jest definiowana przez programistę (parametr wzór jest równy stałej USERBIT_LINE), to na ekranie będą wyświetlone tylko te punkty linii, które odpowiadają bitom o wartości 1.
2.5. Kreślenie figur
a). Linia prosta
line(x1, y1, x2, y2) (* kreślenie linii prostej łączącej punkty *)
(* o współrzędnych (x1, y1) i (x2, y2) *)
lineto(x, y); (* kreślenie linii prostej łączącej punkt o aktualnych *)
(* współrzędnych z punktem (x, y) *)
linerel(dX, dY); (* kreślenie linii prostej łączącej punkt o aktualnych *)
(* współrzędnych z punktem , którego współrzędne *)
(* różnią się od aktualnych o dX i dY *)
b). Prostokąt
rectangle(x1, y1, x2, y2); (* (x1, y1) - współrzędne lewego górnego *)
(* narożnika prostokąta, natomiast (x2, y2) *)
(* są to współrzędne prawego dolnego *)
(* narożnika prostokąta *)
c). Wielobok
drawpoly(liczba_punktów, współrzędne_punktów);
(* liczba punktów musi być o 1 większa *)
(* od liczby wierzchołków wieloboku *)
Współrzędne punktów muszą być sekwencją par liczb całkowitych odpowiadających współrzędnym x oraz y kolejnych wierzchołków wieloboku.
d). Okrąg
circle(x, y, r); (* rysowanie okręgu o promieniu r, którego *)
(* środek znajduje się w punkcie (x,y) *)
e). Łuk okręgu
arc (x, y, α, β, r); (* rysowanie łuku okręgu o promieniu r, którego *)
(* środek znajduje się w punkcie (x, y); *)
(* α - kąt początkowy łuku; *)
(* β - kąt końcowy łuku. *)
f). Wypełnianie konturów zamkniętych
setfillstyle(wzór, kolor) (* określenie wzoru wypełniającego kontur *)
(* kolor - jest kolorem konturu *)
C++ oferuje 12 wzorów standardowych (patrz stałe wypełnień) oraz wzór programisty USER_FILL. Użycie wzoru USER_FILL wymaga zdefiniowania wzoru za pomocą procedury:
setfillpattern(wzór_definiowany, kolor_wzoru);
(* wzór definiowany jest wzorcem 8×8 piks. *)
Wyspecyfikowanym wzorem wypełnia się figury zamknięte:
bar(x1, y1, x2, y2) (* prostokąt wypełniony; *)
(* x1, y1 - współrzędne lewego górnego *)
(* narożnika; x2, y2 - współrzędne *)
(* prawego dolnego narożnika *)
bar3d(x1, y1, x2, y2, h, góra)
(* słupek trójwymiarowy; *)
(* x1, y1 - współrzędne lewego górnego *)
(* narożnika płaszczyzny czołowej słupka; *)
(* x2, y2 - współrzędne prawego dolnego *)
(* narożnika płaszczyzny czołowej słupka; *)
(* h - głębokość; góra - parametr typu *)
(* int; wartość niezerowa powoduje *)
(* zaznaczenie płaszczyzny górnej *)
fillpoly(liczba_pinktów, współrzędne_punktów)
(* wielobok wypełniony *)
pieslice(x, y, α, β, r) (* wypełniony wycinek kołowy *)
fillellipse(x, y, półośX, półośY) (* wypełniona elipsa ze środkiem *)
(* w punkcie x,y; *)
2.6. Okna w trybie graficznym
setviewport(x1, y1, x2, y2, obcięcie)
(* otwarcie okna graficznego; *)
(* x1, y1 - współrzędne lewego górnego *)
(* narożnika okna; x2, y2 - współrzędne *)
(* prawego dolnego narożnika okna; *)
(* obcięcie - parametr typu int - jeśli jest *)
(* niezerowe, to rysunek jest przycinany *)
(* do rozmiarów okna *)
clearviewport (* czyszczenie aktualnego okna graficznego *)
cleardevice (* czyszczenie urządzenia graficznego *)
2.7. Przełączanie stron graficznych
setactivepage(strona) (* uczynienie strony podanej jako parametr *)
(* stroną aktywną *)
setvisualpage(strona) (* uczynienie strony podanej jako parametr *)
(* stroną widoczną; *)
(* parametr strona jest typu int *)
2.8. Przełączanie trybów pracy monitora
restorecrtmode (* przełączenie się z trybu graficznego *)
(* na tryb tekstowy *)
setgraphmode(tryb) (* powrót do podanego trybu graficznego *)
2.9. Działania na obrazach
a). Określenie rozmiarów obrazu:
imagesize(x1, y1, x2, y2)
(* określenie rozmiarów obrazu *)
(* prostokątnego; x1,y1 - współrzędne *)
(* lewego górnego narożnika; *)
(* x2, y2 - współrzędne prawego dolnego *)
(* narożnika *)
b). Zapamiętanie obrazu:
getimage(x1, y1, x2, y2, *obraz)
(* x1, y1, x2, y2 - parametry muszą być *)
(* takie same jak w imagesize; *)
(* obraz - wskaźnik do obszaru pamięci, *)
(* w którym przechowywany jest obraz *)
c). Wywołanie obrazu na ekranie
putimage(x, y, obraz, operacja)
(* x, y - współrzędne lewego górnego *)
(* narożnika obrazu na ekranie; *) (* obraz - definicja obrazu; *)
(* operacja - działanie wykonywane na *)
(* odpowiadających sobie punktach *) (* ekranu oraz wyprowadzanego na ten *) (* ekran obrazu *)
Parametr operacja może przyjmować wartość jednej ze stałych:
nazwa kod
COPY_PUT (0)
XOR_PUT (1)
OR_PUT (2)
AND_PUT (3)
NOT_PUT (4)
2.10. Otwieranie i zamykanie trybu graficznego
detectgraph(sterownik, tryb)
(* określenie sterownika karty graficznej *) (* i trybu pracy tej karty; *)
(* sterownik i tryb - zmienne typu int *)
initgraph(sterownik, tryb, ścieżka)
(* zainicjowanie trybu graficznego; *)
(* ścieżka - jest łańcuchem znaków, , *)
(* który określa ścieżkę dostępu do *)
(* sterownika karty graficznej (plik typu *)
(* .BGI *)
closegraph (* zamknięcie trybu graficznego *)
(0, 0)
(640, 480)
Ala ma kota
320
160
Ala ma kota
320
160
Ala ma kota
320
160