OpenGL on võimas 3D programmeerimisvahend, mida kasutatakse lihtsate primitiivide põhjal keerukate kolmemõõtmeliste stseenide joonistamiseks. See artikkel õpetab teile, kuidas joonistada lihtsat kuubikut, mida saate kolmemõõtmeliseks vaatamiseks keerutada!
Selle projekti jaoks vajate koodiredaktorit ja mõningaid teadmisi C programmeerimisest.
Sammud
Osa 1 /3: Esmane seadistamine
Samm 1. OpenGL -i installimine Alustamiseks järgige neid samme OpenGL -i installimiseks oma süsteemi
Kui teil on juba OpenGL ja ühilduv C -kompilaator installitud, võite selle sammu vahele jätta ja järgmise juurde minna.
Samm 2. Looge dokument
Looge uus fail oma lemmikkoodiredaktoris ja salvestage see nimega mycube.c
Samm 3. Lisage #sisaldab
Need on põhiprogrammid, mida vajate oma programmi jaoks. Oluline on mõista, et erinevate operatsioonisüsteemide jaoks on tegelikult vaja erinevaid kaasamisi. Lisage need kõik kindlasti, et teie programm oleks mitmekülgne ja seda saaks kasutada iga kasutaja.
// Sisaldab #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif
Samm 4. Lisage funktsioonide prototüübid ja globaalsed muutujad
Järgmine samm on mõne funktsiooni prototüübi deklareerimine.
// Funktsioon Prototüübid void display (); void specialKeys (); // Globaalsed muutujad double rotate_y = 0; topeltpööramine_x = 0;
Samm 5. Seadistage põhifunktsioon ()
int main (int argc, char* argv ) {// GLUT initsialiseerimine ja kasutaja parameetrite töötlemine glutInit (& argc, argv); // Taotle kahekordselt puhverdatud tõelise värvi akent Z-puhvriga glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Samm 6. Looge aken
Järgmine samm on loo aken mille piires joonistad kuubi. Selles õpetuses nimetatakse akent "Awesome Cube".
// Loo aken glutCreateWindow ("Awesome Cube");
Samm 7. Luba sügavustesti
OpenGL on range keel selle poolest, et see ei eelda erifunktsioonide lubamist. Selleks, et teie programm saaks õigesti kuvada kolmemõõtmelisena, kasutades varem vaadatud Z-puhvrit, peate seda tegema lubada sügavustesti. Kui jätkate OpenGL-i uurimist, avastate paljusid funktsioone, mida peate lubama, sealhulgas valgustust, tekstuure, nägu ja palju muud.
// Luba Z-puhvri sügavuse test glEnable (GL_DEPTH_TEST);
Samm 8. Lisage tagasihelistamisfunktsioonid
Siin on tagasihelistamisfunktsioonid, mille jaoks te varem prototüübid kirjutasite. Neid funktsioone kutsutakse iga kord läbi põhiahela. Ekraanifunktsioon joonistab stseeni ümber, lähtudes muutustest, mis on tehtud pärast eelmist kõnet. Funktsioon specialKeys võimaldab meil programmiga suhelda.
// Tagasihelistamise funktsioonid glutDisplayFunc (kuva); glutSpecialFunc (erivõtmed);
Samm 9. Käivitage MainLoop
See tuletab meelde põhifunktsiooni, kuni sulgete programmi, et võimaldada animatsioone ja kasutajatega suhtlemist.
// Edastage juhtimine GLUT -ile sündmuste jaoks glutMainLoop (); // OS -i naasmine return 0; }
Osa 2/3: Ekraani () funktsioon
Samm 1. Mõistke selle funktsiooni eesmärki
Kõik funktsioonid, mis teie kuubi joonistavad, tehakse selle funktsiooni abil. Kuubi üldine idee on joonistada kõik kuus külge eraldi ja asetada need sobivasse kohta.
Kontseptuaalselt joonistatakse iga külg, määratledes neli nurka ja lastes OpenGLil jooned ühendada ja täita see teie määratud värviga. Allpool on toodud sammud selle tegemiseks
Samm 2. Lisage glClear ()
Esimene samm, mille peate selle funktsiooni täitmiseks tegema, on puhastage värv ja Z -puhver. Ilma nende toiminguteta võivad vanad joonised olla uute jooniste all nähtavad ja joonistatud objektid ei asuks ekraanil õiges kohas.
void display () {// Kustuta ekraan ja Z-puhver glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Samm 3. Lisage glBegin () ja glEnd ()
OpenGL määratleb objektid erinevate hulknurkade kombinatsioonidena. Kasutades glBegin () käsk, panete tõhusalt maha pliiatsi, mis joonistab kuju. Pliiatsi üles tõstmiseks ja uue kuju alustamiseks peate kasutama glEnd () käsk. Selles õpetuses kasutate kuubi iga külje joonistamiseks GL_POLYGON, kuid muude kujundite loomiseks on võimalik kasutada ka muid parameetrite valikuid, näiteks GL_LINE, GL_QUAD või GL_TRIANGLE.
- Siin alustate oma kuubi esiosast. Hiljem lisate värvi kõigile 6 küljele.
// Mitmevärviline külg - FRONT glBegin (GL_POLYGON); // Tipud lisatakse järgmises etapis glEnd ();
Samm 4. Lisage glVertex3f ()
Kui olete öelnud, et soovite oma hulknurka alustada, peate seda tegema määratle tipud objektist. glVertexil on mitu vormi sõltuvalt sellest, mida soovite oma objektiga teha.
- Esimene on see, kui mitmes mõõtmes te töötate. GlVertex3f ülaltoodud 3 ütleb, et joonistate kolmes mõõtmes. Võimalik on töötada ka 2 või 4 mõõdus. F ülaosas glVertex3f ütleb, et töötate ujukomaarvudega. Võite kasutada ka lühikesi, täisarvu või paarismänge.
- Pange tähele, et need punktid on määratletud punktis a vastupäeva viisil. See pole praegu eriti oluline, kuid kui hakkate töötama valgustuse, tekstuuride ja näoga näoga, muutub see uskumatult oluliseks, nii et harjuge oma punkte praegu vastupäeva määratlema.
- Lisage tippude lisamine ridade glBegin () ja glEnd () vahele.
// Mitmevärviline külg - 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 ();
Samm 5. Lisage glColor3f ()
glColor töötab sarnaselt glVertexiga. Punkte saate määratleda lühikeste, täisarvude, kahe- või ujukina. Iga värvi väärtus on 0 kuni 1. Kõik 0 -d muudavad punkti mustaks ja kõik 1 -d punkti valgeks. 3 glColor3f () -is viitab RGB -värvisüsteemile, millel puudub alfa -kanal. Värvi alfa määrab selle läbipaistvuse. Alfa taseme muutmiseks kasutage glColor4f (), kusjuures viimane parameeter on läbipaistmatu kuni läbipaistev väärtus 0 kuni 1.
- Kui helistate glColor3f (), on iga sellest punktist tõmmatud tipp seda värvi. Seega, kui soovite, et kõik neli tippu oleksid punased, määrake lihtsalt värv igal ajal enne glVertex3f () käske ja kõik tipud on punased.
- Allpool määratletud esikülg näitab, kuidas määrata igale tipule uus värv. Seda tehes näete OpenGL -i värvide huvitavat omadust. Kuna igal hulknurga tipul on oma värv, segab OpenGL värvid automaatselt! Järgmine samm näitab, kuidas määrata neli sama värvi tippu.
// Mitmevärviline külg - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 on punane glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 on roheline glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 on sinine glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 on lilla glEnd ();
Samm 6. Käsitsege teisi külgi
Uurige välja, milline on iga tipu asukoht kuue ülejäänud poole jaoks, kuid lihtsuse huvides on need teie jaoks välja arvutatud ja need on lõpliku kuvamise () funktsioon allpool.
// Valge pool - TAGASI 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 külg - PAREM 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 (); // Roheline pool - VASAK 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 (); // Sinine pool - 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 (); // Punane pool - 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 (); }
Samuti tahame selle funktsiooni jaoks lisada kaks viimast koodirida. Need on glFlush ();
ja glutSwapBuffers ();
mis annavad meile varem teada saanud kahekordse puhverdamise efekti.
Osa 3/3: kasutajate interaktiivsus
Samm 1. Lisage specialKeys ()
Olete peaaegu valmis, kuid praegu saate kuubi joonistada, kuid teil pole võimalust seda pöörata. Selleks teete seda loo erilineKeys () funktsioon, mis võimaldab meil nooleklahve vajutada ja kuubi pöörata!
- Selle funktsiooni tõttu deklareerisite globaalsed muutujad rotate_x ja rotate_y. Kui vajutate paremale ja vasakule nooleklahve, suurendatakse või vähendatakse pööramise_y väärtust 5 kraadi võrra. Samamoodi, kui vajutate üles ja alla nooleklahve, muutub rotate_x vastavalt.
void specialKeys (int võti, int x, int y) {// Paremnool - pöörlemise suurendamine 5 kraadi võrra, kui (võti == GLUT_KEY_RIGHT) pöörab_y += 5; // Vasaknool - pöörlemise vähendamine 5 kraadi võrra, kui (võti == GLUT_KEY_LEFT) pöörleb_y - = 5; else if (võti == GLUT_KEY_UP) rotate_x += 5; else if (võti == GLUT_KEY_DOWN) rotate_x -= 5; // Taotle kuvari värskendust glutPostRedisplay (); }
Samm 2. Lisage glRotate ()
Teie viimane avaldus on lisada avaldus, mis pöörab teie objekti. Minge tagasi kuva () funktsiooni juurde ja lisage enne FRONT -külge need read:
// Lähtesta teisendused glLoadIdentity (); // Pööra, kui kasutaja muudab rotate_x ja rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (pöörlemine_y, 0,0, 1,0, 0,0); // Mitmevärviline külg - ESIOSA….
Samm 3. Lisage järgmised käsud, et kuubikut skaleerida 2 võrra piki x-telge, 2 mööda y-telge, pöörata kuubi 180 kraadi y-telje ümber ja teisendada kuup 0,1 võrra mööda x-telge
Järjestage need ja ka eelmised käsud glRotate () õiges järjekorras, nagu eespool kirjeldatud. (Kui te pole kindel, tehakse seda õpetuse lõpus olevas lõplikus koodis.)
// Muud teisendused glTranslatef (0,1, 0,0, 0,0); glRotatef (180, 0,0, 1,0, 0,0); glScalef (2,0, 2,0, 0,0);
Samm 4. Koostage ja käivitage oma kood
Eeldades, et kasutate kompilaatorina gcc -d, käivitage oma programmi kompileerimiseks ja testimiseks need käsud oma terminalist.
Linuxis: gcc cube.c -o kuubik -lglut -lGL./ mycube Macis: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Windowsis: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Samm 5. Kontrollige täielikku koodi
See peaks olema selline:
// // Fail: mycube.c // Autor: Matt Daisley // Loodud: 25.04.2012 // Projekt: OpenGL -i kuubi tegemise lähtekood // Kirjeldus: loob OpenGL -i akna ja joonistab 3D -kuubi/ / Et kasutaja saaks nooleklahvide abil pöörata // // Juhtnupud: vasak nool -pööramine vasakule // paremnool -pööramine paremale // ülesnool -pööramine üles // allanool -pööramine alla // ------ -------------------------------------------------- -// sisaldab // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- -------------------------------------------- // Funktsiooni prototüübid / / ------------------------------------------------- --------- tühi kuva (); void specialKeys (); // ------------------------------------------------ ---------- // Globaalsed muutujad // ---------------------------------- ------------------------ topeltpööre_y = 0; topeltpööramine_x = 0; // ------------------------------------------------ ---------- // kuva () tagasihelistamise funktsioon // ------------------------------- --------------------------- tühi kuva () {// Kustuta ekraan ja Z-puhver glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Lähtesta teisendused glLoadIdentity (); // Muud teisendused // glTranslatef (0,1, 0,0, 0,0); // ei sisaldu // glRotatef (180, 0,0, 1,0, 0,0); // Ei kuulu // Pööra, kui kasutaja muudab rotate_x ja rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0); glRotatef (pöörlemine_y, 0,0, 1,0, 0,0); // Muud teisendused // glScalef (2.0, 2.0, 0.0); // Ei kuulu // Mitmevärviline külg - FRONT glBegin (GL_POLYGON); glColor3f (1,0, 0,0, 0,0); glVertex3f (0,5, -0,5, -0,5); // P1 on punane glColor3f (0,0, 1,0, 0,0); glVertex3f (0,5, 0,5, -0,5); // P2 on roheline glColor3f (0,0, 0,0, 1,0); glVertex3f (-0,5, 0,5, -0,5); // P3 on sinine glColor3f (1,0, 0,0, 1,0); glVertex3f (-0,5, -0,5, -0,5); // P4 on lilla glEnd (); // Valge pool - TAGASI 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 külg - PAREM 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 (); // Roheline pool - VASAK 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 (); // Sinine pool - 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 (); // Punane pool - 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 () tagasihelistamise funktsioon // ------------------------------ ---------------------------- void specialKeys (int võti, int x, int y) {// paremnool-pöörlemise suurendamine 5 võrra kraad if (võti == GLUT_KEY_RIGHT) pöörlema_y += 5; // Vasaknool - pöörlemise vähendamine 5 kraadi võrra, kui (võti == GLUT_KEY_LEFT) pöörleb_y - = 5; else if (võti == GLUT_KEY_UP) rotate_x += 5; else if (võti == GLUT_KEY_DOWN) rotate_x -= 5; // Taotle kuvari värskendust glutPostRedisplay (); } // ------------------------------------------------ ----------- // peamine () funktsioon // ------------------------------- --------------------------- int main (int argc, char* argv ) {// GLUT initsialiseerimine ja kasutaja parameetrite töötlemine glutInit (& argc, argv); // Taotle kahekordse puhverdatud tõelise värvi akent Z-puhveriga glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // Loo aken glutCreateWindow ("Awesome Cube"); // Luba Z-puhvri sügavuse test glEnable (GL_DEPTH_TEST); // Tagasihelistamise funktsioonid glutDisplayFunc (kuva); glutSpecialFunc (erivõtmed); // Edastage juhtimine GLUT -ile sündmuste jaoks glutMainLoop (); // OS -i naasmine return 0; }