OpenGL megjelenítési listák
OpenGL display list Lista: olyan OpenGL parancsok csoportja, amelyet a rendszer lefordított (compiled) formában tárol Nem minden hívás tárolható listákban Nem mindig érhető el jelentős sebességnövekedés
Példa 1. 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 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(); glFlush(); Nem hatékony módszer, mivel minden fázis kirajzolásánál újra kell számolni a vertexeket.
Példa 2. int points = 100; float korkoords[points][2]; 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_LINE_LOOP); … // korkoords feltöltése for (int i = 0; i < points; i++) glVertex2fv(&korkoords[i][0]); // vektoros forma } glEnd(); glFlush(); Hatékonyabb módszer, de a ciklust nem lehet kikerülni ebben az esetben sem.
Megoldás listával int points = 100; void listakeszites(void) { glNewList(1, GL_COMPILE); glBegin(GL_LINE_LOOP); for (int i = 0; i < points; i++) float szog = 2 * PI * i / points; glVertex2f(cos(szog), sin(szog)); } glEnd(); glEndList(); void kirajzol { glCallList(1); // csak 1 függvényhívás!
Listatervezési filozófia A listák specifikálásának fő oka az OpenGL hálózatban történő gyors működtetése volt kliens-szerver modell esetén a kliens nem küldi el a teljes geometriát, csak a megjelenítési lista sorszámát Az OpenGL megjelenítési lista nem dinamikus adatstruktúra Létrehozás után nem módosítható Ha lehetne módosítani, nagymértékű teljesítmény csökkenést tapasztalnánk. Dinamikus allokáció de-allokáció memória „töredezettséghez” vezethet. Legalább olyan gyors, mint a közvetlen mód. (immediate-mode) A sebességnövekedés függ az adott implementációtól
Listatervezési filozófia A legvalószínűbb optimálási lehetőségek: Mátrix operációk szükség van mátrixok inverzének számítására, listás tárolás esetén az előre kiszámított inverz tárolódik, nem kell kiszámítani. Bittérképek ezek megadásakor az eredeti formátum (általában) nem optimális az adott videohardver szempontjából Anyagtulajdonságok, megvilágítási modellek anyagtulajdonságok és komplex megvilágítások definiálásakor jelentős a számítási igény Textúrák hasonló okok miatt érdemes használni, mint a bittérképek esetén számos modern videohardver támogatja a textúra tömörítést
Feladat glRotatef(45, 1.0, 0.0, 0.0); glNewList(1, GL_COMPILE); geometriarajzolas(); glEndList(); glRotatef(45, 1.0, 0.0, 0.0); glCallList(1); glNewList(1, GL_COMPILE); glRotatef(45, 1.0, 0.0, 0.0); geometriarajzolas(); glEndList(); glCallList(1); Mi a különbség a két megoldás között? Melyik megoldás gyorsabb? Mi a hátránya a második megoldásnak?
Megjelenítési listák hátrányai A lista nem módosítható float c[3] = {1.0,1.0,1.0}; glNewList(1,GL_COMPILE); glColor3fv(c); glEndList(); c[0]=0.0; // mi történik ekkor? Léteznek memóriakorlátok A listák számozása okozhat nehézségeket Nagyobb rugalmasságot és egyszerűbb menedzselhetőséget ad a vertex-tömbök alkalmazása. (vertex-arrays)
Egyszerű példa GLuint listName; void display(void) void init (void) { listName = glGenLists (1); glNewList (listName, GL_COMPILE); glColor3f (1.0, 0.0, 0.0); glBegin (GL_TRIANGLES); glVertex2f (0.0, 0.0); glVertex2f (1.0, 0.0); glVertex2f (0.0, 1.0); glEnd (); glTranslatef (1.5, 0.0, 0.0); glEndList (); glShadeModel (GL_FLAT); } void drawLine (void) glBegin (GL_LINES); glVertex2f (0.0, 0.5); glVertex2f (15.0, 0.5); void display(void) { GLuint i; glClear (GL_COLOR_BUFFER_BIT); glColor3f (0.0, 1.0, 0.0); for (i = 0; i < 10; i++) glCallList (listName); drawLine (); glFlush (); } void reshape(int w, int h) glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) gluOrtho2D (0.0, 2.0, -0.5 * (GLfloat) h/(GLfloat) w, 1.5 * (GLfloat) h/(GLfloat) w); else gluOrtho2D (0.0, 2.0 * (GLfloat) w/(GLfloat) h, - 0.5, 1.5); glMatrixMode(GL_MODELVIEW);
Listákkal kapcsolatos függvények GLuint glGenLists(GLsizei n) n darab listát generál a visszatérési értéktől kezdődően. Ha i a visszatérési érték: i … (i+n-1) a listák azonosítói. listindex=glGenLists(1); if(listindex!=0) {glNewList(listindex, GL_COMPILE);…} GLboolean glIsList(GLuint list) GL_TRUE, ha a lista azonosító már foglalt, GL_FALSE ha nem void glNewList(GLuint list, GLenum mode) mode: GL_COMPILE , GL_COMPILE_AND_EXECUTE void glEndList() void glCallList(GLuint list) void glDeleteLists(GLuint list, GLsizei n)
Mi nem tárolható megjelenítési listában? glDeleteLists() glIsEnabled() glFeedbackBuffer() glIsList() glFinish() glPixelStore() glFlush() glReadPixels() glGenLists() glRenderMode() glGet*() glSelectBuffer() Az ok legtöbbször a kliens-szerver architektúrában keresendő. pl. glReadPixels() – mit olvasna?
Állapotváltozások perzisztenciája glNewList(1,GL_COMPILE); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex(); … glEnd(); glTranslatef(10.0,10.0,10.0); glEndList(); A listában letárolásra kerülnek az állapotgép attribútumai, pl. színek, transzformációs mátrixok. A glCallList() alkalmazásakor zavaró lehet a piros színre váltás és az eltolás Már megtanultuk, hogy a transzformációs mátrixok lementhetőek a glPush/PopMatrix()-al.
Állapotváltozások perzisztenciája glNewList(1,GL_COMPILE); glPushMatrix(); glPushAttrib(GL_CURRENT_BIT); glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex(); … glEnd(); glTranslatef(10.0,10.0,10.0); glPopAttrib(); glPopMatrix(); glEndList(); A glPush/PopAttrib() pár lementi az állapotgép attribútumait. GL_CURRENT_BIT paraméter többek között a színinformációkat menti.
Hierarchikus megjelenítési listák Egy megjelenítési listán belül meghívhatunk más listákat is glCallList()-el. glNewList (listindex, GL_COMPILE); // összetett alkatrész glCallList (part1); glCallList (part2); glCallList (part3); glTranslatef(…); glCallList (part3); glEndList(); A listák mélysége minimum 64 és implementáció függő. glGetIntegerv(GL_MAX_LIST_NESTING, GLint *);
Hierarchikus megjelenítési listák A listák hierarchikus rendezésével dinamikus listákat is képezhetünk. glNewList(1, GL_COMPILE); glVertex3fv(v1); glEndList(); glNewList(2, GL_COMPILE); glVertex3fv(v2); glEndList(); glNewList(3, GL_COMPILE); glVertex3fv(v3); glEndList(); glNewList(4, GL_COMPILE); glBegin(GL_POLIGON); glCallList(1); glCallList(2); glCallList(3); glEnd(); glEndList(); Poligon rendereléshez a 4. listát kell meghívni. Vertexek módosításához az 1..3 listákat újra lehet definiálni.
Rugalmasabb vertex tömbök alkalmazása void glVertexPointer( GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid *pointer ); Paraméterek: size Koordináták száma: 2, 3 vagy 4. type Koordináták adatípusa: GL_SHORT, GL_INT, GL_FLOAT vagy GL_DOUBLE. stride Byte offset. 0 estén a vertexek sorban vannak a tömbben count vertexek száma pointer pointer az első elemre
Rugalmasabb vertex tömbök alkalmazása void glDrawArrays( GLenum mode, GLint first, GLsizei count ); mode Geometriai primitív fajtája: GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON. first kezdő index count a kirajzolandó elemszám
Rugalmasabb vertex tömbök alkalmazása float *kor; int points = 100; void init() { kor = new float [points * 2]; // memória foglalás for (int i = 0, j = 0; i < points; i++) // tömb feltöltése float szog = 2 * PI * i / points; kor[j] = cos(szog); kor[j+1] = sin(szog); j+=2; } void kirajzol(void) glClearColor (0.5f, 0.5f, 0.5f, 0.0f); // a szokásos glClear (GL_COLOR_BUFFER_BIT); glVertexPointer(2, GL_FLOAT, 0, kor); // tömb struktúra megadása glEnableClientState(GL_VERTEX_ARRAY); // a vertex array használható glDrawArrays(GL_LINE_LOOP, 0, points); // kirajzolás glFlush();
Rugalmasabb vertex tömbök alkalmazása Összetettebb példa: glColorPointer(), glNormalPointer() használatára: glNormalPointer(GL_SHORT, 0, normals); // normálvektorok tömbje glVertexPointer(3,GL_FLOAT,0, vertices); // vertexek tömbje glEnableClientState(GL_NORMAL_ARRAY); // bekapcsolás glEnableClientState(GL_VERTEX_ARRAY); glDrawArrays(GL_TRIANGLES, 0, db); // kirajzolás
Listakezelő osztály C++ nyelven Példa osztályok: CTriangleObject SObjectIndex Funkciók: Slp fájl betöltése: LoadObject() Listakészítés és megjelenítés egy függvénnyel Show()
Listakezelő osztály C++ nyelven SLP formátum: (Pro/Engineer) példa: solid PRT0004 # partfájl név color 1.000 1.000 1.000 # szín facet # háromszög jön normal 0.000000e+000 -1.000000e+000 0.000000e+000 outer loop # kifelé mutató normálvektor vertex -4.822880e+001 0.000000e+000 1.136822e+002 vertex -1.562823e+002 0.000000e+000 1.086453e+002 vertex -1.500000e+002 0.000000e+000 1.000000e+002 endloop endfacet
Standard Template Library (STL) alkalmazása Az STL segít a dinamikus memória objektumok (tömbök, listák, sztringek, stb.) létrehozásában: vector<short int> normal; normal.push_back(1); //feltöltés normal.push_back(2); for(int i=0; i < normal.size(); i++) { do_something(normal[i]); // kiolvasás } normal.clear(); // törlés #include <vector>
Színek A látható fény 390-720 nm hullámhossz tartományban helyezkedik el A fehér fény egyenlő mértékben tartalmaz minden frekvenciát A lézer fény azonos frekvenciájú fényt tartalmaz A számítógépek monitorai a színeket a piros, zöld és kék kombinációjaként emulálják
Színek RGBA – általában 4 bájt tartozik minden egyes pixelhez Az ‘A’ (alpha) értéke az átlátszóságnál jut szerephez. A ‘color-index’ módban minden pixelhez egy számérték tartozik. Az értékhez tartozó szín ‘color-map’-ból jön. A color-map vezérlését az ablakozó rendszer végzi, nem az OpenGL. A color-index mód mára már kihalt.
RGBA és color-index módok Mindkét esetben a megjeleníthető színek számát a ‘bitplane’-k száma határozza meg. A 24-bites képernyő 3x8 bitet enged meg színenként: egyenlően elosztva a három komponens között. A bitek száma lekérdezhető: glGetIntegerv() - GL_RED_BITS, GL_GREEN_BITS, GL_BLUE_BITS, GL_ALPHA_BITS A 255 a teljes intenzitás 0 a zéro intenzitás
Példa smooth.c
Dithering A színbitek korlátozott kapacitás miatt kvantálást kell alkalmazni. 0/255 … 255/255 A rendszer a színek számításait lebegőpontos alakban végzi, majd az eredményt 0-255 tartományba kvantálja Ha a szín lassan változó akkor ugrásszerű változásokat tapasztalhatunk. A dithering a végső kvantálás előtt egy 0 várható értékű nagyfrekvenciás zajt kever a megjelenítendő színekhez, majd a zajos jelet kvantálja.
Dithering A végeredményként számolt színt, a zavarás és a kvantálás lefelé vagy felfelé kerekíti azzal a valószínűséggel, amennyire közel vagyunk a kvantálási szintekhez. A szem átlagolja a nagyfrekvenciás zajt és az átlagértéket, vagyis a tényleges színt érzékeli. glEnable vagy glDisable GL_DITHER; Néhány hardver dupla buffereléskor a bitplane-okat felezi - 12-12 bit.
Megvilágítás (lighting)
Lokális illuminációs algoritmusok Adott pixelben látható felületi pont színe függ az adott pontból látható többi felülettől és azok fényerősségéből (radianciájából) számítható a pixel fényerőssége. A lokális illuminációs algoritmusok az árnyalási egyenlet drasztikus leegyszerűsítésén alapulnak. Nem veszik figyelembe a többi felület fényességét Megvilágítás csak a képen közvetlenül nem látható absztrakt fényforrásokból érkezhet Az absztrakt fényforrást minden pontból láthatóként kezelik
Lokális illuminációs algoritmusok Illuminációs (megvilágítás) képlet: ahol: Az l. absztrakt fényforrásból az pontba az irányból érkező fényerősség. ambiens tag feladata, hogy az elhanyagolásokat kompenzálja. A felület által kibocsátott fény
Árnyalási modellek (shading modells) Saját színnel történő árnyalás (nem árnyékolás!) 2D képszintézis árnyalási módszerének direkt alkalmazása. Nem igényel számítást, nem térhatású a keletkezett kép. Konstans árnyalás: glEnable(GL_FLAT) A poligonokra csak egyszer számítja ki a fényforrások hatását. Minden poligon egy színnel lesz árnyalva. Gourand-árnyalás: glEnable(GL_SMOOTH) Phong-árnyalás
Gourand-árnyalás A háromszögek csúcspontjában értékeli ki a fényforrásokból odajutó fény visszaverődését. Az eredeti felület normálvektoraival dolgozik. A háromszög belső pontjainak színét a csúcspontok színéből lineárisan interpolálja. Akkor ad helyes eredményt, ha a háromszögön belüli szín valóban közelítően lineárisan változik.
Phong árnyalás Az illuminációs képletben felhasznált normálvektort interpolálja a háromszög csúcspontjában érvényes normálvektorokból. Az illuminációs képletet pedig minden pixelre külön határozza meg. Ez nemlineáris árnyalásnak felel meg. A Phong árnyalás a Gourand árnyalás olyan határesete, amikor a poligonok vetített területe 1 pixel méretű.
Fénytípusok Emmited light: kibocsátott fény, objektumok által kibocsátott fény. Ambient light: környezeti fény, nem lehet az irányát meghatározni, pl: borús, felhős időben is van fény, de az iránya nem meghatározott. Diffuse light: fényforrásból jön. Specular light: visszavert fény
RGB értékek fény és anyagok esetén Anyagok esetén R=1, G=0.5, B=0 azt jelenti, hogy a tárgy visszaveri a piros színt a zöldet félig, a kéket pedig teljesen elnyeli. Ha megvilágítjuk a tárgyat LR, LG, LB színű fénnyel: az eredő fény (LR*R, LG*G, LB*B) színű lesz. (pl. LR=0,LG=0,B=1 esetén nem látunk semmit!) Több fényforrás esetén: (R1, G1, B1) és (R2, G2, B2) = (R1+R2, G1+G2, B1+B2). Ha az érték nagyobb mint 1, akkor a rendszer 1-re kerekít.
Fényforrások létrehozása Alapvető tulajdonságok: szín, helyzet, irány. glLight*() segítségével minden tulajdonság állítható: void glLight{if}[v](GLenum light, GLenum pname, TYPE param); light: GL_LIGHT0, GL_LIGHT1, … GL_LIGHT7 pname: tulajdonság kiválasztása param: az adott tulajdonságtól függő paraméter
Alapértelmezett érték Paraméter neve Alapértelmezett érték Jelentés GL_AMBIENT (0.0,0.0,0.0,1.0) Ambiens (környezeti) RGB intenzitás GL_DIFFUSE (1.0,1.0,1.0,1.0) Diffuse (szórt) RGB intenzitás GL_SPECULAR Specular (visszavert) RGB intenzitás GL_POSITION (0.0,0.0,1.0,0.0) fényforrás (x,y,z,w) helyzet GL_SPOT_DIRECTION (0.0,0.0,-1.0) (x,y,z) irány GL_SPOT_EXPONENT 0.0 exponent GL_SPOT_CUTOFF 180.0 szög GL_CONSTANT_ATTENUATION 1.0 elhalványodási faktor GL_LINEAR_ATTENUATION GL_QUADRATIC_ATTENUATION
Példa fényforrás float light_ambient[] = {0.0,0.0,0.0,1.0}; float light_diffuse[] = {1.0,1.0,1.0,1.0}; float light_specular[] = {1.0,1.0,1.0,1.0}; float light_postion[] = {1.0,1.0,1.0,0.0}; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightfv(GL_LIGHT0, GL_POSITION, light_position);
Fényforrás pozíciója két alapvető típus: directional light – positional light GL_POSITION paraméter (x, y, z, w) negyedik értéke határozza meg a típust. w=0 – directional light w=1 – position light alapértelmezett értéke: (0,0,1,0), amely negatív z irányú fényt jelent. megadható (0,0,0) irányú (directional) fényforrás is. (de értelmetlen)
Fényforrás gyengülése (attenuation) ahol: d - távolság a fényforrás és a vertex között kc - GL_CONSTANT_ATTENUATION kl – GL_LINEAR_ATTENUATION kq – GL_QUADRIC_ATTENUATION Csak ‘positional’ fényforrásokra van hatással! A kibocsátott és a globális ambiens fényre nincs hatással.
Fényszórók (spotlights) Tulajdonságok: félkúpszög, intenzitás eloszlás. GL_SPOT_CUTOFF: 0..90, 180 az alapértelmezett értéke, ami a kikapcsolást jelenti. GL_SPOT_DIRECTION: a fénysugár irányát adja meg GL_SPOT_EXPONENT: intenzitás eloszlás érték
Paraméterek gyakorlati beállításai Figyeljük meg: Light_pos negyedik paraméterállításának hatása jobb egérgomb, majd spotlight attenuation CUTOFF szög, EXPONENT a három ATTENUATION faktor hatása
Fényforrások helyzete A fényforrásokon ugyanolyan mátrix transzformációk mennek végbe, mint a geometriai primitíveken. A projekciós mátrix nem befolyásolja a fényforrás irányát vagy a helyét. Háromféle hatás érhető el: A fényforrás pozíciója fix marad A fényforrás egy objektum körül mozog A fényforrás a nézőponttal együtt mozog
Fényforrások helyzete A fényforrás pozíciója fix marad: glViewport (0, 0, (GLsizei) w, (GLsizei) h); glMatrixMode (GL_PROJECTION); glLoadIdentity(); gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode(GL_MODELVIEW); … … később a init függvényben glLightfv (GL_LIGHT0, GL_POSITION, position); A fényforrás helyzete nem változik, mivel a pozíció az init() függvényben csak egyszer hívódik meg.
Fényforrások helyzete A fényforrás egy objektum körül mozog void display(void) { GLfloat position[] = { 0.0, 0.0, 1.5, 1.0 }; glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); glPushMatrix (); glTranslatef(0.0,0.0,-5.0); glRotatef (spin, 1.0, 0.0, 0.0); glLightfv(GL_LIGHT0, GL_POSITION, position); glPopMatrix(); glutSolidSphere(1.0,16,16); glPopMatrix (); … …
Fényforrások helyzete A fényforrás a nézőponttal együtt mozog void display(void) { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPushMatrix (); glTranslatef(0.0,0.0,-5.0); glRotatef (spin, 1.0, 0.0, 0.0); glLightfv(GL_LIGHT0, GL_POSITION, position); glutSolidSphere(1.0,16,16); glPopMatrix(); glFlush(); } CAD és egyéb mérnöki rendszerek ezt a modellt alkalmazzák
Mozgó fényforrás (példa) movelight.c
Megvilágítási modell OpenGL megvilágítási modellnek három komponense van: globális ambiens (szórt) fény lokális vagy végtelen nézőpont ‘kétoldalas’ megvilágítás (two-sided lighting)
Globális szórt fény 8 fényforrás adható meg, de ezen kívül egy globális szórt fényt is definiálhatunk, amely egyik fényforráshoz sem köthető: float lma [] = {0.2, 0.2, 0.2, 1.0}; glLightModelfv (GL_LIGHT_MODEL_AMBIENT, lma); Ha más fényforrás nincs megadva akkor globális szórt szürke lesz minden objektum a képernyőn! Próbáljuk ki az arnyalas.cpp mintafájlban!
Lokális vagy végtelen nézőpont A visszaverődő fény számítása szempontjából a nézőpont helyzete meghatározó. A nézőpont, a fényforrás helyzete a vertex normálisa meghatározza a poligonok fényességét. (highlight) Végtelen távoli nézőpontot feltételezve vertexekkel bezárt szög konstans. Így gyorsabban számolhat a rendszer. De a képminőség gyengébb. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); alapértelmezetten a rendszer végtelen távoli nézőpontot feltételez
Kétoldalas megvilágítás Lehetőséget ad a poligonok mindkét oldalának (front and back face) megvilágítási tulajdonságainak megadására glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE); alapértelmezés szerint: GL_FALSE Az arnyalas.cpp display() függvényében próbáljuk ki a következőt: GLdouble egy1[4] = {1.0, 0.0, 0.0, 0.0}; glClipPlane(GL_CLIP_PLANE0, egy1); glEnable(GL_CLIP_PLANE0); majd a kétoldalas megvilágítással is próbáljuk ki!
Anyagtulajdonságok megadása Anyagtulajdonságok a következő függvényhívás segítségével adhatjuk meg: glMaterial{if}[v](GLenum face, GLenum pname, GLenum param); face: GL_FRONT, GL_BACK, GL_FRONT_AND_BACK pname: a tulajdonság neve param: a tulajdonsághoz tartozó paraméter
Alapértelmezett érték Paraméter neve Alapértelmezett érték Jelentés GL_AMBIENT (0.2,0.2,0.2,1.0) ambiens (környezeti) szín GL_DIFFUSE (0.8,0.8,0.8,1.0) diffuse (szórt) szín GL_AMBIENT_AND_DIFFUSE ambiens és diffuse szín együtt GL_SPECULAR (0.0,0.0,0.0,1.0) visszavert fény GL_SHININESS 0.0 fényesség (visszavert fény exponens) GL_EMISSION Kibocsátott szín GL_COLOR_INDEXES (0, 1, 0) Ambiens, diffuse, specular szín index
Diffuse és ambiens tulajdonságok Egyik sem függ a nézőpont helyzetétől Gyakran egyforma értékűre állítják mindkét tulajdonságot A diffuse (szórt) tulajdonság határozza meg legjobban a színt float mat_amb_diff[]={0.1,0.5,0.8,1.0}; glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_amb_diff);
Visszatükröződés és kibocsátott fény Visszatükröződés: float mat_specular[] = {1.0, 1.0, 1.0, 1.0}; float low_shininess[] = {5.0}; glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, low_shininess); a shininess 0..128 között változhat Kibocsátott fény: float mat_emission[] = {0.3,0.2,0.2,0.0}; glMatrialfv(GL_FRONT, GL_EMISSION, mat_emission); mat_emission a kibocsátott fény színe
‘Tutorial’ alapján az anyagtulajdonságok gyakorlása Feladatok önálló gyakorláshoz: 1. A fényforrás globális ambiens összetevőjét állítsuk (0.0,0.0,0.0,0.0)–ra. És a light_ka[]-t is állítsuk (0.0,0.0,0.0,0.0)-ra. 2. Figyeljük meg, hogy a material_ka[] változtatásának most nincs hatása. Miért? 3. Állítsuk be a light_Ka[] = {1.0,0.0,0.0,0.0}-t és így a material_Ka[] piros (red) összetevője megváltozásának hatását megfigyelhetjük. 4. Nullázzuk le a light_Ka és material_Ka vektorokat. 5. Állítsuk be a material_Ks[]={1.0,0.0,0.0,1.0} – ra. És állítsuk be a material_Se értékét 100-tól nagyobbra. 6. Változtassuk meg a material_Ke első paraméterét, vörösen ízzó tóruszt kapunk. Ha az attenuation értéket növeljük, akkor a kibocsátott szín jobban érvényesül. 7. szabadon próbáljunk beállítani tetszőleges tulajdonságokat.