OpenGL on tehokas 3D-ohjelmointityökalu, jota käytetään piirtämään monimutkaisia kolmiulotteisia kohtauksia yksinkertaisista primitiiveistä. Tämä artikkeli opettaa sinulle kuinka piirtää yksinkertainen kuutio, jonka voit pyörittää katsellaksesi kolmea ulottuvuutta!
Tätä projektia varten tarvitset koodieditorin ja jonkin verran tietoa C -ohjelmoinnista.
Askeleet
Osa 1/3: Alkuasetukset
Vaihe 1. OpenGL: n asentaminen Aloita asentamalla OpenGL järjestelmään seuraavasti
Jos sinulla on jo OpenGL ja yhteensopiva C -kääntäjä, voit ohittaa tämän vaiheen ja siirtyä seuraavaan.
Vaihe 2. Luo asiakirja
Luo uusi tiedosto suosikkikoodieditorissasi ja tallenna se nimellä mycube.c
Vaihe 3. Lisää #sisältö
Nämä ovat perussisältöjä, joita tarvitset ohjelmaan. On tärkeää ymmärtää, että eri käyttöjärjestelmille tarvitaan todella erilaisia sisältöjä. Muista sisällyttää kaikki nämä varmistaaksesi, että ohjelmasi on monipuolinen ja voidaan ajaa kaikille käyttäjille.
// Sisältää #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Vaihe 4. Lisää funktion prototyyppejä ja globaaleja muuttujia
Seuraava askel on julkaista joitakin toimintojen prototyyppejä.
// Toiminto Prototyypit tyhjä näyttö (); void specialKeys (); // Globaalimuuttujat double rotate_y = 0; kaksoiskierrä_x = 0;
Vaihe 5. Määritä päätoiminto ()
int main (int argc, char* argv ) {// Alusta GLUT ja käsittele käyttäjän parametrit glutInit (& argc, argv); // Pyydä kaksoispuskuroitu todellinen väri-ikkuna Z-puskurilla glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Vaihe 6. Luo ikkuna
Seuraava askel on luo ikkuna johon piirtää kuution. Tässä opetusohjelmassa ikkunan nimi on "Mahtava kuutio".
// Luo ikkuna glutCreateWindow ("Mahtava kuutio");
Vaihe 7. Ota syvyystesti käyttöön
OpenGL on tiukka kieli, koska se ei oleta, että erityisominaisuudet ovat käytössä. Jotta ohjelmasi näkyisi oikein kolmiulotteisena käyttämällä aiemmin tarkasteltavaa Z-puskuria, sinun on tehtävä se ottaa syvyystestin käyttöön. Kun jatkat OpenGL: n tutkimista, huomaat monia ominaisuuksia, jotka sinun on otettava käyttöön, mukaan lukien valaistus, tekstuurit, teurastus ja paljon muuta.
// Salli Z-puskurin syvyystesti glEnable (GL_DEPTH_TEST);
Vaihe 8. Lisää takaisinsoittotoimintoja
Tässä ovat takaisinsoittotoiminnot, joita varten kirjoitit prototyypit aiemmin. Näitä toimintoja kutsutaan joka kerta pääsilmukan kautta. Näyttötoiminto piirtää kohtauksen uudelleen perustuen muutoksiin, jotka on tehty edellisen puhelun jälkeen. SpecialKeys -toiminnon avulla voimme olla vuorovaikutuksessa ohjelman kanssa.
// Takaisinsoittotoiminnot glutDisplayFunc (näyttö); glutSpecialFunc (specialKeys);
Vaihe 9. Käynnistä MainLoop
Tämä palauttaa päätoiminnon muistiin, kunnes suljet ohjelman animaatioiden ja käyttäjien vuorovaikutuksen sallimiseksi.
// Ohjaa GLUT tapahtumille glutMainLoop (); // Paluu käyttöjärjestelmään return 0; }
Osa 2/3: Näyttö () -toiminto
Vaihe 1. Ymmärrä tämän toiminnon tarkoitus
Kaikki kuution piirtotyöt tehdään tässä toiminnossa. Kuution yleinen idea on piirtää kaikki kuusi sivua yksitellen ja sijoittaa ne oikeaan paikkaan.
Käsitteellisesti jokainen puoli piirretään määrittelemällä neljä kulmaa ja antamalla OpenGL: n yhdistää linjat ja täyttämällä se valitsemallasi värillä. Alla on vaiheet tämän tekemiseen
Vaihe 2. Lisää glClear ()
Ensimmäinen askel, joka sinun on suoritettava tässä toiminnossa, on tyhjennä väri ja Z -puskuri. Ilman näitä vaiheita vanhat piirustukset voivat silti näkyä uusien piirustusten alla ja piirretyt objektit eivät ole oikeassa paikassa näytöllä.
void display () {// Tyhjennä näyttö ja Z-puskuri glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Vaihe 3. Lisää glBegin () ja glEnd ()
OpenGL määrittelee objektit eri monikulmioiden yhdistelmiksi. Käyttämällä glBegin () komento, laitat tehokkaasti kynän, joka piirtää muodon. Jos haluat nostaa kynän ylös ja aloittaa uuden muodon, käytä glEnd () komento. Tässä opetusohjelmassa piirrät kuution jokaisen sivun GL_POLYGONilla, mutta voit käyttää muita parametrivaihtoehtoja, kuten GL_LINE, GL_QUAD tai GL_TRIANGLE muiden muotojen luomiseen.
- Tässä aloitat kuution etupuolelta. Myöhemmin lisäät väriä kaikille 6 puolelle.
// Monivärinen puoli - FRONT glBegin (GL_POLYGON); // Pisteet lisätään seuraavassa vaiheessa glEnd ();
Vaihe 4. Lisää glVertex3f ()
Kun olet ilmoittanut, että haluat aloittaa monikulmion, sinun on tehtävä se määrittele kärkipisteet esineestä. glVertexillä on useita muotoja riippuen siitä, mitä haluat tehdä objektillesi.
- Ensimmäinen on kuinka monessa ulottuvuudessa työskentelet. GlVertex3f: n yllä oleva 3 kertoo, että piirrät kolmiulotteisesti. On myös mahdollista työskennellä 2 tai 4 ulottuvuudessa. GlVertex3f: n yllä oleva f kertoo, että käytät liukulukuisia numeroita. Voit myös käyttää shortseja, kokonaislukuja tai nelinpeliä.
- Huomaa, että nämä kohdat on määritelty kohdassa a vastapäivään tavalla. Tällä ei ole kovin suurta merkitystä tällä hetkellä, mutta kun aloitat työskentelyn valaistuksen, tekstuurien ja teurastamisen kanssa, siitä tulee uskomattoman tärkeää, joten ota tapana määritellä pisteesi vastapäivään.
- Lisää lisää pisteet glBegin () - ja glEnd () -rivien väliin.
// Monivärinen puoli - 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 ();
Vaihe 5. Lisää glColor3f ()
glColor toimii samalla tavalla kuin glVertex. Voit määrittää pisteitä lyhyiksi, kokonaisluvuiksi, tuplaksi tai kellukkeiksi. Jokaisella värillä on arvo 0 - 1. Kaikki 0 tekevät pisteestä mustan ja kaikki 1 tekee pisteestä valkoisen. 3 in glColor3f () viittaa RGB -värijärjestelmään ilman alfa -kanavaa. Värin alfa määrittää sen läpinäkyvyyden. Jos haluat muuttaa alfa -tasoa, käytä glColor4f () -toimintoa ja viimeisen parametrin arvo on 0–1, jotta läpinäkymätön tai läpinäkyvä.
- Kun kutsut glColor3f (): a, jokainen siitä pisteestä piirretty kärki on samaa väriä. Siksi, jos haluat, että kaikki neljä kärkeä ovat punaisia, aseta väri milloin tahansa ennen glVertex3f () -komentoja ja kaikki kärkipisteet ovat punaisia.
- Alla määritelty etupuoli näyttää uuden värin määrittämisen kullekin kärkipisteelle. Kun teet tämän, näet mielenkiintoisen ominaisuuden OpenGL -väreistä. Koska monikulmion jokaisella kärjellä on oma väri, OpenGL sekoittaa värit automaattisesti! Seuraavassa vaiheessa näytetään, kuinka neljä samanväristä kärkeä annetaan.
// Monivärinen puoli - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 on punainen glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 on vihreä glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 on sininen glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 on violetti glEnd ();
Vaihe 6. Käsittele muita sivuja
Selvitä, mikä on kunkin kärjen sijainti kuution viidellä muulla puolella, mutta yksinkertaisuuden vuoksi nämä on laskettu sinulle ja ne sisältyvät viimeisen näytön () toiminto alla.
// Valkoinen puoli - TAKAISIN 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 (); // Violetti puoli - OIKEA 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 (); // Vihreä puoli - VASEN 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 (); // Sininen puoli - 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 (); // Punainen puoli - ALAS 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 (); }
Haluamme myös lisätä kaksi viimeistä koodiriviä tälle toiminnolle. Nämä ovat glFlush ();
ja glutSwapBuffers ();
jotka antavat meille kaksinkertaisen puskurointivaikutuksen, josta opit aiemmin.
Osa 3/3: Käyttäjien vuorovaikutteisuus
Vaihe 1. Lisää specialKeys ()
Olet melkein valmis, mutta tällä hetkellä voit piirtää kuution, mutta sinulla ei ole mahdollisuutta kiertää sitä. Voit tehdä tämän luo erikoisavaimet () toiminto, jonka avulla voimme painaa nuolinäppäimiä ja kiertää kuutiota!
- Tämän funktion vuoksi olet ilmoittanut globaalimuuttujat rotate_x ja rotate_y. Kun painat oikeaa ja vasenta nuolinäppäintä, rotate_y kasvaa tai pienenee 5 astetta. Samoin, kun painat ylä- ja alanuolinäppäimiä, rotate_x muuttuu vastaavasti.
void specialKeys (int -näppäin, int x, int y) {// Oikea nuoli - lisää kiertoa 5 astetta, jos (avain == GLUT_KEY_RIGHT) rotate_y += 5; // Vasen nuoli - vähennä kiertoa 5 astetta, jos (näppäin == GLUT_KEY_LEFT) rotate_y - = 5; else if (avain == GLUT_KEY_UP) rotate_x += 5; else if (avain == GLUT_KEY_DOWN) rotate_x -= 5; // Pyydä näytön päivitystä glutPostRedisplay (); }
Vaihe 2. Lisää glRotate ()
Viimeinen lauseesi on lisätä lauseke, joka kääntää objektiasi. Palaa takaisin näyttö () -toimintoon ja lisää seuraavat rivit FRONT -puolen eteen:
// Nollaa muunnokset glLoadIdentity (); // Kierrä, kun käyttäjä muuttaa rotate_x ja rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (kierrä_y, 0,0, 1,0, 0,0); // Monivärinen puoli - ETU….
Vaihe 3. Lisää seuraavat komennot skaalataksesi kuutiota 2 x-akselia pitkin, 2 y-akselia pitkin, kiertämällä kuutiota 180 astetta y-akselin ympäri ja kääntämällä kuutiota 0,1 x-akselia pitkin
Varmista, että järjestät nämä sekä edelliset glRotate () -komennot oikeaan järjestykseen yllä kuvatulla tavalla. (Jos olet epävarma, tämä tehdään opetusohjelman lopussa olevassa lopullisessa koodissa.)
// Muut muunnokset glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);
Vaihe 4. Käännä ja suorita koodisi
Olettaen, että käytät gcc: tä kääntäjänä, suorita nämä komennot päätelaitteestasi ohjelman kääntämiseksi ja testaamiseksi.
Linuxissa: gcc cube.c -o kuutio -lglut -lGL./ mycube Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Vaihe 5. Tarkista täydellinen koodi
Sen pitäisi olla näin:
// // Tiedosto: mycube.c // Tekijä: Matt Daisley // Luotu: 25.4.2012 // Projekti: Lähdekoodi Make a Cube in OpenGL // Kuvaus: Luo OpenGL -ikkunan ja piirtää 3D -kuution/ / Käyttäjä voi kiertää nuolinäppäimillä // // Säätimet: Vasen nuoli -Kierrä vasemmalle // Oikea nuoli -Kierrä oikealle // Ylänuoli -Kierrä ylös // Alanuoli -Kierrä alas // ------ -------------------------------------------------- -// Sisältää // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- -------------------------------------------- // Toimintojen prototyypit / / ------------------------------------------------- --------- tyhjä näyttö (); void specialKeys (); // ------------------------------------------------ ---------- // Globaalimuuttujat // ---------------------------------- ------------------------ kaksinkertainen kierto_y = 0; kaksoiskierrä_x = 0; // ------------------------------------------------ ---------- // display () callback-toiminto // ------------------------------- --------------------------- tyhjä näyttö () {// Tyhjennä näyttö ja Z-puskuri glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Nollaa muunnokset glLoadIdentity (); // Muut muunnokset // glTranslatef (0,1, 0,0, 0,0); // ei sisälly // glRotatef (180, 0,0, 1,0, 0,0); // Ei sisälly // Kierrä, kun käyttäjä muuttaa rotate_x ja rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (kierrä_y, 0,0, 1,0, 0,0); // Muut muunnokset // glScalef (2.0, 2.0, 0.0); // Ei sisälly // Monivärinen puoli - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 on punainen glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 on vihreä glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 on sininen glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 on violetti glEnd (); // Valkoinen puoli - TAKAISIN 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 (); // Violetti puoli - OIKEA 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 (); // Vihreä puoli - VASEN 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 (); // Sininen puoli - 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 (); // Punainen puoli - ALAS 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 () takaisinsoittotoiminto // ------------------------------ ---------------------------- void specialKeys (int-näppäin, int x, int y) {// Oikea nuoli-lisää kiertoa 5 aste jos (avain == GLUT_KEY_RIGHT) kierrä_y += 5; // Vasen nuoli - vähennä kiertoa 5 astetta, jos (näppäin == GLUT_KEY_LEFT) rotate_y - = 5; else if (avain == GLUT_KEY_UP) rotate_x += 5; else if (avain == GLUT_KEY_DOWN) rotate_x -= 5; // Pyydä näytön päivitystä glutPostRedisplay (); } // ----------------------------------------------- ----------- // päätoiminto // ------------------------------- --------------------------- int main (int argc, char* argv ) {// Alusta GLUT ja käsittele käyttäjän parametrit glutInit (& argc, argv); // Pyydä kaksoispuskuroitu todellinen väri-ikkuna Z-puskurilla glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Luo ikkuna glutCreateWindow ("Mahtava kuutio"); // Salli Z-puskurin syvyystesti glEnable (GL_DEPTH_TEST); // Takaisinsoittotoiminnot glutDisplayFunc (näyttö); glutSpecialFunc (specialKeys); // Ohjaa GLUT tapahtumille glutMainLoop (); // Paluu käyttöjärjestelmään return 0; }