OpenGL er et kraftig 3D-programmeringsverktøy som brukes til å tegne komplekse tredimensjonale scener fra enkle primitiver. Denne artikkelen vil lære deg hvordan du tegner en enkel terning som du kan snurre for å se i tre dimensjoner!
For dette prosjektet trenger du en kodeditor og litt kunnskap om C -programmering.
Trinn
Del 1 av 3: Første oppsett
Trinn 1. Installer OpenGL Følg disse trinnene for å begynne å installere OpenGL på systemet
Hvis du allerede har OpenGL, samt en kompatibel C -kompilator installert, kan du hoppe over dette trinnet og gå til neste.
Trinn 2. Lag dokumentet
Lag en ny fil i din favorittkode -editor og lagre den som mycube.c
Trinn 3. Legg til #includes
Dette er de grunnleggende inkluderer du trenger for programmet ditt. Det er viktig å innse at det faktisk er forskjellige inkludert som kreves for de forskjellige operativsystemene. Sørg for å inkludere alle disse for å sikre at programmet er allsidig og kan kjøres for alle brukere.
// Inkluderer #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Trinn 4. Legg til funksjonsprototyper og globale variabler
Ditt neste trinn er å deklarere noen funksjonsprototyper.
// Funksjon Prototyper ugyldig visning (); void specialKeys (); // Globale variabler dobbel rotere_y = 0; dobbel roter_x = 0;
Trinn 5. Sett opp hovedfunksjonen ()
int main (int argc, char* argv ) {// Initialiser GLUT og behandle brukerparametere glutInit (& argc, argv); // Be om dobbeltbuffret vindu i ekte farge med Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Trinn 6. Lag vinduet
Det neste trinnet er å lag vinduet der du vil tegne terningen. I denne opplæringen kalles vinduet "Awesome Cube".
// Lag vindu glutCreateWindow ("Awesome Cube");
Trinn 7. Aktiver dybdetest
OpenGL er et strengt språk ved at det ikke forutsetter at noen spesielle funksjoner er aktivert. For at programmet skal vises riktig i 3-dimensjoner ved hjelp av Z-bufferen du så på tidligere, må du mulig dybde-test. Når du fortsetter å utforske OpenGL, vil du oppdage mange funksjoner du trenger for å aktivere, inkludert belysning, teksturer, cull-facing og mye mer.
// Aktiver Z-buffer dybde test glEnable (GL_DEPTH_TEST);
Trinn 8. Legg til tilbakeringingsfunksjoner
Her er tilbakeringingsfunksjonene du skrev prototypene til tidligere. Hver gang gjennom hovedløkken vil disse funksjonene bli kalt. Displayfunksjonen tegner scenen på nytt basert på eventuelle endringer i variablene som ble gjort siden forrige samtale. SpecialKeys -funksjonen lar oss samhandle med programmet.
// Tilbakekallingsfunksjoner glutDisplayFunc (display); glutSpecialFunc (specialKeys);
Trinn 9. Start MainLoop
Dette vil huske hovedfunksjonen til du lukker programmet for å tillate animasjoner og brukerinteraksjon.
// Pass kontroll til GLUT for hendelser glutMainLoop (); // Gå tilbake til OS -retur 0; }
Del 2 av 3: Displayet () Funksjon
Trinn 1. Forstå formålet med denne funksjonen
Alt arbeidet med å tegne kuben din blir utført i denne funksjonen. Den generelle ideen bak kuben din er å tegne alle seks sider individuelt og plassere dem i riktig posisjon.
Konseptuelt vil hver side tegnes ved å definere de fire hjørnene og la OpenGL koble linjene og fylle den med en farge du definerer. Nedenfor er trinnene for å gjøre dette
Trinn 2. Tilsett glClear ()
Det første trinnet du må ta i denne funksjonen er å fjern fargen og Z -bufferen. Uten disse trinnene kan de gamle tegningene fortsatt være synlige under de nye tegningene, og objektene som er tegnet ville ikke være på riktig sted på skjermen.
ugyldig visning () {// Fjern skjerm og Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Trinn 3. Legg til glBegin () og glEnd ()
OpenGL definerer objekter som kombinasjoner av forskjellige polygoner. Bruker glBegin () kommando, legger du effektivt ned en blyant som tegner en form. For å løfte opp blyanten og begynne en ny form, må du bruke glEnd () kommando. I denne opplæringen bruker du GL_POLYGON til å tegne hver side av kuben, men det er mulig å bruke andre parameteralternativer som GL_LINE, GL_QUAD eller GL_TRIANGLE for å lage andre former.
- Her starter du med forsiden av kuben din. Senere vil du legge til farge på alle 6 sidene.
// Flerfarget side - FRONT glBegin (GL_POLYGON); // hjørner legges til i neste trinn glEnd ();
Trinn 4. Legg til glVertex3f ()
Når du har uttalt at du vil begynne på polygonen din, må du definere toppunktene av objektet. glVertex har flere former, avhengig av hva du vil gjøre med objektet ditt.
- Den første er hvor mange dimensjoner du arbeider i. De 3 ovenfor i glVertex3f sier at du tegner i 3 dimensjoner. Det er også mulig å arbeide i 2 eller 4 dimensjoner. F ovenfor i glVertex3f sier at du jobber med flytende tall. Du kan også bruke shorts, heltall eller dobbeltrom.
- Legg merke til at disse punktene er definert i a mot klokken måte. Dette er ikke veldig viktig for øyeblikket, men når du begynner å jobbe med belysning, teksturer og cull-facing, vil dette bli utrolig viktig, så vane deg med å definere poengene dine mot klokken nå.
- Legg til legg til hjørnene mellom linjene glBegin () og glEnd ().
// Flerfarget side - 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 ();
Trinn 5. Legg til glColor3f ()
glColor fungerer på samme måte som glVertex. Du kan definere poeng som shorts, heltall, dobler eller flyter. Hver farge har en verdi fra 0 til 1. Alle 0 -er gjør punktet svart og alle 1 -er gjør punktet hvitt. 3 i glColor3f () refererer til RGB -fargesystemet uten alfakanal. Alfaen til en farge definerer dens gjennomsiktighet. For å endre alfa -nivået, bruk glColor4f () med den siste parameteren en verdi på 0 til 1 for ugjennomsiktig til gjennomsiktig.
- Når du ringer til glColor3f (), vil hvert toppunkt trukket fra det tidspunktet være av den fargen. Derfor, hvis du vil at alle fire toppunktene skal være røde, må du bare sette fargen en gang når som helst før glVertex3f () -kommandoene, og alle hjørner vil være røde.
- Forsiden definert nedenfor viser hvordan du definerer en ny farge for hvert toppunkt. Når du gjør dette, kan du se en interessant egenskap med OpenGL -fargene. Siden hvert toppunkt i polygonen har sin egen farge, blander OpenGL fargene automatisk! Det neste trinnet viser hvordan du tildeler fire hjørner med samme farge.
// Flerfarget side - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 er rød glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 er grønn glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 er blå glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 er lilla glEnd ();
Trinn 6. Håndter de andre sidene
Regn ut hvor hvert toppunkt vil ligge for de andre fem sidene av terningen, men for enkelhets skyld er disse beregnet for deg og er inkludert i siste display () -funksjon under.
// Hvit side - TILBAKE 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 (); // Lilla side - HØYRE 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ønn side - VENSTRE 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å side - 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 side - BUNN 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 vil også legge til to siste kodelinjer for denne funksjonen. Disse er glFlush ();
og glutSwapBuffers ();
som gir oss dobbeltbuffereffekten du lærte om tidligere.
Del 3 av 3: Brukerinteraktivitet
Trinn 1. Legg til specialKeys ()
Du er nesten ferdig, men for øyeblikket kan du tegne en terning, men du kan ikke rotere den. For å gjøre dette, vil du opprett en spesiell nøkkel () funksjon for å la oss trykke på piltastene og rotere terningen!
- Denne funksjonen er grunnen til at du erklærte de globale variablene rotate_x og rotate_y. Når du trykker på høyre og venstre piltast, økes eller reduseres rotate_y med 5 grader. På samme måte, når du trykker på pil opp og ned, vil rotate_x endre seg tilsvarende.
void specialKeys (int key, int x, int y) {// Høyre pil - øk rotasjonen med 5 grader hvis (key == GLUT_KEY_RIGHT) rotate_y += 5; // Venstre pil - reduser rotasjonen med 5 grader ellers hvis (key == GLUT_KEY_LEFT) rotate_y - = 5; ellers hvis (key == GLUT_KEY_UP) rotate_x += 5; ellers hvis (key == GLUT_KEY_DOWN) rotate_x -= 5; // Be om skjermoppdatering glutPostRedisplay (); }
Trinn 2. Legg til glRotate ()
Din siste setning er å legge til setningen som vil rotere objektet ditt. Gå tilbake til display () -funksjonen, og legg til disse linjene foran på FRONTEN:
// Tilbakestill transformasjoner glLoadIdentity (); // Roter når brukeren endrer rotate_x og rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Flerfarget side - FRONT….
Trinn 3. Legg til følgende kommandoer for å skalere kuben med 2 langs x-aksen, 2 langs y-aksen, rotere kuben 180 grader rundt y-aksen og oversette kuben med 0,1 langs x-aksen
Sørg for å ordne disse så vel som de tidligere glRotate () -kommandoene i riktig rekkefølge som beskrevet ovenfor. (Hvis du er usikker, gjør du dette i den siste koden på slutten av opplæringen.)
// Andre transformasjoner glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);
Trinn 4. Kompiler og kjør koden din
Forutsatt at du bruker gcc som kompilator, kjører du disse kommandoene fra terminalen for å kompilere og teste programmet.
På Linux: gcc cube.c -o cube -lglut -lGL./ mycube På Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube På Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Trinn 5. Sjekk hele koden
Det skal være slik:
// // Fil: mycube.c // Forfatter: Matt Daisley // Laget: 25.04.2012 // Prosjekt: Kildekode for Lag en kube i OpenGL // Beskrivelse: Oppretter et OpenGL -vindu og tegner en 3D -kube/ / At brukeren kan rotere ved hjelp av piltastene // // Kontroller: Venstre pil -Roter venstre // Høyre pil -Roter høyre // Pil opp -Roter opp // Pil ned -Roter ned // ------ -------------------------------------------------- -// Inkluderer // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Funksjonsprototyper / / ------------------------------------------------- --------- ugyldig display (); void specialKeys (); // ------------------------------------------------ ---------- // Globale variabler // ---------------------------------- ------------------------ dobbel roter_y = 0; dobbel roter_x = 0; // ------------------------------------------------ ---------- // display () Tilbakekallingsfunksjon // ------------------------------- --------------------------- ugyldig visning () {// Fjern skjerm og Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Tilbakestill transformasjoner glLoadIdentity (); // Andre transformasjoner // glTranslatef (0,1, 0,0, 0,0); // Ikke inkludert // glRotatef (180, 0.0, 1.0, 0.0); // Ikke inkludert // Roter når brukeren endrer rotate_x og rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Andre transformasjoner // glScalef (2.0, 2.0, 0.0); // Ikke inkludert // Flerfarget side - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 er rød glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 er grønn glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 er blå glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 er lilla glEnd (); // Hvit side - TILBAKE 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 (); // Lilla side - HØYRE 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ønn side - VENSTRE 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å side - 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 side - BUNN 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 () tilbakeringingsfunksjon // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Høyrepil-øk rotasjonen med 5 grad hvis (nøkkel == GLUT_KEY_RIGHT) roter_y += 5; // Venstre pil - reduser rotasjonen med 5 grader ellers hvis (key == GLUT_KEY_LEFT) rotate_y - = 5; ellers hvis (key == GLUT_KEY_UP) rotate_x += 5; ellers hvis (key == GLUT_KEY_DOWN) rotate_x -= 5; // Be om skjermoppdatering glutPostRedisplay (); } // ----------------------------------------------- ----------- // hovedfunksjon // ------------------------------- --------------------------- int main (int argc, char* argv ) {// Initialiser GLUT og behandle brukerparametere glutInit (& argc, argv); // Be om dobbeltbuffret vindu i ekte farge med Z-buffer glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Lag vindu glutCreateWindow ("Awesome Cube"); // Aktiver Z-buffer dybde test glEnable (GL_DEPTH_TEST); // Tilbakekallingsfunksjoner glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Pass kontroll til GLUT for hendelser glutMainLoop (); // Gå tilbake til OS -retur 0; }