[Vissza a CD főoldalra]

Példaprogramok

A könyv egyes fejezetei végén C++ nyelvű programrészletek mutatják be, hogy az elmélet hogyan alkalmazható a gyakorlatban. A programok teljes változatban a CD-n megtalálhatók.
 

A példaprogramok fordítása

A programokat Borland C++ és Microsoft C++ fordítóprogrammal fordítottuk le. A fordítás során "nagy" memóriamodellt illetve WIN32 módot kell választani. A fordítóprogram kapcsolóinak és a defines.h fájl WINDOWS konstansának a megfelelő beállításával MS-Windows és DOS környezetben futtatható programokat hozhatunk létre.
 

A programok közös kerete

A programok közös grafikus keretrendszert használnak, amely a következő fájlokból áll.
  • defines.h: fordítási paraméter fájl. Ebben a fájlban leírhatjuk, hogy a következő fordítás során DOS vagy MS-Windows alkalmazást kívánunk-e a készíteni (WINDOWS), a könyvtár logikai vagy fizikai eszközkoordinátákkal dolgozzon-e (LOGCOORD), foglaljunk-e memóriát a z-buffernek (ZBUFFER), és hogy mekkora legyen a grafikus terület maximális mérete (XRES, YRES). Előfordulhat, hogy a lefordított program a z-buffer lefoglalása során "Dinamikus memória elfogyott'' hibaüzenettel rögtön az indítás után leáll. Ezen úgy segíthetünk, hogy vagy teljes egészében kikapcsoljuk a z-buffer memóriát (a 2D programok és a sugárkövetés úgy sem használják), vagy pedig csökkentjük a grafikus terület méretét.
  • types.h: általános típus fájl. Ez a fájl a beállított környezet alapján elhelyezi a megfelelő include direktívákat (MS Windows esetén a windows.h-t, DOS esetén a graphics.h-t) és definiálja a környezetfüggetlen elérés típusait (Coord, RGBColor).
  • tga.h: a generikus, nyújtózkódó tömb sablon (Array) definíciós fájlja.
  • menu.h: egyszerűsített menükezelés fájlja.
  • zbuffer.h: a z-buffer osztály fájlja.
  • draw.h: a fizikai szintű kezelés deklarációs fájlja. Itt a fizikai szintű elérés típusait (PCoord, PColor, ROP, PVertex) és függvényeinek a prototípusát adjuk meg.
  • draw.cpp: a fizikai szintű rajzolás fájlja. A PLine rutinban a szakaszrajzoláshoz a Bresenham algoritmust implementáltuk. A 3D háromszögek árnyalt megjelenítését a PFacet eljárás végzi el, amely a takarási viszonyokat z-buffer algoritmussal határozza meg, a színt pedig Gouraud árnyalással interpolálja.
  • objwin.h: az objektum-orientált, logikai szintű eszközkezelő deklarációs fájlja. Itt található a Window osztály, ami a grafikus kimenetet eszközfüggetlen módon illeszti és eseményvezérelt felhasználói kommunikációt valósít meg.
  • window.cpp: az objektum-orientált eszközkezelő implementációs fájlja. A Window osztály tagfüggvényein kívül, itt írtuk le azokat a beviteli eszközöket illesztő rutinokat és fizikai szintű kiviteli eljárásokat (Pixel, PReadPixel, PClear) is, amelyek függnek a futási környezettől (jelen esetben MS-Windows vagy DOS/BGI). Ez azt jelenti, hogy ha az olvasó más környezetekre is szeretné használni a megadott programokat, csak ezt a fájlt kell kiegészítenie.
  • tga.h: TARGA fájlkezelő osztályok definíciója. A TARGA formátum kezelését két osztály támogatja. A TGAOutputFile egy TARGA fájlt készít el, aTGAInputFile pedig egy TARGA fájlt olvas be. Ezen osztályokat használjuk a képek mentéséhez és betöltéséhez.
  • color.h: színkezelés deklarációs fájlja. Ebben a fájlban található a Spectrum generikus osztály és a Color szín osztály definíciója.

TARGA formátumú képek megjelenítése: tgashow.exe


Figyelem: ha a program az indítása után egy üres képet tölt be, akkor nem találta meg a képfájlt (image.tga). Ekkor állítsa az internet böngésző "kezdet" tulajdonságát a CD gyökerére! Ez úgy ellenőrizhető, hogy a fájl megnyitás a gyökérkönyvtárból indul.
 
 

A tgashow példaprogram TARGA típusú képfájlokat jelenít meg. A programot a 1.7 fejezetben tárgyaltuk. A képfájl nevét parancssor argumentumként kell megadni. A megjelenített képet medián szűrő és doboz szűrő algoritmusokkal módosíthatjuk, majd az eredményt eltárolhatjuk. 

A programmal előállított képek:


Egy zajos kép

mediánszűrés után

dobozszűrés után

Az alkalmazás belépési pontját, az ablakobjektumát és a szűrőalgoritmusokat a tgashow.cpp fájl tartalmazza. A programhoz, az általános keretfájlokon kívül a tga.h fájl tartozik, amelyben a TARGA fájlkezelő osztályok definíciója található. A TARGA formátum kezelését két osztály támogatja. A TGAOutputFile egy TARGA fájlt készít el, aTARGAInputFile pedig egy TARGA fájlt olvas be. Ezen osztályokat használjuk a képek mentéséhez és betöltéséhez.
 

Gumivonal rajzoló program: gumi.exe

Ez a program a 2.3.4 fejezetben tárgyalt gumivonal rajzoló implementációja, amely az eseményvezérelt programozás fogásait mutatja be. A teljes program a gumi.cpp fájlban olvasható, amelyet a keretrendszerhez kell hozzászerkeszteni.
 

Színszerkesztő: color.exe

A színszerkesztő program a 4.3 fejezet színkezelő osztályait és algoritmusait használja fel. A program segítségével a grafikus terület háttérszínét változtathatjuk RGB, CMY, HLS színrendszerben illetve monokromatikus spektrum hullámhosszának a módosításával.

Az interaktív kezelői felületet a colgen.cpp fájl valósítja meg, amely épít a color.h színosztályaira és a color.cpp-ben implementált színkonverziós és a színillesztő algoritmusokra. Ezekben a fájlokban található a Spectrum generikus osztály és a Color szín osztály definíciója, és a Color osztály színkonverziós rutinjai és a színillesztő függvényei.
 

2D grafikus rendszer: 2d.exe


Ez az alkalmazás egy teljes 2D grafikus rendszert mutat be. A program lényeges elemeit a 7. fejezetben ismertettük. A program segítségével interaktív módon törtvonalakat, Bezier görbéket és Lagrange görbéket definiálhatunk. A korábban definiált görbéket az egér kurzor és a bal egérgomb segítségével kiválaszthatjuk. A bal egérgomb lenyomásával majd a lenyomott gombbal az egér mozgatásával a kiválasztott görbét áthelyezhetjük. A kiválasztott objektumokat XOR módban rajzoljuk, az áthelyezés hasonló a gumivonal technikához.

A program tartalmazza a görbék modellezéséhez szükséges adatszerkezeteket és algoritmusokat. A megjelenítéshez a teljes 2D grafikus csővezetéket implementáltuk, amely vektorizálja a görbéket, alkalmazza a modellezési és nézeti transzformációkat, Cohen-Sutherland algoritmussal elvégzi a vágást, majd Bresenham algoritmussal raszterizálja a kapott szakaszokat.

A 2d.cpp a virtuális világot és a kamerát összefogó színteret (Scene), a színtér módosításához és megjelenítéséhez szükséges függvényeket, azaz a bemeneti és a kimeneti csővezeték algoritmusait, és a felhasználói interakció eljárásait adja meg.

A további programfájlok:

  • 2d.h: 2D geometria. Itt írtuk le az euklideszi pont (Point2D), a projektív pont (HomPoint2D), a téglalap (RectAngle), és a geometriai transzformációk (Transform2D) osztályait.
  • polynom.h: paraméteres görbék polinomjai. A Lagrange interpolációhoz és Bezier approximációhoz szükséges polinomok szerepelnek ebben a fájlban.
  • world2.h: a 2D virtuális világ objektumtípusai. Ez a fájl írja le a 2D virtuális modellek szerkezetét.
  • world2.cpp: a 2D virtuális világ vektorizációja. A fájlban található tagfüggvények a 2D virtuális világ objektumaihoz tartozó vektorizációs algoritmusokat implementálják.
  • camera2.h: 2D kamera. Az ablakból és a nézetből álló 2D kameraosztályt találhatjuk meg itt, amely a 2D nézeti transzformáció előállításáért felelős.
  • pipe2.h: 2D kimeneti csővezeték típusai. A fájl a 2D kimeneti csővezetéken átvihető objektumtípusokat (pont, szakasz, téglalap, szakaszlista) adja meg, és leírja a transzformációjukat.
  • pipe2.cpp: 2D kimeneti csővezeték eljárásai. Itt lelhetjük fel a 2D kimeneti csővezeték eljárásait, mint például a Cohen-Sutherland szakasz vágás algoritmusát.
A kimeneti csővezeték végén megjelenő szakaszokat a keret draw.cpp fájljában implementált a Bresenham algoritmus raszterizálja, a pixel műveleteket pedig a window.cpp fájlban valósítottuk meg.
 
 

3D grafikus rendszer inkrementális képszintézissel: 3d.exe

A programmal előállított képek:


Tömör megjelenítés

huzalváz megjelenítés
Ez az alkalmazás egy teljes 3D grafikus képszintézis rendszert mutat be, amely z-buffer takarási algoritmust és Gouraud-árnyalást alkalmaz.

A 3D.cpp fájl a virtuális világot és a kamerát összefogó színteret (Scene), a kimeneti csővezetéket működtető függvényt (Render), és a felhasználói interakció eljárásait adja meg. A virtuális világot a sphere fájlban építjük fel. 

A további fájlok:

  • 3d.h: 3D geometria. Ez a 3D euklideszi és projektív pont és a 3D homogén lineáris geometriai transzformációk definíciós fájlja.
  • world3.h: a 3D virtuális világ objektumtípusai. A fájl a 3D virtuális világ objektumait definiálja. A virtuális világ transzformálható objektumokból áll, amelyek primitívekből épülnek fel. Egy primitív képviselhet egy gömböt (Sphere), háromszögekkel közelített (PolyFace3D) felületet, törtvonalat (PolyLine3D) vagy különböző súlyfüggvényeket használó paraméteres görbéket (Curve3D).
  • world3.cpp: a 3D virtuális világ vektorizációja és tesszellációja. Itt adtuk meg a 3D virtuális világ objektumaihoz tartozó vektorizációs és tesszellációs algoritmusokat. A képszintézis első lépéseként az általános primitíveket pontokkal, szakaszokkal és háromszögekkel közelítjük. A szakaszokkal történő közelítést vektorizációnak, a háromszögekkel történő közelítést pedig tesszellációnak nevezzük. Görbéket nyilván csak vektorizálni lehet, a felületeket viszont tetszés szerint vektorizálhatjuk vagy tesszellálhatjuk. Az első esetben huzalváz megjelenítéshez, a másodikban pedig tömör megjelenítéshez jutunk.
  • camera3.h: 3D kamera deklarációja. A fájl a 3D virtuális világ leképzéséhez szükséges kamerát definiálja, amely a nézeti transzformáció előállításáért felelős.
  • camera3.cpp: 3D nézeti transzformáció előállítása. A fájlban 3D nézeti transzformációt kiszámító CalcTransf tagfüggvényt implementáltuk mind párhuzamos, mind pedig perspektív vetítés esetén.
  • pipe3.h: 3D kimeneti csővezeték objektumtípusai. A 3D kimeneti csővezetéken átvihető objektumokat a RenderPrimitive3D osztályból származtathatjuk. Az ilyen objektumok konkrét típusai a pont (Marker3D), a szakasz (Line3D), a szakaszlista (LineList3D) és a háromszöglista (TriangleList3D). Az objektumok pontjait (Transform) és normálvektorait (TransformNormals) transzformálhatjuk, és homogén osztással előállíthatjuk a transzformált pontok Descartes koordinátáit (HomDivPoints). A vágási műveleteket két lépésben hajthatjuk végre. A DepthClip homogén koordinátákban az első és hátsó vágósíkra vág, a Clip pedig Descartes koordinátákban nézet téglalapjára. Az Illuminate tagfüggvény a normálvektorok alapján az egyes pontokban látható radianciát számítja ki, a Draw pedig raszterizálja a primitíveket.
  • pipe3.cpp: a 3D csővezeték eljárásai. A 2D kimeneti csővezeték eljárásait találhatjuk itt meg, mint például a Cohen-Sutherland szakasz vágás homogén koordinátákra és 3D térre általánosított algoritmusát, és a brdf.h-ban megfogalmazott BRDF modellekre építő illuminációs algoritmust.
  • brdf.h: BRDF modellek. A felületek optikai tulajdonságait a BRDF modellekkel írjuk le. Egy felület lehet fénykibocsátó (Emitter) és a környezetéből ide érkező fényt is visszaverheti illetve törheti. Az visszaverődés lehet diffúz (DiffuseMaterial), spekuláris (SpecularMaterial) vagy ideális (IdealReflector). A fénytörésnél csak az ideális esetet modellezzük (IdealRefractor). Ebből az inkrementális képszintézisben a DiffuseSpecularMaterial osztályt használjuk. A brdf.h fájlban az SColor típus megadásánál két lehetőség közül választhatunk. Mivel a sugárkövető program mindenütt az SColor típust használja, a brdf.h-ban szereplő RGBCOL konstans értékével szabályozhatjuk, hogy a spektrumot csak a vörös, zöld és kék színek hullámhosszain számítjuk vagy több hullámhosszon követjük a fény terjedését a térben.
A kimeneti csővezeték végén megjelenő szakaszokat a keret draw.cpp fájljában implementált Bresenham algoritmus raszterizálja, a 3D háromszögeket (facet) pedig z-buffer takarási módszert és Gouraud árnyalási eljárást megvalósító függvény alakítja át pixelekké (PFacet). Ezen műveletek kódolása során a nagysebességű, célszerűen gépi kódú implementáció, illetve a hardver támogatás lehetőségének a bemutatása érdekében csakegész műveleteket használtunk.
 

Sugárkövetés: ray.exe

A programmal előállított képek:


lokális illumináció

lokális illumináció árnyékszámítással

rekurzív sugárkövetés

globális illumináció inverz fényútkövetéssel

Ez a példa több alapvető módszert demonstrál, a nem-rekurzív és a rekurzív sugárkövetést, a sugárkövetés kiegészítését a sztochasztikus mintavételezés és az utószűrés kombinálását alkalmazó csipkézettség csökkentéssel, és egy inverz fénykövetés elvű Monte-Carlo globális illuminációs algoritmust. A felületek optikai tulajdonságainál textúra leképzést is beállíthatunk. A sugárkövető algoritmusok a ray.cpp fájlban találhatók. A virtuális világot a tsphere fájlban építjük fel.

Az alkalmazás még az alábbi fájlokból építkezik: 

  • 3d.h: 3D geometria. Ez a 3D euklideszi és projektív pont és a 3D homogén lineáris geometriai transzformációk definíciós fájlja.
  • camera3.h: 3D kamera deklarációja. A fájl a 3D virtuális világ leképzéséhez szükséges kamerát definiálja, amely a nézeti transzformáció előállításáért felelős.
  • camera3.cpp: 3D nézeti transzformáció előállítása. A fájlban 3D nézeti transzformációt kiszámító CalcTransf tagfüggvényt implementáltuk mind párhuzamos, mind pedig perspektív vetítés esetén.
  • brdf.h: BRDF modellek. A felületek optikai tulajdonságait a BRDF modellekkel írjuk le. Egy felület lehet fénykibocsátó (Emitter) és a környezetéből ide érkező fényt is visszaverheti illetve törheti. Az visszaverődés lehet diffúz (DiffuseMaterial), spekuláris (SpecularMaterial) vagy ideális (IdealReflector). A fénytörésnél csak az ideális esetet modellezzük (IdealRefractor). Ebből az inkrementális képszintézisben a DiffuseSpecularMaterial osztályt használjuk, a sugárkövetés pedig mindet. A FresnelFunction fémekre a visszaverődési tényezőt számítja ki. A GeneralMaterial a különböző visszaverődési és törési típusokat egyesíti. Egy BRDF modellnek alapvetően két funkciója van. Egyrészt megmondja, hogy adott megvilágítás és nézőpont esetén milyen intenzitású fényt kap a megfigyelő. Másrészt, egy belépő irány birtokában a BRDF és a kilépő szög koszinuszának szorzatának arányában egy véletlen kilépő irányt generál. Ebből a két funkcióból az elsőre minden algoritmusnak szüksége van, a másodikat viszont csak a Monte-Carlo módszerek használják. A brdf.h fájlban az SColor típus megadásánál két lehetőség közül választhatunk. Mivel a sugárkövető program mindenütt az SColor típust használja, a brdf.h-ban szereplő RGBCOL konstans értékével szabályozhatjuk, hogy a spektrumot csak a vörös, zöld és kék színek hullámhosszain számítjuk vagy több hullámhosszon követjük a fény terjedését a térben.
  • brdf.cpp: fémek törésmutatói. A fájlban a fémekhez szükséges törésmutató táblázatokat találhatjuk meg, amelyeket a Fresnel együtthatók számításához használunk. Itt definiáljuk az alacsony diszkrepanciájú sorozatot jelképező objektum egy példányát is.
  • uniform.h: véletlen és alacsony-diszkrepanciájú sorozatok.

 

Térfogat-vizualizáció masírozó kockák algoritmussal: march.exe

Figyelem: ha a program az indítása után csak egy fekete hátteret hajlandó rajzolni, akkor nem
találta meg a voxeltömb fájlt (head64.vox).  Ekkor állítsa az internet böngésző "kezdet" tulajdonságát a CD gyökerére! Ez úgy ellenőrizhető, hogy a fájl megnyitás a gyökérkönyvtárból indul.

A programmal előállított képek:


head128.vox fájl megjelenítése 
110-es szintértékkel

head128.vox fájl megjelenítése 
60-as szintértékkel

Ez az alkalmazás egy voxeltömböt tölt be a parancssor argumentumával megnevezett fájlból, majd az interaktívan változtatható érték felhasználásával a masírozó kockák algoritmussal szintfelületet generál, amit az inkrementális 3D képszintézis rendszer kimeneti csővezetékén jelenít meg. A térfogatmodellt leíró fájl bináris. A fájl egy egész számmal kezdődik, amely meghatározza a voxeltömb felbontását. A méret mezőt követő bájtsorozat pedig az egyes voxelek sűrűségértékeit adja meg. Ha például az első szóban 128-t találunk, a fájl még ezen kívül 128 x 128 x 128 bájtot tartalmaz.
A CD-n jelenleg ugyanazon modell három különböző felbontású változata található:

  • head32.vox: 32x32x32-es fej
  • head64.vox: 64x64x64-es fej
  • head128.vox: 128x128x128-as fej
A masírozó kockák algoritmus és a kezelői felület a march.cpp fájlban található. Az algoritmus a polytab.h-ban lévő konfiguációk alapján ismeri fel a lehetséges felület-voxel metszési típusokat.

Az alkalmazás ezen kívül felhasználja az általános keretrendszert és a következő fájlokat:

  • 3d.h: 3D geometria. Ez a 3D euklideszi és projektív pont és a 3D homogén lineáris geometriai transzformációk definíciós fájlja.
  • camera3.h: 3D kamera deklarációja. A fájl a 3D virtuális világ leképzéséhez szükséges kamerát definiálja, amely a nézeti transzformáció előállításáért felelős.
  • camera3.cpp: 3D nézeti transzformáció előállítása. A fájlban 3D nézeti transzformációt kiszámító CalcTransf tagfüggvényt implementáltuk mind párhuzamos, mind pedig perspektív vetítés esetén.
  • pipe3.h: 3D kimeneti csővezeték objektumtípusai. A 3D kimeneti csővezetéken átvihető objektumokat a RenderPrimitive3D osztályból származtathatjuk. Az ilyen objektumok konkrét típusai a pont (Marker3D), a szakasz (Line3D), a szakaszlista (LineList3D) és a háromszöglista (TriangleList3D). Az objektumok pontjait (Transform) és normálvektorait (TransformNormals) transzformálhatjuk, és homogén osztással előállíthatjuk a transzformált pontok Descartes koordinátáit (HomDivPoints). A vágási műveleteket két lépésben hajthatjuk végre. A DepthClip homogén koordinátákban az első és hátsó vágósíkra vág, a Clip pedig Descartes koordinátákban nézet téglalapjára. Az Illuminate tagfüggvény a normálvektorok alapján az egyes pontokban látható radianciát számítja ki, a Draw pedig raszterizálja a primitíveket.
  • pipe3.cpp: a 3D csővezeték eljárásai. A 2D kimeneti csővezeték eljárásait találhatjuk itt meg, mint például a Cohen-Sutherland szakasz vágás homogén koordinátákra és 3D térre általánosított algoritmusát, és a brdf.h-ban megfogalmazott BRDF modellekre építő illuminációs algoritmust.
  • brdf.h: BRDF modellek. A felületek optikai tulajdonságait a BRDF modellekkel írjuk le. Egy felület lehet fénykibocsátó (Emitter) és a környezetéből ide érkező fényt is visszaverheti illetve törheti. Az visszaverődés lehet diffúz (DiffuseMaterial), spekuláris (SpecularMaterial) vagy ideális (IdealReflector). A fénytörésnél csak az ideális esetet modellezzük (IdealRefractor). Ebből az inkrementális képszintézisben a DiffuseSpecularMaterial osztályt használjuk.

IFS megjelenítő: ifs.exe

Figyelem: ha a program az indítása után csak egy fekete hátteret hajlandó rajzolni, akkor nem
találta meg az IFS definíciós fájlt (ifscode).  Ekkor állítsa az internet böngésző "kezdet" tulajdonságát a CD gyökerére! Ez úgy ellenőrizhető, hogy a fájl megnyitás a gyökérkönyvtárból indul.

A programmal előállított képek:


  • pafrany2 képe

    sierpien: 2D Sierpienski halmaz képe

    Ez az alkalmazás az ifscode fájlból illetve a parancssorban megadott nevű fájlból egy IFS-t olvas be és azt véletlen bolyongással megjeleníti. 
    Egy IFS fálj szerkezete (a kulcsszavakat kiemeltük):

    v ablak_bal ablak_alsó ablak_jobb ablak_felső    // az ablak paraméterei
    w a1 b1 c1 d1 px1 py1                                          // az első affin leképzés
    p valószínűség1                                                     // az első leképzés valószínűsége 
    w a2 b2 c2 d2 px2 py2                                   // az második affin leképzés
    p valószínűség2                                             // az második leképzés valószínűsége 
    ... 
    A CD-n jelenleg a következő IFS fájlok találhatók:
    • ifscode vagy pafrany1: egy kevésbé hajlott páfrány
    • pafrany2: elősen hajlott páfrány
    • sierpien: 2D Sierpienski halmaz
    Az IFS megjelenítő és a kezelői felület az ifs.cpp fájlban található. Az alkalmazás ezen kívül az alábbi fájlokat használja fel:
    • 2d.h: 2D geometria. Itt írtuk le az euklideszi pont (Point2D), a projektív pont (HomPoint2D), a téglalap (RectAngle), és a geometriai transzformációk (Transform2D) osztályait.
    • camera2.h: 2D kamera. Az ablakból és a nézetből álló 2D kameraosztályt találhatjuk meg itt, amely a 2D nézeti transzformáció előállításáért felelős.

    [Vissza a CD főoldalra]