1 OpenGL grafikus rendszer Dr. Nehéz Károly egyetemi adjunktus Miskolci Egyetem Alkalmazott Informatikai Tanszék.

Slides:



Advertisements
Hasonló előadás
OpenGL 2. gyakorlat Hapák József
Advertisements

L ÁTHATÓSÁG MEGHATÁROZÁSA tavaszi félév.
Grafikus Hardver Alapok
Számítógép grafika.
BSP-fák használata játék- engine fejlesztésében a nagy kiterjedésű zárt terek megjelenítéséhez Előadó: Boromissza Gergely Konzulens: dr. Szirmay-Kalos.
Többfelhasználós és internetes térkép kezelés, megjelenítés.
1 Hernyák Zoltán Programozási Nyelvek II. Eszterházy Károly Főiskola Számítástudományi tsz.
2D grafikus rendszerek Szirmay-Kalos László. 2D grafikus editor: GUI, use-case, dinamikus modell L L L R LD LU MouseLDown első pont MouseLDown második...
Geometriai modellezés
2D grafikus rendszerek Szirmay-Kalos László.
OpenGL Szirmay-Kalos László In theory, there is no difference
Bevezetés.  A számítógépes grafika inkrementális képszintézis algoritmusának hardver realizációja  Teljesítménykövetelmények:  Animáció: néhány nsec.
GPGPU labor I. OpenGL, Cg.
Bevezetés a Java programozásba
1 Programozás alapjai GEIAL312B (ANSI C) BSc (Bachelor of Science) / Alap képzés 2005/2006. őszi félév Miskolci Egyetem Általános Informatikai Tanszék.
5. előadás (2005. március 22.) Függvények definíciója, deklarációja, hívása Enumerációs adattípus 1.
GRAFIKUS PRIMITÍVEK KITÖLTÉSE
Programozás II. 3. Gyakorlat C++ alapok.
Grafika a programban Készítette: Pető László. Bevezetés Valójában nem a célobjektumra rajzolunk, hanem annak festővászon területére (canvas). Csak olyan.
Grafikus Rendszerek Zsitnyánszki Zoltán.
Számítógépes grafika, PPKE-ITK, Benedek Csaba, D képszintézis 4. előadás.
Számítógépes grafika, PPKE-ITK, Benedek Csaba, 2010 Geometriai modellezés 2. előadás.
Grafikus szoftver alrendszer, OpenGL alapok
Számítógépes grafika OpenGL 1. gyakorlat.
C++ Alapok, első óra Elemi típusok Vezérlési szerkezetek
3. Vetületi ábrázolások számítási eljárásai
Webszerkesztés Stíluslapok (CSS).
2D képszintézis és textúrák
PHP I. Alapok. Mi a PHP? PHP Hypertext Preprocessor Szkriptnyelv –Egyszerű, gyors fejlesztés –Nincs fordítás (csak értelmező) Alkalmazási lehetőségek:
Számítógépes grafika 3. gyakorlat.
2. Koordináta-rendszerek és transzformációk
Programozási Nyelvek (C++) Gyakorlat Gyak 02.
2008/2009 tavasz Klár Gergely  Gyakorlatok időpontjai: ◦ Szerda 10:05–11:35 ◦ Csütörtök 10:00+ε –11:30+ε  Gyakvez: ◦ Klár Gergely ◦
Turbo Pascal 11..
A grafikus megjelenítés elvei
Készítette: Csíki Gyula
Rendering pipeline Ogre3D
2D grafikus rendszerek Szirmay-Kalos László.
Web-grafika II (SVG) 3. gyakorlat Kereszty Gábor.
Web-grafika II (SVG) 1. gyakorlat
2.2. Az egyenes és a sík egyenlete
2. gyakorlat DirectX 2007/2008 tavasz Klár Gergely
Objektum orientált programozás
Bevezetés a számítógépi grafikába 2. Paraméteres görbék Paraméteres görbe: 2D-ben: paraméter: általában: kikötések: legyen folytonos legyen folytonosan.
Grafika alapfogalmak.
Számítógépes grafika, PPKE-ITK, Benedek Csaba, 2010 Geometriai modellezés 2. előadás.
Számítógépes grafika I. AUTOCAD alapok 3. előadás.
CUDA C/C++ programozás CUDA C bevezetés A segédanyag készítése a TÁMOP A/ Nemzeti Kiválóság Program című kiemelt projekt keretében.
Geometriai feladatok programozása Geometriai programozás Szlávi Péter ELTE IK Média- és Oktatásinformatika Tanszék 2010.
Képek, képfeldolgozás Szirmay-Kalos László.
Grafikus szoftver Szirmay-Kalos László. Interaktív programok felépítése input csővezeték output csővezeték.
1 Viewing Megtekintés. 2 Miről lesz szó? ► Modellek megtekintése különböző, vagy tetszőleges irányokból ► Nézőpont áthelyezése a háromdimenziós térben.
Táblák létrehozása és feltöltése adatokkal Rendezés Szűrés.
Alapvető raszteres algoritmusok, szakasz rajzolása, DDA, MidPoint algoritmus.
Alkalmazott Informatikai Tanszék
Framebuffer.
OpenGL 2. gyakorlat Valasek Gábor
6. A 3D grafika alapjai 6.1. A 3D szerelőszalag fölépítése
Vizualizáció és képszintézis
OpenGL megjelenítési listák
Árnyékszerkesztés alapjai
Neumann János Informatikai Kar
Átlátszóság, csipkézettség, köd
Görbék, felületek.
Adat- tárolás.
GPGPU – CUDA 2..
Bevezetés Tematika Számonkérés Irodalom
A digitális kép bevezetés.
Neumann János Informatikai Kar
Előadás másolata:

1 OpenGL grafikus rendszer Dr. Nehéz Károly egyetemi adjunktus Miskolci Egyetem Alkalmazott Informatikai Tanszék

2 Az OpenGL története ► Silicon Graphics, IrixGL (1980) ► 1990, OpenGL nyitott (nyílt) grafikus könyvtár ► GLX – összeköttetés az ablakozó rendszerrel ► GLU – gl utility standard kiegészítés ► GLUT – gl utility újabb kiegészítés ► ARB (Architechtural Review Board) konzorcium ► ARB tagok (Silicon Graphics, Microsoft, Sun, IBM, NVIDIA, ATI, Matrox)

3 OpenGL felépítése

4 Geometriai adatok rajzolásának alapjai ► A rajzolási terület törlése egy adott színnel ► Geometrikus primitívek rajzolása (pont, szakasz, poligon) ► A geometrikus primitívek tulajdonságainak megváltoztatása (szín, vonaltípus, vonalvastagság, stb.) ► Normálvektorok megadása ► Rajzolás befejezése

5 ► A megjelenített komplex geometria, minden esetben primitív grafikus elemekből áll. (legtöbbször háromszögek, négyszögek)  A modern grafikus kártyák hardveresen támogatják ezek „renderelését” ► Alapvető rajzolási operációk:  Képernyőtörlés (a színbuffer törlése)  Geometriai objektum kirajzolása. (közvetlen vagy tárolt formában)  Raszter objektum kirajzolása. (raszter objektum lehet: bitmap, karakter fontkészlet elem)

6 Ablak törlése ► Az aktuális video-memória minden esetben vagy memória-szemetet, vagy valamilyen előző kirajzolt fázis képét tartalmazza. Ezért kell feltölteni a színbuffert háttérszínnel.  Miért nem töltjük fel a buffer egy nagyméretű háttérszínre festett négyzettel? 1. A video memória nagyon nagy méretű. Pl.: 1024* bites kép esetén 2.3 Mbyte adat törlése szükséges minden képfázis rajzolása előtt. 2. A raszterizálás folyamán több transzformációt végez a rendszer, így sokszor nehéz kiszámolni a megfelelő méretű téglalapot. 3. A ‘takart felületek eltávolítása’ miatt a négyzet térbeli helyzete is nehezen lenne meghatározható 4. A grafikus rendszer több buffert is tartalmaz, amit ugyancsak törölni kellene minden új fázis rajzolása előtt. (stencil, accumlation, depth bufferek) Megoldás: speciális függvényhívások alkalmazása

7 Ablak törlése ► Példa: ablak hátterének feketére festése  glClearColor (0.0, 0.0, 0.0, 0.0); glClear(GL_COLOR_BUFFER_BITS); Az első függvényhívás feketére állítja a törlés színét. (Red Green Blue Alpha formátumban) A törlés színét elég egyszer beállítani, mivel a rendszer egy állapotváltozóban tárolja a hatékonyság növelése érdekében

8 Ablak törlése ► Példa: glClearColor (0.0, 0.0, 0.0, 0.0); glClearDepth(0.0); glClear(GL_COLOR_BUFFER_BITS | GL_DEPTH_BUFFER_BIT); ► A mélységbuffer alapértelmezett értéke 0.0 Az OpenGL lehetővé tesz több buffer egyidejű törlését a sebesség növelése érdekében.

9 Színek megadása ► A OpenGL rendszerben a geometriai és a színinformáció egymástól független. ► Általában a programozó megad valamilyen színinformációt majd ezt követően adja meg a grafikus adatokat.  Aktuális_Szín(piros); Rajzol(objectA); Rajzol(objectB); Aktuális_Szín(zöld); // mi lesz zöld? Aktuális_Szín(kék); Rajzol(objectC); // milyen színű lesz objectC?

10 Színek megadása ► A színek megadásának módja: glColorXY() glColor3f(1.0, 0.0, 0.0); // piros glColor3f(0.0, 1.0, 0.0); // zöld glColor3f(0.0, 0.0, 1.0); // kék glColor3f(1.0, 1.0, 1.0); // fehér glColor3f(0.0, 0.0, 0.0); // fekete glColor3f(0.5, 0.5, 0.5); // szürke árnyalat

11 Rajzolás befejezése ► Modern grafikus hardverek grafikus csővezeték elvén működnek. A CPU végrehajt egy grafikus utasítást, de e mellett egy másik egység transzformál, vág, árnyal, texturát tömörít, stb. Majd az eredmény megjelenik a különböző bufferekben. Ameddig egy pont (vertex) megjelenik a csővezeték bementénél, addig a transzformációs hardver még az előző elküldött elemen dolgozik. ► Az alkalmazás futhat elosztott környezetben is, több gépen. A kliens gyűjti a hálózatról a soron következő parancsokat. Jó volna tudni, hogy mikor mondhatjuk azt, hogy a képfázis készen van? ► Az OpenGL nem tárolja a grafikus primitíveket, hanem az előzetes beállításoknak megfelelően az állapotgép utasításait hajtja végre a soron következő grafikus elemen!

12 Rajzolás befejezése ► Megoldás: glFlush() A glFlush() minden képfázis végét jelezve végre kell hajtani. ► glFinish() a különbség csak annyi, hogy a hívás után várakozik a befejezésre.  szinkronizáció esetén  user-input esetén biztosítja a teljes rajz megjelenését

13 Takart felületek kezelése ► A több objektumot tartalmazó kép esetén a kirajzolás sorrendjétől függetlenül kell biztosítani, hogy a takart felületek ne látszanak.  Pl: while(1) { getNézőpont_egérpozíció_alapján(); glClear(GL_CLEAR_COLOR_BUFFER_BIT); Rajzol(3dobjectA); Rajzol(3dObjectB); } ► Olyan módszert kellene alkalmazni, amely minden esetben, nézőponttól függetlenül jól működik.

14 Megoldás: z-buffer algoritmus alkalmazása: A z-buffer algoritmus a takarási feladatot az egyes pixelekre oldja meg, oly módon, hogy minden pixelre megkeresi azt a poligont, amelynek a pixeleken keresztül látható pontjának a z koordinátája minimális. 1. Ezt a keresést azzal támogatja, hogy minden pixelhez letárol egy aktuális mélység értéket. 2. A poligonokat egyenként dolgozza fel és meghatározza a poligonok vetületén belül eső pixeleket. 3. Inicializáláskor a z-buffer minden pixelében a tárolható legnagyobb érték van (‘végtelennel’ történő inicializálás). 4. A rajzolási folyamat során a poligonok vetületi képe jelenik meg a szín bufferben, de ugyanakkor pixelenkénti z- koordinátákat a z-buffer tárolja. Ha p(i,j) pixelhez letárolt z koordináta kisebb, mint az aktuális poligon p(i,j) pixelre eső z- koordinátája, akkor felülírjuk a letárolt z-koordinátát, mivel ez azt jelenti, hogy az aktuális poligon ezen p(i,j) pixele nincs takarásban (közelebb esik a képernyő síkjához, mint a letárolt érték). Amennyiben z-buffer felülírás történik, akkor természetesen a képernyő megfelelő pixelének színe is módosul.

15 A z-buffer algoritmus OpenGL megvalósítása ► glEnable(GL_DEPTH_TEST); … … while(1) { glClear (GL_CLEAR_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); getNézőpont_egérpozíció_alapján(); Rajzol(3dobjectA); Rajzol(3dObjectB); }

16 Pontok, szakaszok, poligonok leírása ► Minden geometriai primitív végső soron leírható vertex koordináták segítségével. ► Pontok – vertexek sorozata, ► Szakaszok – kezdő és végpont vertex koordinátáival ► Poligonok – csúcspontok vertex koordinátáival ► Mi a pont, szakasz, poligon?  Matematikai értelemben egyszerű fogalmak  ‘OpenGl értelemben’ más a helyzet, mert a a primitíveket lebegőpontos formában adhatjuk meg, limitált pontossággal.  Az OpenGL színbuffere egy bittérkép, aminek alapegysége a képpont. Sok esetben előfordul, hogy a különböző lebegőpontos értékekkel megadott pontok ugyanarra a pixelre esnek.

17 ► Pontok: pontokat 2 vagy 3 koordináta segítségével adhatunk meg. Minden transzformációs lépés 3 dimenzióban történik. Ha csak két koordinátát adunk meg akkor a harmadikat automatikusan zérónak tekinti a rendszer.  Az OpenGL értelmezi az úgynevezett a háromdimenziós projektív geometria homogén koordinátáit. Ekkor egy pontot 4 koordináta ír le: (x,y,z,w). Ha a w != 1.0 akkor a rendszer (x/w, y/w, z/w) pontot jeleníti meg.

18 ► Szakaszok,vonalak: az OpenGL vonal, vonalszakaszt jelent. Nem a matematikai értelemben vett egyenest. Egymással kapcsolódó szakaszok esetén elegendő a végpontokat megadni.

19 ► Poligonok: zárt vonalszakaszok halmaza.  A szakaszok nem metszhetik egymást.  A poligonoknak konvexeknek kell lenniük.  Nem tartalmazhatnak kivágásokat. ► A poligonok rajzolása nem hatékony, célszerűbb háromszögekkel dolgozni. Amennyiben konkáv vagy kivágott poligonokkal szeretnénk dolgozni, akkor segítségünkre lehet a GLU által támogatott tessallációs függvények.

20 Speciális tulajdonságok ► A poligonok pontjainak nem szükségszerűn kell egy síkon lenniük.

21 Görbék ► A görbék interpolációja vonalszakaszokkal történik. Minél több a vonalszakaszok száma, annál finomabb a görbe, de a rajzolás sebessége csökkenhet.

22 Vertexek megadása ► Minden geometriai objektum vertexek rendezett halmazával írható le. ► glVertex*() függvény segítségével glVertex2s(4,5); glVertex3d(0.0, 0.0, ); glVertex4f(0.0, 1.2, 3.4, 1.0); float dvect[3] = {1.0f,1.0f,3.0f}; glVertex3dv(dvect);

23 Geometriai primitívek megadása ► glBegin(GL_POLYGON); glVertex2f(0.0, 0.0); glVertex2f(0.0, 3.0); glVertex2f(3.0, 3.0); glVertex2f(4.0, 1.5); glVertex2f(3.0, 0.0); glEnd(); ► glBegin() adja meg a geometriai primitív típusát ► Ugyanaz a vertex halmaz, különböző primitívként is megjeleníthető.  Mi történik ha egy poligon esetén csak 1 vertexet adok meg?  Mi történik ha a glVertex hívások között más függvényhívásokat is szerepeltetünk?

24

25 OpenGL - Hello háromszög #include void kirajzol(void); void main() { glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);// megjelenítési mód glutInitWindowSize (500, 500);// ablakméret glutCreateWindow ("Elso OpenGL pelda - 'Hello háromszög'");// ablak létrehozása glutDisplayFunc (kirajzol);// a rajzoló függvény megadása glutMainLoop ();// végtelen ciklus a rajzoláshoz } void kirajzol(void) { glClearColor (0.5f, 0.5f, 0.5f, 0.0f);// szürke szín glClear (GL_COLOR_BUFFER_BIT);// képernyőtörlés glBegin (GL_TRIANGLES);// háromszögeket rajzolunk glVertex2f(0, 0); glVertex2f(0.5, 0.5); glVertex2f(0.5, 0.0); glEnd ();// vége glFlush ();// rajzold ki (de) azonnal! }

26 Megkötések a glBegin() és glEnd() párok használatában ► glBegin() és glEnd() pár között lehetőség van: a színek megváltoztatására, normál vektorok, textura-koordináták, anyagtulajdonságok, megadására. ► Lehetőség van bármilyen más ‘nem grafikus’ művelet elvégzésére glVertex*() vertex koordináták glColor*() vertex színek glIndex*()color-index glNormal*() normál vektorok glEvalCoord*() koordináta generálás glCallList() display listák glTextCoord*() Textura koordináták glEdgeFlag*()élek glMaterial*()anyagtulajdonságok

27 Példa: Kör rajzolása #define PI int points = 100; glBegin(GL_LINE_LOOP); for (int i = 0; i < points; i++) { float szog = 2 * PI * i / points; glVertex2f(cos(szog), sin(szog)); }glEnd(); Önálló feladat: az első példa (hello háromszög) módosítása a fenti kódrészlet segítségével.

28 Pontok, szakaszok, poligonok megjelenítési tulajdonságai ► A programozást az állapotgép számos előre beállított ‘default’ értékei segíti. Pl: pont – egy pixel a képernyőn szakasz – egy pixel széles szakasz poligon – egy adott színnel befestett terület ► Pontok esetén a méret: glPointSize(GLfloat size) – hívással módosítható

29 ► A pont maximális mérete a glGetFloatv(GL_POINT_SIZE_RANGE, …); segítségével lekérdezhető. ► Ha az antialiasing (csipkézettség mentesítés) kikapcsolt állapotban van, akkor a megadott pontméret egészre kerekített pixelértéket jelent. Ellenkező esetben egy körkörös pontcsoport lesz kirajzolva, amelynek határpixelei halványabb színnel lesznek kirajzolva.

30 Szakaszok tulajdonságai ► Vonalvastagság és vonaltípus az állítható tulajdonságok. glLineWidth(GLfloat width); //alapértlemezett:1.0 A vonalvastagság pixelekeben mért értéke csak a csipkézettség mentesítés kikapcsolása esetén jelent egész számú pixelértéket. 1,2,3 – 1,2,3. ► A szakasz maximális szélessége a glGetFloatv(GL_LINE_WIDTH_RANGE, …); segítségével kérdezhető le.

31 Vonaltípusok ► glLineStipple(1, 0x3F07); // faktor, bitek glEnable(GL_LINE_STIPPLE); // bekapcsolás ► 0x3F7 – pixel be, 5 ki, 6 be, 2 ki. ► Ha a faktor pl. 2 akkor, 6 pixel be, 10 ki, 12 be, 4 ki. ► glDisable(GL_LINE_STIPPLE); ► Default esetben: glLineStipple(1, 0xFFFF);

32 Minta Faktor (szorzó) 0x00FF x00FF2 0x0C0F xAAAA xAAAA2 0xAAAA3 0xAAAA4

33 Szakaszok példaprogram

34 Poligonok tulajdonságai ► Minden poligon kétoldalas, egymástól független tulajdonságokkal rajzolható. ► glPolygonMode(GLenum face, GLenum mode); face: GL_FRONT_AND_BACK GL_FRONT, GL_BACK mode: GL_POINT, GL_FILL, GL_LINE

35 ‘Front facing’ - poligon ► Az óramutató járásával ellentétes sorrendű vertexek (GL_CCW) reprezentálják az elülső (front) lapot. ► glFrontFace(GLenum mode) mode: GL_CCW, CL_CW

36 Sebesség növelése ► A nemlátható „hátsó” élek eltüntetése (back-culling): glBegin(GL_CULL_FACE); glCullFace(GLenum mode); mode: GL_FRONT, GL_BACK Az vertexek ablak koordinátái alapján a rendszer el tudja dönteni, hogy melyik oldalt kell kirajzolni: Példa: ha GL_CCW módban vagyunk és a>0 akkor a front oldalt látjuk. Ha a<0 akkor a hátsó oldalt látjuk.

37 Szinusz görbe rajzolás

38 Egy lehetséges megoldás #include #define PI void kirajzol(void); void main() { glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);// megjelenítési mód glutInitWindowSize(500,500);// ablakméret glutCreateWindow("Szinusz görbe rajzolása");// ablak létrehozása glutDisplayFunc(kirajzol);// a rajzoló fuggvény megadása glutMainLoop();// végtelen ciklus a rajzoláshoz } void rajzolkoordinata() { glBegin(GL_LINES);// Egyenesek rajzolása glVertex2f(-2,0); glVertex2f(2,0); glVertex2f(0,1); glVertex2f(0,-1); glEnd(); }

39 Egy lehetséges megoldás. (folyt.) void kirajzol(void) { glClearColor(0.5f,0.5f,0.5f,0.0f);// szürke szin glClear(GL_COLOR_BUFFER_BIT);// képernyőtörlés // // koordináta rendszer rajzolása // glLineWidth(2.0); glColor3f(1.0f,0.0f,0.0f); rajzolkoordinata(); // // beosztás kirajzolása // glLineWidth(12.0); glEnable (GL_LINE_STIPPLE); glLineStipple (3, 0x0101); // szaggatott rajzolkoordinata(); glDisable (GL_LINE_STIPPLE); // // a szinusz görbe // glLineWidth(3.0); glBegin(GL_LINE_STRIP);// Egyenesek rajzolása glColor3f(1.0f, 1.0f, 1.0f); for (float i = -2.0f * PI; i < 2.0f * PI; i += 0.1)// sinus görbe -2PI tol 2PI közötti intervallumban { glVertex2f(i/PI, sin(i)); } glEnd(); glFlush();// rajzold ki }

40 OpenGL adattípusok OpenGL adattípus Belső reprezentáció C típus C suffix GLbyte 8-bit integer Signed char b GLshort 16-bit integer shorts GLint, GLsizei 32-bit integer longi GLfloat, GLclampf 32-bit floating point floatf GLdouble, GLclampd 64-bit floating point doubled GLubyte, GLboolean 8-bit unsigned integer unsigned char ub GLushort 16-bit unsigned integer unsigned short us GLuint, GLenum, GLbitfield 32-bit unsigned integer unsigned long ui