Oprogramowanie i wykorzystanie stacji roboczych Wykład 6
Transkrypt
Oprogramowanie i wykorzystanie stacji roboczych Wykład 6
Oprogramowanie i wykorzystanie stacji roboczych Wykład 6 Dr inż. Tomasz Olas [email protected] Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛estochowska Wykład 6 – p. 1/2 Wektory normalne Wykład 6 – p. 2/2 Tworzenie wielokatów ˛ - kierunek zgodny z ruchem wskazówek zegara clockwise winding (CW) przeciwny do ruchu wskazówek zegara counterclockwise winding (CCW) 2 3 2 1 3 1 Wykład 6 – p. 3/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 wielokaty ˛ o kolejności kraw˛ edzi zgodnej // z ruchem wskazówek zegara sa˛ widoczne od frontu glFrontFace(GL_CW); // określenie, że wielokaty ˛ o kolejności kraw˛ edzi przeciwnej // do ruchu wskazówek zegara sa˛ widoczne od frontu glFrontFace(GL_CCW); Wykład 6 – p. 4/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 strone˛ wielokata, ˛ do której bedzie ˛ sie˛ 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 ˛ (zewnetrznych ˛ kraw˛edzi), zaś GL_POINT powoduje rysowanie jedynie punktów w wierzchołkach wielokata. ˛ Wykład 6 – p. 5/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. 6/2 Ukrywanie niewidocznych powierzchni Można przyspieszyć proces renderowania poprzez wyelminowanie wielokatów ˛ skierowanych tyłem. // właczenie ˛ ukrywania niewidocznych wielokató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 wielokaty ˛ o kolejności kraw˛ edzi zgodnej // z ruchem wskazówek zegara sa˛ widoczne od frontu glFrontFace(GL_CW); ˛ o kolejności kraw˛ edzi przeciwnej // określenie, że wielokaty // do ruchu wskazówek zegara sa˛ widoczne od frontu glFrontFace(GL_CCW); Wykład 6 – p. 7/2 Budowa złożonych obiektów Wykład 6 – p. 8/2 Ograniczenia glBegin() - glEnd() Najważniejszymi informacjami dotyczacymi ˛ wierzchołków sa˛ ich współrz˛edne określane poprzez funkcje˛ glVertex*(). Ponadto można określić dodatkowe informacje dotyczace ˛ wierzchołków, np. kolor, wektor normalny, współrz˛edne 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(). Wykład 6 – p. 9/2 Prymitywy Wykład 6 – p. 10/2 GL_POLYGON - ograniczenia Wszystkie wielokaty ˛ musza˛ być płaskie (wszystkie wierzchołki wielokata ˛ musza˛ leżeć na jednej płaszczyźnie). Krawedzie ˛ wielokata ˛ nie moga˛ sie˛ przecinać, sam zaś wielokat ˛ musi być wielokatem ˛ wypukłym (nie może posiadać żadnych wcieć) ˛ Wykład 6 – p. 11/2 Wypełnianie wielokatów ˛ Wypełnianie wielokatów ˛ glEnable(GL_POLYGON_STIPPLE); a nastepnie ˛ 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. 12/2 Przesuniecie ˛ Przesuniecie ˛ jest operacja˛ przemieszczajac ˛ a˛ punkty o określona˛ wartość w danym kierunku. Do określenia przesuniecia ˛ należy określić wektor przesuniecia ˛ d. glTranslate[df](TYPE dx, TYPE dy, TYPE dz); gdzie: dx - współrz˛edna x wektora przesuniecia, ˛ dy - współrz˛edna y wektora przesuniecia, ˛ dz - współrz˛edna z wektora przesuniecia. ˛ Wykład 6 – p. 13/2 Skalowanie Skalowanie powoduje zwiekszenie ˛ lub zmniejszenie obiektu we wszystkich trzech osiach o zadane współczynniki. Skalowanie nie musi być jednorodne. Można go użyć do ściśniecia ˛ lub rozciagni ˛ ecia ˛ obiektu. Do skalowania służy funkcja: glScale[df](TYPE x, TYPE y, TYPE z); Wykład 6 – p. 14/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. 15/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. 16/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. 17/2 Rzutowanie równoległe Rzutowanie równoległe jest cz˛esto 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. 18/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. 19/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. Wykład 6 – p. 20/2 „Pozycja kamery” Wykład 6 – p. 21/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. 22/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˛edne 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. 23/2 Bufor głeboko ˛ ś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 wieksza, ˛ oznacza to, że jego punkt jest bliżej obserwatora, wiec ˛ stary piksel jest zasłaniany przez nowy. Wykład 6 – p. 24/2 Bufor głeboko ˛ ści (II) Właczenie ˛ bufora głebokości: ˛ glEnable(GL_DEPTH_TEST); Bufor głebokości ˛ musi być wyzerowany za każdym razem gdy przystepujemy ˛ do narysowania sceny. // Wyczyszczenie okna i bufora gł˛ ebokości glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Wykład 6 – p. 25/2 Bufor głeboko ˛ ś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(); Bufor głebokości ˛ wyłaczony ˛ glVertex3f(0.1f, 0.5f, 0.1f); glVertex3f(0.5f, 0.1f, 0.1f); glVertex3f(0.0f, 0.0f, 0.0f); Bufor głebokości ˛ właczony ˛ Wykład 6 – p. 26/2