BAB 4
Berikutnya akan membahas File OBJ. Ini adalah format yang baik untuk objek yang statis dalam sebuah game, seperti potongan kecil dari level geometri, senjata yang tergeletak di tanah, dan daya yang tersebar di seluruh tingkat. OBJ format dapat di eksport dari Maya, salah satu standart industri yang mengkreasikan konten 3D, termasuk dunia 3D and tentu saja model 3D untuk game. Digunakan oleh banyak perusahaan game dan artis internasional, Maya telah menjadi salah satu model program 3D yang paling terkenal. Maya dikembangkan dan dijual oleh Alias|waveFront http://www.aliaswavefront.com).
Sebuah ASCII sederhana berbasis format, format model OBJ mengandung data geometry tetapi tanpa animasi. Mungkin kamu ingin menggunakan format ini jika perlu dapat diedit, ataupun membuat file dengan tangan tanpa paket permodelan. Ini juga format yang bagus untuk digunakan jika tidak membutuhkan animasi karena ini sangat mudah digunakan. Meskipun itu bisa mengandung fitur seperti permukaan yang melengkung, fitur tersebut berada diluar lingkup buku ini. Bab ini hanya meliputi geometry dasar. Ini termasuk wajah-wajah yang membentuk model, bersama dengan simpul yang membentuk wajah sendiri. Juga termasuk didalamnya koordinat tekstur , untuk mengijinkan ditambahkannya tekstur map.serta titik normal digunakan untuk penerangan.
MENGURAIKAN FILE TEKS
Sebelum anda bekerja menggunakan file ASCII, anda harus mngerti bagaimana cara menguraikan informasi yang anda butuhkan yang disebut juga menguraikan dari file. C++ sangat sensitive mengenai apa itu tipe data. Anda tidak bisa dengan mudah mengatur bilangan bulat sama dengan string yang berisi sebuah integer dalam format teks dan mengharapkannya untuk bekerja seperti yang Anda pikir. Sebaliknya, anda harus mengekstraksi data dan mengkonversikannya menggunakan fungsi khusus. Dua fungsi terbaik untuk melakukannya yaitu sscanf(untuk mengekstraksi data dari string) dan fscanf (untuk melakukan hal yang sama dengan file). Kedua fungsi tersebut memiliki parameter yang sama, dengan pengecualian dari tiap parameter. Parameter pertama untuk sscanf adalah string yang menahan data yang tidak terformat, sedangkan parameter pertama dari fscanf adalah pointer fileyang ingin anda ekstrak. Parameter kedua adalah yang terpenting. Memegang string yang disebut format string. Format string membahas tentang scanf yang mana tipe variable mencari dan dalam urutan yang bagaimana. Sebagai contoh format string, tabel 4.1 menunjukan bagaimana membuat format string anda.
Variable terakhir adalah pointer ke variable yang ingin anda simpan kedalam nilai konversi anda. Karena fungsi scanf mengambil nomor variable dari argument, anda dapat membacanya dengan berbagai nilai dalam 1 waktu seperti yang anda inginkan. Ini adalah yang terbaik diikat dengan contoh sederhana. Katakanlah Anda memiliki sebuah string, disebut szVertex, yang berisi baris:
Vertex 15 - [14.12, 12.51, 33.10];
Anda dapat melihatnya ada sebuah string, integer dan 3 nilai floating point, sama bagusnya dengan koma, tanda kurung dan titik koma. Anda ingin mengekstrak bagian-bagian yang berguna dan menyimpannya di tipe data yang benar sehingga Anda dapat menggunakannya di kemudian hari dalam program Anda.
Fungsi Scanf akan tampak seperti berikut ini :
sscanf(szVertex, "%s %d – [%f, %f, %f];", s, &i, &f1, &f2, &f3);
seperti yang dapat anda lihat format string terlihat banyak seperti garis aslinya, hanya dengan nilai yang sebenarnya dihapus. Argument % menjelaskan sscanf digunakan untuk mencari lokasi. Tabel 4.1 memperlihatkan kepada anda banyak digunakannya argument % dan dengan apa mereka berdiri. Set terakhir dari parameter adalah daftar tujuan varable. S sebagai string, ada kemungkinan sebagai karakter array, dan I menunjukan integer dan f1, f2, f3 menunjukan banyaknya floating point yang memegang tiga nilai antara kurung persegi. Pastikan tujuan dari variable anda cocok dengan argument yang tepat dalam format string (s menuju kepada string, I menuju kepada inteer dan &f1, &f2, &f3 menuju kepada nilai floating point). Anda dapat melakukan apapun dsini dengan menampilkan fscanf, hanya parameter pertama adalah pointer file daripada sumber string.
MEMAHAMI FORMAT OBJ
Seperti disebutkan, format OBJ didalam teks biasa. Jika Anda membukanya di Notepad
atau Wordpad, Anda akan melihat daftar simpul dan geometri lainnya. ASCII (teks biasa) memiliki format berbasis daripada biner yang memiliki kelebihan dan kekurangan. Karena mereka disimpan dalam teks biasa, lebih mudah untuk seseorang untuk mengedit file tersebut dengan tangan. Ini bisa baik atau buruk. Hal ini adalah yang baik jika Anda perlu tweak bagian kecil dari model, tetapi tweak dapat berakhir pada bencana jika Anda secara tidak sengaja mengubah cara file ditata. Format ASCII juga cenderung untuk mengambil ruang disk lebih dari biner berdasarkan format karena mereka membutuhkan ruang ekstra untuk nilai-nilai besar karena panjangnya satu "bagian" dari geometri pada setiap baris.
Tabel 4.1 Parameter untuk Format String
PARAMETER FUNGSI
% s Adalah format string yang berarti bahwa scanf akan mencari string. Akan terus membacanya sampai menemukan null,ruang,atau karakter garis baru
%c %c membaca karakter tunggal. Dan akan membaca karakter pertama yang dilihat.
%d Membaca bilangan bulat.dengan scanf akan membaca bilangan bulat sampai menemukan spasi,huruf,dan simbol yang bukan angka. %d akan membaca integer positif dan negatif.
%f %f akan membaca bilangan real.
Seperti yang anda lihat,disini ada 4 tipe garis. Mereka adalah garis yang memberikan rincian tentang simpul, koordinat tekstur, titik normal,atau wajah. Mungkin ada jalur lain untuk hal-hal seperti permukaan melengkung dan komentar juga, tetapi Anda tidak akan membutuhkan itu di sini.
Setiap baris dari file model yang dimulai dengan satu atau dua huruf yang menceritakan
program,untuk apa garis itu. Ada empat jenis prefiks, yang akan dijelaskan di sini:
V: Surat v diikuti oleh spasi adalah simpul plain vanilla. Jika hal ini adalah kasus, berikut sebuah ruang tunggal akan tiga floating-point nilai, masing-masing dipisahkan dengan spasi tunggal juga.
vt: String vt menandakan bahwa baris berisi koordinat tekstur. Setiap koordinat tekstur adalah dua float lagi dipisahkan oleh satu spasi.
vn: vn menandakan titik normal. Selain awalan, baris cermin garis titik: tiga float.
f: f menandakan sebuah wajah. Wajah adalah satu set indeks ke dalam array
simpul, texcoords, dan normals. Namun, hanya simpul indeks harus ada; dua yang lain adalah opsional. Setiap Indeks simpul harus positif. Sebuah nilai negatif di wajah
struktur mungkin berarti file tersebut rusak karena Anda tidak bisa memiliki indeks array negatif. Ini tidak akan benar untuk mengatakan "mengambil obyek kedua negatif, "sehingga Anda jelas tidak bisa mengambil "negatif kedua" simpul baik. Pendekatan terbaik jika Anda menemukan nilai negatif dalam struktur wajah untuk mengabaikan
wajah sama sekali.
Lainnya: Setiap baris prefiks lain seperti g (group), # (komentar), p (titik), l (baris), surfing (permukaan), dan curv (kurva) harus diabaikan untuk saat ini. Meskipun mereka adalah bagian dari format,mereka tidak dibahas di sini.
Sebuah garis khas dalam file obj yang mewakili wajah atau segitiga dan hanya berisi simpul akan terlihat seperti ini:
f 1 2 3
Kode ini mengatakan bahwa wajah menggunakan titik pertama, kedua, dan ketiga indeks untuk menggambar segitiga. Tidak adanya set lain indeks menunjukkan bahwa tekstur koordinat dan titik normals tidak diperlukan.
Jika wajah yang bertekstur, tetapi tidak mengandung titik normals, sintaks akan sama dengan ini:
f 1 / 4 2 / 5 3 / 6
Baris ini mengatakan bahwa segitiga menggunakan simpul 1, 2, dan 3 dan tekstur indeks 4, 5, dan 6.
Namun variasi lain dari garis ini dapat menggunakan semua tiga jenis simpul data koordinat tekstur titik,, dan indeks yang normal. Baris yang akan terlihat seperti:
f 1/4/7 2/5/8 3/6/9
Angka pertama adalah untuk simpul itu sendiri, yang kedua adalah untuk tekstur mengkoordinasikan, dan yang ketiga adalah untuk titik normal.
Hanya ada satu variasi yang lebih: normals vertex dan titik, tetapi tidak ada koordinat tekstur. Ini terlihat seperti ini:
f 1 / / 4 2 / / 5 3 / / 6
Dua garis miring memisahkan angka bukan satu, ini menunjukkan bahwa angka kedua adalah normal simpul, bukan koordinat tekstur.
Kenyataan bahwa wajah tidak perlu berisi semua informasi dapat sangat berguna. Tidak ada alasan sebuah objek yang tidak memerlukan pencahayaan atau texturing harus berisi informasi tersebut. Dengan hanya meninggalkan tidak dibutuhkan informasi di luar, ukuran file berkurang jauh.
Mari kita sekarang beralih ke beberapa kode yang menunjukkan Anda bagaimana untuk memuat file menjadi sesuatu yang bisa anda kerjakan.
Memuat Format OBJ
Karena obj tidak berisi apapun di header, Anda membutuhkan beberapa semacam array resizable untuk memegang simpul Anda, wajah, dan komponen lainnya. Dalam pelaksanaannya ditampilkan di sini, semuanya dimuat ke sebuah STL vektor, semacam array resizable.
Setiap jenis data memiliki struktur tersendiri. Vector3 berisi dua float dan digunakan untuk menyimpan posisi titik tunggal, atau normal vertex. Vector2 jauh seperti saudara yang lebih besar, tetapi memegang hanya dua nilai, cocok untuk koordinat tekstur.
Terakhir dari semua adalah SObjFace, yang berisi 12 bilangan bulat unsigned, tiga untuk
setiap sudut indeks, indeks tekstur coord, dan indeks yang normal. bahkan jika semua variabel wajah tidak selalu digunakan, penyimpanannya masih ada.
Sekarang Anda siap untuk membaca dalam file. Cara terbaik untuk melakukan ini adalah membaca dalam satu baris pada satu waktu, memeriksa awalan, dan ekstrak sisa nilai menggunakan fungsi sscanf. Setiap jenis nilai (data titik, titik yang normal, tekstur mengkoordinasikan, dan wajah) memiliki array sendiri untuk menahannya. Jika loader menemukan baris yang dimulai dengan sesuatu yang tidak menandakan diakui setengah, itu hanya membaca garis dan membuangnya.
Dalam kelas CObj, ada dua nilai Boolean: m_bHasTexCoords dan m_bHasNormals. Variabel ini diatur ke benar jika coord tekstur (untuk m_bHasTexCoords) atau garis normal verteks (untuk m_bHasNormals) ditemukan dalam file. Meskipun hal ini tidak bekerja, ia memiliki beberapa kekurangan. Jika untuk beberapa alasan wajah tidak ada setelah semua titik, loader tidak akan tahu apa jenis wajah untuk membaca dan akan default hanya untuk membaca simpul.
PERHATIAN
Karena format OBJ dapat diprediksi dan juga dapat diedit dengan mudah, akan sangat membantu untuk memiliki beberapa pengecekan error. Misalnya, struktur wajah mungkin referensi simpul yang tidak valid, seperti jumlah titik -2, atau jumlah titik besar dari jumlah total simpul. Untuk menghindari masalah, Anda harus memasukkan beberapa error untuk memeriksa ke dalam kode Anda. Setiap kali Anda memuat nilai, pastikan untuk memeriksa apakah itu sah. Sebagai contoh, tidak ada nomor pada garis wajah harus negatif. Karena mereka adalah indeks ke dalam array, mereka harus positif atau program dapat hancur. Hal yang sama berlaku untuk lebih besar dari jumlah total simpul, tekstur nilai-nilai koordinat, atau normals. Jika wajah referensi simpul luar dari apa yang seharusnya, pilihan terbaik adalah untuk mengabaikan bahwa wajah sepenuhnya. Melakukan hal ini mungkin akan mengakibatkan sebuah lubang dalam model Anda, tetapi sebuah lubang kecil akan terlihat lebih baik daripada tonjolan jelek jika Anda mencoba untuk menebak apa indeks apa yang seharusnya.
Hal ini dapat menyebabkan hasil yang tidak diharapkan seperti hilang atau cacat geometri,
atau bahkan model tidak muncul sama sekali. Jika ini terjadi,pemecahan termudah adalah dengan hanya membuka file dan memindahkan informasi simpul yang bagian atas file. Namun, untuk tujuan pembelajaran dan loading yang OBJs paling umum, ini seharusnya tidak menjadi masalah.
Ketika Anda turun ke face data, anda hanya melihat dua variabel dan mengatur parameter sscanf anda tepat.
Setelah anda memiliki semua data yang dikumpulkan dan disimpan, ada beberapa lagi
hal yang harus Anda lakukan sebelum render. Jika Anda melihat pada kelas,Anda akan melihat bahwa ada pointer untuk semua jenis, serta vektor resizable. Ada alasan yang sangat bagus untuk ini.
Cara termudah untuk mengakses elemen dari sebuah vektor STL adalah melalui operator [] seperti yang Anda lakukan dengan array standar. Namun, metode ini dapat cukup lambat dan tidak dianjurkan, terutama jika Anda perlu menggunakannya setiap kali anda membuat satu frame, seperti halnya dengan format OBJ.
Solusi untuk ini adalah hanya mengatur pointer ke elemen pertama dalam STL vektor. Ini tidak menyebabkan masalah karena STL vektor dijamin akan terus-menerus.Sekarang semua data Anda sudah terorganisir, Anda dapat mulai khawatir tentang render.
RENDERING OBJ
Mari kita lihat apa yang dapat Anda lakukan tentang hal ini pada layar. Jika Anda beralih ke CObj ini:: Render () fungsi dalam obj.cpp, Anda akan melihat apa yang diperlukan untuk mendapatkan segalanya pada layar. Hal pertama yang dilakukan adalah untuk mengaktifkan dan mengikat tekstur. Pastikan untuk memeriksa apakah tekstur berlaku sebelum memanggil untuk menghindari masalah.
Kemudian Anda bisa mulai rendering. Hal pertama yang terjadi adalah ia akan mengecek untuk melihat komponen yang termasuk dalam model dan memilih loop didasarkan pada hasil. Ada loop terpisah untuk setiap kombinasi yang mungkin,untuk meningkatkan kecepatan. Dalam pseudo-kode, kode render akan terlihat seperti kode berikut. Perlu diingat pseudo-kode hanya memberi Anda tata letak dasar tentang bagaimana fungsi akan terlihat. Ini harus jelas bahwa kode berikut tidak akan mengkompilasi dalam C reguler / C + + compiler.
for(each vertex)
if(normals are present)
SendNormal();
if(texcoords are present)
SendtexCoord();
SendVertex()
Itu akan memerlukan dua pernyataan if untuk setiap titik, yang merupakan sisa waktu prosesor ketika Anda dapat lakukan dengan pasangan tetapi untuk setiap frame.Sebaliknya, strukturnya lebih seperti ini:
if(has normals and tex coords)
for(each vertex)
SendNormal()
SendTexCoord()
SendVertex()
else if(has texcoords but not normals)
for(each vertex)
SendTexCoords()
SendVertex();
TIP
Karena geometri adalah statis, Anda mungkin ingin mempertimbangkan kompilasi semua kode Anda untuk menampilkan daftar list. Sebuah daftar tampilan menciptakan objek dikompilasi dan akan mengurangi waktu pemrosesan yang diperlukan untuk setiap frame. Hal ini dapat dilakukan pada saat membuka di OpenGL menggunakan glGenList fungsi dan glNewList. Kemudian, didalam rending fungsi anda, daripada mengirim setiap simpul ke renderer, Anda cukup menjalankan glCallList dengan tepat menampilkan daftar untuk menampilkan model Anda.
Dan seterusnya. Meskipun pendekatan ini lebih panjang, jauh lebih efisien. Untuk mendapatkan nilai yang sesuai untuk masing-masing komponen, Anda menggunakan struktur wajah indeks ke dalam array normals, tex coords, dan simpul. Ada satu kekhasan kecil di sini. Namun untuk beberapa alasan,pencipta dari format OBJ memutuskan untuk membuat 1 indeks pertama,bukan dari 0. Untuk mengatasi ini, Anda harus mengurangkan 1 dari masing-masing titik,tekstur koordinat, dan titik yang normal indeks yang membentuk wajah.
Hal ini dilakukan pada saat membuka dalam kode demo, lihat konstruktor dari SObjFace untuk informasi lebih lanjut. Selamat bersenang-senang.
Untuk lebih jelasnya,lihat model sepenuhnya yang ditunjukkan dalam Gambar 4.1.
TIP
OBJ format sebenarnya memiliki lebih banyak format untuk ditawarkan. hal ini dapat mendukung beberapa jenis permukaan melengkung, wajah yang telah lebih dari tiga sisi, dan hal menarik lainnya. Jika Anda merasa ambisius, coba memodifikasi loader untuk bekerja dengan semua hal-hal ekstra. Ada dokumen lengkap Obj di seluruh Internet. Cukup ketik Format OBJ dipencarian. Beberapa link yang bisa dijadikan bahan antara lain http://astronomy.swin.edu.au/ ~ pbourke / geomformats / obj / dan http://www.royriggs.com/obj.html. Keduanya berisi deskripsi dari format file obj; URL pertama mencakup Format penuh, termasuk garis, titik, permukaan, dan kurva.
Gambar 4.1 Model OBJ lentera jin . Model khusus ini termasuk simpul saja. Untuk lebih jelasnya buka di sini di wireframe. Model ini dibuat oleh John Spirko (http://www.iaw.on.ca/ ~ jspirko / galleries.htm) dan ditemukan di 3D Model Dunia (http://www.3dmodelworld.com). Pastikan untuk melihat kedua situs tersebut untuk model lainnya.
KESIMPULAN
Kesimpulan dari bab ini. Meskipun format OBJ dasar cukup sederhana, konsep-konsep dari bab ini dapat digunakan untuk hal lain di ASCII berbasis format Anda mungkin menemukan, seperti ASE dan ASC. Bab berikutnya membahas beberapa informasi lebih lanjut dengan pengenalan kerangka animasi. Dalam bab berikut, Anda akan melihat bagaimana kerangka animasi telah mengubah dunia game dan belajar tentang beberapa permainan yang sudah menggunakannya. Anda juga akan belajar bagaimana kerangka
animasi bekerja, dan alasan mengapa Anda mungkin ingin menggunakan itu dalam permainan berikutnya.
Tidak ada komentar:
Posting Komentar