Bu makalemde sizlere XNA in çalışma yapısını ve Shader Code ların çalışma mantığını anlatacağım
Derinlemesine XNA
Bu makalemde sizlere XNA in çalışma yapısını ve Shader Code ların çalışma mantığını anlatacağım…
O halde başlayalım:
Aşağıdaki Grafikte Şemasal Olarak Sırayla XNa ve Shader Kodlarının birlikte nasıl çalıştığı gösterilmiştir…
<!--[if !vml]-->
<!--[endif]-->
Şekil 1-a: XNA in Çalışma Hiyerarşisi…
<!--[if !vml]-->
<!--[endif]-->
Şekil 2-a:Shader Kodlarının Çalışma Hiyerarşisi…
Xna Kodlama yapılırken resmi ve varsayılan olarak C# kullanıldığını biliyoruz.İlk önce bahsedeceğim şey XNA de C# kullanılarak yapılan kodlama mantığı olacak…
C# Tarafında yapılacak işlemleri numara sırasına göre açıklıyorum.
1)Başlangıç
Burada import etmek istediğiniz aduzaylarını kullanabilirsiniz…
Örneğin:
#region Aduzaylarımız
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
2)Modül Tanımlamaları
(oyun sınıfımız için kullanılacak nesnelerimizi tanımlarız…)
Örnek vermemiz gerekirse:
GraphicsDeviceManager graphics; //Grafik Aygıtıile ilgili değişkenimiz.
ContentManager content; //İmaj ve modelleri depolayacak değişkenimiz.
ContentManager ve GraphicsDeviceManager nesnelerini tanımladık.
3)Main() Fonksiyonumuz
(Burası oyunumuzun esas başlangıcıdır)
Bu kısımda oyun nesnemizin örneğini alıp çalıştırıyoruz.Nitekim:
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
Görüldüğü üzere game isminde bir Game1 nesnesi oluşturuyoruz ve onu çalıştırıyoruz…
4)Constructor(Yapıcı Fonksiyonumuz)
(GraphicsDevice ve ContentManager nesnelerinin yüklenmesi)
Oluşturulan Class nesnemizi ilk kullanıma hazırlıyoruz…
Mesela;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
}
5)Initialize()
(Kullanıcı Tanımlı İşlemler:
-Pencere Özelliklerini Ayarlama
-Uygulama Özelliklerini Ayarlama
-Perspektif ve Görünümleri Ayarlamak
-Kaynakları(Shaderlar,Köşeler,Sesler) ayarlama ve yükleme…)
Örneğin
protected override void Initialize()
{
this.Window.Title = "Oyun Penceresi";
base.Initialize();
}
yukarıdaki örnekte pencerenin ismini “Oyun Penceresi” olarak değiştirdik.
6)LoadGraphicsContent()
(İmaj ve Modelleri Yükleme…)
mesela bir resim yüklemek istersek;
content.Load<Texture2D>("ornek");
Asset Name(resme ulaşmak için gerekli anahtar sözcük) i ornek olan agac.jpg isimli resim dosyamızı yüklemek için LoadGraphicsContent() isimli fonksiyonumuza yukarıda verdiğim örneği yazmanız yeterli olacaktır…
7)Draw()
-Ekranı yeni bir renkle temizleme
-Nesneleri çizmek için dönüştürme
-Shader a çıktı göndermek.
Draw fonksiyonunda olmazsa olmazlardan birisi Ekranı yeni bir renk ile temizlemesidir.
Örneğin;
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
8)Update()
-Oyun zamanını güncellemek
-Mouse,Klavye ve GamePad olaylarını denetlemek.
-Diğer devam eden kullanıcı-tanımlı aktiviteler:skor tutma,Çarpışmayı Kontrol Etmek(Collision Detection),Animasyon…
Mesela Update() fonksiyonunun içinde yoğunlukla kullanılanların başında İnput işlemleri gelir.
Örnek vermem gerekirse;
if (GamePad.GetState(PlayerIndex.One).Buttons.Start == ButtonState.Pressed)
this.Exit();
Xbox Konsol aygıtında Start düğmesine basınca oyundan çıksın J
9)Uygulamanın kapatılıp kapatılmadığını kontrol etmek.
Eğer Halen daha çalışıyorsa 7.adımdaki Draw işlemleri tekrarlanır.
Eğer ki kapanıyorsa 10. Sıradaki işlemden devam edilir…
10)UnloadGraphicsContent()
(İmaj ve Modellerin Yokedilmesi.Oyun kapatılmadan önce Bütün imaj ve Modeller Yokedilir)
UnloadGraphicsContent() ile ilgili yapabileceğimiz işlemlerden örnek vermem gerekirse;ContentManager da kullanılan imaj ve modellerimizi serbest bırakabiliriz…
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent)
{
content.Unload();
content.Dispose();
}
}
Content.Dispose ile bütün kaynakları serbest bırakıyoruz.Şunun unutulmaması gerekir ki serbest bırakmadan önce muhakkak içeriği sonlandırmamız gerekir.Nitekim Dispose metodundan önce Unload u çalıştırmamızın amacı da bu…
11)Oyunun Bitirilmesi
(bu noktada oyundan çıkış işlemi tamamlanır)
Unload ve Dispose metodları çalıştıktan sonra uygulamaya dair hiçbirşey kalmamıştır.
XNA in çalışma mantığını örnekler vererek anlattıktan sonra sırada Shader kodlarımızın çalışma mantığını anlatma var.
Shader Tarafını açıklayalım o zaman sırasıyla.
1)Draw Fonksiyonu ile devam edilir.Bildiğiniz üzere oyun devam ettikçe Draw Fonksiyonu çalışır.Kapatılınca da UnloadGraphicsContent fonksiyonu çalışır.Draw fonksiyonundan gelen modelleme bilgileri ve shader değişkenleri Shader koda gönderilip efekt bilgileri ayarlanmaya başlanır.
2)Technique Fonksiyonu
(
-Vertex Shader derlenir.
-Piksel Shader derlenir.
-Her iki shader arasında değerlerin birbirine geçmesinin tetiklenmesi.
)
Örnek vermem gerekirse;
float4x4 matWVP : WorldViewProjection;
struct vertexInput {
float3 Position: POSITION;
};
struct vertexOutput {
float4 HPosition : POSITION;
float4 Diffuse : COLOR0;
};
vertexOutput VS_TransformDiffuse(vertexInput IN)
{
vertexOutput OUT;
OUT.HPosition = mul( float4(IN.Position.xyz , 1.0) , matWVP);
OUT.Diffuse = float4(1.0f, 1.0f,1.0f,1.0f);
return OUT;
}
technique textured
{
pass p0
{
VertexShader = compile vs_1_1 VS_TransformDiffuse();
ColorArg1[0] = Diffuse;
AlphaArg1[0] = Diffuse;
ColorOp[0] = SelectArg1;
AlphaOp[1] = SelectArg1;
}
}
Biraz karışık olduğuna bakmayın bu shader kodda materialları uygulandığı şekle beyaz renk efekt vermektedir.Technique fonksiyonumuz bizim C# da kullandığımız Main() fonksiyonu gibidir.Burada VertexShader ımızı derlemekteyiz.Pixel Shader ı ise bu shader uygulamasında kullanmadığımızdan dolayı derleme yapmıyoruz.Değer geçirme prosesini de pass p0 işlemiyle yapmaktayız.
3)Vertex Shader
(Vertex bilgisinin alınıp değiştirilmesi)
Yukarıdaki örnek Shader ımızda da görüldüğü üzere Technique fonksiyonumuzda
VertexShader = compile vs_1_1 VS_TransformDiffuse();
Vertex Shader ımızı derleme işlemini yapıyoruz…
4)Piksel Shader
(Girişleri renkli piksellere çevir.)
Pixel Shader ımız ile ilgili yukarıdaki Shader Kodumuzda pek bir işlem yapmadık dolayısıyla Piksel Shader konusunda şimdilik fazla durmayacağım.
5)Ekran Kartı
Bu işlemde piksek shader ve vertex shader dan derlenen bilgiler ekran kartına gönderilip işlenir.
6)Görüntüleme
Ekran kartı bütün bilgileri monitörde görüntüler
Son olarak da Ekran Kartımız işlemiş olduğu shader kod dan gelen verileri monitörümüze yansıtır.
İşte bu kadar.Buraya kadar elimden geldiğince sizlere XNA ve Shader Kodlarının sırasıyla nasıl çalıştığını anlatmaya çalıştım.