Bu yazımda sizlere mobil dünyanın standart 2d boyutundan 3. Boyuta geçmenin yöntemlerinden yani Direct3D’den bahsedip küçük bir uygulamayla bir direct3d penceresini çalıştıracağız. Bu uygulamamızda ki amaç mobil cihaz üstünde nasıl Direct3D programlama yapabileceğimizi incelemek. Küçük bir demo ile de pekiştireceğimiz bu dünya, geleceğin en temel teknolojisini yani windows mobile cihazlarımızda 3 boyutlu bir dünyaya merhaba dememizi sağlamaktadır. Klasik görünümünden sıyrılıp tam bir bilgisayar olduğunu anlamımıza yarayacak. Şu aşamada XNA’in desteklediği platformlar üstünde windows mobile olmadığı için bu cihazlarda direct3d kullanmaktayız.
Öncelikle temel olarak hangi referanslara ihtiyacımız olduğunu burada belirtmek isterim;
using Microsoft.WindowsMobile.DirectX;
using Microsoft.WindowsMobile.DirectX.Direct3D;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;
Klasik referanslarımız olan DirectX argümanlarına WindowsMobile isim uzayı altından ulaşmaktayız. Bunun için DirectX’in ve SDK’larının bilgisayarınızda kurulu olması gerekmektedir. Using cümleciğiyle ihtiyacımız olan namespaceleri tanımlamış bulunmaktayız. Ardından Direct3D aygıtı için değişken tanımlamamız gereklidir.
Bunun içinde;
şeklinde aygıtımızı tanımladık. Artık 3 boyutlu dünyaya mobil cihazımızda merhaba demiş bulunuyoruz. Bunun için ilk aygıtımızın (Device) ayarlamalarıyla mobil cihaza uygun hale getirmek için gerekli kod parametrelerini vermek istiyorum. Bu sayede programlamaya hazır bir Direct3D penceresi karşımıza gelecektir. Kullanmamız gereken diğer namespace’ler;
using System;
using System.Drawing;
using System.Windows.Forms;
ardından ana sınıfımız ve kurucu metodumuz;
// Uygulamanın ana sınıfı
public class DeviceYarat : Form
{
// Uygulamamızın global değişkeni bundan sonra aygıt diye anacağız
Device device = null;
public DeviceYarat()
{
// başlığı düzenle
this.Text = "D3D dünyasına hoşgeldin";
this.MinimizeBox = false;
}
}
Penceremizin üstünde D3D dünyasına hoşgeldin yazacaktır. Bu uygulama Direct3D programlamanın iskeletini içermektedir. Aşağıdaki metottaki presentparameters sınıfı aygıt oluşturulurken gerekli olan bazı parametreleri içinde bulundurmaktadır. InitializeGraphics metodunda ise; presentParams.Windowed = true ile uygulamanın bir pencereye sahip olacağını söylemektedir.
public bool InitializeGraphics()
{
try
{
PresentParameters presentParams = new PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Default, this,
CreateFlags.None, presentParams);
}
catch (DirectXException)
{
return false;
}
return true;
}
Aygıt dediğimiz device sınıfı ise burada canlanacak ve aldığı parametrelerin anlamları ise şöyledir; İlk 0 olan parametre System.Int32 türünden bir değer oluğ D3D uygulamadaki adaptörlerin sıra numarasıdır, varsayılan parametre ise 0’dır.
İkinci parametre olan devicetype ise aşağıdaki değerlerden birini alabilmektedir;
DeviceType.Hardware
DeviceType.Reference
DeviceType.Software
Biz burada default olanını seçtik. Diğer parametre ise görüntüyü gösterebileceğimiz pencere olarak o anki çalışan pencereyi seçmek için this anahtar kelimesini kullandık. CreateFlags ise uygulamada kullanılacak olan özellikler kümesini kendinde barındırmaktadır. Yine belli bir değer seçmemize rağmen brada seçebileceğimiz bayrakları belirtelim;
CreateFlags.AdapterroupDevice
CreateFlags.DisableDriverMAnagement
CreateFlags.MixedVertexProcessing
CreateFlags.HardwareVertexProcessing
CreateFlags.SoftwareVertexProcessing
CreateFlags.PureDevice
CreateFlags.Mutithreaded
Örnek olarak CreateFlags.HardwareVertexProcessing; tüm bağlantı noktalarının donanımda işleyeceğini söylemektedir. Son parametre ise PresentParameters sınıfından türettiğimiz ve yukarıda anlattığım özellikleri aygıta kazandırır.
private void Render()
{
if (device != null)
{
device.Clear(ClearFlags.Target, System.Drawing.Color.Blue,
1.0f, 0);
device.BeginScene();
device.EndScene();
device.Present();
}
}
Aygıtımızı ayarladıktan sonra sıra render işlemlerine geldi. Render metodumuzda öncelikle render işlermelerine başamadan aygıtımızı ve önbelleğimizi(buffer) temizliyoruz bunun içinde Clear metodunu kullanırken bazı parametreler vermekteyiz. Bunlar; ClearFlags.Target yani belirli bir hedefe göre temizlerken ikinci parametre ise temizledikten sonra mobil cihazımızın ekranının alacağı renktir. Üçüncü parametre derinlik tamponunun değeridir. 1.0f ile herşeyi sıfırlamış oluyoruz. Ardından render işlemine başlamak için BeginScene metodunu kullanıyoruz bu sayede aygıtın çizime hazır olduğunu belirtmekteyiz. Her BeginScene yaptığımızda EndScene’de kullanmalıyız çünkü endscene yapmadan bir daha beginscene metodunu çağıramayız. Fakat bu çağrılar ekranımızı güncellememizi sağlamaz bunun için ekranı güncellemek için ise present metodunu kullanmaktayız.
Diğer olaylarımıza bakmak istersek;
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
this.Render();
this.Invalidate();
}
protected override void OnPaintBackground(
System.Windows.Forms.PaintEventArgs e)
{
}
Bu sayede çıkış tuşuna basıldığında programdan çıkılacaktır.
protected override void OnKeyPress(
System.Windows.Forms.KeyPressEventArgs e)
{
if ((int)(byte)e.KeyChar == (int)System.Windows.Forms.Keys.Escape)
this.Close();
}
Main metodumuz;
static void Main()
{
DeviceYarat frm = new DeviceYarat();
if (!frm.InitializeGraphics())
{
MessageBox.Show("Direct3D başlatılamadı. " +
"programdan çıkıldı.");
return;
}
Application.Run(frm);
}
Gördüğünüz gibi Main metodumuzda ana sınıfımızdan bir nesne yaratarak küçük bir if deyimi ile yazdığımız InitializeGraphics() metodumuzun geri dönüş değerini kontrol edip uygulamamızı çalıştırıyoruz.
Çıktımız;