Mer OpenGL OpenGL-översikt Geometri Operationer på hörn Projective shadows Advanced Rendering Techniques Using OpenGL, SIGGRAPH Courses 997. Gustav Taxén CID gustavt@nada.kth.se Bilddata Operationer på bildelement Rastrering Texturminne Operationer på fragment Framebuffert (bildbuffert + hjälpbuffertar) Hierarkiska modeller Består-av-hierarki pivotpunkt Skelett Arm Överarm Underarm Lokala koordinatsystem Från hierarki till kod, steg Subnodens origo positioneras m.a.p. förälderns koordinatsystem. Skelett Arm void drawskeleton(void) { drawarm(); void drawarm(void) { drawupperarm(); drawlowerarm(); Överarm Underarm void drawupperarm(void) { void drawlowerarm(void) {
Från hierarki till kod, steg 2 void drawskeleton(void) { glpushmatrix(); positionera armens origo; drawarm(); glpopmatrix(); void drawarm(void) { glpushmatrix(); positionera överarmens origo; drawupperarm(); glpopmatrix(); glpushmatrix(); positionera underarmens origo; drawlowerarm(); glpopmatrix(); Transformation av delträd Ändra rotation här! void drawskeleton(void) { glpushmatrix (); positionera armens origo; drawarm (); glpopmatrix (); DEMO Ljussättning: Phongs reflektionsmodell Phongmodellen i OpenGL Ambient Matt C RGB = Ambient RGB + + [ Diffuse RGB LDiffuse RGB cos(θ NL ) + L + Specular RGB LSpecular RGB cos Shininess (θ EL )] Speglande E N L Phongmodellen i OpenGL Ljussättning av hörn Ljuskälla Ambient RGBA Diffuse RGBA Ambient RGBA Hörnets material Diffuse RGBA Specular RGBA, shininess + Hörn RGBA Specular RGBA Hörnets normal Ögats position (= världsorigo) Färg beräknas i varje hörn och interpoleras sedan över polygonen. 2
Exempel: Ljussättning void display(void) { glclearcolor(0., 0.2, 0.3,.0); glclear(gl_color_buffer_bit); glmatrixmode(gl_modelview); glloadidentity(); setlightandmaterial(); gltranslatef(0.0, 0.0, -3.0); glcolor3f(.0,.0,.0); glbegin(gl_triangles); glnormal3f(.0,.0,.0); glvertex3f(.0, 0.0, 0.0); glvertex3f(0.0,.0, 0.0); glvertex3f(0.0, 0.0,.0); glend(); glutswapbuffers(); Exempel: Ljussättning void setmaterialandlight (void) { GLfloat matambient[4] = { 0.33, 0.22, 0.03,.0 ; GLfloat matdiffuse[4] = { 0.78, 0.57, 0.,.0 ; GLfloat matspecular[4] = { 0.99, 0.9, 0.8,.0 ; GLfloat matshininess = 27.8; GLfloat lgtambient[4] = { 0.33, 0.22, 0.03,.0 ; GLfloat lgtdiffuse[4] = { 0.78, 0.57, 0.,.0 ; GLfloat lgtspecular[4] = { 0.99, 0.9, 0.8,.0 ; GLfloat lgtposition[4] = {.0, 3.0, -3.0,.0 ; glenable(gl_lighting); glenable(gl_light0); glenable(gl_normalize); gllightfv(gl_light0, GL_AMBIENT, lgtambient); gllightfv(gl_light0, GL_DIFFUSE, lgtdiffuse); gllightfv(gl_light0, GL_SPECULAR, lgtspecular); gllightfv(gl_light0, GL_POSITION, lgtposition); glmaterialfv(gl_front_and_back, GL_AMBIENT, matambient); glmaterialfv(gl_front_and_back, GL_DIFFUSE, matdiffuse); glmaterialfv(gl_front_and_back, GL_SPECULAR, matspecular); glmaterialf(gl_front_and_back, GL_SHININESS, matshininess); Resultat Bra att komma ihåg om ljussättning Då ljussättning är aktivt har aktuell färg ingen effekt. OpenGL stöder minst 8 aktiva ljuskällor. En ljuskälla avger en viss mängd av varje ljustyp. Då ljuskällans position specificras multipliceras den med aktuell modelviewmatris. Dubbelsidiga polygoner glmaterialf(gl_front, ); glmaterialf(gl_back, ); glmaterialf(gl_front_and_back, ); Fram/baksida beräknas genom tecknet i a = 0.5 x wi y i w - x i w y wi, 0 i (n - ), i (i + ) mod n, (x wi, y wi ) fönsterkoordinater för hörn nr i, n = antal hörn i polygonen Rastrering Operationer på hörn: RGBA, z w, texturkoord. Operationer på bildelement Fragment Texturminne 3
Bilddataspecifikation Operationer på bildelement Två typer av bilddata: Bitmap - bit per pixel. (Se studiehäftet!) Bild - max 32 bitar per pixel. Finns ingen filformatstolk, data hämtas från C-array. Bitmaps går direkt till rastreringen. Bilder går direkt till rastreringen eller lagras som texturdata (internt eller på grafikkortet). Byt plats på bytes i bilddata, delbilder Skalning & offset av bilddata, m.m. Processorminne Pixellagringslägen Pixeltransferoperationer Texturminne Rastrering (inkl. zoomning) Pixellagringslägen Byt plats på bytes i bilddata (endianness). Placera minst signifikanta biten först eller sist (ska 0x3 tolkas som 00000 eller 00000?). Använda delmängd (rektangel) av bilddata. Alignment (ny rad varje, 2, eller 4 bytes?) OBS! Lagringsläget är ett tillstånd! Pixeltransferoperationer Tillverka uppslagstabeller för färger (mappa från en färgmängd till en annan). Skalning av färgvärden. Offset av färgvärden. Förstora eller förminska bilden (en bildpixel behöver då inte svara inte mot en pixel på skärmen). OBS! Funktionerna är aktuella tillstånd! Var ritas bilddata? Rita bild Aktuell rasterposition: glrasterpos2f(x, y); glrasterpos3f(x, y, z); glrasterpos4f(x, y, z, w); Då rasterpositionen anges transformeras den på samma sätt som övriga hörn. Jfr. position för ljuskällor! height gldrawpixels (width, height, format, type, const void *pixels); format R G B R G B R G B A R G B A R R R R (x w, y w, y w ) för aktuell rasterposition utgör origo för bilden/bitmapen. origo width GL_UNSIGNED_BYTE GL_FLOAT type 4
Texturer Texturobjekt Texturkoordinat t Filtreringsalternativ. Clamp/wrap-around för texturkoord. Texturobjekt s Texturappliceringsparametrar Texturkoordinater Rastrering Texturobjekt Innehåller: Texturdata (texels). Information filtrer och texturkoordinatapplicering. Information om huruvida kopia av texturdata har laddats ned till grafikhårdvaran. Endast ett texturobjekt är aktivt! Texturobjekt glgentextures - tillverka texturobjektnamn. glbindtexture - tillverka/aktivera texturobjekt. gltexparameter - sätt filterparametrar, sätt clamp/wrap-around för texturkoordinater. glteximage2d - specificera texturdata. Förstoring och förminskning Textur FÖRSTORING Pixelpunkter på skärmen FÖRMINSKNING Pixelpunkter Textur på skärmen Clamp/wrap around (s, t) = (.25, -2.75) t GL_REPEAT GL_CLAMP Alternativ: GL_NEAREST, GL_LINEAR, m.m. s 5
Texturdataspecifikation origo m n ram (width, height) = (2 n + 2b, 2 m + 2b) där m, n är heltal 0, b = om texturen har ram, 0 annars. Texturdataspecifikation glteximage2d(gl_texture_2d, level, internalformat, width, height, border, format, type, const GLvoid *texels); level = MIP-mapnivå (= 0 på DGI-kursen) internalformat = internt lagringsformat (normalt = type) format, type som i gldrawpixels Observera att lagringslägen och transferoperationer även gäller texturer! Texturapplicering gltexenvi(gl_texture_env, GL_TEXTURE_ENV_MODE, mode); Texturkoordinater gltexcoord2f(s, t); gltexcoord3f(s, t, r); gltexcoord4f(s, t, r, q); Anges före glvertex (precis som för normaler). där mode är GL_DECAL = Ersätt RGB med texturdata, spara A. GL_REPLACE = Ersätt RGBA med texturdata. GL_MODULATE = Kombinera texturdata med ljussättning/färg. t OBS! LAGRAS INTE I TEXTUROBJEKT! s Texturkoordinater Exempel: Texturer s' t' r' q' = T s t r q glmatrixmode(gl_texture); Texturkartan indexeras sedan med (s'/q', t'/q'). r'/q' ignoreras normalt, men används vid 3D-texturering. GLfloat *texels; GLuint texnames[2]; texels = malloc(sizeof (GLfloat) * 256 * 256 * 4); /* RGBA */ /* Read data into texels array here */ glgentextures(2, texnames); glbindtexture(gl_texture_2d, texnames[0]); gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_S, GL_REPEAT); gltexparameteri(gl_texture_2d, GL_TEXTURE_WRAP_T, GL_CLAMP); gltexparameteri(gl_texture_2d, GL_TEXTURE_MAG_FILTER, GL_NEAREST); gltexparameteri(gl_texture_2d, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glteximage2d(gl_texture_2d, 0, GL_RGBA, 256, 256, 0, GL_RGBA, GL_FLOAT, texels); 6
Exempel: Texturer Resultat void display(void) { glenable(gl_texture_2d); gltexenvi(gl_texture_env, GL_TEXTURE_ENV_MODE, GL_REPLACE); glbindtexture(gl_texture_2d, texnames[0]); glbegin(gl_triangles); gltexcoord2f(0.0, 0.0); glvertex3f(.0, 0.0, 0.0); gltexcoord2f(0.5,.0); glvertex3f(0.0,.0, 0.0); gltexcoord2f(.0, 0.0); glvertex3f(0.0, 0.0,.0); glend(); PPM-biblioteket Billboards #include <GL/glut.h> #include <ppm.h> GLuint texwin0, texwin; int main(int argc, char *argv) { float *texels; int w, h; w = ppmwidth( img.ppm ); h = ppmheight( img.ppm ); texels = ppmread( img.ppm, NULL); glutcreatewindow( win ); glgentextures(&texwin0, ); glteximage2d(, texels); glutcreatewindow( win ); glgentextures(&texwin, ); glteximage2d(, texels); Bufferttester Djupbuffert och djuptest Djuptest Färgbuffert Fragment = (R, G, B, A, djup, texturkoordinat) Färgbuffert Djupbuffert Fönster Fragment 7
Exempel: Djupbuffert int main(int argc, char *argv[]) { glutinit(&argc, argv); glutinitdisplaymode(glut_rgb GLUT_DOUBLE GLUT_DEPTH); glutcreatewindow("exempel 6"); glutdisplayfunc(display); glutreshapefunc(reshape); glutmainloop(); return 0; Exempel: Djupbuffert void display(void) { glclearcolor(0., 0.2, 0.3,.0); glclear(gl_color_buffer_bit DEPTH_BUFFER_BIT); glmatrixmode(gl_modelview); glloadidentity(); /* setlightandmaterial (); */ gltranslatef(0.0, 0.0, -3.0); glenable(gl_depth_test); glcolor3f(.0,.0,.0); glbegin(gl_triangles); /* glnormal3f(.0,.0,.0); */ glvertex3f(.0, 0.0, 0.0); glvertex3f(0.0,.0, 0.0); glvertex3f(0.0, 0.0,.0); glcolor3f(0.5, 0.5, 0.5); glvertex3f(0.0, 0.0, 0.0); glvertex3f(.0, 0.0, 0.0); glvertex3f(.0,.0,.0); glend(); glutswapbuffers(); Resultat OpenGL i nätverk OpenGL-klient OpenGLkommandon Grafikhårdvara OpenGL-server Display lists OpenGL i nätverk tung trafik från klient till server. Lösning: lagra kommandosekvenser hos servern som display lists. Upprepa sekvensen genom att hänvisa till display list-id. Inte relevant då klient och server finns på samma maskin. Back-face culling Klipp polygoner som är vända från kameran. Polygonframsida: hörnen ligger i motsols ordning sett från kameran. Kan konfigureras om. Jfr. material i ljussättningssteget. Ger kraftigt ökad prestanda i scener med många polygoner. Aktiveras med glenable(gl_cull_face); 8
Mer information om OpenGL Woo, Neider, Davis: The OpenGL Programming Guide, Addison Wesley Developer Press. Segal, Akeley: The OpenGL Graphics System: A Specification. Version.3. X-Windows och Win32 Kilgard, OpenGL Programming for the X Window System, Addison Wesley Developer Press. Fosner, OpenGL Programming for Windows 95 and Windows NT, Addison Wesley Developer Press. Problem? Gå till http://www.opengl.org/ 9