|
Bazen sahnede çizilen cisimlerin bazı yerlerinin transparan olması yada hiç görünmemesi istenebilir. Bu gibi durumlarda kullanabileceğimiz bir yöntem olan blending, ekranda duran bir piksel ile üzerine çizilecek pikselin kombine edilmesi işlemidir. Nasıl kombine edileceği ile ilgili birçok ayar mevcut olmakla beraber biz burada basit transparanlık efektinden bahsedeceğiz. Vertex Alpha : Vertexlerin alpha değerleri kullanılarak yapılan blending işlemidir. Daha önceki eğitsellerden hatırlayacağınız üzere renk değeri içeren vertexlerin alpha değerlerini göz ardı etmiştik. Burada bunları kullanarak bir efekt oluşturacağız. //3d pozisyon + renk + uv struct vertex3d { float x, y, z; DWORD color; float u, v; }; #define postex_fvf D3DFVF_XYZ | D3DFVF_DIFFUSE | D3DFVF_TEX1 ......... //arka plan karesi vertex3d kare_arka[] = { { -1.0, 1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),0,4}, { 1.0, 1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),4,4}, { -1.0,-1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),0,0}, { -1.0,-1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),0,0}, { 1.0, 1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),4,4}, { 1.0,-1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),4,0} }; //one çizilecek kare vertex3d kare_on[] = { { -1.0, 1.0, 0.0, D3DCOLOR_ARGB(50,255,255,255), 0,1}, { 1.0, 1.0, 0.0, D3DCOLOR_ARGB(50,255,255,255), 1,1}, { -1.0,-1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),0,0}, { -1.0,-1.0, 0.0, D3DCOLOR_ARGB(255,255,255,255),0,0}, { 1.0, 1.0, 0.0, D3DCOLOR_ARGB(50,255,255,255), 1,1}, { 1.0,-1.0, 0.0, D3DCOLOR_ARGB(50,255,255,255), 1,0} };
Biri önde diğeri arkada çizilmek üzere 2 kare tanımladık. Arka plan karesinin alpha değerlerini tam görünür ayarladık. Önde duracak karenin bazı vertex alpha değerlerini yaklaşık 1/5 oranında görünür ayarladık. İki pikselin blend edilmesinde aşağıdaki gibi bir işlem yapılır : Sonuç Pikseli = (KaynakPiksel x KaynakBlendFaktörü) + (HedefPiksel x HedefBlendFaktörü) Buradaki blend faktörleri 0-1 arası değerler olup SetRenderState metodu ile ayarlanabilir. //alpha blending aç aygit->getDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE,true); //KaynakBlendFaktörü aygit->getDevice()->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); //HedefBlendFaktörü aygit->getDevice()->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA);
Yapılan ilk işlem blending'in aktive edilmesi. Blend işlemi piksel bazında yapılan bir işlemdir yani 640*480'lik bir ekranda bile her karede 300000 kere hesaplama yapılması gerekir. Bu yüzden bu ayarı gereken yerlerde açıp işiniz bitince kapatmanız önerilir. Sahnenin çoğunda bu işlem uygulanıyorsa açık kalabilir. D3DRS_SRCBLEND(KaynakBlendFaktörü) ve D3DRS_DESTBLEND( HedefBlendFaktörü) değerleri aşağıdaki değerlerden biri olabilir. Burada kaynak piksel alpha değeri ile çarpılırken, hedef piksel (1-alpha) ile çarpılacaktır. Örnek : Alpha değeri 0.1 olsun. Sonuç Pikseli = (KaynakPiksel x 0.1) + (HedefPiksel x (0.9)). D3DBLEND_ZERO //0 ( D3DRS_DESTBLEND varsayılan değeri) D3DBLEND_ONE //1 (D3DRS_SRCBLEND varsayılan değeri) D3DBLEND_SRCCOLOR //Kaynak Renk D3DBLEND_INVSRCCOLOR //1-Kaynak Renk D3DBLEND_SRCALPHA //Kaynak Alpha D3DBLEND_INVSRCALPHA //1-Kaynak Alpha D3DBLEND_DESTALPHA //Hedef Alpha D3DBLEND_INVDESTALPHA //1-Hedef Alpha D3DBLEND_DESTCOLOR //... D3DBLEND_INVDESTCOLOR D3DBLEND_SRCALPHASAT D3DBLEND_BOTHSRCALPHA D3DBLEND_BOTHINVSRCALPHA Kaplamaya sahip bir nesnede varsayılan olarak alpha argümanı dokudur. Yani blend hesaplamasında texture alphası(D3DTA_TEXTURE) yada keycolor denilen bir renk baz alınır. Bunu değiştirip vertex alphasını kullanmak için alpha hesaplamasının 1. argümanını ayarlıyoruz: //Blend için vertex alphası kullan aygit->getDevice()->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_DIFFUSE);
Gördüğünüz gibi blend hesaplamasının birçok ayarı bulunuyor ve farklı kombinasyonlarla çeşitli efektler elde edilebilinir. Bu tip detayları sdk dökümanından araştırmanız tavsiye edilir. KeyColor : Daha önce doku yüklemek için D3DXCreateTextureFromFile metodunu kullandık. Daha detaylı ayarlar yapabilmek için D3DXCreateTextureFromFileExA kullanılabilir. Bu metodun parametrelerinden biride keycolor isimli bir renk değeridir. Bu değeri 0'dan farklı verdiğiniz zaman blend işleminde verdiğiniz renkteki pikseller çizilmezler. Bu ucuz bir işlem olsada tek renk belirtildiği için kalitesiz sonuçlar üretir. Keycolor kullanacak doku: D3DXCreateTextureFromFileExA( aygit->getDevice(), //aygıt "box.bmp", //dosya adı D3DX_DEFAULT, //genişlik D3DX_DEFAULT, //yükskelik D3DX_DEFAULT, //mipmap sayısı NULL, //kullanım D3DFMT_UNKNOWN, //renk formatı D3DPOOL_MANAGED, //bellek kullanımı D3DX_DEFAULT, //doku filtresi D3DX_DEFAULT, //mipmap filtresi 0xFF000000, //keycolor NULL, //kaynak resim bilgisi NULL, //palet &kaplama_on1); //dönen doku nesnesi Alpha Blend : Kullanılan dokunun alpha değerleri kullanılarak hesaplama yapılır. Tüm resim formatları alpha değeri tutamazlar. DirectX sdk ile gelen bir tool(directx texture tool) yardımı ile bitmaplere alpha kanalı ekleyip bir .dds dosyası elde edebilirsiniz. Ayrıca png,tga gibi resim formatlarıda alpha değeri tutabilirler. Alpha kanalı kullanacak doku: D3DXCreateTextureFromFileExA( aygit->getDevice(), //aygıt "box.png", //dosya adı D3DX_DEFAULT, //genişlik D3DX_DEFAULT, //yükskelik D3DX_DEFAULT, //mipmap sayısı NULL, //kullanım D3DFMT_UNKNOWN, //renk formatı D3DPOOL_MANAGED, //bellek kullanımı D3DX_DEFAULT, //doku filtresi D3DX_DEFAULT, //mipmap filtresi 0, //keycolor NULL, //kaynak resim bilgisi NULL, //palet &kaplama_on2); //dönen doku nesnesi //alpha ayarları //alpha blending aç aygit->getDevice()->SetRenderState(D3DRS_ALPHABLENDENABLE,true); //KaynakBlendFaktörü aygit->getDevice()->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA); //HedefBlendFaktörü aygit->getDevice()->SetRenderState(D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA); //Blend için texture alphası kullan aygit->getDevice()->SetTextureStageState(0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE); Öncekinden farklı olarak alpha argümanı olarak D3DTA_TEXTURE değerini verdik. Böylece işlemler doku alphası üzerinden yapılacak. Ekranın soluna alpha blend kullanan, sağına ise keycolor kullanan 2 kare koyduk. Aradaki farkı programı çalıştırarak görebilirsiniz. Bitirmeden önce alpha test işlemindende bahsedeyim dedim. Blend işlemi sonunda belli bir değerin altındaki pikseller zaten görünmeyecektir. Bu pikseller üzerinde genede işlem yapılır. Bunu engellemek için bir değer belirleyebilirsiniz. Bu değerin altında alpha değerine sahip pikseller doğrudan elenecektir ve işlem tasarrufu sağlanacaktır (Bkz. D3DRS_ALPHATESTENABLE). Kaynak Kodu İndir (Vertex Alpha) -------- EKSTRALAR -------- Ekran Kartı Bilgisi Kodu: http://directx.oyungelistirici.net/dx/onbilgi.rar Kavramlar: http://www.oyungelistirici.net/index.php/egitseller/14-oyunyapimi/233-kavramlar DirectX Kaynakları: http://www.chadvernon.com/blog/tutorials/ http://www.directxtutorial.com/ http://www.zanir.szm.sk/index.html http://www.pieterg.com/ http://www.32bits.co.uk/ http://triplebuffer.devmaster.net/tutorials/archive/ http://www.two-kings.de/ http://www.mvps.org/directx/indexes/index.htm http://www.drunkenhyena.com/cgi-bin/directx.pl DirectX Kitapları: http://www.amazon.com/ adresinde DirectX'i aratmanız yeterli. -------- ÖNEMLİ -------- -Bu sitedeki dökümanlar Türkçe kaynak eksikliği yüzünden hazırlanmış ve ihtiyaç duyanların serbest kullanımına sunulmuştur. -Sunulan kodlar ve bilgilerin doğruluk ve etkinlikleri konusunda bir garanti verilmemekle beraber her türlü talep ve düzeltmelerinizi mail yada ilgili forum başlığı yoluyla iletebilirsiniz -Dökümanlarda daha çok genel kavramlara değinilmiş olup detaylı bilgi edinmek için directx dökümanını ve çeşitli kaynakları (özellikle kitap) okumanız tavsiye edilir. Farklı kaynakların bağlantılarını bu dökümanın sonunda bulabilirsiniz. -Bu eğitsellerden verim alabilmek için orta düzeyde c++ bilgisi yeterlidir. Onun dışında winAPI hakkında bilgi sahibi olmak directx'i kavramakta size yardımcı olacaktır. Ayrıca eğitseller ardışık bağlantılı olduğu için bu işte yeni iseniz sırayla gitmeniz tavsiye edilir. -Örnek kodlar Virusl Studio 2003 projeleridir, vs2005 ile de kullanılabilir. -Kavramları Türkçeleştirmek için çok çaba sarfedilmemiştir, çoğu yerde İngilizce isimler kullanılmıştır. Merak ettikleriniz için kavram sözlüğüne bakabilirsiniz. -İndireceğiniz yazılımlardan dolayı PC'nizin ya da bünyenizin zarar görmesi durumunda sorumluluk kabul etmeyiz, geçmiş olsuna gelebiliriz :) -Yazılanların hakkı saklı değildir, sağda solda ben yaptım diye dağıtabilirsiniz :)
Yunus KARA
|