Selection Feedback 1 Mirl lesz sz Szelekci segtsgvel
Selection, Feedback 1
Miről lesz szó? ► Szelekció segítségével objektumok kiválasztása a képernyőről (pl. interakció) ► A renderelés eredményének visszaolvasása feedback módban. (pl. plotter) ► Példák 2
Selection (kiválasztás) ► Szelekció esetén a framebufferben nincs változás ► Kiválasztási mód befejeztével visszakaphatjuk a ‘nézeti térfogatban’ (viewing volume) elhelyezkedő objektumok ‘neveit’. (A nevek már előzőleg adottak) ► A nézeti térfogatot leszűkíthetjük a kurzor kis környezetére is. 3
Selection (kiválasztás) 1. 2. 3. 4. 5. 6. A kép kirajzolása a szokásos módon. Tömb megadása, amely a visszakapott értékeket (neveket) fogja tárolni Belépés a szelekciós módba Névverem inicializálása, nevek eltárolása kirajzolás közben. Nézeti térfogat definiálása Kilépés a szelekciós módból, az eredmények feldolgozása 4
Selection (kiválasztás) ► gl. Select. Buffer(GLsizei size, GLuint *buffer); § A szelekciós buffer megadása, mérete és a rá mutató pointer segítségével. GLuint típusú nevek tárolására alkalmas. ► GLint gl. Render. Mode(GLenum mode); § Kiválsztja, hogy rendering, selection, vagy feedback módban van-e a rendszer. § A GLint visszatérési érték a kiválasztott elemek számát adja vissza. 5
Névverem (name stack) ►A névverem tartalmazza az alapvető kiválasztási információkat. § Példa: ►gl. Init. Names(); // inicializálás gl. Push. Name(-1); gl. Push. Matrix(); gl. Load. Name(1); rajzol. Object 1(); gl. Load. Name(2); rajzol. Object 2(); gl. Load. Name(3); rajzol. Object 3(); rajzol. Object 4(); // itt is 3 a név gl. Pop. Matrix(); 6
Névverem (name stack) ► gl. Init. Names(void) § Törli a névvermet ► gl. Push. Name(GLuint name) § name érték elhelyezése a névveremben. Túlcsordulás esetén GL_STACK_OVERFLOW-t kapunk. Beállított mélysége a gl. Get. Integerv(), GL_NAME_STACK_DEPTH – el kérdezhető le. ► gl. Pop. Name(void); § A verem tetején lévő név törlése a veremből. Üres veremre alkalmazás esetén GL_STACK_UNDERFLOW-t kapunk. ► gl. Load. Name(GLuint name); § A verem felső elemét kicseréli a name értékkel. gl. Init. Names() után közvetlenül nem lehet meghívni, mert a verem ekkor még üres. Ilyenkor gl. Push. Name()-t 7 kell hívni előtte.
Találat rekord (hit record) ► gl. Render. Mode() visszatérési értékeként kapható meg. § Minden rekord 4 elemet tartalmaz: A nevek száma 2. A legkisebb és legnagyobb ablak koordináta z értéke. [0, 1] közé transzformálva. 3. A névverem tartalma 1. 8
Példa selection/select. c 9
// // a szelekciós tömb kiiratása // void process. Hits (GLint hits, GLuint buffer[]) { int i, j, names; GLuint *ptr; printf ("talalatok = %dn", hits); ptr = (GLuint *) buffer; for (i = 0; i < hits; i++) { names = (int) *ptr; printf (" nevek szama a talalaton belul= %dn", names); ptr++; printf(" z 1 = %g; ", (float) *ptr/0 x 7 fffffff); ptr++; printf(" z 2 = %gn", (float) *ptr/0 x 7 fffffff); ptr++; printf (" a nev: "); for (j = 0; j < names; j++) { printf ("%d ", *ptr); ptr++; } printf ("n"); } } 10
Kiválasztás (egér) kurzorral ► speciális picking matrix alkalmazása ► A kurzor egy kis környezetébe állítjuk be a viewportot A egérrel való kiválasztás lépései: ► A kiválasztási hely meghatározása (egérrel vezérelt) ► glu. Pick. Matrix() alkalmazása Megjegyzés: kiválasztást a szín buffer segítségével is lehet implementálni, a kiválasztott helyen tárolt szín segítségével! 11
Kiválasztás kurzorral ► glu. Pick. Matrix(GLdouble x, GLdouble y, GLdouble width, GLdouble height, GLint viewport[4]); § A kiválasztási tartomány közepe: x, y. § A kiválasztás érzékenysége: width, height. § A viewport lekérdezése: GLuint viewport[4]; gl. Get. Integerv(GL_VIEWPORT, GLint *viewport); 12
Példa picksquare. c 13
Példa void pick. Squares(int button, int state, int x, int y) { GLuint select. Buf[BUFSIZE]; GLint hits; GLint viewport[4]; // csak akkor hajtódik végre, ha a bal egérgomb le van nyomva if (button != GLUT_LEFT_BUTTON || state != GLUT_DOWN) return; gl. Get. Integerv (GL_VIEWPORT, viewport); gl. Select. Buffer (BUFSIZE, select. Buf); (void) gl. Render. Mode (GL_SELECT); gl. Init. Names(); gl. Push. Name(0); gl. Matrix. Mode (GL_PROJECTION); gl. Push. Matrix (); glu. Pick. Matrix (x, y, 5. 0, viewport); // 5 x 5 os terület glu. Ortho 2 D (0. 0, 3. 0, 0. 0, 3. 0); draw. Squares (GL_SELECT); gl. Pop. Matrix (); gl. Flush (); hits = gl. Render. Mode (GL_RENDER); process. Hits (hits, select. Buf); glut. Post. Redisplay(); 14
Többszörös nevek kiválasztása (picking with multiple names) ► kirajzol_kerék_küllő() { kirajzol_agy(); for(int i=0; i<5; i++) { gl. Pushmatrix(); gl. Rotatef(); gl. Push. Name(i); kirajzol_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); } } 15
► kirajzol_váz_kerék_küllő() { kirajzol_váz(); gl. Push. Matrix(); gl. Translate(); gl. Push. Name(1); // 1 kirajzol_kerék_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); gl. Push. Matrix(); gl. Translate(); gl. Push. Name(2); // 2 kirajzol_kerék_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); } 16
kirajzol_három_jármű() { gl. Init. Names(); gl. Push. Matrix(); gl. Translate(); gl. Push. Name(1); kirajzol_váz_kerék_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); gl. Push. Matrix(); gl. Translate(); gl. Push. Name(2); kirajzol_váz_kerék_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); gl. Push. Matrix(); gl. Translate(); gl. Push. Name(3); kirajzol_váz_kerék_küllő(); gl. Pop. Name(); gl. Pop. Matrix(); } // 1 17
►A fenti példa a következő eredményeket adhatja vissza a ‘hit’ rekordban: § üres: nem volt kiválasztás § 2 d 1 d 2 2 1 Kocsi 2, kerék 1, § 1 d 2 3 Kocsi 3, § 3 d 1 d 2 1 1 0 Kocsi 1, kerék 1, küllő 1 18
Kiválasztás, mélység értékek pickdepth. c 19
Feedback ► Rajzolás ebben az esetben sem történik ► Azokról a grafikus adatokról kaphatunk vissza információt, amelyeket kirajzolódtak volna a képernyőre. ► A kiválasztás és a feedback közötti különbség a visszakapott értékek között van. ► Bekapcsolás: gl. Render. Mode(GL_FEEDBACK) 20
Feedback mechanizmus 1. gl. Feed. Back. Buffer() segítségével beállítjuk a feedbackbuffer méretét. 2. gl. Render. Mode(GL_FEEDBACK) átkapcsol feedback módba. 3. Grafikus primitívek rajzolása. gl. Pass. Through() segítségével markereket helyezhetünk el. 4. gl. Render. Mode(GL_RENDER) visszavált normál módra. Visszatérési értéke megadja a feedbackbufferben tárolt elemek számát. 5. A visszakapott értékek feldolgozása a markerek alapján. 21
Feedback ► void gl. Feedback. Buffer(GLsizei size, GLenum type, GLfloat *buffer); type koordináták szín textúra értékek száma GL_2 D x, y - - 2 GL_3 D x, y, z - - 3 GL_3 D_COLOR x, y, z 4 - 7 GL_3 D_COLOR_ TEXTURE x, y, z 4 4 11 GL_4 D_COLOR_ TEXTURE x, y, z, w 4 4 12 22
Feedback tömb primitív típusa token adat Pont GL_POINT_TOKEN vertex Vonal GL_LINE_TOKEN vertex, vertex GL_LINE_RESET_TOKEN Poligon GL_POLYGON_TOKEN n vertex. . vertex Bitmap GL_BITMAP_TOKEN vertex Pixel négyzet GL_DRAW_PIXEL_TOKEN vertex GL_COPY_PIXEL_TOKEN Pass-through GL_PASS_THROUGH_TOKEN float érték void gl. Pass. Through(GLfloat token) - GL_PASS_THROUGH_TOKEN-t szúr be, egy float értékkel követve azt. 23
Példa feedback. c 24
Példa Balgomb: kiválaszt Középső gomb: nagyít triselect. c 25
- Slides: 25