Pobierz prezentację
Pobieranie prezentacji. Proszę czekać
OpublikowałFrydryk Dułak Został zmieniony 11 lat temu
1
Podstawy programowania grafiki 3D z użyciem biblioteki OpenGL
dr inż. Piotr Steć
2
Czym jest OpenGL Biblioteka programistyczna
Interfejs pomiędzy sprzętem a programistą Uniezależnia programistę od platformy sprzętowej i programowej Bazuje na bibliotece Iris GL opracowanej przez Silicon Graphics Wszystkie nowoczesne karty graficzne wspierają sprzętowo funkcje OpenGL Pierwsza wersja powstała w 1992r.
3
Zalety OpenGL Całkowite uniezależnienie od możliwości karty graficznej
Prosty i przejrzysty kod programu Program wygląda prawie tak samo we wszystkich językach programowania i na wszystkich platformach systemowych Biblioteka jest darmowa i można jej używać we własnych programach bez ograniczeń
4
Jak działa OpenGL Schemat potoku renderującego Dane wierzchołków
pikseli Lista wyświetlania Bufor ramki Ewaluacja Rasteryzacja Operacje na pikselach T worzenie tekstur Operacje na fragmentach wierzchołkach i budowanie prymitywów Schemat potoku renderującego
5
Listy wyświetlania Dwa tryby pracy OpenGL:
immediate mode – komendy graficzne wykonywane są natychmiast retained mode – komendy graficzne przechowywane są w listach Listy mogą być wielokrotnie wykonywane
6
Ewaluacja Blok ten przekształca dane sterujące na parametry i współrzędne przestrzenne Może generować: Powierzchnie NURBS Mapowanie tekstur Wektory normalne Informację o kolorze
7
Operacje na wierzchołkach i budowanie prymitywów
Wierzchołki obiektów poddawane są transformacjom Obiekty 3D są rzutowane na płaszczyznę 2D (ekran) Obcinane są niewidoczne części obiektów Obliczane jest oświetlenie obiektów
8
Operacje na pikselach Pobieranie bitmap z pamięci
Konwersja formatów pikseli Skalowanie Filtracja Kopiowanie
9
Tworzenie tekstur Tworzenie tekstur z bitmap
Łączenie wielu bitmap w teksturę Organizacja pamięci tekstur Generowanie MIPMap Filtracja tekstur
10
Rasteryzacja Zamiana danych wektorowych, parametrów oświetlenia i materiałów na tzw. fragmenty: wierzchołki łączone są liniami wielokąty są wypełniane z uwzględnieniem cieniowania Fragment jest surowym odpowiednikiem piksela, czyli jednego punktu na ekranie Fragment zwykle zawiera więcej informacji niż piksel, np. głębię czy wartości buforów specjalnych
11
Operacje na fragmentach
Teksturowanie Obliczanie wartości mgły Mieszanie z buforem alfa Uwzględnianie szablonów Operacje na buforze Z Operacje logiczne Wynik końcowy: piksel zapisany do bufora ramki
12
Bufor ramki Pamięć przechowująca piksele, które mają być wyświetlone na ekranie Wielkość bufora ramki zależy od wielkości okna w którym wyświetlana jest grafika OpenGL może obsługiwać wiele buforów ramki Najczęściej stosuje się 2 bufory ramki: Jeden jest wyświetlany (front), drugi jest używany do rysowania (back) Po zakończeniu rysowania bufory zamieniane są miejscami (podwójne buforowanie) W przypadku wyświetlania stereo, stosowane są 4 bufory (po 2 na jedno oko)
13
Składnia komend OpenGL
Wszystkie komendy rozpoczynają się przedrostkiem gl np. glClearColor() Wszystkie stałe rozpoczynają się przedrostkiem GL_, np. GL_FRONT Komendy są tworzone według jednego schematu: glColor3f( typ parametrów biblioteka liczba parametrów komenda
14
Przyrostki komend i typy parametrów
Przyrostek Typ danych nazwa w C Definicja w OpenGL b 8-bit. liczba czałk. signed char GLbyte s 16-bit. liczba czałk. short GLshort i 32-bit. liczba czałk. int GLint, GLsizei f 32-bit. liczba zmiennopozyc. float GLfloat d 64-bit. liczba zmiennopozyc. double GLdouble np. glVertex2i(33,150); glvertex3f(12.34,100.1,0.5);
15
Szkielet programu Inicjalizacja biblioteki
Ustalenie wielkości okna i typu kamery Opcjonalnie: zmiana parametrów kamery i zmiennych środowiska Rysowanie obiektów Jeśli nie koniec, to skok do 3 Zwalnianie zasobów
16
Pliki nagłówkowe W bibliotekach używających OpenGL należy podłączyć odpowiednie pliki nagłówkowe #include <GL/gl.h> #include <GL/glu.h> Opcjonalnie można użyć pomocniczej biblioteki #include <gl/glaux.h> Biblioteka glaux nie jest częścią standardu, jest nieoficjalna i nie jest standardowo dostępna. Należy samodzielnie zdobyć plik glaux.lib
17
Kontekst urządzenia Kontekst urządzenia pod Windows pozwala na rysowanie Ogólnie jest to ten element okna, który widzimy na ekranie (ale można uzyskać kontekst urządzenia również dla elementów niewidocznych) Globalna zmienna przechowująca kontekst: HDC hdc; Pobieranie kontekstu w czasie inicjalizacji: hdc=GetDC(Handle); Zwalnianie kontekstu na końcu programu: ReleseDC(Handle, hdc);
18
Format piksela Format piksela jest niezależny od aktualnego trybu kolorów PIXELFORMATDESCRIPTOR pfd; ZeroMemory( &pfd, sizeof( pfd ) ); pfd.nSize = sizeof( pfd ); pfd.nVersion = 1; pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; pfd.iPixelType = PFD_TYPE_RGBA; pfd.cColorBits = 24; pfd.cDepthBits = 16; int iFormat = ChoosePixelFormat( hDC, &pfd ); SetPixelFormat( hDC, iFormat, &pfd );
19
Kontekst renderingu Jest dla OpenGL tym samym, czym jest kontekst urządzenia dla Windows Globalna zmienna przechowująca identyfikator: HGLRC hRC; Tworzenie kontekstu (można utworzyć kilka): hRC = wglCreateContext( hDC ); Wybieranie aktywnego kontekstu: wglMakeCurrent( hDC, hRC ); Zwalnianie kontekstu na końcu programu: wglMakeCurrent( NULL, NULL ); wglDeleteContext( hRC );
20
Parametry wyświetlania
Obszar okna, na którym będzie rysowana scena: glViewport(0, 0, ClientWidth, ClientHeight); Przełączenie w tryb edycji kamery: glMatrixMode(GL_PROJECTION); Wyzerowanie kamery: glLoadIdentity(); Parametry projekcji: gluPerspective(45.0,(double)ClientWidth/ (double)ClientHeight,0.1,100.0);
21
Viewport
22
Bryła obcinająca
23
Rysowanie obiektów Czyszczenie bieżącego bufora: glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Kolor czyszczący bufor można ustalić dowolnie funkcją (przed rysowaniem): glClearColor(0.0f, 1.0f, 0.0f, 0.0f); Przełączenie w tryb edycji obiektów: glMatrixMode(GL_MODELVIEW); Wyzerowanie transformacji: glLoadIdentity(); Wprowadzenie przesunięcia: glTranslatef(-1.5f,0.0f,-6.0f);
24
Rysowanie obiektów c.d. Narysowanie trójkąta (dowolna ilość komend glVertex): glBegin( GL_TRIANGLES ); glColor3d( 1.0, 0.0, 0.0 ); glVertex3d( 0.0, 1.0, 0.0 ); glColor3d( 0.0, 1.0, 0.0 ); glVertex3d( -1.0, 0.0, 0.0 ); glColor4d( 0.0, 0.0, 1.0 ,0.5); glVertex3d( 1.0, 0.0, 0.0 ); glEnd(); Zamiana buforów ramki SwapBuffers( _hdc ); //za
25
Rysowanie trójkątów 1 2 5 3 6 4
26
Punkty i linie 1 2 3 4 5
27
Wielokąty 1 2 3 4 5 7 6 GL_POLYGON GL_QUADS
28
Rysowanie pasów trójkątów
glBegin(GL_TRIANGLE_STRIP); 5 1 3 7 4 2 6
29
Pasy czworokątów i wachlarze trójkątów
1 2 3 4 5 7 6 GL_QUAD_STRIP GL_TRINGLE_FAN
30
Kolory w OpenGL Kolor najczęściej jest podawany w postaci składowych RGB lub RGBA, gdzie A określa przeźroczystość Każda składowa przyjmuje wartości z zakresu <0, 1> Taka reprezentacja jest niezależna od bieżącego trybu kolorów Kolor zmieniany jest komendą glColor np. glColor3d( 1.0, 0.0, 0.0 ); (czerwony) Raz ustawiony kolor obowiązuje dla wszystkich rysowanych po zmianie obiektów
31
Współrzędne jednorodne
Punkt w przestrzeni reprezentowany jest przez cztery współrzędne (x,y,z,w) Wsp. jednorodne reprezentują ten sam punkt wtedy, gdy jeden zestaw jest wielokrotnością drugiego, np. (2,1,1,4) i (4,2,2,8) Przynajmniej jedna ze współrzędnych musi być różna od zera ((0,0,0,0) – niedopuszczalne)
32
Przekształcenia 3D Translacja glTranslatef(-1.5f,0.0f,-6.0f);
Skalowanie glScale(2.5f,1.0f,0.5f);
33
Obroty 3D glRotatef(33.0,1.0,0.0,0.0); Pierwszy parametr: kąt obrotu, Pozostałe trzy określają oś obrotu XYZ (w tym przypadku oś X)
34
Macierz jednostkowa Macierz oznaczająca brak przekształceń
glLoad Identity();
35
Składanie przekształceń
OpenGL przechowuje przekształcenia w postaci macierzy Wywoływanie funkcji glTranslate, glRotate, glScale powoduje mnożenie bieżącej macierzy, przez macierz odpowiedniego przekształcenia Przekształcenie musi być dokonane przed narysowaniem obiektu
36
Przykład przekształceń
glTranslatef(-1.5f,0.0f,-6.0f); glBegin( GL_TRIANGLES ); glColor3d( 1.0, 0.0, 0.0 ); glVertex3d( 0.0, 1.0, 0.0 ); glColor3d( 0.0, 1.0, 0.0 ); glVertex3d( -1.0, 0.0, 0.0 ); glColor4d( 0.0, 0.0, 1.0 ,0.5); glVertex3d( 1.0, 0.0, 0.0 ); glEnd(); glTranslatef(3.0f,0.0f,0.0f); glBegin(GL_QUADS); glVertex3f(-1.0f, 1.0f, 0.0f); glVertex3f( 1.0f, 1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f);
37
Wektory normalne Wektor normalny jest to wektor prostopadły do danej powierzchni Wektory krawędziowe: 2 V12 V10 1
38
Wektory normalne c.d. Wektor normalny można uzyskać mnożąc wektorowo dwa wektory krawędziowe Zwykle wektory normalne muszą być znormalizowane, czyli muszą mieć długość 1
39
Światło Oświetlenie jest obliczane dla każdego wierzchołka obiektu
Aby można było obliczyć wartość oświetlenia, musi być podany wektor normalny dla wierzchołka Jasność wnętrza wielokąta jest interpolowana na podstawie jasności jego wierzchołków, tzw. cieniowanie Gouraud’a
40
Cieniowanie Cieniowanie płaskie Cieniowanie gładkie
41
Komponenty składowe oświetlenia
Światło otoczenia (ambient) Światło rozproszone (diffuse) Światło odbite (specular)
42
Dokładność cieniowania a gęstość siatki
16 24 36 100
43
Tworzenie świateł Włączenie oświetlenia: glEnable(GL_LIGHTING);
Włączenie pierwszego światła: glEnable(GL_LIGHT0); Kolejne światła mają identyfikatory GL_LIGHTi, gdzie i jest numerem światła np. GL_LIGHT3 Do zmian parametrów światła służy funkcja glLightfv Nowe parametry są pamiętane aż do kolejnej zmiany
44
Parametry światła Składowa otoczenia (ambient) GLfloat light_ambient[] = { 0.1, 0.1, 0.1, 1.0 }; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); Składowa rozproszenia (diffuse) GLfloat light_diffuse[] = { 0.8, 0.8, 0.8, 1.0 }; glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); Składowa odbicia (specular) GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); Pozycja światła w przestrzeni GLfloat light_position[] = {-9.0, 5.0, 1.0, 1.0 }; glLightfv(GL_LIGHT0, GL_POSITION, light_position);
45
Materiały Podstawowe parametry materiału, tak jak w przypadku świateł, to: ambient, diffuse i specular Dodatkowo można określić: Stopień gładkości powierzchni – shininess Świecenie własnym światłem - emission
46
Parametry materiałów Do zmiany parametrów materiału służy funkcja glMaterialfv Nowe parametry obowiązują dla wszystkich obiektów rysowanych po zmianie Materiał można określić osobno dla przedniej i tylniej ściany obiektu: GL_FRONT – przód, GL_BACK – tył, GL_FRONT_AND_BACK – dwie strony jednocześnie
47
Składnia funkcji glMaterialfv
GLfloat mat_diff[] = { 0.1, 0.5, 0.8, 1.0 }; glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat_diff); nazwa param. wartość domyślna opis GL_AMBIENT (0.2, 0.2, 0.2, 1.0) światło otoczenia GL_DIFFUSE (0.8, 0.8, 0.8, 1.0) kolor rozproszenia GL_AMBIENT_AND_DIFFUSE rozpr. + otocz. GL_SPECULAR (0.0, 0.0, 0.0, 1.0) kolor odbicia lustrzanego GL_SHININESS 0.0 gładkość powierzchni GL_EMISSION kolor świecenia
48
Stos macierzy Zależności hierarchiczne pomiędzy obiektami realizowane są za pomocą stosu macierzy OpenGL nie manipuluje bezpośrednio obiektami, jest to biblioteka która rysuje obiekty 3D To, gdzie zostanie narysowany obiekt zależy od bieżącej macierzy przekształcenia Macierze można odkładać na stos macierzy i pobierać je z niego glPushMatrix – odkłada macierz na stos glPopMatrix – pobiera macierz ze stosu
49
Użycie stosu macierzy glTranslatef(3,3,0); RysujNadwozie();
glPushMatrix(); glTranslatef(-1.5,-1.5,0); RysujKolo(); glPopMatrix(); glTranslatef(1.5,-1.5,0); glTranslatef(-1.5,1.5,0); glTranslatef(1.5,1.5,0);
50
Tekstury Teksturami są zwykle bitmapy, czyli tablice zawierające wartości kolorów pikseli W kartach obsługujących tzw. shader’y możliwe są tekstury proceduralne Standardowo tekstura powinna być kwadratem, którego długość boku jest potęgą 2 (w najnowszych kartach graficznych usunięto to ograniczenie)
51
Biblioteka pomocnicza
Funkcje pomagające ładować tekstury znajdują się w bibliotece glaux Aby jej używać należy dołączyć do programu odpowiedni plik nagłówkowy: #include <GL\glaux.h> W pliku projektu (NazwaProgramu.cpp) należy dodać wpis: USELIB("glaux.lib");
52
Ładowanie bitmapy z dysku
Przygotowanie zmiennej przechowującej bitmapę: AUX_RGBImageRec *TextureImage[1]; memset(TextureImage,0,sizeof(void *)*1); Ładowanie bitmapy z dysku: TextureImage[0]=auxDIBImageLoad('plik.bmp'); Tablica TextureImage może mieć dowolny rozmiar odpowiadający liczbie potrzebnych tekstur
53
Przygotowanie uchwytów
Odwołanie do tekstury następuje poprzez uchwyt, będący liczbą Dla większej ilości tekstur (tutaj 3) można utworzyć tablicę: GLuint texture[3]; Tablicę tą należy zainicjować: glGenTextures(3, &texture[0]); Następnie należy wybrać teksturę aktywną: glBindTexture(GL_TEXTURE_2D, texture[0]);
54
liczba składowych koloru
Generowanie tekstury poziom MIPmap Generowanie tekstury glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data); Operację należy powtórzyć dla wszystkich tekstur Po wygenerowaniu tekstura jest zwykle przechowywana w pamięci karty graficznej (jeśli jest miejsce) Bitmapa załadowana z dysku może zostać zwolniona: free(TextureImage[0]->data); free(TextureImage[0]); liczba składowych koloru
55
Nakładanie tekstury na obiekt
Aktywacja tekstury: glBindTexture(GL_TEXTURE_2D, texture[0]); Rysując obiekty, należy dla każdego wierzchołka określić współrzędne tekstury: glBegin(GL_QUADS); glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glEnd();
56
Współrzędne tekstury tekstura 1 rysowany czworokąt t s 1
57
Tekstury w 3D teksturowana ściana ściana tekstura
58
Filtracja tekstur bez filtracji filtracja liniowa
Włączenie filtracji tekstur: glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); bez filtracji filtracja liniowa
59
Filtracja tekstur przy pomniejszaniu
bez filtracji filtracja liniowa
60
MIPmapping Technika na przygotowaniu wcześniej pomniejszonych i przefiltrowanych wersji tekstury Nazwa pochodzi z łaciny od "multum in parvo" Poziom zerowy MIPmapy oznacza oryginalną teksturę Każdy kolejny poziom jest o połowę pomniejszonym poziomem poprzednim (stąd ograniczenie na długość boku tekstury, który musi być potęgą 2)
61
MIPmapy reprezentacja prosta w pamięci karty graficznej
62
Działanie MIPmap bez filtracji z filtrem liniowym
63
Zasłanianie obiektów Technika bufora Z
Bufor Z – bitmapa zawierająca głębię (odległość w głąb ekranu) każdego piksela w obrazie OpenGL oblicza oświetlenie dla wszystkich wielokątów Przed zapisaniem piksela w określone miejsce porównywana jest jego wartość wsp. Z z wartością bufora Z o tych samych współrzędnych Jeśli piksel jest bliżej kamery niż zapisany poprzednio w tym miejscu, piksel jest rysowany a bufor Z jest aktualizowany na wartość Z nowego piksela Jeśli nowy piksel jest dalej od kamery niż ten zapisany poprzednio, jego wartość jest ignorowana
64
Użyteczne linki Strona domowa standardu OpenGL: http://www.opengl.org
Tutoriale dotyczące programowania:
Podobne prezentacje
© 2024 SlidePlayer.pl Inc.
All rights reserved.