OpenGL je moćan alat za 3D programiranje koji se koristi za crtanje složenih trodimenzionalnih scena iz jednostavnih primitiva. Ovaj članak će vas naučiti kako nacrtati jednostavnu kocku koju možete okretati da biste je vidjeli u tri dimenzije!
Za ovaj projekt trebat će vam uređivač koda i neko znanje programiranja na C -u.
Koraci
1. dio od 3: Početno postavljanje
Korak 1. Instalirajte OpenGL Za početak slijedite ove korake za instaliranje OpenGL -a na vaš sistem
Ako već imate OpenGL, kao i kompatibilan C kompajler, možete preskočiti ovaj korak i prijeći na sljedeći.
Korak 2. Kreirajte dokument
Kreirajte novu datoteku u svom omiljenom uređivaču koda i spremite je kao mycube.c
Korak 3. Dodajte #includes
Ovo su osnovne stavke koje će vam trebati za vaš program. Važno je shvatiti da su za različite operativne sisteme zapravo potrebni različiti sadržaji. Uključite sve ove stavke kako biste bili sigurni da je vaš program svestran i da može raditi za svakog korisnika.
// Uključuje #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Korak 4. Dodajte prototipe funkcija i globalne varijable
Vaš sljedeći korak je deklariranje nekih prototipova funkcija.
// Funkcija Prototipovi void display (); void specialKeys (); // Globalne varijable double rotate_y = 0; dvostruki rotate_x = 0;
Korak 5. Postavite funkciju main ()
int main (int argc, char* argv ) {// Inicijalizacija GLUT -a i obrada korisničkih parametara glutInit (& argc, argv); // Zatražite dvostruki međuspremnik u pravoj boji sa Z-međuspremnikom glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Korak 6. Kreirajte prozor
Sljedeći korak je kreirajte prozor unutar koje ćete nacrtati kocku. U ovom vodiču prozor se zove "Awesome Cube".
// Kreiranje prozora glutCreateWindow ("Awesome Cube");
Korak 7. Omogućite ispitivanje dubine
OpenGL je strog jezik jer ne pretpostavlja da su omogućene posebne funkcije. Da bi se vaš program pravilno prikazao u 3 dimenzije pomoću Z-bafera koji ste ranije pogledali, morate omogući dubinsko ispitivanje. Kako nastavljate s istraživanjem OpenGL-a, otkrit ćete mnoge značajke koje ćete morati omogućiti, uključujući osvjetljenje, teksture, okidanje i mnogo više.
// Omogući test dubine Z-bafera glEnable (GL_DEPTH_TEST);
Korak 8. Dodajte funkcije povratnog poziva
Evo funkcija povratnog poziva za koje ste ranije napisali prototipove. Svaki put kroz glavnu petlju ove funkcije će se pozivati. Funkcija prikaza ponovo iscrtava scenu na osnovu svih promjena varijabli koje su napravljene od prethodnog poziva. Funkcija specialKeys omogućuje nam interakciju s programom.
// Funkcije povratnog poziva glutDisplayFunc (display); glutSpecialFunc (specialKeys);
Korak 9. Pokrenite MainLoop
Ovo će opozvati glavnu funkciju sve dok ne zatvorite program kako biste omogućili animacije i interakciju s korisnikom.
// Prijenos kontrole na GLUT za događaje glutMainLoop (); // Povratak na OS return 0; }
Dio 2 od 3: Funkcija prikaza ()
Korak 1. Shvatite svrhu ove funkcije
Sav posao crtanja kocke bit će obavljen u ovoj funkciji. Opća ideja iza vaše kocke je povući svih šest strana pojedinačno i postaviti ih u odgovarajući položaj.
Konceptualno, svaka strana će biti nacrtana definiranjem četiri ugla i dopuštajući OpenGL -u da poveže linije i ispuni ga bojom koju definirate. U nastavku su navedeni koraci za to
Korak 2. Dodajte glClear ()
Prvi korak koji trebate poduzeti u ovoj funkciji je da to učinite obrišite boju i Z međuspremnik. Bez ovih koraka stari crteži mogu biti vidljivi ispod novih crteža, a nacrtani objekti ne bi bili na ispravnoj lokaciji na ekranu.
void display () {// Očisti ekran i Z-bafer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Korak 3. Dodajte glBegin () i glEnd ()
OpenGL definira objekte kao kombinacije različitih poligona. Koristeći glBegin () naredbom, efikasno odložite olovku koja će nacrtati oblik. Da biste podigli olovku i započeli novi oblik, morate koristiti glEnd () komanda. U ovom vodiču ćete koristiti GL_POLYGON za crtanje svake strane kocke, ali moguće je koristiti i druge opcije parametara kao što su GL_LINE, GL_QUAD ili GL_TRIANGLE za stvaranje drugih oblika.
- Ovdje ćete početi s prednje strane kocke. Kasnije ćete dodati boju na svih 6 strana.
// Višebojna strana - FRONT glBegin (GL_POLYGON); // Vrhovi će se dodati u sljedećem koraku glEnd ();
Korak 4. Dodajte glVertex3f ()
Nakon što ste izjavili da želite započeti svoj poligon, morate to učiniti definirati vrhove objekta. glVertex ima više oblika ovisno o tome što želite učiniti sa svojim objektom.
- Prvi je u koliko dimenzija radite. Gornje 3 u glVertex3f kažu da crtate u 3 dimenzije. Takođe je moguće raditi u 2 ili 4 dimenzije. Gornje slovo f u glVertex3f kaže da radite s brojevima s pomičnim zarezom. Također možete koristiti kratke, cijele brojeve ili parove.
- Primijetite da su ove točke definirane u a suprotno od kazaljke na satu način. Ovo trenutno nije jako važno, ali kada počnete raditi sa osvjetljenjem, teksturama i okretanjem, ovo će postati nevjerojatno važno pa steknite naviku da sada definirate svoje bodove u smjeru suprotnom od kazaljke na satu.
- Dodaj, dodaj vrhove između redova glBegin () i glEnd ().
// Višebojna strana - 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 ();
Korak 5. Dodajte glColor3f ()
glColor radi na sličan način kao glVertex. Možete definirati točke kao kratke, cijele brojeve, dvostruke ili plutajuće. Svaka boja ima vrijednost od 0 do 1. Sve 0 čine tačku crnom, a sve 1 će točku učiniti bijelom. 3 u glColor3f () odnosi se na RGB sistem boja bez alfa kanala. Alfa boje definiše njenu transparentnost. Za promjenu alfa nivoa koristite glColor4f () s posljednjim parametrom od 0 do 1 za neprozirno do prozirno.
- Kada pozovete glColor3f () svaki vrh povučen od te tačke nadalje bit će te boje. Stoga, ako želite da sva četiri vrha budu crvena, samo postavite boju bilo kada prije naredbi glVertex3f () i svi će vrhovi biti crveni.
- Dolje definirana prednja strana pokazuje kako definirati novu boju za svaki vrh. Kada to učinite, možete vidjeti zanimljivo svojstvo OpenGL boja. Budući da svaki vrh poligona ima svoju boju, OpenGL će automatski spojiti boje! Sljedeći korak će pokazati kako dodijeliti četiri vrha iste boje.
// Višebojna strana - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 je crvena glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 je zelena glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 je plavo glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 je ljubičasta glEnd ();
Korak 6. Rukujte drugim stranama
Odredite mjesto svakog vrha za ostalih pet strana kocke, ali radi jednostavnosti, oni su izračunati za vas i uključeni su u final display () funkcija ispod.
// Bijela strana - BACK 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 (); // Ljubičasta strana - DESNO 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 (); // Zelena strana - LIJEVO 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 (); // Plava strana - 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 (); // Crvena strana - 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 (); }
Također želimo dodati dvije zadnje linije koda za ovu funkciju. Ovo su glFlush ();
i glutSwapBuffers ();
koji nam daju dvostruki efekt međuspremnika o kojem ste ranije naučili.
3. dio 3: Interakcija korisnika
Korak 1. Dodajte specialKeys ()
Skoro ste gotovi, ali u ovom trenutku možete nacrtati kocku, ali je ne možete rotirati. Da biste to učinili, hoćete kreiraj specijalne ključeve () funkcija koja nam omogućuje da pritisnemo tipke sa strelicama i rotiramo kocku!
- Ova funkcija je razlog zašto ste proglasili globalne varijable rotate_x i rotate_y. Kada pritisnete desnu i lijevu tipku sa strelicom, rotate_y će se povećati ili smanjiti za 5 stupnjeva. Slično, kada pritisnete tipke sa strelicama gore i dolje, rotate_x će se promijeniti u skladu s tim.
void specialKeys (int key, int x, int y) {// Strelica nadesno - povećanje rotacije za 5 stepeni ako (key == GLUT_KEY_RIGHT) rotate_y += 5; // Strelica ulijevo - smanjite rotaciju za 5 stepeni inače if (key == GLUT_KEY_LEFT) rotate_y - = 5; else if (key == GLUT_KEY_UP) rotate_x += 5; else if (key == GLUT_KEY_DOWN) rotate_x -= 5; // Zatražite ažuriranje prikaza glutPostRedisplay (); }
Korak 2. Dodajte glRotate ()
Vaša posljednja izjava je da dodate izjavu koja će rotirati vaš objekt. Vratite se na funkciju display () i prije FRONT strane dodajte ove redove:
// Poništavanje transformacija glLoadIdentity (); // Rotiraj kada korisnik promijeni rotate_x i rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Višebojna strana - PREDNJA….
Korak 3. Dodajte sljedeće naredbe za skaliranje kocke za 2 duž osi x, 2 duž osi y, zarotirajte kocku za 180 stepeni oko osi y i prevedite kocku za 0,1 duž osi x
Pobrinite se da ove, kao i prethodne naredbe glRotate (), rasporedite ispravnim redoslijedom kako je gore opisano. (Ako niste sigurni, to ćete učiniti u konačnom kodu na kraju vodiča.)
// Ostale transformacije glTranslatef (0.1, 0.0, 0.0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2.0, 2.0, 0.0);
Korak 4. Prevedite i pokrenite svoj kôd
Pod pretpostavkom da koristite gcc kao kompajler, pokrenite ove naredbe sa svog terminala da biste kompajlirali i testirali svoj program.
Na Linuxu: gcc cube.c -o kocka -lglut -lGL./ mycube Na Mac -u: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Na Windows -u: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Korak 5. Provjerite potpuni kod
To bi trebalo biti ovako:
// // Datoteka: mycube.c // Autor: Matt Daisley // Kreirano: 25.4.2012 // Projekt: Izvorni kod za Napravite kocku u OpenGL -u // Opis: Kreira OpenGL prozor i iscrtava 3D kocku/ / Da se korisnik može rotirati pomoću tipki sa strelicama // // Kontrole: strelica ulijevo -rotiranje ulijevo // strelica udesno -rotiranje udesno // strelica gore -rotiranje gore // strelica prema dolje -rotiranje prema dolje // ------ -------------------------------------------------- -// Uključuje // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- --------------------------------------------- // Prototipi funkcija / / ------------------------------------------------- --------- prikaz praznine (); void specialKeys (); // ------------------------------------------------ ---------- // Globalne varijable // ---------------------------------- ------------------------ dvostruko rotiranje_y = 0; dvostruki rotate_x = 0; // ------------------------------------------------ ---------- // display () Funkcija povratnog poziva // ------------------------------- --------------------------- void display () {// Očisti ekran i Z-međuspremnik glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Poništavanje transformacija glLoadIdentity (); // Ostale transformacije // glTranslatef (0.1, 0.0, 0.0); // Nije uključeno // glRotatef (180, 0.0, 1.0, 0.0); // Nije uključeno // Rotiraj kada korisnik promijeni rotate_x i rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotate_y, 0.0, 1.0, 0.0); // Ostale transformacije // glScalef (2.0, 2.0, 0.0); // Nije uključeno // Višebojna strana - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0,5, -0,5, -0,5); // P1 je crvena glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 je zelena glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 je plavo glColor3f (1.0, 0.0, 1.0); glVertex3f (-0,5, -0,5, -0,5); // P4 je ljubičasta glEnd (); // Bijela strana - BACK 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 (); // Ljubičasta strana - DESNO 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 (); // Zelena strana - LIJEVO 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 (); // Plava strana - 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 (); // Crvena strana - 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 () Funkcija povratnog poziva // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Strelica nadesno-povećajte rotaciju za 5 stepen ako (ključ == GLUT_KEY_RIGHT) rotira_y += 5; // Strelica ulijevo - smanjite rotaciju za 5 stepeni inače if (key == GLUT_KEY_LEFT) rotate_y - = 5; else if (key == GLUT_KEY_UP) rotate_x += 5; else if (key == GLUT_KEY_DOWN) rotate_x -= 5; // Zatražite ažuriranje prikaza glutPostRedisplay (); } // ----------------------------------------------- ----------- // funkcija main () // ------------------------------- --------------------------- int main (int argc, char* argv ) {// Inicijalizacija GLUT-a i obrada korisničkih parametara glutInit (& argc, argv); // Zatražite dvostruki međuspremnik u pravoj boji sa Z-međuspremnikom glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Kreiranje prozora glutCreateWindow ("Awesome Cube"); // Omogući test dubine Z-bafera glEnable (GL_DEPTH_TEST); // Funkcije povratnog poziva glutDisplayFunc (display); glutSpecialFunc (specialKeys); // Prijenos kontrole na GLUT za događaje glutMainLoop (); // Povratak na OS return 0; }