Információ megjelenítés Számítógépes ábrázolás Dr. Iványi Péter
Tartalom • Hogyanok? – Egy ilyen rendszer hogyan épül fel – Szükséges matematika, fizika – Alap algoritmusok
• 3D képek létrehozása a cél – Modern rendszerek használják, pl CAD rendszerek alapja is
• Animációval nem foglalkozunk
Ami kell... 1. Az ábrázolandó objektum matematikai modellje – Alak, szín, felület kialakítása – Valóságos modell létrehozása: komplex, hagyjuk a művészekre J
2. Fényforrások helye és tulajdonságai 3. Atmoszféra, amin a fény átmegy 4. A néző helyzete (mintha egy kamerát tartana) – Fókusztávolság, ...
Lépések 1. Projekció: a 3D-s valóság 2D-be leképezése 2. Szín és árnyákolás: minden pont színe is kell, a fényforrásokhoz képesti helyzet 3. Láthatatlan felületek eltávolítása: meg kell állapítani mely felületek láthatóak, melyek nem 4. Raszterizálás (rasterization): (bitmap kép létrehozása) a színes objektumok „rávetítése” a képernyőre
Kép elemei, vonallánc • Vonallánc (polyline) – Egyenes vonal szegmensek sorozata, melyek a végpontokban illeszkednek egymáshoz • A vonal szegmens: él (edge) • A végpontok: vertex
– Zárt: a kezdőpont megegyezik a végponttal – Egyszerű: Nem metszi önmagát
Kép elemei, vonallánc • Grafikus jellemzők, tulajdonságok – Szín, vonalvastagság, vonal stílus, vonal kapcsolat
Nincs
Sarkos (Mitered)
Lekerekített (Rounded)
Lecsapott (Beveled)
Kép elemei, vonallánc • Ív, kör, ellipszis, Bezier, NURBS görbe • A legtöbb rendszer nagy számú, nagyon kicsi egyenes vonalszakaszra osztja fel őket
Kép elemei, régió • Kitöltött régió (filled region) • Egyszerű zárt vonallánc által határolt terület • Van egy belső és külső része
Belső terület és határ
Belső terület
Lyukak
Kép elemei, régió • Mi van belül?
Általánosítással önmetsződő vonallánc is kitölthető. Pontosság!!!
Kép elemei, szöveg • Szöveg (text) • Betűtípus (font) • Szövegstílus – Méret: pont 1/72 inch – Kövér, dőlt, ... – Szín, ...
Kép elemei, raszter kép • Raszter kép: – „Négyzetek 2D mátrixa” – Négyzet: pixel
• Legegyszerűbb (bitmap): – Fekete és fehér pixel-ek – 1 pixel: 1 bit
• Gray-scale (szürke árnyalat) – 1 pixel: 0 – 255 közötti érték
• Színes képek (RGB)
Kép elemei, raszter kép
Színek • Színeket vörös (red), zöld (green), kék (blue) színekből keverjük ki • 24 bit RGB – Minden komponens 8 bit, 0-255 – 16 777 216 szín – az emberi szem kb. 10 millió színt érzékel
• 4. Komponens az átlátszóság jellemzésére – RGBA – A = Alpha faktor
Alpha faktor • Alpha blending – Színek kombinációja, mely az átlátszóság hatását kelti – Értéke 0-1 közötti • 0: teljesen átlátszó • 1: teljesen opaq, kitakar
– Az eredmény szín:
vered = (1 - a ) × v0 + a × v1
Alpha faktor
Szín táblázat • Lehet hogy kevesebb szín is elég • Szín táblázat, színtérkép (color map) – color look-up table (LUT) – pl. GIF fájlok
Kép megjelenítés , egyszerű • A program egy 2D-s tömbben tárolja képet (Frame buffer) • A frame buffer nem hardware, a RAM része • A „video controller” folyamatosan olvassa a frame buffer-t és állítja elő a képet • A képet soronként állítja elő (raszter line)
Kép megjelenítés, egyszerű
Kép megjelenítés, komplex • Speciális hardware (display processor) • Nem a normál processzornak kell dolgoznia • Grafikus gyorsító (graphics accelerator) – Többféle feladatot lát el, például: • Transzformáció • Árnyékolás, színezés • Textúrák
Kép megjelenítés, komplex
Grafikus cső Néző síkba vetítés (projection transform)
3D model definiálása (objektum létrehozás)
2D image
Model elhelyezése a világban (model transformáció) Model nézése (viewing transform) Model árnyékolása (lighting equations)
Primitívek renderelése (scan conversion, hidden surface removal, interpolation of color, texture, normals, …)
Grafikus cső (graphics pipeline) 3D objektumok
Pixel clipping
Parancs feldolgozás
Paraméter interpoláció pixelekhez
Vertex feldolgozás 2D à 3D
Pixel + textúra
Clipping
Pixel Engine Kombinálás Frame bufferrel
Pixel generálás Raszterizálás
Grafikus cső, hardware
Hardware • GPU (Graphics Processing Unit) • VPU (Visual Processing Unit) • Gyártók: – ATI, NVIDIA – Matrox, Intel – VIA Technologies
Programozói interface • • • •
Application Programming Interface (API) SGI – OpenGL Microsoft – Direct3D Pixar – Renderman
OpenGL • Open Graphics Library • Hardware független – Programozó egyszer írja meg a programot és bármely hardware-en futtathatja
• SGI (Silicon Graphics) fejlesztette ki • www.opengl.org
OpenGL történelem • 1990 eleje, SGI a fő 3D-s fejlesztő – IRIS GL (Integrated Raster Imaging System Graphics Library)
• Akkori nyílt szabvány: PHIGS – Komplex, nehezen programozható – IBM, HP, Sun Microsystem támogatja, hardware-t fejleszt
• SGI nyílt szabványt akar, de IRIS GL nem alkalmas – Licensz, probléma
OpenGL történelem • SGI létrehozza OpenGL • Szabványosítás • OpenGL 2.0 – 3DLabs túl lassúnak találja fejlődést – Több nagyobb változást javasolnak
• OpenGL 2.1 – 2006 augusztus 2
• OpenGL 3.0
OpenGL szabványosítása • Szabványosították – OpenGL Architecture Review Board (ARB), 1992
• 2006 április, tagok – SGI, 3Dlabs, ATI Technologies, NVIDIA, Intel – IBM, Apple Computer, Dell, Sun Microsystems
• 2003 óta nem tag – Microsoft
• 2006-tól a Khronos Csoport felügyeli – www.chronos.org
Direct3D • 1992 – Servan Keondjian cége, RenderMorphic • 3D API, Reality Lab
• 1995-ben Microsoft megveszi – Windows 95 – DirectX 2.0, 3.0
• Folyamatos fejlesztés – Windows Vista: DirectX 10
Közös API ??? • Fahrenheit project – Microsoft, SGI, HP – OpenGL és Direct3D egységesítése
OpenGL • Grafikus renderelésra használható API – Jó minőségű színes képek létrehozása egyszerű geometriai és képi primitívekből – GUI rendszer független – Operációs rendszer független
OpenGL • Két fő célja van: – Elrejteni a 3D-s gyorsítok bonyolultságát és egy egyszerű API-t adni – A hardware különbségek elrejtése, mivel minden hardware-nek támogatnia kell
• Több mint 200 függvény • A modellt geometriai primitívekből kell összeállítani: pontok, vonalak, területek • Nincs függvény ablak létrehozásra vagy felhasználói input kezelésére!!! • Nincs file formátum
OpenGL kiegészítések • Az alap specifikáció kiegészítései • Hardware specifikus • Kiegészítések – 318 számozott – 5 számozatlan
• Példa: – GL_EXT_vertex_shader – GL_ATI_fragment_shader – GL_NV_fog_distance
OpenGL könyvtárak • OpenGL Utility Library (GLU) – Magasabbrendű függvények – OpenGL szabványos része
• OpenGL Utility Toolkit (GLUT) – Ablak létrehozása – I/O eszközök kezelése (egér, billentyűzet) – Nem szabványos, csak kiegészítés
OpenGL más API-k graphics application OpenGL widgets (MFC, wxWidgets, Qt, FLTK, …)
GLUT
GLX, AGL or WGL
X, Win32, Mac O/S device drivers hardware
GLU GL
OpenGL program • Konfiguráljunk és nyissunk meg egy ablakot • Initcializáljuk az OpenGL állapotát • Regisztráljunk visszahívó függvényeket – Rajzolás (render) – Méret változás (resize) – Input (billentyűzet, egér)
• Lépjünk be az eseményeket kezelő ciklusba
OpenGL program 1. #include
void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } void SetupRender(void) { glClearColor(0.0, 0.0, 1.0, 1.0); /* kek hatter */ } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutCreateWindow("Simple"); glutDisplayFunc(RenderScene); SetupRender(); glutMainLoop(); return 0; }
OpenGL program részei • glutInit – A parancssori opciókat dolgozza fel – Inicializálja az OpenGL és a GLUT könyvtárakat
• glutInitDisplayMode – Beállítja hogy az OpenGL a frame buffer-t hogyan kezelje – Pl. a színeket hogyan reprezentáljuk
glutInitDisplayMode Mód
Magyarázat
GLUT_RGB
RGB színeket használjon
GLUT_RGBA
RGB színeket használjon és egy komponens az átlátszósághoz
GLUT_INDEX
Színtérkép használata
GLUT_DOUBLE
Két buffert használjon
GLUT_SINGLE
Egy buffert használjon
GLUT_DEPTH
Mélységi buffert is használjon
GLUT_SINGLE • •
Akármit is írunk a frame buffer-be azonnal megjelenik a képernyőn Rajzolás 1. Letöröljük a képernyőt 2. Rajzolunk valamit 3. Vissza az 1. lépéshez
•
Képernyőn villódzást látunk, ez zavaró lehet
Single Buffering
1
Buffer
2
4
8
16
Display
GLUT_DOUBLE • Két buffer van: – front buffer: ami megjelenik a képernyőn – back buffer: ebbe lehet rajzolni
• A kép frissítéséhez csak fel kell cserélni a két buffert • A csere nagyon gyors, de kétszer annyi memória kell
Double Buffering 1.
1
Front Buffer
2
1
4
8
16
2
4
8
16
Display
Back Buffer
Double Buffering 2.
1
Front Buffer
2
1
4
8
16
2
4
8
16
Display
Back Buffer
GLUT_DEPTH • • • •
Mélység buffer Nem látható felületek megállapításához kell Ez is egy buffer A szín bufferek a pixel színét rögzítik, a mélység buffer a nézőtől való távolságot
Depth Buffering
1
Color Buffer
2
1
4
8
16
2
4
8
16
Display
Depth Buffer
Ablakok • glutInitWindowSize(int w, int h) – A létrehozandó ablak mérete pixel-ben
• glutInitWindowPosition(int x, int y) – A létrehozandó ablak pozíciója – x,y : ablak bal felső sarka
• glutCreateWindow(char *title) – Egy ablak létrehozása – A fejlécben az ablak neve is megadható
Esemény vezérelt program render()
event loop event queue
drivers (WM, OS)
for(;;) { e = wait_event(); switch (e.type) case REDRAW: render(); case INPUT: input(); … }
glBegin(); … glEnd();
input() { react on keyboard/mouse; glutPostRedisplay() hardware
}
Visszahívó (callback) függvények • Ahhoz hogy a felhasználó által definiált függvény is lefusson az adott esemény után, a felhasználói függvényt „regisztrálni” kell a „rendszerrel”. • Meg kell mondani, hogy melyik függvényt hívja meg melyik eseménynél • Egy függvény egy ablakhoz tartozik és csak az ablak eseményeiről értesül
Callback függvények • Minden alkalmazásnak meg kell adnia mi történjen, ha az ablakot a rendszer megjeleníti – Az első megjelenítésnél – Miután egy másik ablak kitakarta
• glutDisplayFunc
Callback függvények Esemény
Függvény
Prototípus
Megjelenítés
glutDisplayFunc
myDisplay();
Méretváltozás glutReshapeFunc
myResize(int w, int h);
Egér gomb
glutMouseFunc
myMouse(int b, int s, int x, int y);
Egér mozgás
glutPassiveMotionFunc
myMotion(int x, int y);
Billentyűzet
glutKeyboardFunc
myKeyboard(char c, int x, int y);
Időzítés
glutTimerFunc
myTimer(int id);
Üresjárat
glutIdleFunc
myIdle();
OpenGL függvények • glClearColor – A háttér szín definiálása
• glClear() – Letörli az ablakot, vagyis felülírja a háttér színnel – Valójában mely buffereket kell törölni – Például: glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
• glFlush() – Az összes parancs végrehajtása
GLUT függvények • glutMainLoop(); – Az eseményvezérelt program fő ciklusa – Kilépés csak ha vége a programnak
OpenGL program 2. a) #include void RenderScene(void) { glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex2f(0.90, 0.50); glVertex2f(0.50, 0.90); glVertex2f(0.10, 0.50); glVertex2f(0.50, 0.10); glEnd(); glColor3f(0.0, 0.0, 1.0); glRectf(0.25, 0.25, 0.75, 0.75); glutSwapBuffers(); }
OpenGL program 2. b) void SetupRender(void) { glClearColor(0.0, 0.0, 0.0, 1.0); /* fekete hatter */ } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(300, 300); glutInitWindowPosition(0,0); glutCreateWindow("Simple"); glutDisplayFunc(RenderScene); SetupRender(); glutMainLoop(); return 0; }
OpenGL program 2.
OpenGL „rajzolás” • Csak egyenes oldalú objektumokat lehet rajzolni, így elég a vertex-eket (pontokat) megadni • A látvány egyszerű, kicsi alakzatokból épül fel!!! • A megjelenítési tulajdonságokat is meg kell adni: – – – –
Szín Vonal vastagság Pont méret Stb.
OpenGL színek • glColor3f(Glclampf r, Glclampf g, Glclampf b); – – – –
RGB színek Zérus és egy közötti értékek: [0.0 - 1.0] Például: 1,0,0 = vörös Minden további objektumnak ez lesz a színe
Függvény elnevezési szabályok <prefix> <arg. száma><arg. típusa>
gl Color 3 glColor3f(r, g, b); glColor4f(r, g, b, a);
f
OpenGL adattípusok • • • • • • • •
GLbyte Ha lehet ezeket használjuk!!! GLshort GLint, GLsizei GLfloat, GLclampf GLdouble, GLclampd GLubyte, GLboolean GLushort, GLuint GLenum, GLbitfield
OpenGL színek még egyszer • glColor3ui(Gluint r, Gluint g, Gluint b); – unsigned int – Tartomány: [ 0 – MAXINT ]
OpenGL színek ismét GLclampf szinek[3] = {0.0, 1.0, 0.0}; glColor3fv(szinek); • Vektorosan is megadható
OpenGL objektumok • Ismeretlen számú pontból áll az objektum • glBegin és glEnd között kell megadni • Az objektum típusát a glBegin függvénnyel lehet megadni • Közben nem lehet objektum típust váltani • Konvex objektumokat definiáljunk • A konkáv objektumokat osszuk fel konvex objektumokra!!!
OpenGL objektum típusok
Csak ezek adhatók meg a glBegin függvény argumentumaként
Színek per vertex glBegin(GL_TRIANGLES); glColor3f(1.0, 0.0, 0.0); glVertex2f(-0.90, -0.90); glColor3f(0.0, 1.0, 0.0); glVertex2f(0.90, -0.90); glColor3f(0.0, 0.0, 1.0); glVertex2f(0.0, 0.90); glEnd();
Kör rajzolása #define PI 3.14159265 #define NPONTOK 100 void RenderScene(void) { int i; double angle; glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINE_LOOP); for(i = 0; i < NPONTOK; i++) { angle = 2.0 * PI * i / NPONTOK; glVertex2f(cos(angle), sin(angle)); } glEnd(); glutSwapBuffers(); }
Transzformációk • Eddig egy „ideális” négyzetbe rajzoltunk -1,1
1,1
0,0
-1,-1
1,-1
Transzformációk • Egy másik nézethez transzformációt kell definiálni • Mátrixokat kell manipulálni, de vannak segéd függvények • gluOrtho2D(bal, jobb, alul, felül); – Egy két dimenziós (2D) területet ad meg, ahova rajzolunk
Transzformációk glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 1.0, 0.0, 1.0);
1. sor: vetítési transzformációt módosítjuk 2. sor: az aktuális mátrix legyen az egység mátrix 3. sor: a négyzet definiálása 1,1
0,0
További transzformációk • Az OpenGL nem feltételezi, hogy a teljes ablakot használjuk • Nézet ablak (viewport) definiálható • Ezt igazítani kell minden alkalommal, amikor az ablak mérete megváltozik • glViewport(x, y, szelesszeg, magassag);
Transzformáció (pipeline)
idealizált rajzterület
Minden ami a területen kívülre esik „levágódik” (clipping).
OpenGL program 3. a) #include #include void RenderScene(void) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 1.0, 0.0, 1.0); glClear(GL_COLOR_BUFFER_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex2f(0.90, 0.50); glVertex2f(0.50, 0.90); glVertex2f(0.10, 0.50); glVertex2f(0.50, 0.10); glEnd(); glColor3f(0.0, 0.0, 1.0); glRectf(0.25, 0.25, 0.75, 0.75); glutSwapBuffers(); }
OpenGL program 3. b) void ResizeWin(int w, int h) { glViewport(0, 0, w, h); } void SetupRender(void) { glClearColor(0.0, 0.0, 0.0, 1.0); } int main() { glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(300, 300); glutInitWindowPosition(0,0); glutCreateWindow("Simple"); glutDisplayFunc(RenderScene); glutReshapeFunc(ResizeWin); SetupRender(); glutMainLoop(); return 0; }
OpenGL program 3. Régi változat
Új változat
OpenGL egy állapot ‘masina’ • Minden parancs azonnali hatással van az aktuális képre, állapotra • Például a szín is addig érvényes amíg meg nem változtatjuk • Másik példa: köd – Be- vagy ki van kapcsolva
• A függvényekkel beállítható, de le is kérdezhető
Irodalom • David M. Mount: Computer Graphics, Lecture Notes, CMSC 427, University of Maryland, 2004 • OpenGL Red book