Introduktion till OpenGL Battlezone Atari corp., 1980. Gustav Taxén CID gustavt@nada.kth.se Varför behövs grafikbibliotek? Grafikhårdvara Skillnader i funktionalitet och möjligheter. Skillnader i styrning. Plattformar Skillnader i operativsystem. Applikationer Målet är att koden skall vara densamma oberoende av hårdvara och plattform. OpenGL är ett grafikbibliotek Specifikationen är oberoende av plattform och operativsystem. Alla implementationer måste tillhandahålla all funktionalitet. Systemberoende del sköter datautbyte mellan OpenGL och operativsystem. Enbart rendering: inget stöd för inenheter, fönsterhantering, etc. Fördelar med OpenGL Portabelt. Kraftfullt. Enkelt att använda. Anpassat för 3D-grafikhårdvara men kan även användas för att rita 2D. Effektivt för 3D-grafikhårdvara. Används i industrin. Nackdelar med OpenGL Kan vara ineffektivt på 2Dgrafikhårdvara. OpenGL-kod kan ge många funktionsanrop. Bristfälligt stöd från Microsoft på Windows-plattformar (mjukvara). Oviss framtid? Allmänt om OpenGL Utvecklat av Silicon Graphics (SGI). Kontrolleras av ett Architectural Review Board: 3Dfx, 3DLabs, ATI, Compaq, Evans & Sutherland, HP, IBM, Intel, Microsoft, nvidia, SGI, Sun. Licens måste köpas för utveckling av implementation. Gratis att använda. Mesa: GNU-implementation som har SGIs godkännande. 1
Delbibliotek Pipeline-modell OpenGL Renderingsfunktionalitet. GLU (OpenGL Utility Library) Hjälpfunktioner för bl.a. transformationer. GLX Sköter datautbyte mellan X Window System och OpenGL (GLW på Windows). GLUT Ljussättning Geometribeskrivning Ljussättningsmodell Avbildningsmetod Avbildning Rendering Bildelement Översikt över OpenGL Datapipeline Geometri Operationer på hörn Hörn Op. på hörn Transformerade och ljussatta hörn Rastrering Operationer på fragment Bilddata Op. på bildelement Rastrering Bilddata Operationer på bildelement Texturminne Framebuffert (bildbuffert + hjälpbuffertar) Op. på fragment Fragment (färg + djup + texturkoordinater) Buffertvärden Framebuffert (bildbuffert + hjälpbuffertar) Exempel 1: bildbuffert #include <GL/glut.h> void display(void) { int main(int argc, char *argv[]) { glutinit(&argc, argv); glutinitdisplaymode(glut_rgb GLUT_DOUBLE); glutcreatewindow("exempel 1"); glutdisplayfunc(display); glutmainloop(); return 0; Exempel 1, forts. Välj dubbel RGB-färgbuffert glutinitdisplaymode(glut_rgb GLUT_DOUBLE); R, G, B Synlig Gömd 2
Exempel 1, forts. Vilken färg (RGB) skall färbufferten få när den rensas? Vilket alpha (A) skall alphabufferten få när den rensas? R G B A RGB-färgbuffert och alphabuffert R, G, B A Exempel 1, forts. Rensa färg- och alphabuffert R = 0.1 G = 0.2 B = 0.3 (A = 1.0) Synlig Gömd Exempel 1, forts. Resultat, exempel 1 Byt plats på synlig och gömd buffert Synlig Gömd Exempel 2: geometrispecifikation void display(void) { glcolor3f(1.0, 1.0, 1.0); glvertex3f(1.0, 0.0, 0.0); glvertex3f(0.0, 1.0, 0.0); glvertex3f(0.0, 0.0, 1.0); Exempel 2, forts. b s i f d ub us ui Ändra aktuell färg glcolor3f(1.0, 1.0, 1.0); Antal argument R G B Argumentens datatyp byte short int Alla kombinationer är inte float double relevanta för alla kommandon! unsigned byte unsigned short unsigned int 3
Exempel 2, forts. Resultat, exempel 2 Geometrispecifikation glvertex3f(1.0, 0.0, 0.0); glvertex3f(0.0, 1.0, 0.0); glvertex3f(0.0, 0.0, 1.0); Alla hörn anges i homogena koordinater. Om w saknas sätts den till 1.0. Om z saknas sätts den till 0.0. Mer om detta i transformationsföreläsningen! Det är tillåtet (och önskvärt) att ange fler primitiver i rad. Viktigt att komma ihåg: Transformationer Transformation OpenGL är en tillståndsmaskin. Projektion Transformation Viewporttransformation Transformationer i OpenGL Modelview-matrisen Objektkoord. x o y o z o w o Matrisstack x w y w z w Ögonkoord. x e y e z e w e Perspektivdivision Viewporttransformation Matrisstack x n y n z n Klippkoord. x c y c z c w c Modelviewmatris Projektionsmatris Objektkoordinater anges med glvertex. Modelview-matrisen M omvandlar till ögonkoordinater: v e = M v o. M positionerar modeller (objekt) i världen. Normaler transformeras också. Ljussättning görs i ögonkoordinater. Fönsterkoord. Normerade enhetskoord. 4
Projektionsmatrisen Projektionsmatrisen P omvandlar ögonkoordinater till klippkoordinater: v c = P v e. P projicerar hörnen på ett bildplan och definierar samtidigt en vy-volym. Alla primitiver klipps mot denna volym. Kameran sitter i (0, 0, 0) och ser i riktningen (0, 0, -1). Perspektivdivision och viewport-transformation Perspektivdivision: (x n, y n, z n ) = (x c / w c, y c / w c, z c / w c ). Perspektivdivisionen ger normerade enhetskoordinater i intervallet [-1, 1]. Viewport-transformation: skalning och offset i bildbufferten. Skalning och offset anges i fönsterkoordinater. Exempel 3: transformation void display(void) { glmatrixmode(gl_modelview); gltranslatef(0.0, 0.0, -3.0); glcolor3f(1.0, 1.0, 1.0); glvertex3f(1.0, 0.0, 0.0); glvertex3f(0.0, 1.0, 0.0); glvertex3f(0.0, 0.0, 1.0); Exempel 3, forts. (0,0,1) z glmatrixmode(gl_modelview); gltranslatef(0.0, 0.0, -3.0); y (0,1,0) (0,0,-2) (1,0,0) x (0,1,-3) (1,0,-3) Exempel 3, forts. Matriskommandon glmatrixmode Sätt aktuell matristyp. glloadidentity Ersätt med identitetsmatrisen. gltranslate Multiplicera med translationsmatris. glrotate Multiplicera med rotationsmatris. glscale Multiplicera med skalningsmatris. glmultmatrix Multiplicera med specificerad matris. glloadmatrix Ersätt med specificerad matris. glpushmatrix Pusha aktuell matris på stacken. glpopmatrix Ersätt med matris som ligger överst på stacken. Exempel 3, forts. Transformation Byte av koordinatsystem gltranslatef(0,0,-3); glrotatef(50,0,1,0); gltranslatef(0,0,3); glvertex3f(1,0,0); glvertex3f(0,1,0); glvertex3f(0,0,1); 5
Viktigt att komma ihåg: glpushmatrix pushar aktuellt koordinatsystem på stacken. glpopmatrix ersätter aktuellt koordinatsystem med det som finns överst på stacken. Exempel 4: projektionsspecifikation void reshape(int width, int height) { glmatrixmode(gl_projection); gluperspective(45, (GLfloat) width / (GLfloat) height, 0.5, 10.0); glviewport(0, 0, width, height); int main(int argc, char *argv[]) {... glutcreatewindow("exempel 4"); glutdisplayfunc(display); glutreshapefunc(reshape);... Viktigt att komma ihåg: OpenGLs kamera sitter alltid i origo och ser i riktningen (0,0,-1). Kameran kan inte flyttas. Exempel 4, forts. Perspektivprojektion gluperspective(angle, aspect, near, far); y bildplan angle z x near far Exempel 4, forts. Ortogonalprojektion glortho(left, right, bottom, top, near, far); y left, top bildplan z x right, bottom near far Exempel 4, forts. Skalning och offset av bildplanet glviewport(ox, oy, sx, sy); sy sx (ox, oy) 6
Resultat, exempel 4 7