Programujeme grafický engine VII.

opengl_logo.jpg Tú­to časť se­riá­lu ve­nu­je­me im­ple­men­tá­cii de­tek­cie ko­lí­zií a ob­jek­tu ob­lo­hy do prip­ra­vo­va­nej ap­li­ká­cie En­gi­ne. Po­drob­ne opí­še­me všet­ky up­ra­ve­né sú­bo­ry so zdro­jo­vým kó­dom. Za­me­ria­me sa na opis ob­jek­tu ob­lo­hy, kto­rý dot­vá­ra reál­ny do­jem zo scé­ny vy­tvo­re­nej po­čí­ta­čom.

De­tek­cia ko­lí­zií
De­tek­cia ko­lí­zií je v ap­li­ká­cii En­gi­ne za­ra­de­ná med­zi fun­kcie mo­du­lu Ava­tar. Ide o jed­no­duc­hú fun­kciu: bool de­tect_colli­sion(); v kto­rej sa vy­ko­na­jú všet­ky po­treb­né čin­nos­ti. Uve­de­ná fun­kcia je vy­vo­la­ná vždy, keď po­zo­ro­va­teľ zme­ní svo­ju po­lo­hu v rám­ci scé­ny. Jej vy­ko­na­nie je za­bez­pe­če­né v rám­ci mo­du­lu Inter­fa­ce a je­ho fun­kcie: int ogl_Draw();

Prv ako sa vy­ko­ná de­tek­cia ko­lí­zií, spo­mí­na­ná fun­kcia pre­vez­me prís­luš­né od­ka­zy na ko­líz­ne tro­ju­hol­ní­ky:

col_tri=T->col_tri;
col_tri_num=T->col_tri_num;

De­tek­cia ko­lí­zií sa vy­ko­ná so všet­ký­mi tro­ju­hol­ník­mi, na kto­ré exis­tu­jú od­ka­zy v po­li od­ka­zov na ko­líz­ne tro­ju­hol­ní­ky. Po­drob­ný po­stup vy­ko­na­nia de­tek­cie ko­lí­zií je nas­le­du­jú­ci:
1. Pre všet­ky tro­ju­hol­ní­ky, na kto­ré exis­tu­jú od­ka­zy ulo­že­né v po­li od­ka­zov na ko­líz­ne tro­ju­hol­ní­ky, sa vy­ko­ná test ko­lí­zie tro­ju­hol­ní­ka s gu­ľou, kto­rá ob­klo­pu­je po­sta­vu Ava­ta­ra (Sphe­reIn­Triang­le();). V tej­to ver­zii ap­li­ká­cie je ho­ri­zon­tál­ny aj ver­ti­kál­ny roz­mer gu­le to­tož­ný, tak­že test po­dstú­pi jed­no­duc­há rov­no­mer­ná gu­ľa s ro­vi­nou, kto­rú tvo­rí da­ný tro­ju­hol­ník. Stred gu­le je pred­sta­vo­va­ný po­lo­hou Ava­ta­ra, po­lo­mer gu­le je šír­kou Ava­ta­ra. Tro­ju­hol­ník tvo­rí ro­vin­nú ploc­hu, kto­rej všeo­bec­ná rov­ni­ca je zos­ta­ve­ná z nor­má­ly da­né­ho tro­ju­hol­ní­ka a vop­red vy­po­čí­ta­né­ho pa­ra­met­ra D (po­uži­je sa rov­ni­ca ro­vi­ny Ax+By+Cz+D=0).
2. V prí­pa­de, že nas­ta­la ko­lí­zia gu­le s ro­vi­nou tvo­re­nou da­ným tro­ju­hol­ní­kom, vznik­ne je­di­neč­ný prie­seč­ník gu­le s tou­to ro­vi­nou (ipoint). Po­lo­ha prie­seč­ní­ka je dô­le­ži­tá, pre­to­že iba v prí­pa­de, že prie­seč­ník le­ží vnút­ri tro­ju­hol­ní­ka, nas­ta­la ko­lí­zia (Po­in­tIn­Triang­le();). V prí­pa­de ko­lí­zie dôj­de k po­su­nu Ava­ta­ra na no­vú po­zí­ciu, kto­rá sa vy­po­čí­ta s vy­uži­tím nor­má­lo­vé­ho vek­to­ra ro­vi­ny (tro­ju­hol­ní­ka). Tým sa do­siah­ne efekt kĺza­nia sa Ava­ta­ra po ko­líz­nom tro­ju­hol­ní­ku. V oso­bit­nom prí­pa­de, keď Ava­tar „na­ra­zí“ na po­dla­hu, dôj­de k po­su­nu po osi Y, no nie po osiach X a Z. Do­siah­ne­me tak efekt, pri kto­rom sa Ava­tar ne­bu­de kĺzať po šik­mých plo­chách. Ten­to efekt zdo­ko­na­lí­me v niek­to­rej z bu­dú­cich ver­zií ap­li­ká­cie. Do­siah­ne­me tak zvý­še­nie reál­ne­ho doj­mu pri po­hy­be Ava­ta­ra, pre­to­že ten sa bu­de v ur­či­tých prí­pa­doch kĺzať po dos­ta­toč­ne šik­mých plo­chách.
3. Ak prie­seč­ník ne­pat­rí tro­ju­hol­ní­ku, ale Ava­tar sa nap­riek to­mu prib­lí­žil k ro­vi­ne tvo­re­nej tro­ju­hol­ní­kom, tre­ba otes­to­vať po­lo­hu toh­to prie­seč­ní­ka vzhľa­dom na hra­ny tro­ju­hol­ní­ka (Sphe­reI­nEd­ge();). Mô­že sa to­tiž stať, že ho­ci sa Ava­tar nac­hád­za mi­mo tro­ju­hol­ní­ka, stá­le mô­že byť dos­ta­toč­ne blíz­ko k je­ho hra­nám. Ke­by sme neo­tes­to­va­li ko­lí­ziu Ava­ta­ra s hra­na­mi ko­líz­ne­ho tro­ju­hol­ní­ka, Ava­tar by sa mo­hol nac­hád­zať v ko­lí­zii, kto­rá by však ne­bo­la správ­ne de­te­go­va­ná.
4. v prí­pa­de de­tek­cie ko­lí­zie je po­zas­ta­ve­né pô­so­be­nie gra­vi­tá­cie, tak­že ak Ava­tar do­pad­ne na po­dla­hu, resp. ko­li­du­je s ako­koľ­vek umies­tne­ným tro­ju­hol­ní­kom, je­ho pád sa za­sta­ví. V tom­to mo­men­te za­čne na Ava­ta­ra pô­so­biť gra­vi­tá­cia s nu­lo­vým ča­som pô­so­be­nia, a po­kiaľ je to mož­né, Ava­tar za­čne vy­ko­ná­vať no­vý pád. V prí­pa­de, že Ava­tar do­pa­dol na po­dla­hu, je­ho ďal­ší pád je za­sta­ve­ný.

Ma­te­ma­ti­ka de­tek­cie ko­lí­zií
De­tek­cia ko­lí­zií je za­lo­že­ná na jed­no­du­chých ma­te­ma­tic­kých vzťa­hoch. Všet­ky po­treb­né úda­je vkla­da­né do týc­hto vzťa­hov sú vy­po­čí­ta­né pri vkla­da­ní no­vé­ho tro­ju­hol­ní­ka do zoz­na­mu tro­ju­hol­ní­kov. Med­zi naj­dô­le­ži­tej­šie úda­je pat­rí:
 nor­má­la tro­ju­hol­ní­ka + pa­ra­me­ter D rov­ni­ce ro­vi­ny, kto­rú tvo­rí tro­ju­hol­ník – po­uží­va sa na vý­po­čet vzdia­le­nos­ti Ava­ta­ra od ro­vi­ny, kto­rú tvo­rí tro­ju­hol­ník,
 ko­líz­ne nor­mál­ny pre všet­ky tri stra­ny tro­ju­hol­ní­ka – po­uží­va­jú sa na ur­če­nie po­lo­hy prie­seč­ní­ka k tro­ju­hol­ní­ku,
 mi­ni­mál­ne a maximál­ne sú­rad­ni­ce vr­cho­lov na da­ných osiach – po­uží­va­jú sa na ur­če­nie, či je da­ný tro­ju­hol­ník vi­di­teľ­ný, ale­bo nie.

Fun­kcia Sphe­reIn­Triang­le();
Vzdia­le­nosť bo­du od ro­vi­ny je jed­no­duc­hý ma­te­ma­tic­ký vzťah, po­uží­va­ný na ur­če­nie po­lo­hy Ava­ta­ra k ro­vi­ne tvo­re­nej tro­ju­hol­ní­kom:

d=myAbs(T.x*C.x+T.y*C.y+T.z*C.z+T.w); 

V prí­pa­de, že sa Ava­tar nac­hád­za v blíz­kos­ti ro­vi­ny, dôj­de k „pro­jek­cii“ stre­du gu­le do ro­vi­ny:

ipoint.x=C.x-(T.x*d);
ipoint.y=C.y-(T.y*d);
ipoint.z=C.z-(T.z*d);

Fun­kcia Po­in­tIn­Triang­le();
Ur­če­nie po­lo­hy prie­seč­ní­ka vzhľa­dom na tro­ju­hol­ník sa reali­zu­je na zá­kla­de rov­níc ro­vín tvo­re­ných ste­na­mi tro­ju­hol­ní­ka. V prí­pa­de, že sa prie­seč­ník nac­hád­za as­poň za jed­nou z týc­hto stien, ne­pat­rí tro­ju­hol­ní­ku.

Fun­kcia Sphe­reI­nEd­ge();
Sta­no­ve­nie po­lo­hy gu­le vzhľa­dom na hra­nu ko­líz­ne­ho tro­ju­hol­ní­ka pre­bie­ha v dvoch kro­koch:
1. na zá­kla­de po­lo­hy stre­du gu­le k hra­ne tro­ju­hol­ní­ka sa vy­po­čí­ta po­lo­ha prie­seč­ní­ka le­žia­ce­ho na tej­to hra­ne (Po­in­tOn­Li­ne();),
2. v prí­pa­de, že je vzdia­le­nosť stre­du gu­le a prie­seč­ní­ka men­šia ako po­lo­mer gu­le (šír­ka Ava­ta­ra), doš­lo ku ko­lí­zii (Dis­tan­ce();).

Ob­lo­ha
V ap­li­ká­cii En­gi­ne je im­ple­men­to­va­ný po­mer­ne zlo­ži­tý efekt za­far­be­nia ob­lo­hy v zá­vis­los­ti od po­lo­hy sl­nka. Ta­kis­to je v nej im­ple­men­to­va­ná ob­lo­ha s po­hyb­li­vý­mi ob­lak­mi. Všet­ky tie­to ob­jek­ty sú vy­tvá­ra­né v trie­de mSky­do­me. Po­treb­né dek­la­rá­cie a de­fi­ní­cie sú umies­tne­né v sú­bo­re mSky­do­me.cpp (mSky­do­me.h).

VBO (Ver­tex Buf­fer Ob­jects)
Na vy­tvo­re­nie ob­jek­tu ob­lo­hy bo­lo po­uži­té roz­ší­re­nie ARB_ver­tex_buf­fer_ob­ject. To­to roz­ší­re­nie vy­chád­za z tzv. po­lí vr­cho­lov (ver­tex arrays), o kto­rých sme sa už zmie­ni­li. Zdo­ko­na­ľu­je do­kon­ca po­uži­tie tzv. pred­kom­pi­lo­va­ných po­lí vr­cho­lov, a to naj­mä v sú­vis­los­ti s po­treb­ný­mi pa­mä­ťo­vý­mi ope­rá­cia­mi. Úda­je kla­sic­kých po­lí vr­cho­lov sa to­tiž uk­la­da­jú do hlav­nej pa­mä­te po­čí­ta­ča. V prí­pa­de po­uži­tia týc­hto úda­jov dôj­de k ich pre­su­nu ces­tou gra­fic­kej zber­ni­ce (AGP, PCX) do pa­mä­te gra­fic­kej kar­ty. Ten­to pro­ces sí­ce nie je pri vý­ko­ne dneš­né­ho har­dvé­ru kri­tic­ký, no stá­le ide o ur­či­té zdr­ža­nie pro­ce­su vy­kres­le­nia gra­fic­kej scé­ny. Roz­ší­re­nie VBO rie­ši uve­de­ný prob­lém ulo­že­ním po­treb­ných úda­jov do lo­kál­nej pa­mä­te gra­fic­kej kar­ty. Ide naj­mä o ulo­že­nie ta­kých úda­jov, kto­ré sa po­uží­va­jú frek­ven­to­va­ne, čas­to v kaž­dej vy­kres­le­nej sním­ke. Ta­ký­to prís­tup ne­bol v mi­nu­los­ti mož­ný, pre­to­že gra­fic­ké kar­ty ne­dis­po­no­va­li po­treb­nou veľ­kos­ťou gra­fic­kej pa­mä­te. Mo­der­né kar­ty však ob­sa­hu­jú dos­ta­tok lo­kál­nej pa­mä­te nie­len na ulo­že­nie vý­sled­nej scé­ny (fra­me­buf­fer), textúr, ale aj na ulo­že­nie ďal­ších úda­jov.

Po­uži­tie VBO
Prak­tic­ké po­uži­tie VBO mož­no vi­dieť v prí­pa­de ob­jek­tu ob­lo­hy, kon­krét­ne v sú­bo­re mSky­do­me.cpp a je­ho fun­kcii Up­da­te(). Ide o nas­le­du­jú­ci blok:

// prip­ra­va VBO ob­jek­tu
gl­Gen­Buf­fers(1,&VBO­buf­fer); // po­le vr­cho­lov a fa­rieb
gl­Bin­dBuf­fer(GL_ARRAY_BUF­FER,VBO­buf­fer);
gl­Buf­fer­Da­ta(GL_ARRAY_BUF­FER,3*Num­Ver­ti­ces*si­zeof(float)+
                             4*Num­Ver­ti­ces*si­zeof(float),NULL,GL_STA­TIC_DRAW);
gl­Buf­fer­Sub­Da­ta(GL_ARRAY_BUF­FER,0,3*Num­Ver­ti­ces*si­zeof(float),VB);
gl­Buf­fer­Sub­Da­ta(GL_ARRAY_BUF­FER,3*Num­Ver­ti­ces*si­zeof(float),
                                4*Num­Ver­ti­ces*si­zeof(float),CB);
gl­Gen­Buf­fers(1,&VBOi_buf­fer); // po­le in­dexov
gl­Bin­dBuf­fer(GL_ELE­MENT_ARRAY_BUF­FER,VBOi_buf­fer);
gl­Buf­fer­Da­ta(GL_ELE­MENT_ARRAY_BUF­FER,Nu­mIn­di­ces*si­zeof(un­sig­ned int),
                                     IB,GL_STA­TIC_DRAW);

Na za­čiat­ku prá­ce s VBO tre­ba po­dob­ne ako pri prá­ci s textú­ra­mi vy­tvo­riť tzv. OpenGL ob­jekt. Nás­led­ne je po­treb­né ten­to ob­jekt aso­cio­vať s bež­iacim stro­jom OpenGL, čím sa sta­ne ak­tív­nym. Nas­le­du­je umies­tne­nie úda­jov do vy­tvo­re­né­ho ob­jek­tu a ur­če­nie cha­rak­te­ru týc­hto úda­jov. Naj­čas­tej­šie po­uží­va­ným pa­ra­met­rom po­uži­tia ulo­že­ných úda­jov je GL_STA­TIC_DRAW, kto­rý ho­vo­rí o tom, že úda­je ulo­že­né vo VBO bu­dú za­de­fi­no­va­né raz, no bu­dú sa po­uží­vať po­mer­ne čas­to (pri vy­kres­le­ní kaž­dej jed­not­li­vej sním­ky). Na tom­to mies­te sa VBO ne­bu­de­me ve­no­vať po­drob­nej­šie. Všet­ky po­treb­né in­for­má­cie mož­no ke­dy­koľ­vek zís­kať z do­ku­men­tá­cie k OpenGL, resp. z ma­nuá­lov kon­krét­nej gra­fic­kej kar­ty. V ďal­šom texte sa za­me­ria­me na čo naj­pod­rob­nej­ší opis ob­jek­tu ob­lo­hy a ob­la­kov.

Ob­jekt ob­lo­hy
Ob­jekt ob­lo­hy je tvo­re­ný po­lo­gu­ľou (obr. 1), kto­rá je rep­re­zen­to­va­ná 3D sie­ťo­vým mo­de­lom. Vr­cho­ly a far­by v jed­not­li­vých vr­choloch sú ulo­že­né v ob­jek­te VBO. Vo fun­kcii Ini­tia­li­ze() je umies­tne­ný blok, v kto­rom sa na zá­kla­de jed­no­du­chých ma­te­ma­tic­kých vzťa­hov vy­po­čí­ta­jú sú­rad­ni­ce jed­not­li­vých vr­cho­lov, z kto­rých je zlo­že­ný 3D sie­ťo­vý mo­del. Po­tom sa prip­ra­via in­dexy na tie­to vr­cho­ly, kto­ré bu­dú nes­kôr pre­su­nu­té do po­ľa in­dexov vo VBO. Pro­ces ďa­lej po­kra­ču­je na­čí­ta­ním textúr pre ob­jekt pred­sta­vu­jú­ci sl­nko, me­siac a ob­la­ky. De­fi­ní­cia ob­jek­tov sa kon­čí príp­ra­vou hviezd a vy­tvo­re­ním ob­jek­tu ob­la­kov.

Ob­jekt ob­la­kov pred­sta­vu­je za­kri­ve­ná štvo­ru­hol­ní­ko­vá ploc­ha. Tá je po­dob­ná tej, kto­rá pred­sta­vu­je ob­jekt ob­lo­hy, no je špe­ci­fic­ká tým, že sie­ťo­vý mo­del nie je vy­tvo­re­ný na zá­kla­de go­nio­met­ric­kých fun­kcií sin a cos, ale na zá­kla­de jed­no­duc­hé­ho kvad­ra­tic­ké­ho vzťa­hu. Ob­jekt ob­la­kov je umies­tne­ný „pred“ ob­jekt ob­lo­hy, tak­že po sprieh­ľad­ne­ní tých je­ho čas­tí, kto­ré pred­sta­vu­jú ob­la­ky, sa pre po­zo­ro­va­te­ľa na­vod­zu­je do­jem, že ide o je­di­ný ob­jekt. Roz­diel v umies­tne­ní ob­jek­tu ob­lo­hy a ob­jek­tu ob­la­kov je vi­di­teľ­ný na obr. 1.

engine obr1.bmp
Obr. 1 Ob­jekt ob­lo­hy a ob­jekt ob­la­kov

Na vy­kres­le­nie ob­jek­tu ob­la­kov bol po­uži­tý jed­no­duc­hý Dis­playList, kto­rým sme sa za­obe­ra­li už v pre­doš­lom se­riá­li. Jed­not­li­vé prí­ka­zy OpenGL sa vop­red prip­ra­via, ulo­žia do Dis­playLis­tu a nás­led­ne sa vy­ko­ná­va­jú vo svo­jom pre­kom­pi­lo­va­nom sta­ve. Ten­to prís­tup je veľ­mi po­dob­ný po­uži­tiu VBO, nes­mie­me však za­bud­núť, že v ta­kom­to prí­pa­de sa úda­je neuk­la­da­jú do lo­kál­nej pa­mä­te gra­fic­kej kar­ty, ale do bež­nej pa­mä­te po­čí­ta­ča.

Na vý­po­čet far­by ob­lo­hy bo­li po­uži­té po­mer­ne zlo­ži­té ma­te­ma­tic­ko-fy­zi­kál­ne vzťa­hy, po­mo­cou kto­rých sa fa­reb­ný od­tieň v kon­krét­nom mies­te ob­lo­hy vy­po­čí­ta­va na zá­kla­de po­lo­hy sl­nka. K to­mu som do ad­re­sá­ra doc umies­tnil nie­koľ­ko do­ku­men­tov za­obe­ra­jú­cich sa si­mu­lá­ciou fa­rieb ob­lo­hy na zá­kla­de rôz­nych vý­poč­to­vých me­tód. Prak­tic­kou ap­li­ká­ciou vy­bra­nej me­tó­dy vý­poč­tu fa­reb­ných od­tie­ňov vznik­la fun­kcia Get­Vetr­texCo­lor(), kto­rá nás­led­ne po­uží­va ďal­šie fun­kcie, de­fi­no­va­né na za­čiat­ku sú­bo­ru mSky­do­me.cpp. Ide naj­mä o fun­kcie Se­tIn­fo() a tzv. Pe­rez fun­kcie.

Vy­bra­ným vý­poč­to­vým pro­ce­som do­ká­že­me si­mu­lo­vať množ­stvo po­mer­ne realis­tic­ky vy­ze­ra­jú­cich efek­tov, ako je napr. po­hyb sl­nka po ob­lo­he, zá­pad sl­nka vrá­ta­ne zob­ra­ze­nia me­sia­ca a hviezd. Ta­kis­to mož­no si­mu­lo­vať den­nú do­bu, rôz­ne za­far­be­nie ob­lo­hy, dá sa me­niť in­ten­zits sl­neč­né­ho žia­re­nia a do­kon­ca mož­no na­si­mu­lo­vať vzhľad ob­lo­hy v prie­be­hu 24 ho­dín a 365 dní v ro­ku.

Ta­ký­to zlo­ži­tý vý­poč­to­vý pro­ces sme však z dô­vo­du urýc­hle­nia ap­li­ká­cie up­ra­vi­li tak, aby ne­doc­hád­za­lo k nad­by­toč­ným vý­poč­tom. V prí­pa­de sna­hy o expe­ri­men­to­va­nie však vre­lo od­po­rú­čam vy­užiť všet­ky mož­nos­ti fun­kcie Up­da­te(), kto­rej úp­ra­vou do­ká­že­me si­mu­lo­vať všet­ky spo­mí­na­né uda­los­ti.

engine obr2.bmp
Obr. 2 Gra­fic­ký vý­stup ap­li­ká­cie En­gi­ne v1.1

Na­bu­dú­ce...
V ďal­šej čas­ti se­riá­lu bu­de­me po­kra­čo­vať v zdo­ko­na­ľo­va­ní ap­li­ká­cie En­gi­ne v1.1. Vy­tvo­re­nú scé­nu dopl­ní­me o te­rén­ne ob­jek­ty a na­ďa­lej bu­de­me po­kra­čo­vať v zdo­ko­na­ľo­va­ní gra­fic­kéh

Ďal­šie čas­ti >>

Zdroj: Infoware 5/2008



Ohodnoťte článok:
   
 

24 hodín

týždeň

mesiac

Najnovšie články

Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXVII.
V tejto a takisto v nasledujúcej časti seriálu budeme riešiť synchronizáciu streľby s pohybom postavy. Pôvodne sme sa tejto oblasti venovali oddelene od blokov súvisiacich so zobrazením postavy. čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXVI.
V tejto časti seriálu sa budeme venovať tomu, ako možno do grafických (herných) enginov implementovať objekty reprezentujúce rebríky (ladders). čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXV.
V tejto časti seriálu podrobnejšie rozoberieme jednotlivé časti programového kódu súvisiace s implementáciou streľby. čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXIV.
V tejto časti seriálu vám v stručnosti predstavíme tzv. systémy častíc (particle systems). Kvalitne navrhnutými systémami častíc dokážeme veľmi rýchlo a elegantne zvýšiť dynamiku grafických aplikácií. čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXIII.
V predchádzajúcej časti seriálu sme dokončili kapitolu, v ktorej sme sa venovali simulácii fyziky. čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXII.
Touto časťou seriálu ukončíme tému implementácie fyzikálnych zákonov v rámci grafických enginov. Všetky vedomosti, ktorými v tomto okamihu disponujeme čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXXI.
Týmto článkom sa pomaly dostávame k záveru celku, v ktorom sme sa zaoberali simuláciou fyziky. Zostáva nám opísať princíp detekcie kolízií a uviesť spôsob reakcie simulačného systému čítať »
 
Prog­ra­mu­je­me gra­fic­ký en­gi­ne XXX.
V tomto pokračovaní seriálu si doplníme teoretické vedomosti potrebné na implementáciu fyzikálnych zákonov v grafických a herných enginoch. čítať »
 
 
 
  Zdieľaj cez Facebook Zdieľaj cez Google+ Zdieľaj cez Twitter Zdieľaj cez LinkedIn Správy z RSS Správy na smartfóne Správy cez newsletter