2010. február 6., szombat

Bevezetés a Managed DirectX világába

A Managed DirectX (MDX) 2002-ben jelent meg, mint .NET Framework alatti DirectX támogatás. Az MDX 2.0 pedig már a XNA Framework része lett. Vagyis az MDX mára megszűnt létezni és helyette lett a XNA, de az már framework, szóval semmi vertex buffer, meg ilyenek. XBox 360 és PC-re jó, de a mindkettővel való kompatibilitás miatt DirectX 9-et támogatja csak. Ennek ellenére érdemes megnézni milyen is az MDX, mert még mindig elérhető. A másik lehetőség az MDX megvalósítására a SlimDX. Ez már gyakorlatilag csak egy managed wrapper a DirectX-hez, 1-2 dolog van csupán megoldva benne, viszont akár DirectX 11-ben is lehet programozni és állítólag használja is 1-2 budget cég. Később az MDX mellet a SlimDX lehetőségeit is ki fogjuk próbálni.
A most következő rövid ismertető azoknak készült, akik szeretnék megismeri a DirectX Direct3D API használatát Visual C#-ból. Nem törekszik teljességre, hiszen "A legkifinomultabb alkotás sem vetekedhet az emberi gondolat tökéletességével." Tehát, a következő dolgokra lesz szükségünk a minimális tesztkörnyezet felépítéséhez:
  • Microsoft Visual Studio .NET
  • .NET Framework 1.1
  • DirectX9 SDK
Akkor kezdjünk is bele az első MDX-es programunkba, ami egy ablakot fog megjeleníteni egy színes háromszöggel valamint egyszerű input és DeviceLost esemény kezelést is meg fog oldani.

Az elérendő cél

A tutorial alapvető C#-ban való jártasságot feltételez. A cikk kezdőknek szól, ezért lehet, hogy egy-két részt jobban kifejtek. Hozzunk létre egy új Visual C# Windows alkalmazást, majd adjunk referenciákat a Microsoft DirectX és a Microsoft.DirectX.Direct3D komponensekre:

using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;

Az első, amit tennünk kell, hogy létre kell hoznunk egy device-t. Rövidre fogva a device egy link a grafikus adapterhez, egy objektum, amely segítségével elérhetünk egy hardware eszközt.

private Device device = null;

Természetesen az eszközünket inicializálni is kell:
     private void SetupDevice()
{
// A device típusa határozza meg, hogy a hardware vagy a software implementációt hivjuk egy feladat végrehajtásánál
device = new Device(0, DeviceType.Hardware, this.Handle, CreateFlags.HardwareVertexProcessing, presentParams);
// EventHandler a DeviceLost eseményhez
device.DeviceLost += new EventHandler(device_DeviceLost);
// EventHandler a DeviceReset eseményhez
device.DeviceReset += new EventHandler(device_DeviceReset);
device.DeviceResizing += new System.ComponentModel.CancelEventHandler(OnResize);
}
Paraméterek beállítása:
      public void SetupPresentParams()
{
// A presentParams példányosítása
presentParams = new PresentParameters();

// Hátsó puffer formátumának beállítása (32 bit, ARGB)
presentParams.BackBufferFormat = Format.A8R8G8B8;

//A hátsó puffer szélességét és magasságát állítjuk a Form méreteihez
presentParams.BackBufferWidth = this.Width;
presentParams.BackBufferHeight = this.Height;

// Lapváltás beállítása, nem használunk swappet, egyből megjelenítünk mindent
presentParams.SwapEffect = SwapEffect.Discard;

// Ablakos vagy teljes képernyős legyen az ablak
presentParams.Windowed = true;
}
A Direct3D eszköz létrehozása:
    // Direct3D eszköz létrehozása
public bool CreateDevice()
{
SetupPresentParams();
try
{
SetupDevice();
}
// A DirectXExceptiont elkapjuk és a hibaüzenetet kiíratjuk
catch (DirectXException ex)
{
MessageBox.Show(ex.Message);
return (false);
}
return (true);
}
Ne felejtsük el meghívni a CreateDevice() metódust a Form konstruktorában. Ezután elkészítjük az OnPaint metódusunk saját verzióját (override):
   protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
{
// Rajzolás
this.Render();
Invalidate();
}
Ugye azt mindenki tudja, hogy a 3D-s világban minden háromszögekből áll. (Aki nem tudta az gondolja végig, hogy 3 pont mindig egy síkban van) Szóval egy ilyen háromszöget 3 pont határoz meg, a három csúcsa. Ezek a csúcsok a háromdimenziós térben vektorok v(x, y, z). Persze egy pontot nem csak a koordinátája határoz meg, hanem pl. a színe is. Az objektumot, ami leír egy ilyen pontot, vertex-nek hívnak. Hozzunk létre egy ilyen vertexekből álló tömböt a háromszögünkhöz az OnLoad metódusban:
  protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);

vertices = new CustomVertex.TransformedColored[3];
vertices[0].Position = new Vector4(this.Width / 2.0f, 50.0f, 0.5f, 1.0f);
vertices[0].Color = Color.Red.ToArgb();
vertices[1].Position = new Vector4(this.Width - (this.Width / 5.0f), this.Height - (this.Height / 5.0f), 0.5f, 1.0f);
vertices[1].Color = Color.Green.ToArgb();
vertices[2].Position = new Vector4(this.Width / 5.0f, this.Height - (this.Height / 5.0f), 0.5f, 1.0f);
vertices[2].Color = Color.Blue.ToArgb();
}
Ezután már létrehozhatjuk a Render() metódust:
 private void Render()
{
if (device == null) return;

// Töröljük színpuffert, és CadetBlue színű ClearColort állítunk be
device.Clear(ClearFlags.Target, Color.CadetBlue, 1.0f, 0);

device.BeginScene();
{
device.VertexFormat = CustomVertex.TransformedColored.Format;
device.DrawUserPrimitives(PrimitiveType.TriangleList, 1, vertices);
}
device.EndScene();

try
{
// Megjelenítjük a jelenetet a monitoron
device.Present();
}
// DeviceLostException elkapása
catch (DeviceLostException)
{
// Meghívjuk a Recover függvényt, ami visszaállítja a Direct3D eszközt
Recover();
}
}
És kész, lehet fordítani az alkalmazást. Ha mindent jól csináltunk egy gyönyörű szép színes háromszögnek kell megjelenni az ablakban. A példa teljes forrása itt tekinthető meg:


Ha valamit kihagytam volna vagy valami nem érthető, semmi gond, legközelebb is innen folytatjuk.

0 megjegyzés :

Megjegyzés küldése