15 Nisan 2008 Salı

Managed Directx Bölüm - 2

Bu bölümde Direct3D üzerine yoğunlaşacağız. Ve Direct3DX'in bazı yardımcı fonksiyonlarını göreceğiz.

Adapters

DirectX'te, sistemimizde kullandığımız adaptör ya da birden fazla ise adaptörler(örneğin ekstradan bir 3D Accelerator kartımız varsa) hakkında bilgi veren birtakım fonksiyonlar var. Hemen şunu da belirtelim managed DirectX ile unmanaged kullanım arasındaki en temel fark; .NET öncesi programlama dillerinde DirectX kullanmaya kalktığımızda yapmamız gereken ilk iş "DirectXn"(n=DirectX sürümü) tipinde bir master obje tanımlayıp diğer bileşenleri, vs. bundan türetmemiz gerekiyordu. Managed kullanımda ise yukarıda da belirttiğimiz alt nesneleri direkt olarak türetebiliyoruz. Her neyse... DirectX'te adaptörümüz hakkında bilgi edinmemizi sağlayan hazır bir fonksiyon var adı da "AdapterDetail". Kullanımı aşağıdaki gibi;

AdapterDetail adaptor_bilgisi;
int i;

For(int i = 0;i< Manager.Adapters.Count – 1,i++)
 {
 adaptor_bilgisi = Manager.Adapters(i).Information
 MessageBox.Show (adaptor_bilgisi.Description)
 }

Yukarıdaki kodda adaptörler hakkında bilgiyi getiren fonksiyonun yanında bir de Manager isimli, Direct3D ile ilgili temel işlemleri yerine getiren bir obje var.

Device

DirectX'in sunduğu özel bir nesne tipi "Device" 3D hızlandırıcı katmana erişmemizi sağlar. Her bir adaptör için üç Device tipinden birini seçmeliyiz. Bunlar;

- Hardware(Hardware Abstraction Layer):HAL(Donanım Soyutlama Katmanı) device türettiğimizde direkt donanım özelliklerine ve dolayısıyla da yüksek bir hıza erişiriz. Bu tip bir aygıtı türetirken sistemimizde 3D hızlandırıcı kartımız yoksa(ki yeni ekran kartlarının hepsi bu özellikte) DirectX hata verecektir.

- Reference(Reference Resterizer):Bu tip bir device türettiğimizde her şey software tarafından yapılacak ve türettiğimiz device donanım bağımsız olacaktır. Ancak bu tip bir Device ile oyun yazmayı aklınızdan bile geçirmeyin çünkü inanılmaz yavaş olacaktır( işlem hızı yaklaşık 1-5 fps arasında).

Device classından bir instance aldığımızda classın Constructor'ına girmemiz gereken parametreler sırasıyla aşağıdaki gibidir;

- Adapter:Burada Default adaptörümüzü kullanacağımızı belirtmek için Manager objesini kullanacağız.
- DeiceType:Amacımız bir oyun yazmaksa tabii ki Hardware seçilecek.
- WinHandle:Aygıtın sunum yapacağı pencerenin Handle'ı(Intptr.)
- Create Flags:Bir enumeration'dır. Seçilebilecek Flaglar aşağıdaki gibidir;
   -SoftwareVertexProcessing:En ideal seçenek, DirectX'e bütün vertex hesaplamalarının Software tarafından yapılacağını bildirir. Bu seçenek en yavaş çalışan seçenektir ama her durumda kullanılabilir.
   -HardwareVertexProcessing:Bu seçenek DirectX'in yazılım katmanında kullanılan Shading(gölgeleme) ve Lighting(ışıklandırma) işlemleri hariç tüm vertex işlemleri için donanımı kullanmasını sağlar. 
   -MixedVertexProcessing:İsminden de anlaşılacağı üzere en iyi performans için iki prosesin karışımını kullanır.
- PresentationParameters:Adından da anlaşılacağı gibi programcının device’ın sunumu için kullanabileceği birtakım ince ayarlar sunar. Sunduğu özellikler aşağıda açıklanmıştır;

- EnableAutoDepthStencil:Depth Buffer tabir edilen derinlik tamponu, Direct3D tarafından kullanılmak üzere derinlik bilgilerini saklayan bir Device özelliğidir. Bu konunun kavranması için derinlik algısı örneği geldi aklıma. Tek gözünüzü kapattığınızda, bakış açınıza göre, x ve y eksenleri aynı, z eksenleri farklı olan iki noktadan hangisinin size daha yakın olduğunu ayırt edemezsiniz. İşte size depth buffer’in yaptığı iş. Render edilen yüzeye yakın olan cisimler ile uzak olan cisimlerin ayırt edilebilmesi için gerekli z ekseni(derinlik) bilgilerini tutar. EnableAutoDepthStencil ise True ya da False değerlerini alır.
- AutoDepthStencilFormat:Depth Buffer’da kullanılan format. Bu format değeri geçerli bir depth buffer formatına setlenmelidir. Mesela “DepthFormat.D16” 16
bitlik bir depth buffer belirtir.
- BackBufferCount:1 ile 3 arasında değişen Back Bufferların numarası.
- BackBufferFormat: Format enumeration’u ile belirtilmiş her bir buffer’in formatı. Örneğimizde mevcut görüntü formatını kullanıyoruz. Burada girilen format stencil’de olduğu gibi geçerli bir format olmalıdır. Direct3D’nin CheckDeviceType methodu ile geçerli formatlar kontrol edilebilir. Windowed modda çalışılacaksa bu değere Unknown setlenerek mevcut görüntü ayarlarıyla çalışılabilir.
- BackBufferWidth ve Height:BackBuffer’in pixel cinsinden genişliği ve yüksekliği. Eğer windowed modda çalışılmıyorsa, bu değerler, CheckDeviceType methodu ile alınan görüntü formatlarından birisine uymalıdır.
- SwapEffect:Oyunun render edilme aşamasında back buffer’dan ekrana gönderilen her bir karenin(front buffer) oluşturduğu bir akış söz konusudur. Render methodumuz çağırıldığında ekrandaki görüntü bir önceki ile değiştirilir(swap). İşte bu değişim esnasında kullanılan SwapEffectleri; Dicard, Flip ve Copy efektleridir. Bunlar sırasıyla aşağıda açıklanmıştır;

o Discard:Bu efekt titpinde değiştirme işlemi(swap)  sırasında back buffer’ın içeriği korunmaz. Bu yüzden her kare (frame) için içerik yenilenmelidir.
o Flip:Bu efektte bufferların ekrana aktarılması swap chain denilen bir değiştirme zinciri ile yapılır. Front bufferları(ekran) içeren döngüsel bir sıra gibi düşünülebilir. Bu sıra içerisinde back bufferlar sıfırdan n-1’e kadar numaralanırlar(n = back buffer sayısı). Bu sıralamada 0 numaralı back buffer en son gösterilendir. Döngü devam ederken front buffer(n-1) back buffer, back buffer(0) da front buffera dönüşür ve bu şekilde devam eder.
o Copy:Bu efektte ise back buffer’ın içeriği korunur. Back buffer’ın içeriği front buffer’ın üzerine kopyalanır.

- Windowed:True değerini aldığında pencere, false değerini aldığında da tam ekran modunda çalışılacağını belirtir. Pencere modunda çalışıldığında back buffer formatı arka plan çözünürlüğü ile aynı olmalıdır. Ben bunun için aşağıdaki yöntemi kullanıyorum;

gmodu = Manager.Adapters [Manager.Adapters.Default.Adapter].CurrentDisplayMode;
PresentParameters d3dpp = New PresentParameters();
d3dpp.BackBufferFormat = gmodu.Format;

Pencere modunda çalışırken BackBufferWidth ve Height parametreleri verilmek    zorunda değildir. Tam ekran modunda ise width ve height parametreleri kullanılabilir bir ekran çözünürlüğü ile örtüşmelidir.
- DeviceWindowHandle:DirectX tarafından kullanılacak pencerenin handle’ı(Intptr).

Yukarıdaki hikaye kısmını anlattığımıza göre asıl işimize, yani .X dosyalarımızın ve texturelerimizin yuklenmesine gelelim. Burada amacım device, presentation parameters gibi bileşenleri ayarladıktan sonra .X dosyasını yüklemenin ne kadar kolay olduğunu göstermek. Bu amaçla directX’te kullanılan iki nesneden bahsedeceğim; “mesh” ve “texture”. 

“mesh” ve “texture” nedir, nasıl kullanılır?

Mesh, DirectX’te ingilizcedeki anlamına yakın bir anlamda kullanılıyor. 3D animasyon yapanlar bilirler ki, yapılan çizimler ikiye ayrılır; katı modeller ve sadece yüzeylerden oluşan meshler. İşte kullanacağımız 3D modellerimiz bu, sadece yüzeylerden oluşan meshler yani .X dosyaları. Texture ise bu yüzeylere kaplanacak bitmap dosyaları.

Kaynak: Öğretim Görevlisi Murat Güneş

Hiç yorum yok: