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.

Podobne dokumenty