OpenGL ir spēcīgs 3D programmēšanas rīks, ko izmanto, lai no vienkāršiem primitīviem zīmētu sarežģītas trīsdimensiju ainas. Šis raksts iemācīs jums uzzīmēt vienkāršu kubu, kuru varat griezt, lai apskatītu trīs dimensijās!
Šim projektam jums būs nepieciešams koda redaktors un dažas zināšanas par C programmēšanu.
Soļi
1. daļa no 3: Sākotnējā iestatīšana
1. solis. OpenGL instalēšana Lai sāktu, rīkojieties šādi, lai instalētu OpenGL savā sistēmā
Ja jums jau ir instalēts OpenGL, kā arī saderīgs C kompilators, varat izlaist šo darbību un doties uz nākamo.
2. darbība. Izveidojiet dokumentu
Izveidojiet jaunu failu savā iecienītākajā koda redaktorā un saglabājiet to kā mycube.c
3. solis. Pievienojiet #ietver
Šie ir pamata pakalpojumi, kas jums būs nepieciešami jūsu programmai. Ir svarīgi apzināties, ka dažādām operētājsistēmām ir nepieciešami dažādi iekļaušanas veidi. Noteikti iekļaujiet to visu, lai nodrošinātu, ka jūsu programma ir daudzpusīga un var darboties jebkuram lietotājam.
// Ietver #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Solis 4. Pievienojiet funkciju prototipus un globālos mainīgos
Nākamais solis ir deklarēt dažus funkciju prototipus.
// Funkcija Prototipi void display (); void specialKeys (); // Globālie mainīgie double rotate_y = 0; divreiz pagriezt_x = 0;
Solis 5. Iestatiet galveno () funkciju
int main (int argc, char* argv ) {// Inicializēt GLUT un apstrādāt lietotāja parametrus glutInit (& argc, argv); // Pieprasīt divkārši buferētu patieso krāsu logu ar Z-buferi glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
6. solis. Izveidojiet logu
Nākamais solis ir izveidojiet logu kurā jūs uzzīmēsit kubu. Šajā apmācībā logu sauc par "Awesome Cube".
// Izveidot logu glutCreateWindow ("Awesome Cube");
7. solis. Iespējot dziļuma pārbaudi
OpenGL ir stingra valoda, jo tā neuzskata, ka ir iespējotas īpašas funkcijas. Lai jūsu programma tiktu pareizi parādīta 3 dimensijās, izmantojot iepriekš apskatīto Z buferi, jums tas jādara iespējot dziļuma pārbaudi. Turpinot pētīt OpenGL, jūs atklāsiet daudzas funkcijas, kas jums būs jāiespējo, ieskaitot apgaismojumu, faktūras, nokaušanu un daudz ko citu.
// Iespējot Z-bufera dziļuma pārbaudi glEnable (GL_DEPTH_TEST);
8. solis. Pievienojiet atzvanīšanas funkcijas
Šeit ir atzvanīšanas funkcijas, kurām iepriekš rakstījāt prototipus. Katru reizi, izmantojot galveno cilpu, šīs funkcijas tiks izsauktas. Displeja funkcija pārzīmē ainu, pamatojoties uz izmaiņām mainīgajos, kas tika veiktas kopš iepriekšējā zvana. Funkcija specialKeys ļauj mums mijiedarboties ar programmu.
// Atzvanīšanas funkcijas glutDisplayFunc (displejs); glutSpecialFunc (specialKeys);
9. solis. Sāciet MainLoop
Tādējādi tiks atsaukta galvenā funkcija, līdz aizvērsiet programmu, lai varētu veikt animācijas un lietotāja mijiedarbību.
// Pārejiet kontroli uz GLUT notikumiem glutMainLoop (); // Atgriezties pie OS return 0; }
2. daļa no 3: Displeja () funkcija
Solis 1. Izprotiet šīs funkcijas mērķi
Viss kuba zīmēšanas darbs tiks veikts šajā funkcijā. Jūsu kuba vispārējā ideja ir uzzīmēt visas sešas puses atsevišķi un novietot tās atbilstošā vietā.
Konceptuāli katra puse tiks zīmēta, nosakot četrus stūrus un ļaujot OpenGL savienot līnijas un aizpildīt to ar jūsu definētu krāsu. Tālāk ir norādītas darbības, kā to izdarīt
2. solis. Pievienojiet glClear ()
Pirmais solis, kas jums jāveic, veicot šo funkciju, ir notīriet krāsu un Z buferi. Bez šīm darbībām vecie zīmējumi joprojām var būt redzami zem jaunajiem zīmējumiem, un uzzīmētie objekti neatrodas pareizajā ekrāna vietā.
void display () {// Notīrīt ekrānu un Z-buferi glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
3. solis. Pievienojiet glBegin () un glEnd ()
OpenGL definē objektus kā dažādu daudzstūru kombinācijas. Izmantojot glBegin () komandu, jūs efektīvi noliekat zīmuli, kas uzzīmēs formu. Lai paceltu zīmuli un sāktu jaunu formu, jāizmanto glEnd () komandu. Šajā apmācībā jūs izmantosit GL_POLYGON, lai uzzīmētu katru kuba malu, bet citu formu izveidošanai ir iespējams izmantot citas parametru opcijas, piemēram, GL_LINE, GL_QUAD vai GL_TRIANGLE.
- Šeit jūs sāksit ar sava kuba priekšpusi. Vēlāk jūs pievienosit krāsu visām 6 pusēm.
// Daudzkrāsaina puse - FRONT glBegin (GL_POLYGON); // Virsotnes tiks pievienotas nākamajā solī glEnd ();
4. solis. Pievienojiet glVertex3f ()
Kad esat paziņojis, ka vēlaties sākt savu daudzstūri, jums tas jādara definēt virsotnes no objekta. glVertex ir vairākas formas atkarībā no tā, ko vēlaties darīt ar savu objektu.
- Pirmais ir tas, cik daudzās dimensijās jūs strādājat. GlVertex3f iepriekš minētie 3 norāda, ka zīmējat 3 dimensijās. Ir iespējams strādāt arī 2 vai 4 dimensijās. Iepriekš glVertex3f esošais f saka, ka jūs strādājat ar peldošā komata skaitļiem. Varat arī izmantot šortus, veselus skaitļus vai dubultspēles.
- Ņemiet vērā, ka šie punkti ir definēti a pretpulksteņrādītājvirzienā veidā. Šobrīd tas nav ļoti svarīgi, bet, kad jūs sāksit strādāt ar apgaismojumu, faktūrām un nobīdi, tas kļūs neticami svarīgs, tāpēc pieradiniet savus punktus definēt pretēji pulksteņrādītāja virzienam.
- Pievienojiet pievienojiet virsotnes starp glBegin () un glEnd () līnijām.
// Daudzkrāsaina puse - 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 ();
5. solis. Pievienojiet glColor3f ()
glColor darbojas līdzīgi kā glVertex. Punktus varat definēt kā šortus, veselus skaitļus, dubultspēles vai pludiņus. Katras krāsas vērtība ir no 0 līdz 1. Visi 0 padara punktu melnu, bet visi 1 - punktu baltu. 3 glColor3f () norāda uz RGB krāsu sistēmu bez alfa kanāla. Krāsas alfa nosaka tās caurspīdīgumu. Lai mainītu alfa līmeni, izmantojiet glColor4f () ar pēdējo parametru no 0 līdz 1, lai necaurspīdīgs vai caurspīdīgs.
- Zvanot uz glColor3f (), katra virsotne, kas zīmēta no šī brīža, būs tādā krāsā. Tāpēc, ja vēlaties, lai visas četras virsotnes būtu sarkanas, vienkārši iestatiet krāsu jebkurā laikā pirms glVertex3f () komandām, un visas virsotnes būs sarkanas.
- Tālāk definētā priekšējā puse parāda, kā katrai virsotnei definēt jaunu krāsu. To darot, jūs varat redzēt interesantu OpenGL krāsu īpašību. Tā kā katrai daudzstūra virsotnei ir sava krāsa, OpenGL automātiski sajauks krāsas! Nākamais solis parādīs, kā piešķirt četras vienādas krāsas virsotnes.
// Daudzkrāsaina puse - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 ir sarkans glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 ir zaļa glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 ir zils glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 ir purpursarkans glEnd ();
6. solis. Rokturiet pārējās puses
Noskaidrojiet, kāda būs katra virsotnes atrašanās vieta pārējām piecām kuba pusēm, bet vienkāršības labad tās ir aprēķinātas jums un ir iekļautas pēdējā displeja () funkcija zemāk.
// Baltā puse - 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 (); // Violeta puse - RIGHT 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 (); // Zaļā puse - LEFT 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 (); // Zilā puse - 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 (); // Sarkanā puse - 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 (); }
Mēs arī vēlamies šai funkcijai pievienot divas pēdējās koda rindas. Šie ir glFlush ();
un glutSwapBuffers ();
kas mums nodrošina dubulto buferizācijas efektu, par kuru uzzinājāt iepriekš.
3. daļa no 3: Lietotāja mijiedarbība
1. solis. Pievienojiet specialKeys ()
Jūs esat gandrīz pabeidzis, bet šobrīd jūs varat uzzīmēt kubu, bet nevarat to pagriezt. Lai to izdarītu, jums būs izveidot īpašu taustiņu () funkcija, kas ļauj mums nospiest bulttaustiņus un pagriezt kubu!
- Šī funkcija ir iemesls, kāpēc jūs deklarējāt globālos mainīgos rotate_x un rotate_y. Nospiežot labo un kreiso bulttaustiņu, rotate_y tiks palielināts vai samazināts par 5 grādiem. Līdzīgi, nospiežot augšup un lejup vērstos bulttaustiņus, rotate_x attiecīgi mainīsies.
void specialKeys (int taustiņš, int x, int y) {// labā bultiņa - palieliniet rotāciju par 5 grādiem, ja (taustiņš == GLUT_KEY_RIGHT) rotate_y += 5; // Kreisā bultiņa - samazināt rotāciju par 5 grādiem, ja (taustiņš == GLUT_KEY_LEFT) rotate_y - = 5; cits if (taustiņš == GLUT_KEY_UP) rotēt_x += 5; cits if (taustiņš == GLUT_KEY_DOWN) rotate_x -= 5; // Pieprasīt displeja atjauninājumu glutPostRedisplay (); }
2. solis. Pievienojiet glRotate ()
Jūsu pēdējais paziņojums ir pievienot paziņojumu, kas pagriezīs jūsu objektu. Atgriezieties displeja () funkcijā un pirms priekšpuses pievienojiet šīs rindas:
// Atiestatīt transformācijas glLoadIdentity (); // Pagriezt, kad lietotājs maina rotate_x un rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotēt_y, 0,0, 1,0, 0,0); // Daudzkrāsaina puse - FRONT….
3. solis. Pievienojiet šādas komandas, lai mērogotu kubu par 2 pa x asi, 2 pa y asi, pagrieztu kubu par 180 grādiem ap y asi un pārvērstu kubu par 0,1 pa x asi
Noteikti sakārtojiet šīs, kā arī iepriekšējās glRotate () komandas pareizajā secībā, kā aprakstīts iepriekš. (Ja neesat pārliecināts, tas tiek darīts galīgajā kodā apmācības beigās.)
// Citas transformācijas glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);
Solis 4. Apkopojiet un palaidiet savu kodu
Pieņemot, ka kā kompilatoru izmantojat gcc, palaidiet šīs komandas no sava termināļa, lai apkopotu un pārbaudītu savu programmu.
Operētājsistēmā Linux: gcc cube.c -o kubs -lglut -lGL./ mycube Operētājsistēmā Mac: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Operētājsistēmā Windows: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
5. solis. Pārbaudiet pilnu kodu
Tam vajadzētu būt šādam:
// // Fails: mycube.c // Autors: Matt Daisley // Izveidots: 25.04.2012 // Projekts: Avota kods Izveidot kubu OpenGL // Apraksts: izveido OpenGL logu un uzzīmē 3D kubu/ / Lai lietotājs varētu pagriezties, izmantojot bulttaustiņus // // Vadīklas: kreisā bultiņa -pagriezt pa kreisi // labā bultiņa -pagriezt pa labi // augšupvērstā bultiņa -pagriezt uz augšu // lejupvērstā bultiņa -pagriezt uz leju // ------ -------------------------------------------------- -- // Ietilpst // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- -------------------------------------------- // Funkciju prototipi / / ------------------------------------------------- --------- tukšs displejs (); void specialKeys (); // ------------------------------------------------ ---------- // Globālie mainīgie // ---------------------------------- ------------------------ dubultā rotācija_y = 0; divreiz pagriezt_x = 0; // ------------------------------------------------ ---------- // display () atzvanīšanas funkcija // ------------------------------- --------------------------- void display () {// Clear screen and Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Atiestatīt transformācijas glLoadIdentity (); // Citas pārvērtības // glTranslatef (0,1, 0,0, 0,0); // nav iekļauts // glRotatef (180, 0,0, 1,0, 0,0); // Nav iekļauts // Pagriezt, kad lietotājs maina rotate_x un rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (rotēt_y, 0,0, 1,0, 0,0); // Citas pārvērtības // glScalef (2.0, 2.0, 0.0); // Nav iekļauts // Daudzkrāsaina puse - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 ir sarkans glColor3f (0.0, 1.0, 0.0); glVertex3f (0,5, 0,5, -0,5); // P2 ir zaļa glColor3f (0.0, 0.0, 1.0); glVertex3f (-0,5, 0,5, -0,5); // P3 ir zils glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 ir purpursarkans glEnd (); // Baltā puse - 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 (); // Violeta puse - RIGHT 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 (); // Zaļā puse - LEFT 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 (); // Zilā puse - 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 (); // Sarkanā puse - 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 () atzvanīšanas funkcija // ------------------------------ ---------------------------- void specialKeys (int taustiņš, int x, int y) {// labā bultiņa-palielināt rotāciju par 5 grāds, ja (taustiņš == GLUT_KEY_RIGHT) rotēt_g += 5; // Kreisā bultiņa - samazināt rotāciju par 5 grādiem, ja (taustiņš == GLUT_KEY_LEFT) rotate_y - = 5; cits if (taustiņš == GLUT_KEY_UP) rotēt_x += 5; cits if (taustiņš == GLUT_KEY_DOWN) rotate_x -= 5; // Pieprasīt displeja atjauninājumu glutPostRedisplay (); } // ----------------------------------------------- ----------- // galvenā () funkcija // ------------------------------- --------------------------- int main (int argc, char* argv ) {// Inicializēt GLUT un apstrādāt lietotāja parametrus glutInit (& argc, argv); // Pieprasīt divkārši buferētu patieso krāsu logu ar Z-buferi glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Izveidot logu glutCreateWindow ("Awesome Cube"); // Iespējot Z-bufera dziļuma pārbaudi glEnable (GL_DEPTH_TEST); // Atzvanīšanas funkcijas glutDisplayFunc (displejs); glutSpecialFunc (specialKeys); // Pārejiet kontroli uz GLUT notikumiem glutMainLoop (); // Atgriezties pie OS return 0; }