Ana Menü
· Ana Sayfa
· Dosyalar
· Dökümanlar
· Forum
· Günün Resmi
· Haber Arşivi
· WWW Linkleri
· Üye Listesi

     Forumlar

 strncpy ve strncpy_s
 Konu adi : Borland c++ Builder ile Amiral Batti
 Rady10 - YerliOyun
 Kabusta Kaybolmak
 Konsol da programı bekletmek
 Oyun programlama icin hangi programlama dilli ?
 flash! şanlıurfa bilgisayar oyununda(no rapid)
 Sevgilim Olur musun?
 Directx'e başlamak isteyenler bi bakın
 PSP programlama
 Flash tan php
 Bilgisyr oyunu yapmam için üniverstde hangi bölüme girmeliym
 www.arshiv.gen.ms
 Cimg.h ilgilenenler icin
 müttefik oyunu

Konu Disi
 Emraah
 Yeni sitemiz açıldı
 Kalp krizi durumunda ne yapılmalı?
 Oyun sektöründe hangi görevde çalışmak isterdiniz?
 Takım arkadaşı sorunu
 msn de renklı nıck
 pc hata veriyor ! YARDIM!!
 Gülmek isteyenler Buraya
 İnanılmaz hl 2 modu görüntüsü
 Computer Languages History

[ Forumlara Git ]


OBJ Model Kütüklerini Kullanmak

(1058 kelime)
(819 okuma)   Yazdırılabilir Sayfa




OBJ Model Kütüklerini Kullanmak

// Yazdığımız programlarda ve demolarda her zaman kutular,dikdörtgenler kullanamayız.
// Artık ekrana model çıkarma zamanı geldi diyorsanız bu yazı tam sizler için.
// Bu kodu anladıktan sonra artık diğer model formatlarını kullanmak çok kolay!
// Bir önceki "C/C++ İle Kütük İşlemlerine Giriş" adlı yazıda metin dosyalarından bahsetmiştik
// Şimdi o bilgileri kullanarak bir Obj dosyayı yüklemeyi inceliyeceğiz
// Basit bir model dosyası (sadece vertex koordinatları ve üçgen(face,triangle)lerin vertex
// indeksleri olsun) şu şekilde olabilir:

// Dosyada önce vertexler üç bileşeniyle(x,y,z) verilebilir.Örnek olarak;

// numVertices : 6
// 1.0 3.0 4.0
// 2.0 1.0 4.0
// 5.0 6.0 4.5
// 0.4 2.0 2.0
// 3.2 0.4 1.0
// 3.4 2.5 8.5

// 6 adet vertex'imiz var. Peki ama bunlardan nasıl,hangi üçgenler oluşacak.
// Bunu çözmek için vertex indeksleri kullanılır.Dosyada indekslerimiz şu şekilde olsun;

// numFaces 4
// 0 2 3
// 4 5 1
// 5 3 0
// 1 4 2

// Hepsinden once dosyada kaç vertex,üçgen vs varsa bunlar için önce bellekte dinamik olarak
// yer ayırmalıyız.(new,malloc).İsteyenler STL(standart template library) den <vector> kullanabilir.

// Burada 4 üçgen var. Peki bu rakamlar neyi ifade ediyor.
// 0 2 3 -> bu rakamlar, 1.üçgenin yukarıda belirttiğimiz vertexlerden 0. 2. ve 3. vertexi
// kullanacağını belirtiyor.
// 2.üçgen 4. 5. ve 1. vertexleri kullanacak vs..
// Üçgen dizimiz face[üçgensayısı][3] 3 sayısı üçgenin üç köşesi olduğu için
// vertex dizimiz vert[vertexsayisi] olsun.Birinci(face[0]) üçgeni çizmek için;
// index1=face[0][0]; index2=face[0][1]; index3=face[0][2];
// index değişkenleri sırasıyla yukarıda bahsettiğimiz 0 2 3 değerlerini aldı.
// glVertex3f(vert[index1].x,vert[index1].y,vert[index1].z);
// glVertex3f(vert[index2].x,vert[index2].y,vert[index2].z);
// glVertex3f(vert[index3].x,vert[index3].y,vert[index3].z);
// Tüm model dosyaları bu ve buna benzer yöntemlerle çalışır.

// Obj dosyalarına gelirsek.Obj dosyalari çok basit text dosyalardır.
// Çoğu model programları obj dosyasını export/import edebilir.Ama çoğu kendine göre
// dosyaya eklemeler,çıkarmalar yapıyor.Bazısı normal vektörlerini yazar,
// grup isimlerini ekler,bazısında bu opsiyoneldir vs.İndireceğiniz *.obj(MilkShape3D'de
// kaydedilmişdir www.milkshape3d.com) dosyasını açıp incelerseniz
// v,vt,vn,f ile başlayan satırlar göreceksiniz.
// Diğer satırları gözardı edebiliriz.
// Dosyada:
// 'v' ile başlayan satırlar vertexi belirtir ve sonraki 3 sayi vertexin x,y,z bileşenleridir
// 'vt' doku kordinatlarını(Texture Coordinates) sonraki 2 sayi u,v bileşenleridir.
// 'vn' vertex normallerini belirtir.3 sayi x,y,z bileşenleridir.
// 'f' ise yukarıda anlattığım üçgenlerin vertex,normal,doku kordinatları indeksleri içindir.
// Dikkat ettiyseniz 9 değer var
// f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3
// v1/vt1/vn1 üçgenin 1. köşesinin vertex,normal,doku kordinati indeksi diğerleri 2.3.köşeler
// Bu üçgenin sadece hangi vertexlerden oluştuğu değil buna ek olarak hangi doku
// koordinatları(vt),ve hangi normalleri(vn) kullandığını da anlatıyor bu satır.
// Kullanacağımız tipler ve basit obj sınıfı şu şekilde
// Doku kordinatlarını saklamak için kullanacağız
struct Vektor2{
    float u;
    float v;
};

// Vertex ve normal değerlerini saklamak için
struct Vektor3{
    float x;
    float y;
    float z;
};

// Dikkat ettiyseniz üçgenden bahsederken hep hangi vertex,hangi normal vs diyorum
// Çünkü bu yapıda vertexlerin,normallerin,doku kordinatlarının kendileri değil indeksleri
// saklanıyor.

// Bir üçgenin hangi vertex,normal,doku koordinatlarını kullandığını saklamak için.
// Bu bilgi ile o üçgenin vertexini,normalini bulup çizeceğiz.
struct OBJ_Face
{
    int vertexIndex[3]; // Bu üçgenin hangi vertexlerden oluştuğunu belirten indeks
    int textureIndex[3];// Hangi doku kordinatlarını kullandığını gösteren indeks
    int normalIndex[3]; // Hangi normali kullandığını gösteren indeks
};

class CObj
{

public:
   
    //Yapıcı ve yıkıcı metodlar
    CObj();

    ~CObj();
   
    // LoadObj üye fonksiyonu parametrede belirten dosyadan verileri okuyup
    // üye değişkenlerimize atıyacak.
    void LoadObj(const char *dosya);
   
    // Modelimizi çizmek için
    void Render();

    // Ayrılan belleğin program sonunda geri iadesi için
    void Destroy();

private:
   
    // Bu metod sayesinde modelimizin kaç adet vertex,normal,doku koordinati ve üçgene
    // sahip olduğunu öğrenip aşağıda m_num ile başlayan değişkenlere atıyoruz.
    void GetNums(FILE *fp);

    int m_numVerts;
// Vertex sayısı
   
int m_numNormals; // Normal sayısı
    int m_numTexCoords; // Doku koordinatları sayısı
    int m_numFaces;    // Üçgen sayısı

    // Bu işaretçilere, yukardaki sayılar kadar yer ayrılacak.
    Vektor3         *m_pVerts; // vertex dizisi
   Vektor3         *m_pNormals; // normal dizisi       
    Vektor2         *m_pTexCoords;// doku koordinatlari dizisi
    OBJ_Face    *m_pFaces;    // üçgen indeksleri dizisi   

};

// Metodlarımızıda inceleyelim.
void CObj::LoadObj(const char *dosya)
{
    FILE *fp;
   
    // Dosyadan okunacak her satır bu değişkende
    char satir[255];
       
    fp = fopen(dosya,"rt");
   
    // Dosya açılamadıysa ekrana uyarı mesajı çıkarıp programdan çıkalım.
    if(fp==NULL){
        printf("\n%s acilamadi!\n",dosya);
        exit(0);
    }
   
    // vertex,normal vs.. sayısını öğrenip bellekte yer ayırıyoruz GetNums() ile.
    GetNums(fp);
// getStr() fonksiyonu 3.parametresinde verilen karakterle başlıyan satırı okumak için
    // Bunun amacı:örneğin v satırları arasında boşluk, yorum satırı veya ilgilenmediğimiz bir
    // satır varsa onu atlamak.
    // v 1.0 2.0 2.0
// # exported by...
    // v 3.0 2.0 4.0
    // gibi..burada # ile başlıyan satırla ilgilenmiyoruz.
    // Dosyanın başından itibaren sayısı kadar vertexleri okuyoruz
    for(int i=0;i<m_numVerts;i++)
    {
        getStr(fp,satir,'v');
        sscanf(satir,"v %f %f %f",&m_pVerts[i].x,&m_pVerts[i].y,&m_pVerts[i].z);
    }
    // Doku koordinatları
    for(i=0;i<m_numTexCoords;i++)
    {
        getStr(fp,satir,'v');
        sscanf(satir,"vt %f %f",&m_pTexCoords[i].u,&m_pTexCoords[i].v);
    }
    // Normaller
    for(i=0;i<m_numNormals;i++)
    {
        getStr(fp,satir,'v');
        sscanf(satir,"vn %f %f %f",&m_pNormals[i].x,&m_pNormals[i].y,&m_pNormals[i].z);
    }
   
    // Kodu kısaltmak için geçici fc değişkenini tanımladık ve sıfırladık
    OBJ_Face fc={0};
   
    // üçgen bilgisi okunuyor.
    for(i=0;i<m_numFaces;i++)
    {
       
        getStr(fp,satir,'f');
        sscanf(satir,"f %d/%d/%d %d/%d/%d %d/%d/%d",&fc.vertexIndex[0],&fc.textureIndex[0],&fc.normalIndex[0],
                                                    &fc.vertexIndex[1],&fc.textureIndex[1],&fc.normalIndex[1],
                                                    &fc.vertexIndex[2],&fc.textureIndex[2],&fc.normalIndex[2]
                                                    );
        m_pFaces[i]=fc;
    }
   
    // Dokumuzu yüklüyoruz.
    LoadTexture(texture,"claymore.bmp");
    // Dosyayı da kapattık.
    fclose(fp);
   
}
void CObj::Render()
{
    // modelimizi çizmek için yapmamız gereken artık çok basit.2 döngü işimizi görüyor.
    // 1.si 0 dan m_numFaces'e kadar bir döngü yani tüm üçgenleri çağıracagiz
    // 2.si ise her üçgende 3 tane v,vt,vn olacagından 0 dan 2 ye kadar bir döngü
   
    // en içteki for da o anki üçgenin v,vn,vt indeksleri için bu değişkenler
    // Yine kodu kısaltmak için tanımlıyoruz.
    int i_v,i_vn,i_vt;

    // indeksimizi aldıktan sonra vertex,normal,vs.. dizimizden ilgili vertex,normal,doku kor
    // dinatinin baslangic adresini bu işaretçilerde saklıyoruz ki.Bunları glVertex,glNormal
    // glTexCoord'a parametre olarak geçirelim.
   
    Vektor3 *vV,*vN;
    Vektor2 *vT;

    // Dokumuzu seçiyoruz.
    glBindTexture(GL_TEXTURE_2D, texture);            
   
    glBegin(GL_TRIANGLES);
   
        for(int i=0;i <m_numFaces;i++)
        {   
            for(int j=0;j<3;j++)
            {
                // Şu anki üçgenin ilgili köşesinin ilgili bileşeninin indeksini alıyoruz.
                i_v         = m_pFaces[i].vertexIndex[j];
                i_vn     = m_pFaces[i].normalIndex[j];
                i_vt     = m_pFaces[i].textureIndex[j];
               
                // bu indeksler vasıtasıyla ilgili vertexi,normali.vs buluyoruz.
                // Burada indekslerden 1 çıkarmamızın nedeni Obj dosyasında
                // örneğin f 1/1/2 2/3/1 3/1/2 // Hiç sıfır yok
                // burada üçgenin ilk köşesinin vertex indeksi 1 ama biz biliyoruz ki
                // kastetdiği vertex m_pVerts[1] değil m_pVerts[0]
                // Dolayısıyla 1 eksiltiyoruz.

                vV = &m_pVerts[i_v-1];
                vN = &m_pNormals[i_vn-1];
                vT = &m_pTexCoords[i_vt-1];

                // Son olarak da bunları opengl'ye gonderiyoruz.
                glNormal3f(vN->x,vN->y,vN->z);
                glTexCoord2f(vT->u,vT->v);
                glVertex3f(vV->x,vV->y,vV->z);
            }
   
        }

    glEnd();
   
}

// Obj dosyaları pek kullanışlı değil. Ama bu işi öğrenmek için çok iyi bir başlangıç.
// Bu dosyayı Milkshape'de kaydettim. Aslında dosyanın kullandığı dokuların dosya isimleri ayrı
// bir (*.mtl) dosyada saklanıyor. Ama tek dokumuz olduğu için onu ihmal ettim. Eger modelde
// birden fazla grup(modellerle uğraşanlar bilirler) varsa bunlar için ayrı doku falan
// varsa bu kodlarda biraz oynama yapmak gerekecekti.Zaten bu obj dosyasını fazla kullanmayacağımız
// için fazla da karıştırmak istemedim kodu.

// Geriye kalan açıklamaları indireceğiniz dosyalarda bulabilirsiniz.Bu döküman ile ilgili görüşlerinizi belirtmek yada
// aklınıza takılan konularda sorular sorabilmek için www.oyunyapimi.org sitesinin forumlarını kullanabilirsiniz. İyi çalışmalar.

UzMaN :: 2003 :: www.oyunyapimi.org
  

[ Geri Dön: OpenGL | Bölümler İndeksi ]




Web site powered by PHP-Nuke
Web site engine\'s code is Copyright © 2002 by PHP-Nuke. All Rights Reserved. PHP-Nuke is Free Software released under the GNU/GPL license.
Sayfa Üretimi: 0.048 Saniye