OpenGL, sadə primitivlərdən mürəkkəb üçölçülü səhnələr çəkmək üçün istifadə olunan güclü bir 3D proqramlaşdırma vasitəsidir. Bu məqalə, üç ölçüdə görmək üçün fırlaya biləcəyiniz sadə bir kub çəkməyi öyrədəcək!
Bu layihə üçün bir kod redaktoruna və C proqramlaşdırma haqqında bir az bilgiyə ehtiyacınız olacaq.
Addımlar
3 -dən 1 -ci hissə: İlk Quraşdırma
Addım 1. OpenGL qurun Başlamaq üçün sisteminizə OpenGL qurmaq üçün bu addımları izləyin
Zaten OpenGL və uyğun bir C kompilyatoru qurmusunuzsa, bu addımı atıb sonrakı mərhələyə keçə bilərsiniz.
Addım 2. Sənədi yaradın
Sevdiyiniz kod redaktorunda yeni bir fayl yaradın və mycube.c olaraq qeyd edin
Addım 3. #daxildir
Proqramınız üçün ehtiyac duyacağınız əsas şeylər bunlardır. Fərqli əməliyyat sistemləri üçün lazım olan fərqli komponentlərin olduğunu başa düşmək vacibdir. Proqramınızın çox yönlü olmasını və hər hansı bir istifadəçi üçün işləyə biləcəyini təmin etmək üçün bunların hamısını daxil etməyinizə əmin olun.
// Daxildir #daxil edin #daxil edin #daxil edin #GL_GLEXT_PROTOTYPES təyin edin #ifdef _APPLE_ #əlavə edin #başqa #daxil edin #endif
Addım 4. Funksiya prototipləri və qlobal dəyişənlər əlavə edin
Növbəti addımınız bəzi funksiya prototiplərini elan etməkdir.
// Function Prototypes void display (); void specialKeys (); // Qlobal Dəyişənlər ikiqat rotate_y = 0; ikiqat rotate_x = 0;
Addım 5. main () funksiyasını qurun
int main (int argc, char* argv ) {// GLUT -u işə salın və istifadəçi parametrlərini işləyin glutInit (& argc, argv); // Z-tamponlu glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) ilə ikiqat tamponlu əsl rəngli pəncərə istəyin;
Addım 6. Pəncərəni yaradın
Növbəti addım etməkdir pəncərə yaradın içərisində kub çəkəcəksən. Bu təlimatda, pəncərə "Awesome Cube" adlanır.
// Pəncərə yaradın glutCreateWindow ("Zəhmli Küp");
Addım 7. Dərinlik testini aktiv edin
OpenGL, heç bir xüsusi xüsusiyyətin aktiv olduğunu düşünmədiyi üçün ciddi bir dildir. Proqramınızın əvvəllər baxdığınız Z-tamponundan istifadə edərək 3 ölçüdə düzgün göstərilməsi üçün bunu etməlisiniz dərinlik testini aktiv edin. OpenGL-i araşdırmağa davam edərkən, işıqlandırma, toxumalar, cull-üzləşmə və daha çox daxil olmaqla, aktivləşdirməyiniz lazım olan bir çox xüsusiyyətləri kəşf edəcəksiniz.
// Z-tampon dərinlik testini aktivləşdir glEnable (GL_DEPTH_TEST);
Addım 8. Geri çağırma funksiyalarını əlavə edin
Daha əvvəl prototiplərini yazdığınız geri çağırma funksiyaları. Hər dəfə əsas döngədə bu funksiyalar çağırılacaq. Ekran funksiyası, əvvəlki zəngdən bəri edilən dəyişənlərə edilən hər hansı bir dəyişikliyə əsaslanaraq səhnəni yenidən tərtib edir. SpecialKeys funksiyası proqramla qarşılıqlı əlaqədə olmağımıza imkan verir.
// Geri çağırma funksiyaları glutDisplayFunc (ekran); glutSpecialFunc (xüsusi düymələr);
Addım 9. MainLoop -u işə salın
Proqramı animasiyalara və istifadəçi qarşılıqlı əlaqəsinə icazə vermək üçün bağlayana qədər bu, əsas funksiyanı xatırladır.
// glutMainLoop () hadisələri üçün nəzarəti GLUT -a keçirin; // Əməliyyat sisteminə qayıt 0; }
3 -dən 2 -ci hissə: Ekran () funksiyası
Addım 1. Bu funksiyanın məqsədini anlayın
Kubunuzun çəkilməsi ilə bağlı bütün işlər bu funksiyada yerinə yetiriləcəkdir. Küpünüzün arxasındakı ümumi fikir, altı tərəfi ayrı -ayrılıqda çəkmək və onları uyğun mövqeyə qoymaqdır.
Konseptual olaraq, hər tərəf dörd guşəni təyin edərək və OpenGL -in xətləri birləşdirməsinə və təyin etdiyiniz bir rənglə doldurmasına icazə verərək çəkiləcək. Bunu etmək üçün addımlar aşağıda verilmişdir
Addım 2. glClear () əlavə edin
Bu funksiyanı yerinə yetirməyiniz lazım olan ilk addım budur rəngi və Z tamponunu təmizləyin. Bu addımlar olmadan, köhnə təsvirlər hələ də yeni rəsmlərin altında görünə bilər və çəkilmiş obyektlər ekranda düzgün yerdə olmazdı.
void display () {// Clear ekran və Z-tampon glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Addım 3. glBegin () və glEnd () əlavə edin
OpenGL, obyektləri fərqli çoxbucaqlıların birləşməsi olaraq təyin edir. İstifadə edərək glBegin () əmr etsəniz, təsirli bir şəkil çəkəcək bir qələm qoydunuz. Qələmi yuxarı qaldırıb yeni bir forma başlamaq üçün istifadə etməlisiniz glEnd () əmr. Bu təlimatda kubun hər tərəfini çəkmək üçün GL_POLYGON istifadə edəcəksiniz, ancaq digər formalar yaratmaq üçün GL_LINE, GL_QUAD və ya GL_TRIANGLE kimi digər parametr seçimlərindən istifadə etmək mümkündür.
- Burada kubunuzun ön hissəsindən başlayacaqsınız. Daha sonra bütün 6 tərəfə rəng qatacaqsınız.
// Çox rəngli tərəf - FRONT glBegin (GL_POLYGON); // Növbəti addımda glEnd ();
Addım 4. glVertex3f () əlavə edin
Çoxbucağınıza başlamaq istədiyinizi bildirdikdən sonra etməlisiniz zirvələri müəyyənləşdirin obyektin. glVertex, obyektinizlə nə etmək istədiyinizə görə birdən çox formaya malikdir.
- Birincisi, neçə ölçüdə çalışdığınızdır. GlVertex3f -də yuxarıdakı 3, 3 ölçüdə çəkdiyinizi söyləyir. 2 və ya 4 ölçüdə işləmək də mümkündür. GlVertex3f -də yuxarıdakı f, üzən nöqtə nömrələri ilə işlədiyinizi söyləyir. Şort, tam ədəd və ya cütlüklərdən də istifadə edə bilərsiniz.
- Qeyd edək ki, bu nöqtələr a saat əqrəbinin əksinə tərz. Hal-hazırda bu çox vacib deyil, ancaq işıqlandırma, doku və cull-üzü ilə işləməyə başladığınız zaman, bu inanılmaz dərəcədə əhəmiyyətli olacaq, buna görə də nöqtələrinizi saat yönünün əksinə təyin etməyi öyrənin.
- GlBegin () və glEnd () xətləri arasında ucları əlavə edin.
// Çox rəngli tərəf - 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 ();
Addım 5. glColor3f () əlavə edin
glColor, glVertex ilə eyni şəkildə işləyir. Xalları şort, tam ədəd, ikiqat və ya üzgüçü olaraq təyin edə bilərsiniz. Hər bir rəng 0 -dan 1 -ə qədər bir dəyərə malikdir. Bütün 0 -lar nöqtəni qara edir və bütün 1 -lər nöqtəni ağ edər. GlColor3f () dəki 3, alfa kanalı olmayan RGB rəng sisteminə aiddir. Rəngin alfa şəffaflığını təyin edir. Alfa səviyyəsini dəyişdirmək üçün şəffaf olmayan şəffaf üçün son parametr 0 -dan 1 -ə qədər olan dəyəri olan glColor4f () istifadə edin.
- GlColor3f () çağırdığınız zaman o nöqtədən çəkilən hər bir nöqtə o rəngdə olacaq. Buna görə də, bütün dörd təpənin qırmızı olmasını istəyirsinizsə, glVertex3f () əmrlərindən əvvəl hər dəfə rəngi təyin edin və bütün təpələr qırmızı olsun.
- Aşağıda göstərilən ön tərəf, hər bir təpə üçün yeni bir rəng necə təyin ediləcəyini göstərir. Bunu etdiyiniz zaman OpenGL rənglərinin maraqlı bir xüsusiyyətini görə bilərsiniz. Çoxbucağın hər bir ucunun öz rəngi olduğundan OpenGL avtomatik olaraq rəngləri qarışdıracaq! Növbəti addım eyni rəngli dörd təpənin necə təyin olunacağını göstərəcək.
// Çox rəngli tərəf - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0.5, -0.5, -0.5); // P1 qırmızı glColor3f (0.0, 1.0, 0.0); glVertex3f (0.5, 0.5, -0.5); // P2 yaşıl glColor3f (0.0, 0.0, 1.0); glVertex3f (-0.5, 0.5, -0.5); // P3 mavi glColor3f (1.0, 0.0, 1.0); glVertex3f (-0.5, -0.5, -0.5); // P4 bənövşəyi glEnd ();
Addım 6. Digər tərəfləri tutun
Kübün digər beş tərəfi üçün hər bir zirvənin yerinin nə olacağını düşünün, amma sadəlik üçün bunlar sizin üçün hesablanmışdır və son ekran () funksiyası aşağıda
// Ağ tərəf - 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 (); // Bənövşəyi tərəf - SAĞ 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 (); // Yaşıl tərəf - 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 (); // Mavi tərəf - 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 (); // Qırmızı tərəf - 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 (); }
Bu funksiya üçün son iki kod sətrini də əlavə etmək istəyirik. Bunlar glFlush ();
və glutSwapBuffers ();
bizə əvvəllər öyrəndiyiniz ikiqat tamponlama effekti verir.
3 -cü hissə 3: İstifadəçi İnteraktivliyi
Addım 1. specialKeys () əlavə edin
Demək olar ki, bitirdiniz, ancaq bu anda bir kub çəkə bilərsiniz, ancaq onu fırlatmaq üçün heç bir yolunuz yoxdur. Bunu etmək üçün edəcəksən xüsusi düymələr yaradın () ox düymələrini basmağa və kubu döndərməyimizə imkan verən funksiya!
- Bu funksiya qlobal dəyişənlərin rotate_x və rotate_y elan etməsinin səbəbidir. Sağ və sol ox düymələrinə basdığınızda, rotate_y 5 dərəcə artırılacaq və ya azalacaq. Eynilə, yuxarı və aşağı ox düymələrinə basdığınızda, rotate_x də buna uyğun olaraq dəyişəcək.
void specialKeys (int açarı, int x, int y) {// Sağ ox - (açar == GLUT_KEY_RIGHT) rotate_y += 5 olduqda fırlanmanı 5 dərəcə artırın; // Sol ox - (açar == GLUT_KEY_LEFT) rotate_y - = 5 olarsa fırlanmanı 5 dərəcə başqa dərəcədə azaldın; başqa əgər (açar == GLUT_KEY_UP) rotate_x += 5; başqa əgər (açar == GLUT_KEY_DOWN) rotate_x -= 5; // Ekran yeniləməsini tələb edin glutPostRedisplay (); }
Addım 2. glRotate () əlavə edin
Son ifadəniz, obyektinizi döndərəcək ifadəni əlavə etməkdir. Display () funksiyasına qayıdın və FRONT tərəfdən əvvəl bu sətirləri əlavə edin:
// çevrilmələri sıfırla glLoadIdentity (); // İstifadəçi rotate_x və rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0) dəyişəndə döndür; glRotatef (rotate_y, 0.0, 1.0, 0.0); // Çox rəngli tərəf - ÖN….
Addım 3. Kubu x oxu boyunca 2, y oxu boyunca 2 ölçüsündə ölçmək, kubu y oxu ətrafında 180 dərəcə döndərmək və x ekseni boyunca 0,1 çevirmək üçün aşağıdakı əmrləri əlavə edin
Bunları və əvvəlki glRotate () əmrlərini yuxarıda göstərildiyi kimi düzgün qaydada təşkil etdiyinizə əmin olun. (Əmin deyilsinizsə, bu, təlimatın sonundakı son kodda edilir.)
// Digər çevrilmələr glTranslatef (0.1, 0.0, 0.0); glRotatef (180, 0.0, 1.0, 0.0); glScalef (2.0, 2.0, 0.0);
Addım 4. Kodunuzu tərtib edin və işlədin
Proqramınızı tərtib etmək və yoxlamaq üçün gcc -dən tərtibçi olaraq istifadə etdiyinizi fərz etsək, bu əmrləri terminalınızdan işlədin.
Linux -da: gcc cube.c -o cube -lglut -lGL./ mycube Mac -da: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Windows -da: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Addım 5. Tam kodunuzu yoxlayın
Bu belə olmalıdır:
// // Fayl: mycube.c // Müəllif: Matt Daisley // Yaranma tarixi: 25.04.2012 // Layihə: OpenGL -də Küp Hazırlamaq üçün Mənbə Kodu // Təsvir: OpenGL pəncərəsi yaradır və 3D kub çəkir/ / İstifadəçinin ox düymələrindən istifadə edərək fırlaya biləcəyi // // İdarəetmə: Sol Ok -Sola Döndür // Sağ Ok -Sağa Döndür // Yuxarı Ok -Yuxarı Döndür // Aşağı Ox -Aşağı Döndür // ------ -------------------------------------------------- -// Daxildir // ------------------------------------------- --------------- #daxil edin #daxil edin #əlavə edin #GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #əlavə edin #başqa #daxil edin #endif // ------------- --------------------------------------------- // Funksiya Prototipləri / / ------------------------------------------------- --------- boş ekran (); void specialKeys (); // ------------------------------------------------ ---------- // Qlobal Dəyişənlər // ---------------------------------- ------------------------ ikiqat rotate_y = 0; ikiqat rotate_x = 0; // ------------------------------------------------ ---------- // göstər () Geri çağırma funksiyası // ------------------------------- --------------------------- void display () {// Clear screen and Z-buffer glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // çevrilmələri sıfırla glLoadIdentity (); // Digər Dönüşümlər // glTranslatef (0.1, 0.0, 0.0); // Daxil deyil // glRotatef (180, 0.0, 1.0, 0.0); // Daxil deyil // İstifadəçi rotate_x və rotate_y glRotatef (rotate_x, 1.0, 0.0, 0.0) dəyişəndə döndür; glRotatef (rotate_y, 0.0, 1.0, 0.0); // Digər Dönüşümlər // glScalef (2.0, 2.0, 0.0); // Daxil deyil // Çox rəngli tərəf - FRONT glBegin (GL_POLYGON); glColor3f (1.0, 0.0, 0.0); glVertex3f (0.5, -0.5, -0.5); // P1 qırmızı glColor3f (0.0, 1.0, 0.0); glVertex3f (0.5, 0.5, -0.5); // P2 yaşıl glColor3f (0.0, 0.0, 1.0); glVertex3f (-0.5, 0.5, -0.5); // P3 mavi glColor3f (1.0, 0.0, 1.0); glVertex3f (-0.5, -0.5, -0.5); // P4 bənövşəyi glEnd (); // Ağ tərəf - 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 (); // Bənövşəyi tərəf - SAĞ 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 (); // Yaşıl tərəf - 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 (); // Mavi tərəf - 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 (); // Qırmızı tərəf - 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 (); } // ----------------------------------------------- ----------- // xüsusi düymələr () geri çağırma funksiyası // ------------------------------ ---------------------------- void specialKeys (int key, int x, int y) {// Sağ ox-fırlanmanı 5 artır dərəcə (əgər açar == GLUT_KEY_RIGHT) rotate_y += 5; // Sol ox - (açar == GLUT_KEY_LEFT) rotate_y - = 5 olarsa fırlanmanı 5 dərəcə başqa dərəcədə azaldın; başqa əgər (açar == GLUT_KEY_UP) rotate_x += 5; başqa əgər (açar == GLUT_KEY_DOWN) rotate_x -= 5; // Ekran yeniləməsini tələb edin glutPostRedisplay (); } // ----------------------------------------------- ----------- // main () funksiyası // ------------------------------- --------------------------- int main (int argc, char* argv ) {// GLUT-u işə salın və istifadəçi parametrlərini işləyin glutInit (& argc, argv); // Z-tamponlu glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) ilə ikiqat tamponlu əsl rəngli pəncərə istəyin; // Pəncərə yaradın glutCreateWindow ("Zəhmli Küp"); // Z-tampon dərinlik testini aktivləşdir glEnable (GL_DEPTH_TEST); // Geri çağırma funksiyaları glutDisplayFunc (ekran); glutSpecialFunc (xüsusi düymələr); // glutMainLoop () hadisələri üçün nəzarəti GLUT -a keçirin; // Əməliyyat sisteminə qayıt 0; }