Ogre Kütüphanesi Bölüm-9 Framelistener ve Tamponlanmamış Girdi-2
UstaDerslik Soru-Cevap Yararlı Araçlar
arama ikon
Diller
Türkçe Türkçe

bilgi UstaDerslik
Bu uyari kutusudur.
Tamam
Anasayfa
İletişim
Üyeler

Ogre Kütüphanesi Bölüm-9 Framelistener ve Tamponlanmamış Girdi-2

profil
OLENVERDGRUP
BEĞEN(0)
BEĞENME(0)
GÖRÜNTÜLENME(1408)
RAPOR ET

B. PRATİK DERS



- Proje Adı: Ders4
- Header dosyası: Ders4.h
- CPP dosyası: Ders4.cpp

Adım adım yapılacak işlemler şu şekilde:

1. createScene fonksiyonumuzun içini yazarak başlayalım. Şimdi AmbientLight’ımızı, Gölge Tekniği’mizi, Kamera’mızın konumunu ve yüzünün dönük olduğu konumu belirliyoruz. Sonra döndüreceğimiz ve hareket ettireceğimiz Ninja Entity nesnememizi, SN’sini, SN’sine bağlamayı ve gölge dökümü durumunu kuruyoruz. Ardından Ders2’de oluşturduğumuz zemin tanımını burada da yapıyoruz. Son olarak bir noktasal ışık kaynağı tanımlayıp, konumunu Diffuse ve Specular renklerini kuruyoruz. Bahsettiğimiz tüm bu işlemleri createScene fonksiyonuna ekleyelim:


void Ders4::createScene(void)
{
mSceneMgr->setAmbientLight(Ogre::ColourValue(0.25, 0.25, 0.25));
mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
mCamera->setPosition(Ogre::Vector3(-150, 196, 379));
mCamera->lookAt(Ogre::Vector3(0, 183, -9));

// IJKL-UO tuşlarıyla döndüreceğimiz ve hareket ettireceğimiz Ninja nesnemizi tanımlıyoruz:
Ogre::Entity* ninja = mSceneMgr->createEntity("Ninja", "ninja.mesh");
Ogre::SceneNode* ninjaDugumu = mSceneMgr->getRootSceneNode()->createChildSceneNode("NinjaDugumu");
ninjaDugumu->attachObject(ninja);
ninja->setCastShadows(true);

// DERS2'DEKİ ZEMİN TANIMINI YAPIYORUZ:
Ogre::Plane ilkplanemiz(Ogre::Vector3::UNIT_Y, 0);
Ogre::MeshManager::getSingleton().createPlane("zemin", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, ilkplanemiz, 1500, 1500, 20, 20, true, 1, 5, 5, Ogre::Vector3::UNIT_Z);
Ogre::Entity* zeminPlanesi = mSceneMgr->createEntity("zeminPlanesi", "zemin");
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(zeminPlanesi);
zeminPlanesi->setMaterialName("Examples/Rockwall");
zeminPlanesi->setCastShadows(false);

// Bir noktasal ışık (point light) tanımlıyoruz:
Ogre::Light* noktasalIsik = mSceneMgr->createLight("noktasalIsik");
noktasalIsik->setType(Ogre::Light::LT_POINT);
noktasalIsik->setPosition(Ogre::Vector3(250, 150, 250));
noktasalIsik->setDiffuseColour(Ogre::ColourValue::White);
noktasalIsik->setSpecularColour(Ogre::ColourValue::White);
}


2. Biz oluşturduğumuz noktasalIsik nesnesini, yani ışığı açıp kapatmak istiyoruz. Bu işlemi yaptığımız tamponlanmamisGirdiIslemleri fonksiyonumuzu, FrameListener sınıfının frameRenderingQueued fonksiyonuna kaydedeceğiz. Bu işlemi bir sonraki adımda yapacağız. Işığımızı kontrol etmek için kodlarımızı yazmaya başlayım. Farenin sol tuşuna basıp çektiğimizde ışığımızın açıksa kapanmasını, kapalıysa açılmasını istiyoruz. Teorik derste fare tuşuna bizim çok hızlı basıp çekmemizin bile bilgisayar tarafından, birkaç kare boyunca farenin tuşuna basılı tutmuşuz gibi algılanacağını söylemiştik. Bu durumu önlemek için iki farklı yöntem kullanacağız. İlk yöntemimiz için bir boolean değeri oluşturuyoruz. Boolean değişkenimizi static olarak tanımlıyoruz. Static olarak tanımladığımız, FrameListener sınıfı her kare için boolean değişkenini çağırdığında, boolean değeri ilk sefer hariç eşitlediğimiz değerle aynı olmayacak. Bir önceki karede ona atanan değeri taşıyacak. Bu static boolean değişkenimizin adı fareyeBasildi olsun. Değeri de false olsun. tamponlanmamışGirdiIşlemleri fonksiyonumuza ekleyelim:


bool Ders4::tamponlanmamisGirdiIslemleri(const Ogre::FrameEvent& evt) {
//------------------------------- İLK IŞIK KONTROLÜMÜZ --------------------------------
// Farenin tuşuna basılıp basılmadığının bilgisini tutacak:
static bool fareyeBasildi = false;
return true; }


3. OIS kütüphanesi klavyeden, fareden ve joystickten girdi almamızı sağlar. Bu kütüphaneyi projemizde aktif eden kodlar her zaman olduğu gibi BaseApplication’da hazır geliyor. Bir tuşa basıldığı zaman OIS kütüphanesi, o tuşla ilgili boolean değerini true olarak ayarlar. Biz OIS kütüphanesinin basılı tuşla ilgili boolean değerini, fareninDurumu adında bir başka boolean değeri oluşturup, yeni oluşturduğumuz boolean değerinin içinde saklayacağız. Az sonra yazacağımız mMouse, OIS kütüphanesinin Mouse sınıfından türetilmiş olan fare nesnemizdir. Tabii gerekli tüm işlemler Uygulama Sihirbazı tarafından BaseApplication sınıfında yapılmış durumda. mMouse nesnesinde getMouseState fonksiyonu üzerinden çağırdığımız buttonDown fonksiyonuyla bahsettiğimiz işlemleri gerçekleştireceğiz. buttonDown fonksiyonunun parametresindeki MB_Left komutu, farenin sol tuşunu temsil ediyor. Bahsettiğimiz işlemi tamponlanmamışGirdiIşlemleri fonksiyonumuza her şeyin altına “return true;” satırının üstüne şu satırları ekleyelim:


// Eğer OIS kütüphanesi farenin sol tuşuna baslıırsa bize true değerini döndürecek. Bu değeri de fareninDurumu'nda saklıyoruz:
bool fareninDurumu = mMouse->getMouseState().buttonDown(OIS::MB_Left);


4. Son eklediğimiz kod sayesinde eğer farenin sol tuşuna basılırsa fareninDurumu değişkeni true olacak. Şimdi bir if kontrolü oluşturalım. Eğer fareninDurumu true ve aynı zamanda fareyeBasildi değişkeninin değili(tersi) true, yani fareyeBasili değişkeni false ise if kontrolümüz aktif olsun. “&&” işareti “ve” mantık operatörüydü. “!” işaretiyle de dönen boolean değerinin tersini alıyorduk ya da eşit değildir olarak yorumluyorduk. İf kontrolümüzün içine bir ışık nesnesi oluşturacağız. Ama bu ışık nesnesi createScene fonksiyonumuzda oluşturduğumuz noktasalIsik nesnemizin yerine geçecek. Bu işlemi mSceneMgr nesnesi üzerinden getLight fonksiyonuyla gerçekleştireceğiz. Bu fonksiyonun parametresine de, noktasalIsik nesnemizi tanımlarken ilk parametresinde belirlediğimiz ismini yazıyoruz. İf kontrolünün içinde oluşturduğumuz ışık nesnesi üzerinden setVisible fonksiyonunu çağırıyoruz. Eğer fonksiyona true değerini atarsak ışık açılacak, false değerini atarsak ışık kapanacak. Ama biz setVisible fonksiyonunun parametresinde isVisible fonksiyonunu çağırıyoruz. Işığımız o an açıksa isVisible fonksiyonu bize true döndürecek. Bu fonksiyonun başına da “!” değil işaretini koyarak dönen değerin tam tersini almasını sağlıyoruz. Bu durumda setVisible fonksiyonunun için ışık açıksa false olacak, ışığı kapatacak; ışık kapalıysa true olacak, ışığı açacak. isVisible fonksiyonunun döndürdüğü değerin hep tersi yapılacak. İf kontrolümüzü tamponlanmamışGirdiIşlemleri fonksiyonumuza her şeyin altına “return true;” satırının üstüne şu satırları ekleyelim:


// fareninDurumu = 1 ve fareyeBasildi = 0 ise if kontrolümüz çalışacak:
if (fareninDurumu && ! fareyeBasildi) {
// Bir ışık nesnesi oluşturuyoruz ve createScene fonksiyonunda tanımladığımız noktasalIsik nesnesine eşitliyoruz:
Ogre::Light* isik = mSceneMgr->getLight("noktasalIsik");
// Eğer isik nesnesi görünürse, görünmez; görünmez ise, görünür yapılacak:
isik->setVisible(! isik->isVisible()); }


5. Şimdi de fareninDurumu değişkeniyle, fareyeBasildi değişkenini birbirine eşitleyeceğiz. Hatırlatalım. Eşitliğin sağ tarafındaki değişkenin tuttuğu değer, eşitliğin sol tarafındaki değişkenin tuttuğu değere eşitleniyordu. Biz fareninDurumu’nun değerini fareyeBasildi’nın değerine atayacağız.

Peki, bu işlem ne işimize yarayacak? fareninDurumu ve fareyeBasildi değişkenlerini eşitledikten sonra, uygulamayı çalıştırdık diyelim. Sürekli farenin sol tuşuna basili tutuyoruz. İlk karede, fareyeBasildi değişkeni false olduğu için ışığı kapattık. Sonraki her karede tekrarlanacak işlemler şöyle olacak: “1.işlem*fareninDurumu=1+, 2.işlem*if kontrolü 1 ve !(1) olduğu için çalışmayacak+, 3.işlem*fareninDurumu=1 olduğu için fareyeBasildi=1+”.

Sürekli fareye basili tuttuğumuzda durum üst satırdaki gibi olacak. Bir kez parmağımızı farenin sol tuşundan kaldırdığımızda işlemler: “1.işlem*fareninDurumu=0+, 2.işlem*if kontrolü 0 ve !(0) olduğu için çalışmayacak+, 3.işlem*fareninDurumu=0 olduğu için fareyeBasildi=0+”.

Sürekli farenin sol tuşuna basılı tuttuk, parmağımızı tuştan kaldırdık. Eğer şimdi tuşa basarsak işlemler: “1.işlem*fareninDurumu=1+, 2.işlem*if kontrolü 1 ve !(0) olduğundan çalışacak. Işık ayarı değişecek+, 3.işlem*fareninDurumu=1 olduğu için fareyeBasildi=1+”. Gördüğünüz gibi bu iki boolean değerini birbirine eşitlemek tuşa sürekli bastığımızda ışığın sürekli açılıp kapanmasını engelleyecek. Şuan işlem iki paragraf üstteki işlemlerle aynı oldu.

Şimdi bahsettiğimiz eşitleme işlemini, tamponlanmamışGirdiIşlemleri fonksiyonumuza her şeyin altına “return true;” satırının üstüne şu satırları ekleyelim:


// fareyeBasildi değişkeninin içine fareninDurumu değişkenini atıyoruz: fareyeBasildi = fareninDurumu;


tamponlanmamışGirdiIşlemleri fonksiyonumuzun son hali şu şekilde olmalı:


bool Ders4::tamponlanmamisGirdiIslemleri(const Ogre::FrameEvent& evt) {
//------------------------------- İLK IŞIK KONTROLÜMÜZ --------------------------------

// Farenin tuşuna basılıp basılmadığının bilgisini tutacak:
static bool fareyeBasildi = false;

// Eğer OIS kütüphanesi farenin sol tuşuna baslıırsa bize true değerini döndürecek. Bu değeri de fareninDurumu'nda saklıyoruz:
bool fareninDurumu = mMouse->getMouseState().buttonDown(OIS::MB_Left);

// fareninDurumu = 1 ve fareyeBasildi = 0 ise if kontrolümüz çalışacak:
if (fareninDurumu && ! fareyeBasildi) {
// Bir ışık nesnesi oluşturuyoruz ve createScene fonksiyonunda tanımladığımız noktasalIsik nesnesine eşitliyoruz:
Ogre::Light* isik = mSceneMgr->getLight("noktasalIsik");
// Eğer isik nesnesi görünürse, görünmez; görünmez ise, görünür yapılacak:
isik->setVisible(! isik->isVisible()); }

// fareyeBasildi değişkeninin içine fareninDurumu değişkenini atıyoruz:
fareyeBasildi = fareninDurumu; return true;
}


6. tamponlanmamisGirdiIslemleri fonksiyonumuzu render döngüsüne dâhil etmek için FrameListener sınıfımızın frameRenderingQueued fonksiyonuna kaydetmemiz gerekiyor. tamponlanmamisGirdiIslemleri fonksiyonunu bir if kontrolü içinde frameRenderingQueued fonksiyonuna eklememiz gerekiyor. Eğer tamponlanmamisGirdiIslemleri fonksiyonumuz false döndürürse, frameRenderingQueued fonksiyonunda false döndürerek render döngüsünü durduracak, render döngüsü durduğu için uygulamamızda kapatılacak. Tabii bu durumun if kontrolü içinde geçerli olması için tamponlanmamisGirdiIslemleri fonksiyonumuzun başına “!” koyarak yazıyoruz. Bu işlemi eklediğimizde frameRenderingQueued fonksiyonu, şu şekilde olacak:


bool Ders4::frameRenderingQueued(const Ogre::FrameEvent& evt) {
bool ret = BaseApplication::frameRenderingQueued(evt);
// Eğer tamponlanmamisGirdiIslemleri fonksiyonumuz 0 değerini döndürürse programımız kapatılacak:
if(!tamponlanmamisGirdiIslemleri(evt)) return false; return ret;
}


Projemizi derleyip çalıştıralım. Farenin sol tuşuna tıkladığınızda ışık açılıp kapanacak:

http://ustaderslik.com/resim/ders/tfpx4.png
http://ustaderslik.com/resim/ders/tfpx7.png



Kod
Kalın
Vurgu
Resim
Video
Url
CEVAPLA
Tüm Hakları Saklıdır. ©Arleone 2013-2014 UstaDerslik






Giriş
Şifremi Unuttum...
Şifre Talep
  Kuralları Kabul Ediyorum.
Kaydol