Java a 3D grafika – primitiva

19. února 2004

Jsou situace, kdy potřebujeme zobrazovat složité objekty reálného světa, které není možné vytvořit jinak než zadáním souřadnic jednotlivých vrcholů, na druhou stranu jsou však i situace, kdy jsou tělesa, která chceme zobrazovat, snadno matematicky definovatelná. Mezi taková patří například kužely, kvádry nebo koule. A právě tato primitiva budou vedle seznámení se s třídou Appearance hlavní náplní tohoto článku.

V Javě 3D jsou všechna primitiva odvozena od bázové třídy Primitive z balíčku com.sun.j3d.utils.geometry. Tato třída je navzdory tomu, co by se dalo očekávat, odvozena od třídy Group, místo toho, aby byla odvozena od třídy Shape3D. S objekty Shape3D však pracuje také, pouze je to skryto před zraky programátorů.

Manipulace s primitivy je, jak by se slušelo, snadná a přímočará, tedy do určité míry. Stačí zadat poloměr a máme kouli, stačí šířka, výška a délka a na světě je kvádr. Ostatně, konstruktory mluví samy za sebe.

Kouli je možné vytvořit například voláním konstruktoru Sphere(float radius), který vytvoří kouli o poloměru rovném parametru radius umístěnou v počátku soustavy souřadnic. Stejně jako u dalších primitiv, s nimiž se seznámíme dále, můžeme i u koule určit „hrubost“, tedy množství vrcholů mnohostěnu aproximujícího kouli. To pochopitelně nelze určit přímo, ale jen prostřednictvím parametru divisions v konstruktoru Sphere(float radius, int flags, int divisions), který určuje rozlišení vzhledem k souřadnicovým osám.

Konstruktor Box(float width, float height, float length, Appearance ap) vytváří kvádr o zadaných rozměrech, jehož střed leží v počátku, tedy souřadnice jeho pravého předního vrcholu jsou [width/2, height/2, length/2]. Význam parametru Appearance si vysvětlíme dále v tomto článku. Třída Box je jediná z podtříd třídy Primitive, která vyžaduje ve všech svých konstruktorech předání objektu Appearance.

Další z primitiv, kužel, je možné vytvořit voláním konstruktoru Cone(float radius, float height). Takto vytvořený kužel má podstavu o poloměru radius a jeho výška je rovna height. Osa souměrnosti kužele leží na ose y a střed této osy leží v počátku soustavy souřadnic. Pokud chceme u kužele určit rozlišení, musíme konstruktoru předat dva parametry – jeden pro rovinu podstavy (xdivision), druhý pro osu, v níž leží osa kužele (ydivision). Konstruktor vypadá takto: Cone(float radius, float height, int flags, int xdivision, int ydivision, Appearance ap).

Poslední třídou z našeho výčtu je třída Cylinder, která slouží k vytváření válců. Konstruktoru Cylinder (float radius, float height) se předávají dva parametry, poloměr podstavy (radius) a výška válce (height). Další konstruktory, vyžadující více parametrů, jsou analogické ke konstruktorům již zmíněných tříd.

Na následujícím obrázku jsou zobrazena všechna zmiňovaná primitiva. Pokud ale mají vypadat skutečně trojrozměrně, neobejdeme se bohužel bez světel, s nimiž se seznámíme až v příštím článku, proto zde nyní neuvádím zdrojový kód.

Ukázka jednotlivých primitiv

Pokud máme ve scéně několik objektů Primitive se stejnou geometrií, je vytvořen jen jeden objekt Geometry, který je pak sdílen mezi těmito objekty. Tato optimalizační technika má několik vedlejších důsledků, z nichž nejvýznamnější je, že změníme-li objekt Geometry jednomu objektu, změní se tím u všech. Pokud tedy budete chtít, aby se objekty Geometry nesdílely, nastavte v konstruktoru příznak GEOMETRY_NOT_SHARED.

Appearance

Vzhled objektů ve scéně je dán jednak geometrií těchto objektů, obsažené v objektech Geometry (v nich mohou být uloženy i informace o barvě, o tom ale až jindy), jednak informacemi uloženými v objektech Appearance, které udržují vlastnosti jako je například barva, šířka hran nebo „materiál, ze kterého je objekt vytvořen“. Materiálem jsou myšleny vlastnosti povrchu vzhledem k osvětlení.

Je toho docela dost, co lze pomocí objektů Appearance udělat, nikoli vše je ale stejně užitečné. Ačkoli je to překvapující, například barvu příliš nevyužijete, protože ta je užitečná pouze u neosvětlených objektů, místo toho budete spíše určovat materiál. Pojďme se nyní alespoň v krátkosti seznámit s víceméně užitečnými metodami třídy Appearance.

Metoda setColoringAttributes(ColoringAttributes attr) umožňuje nastavovat druh stínování a barvu, která však, jak už bylo řečeno, je použita pouze tehdy, pokud není objekt osvícen. To je trochu zvláštní, protože druh stínování můžete u osvětlených objektů potřebovat, zatímco barva nastavovaná v témže objektu se u nich vůbec neprojeví.

Konstruktor třídy ColoringAttributes(Color3f color, int shade) vyžaduje dva parametry. První z nich, objekt Color3f je klasická RGB barva bez alfa kanálu určená třemi čísly float z intervalu 0 až 1. Druhý parametr určuje typ stínování, který nabývá jedné z hodnot konstant definovaných ve třídě ColoringAttributes SHADE_FLAT, SHADE_GOURAUD, FASTEST a NICEST (přitom většinou, ale nemusí tomu tak být vždy, platí, že SHADE_FLAT je to samé jako FASTEST a SHADE_GOURAUD jako NICEST). Pokud použijete stínování SHADE_FLAT, bude mít každý trojúhelník jednu barvu po celé své ploše, zatímco když použijete stínování SHADE_GOURAUD, bude každý vrchol trojúhelníku moci mít jinou barvu a barva uvnitř tohoto trojúhelníku se bude postupně měnit mezi těmito vrcholy. Porovnat výsledek obou stínovacích modelů můžete na následujícím obrázku.

Ukázka stínování

Další z parametrů, které můžeme pomocí objektů Appearance ovlivňovat, jsou vlastnosti čar a bodů. K tomu slouží metody setPointAttributes(PointAttributes attrinutes) a setLineAttributes(LineAttributes attributes). Až budeme vytvářet drátěné modely, ukážeme si jejich použití, zatím pro nás nemají velký význam.

Docela zajímavé ale je využití průhlednosti, k čemuž slouží metoda setTransparencyAttributes(TransparencyAttributes attributes). Konstruktor TransparencyAttributes(int transparencyMode, float transparencyValue) přebírá dva parametry. Parametr transparencyMode nabývá hodnoty jedné z konstant BLENDED, SCREEN_DOOR, FASTEST, NICEST nebo NONE, definovaných ve třídě TransparencyAttributes. Nejzajímavější z těchto módů je BLENDED, který, pokud máte v objektu Geometry uloženy hodnoty alfa transparence u jednotlivých vrcholů, zkombinuje tyto hodnoty podle určitého vzorce s hodnotou v objektu Appearance. Následující obrázek byl vytvořen s využitím průhlednosti s hodnotami parametrů transparencyMode rovném NICEST a transparencyValue rovném 0.5 (0 je pro neprůhledné objekty, 1 pro zcela průhledné).

Ukázka transparence

To je vše, co jsme zatím schopni využít. Příště rozšíříme své znalosti o již zmiňovanou práci se světly.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *