Hvordan lage en kube i OpenGL (med bilder)

Innholdsfortegnelse:

Hvordan lage en kube i OpenGL (med bilder)
Hvordan lage en kube i OpenGL (med bilder)

Video: Hvordan lage en kube i OpenGL (med bilder)

Video: Hvordan lage en kube i OpenGL (med bilder)
Video: Hvordan installere Ubuntu i VirtualBox på Windows. (Norwegian) 2024, April
Anonim

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

1994315 1 1
1994315 1 1

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.

1994315 2 1
1994315 2 1

Trinn 2. Lag dokumentet

Lag en ny fil i din favorittkode -editor og lagre den som mycube.c

1994315 3 1
1994315 3 1

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

1994315 4 1
1994315 4 1

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;

1994315 5 1
1994315 5 1

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);

  • Denne uttalelsen setter opp miljøet ditt. En stor ting å huske når du skriver OpenGL -programmer er at du må be om alt. Dette krever at du har en større forståelse av hvordan programmet ditt fungerer og hva du må inkludere for å få den funksjonaliteten du ønsker. På denne linjen vil du sette opp skjermen med dobbel buffering, RGB-farge og en Z-buffer.
  • Dobbel buffering er en teknikk som brukes i grafikkprogrammer for å eliminere et problem som oppstår på grunn av hvordan bilder trekkes til skjermen. Hver gang du tegner scenen på nytt, må displayet først slettes, deretter vil den nye informasjonen bli tegnet. Uten dobbel buffering vil du observere en flimrende effekt når skjermen slettes og tegnes om flere ganger.
  • Dette problemet løses ved å legge til en andre buffer å tegne til. Med denne metoden trekkes et bilde til den første bufferen, og den vises til deg. Den neste rammen trekkes til den andre bufferen, og når det er gjort, vil de to bufferne bytte plass. Du vil umiddelbart se den andre bufferen, men, skjult for oss, blir den første bufferen slettet og tegnet på nytt med den tredje rammen som vil bli byttet inn når den er ferdig.
  • Du vil også aktivere RGB -farge systemet i vinduet ditt.
  • Z-bufring er hvordan du får 3D -effektene du vil ha. OpenGL bruker et tredimensjonalt koordinatsystem med x-, y- og z -akser. For å gi den effekten at et objekt er nærmere deg, økes posisjonen på z -aksen, men for å få det til å se lenger unna, reduseres posisjonen på z -aksen.
1994315 6 1
1994315 6 1

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");

1994315 7 1
1994315 7 1

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);

1994315 8 1
1994315 8 1

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);

1994315 9 1
1994315 9 1

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

1994315 10 1
1994315 10 1

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

1994315 11 1
1994315 11 1

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);

1994315 12 1
1994315 12 1

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 ();

1994315 13 1
1994315 13 1

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 ();

1994315 14 1
1994315 14 1

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 ();

1994315 15 1
1994315 15 1

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

1994315 16 1
1994315 16 1

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 (); }

1994315 17 1
1994315 17 1

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….

  • Legg først merke til at syntaksen til glRotatef () ligner den på glColor3f () og glVertex3f (), men krever alltid 4 parametere. Den første parameteren er rotasjonsgraden som skal brukes. De tre neste parametrene definerer hvilken akse som skal roteres med den første er x -aksen, den andre er y -aksen, og den tredje er z -aksen. Akkurat nå trenger du bare å rotere rundt x- og y-aksen.
  • Alle transformasjoner du skriver i programmet trenger linjer som ligner på dette. Konseptuelt kan du tenke på dette som å rotere objektet ditt om x -aksen med mengden definert av rotate_x og deretter rotere rundt y -aksen med rotate_y. Imidlertid kombinerer OpenGL alle disse utsagnene til en matrisetransformasjon. Hver gang du ringer til skjermfunksjonen, bygger du en transformasjonsmatrise og glLoadIdentity () forsikrer at du starter med en ny matrise i hvert pass.
  • De andre transformasjonsfunksjonene du kan bruke er glTranslatef () og glScalef (). Disse funksjonene ligner på glRotatef () med unntak av at de bare tar 3 parametere, x, y og z beløpene for å oversette eller skalere objektet.
  • For å få riktig effekt når du bruker alle tre transformasjonene på ett objekt, må du bruke dem i riktig rekkefølge. Skriv dem alltid i rekkefølgen glTranslate, glRotate, deretter glScale. OpenGL bruker hovedsakelig transformasjonene på en bunn -opp -måte. For å forstå dette, prøv å forestille deg hvordan en enkel 1x1x1 kube ville sett ut med transformasjonene hvis OpenGL brukte dem fra topp til bunn og hvis OpenGL brukte dem fra bunn til topp.
1994315 18 1
1994315 18 1

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);

1994315 19 1
1994315 19 1

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

1994315 20 1
1994315 20 1

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; }

Anbefalt: