OpenGL är ett kraftfullt 3D programmeringsverktyg som används för att rita komplexa tredimensionella scener från enkla primitiver. Denna artikel kommer att lära dig hur man drar en enkel kub som du kan snurra för att se i tre dimensioner!
För detta projekt kommer du att behöva en kod redaktör och vissa kunskaper i C-programmering.
Steg
Del 1: Inledande installation och main ()
1) Installera opengl
- Till att börja följa dessa steg för att installera OpenGL på ditt system. Om du redan har OpenGL och AC kompilator installerad kan du hoppa över det här steget och går till nästa.
2) skapa dokument
- Skapa en ny fil i din favorit-kod editor och spara den som mycube.c
3) # innefattar
- Dessa är de grundläggande inkluderar vi behöver för vårt program. Det är viktigt att inse att det finns faktiskt olika inkluderar krävs för de olika operativsystemen. Var noga med att inkludera alla dessa för att se ditt program är mångsidig och kan köras för alla användare.
4) funktionsprototyper och globala variabler
- Vårt nästa steg är att förklara någon funktion prototyper.
- Jag kommer att förklara alla dessa funktioner och globala variabler i detalj eftersom vi genomföra dem senare i denna tutorial. För nu är det viktigt att du förklarar dem.
5) om inrättande main () funktionen
- Detta uttalande ställer upp vår miljö. En stor sak att komma ihåg när du skriver OpenGL-program är att du måste be om allt. Detta kräver att du har en större förståelse för hur ditt program fungerar och vad du behöver för att inkludera att få den funktionalitet som du vill. I denna linje kommer vi att ställa in skärmen med dubbel buffring, RGB, och en Z-buffert.
- Dubbel buffring är en teknik som används i grafiska program för att eliminera ett problem som uppstår på grund av hur bilder dras till skärmen. Varje gång vi rita scenen, måste skärmen först raderas då den nya informationen kommer att dras. Utan dubbel buffring du kommer att följa en flimrande effekt som skärmen raderas och ritas om flera gånger.
Detta problem har rättats genom att lägga till en andra buffert för att dra till. Med denna metod kommer en bild dras till den första bufferten och att buffert visas för dig. Den nästa ram kommer att dras till den andra bufferten och när det är gjort, kommer de två buffertarna byta plats. Vi kommer omedelbart att se den andra bufferten, men, dolda för oss, är den första bufferten raderas och ritas med den tredje ramen som ska växlas in när du är klar. - Vi vill också göra det möjligt för RGB-färgsystem i våra fönster. Jag ska förklara mer om hur färg används i OpenGL när vi arbetar på displayen funktionen.
- Z-buffering är hur vi får de 3D-effekter som vi vill ha. OpenGL använder ett tredimensionellt koordinatsystem med x-, y-och z-axlarna. För att ge den effekt som ett objekt är närmare dig sin position på z-axeln ökas, dock så att det visas längre bort sin position på z-axeln minskas. Jag kommer att prata lite mer om detta när vi drar våra hörn för kuben.
6) skapar fönstret
- Nästa steg är att skapa fönstret inom vilket vi kommer att dra kuben. I denna tutorial, jag kallar vårt fönster "Awesome Cube".
7) aktiverar djuptestet
- OpenGL är ett strikt språk genom att den inte förutsätter några speciella funktioner som är aktiverade. För vårt program för att visas korrekt i 3-dimensioner med hjälp av Z-buffert som vi tittat på tidigare, behöver vi aktivera djup-test. När du fortsätter att utforska OpenGL, kommer du att upptäcka många funktioner som du kommer att behöva aktivera inklusive belysning, texturer, gallra-vetter och mycket mer.
8) callback-funktionerna
- Här är de callback funktioner vi skrev prototyper för tidigare. Varje gång genom huvudslingan, kommer dessa funktioner att kallas. Displayen Funktionen ritar scenen bygger på eventuella ändringar variabler som gjorts sedan förra samtalet. Den specialKeys Funktionen tillåter oss att interagera med programmet.
9) callback-funktionerna
- Det sista steget i vår grundinställning är att starta mainloop. Detta kommer att minnas den viktigaste funktionen tills vi stänger programmet att tillåta animationer och interaktion med användaren.
/ / Pass kontrollen till överflöd för händelser glutMainLoop (); / / Återgå till OS återvända 0; }
Del 2: displayen () funktionen
- Allt arbete med att rita vår kub kommer att ske i denna funktion. Den allmänna idén bakom vår kub är att dra alla sex sidor individuellt och placera dem i lämpligt läge.
- Konceptuellt är varje sida kommer att dras genom att definiera de fyra hörnen och låta OpenGL ansluta ledningarna och fyll i med en färg som vi definierar. Nedan är stegen för att göra detta.
1) glclear ()
- Det första steget vi måste ta in denna funktion är att rensa färg och Z-buffert. Utan dessa åtgärder, kan de gamla ritningarna är fortfarande synliga under de nya ritningar och föremål dras inte skulle vara på rätt plats på skärmen.
2) glbegin () och Glend ()
- OpenGL definierar objekt som kombinationer av olika polygoner. Använda glBegin () kommandot, lägger vi effektivt ner en penna som kommer att rita en figur. För att lyfta upp pennan och börja en ny form, måste vi använda Glend () glBegin ()> kommandot. I den här guiden kommer vi att använda GL_POLYGON att dra varje sida av kuben, men det är möjligt att använda andra parametrar alternativ såsom GL_LINE, GL_QUAD, eller GL_TRIANGLE att skapa andra former.
- Här kommer vi att börja med framsidan av vår kub. Senare kommer vi att lägga till färg till alla 6 sidorna.
3) glvertex3f ()
- När vi har sagt att vi vill börja vår polygon, måste vi definiera hörnen av objektet. glVertex har flera former beroende på vad du vill göra med ditt syfte.
- Den första är hur många dimensioner du arbetar i. 3 ovan i glVertex3f säger att vi drar i 3 dimensioner. Det är också möjligt att arbeta i två eller fyra dimensioner. Den f ovan i glVertex3f säger att vi arbetar med flyttal. Du kan också använda shorts, heltal eller dubbel.
- Lägg märke till att dessa punkter är definierade i en moturs sätt. Detta är inte särskilt viktigt just nu, men när vi börjar att arbeta med belysning, texturer och gallra-vända, kommer detta att bli oerhört viktigt så ta för vana att definiera dina poäng moturs nu.
- Nu lägger vi till hörnen mellan glBegin () och Glend () linjer.
4) glcolor3f ()
- glColor fungerar på ett liknande sätt som i glVertex. Vi kan definiera punkter som shorts, heltal, dubbel, eller flyter. Varje färg har ett värde från 0 till 1. Alla 0 s gör poängen svarta och alla 1: or kommer att göra punkten vita. Den 3 i glColor3f () refererar till RGB färgsystem utan alfakanal. Alfa av en färg definierar det genomskinlighet. För att ändra alfa nivå, använd glColor4f () med den sista parametern är ett värde mellan 0 och 1 för ogenomskinlig till genomskinlig.
- När vi kallar glColor3f () varje hörn dras från den punkten kommer att vara av den färgen. Därför, om vi vill att alla fyra hörn för att vara röd, bara ställa in färgen när som helst innan glVertex3f () kommandon och alla hörn kommer att vara röd.
- Den främre sidan definieras nedan visar hur du definierar en ny färg för varje vertex. När vi gör det, kan vi se en intressant egenskap hos OpenGL färger. Eftersom varje hörn av polygonen har en egen färg, kommer OpenGL blanda färgerna automatiskt! Nästa steg kommer att visa hur du tilldelar fyra hörn med samma färg.
5) de övriga sidorna
- Jag uppmuntrar dig att räkna ut vad var varje vertex kommer att vara för de övriga fem sidor av kuben, men för enkelhetens skull har jag beräknat de för dig och har inkluderat dem i vår sista visning () funktionen nedan.
/ / Vita sidan - Lila side - Gröna sidan - Blå sidan - Röda sidan -
- Vi vill också lägga in två sista rader kod för denna funktion. Dessa är glFlush (), och glutSwapBuffers (); glFlush ();> vilket ger oss dubbel-buffrande effekt vi lärt oss om tidigare.
Del 3: användarinteraktivitet
1) specialkeys ()
- Vi är nästan klar, men just nu, kan vi rita en kub men har ingen möjlighet att rotera det. För att göra detta, kommer vi att skapa en specialKeys () funktionen för att tillåta oss att trycka på piltangenterna och rotera kuben!
- Denna funktion är därför vi förklarade globala variabler rotate_x och rotate_y. När vi tryck på höger och vänster piltangenter, kommer rotate_y att inkrementeras eller dekrementeras med 5 grader. Likaså när vi trycker upp och ner piltangenterna, kommer rotate_x ändras därefter.
void specialKeys (int nyckel, int x, int y) { / / Höger pil - ökad rotation med 5 grader if (knapp == GLUT_KEY_RIGHT) rotate_y + = 5; / / Vänster pil - minskning rotation med 5 grader else if (knapp == GLUT_KEY_LEFT) rotate_y - = 5; else if (knapp == GLUT_KEY_UP) rotate_x + = 5; else if (knapp == GLUT_KEY_DOWN) rotate_x - = 5; / / Begär visning uppdatering glutPostRedisplay (); }
2) glrotate ()
- Vår sista uttalande är att lägga det uttalande som kommer att rotera vårt objekt. Gå tillbaka till display ()-funktionen och före framsidan, lägga till dessa rader:
- Först märker att syntaxen i glRotatef () är liknande till det av glColor3f () och glVertex3f () men alltid kräver 4 parametrar. Den första parametern är graden av rotation som skall tillämpas. De nästa tre parametrar definierar vilken axel att rotera runt den förstnämnda är x-axeln, andra är y-axeln, och den tredje är den z-axeln. Just nu behöver vi bara att rotera kring x-och y-axeln.
- Alla förändringar som vi skriver i vårt program behöver linjer som liknar detta. Konceptuellt, vi tänker på detta som roterar vårt syfte kring x-axeln med det belopp som definieras av rotate_x och sedan rotera runt y-axeln genom rotate_y. Men kombinerar OpenGL alla dessa påståenden i en matrix transformation. Varje gång vi kallar displayen funktion, bygger vi en omformningsmatris och glLoadIdentity () försäkrar att vi kommer att börja med en ny matris i varje pass.
- De övriga omformningsfunktioner vi kunde tillämpas är glTranslatef () och glScalef (). Dessa funktioner liknar glRotatef () med undantag för de bara tar 3 parametrar, x, y och z uppgår till översätta eller skala objektet.
- För att få rätt effekt vid tillämpningen samtliga tre transformationer till ett objekt, måste vi tillämpa dem i rätt ordning. Alltid skriva dem i ordning glTranslate, glRotate, sedan glScale. OpenGL tillämpar i huvudsak de förändringar i en bottom up sätt. För att förstå detta försöka föreställa sig vad en enkel 1x1x1 kub skulle se ut med de förändringar om OpenGL tillämpat dem från topp till botten och om OpenGL tillämpade dem från botten till toppen.
- Lägg följande kommandon att skala kuben med två längs x-axeln, 2 längs y-axeln, rotera kuben genom 180 ° kring y-axeln, och översätta kuben med 0,1 längs x-axeln. Se till att ordna dessa liksom den föregående glRotate () kommandon i rätt ordning, såsom beskrivits ovan. (Om du är osäker, har jag gjort detta i den slutliga koden i slutet av vägledningen.)
Kompilera
- Den allra sista steget för att avsluta din första OpenGL-projektet är att kompilera och köra koden. Förutsatt att du använder GCC som din kompilator, köra dessa kommandon från din terminal för att kompilera och testa dina program.
Slutlig koden
- Där har ni det. Din första OpenGL-program! Jag har gett dig mitt källkoden nedan som en referenspunkt.
/ / / / File: mycube.c / / Författare: Matt Daisley / / Skapad: 4/25/2012 / / Projekt: Källkod för Gör en kub i OpenGL / / Beskrivning: Skapar en OpenGL fönster och drar en 3D-kub / / Att användaren kan rotera med piltangenterna / / / / Kontroller: Vänster pil - Rotera vänster / / Högerpil - Rotera höger / / Upp-pil - rotera upp / / Nedåtpil - Rotera Ned / / ------------------------------------------------ ---------- / / Innehåller / / ------------------------------------------------ ---------- # Include <stdio.h> # Include <stdarg.h> # Include <math.h> # Define GL_GLEXT_PROTOTYPES # Ifdef __ APPLE__ # Include <GLUT/glut.h> # Else # Include <GL/glut.h> # Endif / / ------------------------------------------------ ---------- / / Funktion Prototyper / / ------------------------------------------------ ---------- annullera display (); void specialKeys (); / / ------------------------------------------------ ---------- / / Globala variabler / / ------------------------------------------------ ---------- dubbel rotate_y = 0; dubbel rotate_x = 0; / / ------------------------------------------------ ---------- / / Visa () callback-funktion / / ------------------------------------------------ ---------- void display () { / / Rensa skärmen och Z-buffert glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); / / Återställ transformationer glLoadIdentity (); / / Andra Transformations / / GlTranslatef (0.1, 0.0, 0.0), / / Ingår inte / / GlRotatef (180, 0.0, 1.0, 0.0), / / Ingår inte / / Rotera när användaren ändrar rotate_x och rotate_y glRotatef (rotate_x, 1,0, 0,0, 0,0); glRotatef (rotate_y, 0,0, 1,0, 0,0); / / Andra Transformations / / GlScalef (2.0, 2.0, 0.0), / / Ingår inte / / Multi-färgade sidan - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0), glVertex3f (0,5, - 0,5, - 0,5), / / P1 är röd glColor3f (0.0, 1.0, 0.0), glVertex3f (0,5, 0,5, - 0,5), / / P2 är grön glColor3f (0.0, 0.0, 1.0), glVertex3f (- 0,5, 0,5, - 0,5), / / P3 är blå glColor3f (1.0, 0.0, 1.0), glVertex3f (- 0,5, - 0,5, - 0,5), / / P4 är lila Glend (); / / Vita sidan - TILLBAKA glBegin (GL_POLYGON); glColor3f (1,0, 1,0, 1,0); glVertex3f (0,5, - 0,5, 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (- 0,5, 0,5, 0,5); glVertex3f (- 0,5, - 0,5, 0,5); Glend (); / / Lila sida - höger glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 1,0); glVertex3f (0,5, - 0,5, - 0,5); glVertex3f (0,5, 0,5, - 0,5); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, - 0,5, 0,5); Glend (); / / Grön side - VÄNSTER glBegin (GL_POLYGON); glColor3f (0,0, 1,0, 0,0); glVertex3f (- 0,5, - 0,5, 0,5); glVertex3f (- 0,5, 0,5, 0,5); glVertex3f (- 0,5, 0,5, - 0,5); glVertex3f (- 0,5, - 0,5, - 0,5); Glend (); / / Blå sidan - TOP glBegin (GL_POLYGON); glColor3f (0,0, 0,0, 1,0); glVertex3f (0,5, 0,5, 0,5); glVertex3f (0,5, 0,5, - 0,5); glVertex3f (- 0,5, 0,5, - 0,5); glVertex3f (- 0,5, 0,5, 0,5); Glend (); / / Röda sidan - BOTTEN glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, - 0,5, - 0,5); glVertex3f (0,5, - 0,5, 0,5); glVertex3f (- 0,5, - 0,5, 0,5); glVertex3f (- 0,5, - 0,5, - 0,5); Glend (); glFlush (); glutSwapBuffers (); } / / ------------------------------------------------ ---------- / / SpecialKeys () callback-funktion / / ------------------------------------------------ ---------- void specialKeys (int nyckel, int x, int y) { / / Höger pil - ökad rotation med 5 grader if (knapp == GLUT_KEY_RIGHT) rotate_y + = 5; / / Vänster pil - minskning rotation med 5 grader else if (knapp == GLUT_KEY_LEFT) rotate_y - = 5; else if (knapp == GLUT_KEY_UP) rotate_x + = 5; else if (knapp == GLUT_KEY_DOWN) rotate_x - = 5; / / Begär visning uppdatering glutPostRedisplay (); } / / ------------------------------------------------ ---------- / / Main () funktionen / / ------------------------------------------------ ---------- int main (int argc, char * argv []) { / / Initiera GLUT och process användarparametrar glutInit (& argc, argv); / / Begäran buffrat dubbelt sant färg fönster med Z-buffert glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); / / Skapa fönstret glutCreateWindow ("Awesome Cube"); / / Aktivera Z-buffert djuptestet glEnable (GL_DEPTH_TEST); / / Callback-funktionerna glutDisplayFunc (display); glutSpecialFunc (specialKeys); / / Pass kontrollen till överflöd för händelser glutMainLoop (); / / Återgå till OS återvända 0; }