Ogre Kütüphanesi Bölüm-10 Tanponlanmış Girdi-3
Geri Dön

Ogre Kütüphanesi Bölüm-10 Tanponlanmış Girdi-3

Anasayfa
10. frameRenderingQueued fonksiyonumuza geçelim. createFrameListener fonksiyonu BaseApplication sınıfında tanımlanmıştı. Bir önceki derste de createFrameListener fonksiyonunu override etmemiş, tanımlanmış olan fonksiyonu kullanmıştık. Ama az önce createFrameListener fonksiyonunu override ettiğimiz için frameRenderingQueued fonksiyonumuza bazı kodlar eklememiz gerekecek. mWindow üzerinden ekleyeceğimiz isClosed fonksiyonu uygulama penceresi kapatıldığında bize true değerini döndürecek. O true değerini döndürünce biz de if kontrolümüzle frameRenderingQueued fonksiyonumuza false değerini döndüreceğiz. Hatırlarsanız, frameRenderingQueued fonksiyonu false döndürünce render döngüsü durduruluyordu. Diğer işlemimizde mShutDown boolean’ı true olursa frameRenderingQueued fonksiyonu false döndürecek ve render döngüsünden çıkılarak uygulama kapatılacak. mShutDown değeri ve mWindow nesnesi BaseApplication sınıfında oluşturulmuşlardır. mShutDown değerini ESC tuşuyla kontrol edeceğiz. mKeyboard nesnesi üzerinden capture fonksiyonu da her karede klavyeden girdi alma işlemini aktif ediyor. Aynı işlemi mMouse nesnesi için de gerçekleştiriyoruz. mTrayMgr nesnesi üzerinden çağırdığımız frameRenderingQueued fonksiyonu ise uygulama çalıştığında pencerenin sol alt köşesinde bulunan FPS bölümündeki değerleri her karede yenileme işlemini gerçekleştiriyor. Şimdi frameRenderingQueued fonksiyonumuzu düzenleyerek bahsettiğimiz işlemleri gerçekleştirelim:


bool Ders5::frameRenderingQueued(const Ogre::FrameEvent& evt) {
// Uygulama penceresi kapatılırsa render döngüsü durdurulacak:
if (mWindow->isClosed()) return false;
// mShutDown değeri true olursa render döngüsü durdurulacak:
if (mShutDown) return false;
// Her karede mKeyboard ve mMouse nesneleri için girdi alma işlemi gerçekleştirilecek:
mKeyboard->capture();
mMouse->capture();
// Ekranın sol alt köşesindeki FPS değeri her karede yenilecek:
mTrayMgr->frameRenderingQueued(evt); return true; }


11. frameRenderingQueued fonksiyonumuzda son olarak, gecerliKameraDugumu nesnesini translate fonksiyonuyla otelemeVektoru ile işleme sokacağız. Yaptığımız bu işlem bir önceki derstekiyle aynı. Bu nedenle detaylara inmeyeceğiz. gecerliKameraDugumu’ne, eğer KameraDugumu1 atanmışsa otelemeVektoru KameraDugumu1 ile işleme girecek. Eğer gecerliKameraDugumu’ne, KameraDugumu2 atanmışsa otelemeVektoru KameraDugumu2 ile işleme girecek. Şimdi frameRenderingQueued fonksiyonunun içine her şeyin altına return true satırının üstüne şu satırları yazalım:


// gecerliKameraDugumu, otelemeVektoru ile işleme sokularak kamera hareketi ve döndürme işlemi gerçekleştirilecek:
gecerliKameraDugumu->translate(otelemeVektoru * evt.timeSinceLastFrame, Ogre::Node::TS_LOCAL);


12. Şimdi OIS’ın KeyListener sınıfının keyPressed fonksiyonuna gelelim. Fonksiyonun tanımlama satırındaki parametresinde KeyEvent sınıf’ından türemiş, evt nesnesi var. Tamponlanmış girdi işleminde bize, bir tuşa basılırsa o tuşu temsil eden değer dönecekti. İşte bize döndürülen değer evt nesnesinin key değerinde saklanacak. Şimdi bir switch case kontrolü oluşturacağız.

Tuşlarımız, başlarına “KC_” anahtarı konularak ifade ediliyor. ESC tuşuna basıldığında mShutDown değerini true yapmasını söylüyoruz. 1 tuşu için “KC_1” case’sine, kamera nesnemizin bağlı olduğu SN’ye ulaşmasını sağlıyoruz. getParentSceneNode fonksiyonu zaten bize kamera nesnesinin bağlı olduğu SN’yi döndürüyor. SN’nin üye fonksiyonu olan detachObject fonksiyonunu kullanarak kamera nesnemizden yani mCamera’dan ayrılmasını söylüyoruz. Sonraki satırda gecerliKameraDugumu SN’sine, createScene fonksiyonunda oluşturduğumuz KameraDugumu1 SN’sini atıyoruz. Bir alt satırda da gecerliKameraDugumu nesnesine, yani KameraDugumu1 SN’sine kamera nesnemiz olan mCamera’yı bağlıyoruz. Bu işlem 2 tuşuna basıldığında yani “KC_2” case’sinde KameraDugumu2 için gerçekleştiriliyor.

Diğer case’lere gelince: bunlara da tamponlanmamış girdi dersimizde, yani Ders4’te if kontrollerinde yaptığımız otelemeVektoru’nün değerinin, hareketKatsayisi ile işleme girme kodlarının aynısı yazıyoruz. Hatırlayalım, frameRenderingQueued fonksiyonunda otelemeVektoru, gecerliKameraDugumu ile işleme sokuluyordu. Sonuç olarak klavyeden W, Yukarı Ok; A, Sol Ok; S, Aşağı Ok; D, Sağ Ok; E, PageDown; Q, PageUp tuşlarına basıldığında kameramızın hareket etmesini sağlıyoruz. 1 ve 2 tuşlarıyla kameramızın bağlı olduğu SN’nin değişmesini, ESC tuşuyla uygulamadan çıkmayı sağlıyoruz.

13. Tamponlanmış girdide kullandığımız KeyListener sınıfı keyPressed fonksiyonundan sonra keyReleased fonksiyonunu otomatik çağırır. Şimdi keyReleased fonksiyonunda, tuş serbest kaldığı zaman otelemeVektoru artmayacak anlamında, keyPressed fonksiyonumuzda hareket için kullandığımız tuşların case’lerinde, otelemeVektoru’nu sıfıra eşitleyeceğiz.

14. Şimdi MouseListener sınıfımızın mousePressed fonksiyonuna gelelim. Fonksiyonun tanımlama parametresinde MouseEvent sınıfı nesnesi olan evt ve MouseButtonID enum’undan türemiş bir id enum nesnesi vardır. Tanımlama satırındaki id enum nesnesi’ni switch case kontrolünde kullanacağız. id bize farenin basılan tuşunun kodunu gönderecek. evt nesnesine mouseMoved fonksiyonunda değineceğiz. mousePressed fonksiyonumuzun içine öncelikle bir ışık nesnesi tanımlıyoruz. Bu ışık nesnesini createScene fonksiyonunda oluşturduğumuz noktasalIsik nesnemizi atıyoruz. Sonra bir switch case kontrolü oluşturuyoruz. Eğer farenin sol tuşuna basılırsa noktasalIsik nesnemizi, tıpkı tamponlanmamış girdi dersimizdeki gibi açıp kapatacağız. Faremizin sol tuşunu “MB_Left” ifadesi temsil ediyor.

15. MouseListener sınıfında, KeyListener’deki gibi keyPressed fonksiyonumuza yazdığımız case karşılığında keyReleased fonksiyonuna da case yazmamız gerekmiyor. Yani mouseReleased fonksiyonumuza bir şey yazmamız gerekmiyor. Şimdi mouseMoved fonksiyonuna geçelim. Tanımlama parametresindeki MouseEvent sınıfının nesnesi evt, fare tuşlarının durumunu döndürüyor.

Yapmak istediğimiz işlem, farenin sağ tuşuna basılıyken fareyi hareket ettirdiğimizde kameramızın kendi etrafında dönmesidir. Bunun için bir if kontrolü oluşturmamız yeterli. evt'te state üzerinden buttonDown fonksiyonuna ulaşıyoruz. Parametresine faremizin sağ tuşunu temsil eden “MB_Right” tanımını yazıyoruz. Farenin sağ tuşuna basılı tuttuğumuz sürece buttonDown fonksiyonu bize true değerini döndürecek ve if kontrolümüz aktif olacak.

gecerliKameraDugumu nesnesine döndürme işlemi uygulayacağız. gecerliKameraDugumu nesnesi kendisine KameraDugumu1 ve KameraDugumu2 nesnelerinden hangisi atanmışsa onu döndürecek. “evt.state.X.rel” kod dizisi bize, faremizin ekranın X ekseninde ne kadar yer değiştirdiğini döndürüyor. Bu değeri dondurmeKatsayisi ile çarparak Degree nesnesinin, yani derece nesnesinin içinde yaw fonksiyonunun parametresine atıyoruz. Yaw fonksiyonu faremizi sağa sola götürdükçe gecerliKameraDugumu’müzün sağa sola dönmesini sağlayacak. Sonra bu işlemlerin benzerini yine gecerliKameraDugumu nesnemize uyguluyoruz. Bu sefer pitch fonksiyonunu kullanıyoruz. pitch fonksiyonunun parametresinde de “evt.state.Y.rel” kod dizisini kullanıyoruz. Bu seferde bize, faremizin ekranın Y ekseninde ne kadar yer değiştirdiği döndürülüyor. Faremizi yukarı aşağı götürdükçe, kameramızın pitch fonksiyonuyla X ekseninde dönmesini sağlıyoruz.

Projemizi derleyip çalıştırın. 1-2, WASD-QE, YukarıOk-SolOk-SağOk-AşağıOk-PageUp-PageDown, ESC tuşlarını kullanabilirsiniz. Farenin sağ tuşu basılıyken, fareyi oynattığınızda kamera dönecektir. Farenin sol tuşuna basarak da ışığı açıp kapatabilirsiniz.

C. BİTİRİRKEN


OIS kütüphanesin girdi işlemlerini artık biliyorsunuz. Tamponlanmış girdi işlemini de görmüş oldunuz. Eğer bu projeyi oluşturmakta farklı sorunlar yaşıyorsanız kendi kodlarınızı Kaynak Kodu ile karşılaştırabilirsiniz. Ek olarak, Genişletilmiş Bölüm’de, SDL kütüphanesini kullanarak Joystick girdisi almayı anlattık.



Anasayfa

Tüm Hakları Saklıdır. ©Arleone 2013-UstaDerslik