|
Kaplama en basit tabirle poligonlar üzerine bir resmi yapıştırmaktır. Böylece şimdiye kadar tek renk gördüğümüz poligonları daha detaylı ve gerçekçi bir görünüme kavuşturabiliriz. Bu iş için kullandığımz 2B resme bundan sonra doku yada texture diyeceğim. Koda geçmeden önce birkaç kavram üzerinde duralım. UV : Direct3d u(yatay) ve v(dikey) bileşenlerinden oluşan bir texture koordinat sistemi kullanır. Bu değerler 0-1 arasında değişir böylece farklı boyutlardaki dokularla uğraşmak kolaylaşır. Bkz. Resim1. UV değerleri aslında 1'den fazlada olabilir. Bu durumda texture kendini tekrar edecektir. Texel : (texture element)Bir çift UV koordinatından oluşan texture bölgesi. Resim 1: Texture'lar surface(yüzey) denilen yapılarda tutulur. Bunlar texture verisini optimal şekilde bellekte tutarlar. Surface genişlik ve yükseklik değeri olan bir yapıdır ama aslında ardışık bir byte dizisinden başka birşey değildir. Texture'ların boyutları her zaman 2'nin katları olmak zorunda değildir ama bazı donanımların buna desteği olmayabilir. Performans açısından 2' nin katı değerler kullanmak tavsiye edilir. Burada amacımız her üçgen üzerine dokuyu kaplamak , bu sebeple vertex tanımımıza u ve v değerlerini ekledik. //3d pozisyon + uv struct vertex3d { vertex3d(){} //yapıcı metod vertex3d(float _x, float _y, float _z, float _u, float _v) { x = _x; y = _y; z = _z; u = _u; v = _v; } float x, y, z; float u, v; }; #define postex_fvf D3DFVF_XYZ | D3DFVF_TEX1
FVF tanımındada D3DFVF_TEX1 isimli sabiti kullandık. Birden fazla texture'ı üst üst yerleştirerek farklı görünümler elde edebiliriz. Buna multi-texturing denir. Sabitin sonundaki "1" sayısı 1 adet kaplama olacağını belirtiyor Direct3d'de texture'lar IDirect3DTexture9 yapısı ile tutulur. IDirect3DTexture9* kaplama;
Kodu incelemeye devam edersek ilklemeler kısmında rutin olarak aynı şeyleri yapıyoruz. Burada kaplamayı bir küp üzerinde göstereceğiz. Normalde 8 vertexve 36 index ile küp yaratabiliriz fakat uv değerlerini verebilmek adına 24 vertex kullandık(8 tane ilede yapılabilir belki denemedim). //vertex buffer'ı doldur - 24 vertex vertex3d* vertices; vbuffer->Lock(0, 0, (void**)&vertices, 0); //ön yüz vertices[0] = vertex3d(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f); vertices[1] = vertex3d(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f); vertices[2] = vertex3d( 1.0f, 1.0f, -1.0f, 1.0f, 1.0f); vertices[3] = vertex3d( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f); //arka yüz vertices[4] = vertex3d(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); vertices[5] = vertex3d( 1.0f, -1.0f, 1.0f, 0.0f, 1.0f); vertices[6] = vertex3d( 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); vertices[7] = vertex3d(-1.0f, 1.0f, 1.0f, 1.0f, 0.0f); //tavan yüzü vertices[8] = vertex3d(-1.0f, 1.0f, -1.0f, 0.0f, 0.0f); vertices[9] = vertex3d(-1.0f, 1.0f, 1.0f, 0.0f, 2.0f); vertices[10] = vertex3d( 1.0f, 1.0f, 1.0f, 2.0f, 2.0f); vertices[11] = vertex3d( 1.0f, 1.0f, -1.0f, 2.0f, 0.0f); //taban yüzü vertices[12] = vertex3d(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f); vertices[13] = vertex3d( 1.0f, -1.0f, -1.0f, 0.0f, 0.1f); vertices[14] = vertex3d( 1.0f, -1.0f, 1.0f, 0.1f, 0.1f); vertices[15] = vertex3d(-1.0f, -1.0f, 1.0f, 0.1f, 0.0f); //sol yüz vertices[16] = vertex3d(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f); vertices[17] = vertex3d(-1.0f, 1.0f, 1.0f, 0.0f, 1.0f); vertices[18] = vertex3d(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f); vertices[19] = vertex3d(-1.0f, -1.0f, -1.0f, 1.0f, 0.0f); //sağ yüz vertices[20] = vertex3d( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f); vertices[21] = vertex3d( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f); vertices[22] = vertex3d( 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); vertices[23] = vertex3d( 1.0f, -1.0f, 1.0f, 1.0f, 0.0f); vbuffer->Unlock();
Örnek teşkil etmesi açısından tavan ve taban yüzlerinin UV değerlerine 1'den büyük ve küçük değerler verdik. Programı çalıştırdığınızda büyük değer verdiğimiz yerde dokunun kendini tekrar ettiğini, küçük verdiğimiz yerde ise dokunun sadece bir kısmının göründüğünü gözlemleyebilirsiniz. Ayrıca bu vertex değerlerini kağıt üzerine çizerseniz yerleşim şeklini daha iyi kavrayabilirsiniz. //doku ekle D3DXCreateTextureFromFile(aygit->getDevice(), "box.jpg", &kaplama); aygit->getDevice()->SetTexture(0, kaplama); Burada pratik bir şekilde D3DXCreateTextureFromFile yardımcı metodunu kullanarak bir resim dosyasından texture nesnesini oluşturduk. Normalde aygıtın CreateTexture metodu yada D3DXCreateTextureFromFileEx ile bu işi detaylı bir şekilde yapabiliriz, bunu sdk dökümanından inceleyebilirsiniz. D3DXCreateTextureFromFile metodu bmp,jpg,png,dds,tga gibi iyi bilinen formatlardaki resim dosyalarından okuma yapabilir ve oluşturulmuş texture nesnesini döndürür. D3DX metodları texture boyutlarını 2' nin katlarına uygun tutmak için değiştirebilir ve bazı durumlarda artifact denilen kötü görünümlere yol açabilir o yüzden boyutları 2'nin katları olarak ayarlamakta fayda var. Direct3d aynı anda 8 texture'ın kullanımına izin verir ve her birine bir basamak denir. Burada SetTexture metodu ile ilk basamaktaki dokuyu atamış olduk. Bu atamayı bir kere yapmamız yeterli. Kaplamayı değiştimek için metodu farklı bir texture ile çağırmak , silmek için "0" değeri ile çağırmak yeterlidir. aygit->getDevice()->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); aygit->getDevice()->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); Kullandığımız dokular her zaman yapıştırdığımız poligonlarla aynı büyüklükte olmayabilir. Yeri gelince büyütüp yeri gelince ufaltmamız gerekebilir. Bu tip işlemleri doğrudan yapmak görüntüde hoş olmayan yan etkiler oluşturabilir. Bunları aşmak için resimler bazı filtreleme işlemlerinden geçirilebilirler. Burada büyütme(MAGFILTER) ve ufaltma(MINFILTER) işlemleri için performans/kalite oranı iyi filtreler atadık. Diğer filtre tipleri şöyle: D3DTEXF_NONE D3DTEXF_POINT D3DTEXF_LINEAR D3DTEXF_ANISOTROPIC D3DTEXF_PYRAMIDALQUAD D3DTEXF_GAUSSIANQUAD 3B ortamlarda dokular her zaman aynı boyutta kalmazlar, 100 metre ötedeki 1 metrelik doku bize 1mm gibi görünebilir, böyle bir durumda bizim aynı texture'ı kullanmamız pek mantıklı olmayacaktır. Burada mipmap kavramı yardımımıza yetişiyor Bkz. Resim2 . Aygıt nesnesi bir dokunun daha düşük boyutlardaki versiyonlarını oluşturarak uzaktaki nesneler için ufak versiyonları kullanır ve büyük verim elde eder. Mipmap'ler çoğunlukla aygıt tarafından oluşturulur fakat bunları kendi içinde barındırabilen bir resim formatı da vardır:DDS. Resim 2: 
Ayrıca mipmap'lerin oluşturulmasında da bir filtre kullanılabilir (kullanılmalıdır) : aygit->getDevice()->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR); Bu filtre ayarları tek seferde çağrılıp uygulamaya konur ve genellikle uygulama boyunca değiştirilmezler. Programın devamında daha öncekiler gibi çizim işlemlerini gerçekleştiriyoruz. Kaynak Kodu İndir -------- 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
|