Wykład 6 p. 1/2 Oprogramowanie i wykorzystanie stacji roboczych Wykład 6 Dr inż. Tomasz Olas olas@icis.pcz.pl Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska
Wektory normalne Wykład 6 p. 2/2
Wykład 6 p. 3/2 Tworzenie wielokatów - kierunek zgodny z ruchem wskazówek zegara clockwise winding (CW) przeciwny do ruchu wskazówek zegara counterclockwise winding (CCW) 3 2 2 1 3 1
Wykład 6 p. 4/2 Kierunek w OpenGL Do określenia orientacji wielokatów w OpenGL służy funkcja: void glfrontface(glenum mode) gdzie: mode przyjmuje wartości: GL_CW lub GL_CCW Przykład: // określenie, że wielokąty o kolejności krawędzi zgodnej // z ruchem wskazówek zegara są widoczne od frontu glfrontface(gl_cw); // określenie, że wielokąty o kolejności krawędzi przeciwnej // do ruchu wskazówek zegara są widoczne od frontu glfrontface(gl_ccw);
Wykład 6 p. 5/2 Tryby rysowania wielokatów Wielokaty nie musza być wypełnione bieżacym kolorem. Domyślnie wielokaty sa rysowane jednolitym kolorem, można jednak to zmienić nakazujac, aby były rysowane jedynie jako sylwetki lub nawet jako punkty (sa wtedy rysowane jedynie wierzchołki). glpolygonmode(glenum face, GLenum); gdzie: face - Określa stronę wielokata, do której będzie się odnosić dane wywołanie funkcji: GL_FRONT - przednia strona, GL_BACK - tylna strona, GL_FRONT_AND_BACK - obie strony. mode - Określa nowy tryb rysowania. Domyślnym trybem jest GL_FILL dajacy wypełnione wielokaty. GL_LINE powoduje rysowanie jedynie sylwetek wielokatów (zewnętrznych krawędzi), zaś GL_POINT powoduje rysowanie jedynie punktów w wierzchołkach wielokata.
Wykład 6 p. 6/2 Kierunek wielokatów - przykład void drawtriangle(int x1, int y1, int x2, int y2, int x3, int y3) { glbegin(gl_triangles); glvertex3i(x1, y1, 0); glvertex3i(x2, y2, 0); glvertex3i(x3, y3, 0); glend(); } void MyGLWidget::paintGL() { glclear(gl_color_buffer_bit); glloadidentity(); //glfrontface(gl_cw); glpolygonmode(gl_front, GL_FILL); glpolygonmode(gl_back, GL_LINE); } drawtriangle(0, 0, 1, 0, 0, 1); drawtriangle(1, 0, 0, 1, 1, 1);
Wykład 6 p. 7/2 Ukrywanie niewidocznych powierzchni Można przyspieszyć proces renderowania poprzez wyelminowanie wielokatów skierowanych tyłem. // włączenie ukrywania niewidocznych wielokątów glenable(gl_cull_face); Do określenia, które wielokaty sa widoczne, a które nie służy funkcja glfrontface: // określenie, że wielokąty o kolejności krawędzi zgodnej // z ruchem wskazówek zegara są widoczne od frontu glfrontface(gl_cw); // określenie, że wielokąty o kolejności krawędzi przeciwnej // do ruchu wskazówek zegara są widoczne od frontu glfrontface(gl_ccw);
Budowa złożonych obiektów Wykład 6 p. 8/2
Wykład 6 p. 9/2 Ograniczenia glbegin() - glend() Najważniejszymi informacjami dotyczacymi wierzchołków sa ich współrzędne określane poprzez funkcję glvertex*(). Ponadto można określić dodatkowe informacje dotyczace wierzchołków, np. kolor, wektor normalny, współrzędne mapowania tekstury, itp. Funkcjami jakie moga być użyte wewnatrz pary glbegin() i glend() sa: glvertex*(), glcolor*(), glindex*(), glnormal*(), gltexcoord*(), gledgeflag*(), glmaterial*(), glarrayelement(), glevalcoord*(), glevalpoint*(), glcalllist(), glcalllists().
Prymitywy Wykład 6 p. 10/2
Wykład 6 p. 11/2 GL_POLYGON - ograniczenia Wszystkie wielokaty musza być płaskie (wszystkie wierzchołki wielokata musza leżeć na jednej płaszczyźnie). Krawędzie wielokata nie moga się przecinać, sam zaś wielokat musi być wielokatem wypukłym (nie może posiadać żadnych wcięć)
Wykład 6 p. 12/2 Wypełnianie wielokatów Wypełnianie wielokatów glenable(gl_polygon_stipple); a następnie glpolygonstipple(const GLubyte *bitmap); gdzie: bitmap - wzorzec bitowy o wymiarach 32x32 bity (Jedynki we wzorcu sa rysowane bieżacym kolorem wypełniania, zera nie sa rysowane).
Wykład 6 p. 13/2 Przesunięcie Przesunięcie jest operacja przemieszczajac a punkty o określona wartość w danym kierunku. Do określenia przesunięcia należy określić wektor przesunięcia d. gltranslate[df](type dx, TYPE dy, TYPE dz); gdzie: dx - współrzędna x wektora przesunięcia, dy - współrzędna y wektora przesunięcia, dz - współrzędna z wektora przesunięcia.
Wykład 6 p. 14/2 Skalowanie Skalowanie powoduje zwiększenie lub zmniejszenie obiektu we wszystkich trzech osiach o zadane współczynniki. Skalowanie nie musi być jednorodne. Można go użyć do ściśnięcia lub rozciagnięcia obiektu. Do skalowania służy funkcja: glscale[df](type x, TYPE y, TYPE z);
Wykład 6 p. 15/2 Obrót Obrót jest dokonywany poprzez określenie kata o jaki maja zostać obrócone punkty oraz wektora wyznaczajacego oś obrotu. glrotate[df](type angle, TYPE x, TYPE y, TYPE z); gdzie: angle - kat obrotu w stopniach, x, y, z - współczynniki wektora obrotu. Obrót jest wykonywany w kierunku przeciwnym do ruchu wskazówek zegara.
Wykład 6 p. 16/2 Transformacje - przykład (I) class MyGLWidget : public QGLWidget { public: MyGLWidget(QWidget* parent = NULL, const char* name = NULL); protected: void initializegl(); void paintgl(); void resizegl(int w, int h); void keypressevent(qkeyevent* event); GLfloat zroll; };
Wykład 6 p. 17/2 Transformacje - przykład (II) void MyGLWidget::paintGL() { glclear(gl_color_buffer_bit); glloadidentity(); glrotatef(zroll, 0.0f, 0.0f, 1.0f); drawtriangle(-1, -1, 1, -1, 0, 1); } void MyGLWidget::keyPressEvent(QKeyEvent* event) { if (event->key() == Qt::Key_Left) { zroll -= 3.0f; updategl(); } if (event->key() == Qt::Key_Right) { zroll += 3.0f; updategl(); } }
Wykład 6 p. 18/2 Rzutowanie równoległe Rzutowanie równoległe jest często używane w projektowaniu architektonicznym i programach CAD. W OpenGL do określenia rzutu równoległego służy funkcja glortho. glortho(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
Wykład 6 p. 19/2 Rzutowanie perspektywiczne (I) Ustalanie rzutu perspektywicznego przy użyciu funkcji glfrustrum: glfrustrum(gldouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near, GLdouble far);
Wykład 6 p. 20/2 Rzutowanie perspektywiczne (II) Ustalanie rzutu perspektywicznego przy użyciu funkcji gluperspective: gluperspective(gldouble fovy, GLdouble aspect, GLdouble znear, GLdouble zfar); fovy - szerokość kata widzenia w pionie (w stopniach), aspect - używany do wyznaczenia konta widzenia w poziomie.
Pozycja kamery Wykład 6 p. 21/2
Wykład 6 p. 22/2 Zmiana pozycji kamery Do zmiany położenia kamery może zostać wykorzystana transformacja: gltranslatef(0.0, 0.0, -10.0); rysuj_kwiatek();
Wykład 6 p. 23/2 Funkcja glulookat Funkcja glulookat umożliwia umieszczenie kamery w pewnym punkcie w przestrzeni i określenie kierunku na który zwrócona jest kamera. void glulookat(gldouble eyex, GLdouble eyey, GLdouble eyez, GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx, GLdouble upy, GLdouble upz); eyex, eyey, eyez - punkt obserwacji (współrzędne kamery), centerx, centery, centerz - określa kierunek patrzenia (kierunek w którym zwrócona jest kamera), upx, upy, upz - określa kierunek do góry z miejsca patrzenia.
Wykład 6 p. 24/2 Bufor głębokości (I) Gdy jest rysowany piksel przypisywana jest mu wartość (zwana wartościa z) określajac a odległość punktu tego piksel od obserwatora. Później gdy w tym samym miejscu ekranu ma zostać narysowany piksel, wartość z nowego piksel jest porównywana z wartościa z piksel już narysowanego. Jeżeli jest większa, oznacza to, że jego punkt jest bliżej obserwatora, więc stary piksel jest zasłaniany przez nowy.
Wykład 6 p. 25/2 Bufor głębokości (II) Właczenie bufora głębokości: glenable(gl_depth_test); Bufor głębokości musi być wyzerowany za każdym razem gdy przystępujemy do narysowania sceny. // Wyczyszczenie okna i bufora głębokości glclear(gl_color_buffer_bit GL_DEPTH_BUFFER_BIT);
Wykład 6 p. 26/2 Bufor głębokości - przykład glcolor3f(0.0f, 0.0f, 1.0f); glbegin(gl_quads); glvertex3f(0.1f, 0.1f, 0.1f); glvertex3f(0.5f, 0.5f, 0.1f); glend(); glcolor3f(1.0f, 0.0f, 0.0f); glbegin(gl_triangles); glvertex3f(0.5f, 0.0f, 0.0f); glvertex3f(0.0f, 0.5f, 0.0f); glend(); glvertex3f(0.1f, 0.5f, 0.1f); glvertex3f(0.5f, 0.1f, 0.1f); glvertex3f(0.0f, 0.0f, 0.0f); Bufor głębokości wyłaczony Bufor głębokości właczony