OpenGL, basit ilkellerden karmaşık üç boyutlu sahneler çizmek için kullanılan güçlü bir 3B programlama aracıdır. Bu makale, üç boyutlu olarak görüntülemek için döndürebileceğiniz basit bir küpün nasıl çizileceğini öğretecek!
Bu proje için bir kod düzenleyiciye ve biraz C programlama bilgisine ihtiyacınız olacak.
adımlar
Bölüm 1/3: İlk Kurulum
Adım 1. OpenGL'yi kurun Başlamak için, sisteminize OpenGL'yi kurmak için şu adımları izleyin
Zaten OpenGL ve uyumlu bir C derleyiciniz varsa, bu adımı atlayabilir ve bir sonrakine geçebilirsiniz.
Adım 2. Belgeyi oluşturun
Favori kod düzenleyicinizde yeni bir dosya oluşturun ve mycube.c olarak kaydedin
Adım 3. #includes ekleyin
Bunlar, programınız için ihtiyaç duyacağınız temel içeriklerdir. Farklı işletim sistemleri için gerekli olan farklı içeriklerin olduğunu anlamak önemlidir. Programınızın çok yönlü olduğundan ve herhangi bir kullanıcı için çalışabileceğinden emin olmak için tüm bunları eklediğinizden emin olun.
// #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif içerir
Adım 4. Fonksiyon prototiplerini ve global değişkenleri ekleyin
Bir sonraki adımınız, bazı fonksiyon prototiplerini bildirmektir.
// Fonksiyon Prototipleri void display(); özel Tuşları geçersiz kıl(); // Global Değişkenler double döndürme_y=0; çift döndürme_x=0;
Adım 5. main() işlevini ayarlayın
int main(int argc, char* argv){ // GLUT'u başlat ve kullanıcı parametrelerini işle glutInit(&argc, argv); // Z-tamponlu glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
Adım 6. Pencereyi oluşturun
Bir sonraki adım pencereyi oluştur küpü çizeceğiniz yer. Bu öğreticide, pencereye "Harika Küp" adı verilir.
// glutCreateWindow ("Harika Küp");
Adım 7. Derinlik testini etkinleştirin
OpenGL, herhangi bir özel özelliğin etkinleştirildiğini varsaymadığı için katı bir dildir. Programınızın daha önce baktığınız Z-tamponunu kullanarak 3 boyutlu olarak düzgün bir şekilde görüntülenmesi için şunları yapmanız gerekir: derinlik testini etkinleştir. OpenGL'yi keşfetmeye devam ettikçe, aydınlatma, dokular, dışlama ve çok daha fazlası dahil olmak üzere etkinleştirmeniz gereken birçok özelliği keşfedeceksiniz.
// Z-tampon derinlik testini etkinleştir glEnable(GL_DEPTH_TEST);
Adım 8. Geri arama işlevleri ekleyin
İşte daha önce prototiplerini yazdığınız geri arama işlevleri. Ana döngü boyunca her seferinde bu işlevler çağrılır. Görüntüleme işlevi, önceki çağrıdan bu yana değişkenlerde yapılan herhangi bir değişikliği temel alarak sahneyi yeniden çizer. specialKeys işlevi, programla etkileşime girmemizi sağlar.
// Geri arama fonksiyonları glutDisplayFunc(display); glutSpecialFunc(özel Tuşlar);
Adım 9. MainLoop'u başlatın
Bu, animasyonlara ve kullanıcı etkileşimine izin vermek için programı kapatana kadar ana işlevi hatırlayacaktır.
// Olaylar için kontrolü GLUT'a geçir glutMainLoop(); // OS'ye dön 0 döndür; }
Bölüm 2/3: display() İşlevi
Adım 1. Bu işlevin amacını anlayın
Küpünüzü çizmenin tüm işleri bu fonksiyonda yapılacaktır. Küpünüzün arkasındaki genel fikir, altı kenarı da ayrı ayrı çizmek ve uygun konuma yerleştirmektir.
Kavramsal olarak, dört köşeyi tanımlayarak ve OpenGL'nin çizgileri birleştirmesine ve sizin tanımladığınız bir renkle doldurmasına izin vererek her iki taraf çizilecektir. Bunu yapmanın adımları aşağıdadır
Adım 2. glClear()'ı ekleyin
Bu fonksiyonda atmanız gereken ilk adım, rengi ve Z arabelleğini temizle. Bu adımlar olmadan, eski çizimler yeni çizimlerin altında görünmeye devam edebilir ve çizilen nesneler ekranda doğru konumda olmaz.
void display(){ // Ekranı temizle ve Z-buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
Adım 3. glBegin() ve glEnd()'i ekleyin
OpenGL, nesneleri farklı çokgenlerin kombinasyonları olarak tanımlar. Kullanmak glBegin() komutuyla, şekli çizecek bir kalemi etkili bir şekilde bırakıyorsunuz. Kalemi kaldırıp yeni bir şekle başlamak için glEnd() emretmek. Bu öğreticide, küpün her bir tarafını çizmek için GL_POLYGON kullanacaksınız, ancak başka şekiller oluşturmak için GL_LINE, GL_QUAD veya GL_TRIANGLE gibi diğer parametre seçeneklerini kullanmak da mümkündür.
- Burada küpünüzün ön tarafıyla başlayacaksınız. Daha sonra 6 tarafa da renk katacaksınız.
// Çok renkli taraf - FRONT glBegin(GL_POLYGON); // Vertices bir sonraki adımda eklenecek glEnd();
Adım 4. glVertex3f()'yi ekleyin
Poligonunuza başlamak istediğinizi belirttikten sonra, köşeleri tanımla nesnenin. glVertex, nesnenizle ne yapmak istediğinize bağlı olarak birden çok biçime sahiptir.
- Birincisi, kaç boyutta çalıştığınızdır. glVertex3f'deki yukarıdaki 3, 3 boyutlu çizim yaptığınızı söylüyor. 2 veya 4 boyutlu olarak da çalışmak mümkündür. glVertex3f'deki yukarıdaki f, kayan nokta sayılarıyla çalıştığınızı söylüyor. Ayrıca şort, tamsayı veya çift kullanabilirsiniz.
- Bu noktaların bir tanımda tanımlandığına dikkat edin. saat yönünün tersine tavır. Bu şu anda çok önemli değil ama ışıklandırma, dokular ve itfa ile çalışmaya başladığınızda, bu inanılmaz derecede önemli hale gelecek, bu yüzden puanlarınızı saat yönünün tersine tanımlamayı alışkanlık haline getirin.
- glBegin() ve glEnd() satırları arasına tepe noktaları ekleyin.
// Çok renkli taraf - 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();
Adım 5. glColor3f()'yi ekleyin
glColor, glVertex'e benzer şekilde çalışır. Noktaları kısa, tamsayı, çift veya kayan nokta olarak tanımlayabilirsiniz. Her rengin 0 ile 1 arasında bir değeri vardır. Tüm 0'lar noktayı siyah yapar ve 1'lerin tümü noktayı beyaz yapar. glColor3f() içindeki 3, alfa kanalı olmayan RGB renk sistemini ifade eder. Bir rengin alfası, saydamlığını tanımlar. Alfa seviyesini değiştirmek için glColor4f()'yi kullanın ve son parametre opaktan şeffafa için 0 ile 1 arasında bir değerdir.
- glColor3f()'yi çağırdığınızda, o noktadan itibaren çizilen her köşe o renkte olacaktır. Bu nedenle, dört köşenin de kırmızı olmasını istiyorsanız, rengi glVertex3f() komutlarından önce istediğiniz zaman bir kez ayarlayın, tüm köşeler kırmızı olacaktır.
- Aşağıda tanımlanan Ön taraf, her köşe için yeni bir rengin nasıl tanımlanacağını gösterir. Bunu yaptığınızda, OpenGL renklerinin ilginç bir özelliğini görebilirsiniz. Çokgenin her bir köşesi kendi rengine sahip olduğundan, OpenGL renkleri otomatik olarak karıştıracaktır! Bir sonraki adım, aynı renge sahip dört köşenin nasıl atanacağını gösterecektir.
//Çok renkli taraf - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0.5, -0.5, -0.5); // P1 kırmızıdır glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.5, -0.5); // P2 yeşildir glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); // P3 mavidir glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, -0.5, -0.5); // P4 mor glEnd();
Adım 6. Diğer tarafları ele alın
Küpün diğer beş kenarı için her bir köşenin konumunun ne olacağını hesaplayın, ancak basitlik için bunlar sizin için hesaplandı ve aşağıdakilere dahil edildi. son görüntü () işlevi aşağıda.
// Beyaz taraf - GERİ 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(); // Mor taraf - 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(); // Yeşil taraf - 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 taraf - 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(); // Kırmızı taraf - 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(); }
Ayrıca bu işlev için son iki kod satırı eklemek istiyoruz. Bunlar glFlush();
ve glutSwapBuffers();
bu da bize daha önce öğrendiğiniz çift arabelleğe alma etkisini verir.
Bölüm 3/3: Kullanıcı Etkileşimi
Adım 1. specialKeys() ekleyin
Neredeyse bitirdiniz ama şu anda bir küp çizebiliyorsunuz ama döndürme şansınız yok. Bunu yapmak için özel bir anahtar oluştur() ok tuşlarına basmamıza ve küpü döndürmemize izin veren işlev!
- Bu fonksiyon, genel rotasyon_x ve döndürme_y değişkenlerini bildirmenizin nedenidir. Sağ ve sol ok tuşlarına bastığınızda döndürme_y 5 derece artırılıp azaltılacaktır. Benzer şekilde, yukarı ve aşağı ok tuşlarına bastığınızda, döndürme_x buna göre değişecektir.
void specialKeys(int tuşu, int x, int y) { // Sağ ok - döndürmeyi 5 derece artırın eğer (anahtar == GLUT_KEY_RIGHT) döndürme_y += 5; // Sol ok - döndürmeyi 5 derece azalt, aksi takdirde (anahtar == GLUT_KEY_LEFT) döndürme_y -= 5; yoksa (anahtar == GLUT_KEY_UP) döndürme_x += 5; yoksa (anahtar == GLUT_KEY_DOWN) döndürme_x -= 5; // Ekran güncellemesini talep et glutPostRedisplay(); }
Adım 2. glRotate()'i ekleyin
Son ifadeniz, nesnenizi döndürecek ifadeyi eklemektir. display() işlevine geri dönün ve FRONT tarafından önce şu satırları ekleyin:
// Dönüşümleri sıfırla glLoadIdentity(); // Kullanıcı döndürme_x ve döndürme_y'yi değiştirdiğinde döndür glRotatef(döndürme_x, 1.0, 0.0, 0.0); glRotatef(döndür_y, 0.0, 1.0, 0.0); // Çok renkli taraf - ÖN….
Adım 3. Küpü x ekseni boyunca 2, y ekseni boyunca 2 ölçeklemek, küpü y ekseni etrafında 180 derece döndürmek ve küpü x ekseni boyunca 0,1 çevirmek için aşağıdaki komutları ekleyin
Bunları ve önceki glRotate() komutlarını yukarıda açıklandığı gibi doğru sırada düzenlediğinizden emin olun. (Emin değilseniz, bu, eğitimin sonundaki son kodda yapılır.)
// Diğer dönüşümler glTranslatef(0.1, 0.0, 0.0); glRotatef(180, 0.0, 1.0, 0.0); glScalef(2.0, 2.0, 0.0);
Adım 4. Kodunuzu derleyin ve çalıştırın
Derleyiciniz olarak gcc kullandığınızı varsayarak, programınızı derlemek ve test etmek için bu komutları terminalinizden çalıştırın.
Linux'ta: gcc cube.c -o cube -lglut -lGL./ mycube Mac'te: gcc -o foo foo.c -framework GLUT -framework OpenGL./ mycube Windows'ta: gcc -Wall -ofoo foo.c -lglut32cu - lglu32 -lopengl32./ mycube
Adım 5. Tam kodunuzu kontrol edin
Bunun gibi olmalı:
// // Dosya: mycube.c // Yazar: Matt Daisley // Oluşturuldu: 25.04.2012 // Proje: OpenGL'de Küp Yap için kaynak kodu // Açıklama: Bir OpenGL penceresi oluşturur ve bir 3B küp çizer / / Kullanıcının ok tuşlarını kullanarak döndürebileceği // // Kontroller: Sol Ok - Sola Döndür // Sağ Ok - Sağa Döndür // Yukarı Ok - Yukarı Döndür // Aşağı Ok - Aşağı Döndür // ------ -------------------------------------------------- -- // İçerir // ------------------------------------------- --------------- #include #include #include #define GL_GLEXT_PROTOTYPES #ifdef _APPLE_ #include #else #include #endif // ------------- ------------------------------------------ // Fonksiyon Prototipleri / / ------------------------------------------------- --------- boş ekran(); özel Tuşları geçersiz kıl(); // ------------------------------------------------ ---------- // Global Değişkenler // ---------------------------------- ------------------------ çift döndürme_y=0; çift döndürme_x=0; // ------------------------------------------------ ---------- // display() Geri arama işlevi // ------------------------------- --------------------------- void display(){ // Ekranı temizle ve Z-buffer glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Dönüşümleri sıfırla glLoadIdentity(); // Diğer Dönüşümler // glTranslatef(0.1, 0.0, 0.0); // Dahil değil // glRotatef(180, 0.0, 1.0, 0.0); // Dahil değildir // Kullanıcı döndürme_x ve döndürme_y'yi değiştirdiğinde döndür glRotatef(döndürme_x, 1.0, 0.0, 0.0); glRotatef(döndür_y, 0.0, 1.0, 0.0); // Diğer Dönüşümler // glScalef(2.0, 2.0, 0.0); // Dahil değil //Çok renkli taraf - FRONT glBegin(GL_POLYGON); glColor3f(1.0, 0.0, 0.0); glVertex3f(0.5, -0.5, -0.5); // P1 kırmızıdır glColor3f(0.0, 1.0, 0.0); glVertex3f(0.5, 0.5, -0.5); // P2 yeşildir glColor3f(0.0, 0.0, 1.0); glVertex3f(-0.5, 0.5, -0.5); // P3 mavidir glColor3f(1.0, 0.0, 1.0); glVertex3f(-0.5, -0.5, -0.5); // P4 mor glEnd(); // Beyaz taraf - GERİ 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(); // Mor taraf - 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(); // Yeşil taraf - 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 taraf - 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(); // Kırmızı taraf - 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() Geri Çağırma Fonksiyonu // ------------------------------ ---------------------------- void specialKeys(int tuşu, int x, int y) { // Sağ ok - dönüşü 5 artırır derece if (anahtar == GLUT_KEY_RIGHT) döndürme_y += 5; // Sol ok - döndürmeyi 5 derece azalt, aksi takdirde (anahtar == GLUT_KEY_LEFT) döndürme_y -= 5; yoksa (anahtar == GLUT_KEY_UP) döndürme_x += 5; yoksa (anahtar == GLUT_KEY_DOWN) döndürme_x -= 5; // Ekran güncellemesini talep et glutPostRedisplay(); } // -------------------------------------------------- ----------- // ana işlev // ------------------------------- --------------------------- int main(int argc, char* argv){ // GLUT'u başlat ve kullanıcı parametrelerini glutInit(&argc, argv); // Z-tamponlu glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); // glutCreateWindow ("Harika Küp"); // Z-tampon derinlik testini etkinleştir glEnable(GL_DEPTH_TEST); // Geri arama fonksiyonları glutDisplayFunc(display); glutSpecialFunc(özel Tuşlar); // Olaylar için kontrolü GLUT'a geçir glutMainLoop(); // OS'ye dön 0 döndür; }