OpenGL är ett kraftfullt 3D-programmeringsverktyg som används för att rita komplexa tredimensionella scener från enkla primitiv. Denna artikel lär dig hur man ritar en enkel kub som du kan snurra för att se i tre dimensioner!
För detta projekt behöver du en kodredigerare och viss kunskap om C -programmering.
Steg
Del 1 av 3: Initial Setup
Steg 1. Installera OpenGL Följ dessa steg för att installera OpenGL på ditt system
Om du redan har OpenGL, samt en kompatibel C -kompilator installerad, kan du hoppa över det här steget och gå till nästa.
Steg 2. Skapa dokumentet
Skapa en ny fil i din favorit kodredigerare och spara den som mycube.c
Steg 3. Lägg till #includes
Dessa är de grundläggande inkluderingar du behöver för ditt program. Det är viktigt att inse att det faktiskt behövs olika inkluderingar för de olika operativsystemen. Var noga med att inkludera alla dessa för att säkerställa att ditt program är mångsidigt och kan köras för alla användare.
// Inkluderar #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Steg 4. Lägg till funktionsprototyper och globala variabler
Ditt nästa steg är att deklarera några funktionsprototyper.
// Funktionsprototyper void display (); void specialKeys (); // Globala variabler dubbel rotate_y = 0; dubbel rotera_x = 0;
Steg 5. Ställ in huvudfunktionen ()
int main (int argc, char* argv ) {// Initiera GLUT och bearbeta användarparametrar glutInit (& argc, argv); // Begär dubbelbuffrad äkta färgfönster med Z-buffert glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Steg 6. Skapa fönstret
Nästa steg är att skapa fönstret inom vilken du kommer att rita kuben. I den här självstudien kallas fönstret "Awesome Cube".
// Skapa fönster glutCreateWindow ("Awesome Cube");
Steg 7. Aktivera djupprov
OpenGL är ett strikt språk eftersom det inte förutsätter att några specialfunktioner är aktiverade. För att ditt program ska visas korrekt i 3-dimensioner med hjälp av Z-bufferten som du tittade på tidigare måste du 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, vändskär och mycket mer.
// Aktivera Z-buffertdjupstest glEnable (GL_DEPTH_TEST);
Steg 8. Lägg till återuppringningsfunktioner
Här är återuppringningsfunktionerna du skrev prototyperna för tidigare. Varje gång genom huvudslingan kommer dessa funktioner att anropas. Displayfunktionen ritar om scenen baserat på eventuella ändringar av variabler som gjorts sedan föregående samtal. SpecialKeys -funktionen gör att vi kan interagera med programmet.
// Återuppringningsfunktioner glutDisplayFunc (display); glutSpecialFunc (specialKeys);
Steg 9. Starta MainLoop
Detta kommer att återkalla huvudfunktionen tills du stänger programmet för att möjliggöra animationer och användarinteraktion.
// Passera kontrollen till GLUT för händelser glutMainLoop (); // Återgå till OS -retur 0; }
Del 2 av 3: Display () -funktionen
Steg 1. Förstå syftet med denna funktion
Allt arbete med att rita din kub kommer att utföras i denna funktion. Den allmänna tanken bakom din kub är att rita alla sex sidor individuellt och placera dem i rätt position.
Konceptuellt kommer varje sida att dras genom att definiera de fyra hörnen och låta OpenGL ansluta linjerna och fylla i den med en färg som du definierar. Nedan följer stegen för att göra detta
Steg 2. Lägg till glClear ()
Det första steget du måste ta i denna funktion är att rensa färgen och Z -bufferten. Utan dessa steg kan de gamla ritningarna fortfarande vara synliga under de nya ritningarna och ritade föremål skulle inte vara på rätt plats på skärmen.
void display () {// Clear screen and Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Steg 3. Lägg till glBegin () och glEnd ()
OpenGL definierar objekt som kombinationer av olika polygoner. Använda glBegin () kommando lägger du effektivt ner en penna som kommer att rita en form. För att lyfta upp pennan och börja en ny form måste du använda glEnd () kommando. I denna handledning kommer du att använda GL_POLYGON för att rita varje sida av kuben men det är möjligt att använda andra parameteralternativ som GL_LINE, GL_QUAD eller GL_TRIANGLE för att skapa andra former.
- Här börjar du med framsidan av din kub. Senare kommer du att lägga till färg på alla 6 sidorna.
// Flerfärgad sida - FRONT glBegin (GL_POLYGON); // hörn läggs till i nästa steg glEnd ();
Steg 4. Lägg till glVertex3f ()
När du har sagt att du vill börja din polygon måste du definiera hörnen av föremålet. glVertex har flera former beroende på vad du vill göra med ditt objekt.
- Den första är hur många dimensioner du arbetar i. De 3 ovan i glVertex3f säger att du ritar i 3 dimensioner. Det är också möjligt att arbeta i 2 eller 4 dimensioner. F ovan i glVertex3f säger att du arbetar med flyttal. Du kan också använda shorts, heltal eller dubbel.
- Lägg märke till att dessa punkter definieras i a moturs sätt. Detta är inte särskilt viktigt för närvarande, men när du börjar arbeta med belysning, texturer och avskärning kommer detta att bli otroligt viktigt, så vana att definiera dina poäng moturs nu.
- Lägg till lägg hörnen mellan raderna glBegin () och glEnd ().
// Flerfärgad sida - FRONT glBegin (GL_POLYGON); glVertex3f (-0,5, -0,5, -0,5); // P1 glVertex3f (-0,5, 0,5, -0,5); // P2 glVertex3f (0,5, 0,5, -0,5); // P3 glVertex3f (0,5, -0,5, -0,5); // P4 glEnd ();
Steg 5. Lägg till glColor3f ()
glColor fungerar på liknande sätt som glVertex. Du kan definiera punkter som shorts, heltal, dubbel eller flytande. Varje färg har ett värde från 0 till 1. Alla 0: or gör punkten svart och alla 1: er gör punkten vit. 3 i glColor3f () hänvisar till RGB -färgsystemet utan alfakanal. Färgens alfa definierar dess transparens. För att ändra alfa -nivån, använd glColor4f () där den sista parametern är värdet 0 till 1 för ogenomskinlig till transparent.
- När du ringer glColor3f () kommer varje hörn som dras från den punkten att ha den färgen. Därför, om du vill att alla fyra hörnen ska vara röda, ställer du in färgen en gång när som helst innan glVertex3f () -kommandona och alla hörn blir röda.
- Framsidan som definieras nedan visar hur man definierar en ny färg för varje hörn. När du gör detta kan du se en intressant egenskap hos OpenGL -färgerna. Eftersom varje hörn av polygonen har sin egen färg kommer OpenGL automatiskt att blanda färgerna! Nästa steg visar hur du tilldelar fyra hörn med samma färg.
// Flerfärgad sida - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // Pl ä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 ();
Steg 6. Hantera de andra sidorna
Räkna ut vilken plats för varje hörn blir för de andra fem sidorna av kuben, men för enkelhetens skull har dessa beräknats för dig och ingår i slutlig display () -funktion Nedan.
// Vit sida - 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 - RIGHT 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 sida - 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å sida - 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öd sida - BOTTOM 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 (); }
Vi vill också lägga till två sista kodrader för denna funktion. Dessa är glFlush ();
och glutSwapBuffers ();
vilket ger oss dubbelbufferteffekten du lärt dig tidigare.
Del 3 av 3: Användarinteraktivitet
Steg 1. Lägg till specialKeys ()
Du är nästan klar men för närvarande kan du rita en kub men har inget sätt att rotera den. För att göra detta kommer du att göra det skapa en specialKeys () funktion så att vi kan trycka på piltangenterna och rotera kuben!
- Denna funktion är anledningen till att du deklarerade de globala variablerna rotate_x och rotate_y. När du trycker på höger och vänster piltangenter ökas eller minskar rotate_y med 5 grader. På samma sätt, när du trycker på upp- och nedpilarna, kommer rotate_x att ändras i enlighet därmed.
void specialKeys (int key, int x, int y) {// Högerpil - öka rotationen med 5 grader om (key == GLUT_KEY_RIGHT) rotate_y += 5; // Vänsterpil - minska rotationen med 5 grader annars om (key == GLUT_KEY_LEFT) rotate_y - = 5; annars om (key == GLUT_KEY_UP) rotate_x += 5; annars om (key == GLUT_KEY_DOWN) rotate_x -= 5; // Begär visningsuppdatering glutPostRedisplay (); }
Steg 2. Lägg till glRotate ()
Din sista sats är att lägga till den sats som roterar ditt objekt. Gå tillbaka till displayen () -funktionen och lägg till dessa rader före FRONT:
// Återställ transformationer glLoadIdentity (); // 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); // Flerfärgad sida - FRAM …
Steg 3. Lägg till följande kommandon för att skala kuben med 2 längs x-axeln, 2 längs y-axeln, rotera kuben 180 grader kring y-axeln och översätta kuben med 0,1 längs x-axeln
Se till att ordna dessa såväl som de tidigare kommandona glRotate () i rätt ordning enligt beskrivningen ovan. (Om du är osäker görs detta i den slutliga koden i slutet av självstudien.)
// Andra transformationer glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);
Steg 4. Kompilera och kör din kod
Om du antar att du använder gcc som kompilator kör du dessa kommandon från din terminal för att kompilera och testa ditt program.
På Linux: gcc cube.c -o kub -lglut -lGL./ mycube På Mac: gcc -o foo foo.c -ramwork GLUT -ramwork OpenGL./ mycube I Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Steg 5. Kontrollera din fullständiga kod
Det ska vara så här:
// // Fil: mycube.c // Författare: Matt Daisley // Skapad: 2012-04-25 // Projekt: Källkod för Gör en kub i OpenGL // Beskrivning: Skapar ett OpenGL -fönster och ritar en 3D -kub/ / Att användaren kan rotera med piltangenterna // // Kontroller: vänsterpil -rotera vänster // högerpil -rotera höger // pil upp -rotera upp // pil ned -rotera ned // ------ ---------------------------------------------------------- -// Inkluderar // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Funktionsprototyper / / ------------------------------------------------- --------- ogiltig display (); void specialKeys (); // ------------------------------------------------ ---------- // Globala variabler // ---------------------------------- ------------------------ dubbel rotera_y = 0; dubbel rotera_x = 0; // ------------------------------------------------ ---------- // display () Återuppringningsfunktion // ------------------------------- --------------------------- void display () {// Clear screen and Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Återställ transformationer glLoadIdentity (); // Andra transformationer // 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 transformationer // glScalef (2.0, 2.0, 0.0); // Ingår inte // Flerfärgad sida - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // Pl ä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 (); // Vit sida - 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 - RIGHT 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 sida - 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å sida - 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öd sida - BOTTOM 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 () Återuppringningsfunktion // ------------------------------ ---------------------------- void specialKeys (int-tangenten, int x, int y) {// Högerpil-öka rotationen med 5 grad om (key == GLUT_KEY_RIGHT) rotate_y += 5; // Vänsterpil - minska rotationen med 5 grader annars om (key == GLUT_KEY_LEFT) rotate_y - = 5; annars om (key == GLUT_KEY_UP) rotate_x += 5; annars om (key == GLUT_KEY_DOWN) rotate_x -= 5; // Begär visningsuppdatering glutPostRedisplay (); } // ----------------------------------------------- ----------- // huvudfunktion // ------------------------------- --------------------------- int main (int argc, char* argv ) {// Initiera GLUT och bearbeta användarparametrar glutInit (& argc, argv); // Begär dubbelbuffrad äkta färgfönster med Z-buffert glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Skapa fönster glutCreateWindow ("Awesome Cube"); // Aktivera Z-buffertdjupstest glEnable (GL_DEPTH_TEST); // Återuppringningsfunktioner glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Passera kontrollen till GLUT för händelser glutMainLoop (); // Återgå till OS -retur 0; }