Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
OpenGL -10.díl Náčítání modelů ze souborů
open gl
5. září 2002, 00.00 | Po dlouhé době přicházíme s dalším dílem seriálu. Tentokrát se budeme věnovat načítání modelů ze souborů ASE. Půjde o seznámení s jednoduchým ASCII formátem, do kterého můžete z 3D MAXU exportovat své modely.
{Teorie}Po dlouhé době přicházím s dalším dílem seriálu, který jsem napsal při dlouhém prázdninovém nicnedělání. Budeme se věnovat načítání modelů ze souborů ASE. Půjde o seznámení s jednoduchým ASCII formátem, do kterého můžete z 3D MAXU exportovat své modely. Připravte se, nebude to žádná sranda, ale tvrdá programátorská řehole. Výsledek ale bude stát za to.
Modely můžeme ukládat do nejrůznějších formátů. Mezi nejčastější formáty patří DXF (původně jsem zamýšlel tento článek napsat o něm), 3DS (bude popsán v některém dalším díle), MAX, DWG, ASE atd. Formáty rozdělujeme podle toho, jestli jsou data zapisovány binárně nebo textově.
Pro tento článek jsem vybral ASCII formát ASE, který vyexportujeme v programu 3D Max. Tento formát není nic moc, ale nějak začít musíme. Ale pro nás má jednu velkou přednost, jednoduchost. Nevýhodou naopak je pomalost zpracování textového souboru.
Napišme si třídu, která bude ASE soubory načítat. Tuto třídu pojmenujeme TASEFile. Do této třídy budeme natahovat informace o počtech objektů, počtech materiálů, ukazatel na stream, pak budeme potřebovat data jednotlivých objektů a data materiálů.
Popišme si nejdříve jak jsou data v souboru organizována. Vysvětluje to následující obrázek:
Při načítání si nejdříve zjistíme základní informace, jako je počet objektů, počet materiálů atd. Potom načteme materiály. Každý materiál je reprezentován barvou a popřípadě i texturou (velmi zjednodušeně řečeno). Celá scéna se skládá z jednoho nebo více objektů. Proto se dáme do načítání jednotlivých objektů. Každý objekt má definované umístění a pootočení (neuvažoval jsem je). Pro každý objekt načteme všechny vrcholy objektu (VERTEX). Potom načteme, jakým způsobem tyto vrcholy pospojovat (FACE). Pokud je objekt potexturován načteme navíc vrcholy pro texturu TVERTEX a pro namapování potřebujeme také TFACE. Navíc ještě můžeme ze souboru načíst nebo vypočíst normály, aby objekt vypadal reálněji ve světle. Pokud jste ještě nepochopili, co jsou vertexy a face, podívejte se na následující obrázek:
Pro dokonalé pospojování všech vrcholů nám postačí spojovat vrcholy po 3 bodech (například A,B,F atd).
Udělejme si ještě krátký výlet do souboru ASE, ať si můžeme představit co máme před sebou:
|
To je vystřižená jen malá část ASE souboru a našim úkolem je správně využít
data, která se nám tu povalují. Komentář uvnitř rámečku je natolik bohatý, že
není třeba dál jednotlivé řádky rozebírat. A jakým způsobem budeme data načítat
se dozvíte v další části článku.
To by byla teorie a pusťme se do programování. Jak již bývá zvykem, algoritmy a postup programování jsem si sám nevycucal z prstu (a proč taky), ale inspiroval jsem se výtečnými tutoriály na www.gametutorials.com. Zde je jeden tutoriál věnovaný právě čtení souborů ASE. Všechny tutoriály na zmíněné adrese jsou napsány pro Visual C++ a já jsem je přežvýkal po svém, polidštil a takříkajíc počeštil :). Zkrátka, jak říkám celý kód z GAMETUTORIALS jsem kompletně přepracoval do C++ Builderu a mohu říct, že z původního kódu nezůstal kámen na kameni. Tak se na něj podívejme. Pro dokonalé pochopení navíc doporučuji nahlížet do souboru ASE.
V hlavičkovém souboru ASEClass.h máme všechno potřebné důležité třídy, datové struktury a konstanty. Na začátku tohoto souboru si všimněte právě definic konstant (např. #define OBJECT "*GEOMOBJECT" ). Podle těchto konstant budeme vyhledávat (a orientovat se) v souboru ASE. Dále zde máme definovány samozřejmosti jako 2D a 3D bod ve strukturách TBod2D a TBod3D. Stejně tak se zde nachází definice 1 FACE, který se skládá ze 3 celočíselných hodnot (viz výše). A poslední strukturou je TMyMaterial, která má za úkol popisovat materiál objektu.
Veškerou hybnou silou celého načítacího procesu jsou dvě třídy
T3DObject
TASEFile
Podívejme se na ně blíže:
|
V obou třídách je velmi důležitým prvkem nevizuální objekt TList, který s oblibou využívám pro uložení jakýchkoli dat. Pro připomenutí pouze uvedu, že TList je analogií známého TStringListu, ale místo položek (Item) typu AnsiString jsou zde ukládány položky typu void, takže do něj můžeme nacpat úplně vše. Do objektu TASEFile, uložíme veškeré informace o materiálech a hlavně všechny objekty.
O načítání ze souboru se stará funkce LoadFromFile a zobrazení zajišťuje funkce Render. Funkce MoveToObject je pomocná funkce, která přesunuje ukazatel ve streamu před určitý objekt. Nyní se podívejme na některé záludnosti načítací funkce, na první pohled se funkce může zdát nepřehledná, ale opakuje se zde několikrát jedna a tatáž myšlenka:
|
Veškeré načítání je postaveno na tomto principu, najít data v souboru (v tomto
případě vertexy), načíst tyto data a vložit je do paměti (do TListu Vertexy).
Doufám, že vám tato malá ukázka postačí k pochopení, protože pro podrobnější
popis funkce zde nemáme prostor. Podívejme se nyní na to, jakým způsobem využít
načtená data a zobrazit je. To řeší funkce Render. Připomeňme, že
|
V cyklu procházíme uložené 3D objekty, máme je uloženy v TListu Objekty. Přístup
k jednotlivým 3D objektům dostaneme přes
Object = (T3DObject *)Objekty->Items[c];
Ukazatel z položky TListu je typu void *, proto jej musíme přetypovat na vhodný
typ (T3DObject *). Stejně získáme přístup k materiálům. Nyní máme ukazatel na
jeden objekt a přes něj se přistupujeme k jednotlivým vertexům a face (opět
uloženy v TList). No a nakonec stačí vykreslit trojúhelník a správně namapovat
texturu. Myslím, že to již nepotřebuje větší komentář.
Poznámky:
V textu se vyskytuje výraz face, pro který jsem nenašel český ekvivalent.
Face nám říká, které 3 vertexy máme spojit.
Zdrojové soubory:
Moje řešení (BCB 4.0 500 KB)
GameTutorials (VC++6.0 250 KB)
V uvedeném příkladu jsem neřešil všechny možnosti formátu ASE. Neřešil jsem umístění celého modelu v prostoru včetně otočení, dále jsem neřešil normály atd. To už je výzva pro vás, co myslíte?
Obsah seriálu (více o seriálu):
- OpenGL - 1.díl Nastavení a jednoduché kreslení
- OpenGL - 2 díl Rotace objektů
- OpenGL v C++ Builderu (3.díl)
- OpenGL v C++ Builderu (4.díl)
- OpenGL v C++ Builderu (5.díl)
- OpenGL v C++ Builderu (6.díl)
- OpenGL -Jednoduché efekty 1
- OpenGL - 8. díl - 3D Font, JPEG textury
- OpenGL 9. díl - Bitmap Font
- OpenGL -10.díl Náčítání modelů ze souborů
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007