Oprogramowanie i wykorzystanie stacji roboczych Wykład 10
Transkrypt
Oprogramowanie i wykorzystanie stacji roboczych Wykład 10
Teksturowanie Teksturowanie jest to nakładanie bitmapy na obiekt, włacznie ˛ z korekta˛ perspektywy. Oprogramowanie i wykorzystanie stacji roboczych Wykład 10 OpenGL już od wersji 1.0 zawiera pełny zestaw funkcji realizujacych ˛ nakładanie, filtrowanie i przekształcanie tekstur. Dr inż. Tomasz Olas [email protected] Rodzaje tekstur: jednowymiarowe (1D), dwuwymiarowe (2D), trójwymiarowe (wolumeryczne), sześcienne (kubiczne). Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛estochowska Wykład 10 – p. 1/32 Tekstury Wykład 10 – p Proces nakładania tekstury Tekstura jest zbiorem pixeli (texeli), w przypadku 2D jest tablica˛ dwuwymiarowa. ˛ W OpenGL szerokość wysokość i głebia ˛ tekstury musza˛ być potegami ˛ dwójki. Poszczególne piksele tekstury nazywa sie˛ texelami. 1. Utworzenie obiektu tekstury. 2. Określenie w jaki sposób tekstura ma być odwzorowana na poszczególne punkty. 3. Właczenie ˛ mapowania tekstur. 4. Renderowanie sceny uwzgledniaj ˛ ace ˛ zarówno współrz˛edne obiektów, jak również odwzorowanie tekstury. Wykład 10 – p. 3/32 Wykład 10 – p Utworzenie obiektu tekstury Definiowanie tekstur 2D (I) Utworzenie obiektu tekstury 2D polega na: Wygenerowaniu lub wczytaniu tablicy reprezentujacej ˛ poszczególne texele tworzonej tekstury. Zdefiniowaniu tekstury w OpenGL poprzez wywołanie funkcji glTexImage2D z parametrami charakteryzujacymi ˛ tworzona˛ teksture. ˛ W OpenGL do definiowania dwuwymiarowych tekstur służy funkcja glTexImage2D: void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); gdzie: target - GL_TEXTURE_2D. level - poziom szczegółów mipmapy. Jeśli nie sa˛ używane mipmapy zwykle wynosi zero. internalformat - ilość komponentów koloru, od 1 do 4. width - szerokość obrazu tekstury - musi być poteg ˛ a˛ liczby 2 lub być zgodna ze wzorem 2n + 2 ∗ border. height - wysokość obrazu tekstury - musi być poteg ˛ a˛ liczby 2 lub być zgodna ze wzorem 2m + 2 ∗ border. border - szerokość ramki dookoła obrazu tekstury (0 lub 1). lub 2. Wykład 10 – p. 5/32 Definiowanie tekstur 2D (II) Wykład 10 – p Definiowanie tekstur 2D - Qt (I) void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); Statyczna metoda klasy QGLWidget convertToGLFormat przekształca obiekt klasy QImage do postaci wymaganej przez funkcje glTexImage2D z biblioteki Qt. gdzie: QImage QGLWidget::convertToGLFormat (const QImage & img) [static] format - format danych pikseli ( GL_COLOR_INDEX, GL_RED, GL_GREEN, GL_BLUE, GL_ALPHA, GL_RGB, GL_RGBA, GL_LUMINANCE, GL_ALPHA_LUMINANCE). type - typ danych dla wartości pikseli. Zwracana mapa bitowa nie może być używana jako standardowy obiekt klasy QImage, ale moga˛ być wykorzystywane metody width, height i bits Powyższa metoda dokonuje jedynie konwersji poszczególnych pikseli, nie jest dokonywana zmiana rozmiaru bitmapy - musi ona mieć odpowiednie rozmiary przed dokonaniem konwersji. pixels - dane pikseli. Wykład 10 – p. 7/32 Wykład 10 – p Definiowanie tekstur 2D - Qt (II) Paramety obrazu tekstury (I) QImage tex1, buf; if (!buf.load("sky.bmp")) qDebug("Cannot open image file"); else tex1 = QGLWidget::convertToGLFormat(buf); glTexParameter[if](GLenum target, GLenum pname, GLfloat param); glTexParameter[if]v(GLenum target, GLenum pname, GLfloat *param); gdzie: target - musi to być GL_TEXTURE_1D lub GL_TEXTURE_2D. pname - określa parametr tekstury, który jest ustawiany: glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex1.width(), tex1.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex1.bits()); GL_TEXTURE_MIN_FILTER - określa metode˛ lub filtr stosowany przy zmniejszaniu tekstury. Wartościa˛ param może być: GL_NEAREST - filtrowanie „najbliższy sasiad” ˛ - pobierany jest najbliższy pixel obrazu tekstury, GL_LINEAR - liniowa interpolacja - przed narysowaniem czegokolwiek na ekranie wartości kolorów obrazu tekstury powinny zostać liniowo zinterpolowane, GL_NEAREST_MIPMAP_NEAREST - filtr mipmapy „najbliższy sasiad”, ˛ GL_NEAREST_MIPMAP_LINEAR - liniowo interpolowana mipmapa, GL_LINEAR_MIPMAP_NEAREST - liniowo interpolacja mipmap, GL_LINEAR_MIPMAP_LINEAR - liniowa interpolacja interpolowanych mipmap. Wykład 10 – p. 9/32 Parametry obrazu tekstury (II) Wykład 10 – p. Parametry obrazu tekstury (III) glTexParameter[if](GLenum target, GLenum pname, GLfloat param); glTexParameter[if]v(GLenum target, GLenum pname, GLfloat *param); filtr GL_NEAREST filtr GL_LINEAR gdzie: pname cd: GL_TEXTURE_MAG_FILTER - określa metode˛ lub filtr stosowany przy powiekszaniu ˛ tekstury. Wartościa˛ param może być: GL_NEAREST - filtrowanie „najbliższy sasiad”, ˛ GL_LINEAR - liniowa interpolacja, GL_TEXTURE_WRAP_S - określa sposób traktowania współrz˛ednych S tekstury poza zakresem od 0.0 do 1.0. GL_TEXTURE_WRAP_T - określa sposób traktowania współrz˛ednych T tekstury poza zakresem od 0.0 do 1.0. GL_CLAMP GL_REPEAT GL_BORDER_COLOR - określa kolor ramki to tekstur bez ramki. Wykład 10 – p. 11/32 Wykład 10 – p. Parametry obrazu tekstury (IV) Parametry teksturowania Funkcja glTexEnv ustawia parametry mapowania tekstury, sterujace ˛ sposobem nakładania obrazów tekstur na wielokaty: ˛ glTexEnv{fi}(GLenum target, GLenum pname, TYPE param); glTexEnv{fi}v(GLenum target, GLenum pname, TYPE *param); gdzie: target - definiowane środowisko teksturowania - musi nim być GL_TEXTURE_ENV. pname - nazwa definiowanego parametru: GL_TEXTURE_ENV_MODE - określa tryb teksturowania. Parametr param może przyjmować wartości: · GL_DECAL - obraz tekstury jest bezpośrednio nakładany na wielokat, ˛ · GL_VERB - przed nałożeniem na wielokat, ˛ obraz tekstury jest mieszany z określonym kolorem (GL_TEXTURE_ENV_COLOR). · GL_MODULATE - przed nałożeniem na wielokat, ˛ obraz tekstury jest mnożony przez istniejacy ˛ obraz w buforze ramki. GL_TEXTURE_ENV_COLOR - określa kolor do połaczenia ˛ z tekstura. ˛ W tym przypadku parametr param jest wskaźnikiem do wartości koloru RGBA. Wykład 10 – p. 13/32 Współrzedne ˛ tekstury Wykład 10 – p. Określanie współrzednych ˛ tekstury Do określania współrz˛ednych tekstury dla wielokata, ˛ na który nakładamy teksture przeznaczona jest rodzina funkcji glTexCoord: glTexCoord1{dfis}(TYPE s); glTexCoord1{dfis}v(TYPE *s); glTexCoord2{dfis}(TYPE s, TYPE t); glTexCoord2{dfis}v(TYPE st); glTexCoord3{dfis}(TYPE s, TYPE t, TYPE r); glTexCoord3{dfis}v(TYPE *str); glTexCoord4{dfis}(TYPE s, TYPE t, TYPE r, TYPE q); glTexCoord4{dfis}v(TYPE strq); gdzie: s - pozioma współrz˛edna obrazu tekstury, t - pionowa współrz˛edna obrazu tekstury, r - współrz˛edna głebokości ˛ obrazu tekstury, q - współrz˛edna „czasu” obrazu tekstury. Wykład 10 – p. 15/32 Wykład 10 – p. Właczenie ˛ i wyłaczenie ˛ mapowania tekstur Tekstury 2D - przykład (I) Właczenie ˛ mapowania tekstur 2D: const GLuint Texture = 1; glEnable(GL_TEXTURE_2D); QImage tex1, buf; if ( !buf.load( "sky.bmp" ) ) qDebug("Cannot open image file"); else tex1 = QGLWidget::convertToGLFormat( buf ); Wyłaczenie ˛ mapowania tekstur 2D: glDisable(GL_TEXTURE_2D); Analogicznie można właczać ˛ i wyłaczać ˛ mapowanie tekstur jednowymiarowych (GL_TEXTURE_1D) i trójwymiarowych (GL_TEXTURE_3D) glNewList(Texture, GL_COMPILE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, tex1.width(), tex1.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex1.bits()); glEndList(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); Wykład 10 – p. 17/32 Definiowanie tekstur 2D (III) Wykład 10 – p. Definiowanie tekstur 2D (IV) glEnable(GL_TEXTURE_2D); glCallList(Texture); glBegin(GL_QUADS); glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 0.0f); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, 1.0f, 0.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(1.0f, 1.0f, 0.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 0.0f); glEnd(); Wykład 10 – p. 19/32 Wykład 10 – p. Mipmapy (I) Mipmapy (II) Mipmapy umożliwiaja˛ dobór obrazu tekstury w zależności od odległości od obserwatora. Wielkość obrazów w mipmapie nie jest dowolna. Każdy nastepny ˛ stanowi 1/4 (1/2 × 1/2) rozmiaru poprzedniego obrazka. mipmapa o rozmiarze 128x128 bedzie ˛ zawierała obrazki o rozmiarach 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2 i 1x1, natomiast mipmapa o rozmiarze 64x16 - 64x16, 32x8, 16x4, 8x2, 4x1, 2x1, 1x1. Tekstura taka zawiera w sobie wiele obrazów. Wybierany jest obraz tekstury najbliższy rozmiarowi wielokata ˛ na ekranie. Stosowanie mipmap poprawia wyglad ˛ renderowanej sceny oraz zazwyczaj przyspiesza proces renderowania. Wykład 10 – p. 21/32 Wykład 10 – p. Mipmapy - przykład Paramety obrazu - mipmapy QImage buf; buf.load("sky0.bmp"); QImage sky0 = QGLWidget::convertToGLFormat(buf); buf.load("sky1.bmp"); QImage sky1 = QGLWidget::convertToGLFormat(buf); buf.load("sky2.bmp"); QImage sky2 = QGLWidget::convertToGLFormat(buf); glTexParameter[if](GLenum target, GLenum pname, GLfloat param); glTexParameter[if]v(GLenum target, GLenum pname, GLfloat *param); dla: GL_TEXTURE_MIN_FILTER: GL_NEAREST_MIPMAP_NEAREST - wybiera mipmape, ˛ której teksele maja˛ rozmiar najbardziej zbliżony do pokrywanego piksela i używa filtra GL_NEAREST do wyznaczenia barwy piksela. glNewList(1, GL_COMPILE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, 3, 4, 4, 0, GL_RGB, GL_UNSIGNED_BYTE, sky0.bits()); glTexImage2D(GL_TEXTURE_2D, 1, 3, 2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, sky1.bits()); glTexImage2D(GL_TEXTURE_2D, 2, 3, 1, 1, 0, GL_RGB, GL_UNSIGNED_BYTE, sky2.bits()); glEndList(); GL_LINEAR_MIPMAP_NEAREST - podobnie jak wyżej, ale z użyciem kryterium GL_LINEAR. GL_NEAREST_MIPMAP_LINEAR - wybiera dwie mipmapy, których teksele maja˛ rozmiar najbardziej zbliżony do pokrywanego piksela, nastepnie ˛ posługuje sie˛ filtrem GL_NEAREST do wyznaczenia teksela z każdej mipmapy. Ostateczna wartość elementu tekstury jest średnia˛ ważona˛ dwóch poprzednich tekseli. GL_LINEAR_MIPMAP_LINEAR - tak jak wyżej, lecz z zastosowaniem opcji GL_LINEAR. Ten filtr jest też zwany trójliniowym (Trilinear Filtering). Wykład 10 – p. 23/32 Wykład 10 – p. Mipmapy - filtrowanie Definiowanie tekstur 1D (I) W OpenGL do definiowania jednowymiarowych tekstur służy funkcja glTexImage1D: void glTexImage1D(GLenum target, GLint level, GLint components, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); gdzie: target - musi być GL_TEXTURE_1D. level - poziom szczegółów mipmapy. Jeśli nie sa˛ używane mipmapy zwykle wynosi zero. component - ilość komponentów koloru, od 1 do 4. width - szerokość obrazu tekstury - musi być poteg ˛ a˛ liczby 2 lub być zgodna ze wzorem 2n + 2 ∗ border. border - szerokość ramki dookoła obrazu tekstury. Musi być 0, 1 lub 2. Wykład 10 – p. 25/32 Definiowanie tekstur 1D (II) Wykład 10 – p. Mapowanie tekstur 1D - przykład (I) const GLuint RainbowTexture = 1; static unsigned char tecza[8][3] = { {0x3f, 0x00, 0x3f}, {0x7f, 0x00, 0x7f}, {0xbf, 0x00, 0xbf}, {0x00, 0x00, 0xff}, {0x00, 0xff, 0x00}, {0xff, 0xff, 0x00}, {0xff, 0x7f, 0x00}, {0xff, 0x00, 0x00} }; void glTexImage1D(GLenum target, GLint level, GLint components, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels); gdzie: format - format danych pikseli: GL_COLOR_INDEX - wartości wszystkich pikseli sa˛ indeksami kolorów, GL_RED - wartości pikseli sa˛ intensywnościami czerwieni, GL_GREEN - wartości pikseli sa˛ intensywnościami zieleni, GL_BLUE - wartości pikseli sa˛ intensywnościami niebieskiego, GL_ALPHA - wartości pikseli sa˛ wartościami alfa, GL_RGB - wartości pikseli sa˛ wartościami RGB, GL_RGBA - wartości pikseli sa˛ wartościami RGBA, GL_LUMINANCE - wartości pikseli sa˛ kolorami w skali szarości, GL_ALPHA_LUMINANCE - wartości pikseli sa˛ wartościami alfa i kolorami w skali szarości. type - typ danych dla wartości pikseli. pixels - dane pikseli. Wykład 10 – p. 27/32 glNewList(RainbowTexture, GL_COMPILE); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage1D(GL_TEXTURE_1D, 0, 3, 8, 0, GL_RGB, GL_UNSIGNED_BYTE, tecza); glEndList(); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); Wykład 10 – p. Mapowanie tekstur 1D - przykład (II) Mapowanie tekstur 1D - przykład (III) glEnable(GL_TEXTURE_1D); glCallList(RainbowTexture); glBegin(GL_QUAD_STRIP); for (double th = 0.0; th <= M_PI; th += (0.03125 * M_PI)) { // dolna kraw˛ edź t˛ eczy x = cos(th) * 50.0; y = sin(th) * 50.0; z = -50.0; glTexCoord1f(0.0); glVertex3f(x, y, z); // górna kraw˛ edź t˛ eczy x = cos(th) * 55.0; y = sin(th) * 55.0; z = -50.0; glTexCoord1f(1.0); glVertex3f(x, y, z); } glEnd(); Wykład 10 – p. 29/32 Wykład 10 – p. Mipmapy - automatyczne generowanie Biblioteka GLU Biblioteka GLU dodaje do biblioteki OpenGL dodatkowe funkcje wyższego poziomu. W bibliotece GLU istnieja˛ funkcje do automatycznego generowania mipmap na podstawie pojedynczej tekstury. W skład biblioteki OpenGL wchodza˛ miedzy ˛ innymi: W przypadku jednowymiarowym jest to funkcja gluBuild1DMipmap natomiast dla 2D funkcja˛ realizujac ˛ a˛ ta˛ operacje jest funkcja gluBuild2DMipmap. transformacje ze współrz˛ednych obiektu na współrz˛edne obserwatora i odwrotnie, wsparcie dla powierzchni NURBS, funkcje do podziału wielokatów ˛ na trójkaty, ˛ skalowanie rysunków 2D oraz tworzenie mipmap, dodatkowe funkcje wspierajace ˛ rzutowanie perspektywiczne i równoległe, zmiana pozycji kamery, wybór obiektów, funkcje do renderowania dysków, cylindrów oraz sfer, Wykład 10 – p. 31/32 Wykład 10 – p.