Makale Özeti

Bir önceki makalemizde Vertex alt yapısını anlatmıştık. Bu makalemizde vertex altyapısı ile geometrik çizimler çizerek vertex nesnesinin kullanıcılara ne gibi kolaylıklar sağladığını göreceğiz. Vertex nesnesini kullanarak transparan bir formun nasıl yapılacağını, forma çember ve kare geometrik şekillerinin nasıl çizilebileceğini adım adım göreceğiz.

Makale

DirectX İle Geometrik Nesneleri Çizmek

Bir önceki makalemizde Vertex alt yapısını anlatmıştık. Bu makalemizde vertex altyapısı ile  geometrik çizimler çizerek vertex nesnesinin kullanıcılara ne gibi kolaylıklar sağladığını göreceğiz. Vertex nesnesini kullanarak transparan bir formun nasıl yapılacağını, forma çember ve kare geometrik şekillerinin nasıl çizilebileceğini adım adım göreceğiz.

Transparant şekiller

Transparent şekiller ile birbiri üzerine geçmiş şekillerin alt şeklini kullanıcının görmesi sağlanır.Transparantlık uygulanarak kullanıcılara üç boyutlu ekran izlenimi verilecektir.

 

Yukarıdaki şekilde iç içe geçmiş iki üçgen görülmektedir. Bu özelliği sağlamak için renk özelliğinin şeffaflık(tranparant) özelliğini veren byte'ını yani şeklin alpha özelliğini değiştirmek gerekmektedir.Form üzerindeki tüm nesnelere bu özelliği sağlamak için yarattığımız device nesnesi üzerinde bu alpha özelliğini değiştireceğiz. Yaptığımız bu alpha blend özelliği en çok kullanılan transparanlıktır. Farklı özelliklerin şekilleriniz üzerinde nasıl değişikliklere yol açtığını deneyerek görebilirsiniz.

device.RenderState.AlphaBlendEnable = true;

device.RenderState.AlphaBlendOperation =BlendOperation.Add;

device.RenderState.DestinationBlend = Blend.InvSourceAlpha;

device.RenderState.SourceBlend = Blend.SourceAlpha;

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

namespace gamer

{

    public class MainClass : Form

    {

        Device device = null;

        CustomVertex.TransformedColored []vertices=new CustomVertex.TransformedColored[6];

        public MainClass()

        {

            this.ClientSize = new System.Drawing.Size(640, 480);

            this.Text = "Mehmet Ali ECER";

    }

    public bool InitializeGraphics()

    {

        try {

            PresentParameters presentParams = new PresentParameters();

            presentParams.Windowed = true;

            presentParams.SwapEffect = SwapEffect.Copy;

            device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

            device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);

            device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);

            device.Disposing += new EventHandler(this.DeleteDeviceObjects);

            device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);

            vertices[0].Position = new Vector4(150, 100, 0, 0);

            vertices[0].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

            vertices[1].Position = new Vector4 (this.Width/2 + 150,100,0,0);

            vertices[1].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

            vertices[2].Position = new Vector4(260, 300, 0, 0);

            vertices[2].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

            vertices[3].Position = new Vector4(300, 200, 0, 0);

            vertices[3].Color = Color.FromArgb( 127, 255, 0, 0 ).ToArgb();

            vertices[4].Position = new Vector4 (this.Width/2 + 150,300,0,0);

            vertices[4].Color = Color.FromArgb( 127, 255, 0, 0 ).ToArgb();

            vertices[5].Position = new Vector4(150, 300, 0, 0);

            vertices[5].Color = Color.FromArgb( 127, 255, 0, 0 ).ToArgb();

            return true;

        } catch (DirectXException) {

        return false;

    }

    }

protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("invalidate device");}

protected virtual void RestoreDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device reset");}

protected virtual void DeleteDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device delete");}

protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)

{// MessageBox.Show("hareket");}

protected virtual void FrameMove()

{}

protected virtual void Render()

{

    if (device == null)

        return;

    device.Clear(ClearFlags.Target, System.Drawing.Color.Aqua, 1.0f, 0);

    device.BeginScene();

    device.RenderState.AlphaBlendEnable = true;

    device.RenderState.AlphaBlendOperation =BlendOperation.Add;

    device.RenderState.DestinationBlend = Blend.InvSourceAlpha;

    device.RenderState.SourceBlend = Blend.SourceAlpha;

    device.VertexFormat = CustomVertex.TransformedColored.Format;

    device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices);

    device.EndScene() ;

    device.Present();

}

public void Run()

{

    while (Created) {

        FrameMove();

        Render();

        Application.DoEvents();

    }

}

protected override void OnPaint(PaintEventArgs e)

{

    this.Render();

}

protected override void OnKeyPress(KeyPressEventArgs e)

{

    base.OnKeyPress(e);

    if ((int)e.KeyChar == (int)System.Windows.Forms.Keys.Escape) {

        this.Close();

}

}

static void Main()

{

    using (MainClass mainClass = new MainClass()) {

        if (!mainClass.InitializeGraphics()) {

            MessageBox.Show("Error while initializing Direct3D");

        return;

    }

    mainClass.ShowIcon=true;

    mainClass.Icon=new System.Drawing.Icon("gears.ico");

    mainClass.Show();

    mainClass.Run();

}}}}

        Şimdiye kadar ekrana çizdiğimiz nesnelerde hep device.DrawUserPrimitives(PrimitiveType.TriangleList, 2, vertices); kullandık. PrimitiveType: LineList, LineStrip, Point List, Triangle Fan, TriangleList,Triangle Strip tiplerini alır. Burada LineList iki noktadan oluşan çizgiler için, LineStrip bağlantılı çizgiler için , Point List birbirinden bağımsız noktalar için,TriangleFan oval nesneler için, TriangleList birbirinden bağımsız üçgenler, TriangleStrip birbiri ile bağlantılı üçgenler için kullanılır. Şimdi point list kullanarak form üzerinde bir çember çizdireceğiz. Çemberleri noktalardan oluşturacağız. Bir çemberi oluşturmak 360 tane nokta olması gerekmektedir. Bu nokta hesabını yapmak için trigonometrik bilgilerimizden faydalanıp tek tek bu 360 noktanın X ve Y koordinatlarını hesaplamamız gerekmektedir. Bunun için 360 tane noktayı saklayabilmek için vertex dizimizin boyutunu 360 olarak veriyoruz ve herbir noktanın X ve Y koordinatlarını bulmak için aşağıdaki algoritma ile hesaplamaktayız. Algoritmadan anlaşılacağı gibi her bir açının X koordinatını o açının kosinüs değerinden Y koordinatınıda açının sinüs değerinden hesaplarız. Çemberimizin yarıçapı 100dür.

    float x = 0f;

    float y = 0f;

    float m_width = 100;

    float m_height = 100;

    for (int i = 0; i < 359; i++)

    {

        x = (float)Math.Cos((double)i);

        y = -(float)(Math.Sin((double)i));

        vertices[i].Position = new Vector4(x * m_width+200, y * m_height+200, 0f,0);

        vertices[i].Color = Color.Green.ToArgb();

}

 

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

namespace gamer

{

public class MainClass : Form

{

    Device device = null;

    CustomVertex.TransformedColored []vertices=new CustomVertex.TransformedColored[360];

    public MainClass()

    {

        this.ClientSize = new System.Drawing.Size(640, 480);

        this.Text = "Mehmet Ali ECER";

    }

public bool InitializeGraphics()

{

    try {

        PresentParameters presentParams = new PresentParameters();

        presentParams.Windowed = true;

        presentParams.SwapEffect = SwapEffect.Copy;

        device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

        device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);

        device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);

        device.Disposing += new EventHandler(this.DeleteDeviceObjects);

        device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);

        float x = 0f;

        f loat y = 0f;

        float m_width = 100;

        float m_height = 100;

        for (int i = 0; i < 359; i++)

        {

            x = (float)Math.Cos((double)i);

            y = -(float)(Math.Sin((double)i));

            vertices[i].Position = new Vector4(x * m_width+200, y * m_height+200, 0f,0);

            vertices[i].Color = Color.Green.ToArgb();

        }

    return true;

    } catch (DirectXException) {

        return false;

    }    }

protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("invalidate device");}

protected virtual void RestoreDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device reset");}

protected virtual void DeleteDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device delete");}

protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)

{// MessageBox.Show("hareket");}

protected virtual void FrameMove(){}

protected virtual void Render()

{

    if (device == null)

        return;

    device.Clear(ClearFlags.Target, System.Drawing.Color.Aqua, 1.0f, 0);

    device.BeginScene();

    device.DrawUserPrimitives(PrimitiveType.PointList,360, vertices);

    device.EndScene() ;

    device.Present();

}

public void Run()

{

    while (Created) {

        FrameMove();   

        Render();

        Application.DoEvents();

}}

protected override void OnPaint(PaintEventArgs e)

{    this.Render();}

protected override void OnKeyPress(KeyPressEventArgs e)

{

    base.OnKeyPress(e);

    if ((int)e.KeyChar == (int)System.Windows.Forms.Keys.Escape) {

    this.Close();

}

}

static void Main()

{

    using (MainClass mainClass = new MainClass()) {

    if (!mainClass.InitializeGraphics()) {

    MessageBox.Show("Error while initializing Direct3D");

    return;

}

    mainClass.ShowIcon=true;

    mainClass.Icon=new System.Drawing.Icon("gears.ico");

    mainClass.Show();

    mainClass.Run();

}}}}

    En son olarak form üzerine kare çizdireceğiz. Kare geometrik şeklini çizdirirken dik iki ikizkenar üçgeni hipotenüs üzerinden birleştireceğiz.

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Drawing;

using System.Windows.Forms;

using Microsoft.DirectX;

using Microsoft.DirectX.Direct3D;

namespace gamer

{

public class MainClass : Form

{

    Device device = null;

    CustomVertex.TransformedColored []vertices=new CustomVertex.TransformedColored[360];

    public MainClass()

    {

        this.ClientSize = new System.Drawing.Size(640, 480);

        this.Text = "Mehmet Ali ECER";

}

public bool InitializeGraphics()

{

    try {

    PresentParameters presentParams = new PresentParameters();

    presentParams.Windowed = true;

    presentParams.SwapEffect = SwapEffect.Copy;

    device = new Device(0, DeviceType.Hardware, this, CreateFlags.SoftwareVertexProcessing, presentParams);

    device.DeviceLost += new EventHandler(this.InvalidateDeviceObjects);

    device.DeviceReset += new EventHandler(this.RestoreDeviceObjects);

    device.Disposing += new EventHandler(this.DeleteDeviceObjects);

    device.DeviceResizing += new CancelEventHandler(this.EnvironmentResizing);

    vertices[0].Position = new Vector4(150, 100, 0, 0);

    vertices[0].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

    vertices[1].Position = new Vector4 (250,100,0,0);

    vertices[1].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

    vertices[2].Position = new Vector4(150, 200, 0, 0);

    vertices[2].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

    vertices[3].Position = new Vector4(250,100,0,0);

    vertices[3].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

    vertices[4].Position = new Vector4 (250, 200, 0, 0);

    vertices[4].Color = Color.FromArgb( 255, 0, 0, 255 ).ToArgb();

    vertices[5].Position = new Vector4(150, 200, 0, 0);

    vertices[5].Color = Color.FromArgb( 255, 0, 0, 255).ToArgb();

    return true;

    } catch (DirectXException) {

        return false;

    }}

protected virtual void InvalidateDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("invalidate device");}

protected virtual void RestoreDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device reset");}

protected virtual void DeleteDeviceObjects(object sender, EventArgs e)

{// MessageBox.Show("device delete");}

protected virtual void EnvironmentResizing(object sender, CancelEventArgs e)

{// MessageBox.Show("hareket");}

protected virtual void FrameMove(){}

protected virtual void Render()

{

    if (device == null)

        return;

    device.Clear(ClearFlags.Target, System.Drawing.Color.Aqua, 1.0f, 0);

    device.BeginScene();

    device.VertexFormat = CustomVertex.TransformedColored.Format;

    device.DrawUserPrimitives(PrimitiveType.TriangleList,2, vertices);

    device.EndScene() ;

    device.Present();

}

public void Run()

{

    while (Created) {

        FrameMove();

        Render();

        Application.DoEvents();

    }}

protected override void OnPaint(PaintEventArgs e)

{this.Render();}

protected override void OnKeyPress(KeyPressEventArgs e)

{

    base.OnKeyPress(e);

    if ((int)e.KeyChar == (int)System.Windows.Forms.Keys.Escape) {

        this.Close();

}}

static void Main()

{

    using (MainClass mainClass = new MainClass()) {

    if (!mainClass.InitializeGraphics()) {

        MessageBox.Show("Error while initializing Direct3D");

    return;

    }

    mainClass.ShowIcon=true;

    mainClass.Icon=new System.Drawing.Icon("gears.ico");

    mainClass.Show();

    mainClass.Run();

}}}}

Makalede 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