GLUT Dersleri - 3 (Klavye Kontrolü)

1. Klavye Tuşlarının Okunması:

GLUT kullanarak klavyeden basılan tuşları okuyabilir, bu tuşlar doğrultusunda programımıza yön verebiliriz. GLUT hem normal tuşlar için (harfler, sayılar) hemde özel tuşların (OK TUŞLARI, DELETE, INSERT, F1, F2... vb.) okunması için gerekli alt yapıyı bize sağlar.

Şimdiye kadar öğrendiğimiz gibi, GLUT sistemi oluşan işletim sistemi olaylarının herbiri için bir yordam görevlendirmemizi ve yordamın her olay oluşunda otomatik olarak çağırılmasını sağlamaktadır. Geçen derslerimizde bu mekanizmayı kullanarak pencere boyutu değiştiriminde, her pencere görüntüsü yenilenmesi gerektiğinde ve de programımız boş ta beklerken (bir işletim döngüsü içerisinde bulunmazken) çağırılması gereken yordamları belirtmiştik. Aynen bu olaylara cevap oluşturacak yordamları tanımladığımız gibi, tuşa basılma olayı sırasında çağırılmasını istediğimiz yordamı da GLUT sistemine bildirmemiz gerekmektedir.

GLUT klavye tuşa basılmaları sonucu çağırılacak servis yordamını belirtebilmemiz için bize 2 farklı fonksiyon sunar. İlk fonksiyonumuz olan "glutKeyboardFunc" ile sistemde oluşan normal tuş basılma durumları için çağırılacak servis yordamını belirtebiliriz. Normal tuşlar olarak sayılar, harfler kısaca ASCII kodu olan her tuşu kastetmekteyiz. Bu yordamın tanımı aşağıdaki gibidir.

void glutKeyboardFunc(void (*func) (unsigned char key, int x, int y));

Parametreler:

func :: normal tuşlara basılma durumunda çağırılacak rutinin ismi. Burada NULL parametresi verilmesi durumunda GLUT sistemi normal tuşa basılmaları herhangi bir şekilde işleyemeyecektir.

Yordamımızın ismini istediğimiz gibi belirleyebiliriz. Dikkat etmemiz gereken şey, bu yordamın 3 adet paremetreye ihtiyaç duymasıdır. GLUT sistemi tarafından bu yordamımız çağırıldığı zaman paremetreler uygun değerler ile otomatik olarak doldurulur. İlk paremetre ASCII kod olarak basılan tuşun kodunu içerir. Diğer iki paremetre ise tuşa basılma anında mouse un konumunu ekranın sol üst köşesine göreli olarak bildirmektedir.

Şimdi bu özelliği kullanmak için basit bir örnek yapalım. Öncelikle tuşa basılma sırasında çağırılacak yordamı yazalım. Bu yordam içerisinde eğer ESC tuşuna basılıyor ise programımıza exit() yordamını çağırarak son verelim. 27 ESC tuşunun ASCII kodudur. Yordamımızın ismi ise "processNormalKeys" olsun.
   
void processNormalKeys(unsigned char key, int x, int y) {
    if (key == 27)
        exit(0);
}

Tabii şimdi glutKeyboardFunc içerisine yordamımızın adını göndermemiz gerekiyor. Bu işi şimdilik yapmayalım. Biraz önce özel tuşları yakalamak için de yine bir mekanizma olduğunu söylemiştik. Aynen normal tuşlar için yaptığımız gibi bu tuşlar içinde bir yordam yazmalı daha sonra "glutSpecialFunc" fonksiyonunu kullanarak bu yordamımızı sisteme kayıt ettirmeliyiz. Bu sayede F1..F12, OK TUŞLARI gibi özel tuşlara basılmaları elde edebiliriz.

void glutSpecialFunc(void (*func) (int key, int x, int y));

Parametreler:

func :: Özel tuşlara basılma durumunda sistem tarafından çağırılacak yordamın adı. Bu yordamımız 3 adet parametre almalıdır.

Şimdi yeni öğrendiğimiz bu olanağı programımız içerisinde kullanalım. Örnek olarak: F1 tuşuna basıldığında kırmızı, F2 tuşuna basıldığında yeşil, F3 tuşuna basıldığında ise mavi bir üçgen çizdirelim. Yordamımıza processSpecialKeys adını veriyoruz. red, green, blue olarak tanımladığımız 3 değişken ile üçgenin rengini saklayıp bu yordam içerisinden basılan tuşa göre değerler ile oynayarak istediğimiz rengi oluşturuyoruz.
   
void processSpecialKeys(int key, int x, int y) {
    switch(key) {
        case GLUT_KEY_F1 :
            red = 1.0;
            green = 0.0;
            blue = 0.0;
            break;
        case GLUT_KEY_F2 :
            red = 0.0;
            green = 1.0;
            blue = 0.0;
            break;
        case GLUT_KEY_F3 :
            red = 0.0;
            green = 0.0;
            blue = 1.0;
    }
}

GLUT_KEY_* şeklinde belirtilen sabitlerin herbiri özel tuşlardan birini temsil eder. Bu tanımlamalar glut.h içerisinde yapılmışlardır. Aşağıda bu özel tuş tanımlarının tümünü görebilirsiniz.
   
GLUT_KEY_F1
GLUT_KEY_F2
GLUT_KEY_F3
GLUT_KEY_F4
GLUT_KEY_F5
GLUT_KEY_F6
GLUT_KEY_F7
GLUT_KEY_F8
GLUT_KEY_F9
GLUT_KEY_F10
GLUT_KEY_F11
GLUT_KEY_F12
GLUT_KEY_LEFT
GLUT_KEY_RIGHT
GLUT_KEY_UP
GLUT_KEY_DOWN
GLUT_KEY_PAGE_UP
GLUT_KEY_PAGE_DOWN
GLUT_KEY_HOME
GLUT_KEY_END
GLUT_KEY_INSERT


Sanırım isimlerinden hangi özel tuşları simgeledikleri açıkça anlaşılıyordur. Yukarıdaki kodun düzgün derlenmesi ve çalışabilmesi için programımızın en üst kesiminde global olarak red, green, blue isiminde üç adet float değişken tanımlamalı ve ayriyeten renderScene yordamı üzerinde gerekli değişiklikleri yaparak üçgenin bu parametreler doğrultusunca çizilmesini sağlamalıyız.

// her parametreye 1 ilk değerini veriyoruz. Böylelikle ilk olarak beyaz bir üçgen ile karşılaşacağız.
float red=1.0, blue=1.0, green=1.0;

...

void renderScene(void) {
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
    glRotatef(angle,0.0,1.0,0.0);

    // çizilecek üçgenin rengini parametreler doğrultusunda değiştiriyoruz.
    glColor3f(red,green,blue);

    glBegin(GL_TRIANGLES);
        glVertex3f(-0.5,-0.5,0.0);
        glVertex3f(0.5,0.0,0.0);
        glVertex3f(0.0,0.5,0.0);
        glEnd();
    glPopMatrix();

    angle++;
    glutSwapBuffers();
}


Evet, şimdi son olarak glutKeyboardFunc ve glutSpecialFunc yordamlarını kullanarak kendi fonksiyonlarımızı sisteme kaydettirmeliyiz. Bu sayede tuşa basılmalar sırasında kendi yordamlarımızın çağırılmasını sağlamış olacağız. Bu işi main() fonksiyonu içerisinden yapıyoruz. Aşağıda main() yordamımızın değişmiş son hali bulunmaktadır.
   
void main(int argc, char **argv) {

    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DEPTH|GLUT_DOUBLE|GLUT_RGBA);

    glutInitWindowPosition(100,100);
    glutInitWindowSize(320,320);
    glutCreateWindow("3D Tech - GLUT Tutorial");
    glutDisplayFunc(renderScene);
    glutIdleFunc(renderScene);
    glutReshapeFunc(changeSize);

    // Bu satırlar yeni eklendi....
    glutKeyboardFunc(processNormalKeys);
    glutSpecialFunc(processSpecialKeys);

    glutMainLoop();

}


2. CTRL, ALT ve SHIFT Kombinasyonlarını Yakalama:

Kimi durumlarda basılan tuşlar ile birlikte CTRL, ALT ve SHIFT tuşlarının basılı olma durumlarını da öğrenmek isteyebiliriz. Bu tuşlar özel yada normal tuşlar kategorisi içerisinde bulunmadıkları için yukarıda bahsettiğimiz yöntemler ile yakalanamazlar. "glutGetModifiers" fonksiyonunu kullanarak o anda bu üç tuşun hangilerine basılıp basılmadığını öğrenebiliriz. Yalnız bu fonksiyonu sadece tuşa basılmaları işleyen yordamlarımız içerisinden, yani glutSpecialFunc ve glutKeyboardFunc ile kayıt ettirdiğimiz yordamlarımız içinden çağırabiliriz.

int glutGetModifiers(void);

Bu fonksiyonun geri dönüş değeri glut.h içerisinde tanımlı olan tuşu yada bu tuşların OR lanmış kombinasyonlarını içerir: glut.h da tanımlı olan sabitler şunlardır:

  • GLUT_ACTIVE_SHIFT :: SHIFT basılı ise, yada CAPS LOCK açık ise geridöndürülür..
  • GLUT_ACTIVE_CTRL :: CTRL basılı ise geri döner.
  • GLUT_ACTIVE_ALT :: ALT tuşu basılı ise geri döner.

Şimdi processKeys yordamımızı biraz değiştirerek yeni öğrendiğimiz özelliği kullanalım. Yeni yordamımızda 'r' tuşuna basıldığı taktirde glutGetModifiers() fonksiyonunu çağırarak CTRL, ALT, SHIFT durumunu öğreniyoruz. Daha sonra bu durum eğer ALT tuşunun basılı olduğunu gösteriyor ise red değişkenini 0 yapıyor, basılı değil ise red = 1 'liyoruz.
   
void processNormalKeys(unsigned char key, int x, int y) {

    if (key == 27)
        exit(0);
    else if (key=='r') {
        int mod = glutGetModifiers();
        if (mod == GLUT_ACTIVE_ALT)
            red = 0.0;
        else
            red = 1.0;
    }

}


Peki CTRL+ALT+F1 gibi bir tuş kombinasyonunu nasıl sınayabilirsiniz? Bunun için CTRL ve ALT kombinasyonunu aynı anda sınamak durumundayız. Test işlemini gerçekleştirirken CTRL ve ALT için kullandığımız sabitleri OR işlemine tutup denetlememiz gerekmektedir. Aşağıda verdiğimiz yordam sadece CTRL+ALT+F1 tuşların aynı anda basılması durumunda üçgen rengini kırmızıya çeviriyor.
   
void processSpecialKeys(int key, int x, int y) {

    int mod;
    switch(key) {
        case GLUT_KEY_F1 :
           mod = glutGetModifiers();
           if (mod == (GLUT_ACTIVE_CTRL|GLUT_ACTIVE_ALT)) {
               red = 1.0; green = 0.0; blue = 0.0;
           }
           break;
        case GLUT_KEY_F2 :
           red = 0.0;
           green = 1.0;
           blue = 0.0; break;
        case GLUT_KEY_F3 :
           red = 0.0;
           green = 0.0;
           blue = 1.0; break;
    }

}

Deniz Aydınoğlu tarafından www.lighthouse3d.com   sitesindeki belgeden çevrilmiştir :: 2002 ::




Bu yazının bulunduğu site: OyunYapimi.org
http://www.oyunyapimi.org

Bu yazı için adres:
http://www.oyunyapimi.org/modules.php?name=Sections&op=viewarticle&artid=9