|
DirectX Direct.Input Alt Yapısı
Bu makalemizde directX'in kullanıcılar ile etkileşimi sağlayan Direct.Input
sınıfını inceleyeceğiz. Ayrıca
şimdiye kadar öğrendiğimiz DirectX mimarisi ile oluşturacağımız projeyi
screen saver(ekran koruyucu) olarak tasarlayacağız.
Uzun süre
sabit görüntü gösteren monitörlerde bir süre sonra görüntülerde bozukluk başlar.
Bunun ana nedeni monitörde uzun süre aynı bölgenin aynı ışığı vermesidir. Bunun
önlenmesi için ekran koruyucular tasarlanmıştır. Ekran koruyucuların görevi
devamlı olarak aynı görüntünün monitör üzerinde kalıp monitörün kalıcı bir hasar
almasını önlemektir. Ekran koruyucuların bir diğer faydası ise eğer ekran
koruyucunuza parola girişi yaptıysanız, siz bilgisayarın başında değilken başka
bir kişinin ilgili parolayı girmeden monitörü açamaması ve ekranda olabilecek
önemli bilgileri okuyamaması, sizin adınıza kritik işlemler yapamamasıdır. Tüm
ekran koruyucu programları WINDOWS\system32 dosyası altında .scr uzantılı olarak
bulunurlar. Bir ekran koruyucu program kendini masaüstünde sağ tuşa basıp
özellikler dedikten sonra ekran koruyucu bölümüne atması için kendini
bilgisayarın kütüğüne kayıt etmesi gerekmektedir(register). Programlar bu işlemi
yapabilmek için Start/Run/Regedit komutuyla sizin regedit üzerinden ellede
yapabileceğiniz gibi HKEY_CURRENT_USER\Control Panel\Desktop.scrnsave.exe
kayıdına kendi yollarını girmek zorundadırlar. Kendi yollarını girerkende yolu
WINDOWS\system32 altına ve dosya uzantısı olarak da .scr olarak vermeleri
gerekmektedir. Bu işlem yapıldıktan sonra ilgili program kendini ekran koruyucu
olarak kaydetmiş olacaktır. Ekran koruyucu olarak bir programı ayarlayabilmek
için programı tam ekran ve taskbar gözükmeyecek şekilde ayarlamak gerekmektedir.
Ekran koruyucu herhangibir tuşa basıldığında ya da mouse koordinatları üzerinde
bir değişiklik yapıldığında otomatik olarak kendini kapatacaktır. DirectX ile
oluşturduğumuz yazılıma setup projesi ekletip setup projesinde yukarıdaki
anlatılan işlemler yapıldığında, görüntü özelliklerine yazdığımız ekran
koruyucunun eklenmiş olduğunu görebiliriz.
this.WindowState= FormWindowState.Maximized;
this.Text = "mehmet ali ecer";
ShowInTaskbar = false;
this.ShowIcon=false;
this.TopMost=true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ScreenSaverForm_MouseMove);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ScreenSaverForm_KeyDown);

Bunun için ise program içerisinde mouse'da ya da klavyede bir işlem yapılıp yapılmadığı kontrol
edilmelidir. Bu kontrol işleminde DirectX'in bize sunduğu Direct.Input uzayını
kullanacağız. Direct.Input içerisinde kullanıcı ile etkileşimi sağlayan üç temel
giriş elemanını yönetirsiniz. Bunlar fare,klavye ve joystick'dir. Bu giriş
elemanları için şimdi Direct.Input alt yapısını tasarlayalım.
//klavye aygıtı
keyboard = new Device(SystemGuid.Keyboard);
if(keyboard == null)
throw new Exception("Klavye aygıtı
bulunamadı..");
//fare Aygıtı
mouse = new Device(SystemGuid.Mouse);
if(mouse == null)
{
throw new Exception("Fare aygıtı
bulunamadı.");
}
//joystick aygıtı
foreach(
DeviceInstance di in
Manager.GetDevices(
DeviceClass.GameControl,
EnumDevicesFlags.AttachedOnly))
{
joystick =
new Device(di.InstanceGuid);
break;
}
if(joystick == null)
{
throw new Exception("joystick aygıtı bulunamadı.");
}
Bu üç temel bilgisayar giriş elemanı bilgisayar üzerinde başka yapılar
tarafından kullanıldığı ya da kullanılabileceği için sistem kaynakları
ayarlaması gerekmektedir. Bu üç aygıtın SetCooperativeLevel fonksiyonu ile
CooperativeLevelFlags özellikleri verilmelidir.
 

Bu özelliklerle kaynağın nasıl kullanılacağını yönetir.
CooperativeLevelFlags'leri;
CooperativeLevelFlags.Background Bu aygıt arka planda kullanılır, eğer
program masaüstü üzerinde aktif bile olmasa gerektiğinde alınılır ve kullanılır.
CooperativeLevelFlags.Foreground Sadece çalışan ekran arka planında
kullanılır.Eğer ekran seçim özelliğini yitirirse aygıtada erişim gider.
CooperativeLevelFlags.Exclusive Çok mecburi durumlarda kullanılır.
Kaynağı tek başına kullanır ve başka istekleri reddeder. Fare ve klavye için bu
bayrak kullanılamaz.
CooperativeLevelFlags.NonExclusive Aygıt diğer kaynaklarla
paylaşılır.Paylaşılan durumlarda aygıt hemen alınamaz.
CooperativeLevelFlags.NoWindowsKey Window kısayollarını kapatır.
Aygıtların Flag'lere göre aygıtların SetCooperativeLevel ve duyarlıkları da
ayarlanması aşağıdaki gibi yapılabilir.
foreach(DeviceObjectInstance doi in joystick.Objects)//Joystick duyarlığı
ayarlanıyor.
{
if((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0)
{
joystick.Properties.SetRange(
ParameterHow.ById,
doi.ObjectId,
new InputRange(-5000,5000));
}
}
joystick.Properties.AxisModeAbsolute = true;
keyboard.SetCooperativeLevel(
this,
CooperativeLevelFlags.NonExclusive |
CooperativeLevelFlags.Background);
mouse.SetCooperativeLevel(
this,
CooperativeLevelFlags.NonExclusive |
CooperativeLevelFlags.Background);
joystick.SetCooperativeLevel(
this,
CooperativeLevelFlags.NonExclusive |
CooperativeLevelFlags.Background);
//Acquire devices for capturing.
keyboard.Acquire();
mouse.Acquire();
joystick.Acquire();
Üç temel giriş elemanını tanımladıktan sonra bu üç eleman üzerinden gelen
girişleri yakalamak için bu aygıtların nasıl kullanılacağı aşağıda
gösterilmiştir.
Klavye Girişleri İçin
foreach(Key k in keyboard.GetPressedKeys())
{
info += k.ToString() + " ";
}
Fare Girişleri İçin
MouseState state = mouse.CurrentMouseState;//fare konum koordinatlarını almak
için
info += "X:" + state.X + " ";
info += "Y:" + state.Y + " ";
info += "Z:" + state.Z + " ";
byte[] buttons = state.GetMouseButtons();//fare üzerinde
bulunan butonlar için
for(int i = 0; i < buttons.Length; i++)
{
if(buttons[i] != 0)
{
info += "Button:"
+ i + " ";
}
}
Joystick Girişleri İçin
JoystickState state = joystick.CurrentJoystickState;
info += "X:" + state.X + " "; //koordinat
noktaları için
info += "Y:" + state.Y + " ";
info += "Z:" + state.Z + " ";
//buton hareketleri
byte[] buttons = state.GetButtons();
for(int i = 0; i < buttons.Length; i++)
{
if(buttons[i] != 0)
{
info += "Button:"
+ i + " ";
}
}
Ayrıca Joystick için state içerisinde, Rx: X eksenine dönüş açısı,
ARx: X eksenin dönüş ivmesi, AX: X ekseni ivmesi, FRx: X
eksenine göre tork, FX: X ekseni hareket gücü, VRx: X ekseni
açısal hız, VX: X ekseni hız bilgilerine ulaşılabilir.
Makale ya da kodlarda bulunan hatalar ya da sorularınız için
mehmetaliecer@gmail.com adresinden
bana ulaşabilirsiniz. İyi çalışmalar.
Mehmet Ali ECER
www.mehmetaliecer.com
using System;
using System.Drawing;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace CubeExample
{
static class Program
{
public class Form1 : System.Windows.Forms.Form
{
private Device device = null;
private VertexBuffer vb = null;
private System.ComponentModel.Container
components = null;
private float angle = 0.0f;
public Form1()
{
InitializeComponent();
this.SetStyle(ControlStyles.AllPaintingInWmPaint
| ControlStyles.Opaque, true);
}
public void InitializeGraphics()
{
PresentParameters presentParams = new
PresentParameters();
presentParams.Windowed = true;
presentParams.SwapEffect = SwapEffect.Discard;
device = new Device(0, DeviceType.Hardware,
this, CreateFlags.SoftwareVertexProcessing, presentParams);
vb = new VertexBuffer(typeof(CustomVertex.PositionColored),
36, device, Usage.Dynamic | Usage.WriteOnly, CustomVertex.PositionColored.Format,
Pool.Default);
vb.Created += new EventHandler(this.OnVertexBufferCreate);
OnVertexBufferCreate(vb, null);
}
private void OnVertexBufferCreate(object sender, EventArgs e)
{
VertexBuffer buffer = (VertexBuffer)sender;
CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[36];
verts[0] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Red.ToArgb());
verts[1] = new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, Color.Red.ToArgb());
verts[2] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Red.ToArgb());
verts[3] = new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, Color.Red.ToArgb());
verts[4] = new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, Color.Red.ToArgb());
verts[5] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Red.ToArgb());
verts[6] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Blue.ToArgb());
verts[7] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Blue.ToArgb());
verts[8] = new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, Color.Blue.ToArgb());
verts[9] = new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, Color.Blue.ToArgb());
verts[10] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Blue.ToArgb());
verts[11] = new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, Color.Blue.ToArgb());
verts[12] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Yellow.ToArgb());
verts[13] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Yellow.ToArgb());
verts[14] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Yellow.ToArgb());
verts[15] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Yellow.ToArgb());
verts[16] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Yellow.ToArgb());
verts[17] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Yellow.ToArgb());
verts[18] = new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, System.Drawing.Color.Black.ToArgb());
verts[19] = new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, Color.Black.ToArgb());
verts[20] = new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, Color.Black.ToArgb());
verts[21] = new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, Color.Black.ToArgb());
verts[22] = new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, Color.Black.ToArgb());
verts[23] = new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, Color.Black.ToArgb());
verts[24] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Gray.ToArgb());
verts[25] = new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, Color.Gray.ToArgb());
verts[26] = new CustomVertex.PositionColored(-1.0f, -1.0f, -1.0f, Color.Gray.ToArgb());
verts[27] = new CustomVertex.PositionColored(-1.0f, 1.0f, 1.0f, Color.Gray.ToArgb());
verts[28] = new CustomVertex.PositionColored(-1.0f, -1.0f, 1.0f, Color.Gray.ToArgb());
verts[29] = new CustomVertex.PositionColored(-1.0f, 1.0f, -1.0f, Color.Gray.ToArgb());
verts[30] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Green.ToArgb());
verts[31] = new CustomVertex.PositionColored(1.0f, -1.0f, -1.0f, Color.Green.ToArgb());
verts[32] = new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, Color.Green.ToArgb());
verts[33] = new CustomVertex.PositionColored(1.0f, 1.0f, 1.0f, Color.Green.ToArgb());
verts[34] = new CustomVertex.PositionColored(1.0f, 1.0f, -1.0f, Color.Green.ToArgb());
verts[35] = new CustomVertex.PositionColored(1.0f, -1.0f, 1.0f, Color.Green.ToArgb());
buffer.SetData(verts, 0, LockFlags.None);
}
private void SetupCamera()
{
device.RenderState.Lighting = false;
angle = angle + 0.01f;
device.Transform.World=Matrix.RotationYawPitchRoll(angle,angle,angle);
device.Transform.View = Matrix.LookAtRH( new Vector3(0.0f,
0.0f, -5.0f), new Vector3(0.0f, 0.0f, 0.0f), new Vector3(0.0f, 1.0f, 0.0f));
device.Transform.Projection = Matrix.PerspectiveOffCenterRH(-1.0f
* (float)this.Width /(float)this.Height, 1.0f * (float)this.Width / (float)this.Height,
-1.0f, 1.0f, 1.0f, 100.0f);
}
protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
device.Clear(ClearFlags.Target, Color.CornflowerBlue, 1.0f,
0);
SetupCamera();
device.BeginScene();
drawingFont.DrawText(60, 100, Color.Red, "GraphicsFont.DrawText");
device.VertexFormat = CustomVertex.PositionColored.Format;
device.SetStreamSource(0, vb, 0);
device.DrawPrimitives(PrimitiveType.TriangleList,0, 12);
device.EndScene();
device.Present();
this.Invalidate();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.Size = new Size(800, 600);
this.WindowState= FormWindowState.Maximized;
this.Text = "mehmet ali ecer";
ShowInTaskbar = false;
this.ShowIcon=false;
this.TopMost=true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.ScreenSaverForm_KeyDown);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ScreenSaverForm_MouseDown);
}
#endregion
static void Main()
{
using (Form1 frm = new Form1())
{
frm.Show();
frm.InitializeGraphics();
Application.Run(frm);
}
}
private void ScreenSaverForm_KeyDown(object sender, KeyEventArgs e)
{
Close();
}
private void ScreenSaverForm_MouseDown(object sender, MouseEventArgs e)
{
Close();
}}}}
|