|
Şimdiye kadarki eğitsellerde çizilecek tüm cisimlerin vertexlerini tek tek yazdık. İş daha komplike modeller kullanmaya gelince bunları elle yazmak pekde kolay olmayacaktır :). 3B modelleme programları ile çok detaylı tasarımlar yapıp bunları çeşitli formatlarda elde etmek mümkün. Burada biraz mesh kavramından bahsedip, bir (directx'in model formatı).x dosyasından nasıl yükleme yapabileceğimizi anlatacağız. ID3DXMesh* mesh; Directx'in mesh yapısı(ID3DXMesh) temelde vertexleri ve indexleri tutan bir yapıdır. Bir vertex buffer , bir index buffer ve bir attribute buffer(optimizasyon için kullanılır) içerir. Bu vertex ve index bufferlara doğrudan erişip bunları gene elle doldurmak mümkün olsada biz burada bu işlemi dosyadan yükleyerek yapacağız. Ayrıca bu eğitselde bahsettiğimiz mesh bir sabit(static) mesh'tir yani animasyon vb.içermez. Mesh'ler submesh denen alt yapılardan oluşur. Submesh derken bir üçgen topluluğundan bahsediyoruz. Bu topluluk aynı attribute(materyal,texture,render state...) ile çizilebilen üçgenleri içerir. Örneğin bir aracın dışı ile içi farklı materyal ve kaplamaya sahiptir ve bunlar submesh olarak bulunabilirler. Submesh'ler 0'dan başlayarak numaralandırılırlar. Bunları çizdirmek için şu şekilde bir metod çağrısı yapılır : mesh->DrawSubset(0);
Şimdi kodu incelemeye başlayalım. //tanımlar Aygit* aygit; ID3DXMesh* mesh; IDirect3DTexture9* kaplama; D3DXMATERIAL* materyal; Burada kullanacağımız model tek bir submesh'e sahip. Tek bir materyal ve tek bir kaplama kullanıyor. void ilklemeler() { .....
yukle_x("araba.x"); }
Rutin ilklemeleri yaptıktan sonra yukle_x metodu içerisinde verilen isimdeki model dosyasını yüklüyoruz. Çizim yaparken sadece ::drawsubset metodunu çağırmamız yeterli olacak. void yukle_x(char* xfile) { //materyal bilgisi ID3DXBuffer* mtrlBuffer = 0; D3DXLoadMeshFromX( xfile, //dosya adı D3DXMESH_MANAGED, //mesh ayarları aygit->getDevice(), //aygıt nesnesi NULL, //adjacency bilgisi &mtrlBuffer, //materyal bilgisi NULL, //efect bilgisi NULL, //materyal sayısı &mesh); //dönen değer //materyalleri al materyal = (D3DXMATERIAL*)mtrlBuffer->GetBufferPointer(); //1. materyali ata aygit->getDevice()->SetMaterial(&materyal[0].MatD3D); //resim dosyası ismini al char* tex_file = materyal[0].pTextureFilename; //dokuyu yükle D3DXCreateTextureFromFile(aygit->getDevice(),tex_file,&kaplama); //dokuyu ata aygit->getDevice()->SetTexture(0,kaplama); //ihtiyaç kalmadı SAFE_RELEASE( mtrlBuffer ); }
ID3DXBuffer yapısı direct3d'nin ardışık veri depolamak için kullandığı bir yapıdır. Burada materyal bilgilerini bu yapıda tutacağız. D3DXLoadMeshFromX metodunu kullanarak bir model dosyası okunabilir. İlk parametre okunacak dosyanın konumu. Burada dosyanın bulunamaması sonucu oluşacak durumu kontrol etmedik ama metoddan dönen değeri kontrol etmek gerekir. 2. parametre mesh oluşturmayla ilgili bazı ayarlar. Bunlar aşağıdakilerden biri yada birkaçının kombinasyonu olabilir: D3DXMESH_SYSTEMMEM // sistem belleğini kullan D3DXMESH_MANAGED // bellek yönetimi otomatik D3DXMESH_WRITEONLY // sadece yazılabilir D3DXMESH_DYNAMIC // dinamik, değiştirilebilir D3DXMESH_SOFTWAREPROCESSING // yazılımsal vertex işlemi yap
3. parametre optimizasyon için kullanılan ekstra bir bilgi, burada kullanmıyoruz. 4. parametre D3DXMATERIAL göstericisi döndürür ve materyal bilgilerini içerir. 5. parametre şu an için kullanılmayacak(shader bazlı). 6. parametre 4. parametrede dönen dizinin uzunluğunu belirtir. Burada ben modelde 1 tek materyal olduğunu bildiğim için 6. parametreyi kullanmadım ve direk gelen materyali aldım. GetBufferPointer() metodundan dönen void* değerini (D3DXMATERIAL*) ' e dönüştürdük. D3DXMATERIAL yapısı bir D3DMATERIAL9 yapısı ve bir kaplama ismi içerir. Gelen değerdeki materyali aktif materyal olarak atadık. Daha sonra yine gelen değerdeki dosya ismini aldık. Bu isimdeki dokuyu yükledik ve gene aktif kaplama olarak atadık. Son olarak artık ihtiyacımız olmayan buffer'ı sildik. Artık mesh çizilebilir durumda. Programı çalıştırırsanız mavi bir araba göreceksiniz ama materyalden dolayı hafif bir yeşillikte olacak. Evet burada anlatacaklarımız bu kadar. Mesh'ler ile ilgili daha detaylı işler yapmakta mümkün(normal hesaplama, optimizasyon, progressive mesh ...). Bu tip detayları çeşitli dökümanlardan araştırmanız tavsiye edilir. 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
|