Grafiska System APIer mm Björn Eiderbäck bjorne@nada.kth.se Innehåll Grafiska System en intro Primitiver Inmatning Grafik-APIer Exempel Java OpenGL Varför intressera sig för grafik och interaktion? Användarsynvinkel Grafiska gränssnitt ger (om rätt konstruerade) överskådlighet enkel och effektiv inlärning rolig och inbjudande presentation och interaktion ökad kreativitet hos användarna Utvecklarsynvinkel Vad är ett bra grafiskt/interaktivt gränssnitt? Vilka olika möjligheter finns det? Hur konstruerar jag en sådan applikation rent tekniskt? Finns det bra verktyg för att konstruera tillämpningarna? previous next previous next 2 Vad behöver vi veta för att konstruera grafiska applikationer? Grafik Matematiska modeller, grundläggande grafiska algoritmer, visualisering, modellering, termer, tekniker och något om hårdvara Grafikprogrammering Kan delas upp på tre inbördes beroende delar Grsfikprogrammering Interaktion Utformning, konstruktion, design och tekniker för att fabricera interaktiva grafiska applikationer Programmering Tekniker Språk Grafik Tekniker Mjukvara Interaktion Tekniker Hårdvara Programmering Programmeringsverktyg för att skapa grafiska interaktiva tillämpningar APIer Utvecklingsmiljöer Gränssnitt WWW, Internet Visualisering Dimensioner Hårdvara Människan Modeller Ergonomi previous next 3 previous next 4 Programmering Grafik Grafik Programmering Tekniker Visualisering Interaktion Frameworks Komponentbaserade Språk C Java Smalltalk Lingo Utvecklingsmiljöer Smalltalkmiljöer Javamiljöer Director Andra Gränssnitt Tekniker Anpassningsbara Gränssnittsbyggare WWW, Internet, mm Applets Distribuerade applikationer HTML Tekniker Algoritmer Primitiver Modellering Mjukvara OpenGL GKS, PHIGS, mfl VRML Visualisering Grafisk presentation Färg, belysning Perceptuella aspekter Dimensioner 2D 2.5D 3D Hårdvara Maya Maya Inmatningsverktyg Utmatning Bildminne previous next 5 previous next 6
Interaktion Interaktion Tekniker Presentations Interaktions Programmerings Hårdvara Grafik kort historik (som ni sett på videon) Men några Milstolpar redan tidigt i datorhistorien (50-talet) fanns halvdumma utskriftsenheter som teleprintrar och radskrivare Pekverktyg Skärm Hjälm, handske Människan Förutsättningar Deltagande under utvecking Seendet Modeller omkring 1950 kom datordrivna katodstrålerör (CRT) Konceptuella Programmeringsmodeller Styrd av människans krav previous next 7 previous next 8... historik... under tidigt 60-tal utvecklades Sketchpad av Ivan Sutherland på MIT Lincoln lab här användes eleganta sätt att rita och manipulera grafiska objekt med en ljuspenna man introducerade många intressanta tekniker bl.a. hierarkier av bilder och delbilder, gummibandslinjer, restriktioner (eng. constraints), gester för vissa operationer många av dessa tekniker hittar vi i dagens system... historik... Samtidigt såg bil- och flygindustrin möjligheterna att använda grafiska tekniker Computer Aided Design (CAD) och Computer Aided Manufacturing (CAM) Arkadspelen som kom i mitten av sjuttiotalet bidrog också starkt till populäriseringen av datorstödda grafiska lösningar. PONG (dvs ett sorts enkelt tennisspel) mitten av 70-talet. previous next 9 previous next 10... historik... Under sjuttiotalet utvecklades också grafiska arbetsstationer med bl.a. fönster och möss. Under 80-talet då billiga persondatorer med bitmappade skärmar kom tog den grafiska användningen riktig fart. (även om hårdvaruteknikerna till stora delar utvecklades under 60-talet)... historik Många grafiska standarder har utvecklats Med en strävan att enklare skriva komplexa grafiska applikationer flyttbar kod som kan köras på flera olika plattformar och hårdvaror Några betydelsefulla grafikpaket 80-talet GKS, PHIGS, NeWS mfl 90-talet OpenGL VRML previous next 11 previous next 12
Interaktiva grafiska system Milstolpar (några axplock): Douglas Engelbart, mitten av 1960-talet NLS, on Line System, innehöll email, hypertext, direkmanipulation, konferenssystem med videolänk, mm Smalltalk, på Xerox under 1970-talet Introducerade bitmappade skärmar, fönstersystem, pop-upmenyer, användning av mus, reflexiv öppen omgivning, maskinoberoende portabel kod, MVC, objektorientering, stort klassbibliotek....milstolpar... Xerox Star, 1981 Desktopmetafor med ikoner och överlappande fönster. What You See Is What You Get (WYSIWYG) MAC, 1984 Första billiga alternativet. Genomgående grafisk direkmanipulativ filosofi. X-windows, 1987 Windows 3, 1990 Sålde idéerna till en bredare publik (även om gränssnittet var ett :-)) IDE, Integrated Development Environment, med utvecklingsverktyg previous next 13 previous next 14...milstolpar Videospel Gjorde oss vana vid idéerna. Grundläggande grafiskt system Windows 95/NT gav vidare spridning (Det börjar se snyggare ut.) HTML, WWW med browsrar som Mosaic och Netscape, tidigt 1990- tal Har (indirekt) ökat intresset och spritt idéerna till en riktigt bred marknad Java (första versionen släpptes 1995) Ökade möjligheter att skriva plattformsoberoende interaktiva system, enkelt att sprida med sin koppling till Internet Modernare IDEer VisualWorks\Smalltalk med SUnit, refactoring, mm Eclipse Inmatningsenhet Bilden skapad i FB Utmatningsenhet previous next 15 previous next 16 Inmatningsverktyg Katodstrålerör mouse trackball light pen data tablet joy stick space ball Kan antingen användas som linjeritande enhet eller innehållet i en frame buffer (rastergrafik) previous next 17 previous next 18
Datorgrafik: 1950-1960 Som tidigare sagts går datorgrafik tillbaks till datorernas barndom Datorgrafik : 1960-1970 Trådmodeller Kostnaden för omritning via katodstrålerör var då hög Datorerna var långsamma, dyra och inte tillförlitliga previous next 19 previous next 20 Grafikprocessor (eng Display Processor) Istället för att den vanliga datorn ska behöva uppdatera skärmen finns en speciell grafikprocessor (display processor (DPU)) Dom grafiska elementen lagras i en utritningslista (eng display list (display file)) i grafikprocessorn Värddatorn kompilerar display-listan och skickar den till DPU Datorgrafik : 1970-1980 Rastergrafik Grafiska standardpaket började komma Ett par av dom största GKS: Europeiskt Blev ISO 2D standard Core: Nordamerikanskt 3D men blev aldrig ISO standard Arbetstationer och PC previous next 21 previous next 22 Rastergrafik En bild skapad som en vektor (ett raster) av bildelement (pixels) i frame bufferten Rastergrafik Låter oss gå från linjer och trådmodeller till fyllda polygoner previous next 23 previous next 24
PCar och arbetsstationer Även om vi inte längre skiljer på PCar och arbetsstationer så har dom utvecklats från olika källor Tidiga arbetsstationer karaktäriseras av Nätverksanslutning: klient-server Hög nivå av interaktivitet Tidiga PCar inkluderade bildminne som del av användarminnet Datorgrafik : 1980-1990 Realism kommer till datorgrafiken smooth shading environmental mapping bump mapping previous next 25 previous next 26 Datorgrafik: 1980-1990 Specialhårdvara Silicon Graphics geometrimotor VLSI implementation av grafisk pipeline Industristandard PHIGS RenderMan Nätverksbaserad grafik: X Window System Datorgrafik: 1990-2000 OpenGL API Helt datorgenerarade filmer (Toy Story) gör succe Nya hårdvarumöjligheter Texture mapping Blending Accumulation, stencil buffer Human-Computer Interaction (HCI) previous next 27 previous next 28 Datorgrafik: 2000- Fotorealism Utmatningstekniker Vektoriserade (linjeritande) skärmar Grafikkort till PCs dominerar marknaden Nvidia, ATI, 3DLabs var ganska vanliga fram till en bit in på 80-talet utritning sker genom att linje för linje i en slumpmässig ordning ritas ut på skärmen, därför den engelska termen random scan kunde rita linjer mellan godtyckliga punkter på skärmen Spelkonsoler leder marknadsutveckoingen Datorgrafik blir rutin i filmindustrin: Maya, Lightwave Refresh rate Skärmens fosforyta efterlyser endast en viss tid måste uppdateras flera gånger i sekunden (typiskt 30-70) för att undvika flimmer. previous next 29 previous next 30
... Rasterskärm... Interlacing (sve. radsprång) skärmen uppbyggd som en bitkarta varannan sveplinje uppdateras i varje svep bilderna lagras i en speciell refresh buffer Raster hela bilden skapas från ett raster, som är en uppsättning horisontella svep-linjer bra för skärmar med låg uppdateringshastighet (med typiskt 30 ggr per sekund). Reducerar flimmer. previous next 31 previous next 32... Monokrom skärm... Element konstrueras som bitkartor Exempel bitkarta till bild (från VisualWorks) ritar med två färger Pixmap (pixel map), bitkarta en representation av en rektangulär area med en vektor av punkter bestående av heltal Namnet pixmap kan betyda både innehållet i refreshbufferten och buffertens minne. För att inte skapa förvirring brukar det senare kallas för frame buffer. 0000000000000000 0100000000000000 0110000000000000 0111000000000000 0111100000000000 0111110000000000 0111111000000000 0111111100000000 0111110000000000 0111110000000000 0100110000000000 0000011000000000 0000011000000000 0000001100000000 0000001100000000 0000000000000000 Cursor normal 0000000110000000 0001101001110000 0010011001001000 0010011001001010 0001001001001101 0001001001001001 0110100000001001 1001100000000001 1000100000000010 0100000000000010 0010000000000010 0001000000000100 0001000000000100 0000100000001000 0000010000001000 0000010000001000 Cursor hand previous next 33 previous next 34... Matematisk beskrivning till raster Svepkonvertering/rastrering (matematiska) (linje-)beskrivningar översätts till rasterpunkter Ett problem: Aliasing en term från signalprocessing för fel som uppstår då en kontinuerlig signal diskretiseras I grafiska sammanhang syns detta genom att räta linjer blir trappor. y = mx + b R2 R 2 = x 22 + y 22 previous next 35 previous next 36
En lösning: Antialiasing tekniker för att reducera aliasing-effekter vanlig teknik är att låta intensiteten vara proportionell mot hur mycket en viss rasterpunkt befinner sig inom den ideala linjen Koordinatsystem och koordinater Vanligen jobbar vi i Cartesiska koordinater Vissa system har origo nere till vänster andra uppe till vänster Världskoordinater Är dom koordinater vi använder i våra applikationer Här bryr vi inte oss om vilka pixlar på skärmen som kommer representera dem Utan antialiasing Antialiasing Skärmkoordinater De koordinater som verkligen representerar punkter på skärmen previous next 37 previous next 38 Kameramodell projektor p bildplan projektion av p Projektionscentrum (center of projection, cop) Världen med världskoordinater Skärmen med skärmkoordinater Vanliga ritrutiner och attribut Dom flesta grafiska paket innehåller åtminstone stöd för att rita (2D) Punkter Av olika storlek Linjer Heldragna, streckade, prickade osv Polygoner Fyllda eller icke fyllda Text Med olika storlek och typsnitt Kurvor Som splines och Bezierkurvor previous next 39 previous next 40 OpenGL-primitiver GL_POINTS GL_LINES GL_TRIANGLES GL_LINE_STRIP GL_LINE_LOOP GL_POLYGON GL_QUAD_STRIP Attribut Det finns också stöd för att ange Färg eller mönster Linjebredd Prickad streckad I OpenGL kommer ni senare se prov på fler attribut, tex för att ange olika typer av polygoner och (självklart) i tre dimensioner GL_TRIANGLE_STRIP GL_TRIANGLE_FAN previous next 41 previous next 42
Klippning Då man konstruerar ett fönster att rita i brukar (eller kan) man också ange klipprektanglar Dvs ange dom områden där objekten skall synas Objekt utanför, eller delvis utanför, klipps mot området Fönster och vyer Ett fönster brukar ofta delas in i delvyer (viewports) I varje viewport jobbar man med ett lokalt koordinatsystem (fönstret har också ett koordinatystem) Med klipprektangel satt snabbas ofta utritningen upp previous next 43 previous next 44 Attribut Linjetjocklek Linjeändor Linjehörn previous next 45 3 huvudtyper 1 2 Olika inmatningstyper Det är centralt att ta hand om inmatning från olika inenheter i alla typer av interaktiva tillämpningar Request mode Vänta tills dess att något sker tex på inmatning via tangentbordet eller klick på mus traditionell inmatning från tangentbord, scanf (C), readln (Pascal) sensor.waitbutton(); gc.displaystring("inmatning ", sensor.pos()); Där sensor är ett (tänkt) objekt som ger oss möjlighet att läsa av inmatningsverktygens status (dvs tex tangentbord och mus) Samplad/pollad Kontrollera status för enhet Omedelbar avläsning tex är någon knapp på musen nertryckt while(sensor.anybuttonpressed()) { pen.moveto(sensor.mousepoint()); previous next 46 3... inmatningstyper Händelsestyrd Förändringar hos enheter placeras i en kö intresserade program meddelas om att händelse inträffat från början av kön (flera kan alltså meddelas om samma händelse) API:er Genom åren har flera APIer (Application Programmer s Interface) skapats, tex GKS, Phigs mfl Smalltalk-APIer Java-APIer OpenGL-APIer (med bla GLUT, GLU) Det är sedan upp till varje program att själv bestämma hur det skall (eller inte skall) reagera Exempel, en metod som reagerar om händelsen dubbeklick inträffar public void doubleclickevent(event event) { frame.setlocation(event.position()); Gör det relativt enkelt att programmera både grafiska och interaktiva gränssnitt previous next 47 previous next 48
Inmatningstyper och APIer Dom modernare APIerna för grafik och interaktion använder en händelsebaserad inmatning Används i exempelvis Java Utnyttjar polymorfism och andra oo-tekniker Händelsehanterare Smalltalk OO-tekniker Shockwave och Flash Olika händelser resulterar i olika funktionsanrop OpenGL Bakomliggande system anropar metoder som programmeraren definerat och bundit till specifika händelser previous next 49 Javas API (Application Programmer s Interface) Java:s API innehåller bla awt (abstract windowing toolkit) som delvis kan användas som ett FrameWork som bla stödjer konstruktion av applikationer med fönster Konstruktion av egna fönster Fundamental fönsterklass AWT: Frame Swing: JFrame Ett sätt att konstruera fönster med egna egenskaper (tex speciell utritning) är att subklassa fönsterklassen Beteendet ändras, dvs anpassas till dom egna önskemålen, genom att lämpliga metoder skrivs om i den konkreta (egna) subklassen Tex paint(...) eller paintcomponent(...) för att beskriva utritning Olika händelsehanterare definieras för att ta hand om olika inmatningshändelser I Swing subklassar man ofta JComponent previous next 50 Frame och Applet java.lang java.awt java.applet Object Object Component Component Container Container Window Window Panel Panel Frame Frame Applet Applet Ofta importeras alla klasser i java.awt Java-exempel 1 (AWT) import java.awt.*; // Klassdefinition (utan extends medför subklass till Object) public class MyApplication { Ofta är det tillräckligt att (Java 1.1) subklassa Frame och implementera tex WindowListener, MouseListener och MouseMotionListener senare skall vi titta på hur vi istället kan använda adaptorer skriva public static void main(string [] args) instansiera den egna klassen, ange fönsterstorlek och ange att fönster och mushändelser skall tas emot (addwindowlistener(this) osv), öppna det hela skriva public void paint(graphics g) rita på skärmen konstruera metoder för dom gränssnitt för dom "lyssnare" vi angett att vi skall implementera Instansiera Frame Sätt storlek Och öppna public static void main(string [] s) { Frame f = new Frame("Mitt första fönster"); f.setsize(200, 300); f.setvisible(true); previous next 51 previous next 52... och så sparar vi, kompilerar och kör Spara Spara filen med samma namn som klassen med extension.java, dvs här MyApplication.java Kompilera javac MyApplication.java Skapar en fil MyApplication.class Kör java MyApplication previous next 53 Vi definierar hur omritning av fönstret ska gå till Java-exempel 2 (AWT) import java.awt.*; public class MyFrame extends Frame { public MyFrame() { public MyFrame(String s) { super(s); public void paint(graphics g) { int x = 100, y = 200; for (int i = 0; i < 100; i++) { g.drawoval(x, y, i, i); public static void main(string [] s) { MyFrame f = new MyFrame("Mitt andra fönster"); f.setsize(200, 300); f.setvisible(true); previous next 54
Java2D: hur Java har ett rikt API för att konstruera grafiska tillämpningar http://java.sun.com/docs/books/tutorial/2d/index.html Graphics och Graphics2D är dom centrala utritningsklasserna För att komma åt Graphics2D:s rutiner måste vi dock göra en cast (i tex paint-metoden) public void paint(graphics g) { Graphics2D g2 = (Graphics2D) g; // Nu kan vi använda rutiner i Graphics2D utan att // komplikatorn klagar... Java2D: några primitiver och enkla ritrutiner linjetjocklek float width = 10; BasicStroke bs = new BasicStroke(width); gc2.setstroke(bs); gc2.drawline(10, 10, 100, 200); streckad linje float [] dash = {10; BasicStroke b = new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f); g2.setstroke(b); previous next 55 previous next 56... Polygon (beskriv först rita sedan) GeneralPath p = new GeneralPath(); p.moveto(0, 0); p.lineto(w/12, h/10); p.lineto(0,h/5); p.closepath(); g2.draw(p); //Rita ut det hela nu Java2D: ange typ av linje och hörn I många grafikpaket kan man ange om ändor av linjer skall vara räta, rundade eller projicerade CAP_BUTT, CAP_ROUND, CAP_SQUARE Motsvarande gäller för hörn i polygoner BasicStroke.JOIN_MITER, BasicStroke.JOIN_ROUND, BasicStroke.JOIN_BEVEL BasicStroke bs = new BasicStroke(20.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND); Antialiasing g2.setrenderinghint(renderinghints.key_antialiasing, RenderingHints.VALUE_ANTIALIAS_ON); Rita sen som vanligt previous next 57 previous next 58 För JFrame importerar vi javax.swing För mer avancerad grafik importerar vi java.awt.geom Med Graphics2D kan vi göra mer avancerade 2Dsaker Java-exempel 3, Swing, Graphics2D och JFrame import java.awt.*; import javax.swing.*; import java.awt.geom.*; public class MyJFrame extends JFrame { public void paint(graphics g) { Graphics2D g2 = (Graphics2D)g; g2.setstroke(new BasicStroke(8.0f)); g2.setcolor(color.magenta); g2.draw(new Arc2D.Double(40, 70, 200, 100, 120, 135, Arc2D.OPEN)); public static void main(string [] s) { MyJFrame f = new MyJFrame(); f.setsize(200, 300); f.setvisible(true); previous next 59 Java-exempel 4 import java.awt.*; import java.awt.event.*; import java.awt.geom.*; import java.awt.image.*; import javax.swing.*; public class Demo1Java2D extends JFrame { public Demo1Java2D(){ super( Some 2D graphics"); public void paint(graphics g){ super.paint(g); Graphics2D graphics2d = (Graphics2D) g; graphics2d.translate(0, 20); graphics2d.setpaint(new GradientPaint (5, 30, Color.blue, 35, 100, Color.yellow, true)); graphics2d.fill(new Ellipse2D.Double(5, 30, 65, 100)); previous next 60
graphics2d.setpaint(color.red); graphics2d.setstroke(new BasicStroke(10.0f)); graphics2d.draw( new Rectangle2D.Double(80, 30, 65, 100)); graphics2d.setpaint(new TexturePaint( bufferedimage, new Rectangle(10, 10))); graphics2d.fill(new RoundRectangle2D.Double( 155, 30, 75, 100, 50, 50)); BufferedImage bufferedimage = new BufferedImage( 10, 10, BufferedImage.TYPE_INT_RGB); Graphics2D graphics= bufferedimage.creategraphics(); graphics.setcolor(color.yellow ); graphics.fillrect(0, 0, 10, 10 ); graphics.setcolor(color.black ); graphics.drawrect(1, 1, 6, 6 ); graphics.setcolor(color.blue ); graphics.fillrect(1, 1, 3, 3 ); graphics.setcolor(color.red ); graphics.fillrect(4, 4, 3, 3 ); graphics2d.setpaint(color.white); graphics2d.setstroke(new BasicStroke(6.0f)); graphics2d.draw( new Arc2D.Double( 240, 30, 75, 100, 0, 270, Arc2D.PIE)); graphics2d.setpaint(color.green ); graphics2d.draw(new Line2D.Double(395, 30, 320, 150)); float[] dashes = {10, 2; graphics2d.setpaint(color.yellow); graphics2d.setstroke(new BasicStroke( 4, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 10, dashes, 0)); graphics2d.draw(new Line2D.Double(320, 30, 395, 150)); previous next 61 previous next 62 public static void main(string[] args){ Demo1Java2D application = new Demo1Java2D (); application.setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE); application.setsize(425, 180); application.setvisible(true); Inkludera nödvändiga bibliotek Beskriv vad som ska göras om fönstret behöver ritas om OpenGL ett första exempel (simple1.c) #include <GL/glut.h> /* glut.h inkluderar gl.h och glu.h*/ void mydisplay(void) { glclear(gl_color_buffer_bit); /* Rensa fönstret */ glbegin(gl_polygon); /* Beskriv en polygon */ glvertex2f(-0.5, -0.5); glvertex2f(-0.5, 0.5); glvertex2f(0.5, 0.5); glvertex2f(0.5, -0.5); glend(); glflush(); /* Töm bufferten, dvs rita polygonen */ int main(int argc, char** argv) { glutcreatewindow("simple 1"); glutdisplayfunc(mydisplay); glutmainloop(); Skapa ett fönster Ange att mydisplay ska anropas vid omritning Låt glut:s huvudloop ta över (måste alltid vara med och sist i koden) previous next 63 previous next 64... kompilera och köra... På NADAs Solaris/Unix-maskiner gcc simple1.c o simple1 -lglut -lgl -lglu -lxmu -lx11 -lm Under Windows med Cygwin och gcc/g++ och glut 3.7.6 installerat gcc simple1.c o simple1 -lopengl32 -lglu32 -lglut32 -lm -LC:\GLUT\glut-3.7.6-bin Där jag placerat glut-binärerna i C:\GLUT\glut-3.7.6-bin Kör genom att skriva (eller kanske dubbelklicka på simple1.exe) simple1... det blir enklare att kompilera med hjälp av en make-fil... Alexander pratar mer om detta senare i kursen # This sample Makefile allows you to make an OpenGL application # whose source is exactly one.c file. # # To use this Makefile, you type: # make xxxx # where # xxxx.c is the name of the file you wish to compile # # A binary named xxxx will be produced CC = gcc #Windows LDLIBS = -lopengl32 -lglu32 -lglut32 -lm -LC:\GLUT\glut-3.7.6-bin #UNIX #LDLIBS = -lglut -lgl -lglu -lxmu -lx11 -lm.c: $(CC) $@.c $(LDLIBS) -o $@ previous next 65 previous next 66
... då kan vi kompilera på följande sätt make simple1 Då kommer kompilering bara ske om simple1.c är förändrad I så fall skapas simple1.exe En egen initrutin Sätt upp fönstrets koordinater Vi utvidgar exemplet en aning (simple2.c) I förra exemplet använde vi en hel del defaultvärden Vi ändrar lite #include <GL/glut.h> void mydisplay(void) { /* Som i förra versionen void init() { /* Vi rensar med grönt den här gången */ glclearcolor (0.0, 1.0, 0.0, 1.0); /* och ritar med rött */ glcolor3f(1.0, 0, 0); glmatrixmode (GL_PROJECTION); glloadidentity (); previous next 67 /* left, right, bottom, top, near, far */ glortho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0); previous next 68 Anropa den egna init() int main(int argc, char** argv) { glutinit(&argc,argv); glutinitdisplaymode (GLUT_SINGLE GLUT_RGB); glutinitwindowsize(500,500); glutinitwindowposition(20,50); glutcreatewindow("simple 2"); glutdisplayfunc(mydisplay); init(); glutmainloop(); En buffer för omritning vidd, höjd Använd RGB för att definiera färger Fönstrets övre vänstra hörn origo i skärmens övre vänstra hörn previous next 69