Sayfalar

1 Eylül 2010 Çarşamba

ogre3D ve temel sınıflar ve dosyalar – bölüm 2

Temel sınıfları anlattığım Ogre3D ve temel sınıflar ve dosyalar – bölüm 1 başlıklı yazıdan sonra sıra “exampleApplication.h” ile “exampleApplicationListener.h” dosyalarını incelemekte…

Diğer bir önemli dosyamız da “ExampleApplication.h”tır. Bu dosya ile birlikte çalışacak diğer önemli bir dosya da “ExampleFrameListener.h” dosyasıdır. Bu iki dosya daha önceden de bahsettiğim gibi bazı temel değişkenleri içermektedirler. Ancak bu iki dosya arasında temel bir farklılık söz konusudur. Birinci dosyamız yani ExampleApplication dosyamız projemizinde yer almasını istediğimiz temel nesneleri yerleştirdiğimiz kısımken, ExampleFrameListener dosyamız da bu nesnelerin nasıl ve neye göre hareket edeceklerini tanımladığımız kısımdır diyebiliriz. Ancak bu zaruri bir durum değildir. Yani projenizin iki sınıfı da miras alıp birincisinde uygulama diğerinde de hareket olacak şekilde zorlamak zorunda değilsiniz. Yani daha ileri bir seviye Ogre’ci olduğunuzda bunu halledebilecek konuma erişirsiniz ama halihazırda ben de yapamıyorum o yüzden projenizin uygulama kısmını ExampleApplication‘u miras aldırarak, hareket kısmını da ExampleFrameListener‘ı miras aldırarak ilerlemek mantıklı olacaktır.

Şimdi ExampleApplication dosyasının içindeki ExampleApplication sınıfında tanımlanmış bazı değişken ve fonksiyonlara bir göz atalım şimdi. İlk önce “protected” alanda tanımlanmış olan değişkenlere bir göz atalım.

  • Root *mRoot;
  • Camera* mCamera;
  • SceneManager* mSceneMgr;
  • ExampleFrameListener* mFrameListener;
  • RenderWindow* mWindow;
  • Ogre::String mResourcePath;

Bunlardan bazılarını bu yazı dizisinin birinci bölümünde görmüştük. Şimdi görmediklerimizle devam edelim.

“ExampleFrameListener* mFrameListener;” ExampleFrameListener yukarıda bahsettiğim gibi hareketlerin olduğu sınıf ve bu kod satırı sayesinde de o sınıftan “mFrameListener” adı altında bir değişken üretmiş olduk.

“Ogre::String mResourcePath; satırı da bizim kaynakları nerede tutacağımızı elle yazmamız için string sınıfından üretilmiş bir değişkenden ibarettir ve string ifadeleri tutmaktan öteye pek bir işlevi yoktur. ExampleApplication sınıfının constructor‘unda tanımlı olan mResourcePath‘ın değeri eğer ki uygulamanın çalıştığı platform MAC OS değilse ” ” olacak şekilde ayarlanmış.

Şimdi ExampleApplication’daki değişkenleri bitirdiğimize göre sıra geldi fonksiyonlara.

ExampleApplication sınıfında daha öncedenbahsettiğim go() fonksiyonu tanımlıdır. Bu fonksiyon render işleminin yapılmasını sağlamaktadır. Ancak bu işlem için hem root sınıfından üretilmiş bir değişkene yani mRoot‘a hem de root sınıfının bir fonksiyonu olan startRendering() fonksiyonuna ihtiyaç vardır( Örnek Resim 01 ) . Go() fonksiyonu setup() fonksiyonundan false dönmesi dahilinde bitirlecek şekilde tasarlanmış. Böylece setup() çalışmadan renderleme işlemi de çalışmayacaktır.

Şimdi de setup fonksiyonuna bir göz atalım ( “virtual bool setup(void)” ) Bu fonksiyon ilk önce mRoot değişkenine değer atayarak başlamış. Bu değer atama sırasında pluginlerin tutulduğu “plugin.cfg” dosyası ile birlikte ekran ayarlamalarını yaptığınız diyalog ekranının çıktılarını tutan “ogre.cfg” dosyası ve tüm hareketlerin ( kayıt edilmesi istenilen hareketlerin ) kayıtlarınıtutan “ogre.log” dosyası değişken olarak eklenmiş:

mRoot = OGRE_NEW Root(pluginsPath,
mResourcePath + “ogre.cfg”, mResourcePath + “Ogre.log”);

mRoot değişkeniyle işlemler bittikten sonra setup() fonksiyonunun devamına baktığımızda aşağıda çalıştırdığı bazı fonkisyonları görebilirsiniz.

  • chooseSceneManager();
  • createCamera();
  • createViewports();
  • createScene();
  • createFrameListener();

” chooseSceneManager(); “ fonksiyonu sahne yöneticisinin seçimini yapmak için yapılandırılmış bir fonksiyondur. ” mSceneMgr = mRoot->createSceneManager(ST_GENERIC, “ExampleSMInstance”);Satırında da görülebileceği gibi mRoot değişkenine createSceneManager() fonksiyonu sayesinde belirlenen değişkenler çerçevesinde sahne yöneticimizi oluşturmuş bulunmakta. Fonksiyona ilk parametre olarak girilen değişkenler şunlar olabilir:

  • ST_GENERIC : En küçük sahne yöneticisi yapısıdır. Herhangi bir sahne içeriği veya yapısı için optimize edilmemiştir. Temel düzeydeki sahneler için idealdir.
  • ST_INTERIOR : Bu seçenekte sahne yöneticisi yapısı iç mekanları renderlemek için optimize edilmiştir.
  • ST_EXTERIOR_CLOSE : Sahne yöneticisi yapısı orta seviyede görünürlüğe sahip dış mekanları renderlermek için optimize edilmiştir.
  • ST_EXTERIOR_FAR : Artık pek tercih edilmeyen bir seçenekmiş kendsisi hatta yerine ST_EXTERIOR_CLOSE veya ST_EXTERIOR_REAL_FAR kullanılması tercih edilirmiş.
  • ST_EXTERIOR_REAL_FAR : Sahne yöneticisi yapısı en geniş evrenleri haritaları yüzeyleri de desteklemeye uygundur.

İkinci parametre olarak bir isim girmenizde fayda var ancak boş bırakırsanız da otomatik bir isimlendirme yapılacaktır fonksiyon tarafından.

virtual void createCamera(void)fonksiyonunda mCamera değişkenimiz sahnemize “PlayerCam” adı altında yaratılmıştır. Bu isimlendirme işleminde tek dikkat etmeniz gereken husus başka bir nesnenin adı ile çakışmamasıdır. Kameramızın konumu Z ekseninde 500 br öteye çekilmiştir ve yine Z ekseninde arkaya bakması için -300‘e bakması söylenmiştir.

virtual void createViewports(void)fonksiyonu ise kameranın görüş alanını ayarlayan fonksiyondur desem mantıklı olur sanırım, şöyle ki; kameranın görüntüsünün taraf oranı gibi özellikleri ( 4:3, 16:9 gibi ) viewport‘un özellikleridir.

Render sınıfından üretilen mWindow değişkeni, viewport‘tan üretilen vp değişkenine atanmış. ” vp->setBackgroundColour (ColourValue(0,0,0)); “kod satırı ile de evrenimizin arkaplan kaplaması atanmazsa diye arkaplanın rengini siyah yapılmıştır. mCamera-> setAspectRatio( Real( vp->getActualWidth()) / Real( vp->getActualHeight())); kod satırı ekranın yüksekliğini ve genişliğini alıp bunları kameranın taraf oranına eklenmiş oluyor. Yan taraftaki resim için iki farlı taraf oranı değeri girilmiştir ve arkaplan rengi için de turuncu rengi ayarlanmıştır( mCamera->setAspectRatio(16/9) - sol, mCamera->setAspectRatio(2/1) - sağ, ColourValue(1,0.5,0) - Arkaplan Renk Değerleri).

virtual void createScene(void) = 0;, işte bu fonksiyona, özellikle de fonksiyonun sıfıra eşitlenmesine dikkat! “createScene” bizim sahnemizi oluşturduğumuz fonksiyondur ancak fonksiyon boş olarak tanımlanmış, içeriğini doldurmak da miras alan sınıfa kalmıştır. Bu benim de yeni öğrendiğim bir konu oldu ama bu tarz fonksiyonların adı “Saf Sanal Fonksiyonlar”dır ve konu hakkında daha detaylı bilgi almak isteyenleri Esat‘ın bloguna yönlendirmemde sakınca yoktur sanırım :) Code::Blocks’da yeni bir proje oluşturduğunuz zaman ExampleApplication sınıfını miras alan sizin yeni projeniz bu fonksiyonu protected alanda içi temel birkaç nesne ile doldurmuş şekilde sunuyor.

virtual void createFrameListener(void) olarak tanımlı foknsiyon da bizim sahnemizde nesnelerin sürekliliğinin sağlandığı sınıfımızdır. Projelerinizde yapı gereği ExampleApplication sınıfını miras alan sizin Application sınıfınız ile ExampleFrameListener‘ı miras alan Listener sınıflarınızın olması mantıklı olacaktır. Şimdi süreklilik ile kastımı ufak bir proje örneğiyle şekillendirmeye çalışayım. Diyelim ki siz Application sınıfınızda içerisinde ana karakteriniz ve onun kullanacağı taşıtı ile birlikte ev, ağaç, çiçek vb nesnleler tanımlayıp sahneye yerleştirdiniz.Ancak bunlardan kimilerinin hareketlenmesine ihtiyacınız var, örneğin taşıt ile karakter gibi hatta çiçeklerin salınım hareketi bile olabilir sanki rüzgar esiyormuş gibi. Bunu ister bu nesneleri global birer değişken olarak tanımlayacak şekilde yapabiliriz, istersek de Application sınıfında tanımlayıp Listener sınıfına çalıştıracağımız fonksiyon aracılığıyla gönderebiliriz. Bu çalışacak olan fonksiyon da createFrameListener fonksiyonudur. Burada “mFrameListener= new ExampleFrameListener( mWindow, mCamera );kod satırı ile mWindow ile mCamera değişkenleri ExampleFrameListener sınıfına gönderiliyor. Dediğim gibi istersek buraya yeni bir değişken daha ekleriz, bu örneğin karakterimizin sceneNode değişkeni olabilir, ancak buna uygun bir şekilde ExampleApplicationListener sınıfını da düzenlememiz gerekir. Biz bu yüzden bu temel sınıflarda değişiklik yapmadan kendi yarattığımız Application ve Listener sınıflarında bahsettiğim değişiklikleir yapıyoruz. Bu kısımlara ilerleyen yazılarda devam edeceğim. Şimdilik amaç temel mantığı kazandırmak olduğu için teorik olarak devam ediyorum. Bir şekilde Listener sınıfımıza bizim karakterimizin sceneNode‘unu göndermeyi başardık diyelim, şimdi bize bu karakterin hangi durumda nasıl hareket edeceğini anlatmak kalıyor tek yapılması gereken. Örneğin klavyeden “ W “ya basınca ileri hareket etmesi gibi…

ExampleApplication hakkında bu kadar temel bilgi yeterli sanırım. Sıra geldi o zaman ExampleFrameListener‘a… :)

Hiç yorum yok:

Yorum Gönder