Wykład 12. Wprowadzenie do malarstwa, str. 1 OpenGL Open Graphics Library OpenGL składa się z teoretycznego modelu grafiki 3D, zestawu typów i funkcji obsługujących różne cechy tego modelu. WjęzykuC: pliki nagłówkowe: #include <GL/glut.h> #include <math.h> Funkcje OpenGL dostępne są z różnych języków na wielu platformach. jeśli liczymy obroty, rzuty, itp. biblioteki do wspólnej kompilacji: gcc-lgl-lglu-lglut-lm... Wykład 12. Wprowadzenie do malarstwa, str. 2 OpenGL Open Graphics Library Typowy Makefile: # nazwa programu: PROG = wprawki # biblioteki: LIBS=-lGL-lGLU-lglut-lm $(PROG):$(PROG).c gcc-wall-std=c99 $(PROG).c-o $(PROG) $(LIBS) usun: rm-f$(prog)*
Sztalugi i płótno Wykład 12. Wprowadzenie do malarstwa, str. 3 Program główny ustala początkowy rozmiar okna: glutinitwindowsize(szerokość, wysokość); ustala początkową pozycję okna na ekranie: glutinitwindowposition(od lewej, od góry); tworzy okno: glutcreatewindow(nazwa na ramce); ustalakolortła:glclearcolor(r,g,b,α); wywołuje funkcję użytkownika odwzorowującą scenę w okno i przekazuje jej rozmiary okna: glutreshapefunc(funkcja); wywołuje funkcję użytkownika rysującą scenę: glutdisplayfunc(funkcja); uruchamia rysowanie: glutmainloop(); Sztalugi i płótno Wykład 12. Wprowadzenie do malarstwa, str. 4 glutinitwindowsize(400, 300); glutinitwindowposition(200, 250); glutcreatewindow("wprawki"); glclearcolor(zolty, 0.0); 200 250 wprawki Żeby okno się pojawiło, konieczna jest jeszcze komenda glutmainloop(); (por. program wprawki00.c). 300 400
Kadrowanie i głębia ostrości Wykład 12. Wprowadzenie do malarstwa, str. 5 Funkcja wywołana w glutreshapefunc ustala geometrię. Patrzymy od strony dodatniej półosi z. Funkcja glortho(-20, 20,-15, 15,-5, 5); wyznacza prostopadłościan, którego zawartość zostanie przedstawiona: y x [ 20..20] y [ 15..15] x z [ 5..5] z... Kadrowanie i głębia ostrości Wykład 12. Wprowadzenie do malarstwa, str. 6 O rzutowaniach HORYZONT rzut zbieżny perspektywiczny rzut równoległy Funkcja glortho realizuje rzut równoległy; rzut zbieżny realizuje funkcja gluperspective (nie na tym wykładzie). O zmienianiu punktu widzenia mowa będzie później.
Pierwsze szkice Funkcja wywołana w glutdisplayfunc tworzy rysunek. W OpenGL rysunek powstaje z wierzchołków: Wykład 12. Wprowadzenie do malarstwa, str. 7 glbegin(gl LINE LOOP); glvertex3d(-5, 0, 0); glvertex3d( 0, 5, 0); glvertex3d( 5, 0, 0); glvertex3d( 0,-5, 0); glend(); ( 5,0,0) (0,5,0) (0, 5,0) (5,0,0) GL POINTS rysuje zbiór punktów. GL LINES rysuje pary odcinków. GL LINE STRIP rysuje łamaną otwartą. GL LINE LOOP rysuje łamaną zamkniętą. GL POLYGON rysuje wypełniony wielokąt. (por. program wprawki01.c). Pierwsze szkice Wykład 12. Wprowadzenie do malarstwa, str. 8 Modyfikacje rysunku glcolor3d(kolor); ustalenie koloru(ważne aż do ustalenia nowego koloru); np. glcolor3d(1.0, 0.0, 0.0); oznaczaczerwony(r=1.0,g=0.0,b=0.0); gllinewidth(liczba pikseli); ustalenie grubości linii(ważne aż do ustalenia nowej grubości); np. gllinewidth(5); oznacza linie szerokości 5 pikseli; glpushmatrix(); gltranslated(x, y, z); glpopmatrix(); przesunięcieobrazkaowektor(x,y,z).
Pierwsze szkice Wykład 12. Wprowadzenie do malarstwa, str. 9 Ciało funkcji rysującej musi zaczynaćsięod glclear(gl COLOR BUFFER BIT); inaczej w rysunku mogą wystąpić śmieci; kończyćsięna glflush(); (ang. flush = spłukać) żeby przygotowany rysunek się pojawił. Linie inne niż łamane Wykład 12. Wprowadzenie do malarstwa, str. 10 Linie inne niż łamane są rysowane jako łamane z bardzo krótkich odcinków. glbegin(gl LINE STRIP); for(double x=-4.0; x<=4.0; x+=przyrost) glvertex3d(x, x*x-7, 0); glend(); parabola glbegin(gl POLYGON); for(double kat=0; kat<=2*m PI; kat+=przyrost) glvertex3d(prom*cos(kat), prom*sin(kat), 0); glend(); koło pełne (por. program wprawki02.c).
Ćwiczenie z rysowania buźki Wykład 12. Wprowadzenie do malarstwa, str. 11 Buźka składa się z: okręgu stanowiącego obrys; koła stanowiącego wypełnienie; oczuzłożonychzdwóchłuków (odcinków okręgu); ust wycinkakoła; nosa kuli,wystającejwtrzeci wymiar. (por. program wprawki03.c). To,żenosjestkuląaniekołem,uwidocznisię,kiedybędziemymoglispojrzećnabuźkęzboku. Co widzimy na rysunku? Wykład 12. Wprowadzenie do malarstwa, str. 12 Jeśli niczego nie zażądamy, to: na rysunku zostanie przedstawiona zawartość sześcianu [ 1..1] [ 1..1] [ 1..1] obraz będzie przedstawiony z punktu widzenia obserwatora na osi z, patrzącego w kierunku od plusów do minusów y x z czyli tak: (por. program wprawki04.c).
Co widzimy na rysunku? Wykład 12. Wprowadzenie do malarstwa, str. 13 Zmiany zakresu sceny dokonuje funkcja glortho(x,x +,y,y +,z,z + ): x x x + y y y + z + z z y x z Przykład: M glortho(-2,2,-2,2,-2,2): glortho(-1,1,-2,2,-1,1): (por. program wprawki05.c) (por. program wprawki06.c) Co widzimy na rysunku? Wykład 12. Wprowadzenie do malarstwa, str. 14 Zmiany zakresu sceny dokonuje funkcja glortho(x,x +,y,y +,z,z + ): x x x + y y y + z + z z y x z Przykład: M glortho(0,2,-1,1,-1,1): glortho(-1,1,-1,1, 1,2): (por. program wprawki07.c) (por. program wprawki08.c)
Co widzimy na rysunku? Zmiany punktu widzenia dokonuje funkcja glulookat(oko x,oko y,oko z, centrum x,centrum y,centrum z, góra x,góra y,góra z ): Wykład 12. Wprowadzenie do malarstwa, str. 15 oko= oko x,oko y,oko z punkt,wktórymustawionajest kamera, centrum= centrum x,centrum y,centrum z punkt,naktórypatrzy Jeszcze trzeba powiedzieć, jak kamera jest przekręcona:...... góra= góra x,góra y,góra z wektornarysunkuskierowanywgórę Co widzimy na rysunku? Wykład 12. Wprowadzenie do malarstwa, str. 16 Przykład: M glulookat(-0.6,0.7,1, 0,0,0,0,1,0); -0.6 przesunięcie kamery w lewo 0.7 przesunięcie kamery w górę 0,0,0 skierowanie na środek 0,1,0 osiąykugórze (por. program wprawki09.c) y x.. z....
Zmiana punktu widzenia Wykład 12. Wprowadzenie do malarstwa, str. 17 glulookat(gdzie jest oko, na co patrzy, co przedstawić na górze) Standardowo OpenGL patrzy odstronydodatniejpółosiz w kierunku punktu jej ujemnych wartości tak, żeby dodatnia półoś y wskazywała w górę rysunku. Możemy to zmienić przez użycie funkcji glulookat: pierwsze trzy argumenty współrzędne oka; następne trzy argumenty współrzędne punktu, na który patrzymy; ostatnie trzy argumenty kierunek w górę obrazka. Uwaga: Użycie funkcji glulookat powoduje zmianę ustawienia w przestrzeni(obrót) przedstawianego obiektu. W wyniku tej zmiany może on przestać się mieścić w prostopadłościanie, wyznaczonym przez funkcję glortho. Dwukrotne zastosowanie funkcji glulookat powoduje dalszy obrót(por. program wprawki10.c). Zmiana punktu widzenia Wykład 12. Wprowadzenie do malarstwa, str. 18 Standardowy punkt widzenia Punkt widzenia po glulookat(3,0,1, 0,0,0, 0,1,0); okonapłaszczyźniexz,bardzozprawej, centrum sceny w początku układu współrzędnych, ośypatrzywgórę. (por. program wprawki11.c).
Zmiana punktu widzenia Wykład 12. Wprowadzenie do malarstwa, str. 19 OpenGL transformuje kierunki rzutowania(również oświetlenie itp.) przy pomocy rachunku macierzowego. Zmianie punktu widzenia odpowiada przekształcenie obrazu, polegające na pomnożeniu przez odpowiednią macierz. Polecenie ustalenia rzutu(np. równoległego) w funkcji odpowiedzialnej za geometrię należy poprzedzić informacją, że będziemy zmieniać macierz odpowiedzialną za perspektywę i że początkowo ma to być macierz jednostkowa: voidgeom(intw,inth) { glmatrixmode(gl PROJECTION); glloadidentity(); glortho(-20, 20,-15, 15,-25, 25); } Zmiana punktu widzenia Wykład 12. Wprowadzenie do malarstwa, str. 20 OpenGL transformuje kierunki rzutowania(również oświetlenie itp.) przy pomocy rachunku macierzowego. Zmianie punktu widzenia odpowiada przekształcenie obrazu, polegające na pomnożeniu przez odpowiednią macierz. Polecenie ustalenia punktu widzenia w funkcji odpowiedzialnej za wyswietlanie należy poprzedzić informacją, że będziemy zmieniać macierz odpowiedzialną za widok modelu, oraz że początkowo ma to być macierz jednostkowa: void wyswietl(void) { glclear(gl COLOR BUFFER BIT); glmatrixmode(gl MODELVIEW); glloadidentity(); glulookat(3,0,1, 0,0,0, 0,1,0); twarz(); glflush(); }
Wykład 12. Wprowadzenie do malarstwa, str. 21 Film ruchomy(ale ciągle niemy) Jak wyświetlać różniące się obrazki jeden za drugim, żeby uzyskać efekt ruchu? funkcji wyświetlającej zabrać odpowiedzialność za punkt widzenia: void wyswietl(void) { glclear(gl COLOR BUFFER BIT); glmatrixmode(gl MODELVIEW); glloadidentity(); glulookat(3,0,1, 0,0,0, 0,1,0); twarz(); glflush(); } (ale pozostawić zbudowanie początkowego obrazka). dodatkowej funkcji powierzyć modyfikacje obrazka; np. co ustalony czas; albo co kliknięcie myszą. Wykład 12. Wprowadzenie do malarstwa, str. 22 Film ruchomy(ale ciągle niemy) W części main umieścić informację, że będzie używany czasomierz: gluttimerfunc(15, timer, 0); zwłoka w milisekundach Zdefiniować zmiany w obrazku: funkcja czasomierza parametr dla fkcji czasomierza void timer(int v) { staticdoublealfa=0; alfa+=katobrotu; if(alfa>=2*mpi)alfa-=2*mpi; glmatrixmode(gl MODELVIEW); glloadidentity(); glulookat(20*cos(alfa), 7, 20*sin(alfa), 0,0,0, 0,1,0); glutpostredisplay(); gluttimerfunc(15, timer, v); } (por. program wprawki12.c). obrótwokółosiy
Dlaczego nos wędruje? Wykład 12. Wprowadzenie do malarstwa, str. 23 Fragmenty obrazka narysowane później zakrywają fragmenty narysowane wcześniej. Nos był narysowany na końcu, dlatego jest stale na wierzchu. Jak to leczyć? Sprawdzanie głębokości OpenGL może sprawdzać odległość elementów sceny od obserwatora i nie rysować dalszych, zasłoniętych przez bliższe. W części main: glenable(gl DEPTH TEST); (por. program wprawki13.c). W funkcji wyświetlającej: glclear(gl DEPTH BUFFER BIT); Zasłanianie dlaczego miga?! Wykład 12. Wprowadzenie do malarstwa, str. 24 Dwa wielokąty wypełnienie buzki i usta są narysowane w tej samej płaszczyźnie, więc OpenGL nie wie, który powinien zasłaniać który. Jak to leczyć? Lekko przesunąć w przestrzeni jeden wielokąt, żeby uniknąć współpłaszczyznowości z drugim: glpushmatrix(); gltranslated(0, 0, 0.5); glbegin(gl POLYGON); odcinek okregu(1.414*4, 5*M PI/4, 7*M PI/4); glend(); glpopmatrix(); (por. program wprawki14.c).
Więcej przestrzeni! Wykład 12. Wprowadzenie do malarstwa, str. 25 Drugiednoodtyłu korzyśćzprzesunięć: glpushmatrix(); gltranslated(0, 0,-2); glcolor3d(czarn); //obrysbuzki... glcolor3d(szary); // wypelnienie buzki... glpopmatrix(); (por. program wprawki15.c). Zadanie domowe: Dorobić powierzchnię walcową między dwoma szarymi kołami, żeby zamknąć pudełko. Więcej światła! Wykład 12. Wprowadzenie do malarstwa, str. 26 Bez właściwego oświetlenia nie widać przestrzenności: Ilustracja z http://www.glprogramming.com/red/chapter05.html (por. program wprawki16.c).
Więcej światła! Wykład 12. Wprowadzenie do malarstwa, str. 27 Ustawianie źródeł światła: glenable(gl LIGHTING); GLfloatswiatlomce[]={2,2,-1,0}; gllightfv(gl LIGHT0, GL POSITION, swiatlo mce); glenable(gl LIGHT0); glenable(gl COLOR MATERIAL); Oświetlenie jest rzeczą skomplikowaną. W OpenGL można ustawiać m.in. charakterystykę światła(kolor, rozproszenie itp.), geometrię powierzchni odbijającej(jak jest powyginana), charakterystykę powierzchni odbijającej(kolor, połysk, gładkość, itp.), osłabianie i rozmywanie światła przez odległość, mgłę itd. Wykład 12. Wprowadzenie do malarstwa, str. 28 Skacząca piłeczka, czyli trochę fizyki (por. program wprawki17.c). Ruch obiektów bez własnego napędu odbywa się pod wpływem sił. JeśliFjestsumą(wektorową!)siłdziałającychnapiłeczkę,mającąw chwilitprędkość vipołożenie r,to jejprędkośćwchwilit+ twyniesie v+ t F (m masa m piłeczki); jejpołożeniewchwilit+ twyniesie r+ t v+ t2 F. 2m Na piłeczkę działają dwie siły: grawitacja:m g=m 0, g,0,gdzieg 10 m s 2 jestprzyspieszeniem grawitacyjnym; opór powietrza proporcjonalny do kwadratu prędkości i przeciwnieskierowany: ω v v. Odbicie: kiedy piłeczka dotknie podłogi(czyli jej y będzie mniejszy od promienia), to pionowa składowa prędkości zmieni się na przeciwną.