Wkuno

Hvordan lage en kube i OpenGL

OpenGL er et kraftig 3D programmering verktøy som brukes for å tegne komplekse tredimensjonale scener fra enkle primitive. Denne artikkelen vil lære deg hvordan å trekke en enkel kube som du kan spinne å se i tre dimensjoner!

For dette prosjektet trenger du en kode redaktør og noe kunnskap om C-programmering.

Trinn

Hvordan lage en kube i OpenGL. gjøre det mulig dybde-test.
Hvordan lage en kube i OpenGL. gjøre det mulig dybde-test.

Del 1: innledende oppsett og main ()

1) installere OpenGL

  • Til å begynne følge disse trinnene for å installere OpenGL på systemet ditt. Hvis du allerede har OpenGL og ac kompilatoren installert, kan du hoppe over dette trinnet og gå til neste.

2) oppretter dokumentet

  • Lag en ny fil i din favoritt kode editor og lagre det som mycube.c

3) inkluderer #

  • Dette er den grunnleggende inkluderer vi trenger for vårt program. Det er viktig å innse at det er faktisk forskjellige inkluderer nødvendig for de ulike operativsystemene. Sørg for å inkludere alle disse for å sikre at programmet er allsidig og kan kjøre for alle brukere.
    
    

4)-funksjonen prototyper og globale variabler

  • Vårt neste skritt er å erklære noen funksjon prototyper.
    
    
  • Jeg vil forklare hver av disse funksjonene og de globale variabler i detalj som vi implementere dem senere i denne opplæringen. For nå er det viktig at du erklære dem.

5) sette opp main ()-funksjonen

  • 
    
  • Denne uttalelsen setter opp vårt miljø. En stor ting å huske på 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 fungerer og hva du trenger for å inkludere for å få den funksjonalitet som du ønsker. I denne linjen, vil vi sette opp skjermen med dobbel buffering, RGB farge, og en Z-buffer.
  • Dobbel buffering er en teknikk som brukes i grafiske programmer for å eliminere et problem som oppstår på grunn av hvordan bildene er trukket til skjermen. Hver gang vi tegne scenen, må displayet først bli slettet da den nye informasjonen vil bli trukket. Uten dobbel buffering vil du observere en flimrende effekt som skjermen blir slettet og oppdateres flere ganger.
    Dette problemet er løst ved tilsetning av en andre buffer for å trekke til. Med denne metoden blir et bilde trukket til den første bufferen, og at bufferen er vist i den. Den neste rammen vil bli trukket til den andre buffer, og når det er gjort, vil de to buffere bytte plass. Vi vil umiddelbart se andre buffer, men skjult for oss, er det første buffer blir slettet og tegnet på nytt med den tredje rammen som vil bli byttet i når du er ferdig.
  • Vi ønsker også å aktivere RGB fargesystem i vinduet vårt. Jeg skal forklare mer om hvordan farger skal brukes i OpenGL når vi jobber på displayet funksjon.
  • Z-buffering er hvordan vi får 3D-effekter som vi ønsker. OpenGL benytter et tredimensjonalt koordinatsystem med x-, y-og z-aksene. For å gi inntrykk at et objekt er nærmere deg sin posisjon på z-aksen er økt, men å gjøre det synes lenger unna sin posisjon på z-aksen er redusert. Jeg vil snakke litt mer om dette når vi trekker våre topp-punkt for kuben.

6) skaper vinduet

  • Det neste trinnet er å lage vindu i som vi vil trekke kuben. I denne opplæringen, jeg kaller vår vindu "Awesome Cube".
    
    

7) gjør grundig test

  • OpenGL er en streng språk ved at det ikke påtar seg noen spesielle funksjoner som er aktivert. For vårt program ikke viser i tre dimensjoner ved hjelp av Z-buffer som vi så på tidligere, må vi gjøre det mulig dybde-test. Som du fortsetter å utforske OpenGL, vil du oppdage mange funksjoner som du må aktivere inkludert belysning, teksturer, cull-vendt og mye mer.
    
    

8) tilbakeringing funksjoner

  • Her er de tilbakeringing funksjoner vi skrev prototypene for tidligere. Hver gang gjennom de viktigste loop, vil disse funksjonene bli kalt. Displayet funksjon tegner scenen basert på eventuelle endringer i variabler som er gjort siden forrige samtale. Den specialKeys funksjon tillater oss å samhandle med programmet.
    
    

9) tilbakeringing funksjoner

  • Det siste trinnet i vår første oppsettet er å starte MainLoop. Dette vil huske den viktigste funksjonen til vi lukke programmet for å tillate animasjoner og brukermedvirkning.
     / / Pass kontrollen til GLUT for arrangementer
     glutMainLoop ();
     
     / / Tilbake til OS
     returnere 0;
     
     }
    

Del 2: displayet ()-funksjonen

  • Alt arbeidet med å utarbeide vår kuben vil bli gjort i denne funksjonen. Den generelle ideen bak kuben vår er å trekke alle seks sider individuelt og plassere dem i riktig posisjon.
  • Konseptuelt er hver side kommer til å bli trukket ved å definere de fire hjørnene og la OpenGL koble linjene og fylle det med en farge som vi definerer. Nedenfor er fremgangsmåten for å gjøre dette.

1) glclear ()

  • Det første skrittet vi må ta i denne funksjonen er å fjerne farge og Z-buffer. Uten disse trinnene, kan de gamle tegningene fortsatt være synlig under de nye tegninger og objekter trukket ville ikke være på riktig sted på skjermen.
    
    

2) glbegin () og Glend ()

  • OpenGL definerer objektene som kombinasjoner av ulike polygoner. Bruke glBegin () kommandoen, vi effektivt sette ned en blyant som vil tegne en figur. For å løfte opp blyanten og begynne en ny form, må vi bruke de Glend () glBegin ()> kommandoen. I denne opplæringen vil vi bruke GL_POLYGON å trekke hver side av kuben, men det er mulig å bruke andre parameter alternativer som GL_LINE, GL_QUAD, eller GL_TRIANGLE å lage andre former.
  • Her vil vi starte med forsiden av kuben vår. Senere vil vi legge farge til alle seks sider.
    
    

3) glvertex3f ()

  • Når vi har sagt at vi ønsker å begynne vår polygon, må vi definere hjørnene av objektet. glVertex har flere former avhengig av hva du vil gjøre med objektet.
  • Det første er hvor mange dimensjoner du jobber i. 3 ovenfor i glVertex3f sier at vi trekker i tre dimensjoner. Det er også mulig å arbeide i to eller fire dimensjoner. F ovenfor i glVertex3f sier at vi arbeider med flyttall. Du kan også bruke shorts, heltall eller dobbeltrom.
  • Legg merke til at disse punktene er definert i en mot klokken måte. Dette er ikke veldig viktig i øyeblikket, men når vi begynner å jobbe med belysning, teksturer, og cull-vendt, vil dette bli utrolig viktig så komme i vane med å definere dine poeng mot klokken nå.
  • Nå legger vi til hjørnene mellom glBegin () og Glend () linjer.
    
    

4) glcolor3f ()

  • glColor fungerer på en lignende måte som glVertex. Vi kan definere poeng som shorts, heltall, dobbeltrom, eller flyter. Hver farge har en verdi fra 0 til 1. All 0-tallet gjør et poeng svart og alle 1s vil gjøre det punktet hvitt. Den 3 i glColor3f () refererer til RGB fargesystem uten alfakanal. Alfa av en farge definerer det er åpenhet. For å endre alfa kan man ved bruk glColor4f () med den siste parameter er en verdi fra 0 til 1 for opak til transparent.
  • Når vi kaller glColor3f () hver toppunktet trukket fra det punktet på vil være av den fargen. Derfor, hvis vi ønsker alle fire hjørner å være rød, bare sette farge når som helst før den glVertex3f () kommandoer og alle hjørnene skal være rød.
  • The Front side definert nedenfor viser hvordan du definerer en ny farge for hvert toppunkt. Når vi gjør dette, kan vi se en interessant egenskap av OpenGL farger. Siden hver toppunktet på polygonet har sin egen farge, vil OpenGL automatisk blande fargene! Det neste trinnet vil vise hvordan å tildele fire hjørnene med samme farge.
    
    

5) de andre sidene

  • Jeg oppfordrer deg til å regne ut hva plasseringen av hver toppunktet vil være for de andre fem sider av kuben, men for enkelhet, jeg har beregnet de for deg og har inkludert dem i vår endelige display ()-funksjonen under.
     / / Hvit side - Purple side - Grønne siden - Blå side - Rød side - 
  • Vi ønsker også å legge inn to siste linjene med kode for denne funksjonen. Dette er glFlush (); og glutSwapBuffers (); glFlush ();> som gir oss det doble buffering effekt vi lærte om tidligere.

Del 3: bruker interaktivitet

1) specialkeys ()

  • Vi er nesten ferdig, men i øyeblikket, kan vi tegne en kube, men har ingen måte å rotere det. For å gjøre dette, vil vi lage en specialKeys ()-funksjonen til å tillate oss å trykke på piltastene og rotere kuben!
  • Denne funksjonen er derfor vi erklærte den globale variabler rotate_x og rotate_y. Når vi trykker på høyre og venstre piltastene, vil rotate_y økes eller reduseres med 5 grader. Tilsvarende når vi trykker på henholdsvis opp og ned piltastene, vil rotate_x endres tilsvarende.
     void specialKeys (int nøkkel, int x, int y) {
     
     / / Høyre pil - økning rotasjon ved 5 grader
     if (nøkkel == GLUT_KEY_RIGHT)
     rotate_y + = 5;
     
     / / Venstre pil - nedgang rotasjon ved 5 grader
     else if (nøkkel == GLUT_KEY_LEFT)
     rotate_y - = 5;
     
     else if (nøkkel == GLUT_KEY_UP)
     rotate_x + = 5;
     
     else if (nøkkel == GLUT_KEY_DOWN)
     rotate_x - = 5;
     
     / / Request skjermoppdateringshastighet
     glutPostRedisplay ();
     
     }
    

2) glrotate ()

  • Vår siste uttalelsen er å legge til uttalelse som vil rotere vår objekt. Gå tilbake til skjermen ()-funksjonen og før FRONT side, legge til disse linjene:
    
    
  • Første varsel om at syntaksen til glRotatef () er lik som glColor3f () og glVertex3f (), men alltid krever fire parametere. Den første parameter er graden av rotasjon som skal anvendes. De neste tre parametere definerer hvilken akse for å rotere rundt med den første som x-aksen, andre er på y-aksen, og tredje er langs z-aksen. Akkurat nå trenger vi bare å rotere om x-og y-aksen.
  • Alle transformasjoner som vi skriver i vårt program trenger linjer som ligner på dette. Konseptuelt, tenker vi på dette som roterende vår objekt om x-aksen av mengden definert ved rotate_x og rotere rundt y-aksen ved rotate_y. Men kombinerer OpenGL alle disse utsagnene i en matrise transformasjon. Hver gang vi kaller vises funksjonen, bygger vi en transformasjonsmatrise og glLoadIdentity () forsikrer at vi vil starte med en ny matrise i hver passering.
  • De andre transformasjon funksjoner vi kunne gjelde er glTranslatef () og glScalef (). Disse funksjonene er lik glRotatef () med unntak at de bare tar tre parametere, x-, y-og z-mengder for å oversette eller skalere objektet.
  • For å få den riktige effekten når du søker alle tre transformasjoner til ett objekt, må vi bruke dem i riktig rekkefølge. Alltid skrive dem i den rekkefølgen glTranslate, glRotate, deretter glScale. OpenGL gjelder i hovedsak de transformasjoner i en bottom up måte. For å forstå dette kan du prøve å forestille seg hva en enkel 1X1X1 kube ville se ut med de transformasjoner hvis OpenGL brukt dem fra topp til bunn, og hvis OpenGL brukt dem fra bunn til topp.
  • Legg inn følgende kommandoer for å skalere kuben ved to langs x-aksen, to langs y-aksen, rotere kuben ved 180 grader om y-aksen, og oversette kuben med 0,1 langs x-aksen. Sørg for å ordne disse samt den forrige glRotate () kommandoer i riktig rekkefølge som beskrevet ovenfor. (Hvis du er usikker, har jeg gjort dette i den endelige koden på slutten av opplæringen.)
    
    

Kompilering

  • Den aller siste steget for å fullføre din første OpenGL prosjektet er å kompilere og kjøre koden din. Forutsatt at du bruker gcc som kompilatoren din, kjøre disse kommandoene fra terminalen for å kompilere og teste programmet.
    
    

Endelige koden

  • Det du har det. Din første OpenGL program! Jeg har gitt deg min kildekode under som et referansepunkt.
     / /
     / / Fil: mycube.c
     / / Forfatter: Matt Daisley
     / / Laget: 4/25/2012
     / / Prosjekt: Kildekoden for Lag en kube i OpenGL
     / / Beskrivelse: Oppretter en OpenGL vindu og trekker en 3D-kube
     / / At brukeren kan rotere ved hjelp av piltastene
     / /
     / / Kontroller: Venstre pil - Roter Venstre
     / / Høyre pil - Roter mot høyre
     / / Pil opp - Roter Up
     / / Down Arrow - Roter Down
     
     / / ------------------------------------------------ ----------
     / / Inkluderer
     / / ------------------------------------------------ ----------
     # 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
     
     / / ------------------------------------------------ ----------
     / / Funksjon prototyper
     / / ------------------------------------------------ ----------
     ugyldiggjøre display ();
     void specialKeys ();
     
     / / ------------------------------------------------ ----------
     / / Globale variabler
     / / ------------------------------------------------ ----------
     double rotate_y = 0; 
     double rotate_x = 0;
     
     / / ------------------------------------------------ ----------
     / / Display () tilbakekallsfunksjon
     / / ------------------------------------------------ ----------
     void display () {
     
     / / Clear 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
     
     / / Multi-farget 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 ();
     
     / / Purple 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 () tilbakekallsfunksjon
     / / ------------------------------------------------ ----------
     void specialKeys (int nøkkel, int x, int y) {
     
     / / Høyre pil - økning rotasjon ved 5 grader
     if (nøkkel == GLUT_KEY_RIGHT)
     rotate_y + = 5;
     
     / / Venstre pil - nedgang rotasjon ved 5 grader
     else if (nøkkel == GLUT_KEY_LEFT)
     rotate_y - = 5;
     
     else if (nøkkel == GLUT_KEY_UP)
     rotate_x + = 5;
     
     else if (nøkkel == GLUT_KEY_DOWN)
     rotate_x - = 5;
     
     / / Request skjermoppdateringshastighet
     glutPostRedisplay ();
     
     }
     
     / / ------------------------------------------------ ----------
     / / Main ()-funksjonen
     / / ------------------------------------------------ ----------
     int main (int argc, char * argv []) {
     
     / / Initialiser GLUT og prosess bruker parametere
     glutInit (& argc, argv);
     
     / / Request dobbel bufret ekte farger vindu med Z-buffer
     glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
     
     / / Opprett vindu
     glutCreateWindow ("Awesome Cube");
     
     / / Aktiver Z-buffer dybde test
     glEnable (GL_DEPTH_TEST);
     
     / / Tilbakeringing funksjoner
     glutDisplayFunc (display);
     glutSpecialFunc (specialKeys);
     
     / / Pass kontrollen til GLUT for arrangementer
     glutMainLoop ();
     
     / / Tilbake til OS
     returnere 0;
     
     }