opengl es: 3d fraktali -...

63
SVEUČILIŠTE U ZAGREBU FAKULTET ORGANIZACIJE I INFORMATIKE VARAŽDIN Gabrijel Bartošek Samuel Picek OPENGL ES: 3D FRAKTALI SEMINARSKI RAD IZ KOLEGIJA RAČUNALNA GRAFIKA Varaždin, 2015.

Upload: phamquynh

Post on 06-Feb-2018

223 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

SVEUČILIŠTE U ZAGREBU

FAKULTET ORGANIZACIJE I INFORMATIKE

VARAŽDIN

Gabrijel Bartošek

Samuel Picek

OPENGL ES: 3D FRAKTALI

SEMINARSKI RAD IZ KOLEGIJA RAČUNALNA GRAFIKA

Varaždin, 2015.

Page 2: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

SVEUČILIŠTE U ZAGREBU

FAKULTET ORGANIZACIJE I INFORMATIKE

VARAŽDIN

Gabrijel Bartošek, 42642/13-R

Samuel Picek, 42632/13-R

OPENGL ES: 3D FRAKTALI

SEMINARSKI RAD IZ KOLEGIJA RAČUNALNA GRAFIKA

Mentor:

Doc. dr. sc. Ivan Hip

Prof. Damir Horvat

Varaždin, siječanj 2015.

Page 3: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

I

Sadržaj 1.Uvod ........................................................................................................................................ 1

2.Povijest fraktala ....................................................................................................................... 2

3.Definicija fraktala .................................................................................................................... 4

3.1.Podjela fraktala ................................................................................................................. 5

3.2.Primjena fraktala ............................................................................................................ 12

3.3.Fraktalna dimenzija ........................................................................................................ 14

4.Prikaz grafike s OpenGL ES ................................................................................................. 17

4.1.Izgradnja OpenGL ES okruženja ................................................................................... 17

4.1.1.Deklariranje OpenGL koristeći Manifest ................................................................ 17

4.1.2.Kreiranje aktivnosti za OpenGL ES grafiku ........................................................... 18

4.1.3.Gradnja GLSSurfaceView objekata ........................................................................ 18

4.1.4.Gradnja Renderer klase (klasa prikazivanja) .......................................................... 20

4.2.Definiranje oblika ........................................................................................................... 21

4.2.1.Primjer definiranja trokuta ...................................................................................... 21

4.2.2.Primjer definiranja kvadrata .................................................................................... 22

4.3.Crtanje oblika ................................................................................................................. 24

4.3.1.Inicijalizacija oblika ................................................................................................ 24

4.3.2.Crtanje oblika .......................................................................................................... 25

4.4.Primjena projekcije i pogled kamere .............................................................................. 26

4.4.1. Definiranje projekcije ............................................................................................. 27

4.4.2. Definiranje pogleda kamere ................................................................................... 27

4.5. Dodavanje pokreta ......................................................................................................... 28

4.5.1.Rotiranje oblika ....................................................................................................... 28

4.5.2. Omogućavanje kontinuiranog prikazivanja (renderiranja)..................................... 29

5. Prikaz grafike s OpenGL ES iz Processinga 2.0 .................................................................. 30

5.1. Geometrijske transformacije ......................................................................................... 31

5.1.1. Translacija .............................................................................................................. 32

5.1.2. Rotacija ................................................................................................................... 33

5.1.3. Skaliranje ................................................................................................................ 35

5.2. Kamera i perspektiva ..................................................................................................... 36

5.3. Stvaranje 3D objekata ................................................................................................... 39

5.3.1. Teksture .................................................................................................................. 41

5.3.2. Svijetlo ................................................................................................................... 43

6. Kochova pahulja u 3D .......................................................................................................... 46

6.1. Analiza izvornog koda................................................................................................... 48

Page 4: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

II

6.2. Analiza različitih dubina rekurzije ................................................................................ 53

7. Zaključak .............................................................................................................................. 57

Literatura .................................................................................................................................. 58

Page 5: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

1

1.Uvod

Jedno od zanimljivijih područja računalne grafike zauzimaju matematičke umotvorine,

tj. fraktali. Cijeli svijet oko nas, te unutar nas zapravo je i sačinjen od nekakvoga vida

fraktala, a mogli bi slobodno reći da je i metodika našeg razmišljanja fraktalna.

U davnoj prošlosti matematika je bila pretežito orijentirana na skupove i funkcije nad kojima

su se pretežito primjenjivale metode klasičnog diferencijalnog računa. Skupovi funkcija koji

nisu bili dovoljno glatki ili regularni, pretežito su se ignorirali. U posljednjim desetljećima

ovakav se način razmišljanja uvelike promijenio.

Fraktali su čudesni geometrijski oblici koji se sastoje od umanjenih verzija samih sebe

(svaki dio je umanjena kopija cjeline). Nalazimo ih posvuda oko nas, te ih vidimo svaku dan,

mada ih ne primjemjećujemo. Možemo ih zapaziti na običnoj brokuli, cvjetači, ali isto tako u

planinskim lancima, te deltama rijeka. No međutim osim onih u prirodi, mi ćemo se u

seminarskom radu fokusirati na one fraktale koje stvara čovjek, kako bi se umjetnički i

vizualno posebno izrazio.

Prvenstveno fraktalna umjetnost je ona umjetnost koja nastaje uz pomoć računala i

matematike. Fraktalna geometrija nam daje generalni okvir gdje se proučavaju iregularni

skupovi. Premda dosta često u današnjici čujemo riječ fraktali, velika većina neće razumjeti

što oni točno predstavljaju i što znače. Bilo je mnogo pokušaja da se fraktali definiraju u čisto

matematičkom smislu, no te definicije često su se ispostavile neispravnima u općem smislu

značenja. Međutim, fraktalna geometrija daje podosta tehnika za upravljanje fraktalima.

Page 6: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

2

2.Povijest fraktala

Kao što smo u uvodu naveli, fraktali koje stvara čovjek nastaju pomoću računala i

matematike. Računala danas pronalaze mnogobrojne primjene povezujući grafiku i

matematiku u pogledu umjetnosti, npr. digitalno obrađene fotografije i dizajn. S prvom

pojavom računala, umjetnici su se zapitkivali na koji način bi mogli iskoristiti taj novitet u

svom području, tj. za izradu svojih radova.

Računala koja su prva našla svoju primjenu u aspektu našeg privatnog, ali i poslovnog

života, zasigurno su našla svoju primjenu i u umjetnosti, tako da danas već koristimo izraz za

to „digitalna umjetnost“. Takva umjetnost je izazvana uz pomoć računala, a na to možemo

gledati kao sredstvo, odn. materijal i tehniku u isto vrijeme baš kao što su slikaru kist, boje i

platno. Poput fraktalnog umjetnika, kipara ili bilo koga drugog umjetnika, potrebna su

pomoćna sredstva da bi stvorili umjetničko djelo, no bez vlastite kreativnosti i rada to ne bi

moglo proizlaziti.

Fraktali su ljudima poznati od pamtivijeka, samo što se oni na taj način nisu

prepoznavali. Prvi dokumentirani prikaz fraktala možemo naći već 1525. god. u „Priručniku

za slikanje“ Albrechta Dürera gdje se opisuju uzorci nastali korištenjem pentagona. U 17. st.

Leibnitz je definirao ponavljanje samosličnosti, no međutim uzeo je u obzir da samo linija

može biti sebi slična. Od tada, pa do 19.st. nisu se javljale nikakve slične definicije. Tek 1872.

god. Karl Weierstrass daje primjer funkcije kojom je definirao samosličnost. Takva definicija

je bila suviše apstraktna, pa je Helge von Koch 1904. god. dao geometrijsku interpretaciju

slične funkcije, koja je danas poznata kao Kochova pahulja, a to će nam ujedno biti i

projektni zadatak iz ovog kolegija. Poslije toga 1915. god. Waclaw Sierpinski kreirao je svoj

uzorak fraktala pomoću trokuta. U tome razdoblju pronalazimo dosta fraktalnih prikaza poput

onih Pierrea Fatoua, Henria Poincaréa, Georgea Cantora, Gastona Julie i Felixa Kleina. Svi

oni su djelovali krajem 19. st. i početkom 20. st. i proučavali su te fascinantne tvorevine

dobivane iteracijama, no međutim bez računala, pa nisu mogli uočiti sav njihov značaj.

Prvi puta se termin „fraktal“ pojavljuje 1975. god. kojeg je upotrijebio matematičar

Benoit Mandelbrot, a fraktalna umjetnost se počinje razvijati tek sredinom 1980-ih godina.

Prva fraktalna slika je nastala na naslovnoj stranici časopisa „Scientific American“ 1985. god.

i prikazivala je Mandelbrotov skup.

Page 7: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

3

Slika 1 - Scientific American - Mandelbrotov skup [Shane Bow The Chaos of

Mandelbrot, dostupno na: http://shanebow.com/projects/mandelbrot/, učitano:

17.01.2015.]

Takva slika je nastala s intencijom da ponudi vizualne i umjetničke kvalitete. Nedugo

nakon toga izdana je bogato ilustrirana knjiga „The Beauty of Fractals“ čiji su autori Heinz-

Otto Peitgen i Peter Richter. U toj knjizi velik broj ilustracija se temelji na drugom

najpopularnijem fraktalu, a riječ je Juliaovu skupu. [Fraktali i umjetnost, Vesna Mišljenović,

Zagreb (2011./2012. br. 80), str. 223.]

Kako smo konstatirali da je fraktalna umjetnost vrlo mlada, ona nije još pronašla svoje

pravo mjesto u „mainstream“ umjetničkim krugovima, a isto tako nije zastupljena na tržištu

umjetnosti i galerijama. Međutim možemo reći da fraktalna umjetnost ima široku primjenu u

računalnoj animaciji, konkretno u simulaciji rasta biljaka ili primjerice generiranju krajolika.

Page 8: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

4

3.Definicija fraktala

Fraktali su slike nastale uzastopnim ponavljanjem neke matematičke funkcije,

odnosno ponavljanjem određenog geometrijskog postupka. Mogli bismo reći da su to zapravo

objekti koji daju jednaku razinu detalja neovisno o razlučivosti koju koristimo.

Kako smo na laboratorijskim vježbama mogli vidjeti kod profesora Horvata, fraktale

je moguće uvećavati beskonačno mnogo puta, a pri tome se prilikom svakog novog uvećanja

mogu opaziti detalji koji prije povećanja nisu bili vidljivi, a da količina novih, možemo reći i

sitnijih detalja uvijek bude otprilike jednaka.

U uvodu je važno za napomenuti da fraktali imaju svoja osnovna svojstva, a to su: [Uvod u

matematičke metode u inženjerstvu, Fraktali, dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf, 3.

str. učitano: 17.01.2015.]

1) Samo-sličnost – svojstvo objekta da sliči sam na sebe, neovisno o tome koji dio

promatramo i koliko ga puta uvećavamo.

2) Fraktalna dimenzija – vrijednost koja nam daje uvid u to kojoj mjeri pojedini fraktal

ispunjava prostor u kojem se nalazi. Za razliku od fraktalne dimenzije, euklidska

dimenzija koristi se kako bi se izrazila linija (jedna dimenzija), površina (dvije

dimenzije) i prostor (tri dimenzije), te može biti bilo koji prirodni broj ili nula (0, 1, 2,

3, 5, 10, 100, ... ). Fraktalna dimenzija, nasuprot tome koristi se kako bi se postigla

gustoća kojom objekt ispunjava prostor, tj. koliko se novih dijelova pojavljuje pri

uvećavanju rezolucije. Fraktalna dimenzija nije cijeli broj i u pravilu je veća od

euklidke dimenzije.

Primjer:

Fraktalna dimenzija zapadne obale Engleske je 1,3 dok je od Norveške obale 1,52.

One su veće od 1, na temelju čega možemo zaključiti da su euklidske obale shvaćene

kao krivulje. Isto tako to bi značilo da Norveška ima razvodnjeniju obalu od Engleske.

Samo bi približno mogli na eksperimentalnoj razini govoriti o fraktalnim dimenzijama

obale.

Izraz po kojem se mjeri dimenzija je:

d=log(n)/log(s),

a pri tome je:

o d – fraktalna dimenzija

Page 9: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

5

o n – broj novih kopija objekta promatrano nakon uvećanja

o s – faktor uvećanja.

Primjer:

Cantorov skup C3 ima dim C3 = log2/log3 = 0.63..... < 1;

Kochova krivulja KK ima dim KK = log4/log3 = 1.2618..... > 1.

3) Oblikovanje iteracijom – svojstvo da se objekt generira nekim matematičkim ili

geometrijskim postupkom, tako da se u osnovni (početni) objekt iterativno ugrađuju

svojstva generatora.

3.1.Podjela fraktala

Fraktale dijelimo prema:

1) stupnju samosličnosti

2) načinu nastanka.

3.1.1.Podjela fraktala prema stupnju samosličnosti

Kod podjele fraktala prema stupnju samosličnosti možemo razlikovati:

1) potpuno samoslične fraktale

2) kvazi samoslične fraktale

3) statičke samoslične fraktale

Potpuno samoslični fraktali sadrže kopije sebe koje su slične cijelom fraktalu. Ovdje je vrlo

bitno poznavati bazu i motiv. Baza je bilo koji oblik koji je sastavljen od linijskih segmenata,

dok je motiv neki drugi oblik koji se također sastoji od linija. Ako se svaka linija baze

nadomjesti oblikom motiva i taj proces nastavi u beskonačnost, dobivamo fraktal.

Page 10: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

6

Slika 2 - Baze i motivi [Uvod u fraktale, M.Paušić, dostupno na:

http://www.fer.unizg.hr/_download/repository/Uvod%20U%20Fraktale%20by%20Mla

den%20Pausic.pdf, učitano: 17.01.2015.]

Potpuno samoslični fraktali su svi geometrijski fraktali, a primjere za to možemo vidjeti na

slikama ispod:

slika 2 – Kochova krivulja

slika 4 - Sierpinskijev trokut

slika 5 – Hilbertova krivulja

slika 6 – Cantorov skup

Page 11: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

7

Slika 3 - Kochova krivulja [Hrvatski matematički elektronski časopis math.e, Galerija

fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Kochovu krivulju uveo je švedski matematičar Helge von Koch. Fraktalna dimenzija

Kochove krivulje je log4 / log3 = 1,2619.

Slika 4 - Nastanak Kochove pahuljice (2D) [Hrvatski matematički elektronski časopis

math.e, Galerija fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Page 12: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

8

Napomena: razlika između Kochove krivulje i Kochove pahuljice je u tome što krivulja

počinje dužinom, a pahuljica jednakostraničnim trokutom.

Kochovu pahuljicu ćemo kasnije prikazati u praktičnom primjeru: OpenGL ES 2.0 & 3.0 na

Androidu - 3D fraktali (primjer Kochove pahuljice).

Slika 5 - Sierpinskijev trokut - kontrukcija otkidanjem trokuta [Hrvatski matematički

elektronski časopis math.e, Galerija fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Sierpinskijev trokut uveo je poljski matematičar Waclaw Sierpinski. Fraktalna dimenzija

Sierpinskijevog trokuta iznosi log3 / log4 = 1,584962.

Poslije većeg broja iteracija možemo opaziti da duljina Kochove krivulje teži u beskonačnost

kada i broj iteracija teži u beskonačnost. Ali cijela ta duljina je i dalje na istoj površini, samo

možemo reći da je malo više zgužvana. Stupanj te zgužvanosti možemo vidjeti iz fraktalne

dimenzije. To nam daje uvid u to u kojoj mjeri nekakav fraktal zauzima ravninu ili općenito

n-dimenzionalni prostor u kojem se nalazi. Tako primjerice Kochova krivulja ima fraktalnu

dimenziju 1,2619, dok Sierpinskijev trokut približno 1,584962. Iz vrijednosti, kao i sa

prethodnih slika, možemo uočiti da je trokut malo gušći od Kochove krivulje, tj. kažemo da

ispunjava veći dio ravnine.

Page 13: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

9

Slika 6 - Hilbertova krivulja [Wikipedia, Hilbertova krivulja, dostupno na:

http://hr.wikipedia.org/wiki/Hilbertova_krivulja, učitano: 17.01.2015.]

Hilbertova krivulja je beskonačno gusta krivulja koju je opisao njemački matematičar

David Hilbert 1891. god. Ona nastaje nakon beskonačno mnogo iteracija.

Slika 7 - Contorov skup [Hrvatski matematički elektronski časopis math.e, Galerija

fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Za fraktalne skupove moguće je definirati njihove fraktalne dimenzije na nekoliko načina.

Pokazuje se da je fraktalna dimenzija Cantorova skupa strogo manja od 1 i to točno jednaka

log2 / log3 = 0,6309.

Kvazi samoslični fraktali su oni fraktali koji sadrže male kopije sebe koje nisu slične cijelom

fraktalu, već se pojavljuju u iskrivljenom obliku, a primjere za to možemo vidjeti na donjim

slikama:

slika 7 – Juliaov skup

slika 8 – Mandelbrotov skup

Page 14: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

10

Slika 8 - Juliaov skup za c = -1 [Hrvatski matematički elektronski časopis math.e,

Galerija fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Slika 9 - Mandelbrotov skup [Hrvatski matematički elektronski časopis math.e, Galerija

fraktala, V. Antočić, A. Galinović, dostupno na:

http://e.math.hr/galerija/galerija_print.html, učitano: 17.01.2015.]

Statistički samoslični fraktali su fraktali koji ne sadrže kopije samoga sebe, no međutim

neke njegove osobine kao što je fraktalna dimenzija ostaju iste pri različitim mjerilima.

Primjer za to možemo vidjeti na slici 10.

Page 15: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

11

Slika 10 – Dvodimenzionalni Perlinov šum – svjetlije nijanse predstavljaju više

vrijednosti funkcije [Fractal Noise, Neil Blevins, dostupno na:

http://www.neilblevins.com/cg_education/fractal_noise/fractal_noise.html, učitano:

17.01.2015.]

3.1.2.Podjela fraktala prema načinu nastanka

Kod podjele fraktala prema načinu nastanka razlikujemo:

iterativne fraktale

rekurzivne fraktale

slučajne fraktale

Iterativni fraktali nastaju kopiranjem, te rotiranjem i/ili translatiranjem kopije, te mogućim

zamjenjivanjem nekog elementa kopijom (npr. Kochova krivulja).

Rekurzivni fraktali su određeni rekurzivnom matematičkom formulom koja određuje

pripada li određena točka prostora (npr. kompleksna ravnina) skupu ili ne.

Slučajni fraktali posjeduju najmanji stupanj samosličnosti i možemo ih zapaziti najčešće u

prirodi kao što su munje, oblaci, obale ili drveće.

Page 16: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

12

Slika 11 - Istra i mnogi drugi poluotoci su fraktali [Neverinov blog, dostupno na:

http://blog.dnevnik.hr/blogodneverina/2010/02/1627237517/fasciniranost-

fraktalima.html, učitano: 17.01.2015.]

Slika 12 - Drvo iz prirode – fraktal [Silvergreen, Deviant art, dostupno na:

http://silvergreen.deviantart.com/art/Fractal-Tree-1646228, učitano: 17.01.2015.]

3.2.Primjena fraktala

Najjednostavniji primjer gdje se susrećemo s konkretnom primjenom fraktala u

računalnoj grafici je crtanje terena, a posebice se to odnosi na planine. Njih možemo crtati

tako da se horizontalno položenom trokutu svaki vrh snizi ili povisi za neku slučajno

odabranu vrijednost. Takvom trokutu se zatim spoje polovišta stranica, te se na taj način

dobivaju četiri nova trokuta. Srednjemu od njih snizimo ili povisimo vrhove kao i prvotnom

trokutu, no međutim tada koristimo dvostruko manje vrijednosti. Isti postupak se nadalje

Page 17: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

13

ponavlja za sva četiri trokuta ispočetka. [Uvod u matematičke metode u inženjerstvu, Fraktali,

dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf, 5.str.

učitano: 17.01.2015.]

Na sljedećoj slici dolje možemo vidjeti funkciju prikazanu u trodimenzionalnom prostoru.

Ovdje su više vrijednosti jednostavno prikazane na višem položaju. Tako se dobiva model

koji uvelike nalikuje planini.

Slika 13 - Stvorena planina uz pomoć Perlinovog šuma (WebGL Demo – Fractal Terrain

Generator, dostupno na: http://www.webgl.com/2012/05/webgl-demo-fractal-terrain-

generator/ , učitano: 17.01.2015.]

Ako bi uzeli u obzir sustave iteriranih funkcija u tri dimenzije, mogli bismo iscrtavati razne

objekte kao što su drveće, cvijeće, grmlje, korijenje i tome slično. Ako to isto napravimo u

trodimenzionalnom sustavu i na kraj svake grančice dodamo pokoji list, rezultat bi bio

nevjerovatno sličan stvarnim pojavama u prirodi, baš kao što je prikazano na slici 14. Od

manje bitnijih primjena tu je predviđanje stohastičkih procesa kao što su recimo potresi,

slaganje snopova optičkih vlakana, oponašanje rada neuronskih mreža za razvoj umjetne

inteligencije i dr. Za uređaje kao što su mobiteli, proizvode se antene u obliku fraktala koje

zbog toga koriste široki spektar frekvencija, a uz to ne zauzimaju puno prostora.

Page 18: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

14

Slika 14 - Trodimenzionalni fraktal – drvo [Pythagoras Tree, dostupno na:

http://www.phidelity.com/blog/phidelity/blog/fractal/pythagoras-tree/, učitano:

17.01.2015.]

3.3.Fraktalna dimenzija

Fraktalna dimenzija je vrijednost koja nam daje uvid u to u kojoj mjeri nekakav

fraktal ispunjava prostor u kojem se nalazi. Pronašli smo podosta definicija fraktalnih

dimenzija od kojih se niti jedna nije pokazala univerzalnom. Najbolja je dimenzija

samosličnosti, no međutim nju upotrebljavamo samo kod jako jednostavnih geometrijskih

fraktala. Za teoriju nam je najbitnija ona Hausdorffova dimenzija, a u konkretnim

slučajevima, odn. u praksi najviše se koristi Minkowski-Bouligandova dimenzija. [Uvod u

matematičke metode u inženjerstvu, Fraktali, dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf, 6. str.

učitano: 17.01.2015.]

Dimenzija samosličnosti koristi razne promjene mjera (primjerice dužine, površine,

obujmi, ...) u odnosu na mijenjanje broja iteracija kod potpuno samosličnih fraktala. Kod

Kochove krivulje svaka naredna iteracija daje četiri puta više segmenata na tri puta manje

dužine. Ako bismo broj segmenata označili sa N, a dužinu segmenta s L, ukupno bi dobili

dužinu krivulje NL. Možemo zatim reći da za Kochovu krivulju vrijedi: 4𝑁 (𝐿

3) = 𝑁𝐿𝑑 ako za

mjeru dužine uvrstimo spomenuti „d-dimenzionalni metar“. Daljnjim preuređivanjem

Page 19: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

15

jednadžbe dobivamo 𝑑 = 𝑙𝑜𝑔34 ili češće 𝑑 =𝑙𝑜𝑔4

𝑙𝑜𝑔3. Tako bi mjerna jedinica za Kochovu

krivulju bila otprilike m1.2619

. Općenito možemo reći da se dimenzija potpuno samosličnog

fraktala računa po formuli 𝑑 =𝑙𝑜𝑔𝑁

𝑙𝑜𝑔𝐿.

Minkowski-Bouligandova dimenzija – ako bismo uzeli fraktal koji leži u ravnini i prekrili

ga proizvoljnim brojem N sukladnih kvadrata duljine stranice A, smanjivanjem te duljine

kvadrata (a samim time i povećanjem njihovog broja) promijenio bi se i broj kvadrata koji

sadrže fraktal. Upravo ova metoda koristi odnos broja tih kvadrata i duljine stranica. Na taj

način možemo odrediti dimenziju jednostavnih objekata, čija nam je dimenzija već poznata

(razne definicije dimenzije ne bi trebale davati različite rezultate kod vrlo jednostavnih

objekata) kao što su primjerice kvadrati. Dobit ćemo opću formulu za kvadrat (pri tome

znamo da se radi o dvodimenzionalnom kvadratu): 𝑁 =1

𝐴2. Ako bismo učinili istu stvar i sa

dužinom (jednodimenzionalnom), te kockom (trodimenzionalnom), dobili bi opće formule:

𝑁 =1

𝐴 i 𝑁 =

1

𝐴3 . Iz ovih primjera vidimo opću formulu za objekte bilo koje dimenzije

𝑁 =1

𝐴𝑑, tj. 𝑑 =

𝑙𝑜𝑔𝑀

𝑙𝑜𝑔1

𝐴

. Valja istaknuti da ova metoda ne daje uvijek potuno točne rezultate, te

da joj se rezultati pomiču stvarnima s povećanjem broja dužina, kvadrata i kocaka. Najviše se

koristi kod određivanja fraktalne dimenzije nepravilnih objekata. [Uvod u matematičke

metode u inženjerstvu, Fraktali, dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf, 7. str.

učitano: 17.01.2015.]

Topološka dimenzija je ono što nazivamo još i intuitivnom dimenzijom, tj. broj smjerova u

kojima bismo mogli ići da smo u određenom objektu, odnosno broj stupnjeva slobode. Na

takav način je svaka linija (ravna ili zakrivljena) jednodimenzionalna, jer postoji samo jedan

stupanj slobode, a to je dužina (lijevo-desno). Svaka je ploha (ravna ili savinuta)

dvodimenzionalna, jer postoje dva stupnja slobode – dužina i širina (lijevo-desno i gore-

dolje). Topološka dimenzija uvijek je pozitivan cijeli broj ili nula. Ako bi to sagledavali

stručnije, topološka dimenzija se može definirati i kao najmanja moguća vrijednost n, tako da

se bilo koji otvoreni pokrivač (pokrivač čiji su svi elementi otvoreni skupovi) može podesiti

tako da svaka točka bude najviše n+1 element. Primjerice, ako želimo odrediti topološku

dimenziju kružnice, konstruirat ćemo joj pokrivač od otvorenih kružnih lukova. Zatim ćemo

podesiti taj pokrivač tako da smanjimo preklapanje njegovih elemenata na najmanju moguću

mjeru, ali da cijela kružnica i dalje bude potpuno pokrivena. Pošto smo uzimali otvorene

lukove, preklapanje je neizbježno, a može se napraviti tako da svaka točka kružnice bude dio

Page 20: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

16

samo jednog ili dva elementa pokrivača. Najveća je vrijednost n = 2, tako da topološka

dmenzija iznosi n – 1, te zaključujemo na temelju toga da je kružnica jednodimenzionalna.

Ovo matematičko objašnjenje se na prvi pogled možda čini nepotrebnim, ali je vrlo bitno u

nekim elementima više matematike, kao primjerice u našoj seminarkoj temi o fraktalima.

[Uvod u matematičke metode u inženjerstvu, Fraktali, dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf, 8. str.

učitano:17.01.2015.]

Page 21: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

17

4.Prikaz grafike s OpenGL ES

Android okvir pruža mnogo standardnih alata za stvaranje funkcionalnog grafičkog

sučelja. Ako primjerice želimo postići veću kontrolu nad onime što želimo prikazati na

zaslonu kao što je modeliranje u trodimenzionalnim slikama trebali bismo koristiti više vrsta

različitih funkcija. OpenGL ES API od strane Android okvira nudi čitav niz alata za prikaz

vrhunske animirane grafike koje su ograničene samo našom maštom i također možemo imati

koristi od ubrzanja grafičke obrade jedinica (GPU) koje se nalaze na mnogim Android

uređajima.

4.1.Izgradnja OpenGL ES okruženja

Kako bi mogli iscrtavati grafičke objekte uz pomoć OpenGL ES na našem Android-u

moramo prvo kreirati određene poglede na spremnike za njih. Jedan od najboljih načina za to

je implementacija sučelja GLSurfaceView i GLSurfaceView.Renderer. GLSurfaceView je

spremnik za grafičko crtanje s OpenGL-om i GLSurfaceView-om. Renderer kontrolira ono

što je nacrtano u tom pogledu. GLSurfaceView je samo jedan od načina da se u OpenGL ES

uključi grafika u takav program. Primjerice za prikaz punog zaslona to je definitivno najbolji

izbor.

4.1.1.Deklariranje OpenGL koristeći Manifest

Kako bi mogli koristiti OpenGL ES 2.0 API u našoj aplikaciji moramo ga deklarirati u

našem manifestu sa ovim XML isječkom:

<uses-feature android:glEsVersion="0x00020000"

android:required="true" />

Ako naša aplikacija koristi kompresiju teksture, također moramo deklarirati u manifestu koje

formate kompresije naša aplikacija podržava. To vrijedi samo za kompatibilne uređaje.

[Developers, Displaying Graphics with OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]

Page 22: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

18

<supports-gl-texture

android:name="GL_OES_compressed_ETC1_RGB8_texture" />

<supports-gl-texture

android:name="GL_OES_compressed_paletted_texture" />

4.1.2.Kreiranje aktivnosti za OpenGL ES grafiku

Android aplikacije koje koriste OpenGL ES imaju aktivnosti baš kao i bilo koje druge

aplikacije koja ima korisničko sučelje. Glavna razlika od drugih aplikacija je ono što se stavi

u raspored za naše aktivnosti. Dok se u mnogim aplikacijama koriste TextView, gumb i

ListView, u aplikaciji koji koristi OpenGL ES, također možete dodati i GLSurfaceView.

Sljedeći kod pokazuje minimalnu provedbu aktivnosti koje koristi GLSurfaceView kao svoj

primarni pogled [Developers, Displaying Graphics with OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

public class OpenGLES20Activity extends Activity {

private GLSurfaceView mGLView;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

// Create a GLSurfaceView instance and set it

// as the ContentView for this Activity.

mGLView = new MyGLSurfaceView(this);

setContentView(mGLView);

}

}

4.1.3.Gradnja GLSSurfaceView objekata

GLSurfaceView je specijalizirani pogled u kojem možemo crtati grafiku OpenGL ES.

To samo za sebe ne znači baš mnogo. Stvarni crtež objekata se kontrolira u

GLSurfaceView.Renderer-u koje smo postavili na ovom prikazu. Naime, kod za ovaj objekt

je tako malen, pa možemo biti u iskušenju da ga preskočimo ili stvorimo nemodificiranu

GLSurfaceView instancu. Morali bismo proširiti ovu klasu kako bi se omogućilo snimanje

događaja. Veoma važan programski kod za GLSurfaceView je minimalan, tako da za brzu

Page 23: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

19

provedbu, uobičajeno je da samo stvorimo unutarnje klase u aktivnosti koje koristimo

[Developers, Displaying Graphics with OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

class MyGLSurfaceView extends GLSurfaceView {

public MyGLSurfaceView(Context context){

super(context);

// Set the Renderer for drawing on the GLSurfaceView

setRenderer(new MyRenderer());

}

}

Kada koristimo OpenGL ES 2.0, moramo dodati još jedan poziv na svoj GLSurfaceView

konstruktor, te naznačimo da želimo koristiti 2.0 API [Developers, Displaying Graphics with

OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

// Create an OpenGL ES 2.0 context

setEGLContextClientVersion(2);

Jedan drugi izborni dodatak našem GLSurfaceView-u je postavljanje načina za pogled kada je

došlo do promjene crtanja podataka pomoću

GLSurfaceView.RENDERMODE_WHEN_DIRTY postavke [Developers, Displaying

Graphics with OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

// Render the view only when there is a change in the drawing data

setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

Ova postavka sprječava GLSurfaceView okvir od toga da ponovno iscrtava dok ne pozovemo

funkciju requestRender(), što je učinkovitije za ovaj uzorak.

Page 24: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

20

4.1.4.Gradnja Renderer klase (klasa prikazivanja)

Implementacija GLSurfaceView.Renderer klase unutar aplikacije koja koristi OpenGL ES je

dio gdje stvari počinju biti zanimljive i interesantne. Ova klasa kontrolira ono što je iscrtano u

GLSurfaceView s kojim je i povezana. Postoje tri metode u renderer klasi koje se pozivaju od

strane Android sustava kako bi shvatili što i kako se iscrtava na GLSurfaceView-u:

onSurfaceCreated() – poziva se samo jednom kako bi se postavili pogledi OpenGL ES

okruženja;

onDrawFrame() – pozivanje prilikom svakog prikaza iscrtavanja;

onSurfaceChanged() – poziva se prilikom promjene geometrijskog prikaza, primjerice

izmijene orijentacije ekrana uređaja.

Primjer koda ispod je osnovna provedba OenGL ES prikazivača koji ne radi ništa bitno, samo

postavlja sivu pozadinu u GLSurfaceView-u [Developers, Displaying Graphics with OpenGL

ES, dostupno na: http://developer.android.com/training/graphics/opengl/environment.html,

25.01.2015.]:

public class MyGLRenderer implements GLSurfaceView.Renderer {

public void onSurfaceCreated(GL10 unused, EGLConfig config) {

// Set the background frame color

GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

}

public void onDrawFrame(GL10 unused) {

// Redraw background color

GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);

}

public void onSurfaceChanged(GL10 unused, int width, int height)

{

GLES20.glViewport(0, 0, width, height);

}

}

Kod koji smo naveli iznad je u biti jednostavna mala Android aplikacija koja prikazuje sivi

zaslon pomoću OpenGL-a. Ova klasa je temelj koji je potreban za početak iscrtavanja

Page 25: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

21

grafičkih elemenata s OpenGL-om. Sada kada smo upoznati s OpenGL ES API-jem, možemo

postaviti OpenGL ES okruženje u aplikaciji i početi crtati grafiku.

4.2.Definiranje oblika

Biti u stanju definirati oblike koji se mogu izvesti u kontekstu pogleda OpenGL ES-a

je prvi korak u stvaranju visokozahtjevne grafike. Crtanje s OpenGL ES-om može biti malo

teže bez poznavanja nekoliko osnovnih stvari o tome kako OpenGL ES očekuje definiranje

grafičkih objekata. Ovdje ćemo objasniti kako je OpenGL ES koordinatni sustav relativan u

odnosu na Android-ov zaslon uređaja, osnove definiranja oblika, oblik lica, te definiranje

trokuta i kvadrata.

4.2.1.Primjer definiranja trokuta

OpenGL ES omogućuje definiranje crtanja objekata pomoću koordinata u

trodimenzionalnom prostoru. Prije nego što nacrtamo trokut, moramo definirati svoje

koordinate. U OpenGL, tipičan način da to učinimo je da si definiramo najvišu točku ili tjeme

i brojeve s pomičnim zarezom za koordinate. Za maksimalnu učinkovitost, pišemo ove

koordinate u ByteBuffer, koji je uspješno prošao u OpenGL ES grafički cjevovod za obradu.

[Developers , Defining Shapes, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]

public class Triangle {

private FloatBuffer vertexBuffer;

// number of coordinates per vertex in this array

static final int COORDS_PER_VERTEX = 3;

static float triangleCoords[] = { // in counterclockwise

order:

0.0f, 0.622008459f, 0.0f, // top

-0.5f, -0.311004243f, 0.0f, // bottom left

0.5f, -0.311004243f, 0.0f // bottom right

};

// Set color with red, green, blue and alpha (opacity) values

Page 26: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

22

float color[] = { 0.63671875f, 0.76953125f, 0.22265625f, 1.0f };

public Triangle() {

// initialize vertex byte buffer for shape coordinates

ByteBuffer bb = ByteBuffer.allocateDirect(

// (number of coordinate values * 4 bytes per float)

triangleCoords.length * 4);

// use the device hardware's native byte order

bb.order(ByteOrder.nativeOrder());

// create a floating point buffer from the ByteBuffer

vertexBuffer = bb.asFloatBuffer();

// add the coordinates to the FloatBuffer

vertexBuffer.put(triangleCoords);

// set the buffer to read the first coordinate

vertexBuffer.position(0);

}

}

Po početnim vrijednostima, OpenGL ES pretpostavlja koordinatni sustav [0,0,0] (X, Y, Z)

i specificira središte GLSurfaceView okvir. [1,1,0] je gornji desni kut okvira i [- 1, -1,0] je u

donjem lijevom kutu okvira.

4.2.2.Primjer definiranja kvadrata

Definiranje trokuta je prilično lako u OpenGL, ali što ako želimo da nešto malo

složenije? U ovom primjeru konkretno mislimo na kvadrat. Postoji nekoliko načina za

iscrtavanje kvadrata, ali tipičan način izrade takvog oblika u OpenGL ES-u je koristiti dva

trokuta nacrtana zajedno kao što je prikazano na slici ispod.

Page 27: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

23

Slika 15 - Crtanje kvadrata uz pomć 2 trokuta [Defining Shapes, dostupno na:

http://developer.android.com/training/graphics/opengl/shapes.html, učitano:

25.01.2015.]

Opet bi trebali definirati točke u suprotnom smjeru od kazaljke na satu kako bi oba trokuta

predstavljali ovaj oblik, te postaviti vrijednosti u ByteBuffer. Kako bi se izbjeglo da dvije

koordinate dijele svaki trokut dva puta, koristimo se popisom za crtanje koji daje upute

OpenGL ES-u na način kako da grafički cjevovod izvuće te vrhove. Pogledajmo kod za

kvadrat [Developers, Defining Shapes, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

public class Square {

private FloatBuffer vertexBuffer;

private ShortBuffer drawListBuffer;

// number of coordinates per vertex in this array

static final int COORDS_PER_VERTEX = 3;

static float squareCoords[] = {

-0.5f, 0.5f, 0.0f, // top left

-0.5f, -0.5f, 0.0f, // bottom left

0.5f, -0.5f, 0.0f, // bottom right

0.5f, 0.5f, 0.0f }; // top right

private short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to

draw vertices

public Square() {

// initialize vertex byte buffer for shape coordinates

Page 28: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

24

ByteBuffer bb = ByteBuffer.allocateDirect(

// (# of coordinate values * 4 bytes per float)

squareCoords.length * 4);

bb.order(ByteOrder.nativeOrder());

vertexBuffer = bb.asFloatBuffer();

vertexBuffer.put(squareCoords);

vertexBuffer.position(0);

// initialize byte buffer for the draw list

ByteBuffer dlb = ByteBuffer.allocateDirect(

// (# of coordinate values * 2 bytes per short)

drawOrder.length * 2);

dlb.order(ByteOrder.nativeOrder());

drawListBuffer = dlb.asShortBuffer();

drawListBuffer.put(drawOrder);

drawListBuffer.position(0);

}

}

Ovaj primjer daje nam ono što je potrebno za stvaranje složenijih oblika s OpenGL-om.

Općenito, koristimo zbirke trokuta za crtanje objekata.

4.3.Crtanje oblika

Nakon što smo prikazali oblike koji se mogu izvesti s OpenGL, poželjet ćemo ih i

iscrtati. Crtanje oblika s OpenGL ES 2.0 traje malo više koda, jer API omogućuje veliku

kontrolu nad slikama koji pruža cjevovod.

4.3.1.Inicijalizacija oblika Prije nego bilo što nacrtamo, moramo inicijalizirati i učitati oblike koje namjeravamo nacrtati.

Osim ako strukturu (izvornih koordinata) oblika koje koristimo u svom programu promjenimo

tijekom izvršenja, trebali bismo ih inicijalizirati u onSurfaceCreated() metodi našeg renderer-a

(prikazivača) za pamćenje i učinkovitost obrade. [Developers, Drawing Shapes, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

Page 29: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

25

public void onSurfaceCreated(GL10 unused, EGLConfig config) {

...

// initialize a triangle

mTriangle = new Triangle();

// initialize a square

mSquare = new Square();

}

4.3.2.Crtanje oblika

Crtanjem definiramo oblik pomoću OpenGL ES-a 2.0 i to zahtijeva značajnu količinu

koda, jer moramo pružiti puno detalja u grafici pruzujući sve kroz cjevovod. Moramo

definirati sljedeće:

Vertex Shader - OpenGL ES kod za grafiku za prikaz vrhova oblika;

Fragment Shader - OpenGL ES kod za prikazivanje oblika s bojama ili teksturama.

Program - OpenGL ES objekt koji sadrži sjenčanje koje ćemo koristiti za izradu

jednog ili više oblika.

Shader je računalni program koji se koristi za napraviti sjenčanje.

Trebamo barem jedan vrh osjenčati kako bi nacrtali oblik i jedan fragment osjenčati bojom da

bi prikazali oblik. To sjenčanje mora biti iskompajlirano, a zatim je dodano u OpenGL ES

program, koji se potom koristi za iscrtavanje oblika. Ovdje je primjer kako definirati osnovno

sjenčanje koje možemo koristiti za crtanje oblika [Developers, Drawing Shapes, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.].

private final String vertexShaderCode =

"attribute vec4 vPosition;" +

"void main() {" +

" gl_Position = vPosition;" +

"}";

private final String fragmentShaderCode =

"precision mediump float;" +

"uniform vec4 vColor;" +

"void main() {" +

Page 30: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

26

" gl_FragColor = vColor;" +

"}";

Shaderi ili zasjenjivači sadrže OpenGL sjenčanje jezika (GLSL) kod kojeg se mora

iskompajlirati prije upotrebe u OpenGL ES okruženju. Kako bi mogli nacrtati svoje oblike,

moramo prvo sastaviti Shader šifru, dodati ga u OpenGL ES programski objekt, a zatim

povezati program. To možemo napraviti u našem nacrtanom objektu konstruktora, pa je to

dovoljno učiniti samo jednom.

Kompajliranje OpenGL ES shadera i povezivanja programa je skuplji u odnosu na

CPU ciklus i vrijeme obrade, tako da treba izbjegavati to više puta. Ako ne znamo sadržaj

naših shader-a ili zasjenjivača tijekom instalacije, trebali bismo napraviti svoj kod, dovoljno

ga je samo jednom kreirati i spremiti za kasniju uporabu [Developers, Drawing Shapes,

dostupno na: http://developer.android.com/training/graphics/opengl/environment.html,

25.01.2015.].

public class Triangle() {

...

int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER,

vertexShaderCode);

int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER,

fragmentShaderCode);

mProgram = GLES20.glCreateProgram(); // create empty

OpenGL ES Program

GLES20.glAttachShader(mProgram, vertexShader); // add the

vertex shader to program

GLES20.glAttachShader(mProgram, fragmentShader); // add the

fragment shader to program

GLES20.glLinkProgram(mProgram); // creates

OpenGL ES program executables

}

4.4.Primjena projekcije i pogled kamere

Page 31: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

27

U OpenGL ES okruženju, projekcije i pogled kamere omogućuju prikazivanje

nacrtanih objekata na način da više fizički sliče kao oni iz stvarnosti. Ova simulacija fizičkog

pogleda je načinjena s matematičkim transformacijama nacrtanih objekata uz pomoć

koordinata:

Projekcija - ova transformacija postavlja koordinate nacrtanih objekata na temelju

širine i visine GLSurfaceView gdje se prikazuju.

Pogled kamere - ova transformacija podešava koordinate nacrtanih objekata na

temelju virtualnog položaja kamere.

4.4.1. Definiranje projekcije

Podaci za transformaciju projekcijom se izračunavaju onSurfaceChanged() metodom

naše GLSurfaceView.Renderer klase. Sljedećim kodom uzimamo visinu i širinu

GLSurfaceView i koristimo ga za popunjavanje matrice projekcije transformacije pomoću

Matrix.frustumM () metode [Developers, Applying Projection and Camera Views, dostupno

na: http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

@Override

public void onSurfaceChanged(GL10 unused, int width, int height) {

GLES20.glViewport(0, 0, width, height);

float ratio = (float) width / height;

// this projection matrix is applied to object coordinates

// in the onDrawFrame() method

Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3,

7);

Ovaj kod popunjava matricu projekcija, mProjectionMatrix koje možemo kombinirati s

transformacijom kamera u onDrawFrame() metodi.

4.4.2. Definiranje pogleda kamere

Kompletan proces transformacije nacrtanih objekata završava dodavanjem transformacija u

pogled kamere kao dio procesa crtanja. U sljedećem primjeru koda, transformacija pogleda

kamere se izračunava pomoću Matrix.setLookAtM() metode, a zatim u kombinaciji s

prethodno izračunatom projekcijom matrice [Developers, Applying Projection and Camera

Page 32: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

28

Views, dostupno na: http://developer.android.com/training/graphics/opengl/environment.html,

25.01.2015.].

public void draw(float[] mvpMatrix) { // pass in the calculated

transformation matrix

...

// get handle to shape's transformation matrix

mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram,

"uMVPMatrix");

// Pass the projection and view transformation to the shader

GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix,

0);

// Draw the triangle

GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vertexCount);

...

}

4.5. Dodavanje pokreta

Crtanje objekata na zaslonu je temeljna značajka OpenGL, ali možemo to učiniti s drugim

Android grafičkim okvirima klasa, uključujući Canvas i Drawable objekte. OpenGL ES nudi

dodatne mogućnosti za kretanje i pretvaranje nacrtanih objekata u tri dimenzije ili druge

jedinstvene načine za kreiranje korisnikovih iskustava.

4.5.1.Rotiranje oblika

Rotirajunje objekata s OpenGL ES 2.0 je relativno jednostavno. Možemo jednostavno stvoriti

drugu matricu transformacije (matricu rotacije), a zatim je kombinirati sa svojim projekcijama

i pogledom kamere matricom transformacija [Developers, Adding Motion,dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

private float[] mRotationMatrix = new float[16];

public void onDrawFrame(GL10 gl) {

...

float[] scratch = new float[16];

Page 33: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

29

// Create a rotation transformation for the triangle

long time = SystemClock.uptimeMillis() % 4000L;

float angle = 0.090f * ((int) time);

Matrix.setRotateM(mRotationMatrix, 0, angle, 0, 0, -1.0f);

// Combine the rotation matrix with the projection and camera

view

// Note that the mMVPMatrix factor *must be first* in order

// for the matrix multiplication product to be correct.

Matrix.multiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix,

0);

// Draw triangle

mTriangle.draw(scratch);

}

4.5.2. Omogućavanje kontinuiranog prikazivanja (renderiranja)

Ako se slučajno naš oblik ne okreće, moramo komentirati u kodu dio s postavkom

GLSurfaceView.RENDERMODE_WHEN_DIRTY. OpenGL inače rotira oblik

inkrementalno i čeka poziv funkcije requestRender() iz GLSurfaceView spremnika

[Developers, Adding Motion, dostupno na:

http://developer.android.com/training/graphics/opengl/environment.html, 25.01.2015.]:

public MyGLSurfaceView(Context context) {

...

// Render the view only when there is a change in the drawing

data.

// To allow the triangle to rotate automatically, this line is

commented out:

//setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

}

Osim ako imamo objekte koji se mijenjaju bez bilo kakve interakcije s korisnikom, onda je

dobra ideja imati ovu zastavicu podignutu ili uključenu.

Page 34: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

30

5. Prikaz grafike s OpenGL ES iz Processinga 2.0

Kako Android platforma sadrži potpunu podršku za Java okruženje u prethodnom poglavlju

obradili smo OpenGL ES iz perspektive Jave. No, Android je i ujedno open source ekosustav,

što znači da Java nije jedini alat koji nam stoji za manipulaciju OpenGL ES-a. Na Android

platformi možemo pristupiti OpenGL ES-u iz bilo kojeg skriptnog jezika putem Android

SL4A ili nekog trećeg ekosustava kao što je to Processing 2.0.

Kako bi učinili cijelokupnu stvar nama zanimljivijom, pitali smo se kako upravljati OpenGL

ES-om iz neke druge perspektive koja nije Javina, istraživanjem došli smo do 2 odgovora.

Prvi je, da je to moguće uz pomoć C/C++ jezika kojeg ćemo ugraditi u Java aplikaciju putem

JNI sučelja. Drugi je, putem Processing 2.0 API-a. Naime, Processing je veoma popularan

jezik i okruženje za programiranjem sa velikim naglaskom na računalnu grafiku i grafičke

elemente. Kada smo vidjeli da Processing 2.0 sadrži podršku za Android grafiku putem

OpenGL ES-a odlučili smo dalje istražiti tu perspektivu razvoja.

U ovom poglavlju napraviti ćemo kratak pregled u OpenGL ES iz perspektive Processing 2.0

jezika. U prethodnim poglavljima razmatrali smo kako je OpenGL ES zapravo okvir za koji je

zadužna grafička kartica na uređaju (eng. Graphic Processing Unit, u nastavku GPU). Upravo

taj okvir čini direktan način programiranja 3D grafike na Androidu. OpenGL ES je također

API koji je namjenjen da se koristi na više platformi, a ne samo na Androidu, te ujedno čini i

podskup OpenGL-a. Minimalni hardwerski zahtjevi da pokrenemo neku 3D grafiku na

Androidu iz Processinga su sljedeći:

GPU koji ima podršku minimalno za OpenGL ES 1.1

Android 2.1+, no neka svojstva OpenGL još uvijek nedostaju na Androidu 2.1, tako da

se preporuča upotreba minimalno Android 2.2 platforme

Kada radimo Processing skicu za Android dostupna su nam 2 stroja renderiranja. Prvi je sam

OpenGL ES, dok je drugi Android 3D (u nastavku A3D). Cijelokupan Processing na

Androidu koristi OpenGL ES direktno, i sve skice koje izradimo će u runtime-u koristiti

OpenGL ES 2.0. Stroj renderiranja u Processingu je zapravo modul koji je zadužan za sva

crtanja i sve operacije sa kojima crtamo. Stroj renderiranja specificiramo kada stvaramo

objekt ekrana i zadajemo mu rezoluciju. U slučaju ako ne zadamo neki stroj renderiranja

Processing će upotrebljavati A2D. U nastavku ćemo razmotriti neke od scenarija korištenja

Page 35: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

31

Processinga na Androidu te uvidjeti da je zapravo puno intuitivnije za koristiti Processingom

API za crtanje nego čiste pozive OpenGL ES-a iz Jave.

Prije nego se upustimo u naprednije stvari iz Processinga razmotrimo primjer kako crtati na

platno koje nećemo prikazati na ekranu (eng. Offscreen drawing). Da bi izradili platno u

Processingu potrebno je pozvati se na createGraphics() metodu.

PGraphicsAndroid3D pg;

void setup() {

size(480, 800, A3D);

pg = createGraphics(300, 300, A3D);

...

}

Ovakav crtež koji se ne prikazuje na ekranu, kasnije možemo iskoristi kao sliku za teksturu

objekta ili da kombiramo sa drugim slojevima. Naprimjer, ovako:

void draw() {

pg.beginDraw();

pg.rect(100, 100, 50, 40);

pg.endDraw();

...

cube.setTexture(pg.getOffscreenImage());

...

}

5.1. Geometrijske transformacije

Koordinatni sustav u Processingu definiran je sa X osi koja se proteže od lijeve prema desnoj

strani, Y os od doljnoj prema gornjoj strani i negativna Z os pokazuje od ekrana. Kada bi

gledali ishodište koordinatnog sustava ono bi bilo u gornjom lijevom kutu. Ovo je važno da

znamo jer sve geometrijske transformacije koje ćemo primjeniti nad našim objektima će se

Page 36: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

32

odnositi na cijeli koordinatni sustav. Iz slike 16. možemo vidjeti kako je koordinatni sustav za

3D implementiran u Processingu.

Slika 16 Koordinatni sustav kako je implementiran u Processingu

5.1.1. Translacija

Translacija se vrši uz pomoć translate(dx, dy, dz) funkcije.

void setup() { size(240, 400, A3D); stroke(255, 150);

} void draw() {

background(0); translate(50, 50, 0); noStroke(); fill(255, 200); rect(60, 0, 100, 100);

}

Iz slike 17. možemo vidjeti kako će gornji kod napraviti translaciju rect-a.

Page 37: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

33

Slika 17 Primjer translacije

5.1.2. Rotacija

Rotacija uvijek sadrži jednu od osi oko koje objekt rotira. Ta os može biti koordinatna ili

može biti neki proizvoljni vektor.

rotateX(angle), rotateY(angle), rotateZ(angle), rotate(angle, vx,

vy, vz)

void setup() {

size(240, 400, A3D);

stroke(255, 150);

}

void draw() {

background(0);

Page 38: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

34

rotateZ(PI / 4);

noStroke();

fill(255, 200);

rect(60, 0, 100, 100);

}

Iz doljnje slike možemo vidjeti kako gornji isječak koda će rotirati rect.

Slika 18 Prikaz rotacije

Page 39: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

35

5.1.3. Skaliranje

Skaliranje može biti uniformno, znači da se objekt proširuje u svim smjerovima za određenu

jednaku duljinu, tj. za neki faktor. Ili možemo definirati funkciji scale(sx, sy, sz) zasebne

vrijednosti za svaki smjer.

void setup() {

size(240, 400, A3D);

stroke(255, 150);

}

void draw() {

background(0);

scale(1.5, 3.0, 1.0);

noStroke();

fill(255, 200);

rect(60, 0, 60, 60);

}

Iz gornjeg isječka, naš pravokutnik će se skalirati kako je prikazano na sljedećoj slici.

Page 40: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

36

Slika 19 Primjer skaliranja u Processingu

5.2. Kamera i perspektiva

Konfiguriranje pogleda sceneu A3D zahtjeva konfiguraciju lokaciju kamere i volumena

gledanja. Postavljanje kamere je specificirano pozicijom oka, centrom scene te koja

koordinatna os gleda prema gore. Funkcija za konfiguraciju kamere u Processingu je:

camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);

Ako se gore definirana funkcija ne poziva, A3D automatski će ju pozvati sa defaltnim

vrijednostima koje su:

Page 41: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

37

camera(width / 2.0, height / 2.0, (height / 2.0) / tan(PI * 60.0 /

360.0), width / 2.0, height / 2.0, 0, 0, 1, 0);

Razmotrimo sada primjer postavljanja kamere.

void setup() {

size(240, 400, A3D);

fill(204);

}

void draw() {

lights();

background(0);

camera(30.0, mouseY, 220.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

noStroke();

box(90);

stroke(255);

line(-100, 0, 0, 100, 0, 0);

line(0, -100, 0, 0, 100, 0);

line(0, 0, -100, 0, 0, 100);

}

Gornji programski isječak nacrtati će sljedeću grafiku iz koje možemo vidjeti jednostavno

kako smo zapravo postavili kameru u prostor.

Page 42: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

38

Slika 20 Primjer kamere u prostoru

Kako bi napravili pogled iz određene perspekitve koristimo funkciju perspecitve. Volumen

pogleda u tom slučaju je smanjena ili povećana piramida te konvergencija nacrtanih linija

prema oku stvara perspektivnu projekciju gdje objekti koji su smješteni dalje će se činiti

manji, dok oni bliže će se činiti većima.

Slika 21 Slika objašnjava elemente koji su uključeni u perspektivnu geometriju

Page 43: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

39

5.3. Stvaranje 3D objekata

Processing je veoma jednostavan za korištenje, te stvaranje 3D objekata je puno

jednostavnije, brže i intuitivnije nego je to recimo u Javi. On nam definira u A3D već

određene predefinirane objekte poput sfere i kocke. Kako stvarati 3D objekte je najlakše

objasniti na primjeru. Primjer jednostavnosti upotrebe jednostavnih grafičkih primitiva nalazi

se u nastavku.

void setup() {

size(240, 400, A3D);

stroke(0);

}

void draw() {

background(0);

translate(width/2,height/2,0);

fill(200, 200);

pushMatrix();

rotateY(frameCount*PI/185);

box(150, 150, 150);

popMatrix();

fill(200, 40, 100, 200);

pushMatrix();

rotateX(-frameCount*PI/200);

sphere(50);

popMatrix();

}

Ovaj programski isječak prikazuje nam kako koristiti neke predefinirane grafičke primitive.

Kada ga iskompajliramo i pokrenemo na Android uređaju ili emulatoru, dobiti ćemo prikaz

koji se nalazi na idućoj slici.

Page 44: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

40

Slika 22 Primjer korištenja predefiniranih 3d grafičkih primitiva

Drugi način stvaranja 3D objekata koji nisu predefinirani je putem beginShape(), endShape()

konstrukata. Ove dvije funkcije omogućavaju nam da stvorimo složenije objekte tako da

specificiramo vrhove i način njihovog spajanja (te opcionalno možemo specificirati i normale

i koordinata tekstura za svaki verteks). Ova funkcionalnost je dostupna i u A2D sa malom

razlikom da u A3D imamo jednu koordinatnu os više pa i za nju moramo specificirati

koordinate. Naprimjer, razmotrimo sljedeći isječak Processinga.

beginShape(TRIANGLE_STRIP);

vertex(30, 75, 0);

vertex(40, 20, 0);

vertex(50, 75, 0);

vertex(60, 20, 0);

vertex(70, 75, 0);

Page 45: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

41

vertex(80, 20, 0);

vertex(90, 75, 0);

endShape();

Za ovaj složeni objekt pod nazivom „TRIANGLE_STRIP“ dobiti ćemo sliku 23. kada ga

renderiramo.

Slika 23 Renderiranje složenih objekata

5.3.1. Teksture

Teksture su jedna od najvažnijih tehnika u računalnoj grafici koje se sastoje od korištenja

slike kao papira u koji ćemo omotati neki 3D objekt sa ciljem da simuliramo da taj objekt je

načinjen od nekog materijala, da dobijemo realističnu površinu objekta ili možda neke efekte.

Slika 24 Slika objašnjava koncept tekstura u računalnoj grafici

Mapiranje tekstura na objekte je izazovan i kompleksan problem kada trebamo pridodati

teksturu nekom kompliciranom 3D objektu (koji još k tome je organske prirode). Da bi

Page 46: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

42

pronašli pravilno mapiranje 2D slike u 3D objekt zahtjeva precizne matematičke tehnike koje

u svojim izračunima uzimaju u obzir rubove, presjeke, itd. Ako razmotrimo sliku 25. vidimo

koliko zapravo 3D objekt može biti kompleksan.

Slika 25 Slika demonstrira primjerom kako proces mapiranja tekstura može biti složen za određene 3D objekte

Kako bi u Processingu iskoristili teksture, pokazati ćemo to na jednostavnom primjeru kako

se to radi.

PImage img1, img2; void setup() {

size(240, 240, A3D); img1 = loadImage("beach.jpg"); img2 = loadImage("peebles.jpg"); textureMode(NORMAL); noStroke();

} void draw() {

background(0); beginShape(TRIANGLES); texture(img1); vertex(0, 0, 0, 0, 0); vertex(width, 0, 0, 1, 0); vertex(0, height, 0, 0, 1); texture(img2); vertex(width, 0, 0, 1, 0); vertex(width, height, 0, 1, 1); vertex(0, height, 0, 0, 1); endShape();

}

Page 47: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

43

Kada kompajliramo gornji primjer i pokrenemo ga na Androidu dobivamo rezultat sa sljedeće

slike.

Slika 26 Primjer rada sa teksturama u Processingu

Iz gornjeg primjera vidimo kako raditi sa teksturama u Processingu na Androidu. Također,

prikazali smo još jedno važno svojstvo, a to je da sa beginShape i endShape u A3D možemo

iskoristiti kombinaciju više tekstura za različite dijelove jednog objekta.

5.3.2. Svijetlo

Android 3D također pruža lokalni model osvijetljenja baziran na OpenGL modelu. To je

jednostavan pravovremeni (eng. realtime) model osvijetljenja, gdje svaki izvor svijetlosti

sadrži 4 komponente:

Ambijent

Difuziju

Spekular

Emisiju

Page 48: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

44

Zbroj tih 4 komponenata čini total. Ovaj model ne dopušta stvaranje sjena te može definirati i

do 8 različitih izvora svijetla. Odgovarajući izračuni za svijetlo zahtjevaju da se specificira

normala objekta. Android 3D podržava nekoliko tipova svijetla, a to su:

Ambijentalno – Ambijentalno svijetlo je takvo svijetlo koje ne dolazi iz nekog

specifičnog smjera, zrake svijetlosti sadrže osvijetljenje na sve strane tako da su

objekti ravnomjerno osvijetljenji sa svih strana. Ambijentalno svijetlo se gotovo uvijek

koristi u kombinaciji sa drugim tipovima svijetla.

o U Android Processingu definiramo ga funkcijom: ambientLight(v1, v2 ,v3, x,

y, z), gdje su v1, v2, v3 rgb boje svijetla, a x, y, z pozicija

Slika 27 Primjer ambijentalnog svijetla

Direkcionalno – Direkcionalno svijetlo dolazi iz nekog smjera i puno je jače na

dodirnim točkama objekta te zatim nakon toga slabi. Nakon što udari površinu

objekta, direkcionalno svijetlo će se raspršiti u svim smjerovima.

o U Android Processingu definiramo ga funkcijom: directionalLight(v1, v2, v3,

nx, ny, nz), gdje su v1, v2, v3 rgb boje svijetla, a nx, ny i nz vektor smjera

svijetla

Slika 28 Primjer direkcionalnog svijetla

Točkasto – Točkasto svijetlo zrači svijetlošču iz specificirane pozicije.

o U Android Processingu definiramo ga funkcijom: pointLight(v1, v2, v3, x, y,

z), gdje su v1, v2, v3 rgb boje svijetla, a x, y, z koordinate točke

Page 49: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

45

Slika 29 Primjer točkastog svijetla

Pjegasto – Pjegasto svijetlo emitira svjetlost prema određenog konusu emitiranja tako

da onemogući prostoru emitiranja izvor svijetlosti

o U Android Processingu definiramo ga sa: spotLight(v1, v2, v3, x, y, z, nx, ny,

nz, angle, concentration) gdje su v1, v2 i v3 rgb boje svijetlosti, x, y, z su

koordinate konusa, nx, ny, nz specificiraju vektor smjera svijetlosti, angle

označava pod kojim kutem će konus biti i concetration označava eksponent

koji determinira centralni nagib konusa.

Slika 30 Primjer pjegastog svijetla

Page 50: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

46

6. Kochova pahulja u 3D

Sada kada smo napravili kratak pregled kroz osnove OpenGL ES-a na Androidu iz dvije

različite perspektive, pokušati ćemo izmodelirati Kochovu pahulju u 3D-u. Kako više

naginjemo novijem pristupu razvoja Android grafike, koristiti ćemo Processing 2.0 za crtanje

našeg 3D fraktala.

Za početak prisjetimo se kako se crta Kochova pahulja u 2D-u. Iz teorije znamo da se

Kochova pahulja crta uz pomoć Kochove krivulje, a Kochova krivulja se dobiva tako da

zadani vektor podijelimo prvo na 3 jednaka dijela, te zatim obrišemo srednji dio te na

njegovom mjestu nacrtamo dva vektora koja se dodiruju u normali početnog vektora. Ovaj

proces ponavljamo rekurzivno za svaki od vektora koji imamo na platnu. Kochova krivulja

počinje od 1 vektora i njega rekurzivno dijeli, te na taj način tvori fraktal dok Kochova

pahulja za početni oblik uzima trokut, te cijelokupni postupak iz Kochove krivulje ponavlja za

svaku od stranica trokuta.

No pitanje se sada postavlja na koji način možemo nacrtati Kochovu pahulju u 3D-u. Da bi

cijelu priču iz 2D-a pretvorili u 3D moramo zamijeniti primitivne konstrukte. Jednostavnim i

brzim istraživanjem otkrili smo da Kochovu pahulju u 3D-u možemo nacrtati na dva načina.

Prvi način je da našu pahulju krenemo crtati od piramide. Na svaku stranicu početne piramide

nacrtati ćemo novu umanjenu piramidu. Na svaku od nacrtanih piramida nacrtati ćemo po još

jednu piramidu, itd. Ovim postupkom dobiti ćemo Kochovu pahulju kao što je prikazana na

sljedećoj slici.

Page 51: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

47

Slika 31 Prvi način crtanja Kochove pahulje [3D Koch Snowflake, dostupno na:

http://blog.3dvision.com/2008/10/30/3d-koch-snowflake/]

Drugi način crtanja Kochove pahulje u 3D također kreće od piramide kao baze. No u ovom

slučaju pojedinu stranicu piramide ćemo podijeliti na 4 jednakostranična trokuta te na

srednjem izgraditi piramidu. U idućem koraku rekurzije to činimo za svaku stranicu trokuta

uključujući i novonastale trokute.

Slika 32 Drugi način crtanja Kochove pahulje [3D Koch snowflake, Dostupno na: https://encrypted-

tbn3.gstatic.com/images?q=tbn:ANd9GcT7GePIlCD-sSHFmcFl3OgYiojQo4rovsUVxT2YS7rEgozfG6AjUA]

S obzirom da nam drugi način crtanja je bio mnogo zanimljiviji od prvog odlučili smo se

implementirati drugi način. Uvidjeli smo da takvim crtanjem Kochove pahulje u 3D, gdje

pojedine stranice dijelimo na isti način kao što i crtamo Sierepinski trokut u 2D dobivamo

mnogo zanimljiviji i bogatiji oblik same pahulje. U nastavku ćemo razmotriti Android

Processing 2.0 kod naše implementacije Kochove pahulje.

Page 52: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

48

6.1. Analiza izvornog koda

U ovom potpoglavlju analizirati ćemo naš izvorni kod.

import processing.opengl.*;

PrintWriter logger;

float pisquared = TWO_PI;

PImage tex;

FraktalniTrokut koch[]=new FraktalniTrokut[4];

void init_koch(PVector a, PVector b, PVector c, PVector d, int

dubina_rekurzije) {

koch[0] = new FraktalniTrokut(a, b, c, dubina_rekurzije);

koch[1] = new FraktalniTrokut(a, d, b, dubina_rekurzije);

koch[2] = new FraktalniTrokut(a, c, d, dubina_rekurzije);

koch[3] = new FraktalniTrokut(b, d, c, dubina_rekurzije);

}

void setup() {

logger = createWriter("calculations.txt");

//stroke(0);

//strokeWeight(1);

size(displayWidth, displayHeight, OPENGL); // OPO velicina

noStroke();

//fill(150,150,150,20);

//textureMode(NORMALIZED);

Page 53: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

49

fill(255,0,0,120);

//noFill();

int tockaA = 200;

int dubina_rekurzije = 2;

PVector A = new PVector(-tockaA, 0, 0);

PVector B = new PVector(tockaA/2, 0, -175);

PVector C = new PVector(tockaA/2, 0, 175);

PVector D = new PVector(0, -tockaA * (sqrt(6) / 3), 0);

init_koch(

A, B, C, D,

dubina_rekurzije

);

}

void setup_camera() {

float tockaX=(mouseX / float(width)) * pisquared;

float pozicija_x=cos(tockaX);

float pozicija_y=sin(tockaX);

float radius=300.000;

camera(pozicija_x * radius, mouseY, pozicija_y*radius, // pogled

iz X, pogled iz Y, pogled iz Z

0.0, -50.0, 0.0, // center X osi, center Y osi, center Z

osi

0.0, -1.0, 0.0);

}

Page 54: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

50

void draw() {

background(mouseY * (255.0/600), 255, 0);

lights();

//setup_camera();

pushMatrix();

translate(displayWidth / 2, displayHeight / 2);

//translate(nf(ax, 1, 2), nf(ay, 1, 2));

rotateX(mouseY * 0.01);

rotateY(mouseX * 0.01);

print("Rotated X: " + mouseY * 0.01);

print("Rotated Y: " + mouseX * 0.01);

scale(1);

for (int i=0;i<koch.length;i++) {

koch[i].display();

}

popMatrix();

}

class FraktalniTrokut {

PVector PointA;

PVector PointB;

PVector PointC;

FraktalniTrokut podijeljeni_trokuti[] = new FraktalniTrokut[6];

int rec;

float skaliranje;

FraktalniTrokut(PVector A,PVector B,PVector C, int recursion){

skaliranje = 0.7;

PointA = A;

Page 55: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

51

PointB = B;

PointC = C;

rec = recursion;

rekurzija ();

}

void rekurzija () {

if (rec != 0) {

// racunamo 3 nova vektora koji dijele povrsinu

PVector PointAB2 = PVector.add(PointA,PointB);

PointAB2.div(2);

PVector PointAC2 = PVector.add(PointA,PointC);

PointAC2.div(2);

PVector PointBC2 = PVector.add(PointB,PointC);

PointBC2.div(2);

// racunamo sredisnju tocku na danom trokutu

PVector PointZ = PVector.add(PointA,PointB);

PointZ.add(PointC);

PointZ.div(3);

// racunamo vektor smjera normale u kojoj ce se spajati

trokuti

PVector PointAB = PVector.sub(PointA,PointB);

PVector PointAC = PVector.sub(PointA,PointC);

PVector PointH = PointAB.cross(PointAC);

PointH.normalize(); // normalizamo vektor na velicinu 1

// racunamo tocku u kojoj ce se spajati novi trokuti

PVector PointAAB2 = PVector.sub(PointA,PointAB2); // ovo je

polovica baznog vektora koji cini stranicu trokuta kojeg dijelimo

float a = PointAAB2.mag(); // racunamo velicinu tog vektora

Page 56: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

52

float pheight = a * (sqrt(8) / 3) * skaliranje; // racunamo

visinu za novu piramidu, te prilagodavamo visinu tako da novi

trokuti nebudu preveliki

PointH.mult(-pheight); // dizemo tocku sa povrsine u zrak

PVector PointZH = PVector.add(PointZ,PointH);

podijeljeni_trokuti[0] = new

FraktalniTrokut(PointA,PointAB2,PointAC2,rec-1); // crtamo trokut 1

podijeljeni_trokuti[1] = new

FraktalniTrokut(PointB,PointBC2,PointAB2,rec-1); // crtamo trokut 2

podijeljeni_trokuti[2] = new

FraktalniTrokut(PointC,PointAC2,PointBC2,rec-1); // crtamo trokut 3

podijeljeni_trokuti[3]=new

FraktalniTrokut(PointZH,PointAC2,PointAB2,rec-1); // crtamo trokut 4

podijeljeni_trokuti[4]=new

FraktalniTrokut(PointZH,PointAB2,PointBC2,rec-1); // crtamo trokut 5

podijeljeni_trokuti[5]=new

FraktalniTrokut(PointZH,PointBC2,PointAC2,rec-1); // crtamo trokut 6

}

}

void display () {

if (rec==0) {

beginShape();

texture(tex);

vertex(PointA.x, PointA.y ,PointA.z);

vertex(PointB.x, PointB.y ,PointB.z);

vertex(PointC.x, PointC.y ,PointC.z);

endShape(CLOSE);

} else {

for (int i=0; i<podijeljeni_trokuti.length;i++) {

Page 57: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

53

podijeljeni_trokuti[i].display();

}

}

}

}

6.2. Analiza različitih dubina rekurzije

Dubina rekurzije: 7

Page 58: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

54

Slika 33 Kochova Pahulja u 3D sa dubinom rekurzije 7

Dubina rekurzije: 6

Slika 34 Kochova Pahulja u 3D sa dubinom rekurzije 6

Dubina rekurzije: 5

Page 59: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

55

Slika 35 Kochova Pahulja u 3D sa dubinom rekurzije 5

Dubina rekurzije: 4

Slika 36 Kochova Pahulja u 3D sa dubinom rekurzije 4

Dubina rekurzije: 3

Page 60: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

56

Slika 37 Kochova Pahulja u 3D sa dubinom rekurzije 3

Dubina rekurzije: 2

Slika 38 Kochova Pahulja u 3D sa dubinom rekurzije 2

Page 61: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

57

7. Zaključak

U ovom seminarskom radu obrađivali smo u sklopu kolegija računalne grafike temu

pod nazivom fraktali. Tema je obrađena na dva načina. Prvi je s teorijskog stajališta općenito

o fraktalima kako bi ostale studente mogli upoznati i povezati s njihovim značenjem i

tematikom, a drugi je praktične prirode gdje smo analizirali - OpenGL ES iz dvije perspektive

– Java i Processing.

Fraktali predstavljaju u biti objekte koji daju jednaku razinu detalja neovisno o

razlučivosti koju koristimo, a njihova osnovna svojstva su samosličnost, fraktalna dimenzija i

oblikovanje iteracijom kao što smo i ranije naveli. Moguća je njihova podjela prema stupnju

samosličnosti i prema načinu nastanka.

Fraktalna umjetnost relativno je mlada u usporedbi s drugim umjetnostima, jer ne bi

mogla nastati bez uporabe računala, no fraktali su ipak s nama oduvijek. Najvjerovatnije se

upravo iz tih razloga ljudima i sviđaju. U njima pronalazimo nekakvu neobičnu ljepotu,

volimo gledati u njih, djeluju na nas umirujuće. Nalazimo ih posvuda u prirodi, pa i na nama

samima (ako malo bolje promotrimo ruku i šaku, vidjet ćemo da je svaki prst u omjerima

umanjena verzija ruke). Ljudi su ih intuitivno osjećali i prepoznavali kao načelo stvaranja

prirode, pa onda nije ni čudo da u povijesti umjetnosti nalazimo fraktale ne samo prije prvih

računala, nego i prije struje i parnoga stroja [Fraktali i umjetnost, Vesna Mišljenović, Zagreb

(2011./2012. br. 80), str. 224.]

Page 62: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

58

Literatura

1. Developers-Android, Displaying Graphics with OpenGL ES, dostupno na:

http://developer.android.com/training/graphics/opengl/index.html, 25.01.2015. ;

2. Fractal Noise, Neil Blevins, dostupno na:

http://www.neilblevins.com/cg_education/fractal_noise/fractal_noise.html, učitano:

17.01.2015. ;

3. Hrvatski matematički elektronski časopis math.e, Galerija fraktala, V. Antočić, A.

Galinović, dostupno na: http://e.math.hr/galerija/galerija_print.html, učitano:

17.01.2015. ;

4. Interaktivna računalna grafika kroz primjere u OpenGL-u, M.Čupić, Ž.Mihajlović,

dostupno na: http://www.zemris.fer.hr/predmeti/irg/knjiga.pdf, učitano: 17.01.2015. ;

5. M. Pašić, Uvod u matematičku teoriju kaosa za inženjere, Skripta FER, Zagreb, 2005.

(57.-83.) ;

6. Neverinov blog, dostupno na:

http://blog.dnevnik.hr/blogodneverina/2010/02/1627237517/fasciniranost-

fraktalima.html, učitano: 17.01.2015. ;

7. Processing for Android, dostupno na: http://processing.flosscience.com/processing-

for-android, 25.01.2015. ;

8. Processing/processing-android, Joel Moniz, dostupno na:

https://github.com/processing/processing-android/wiki, 25.01.2015. ;

9. Processing & Android: Mobile app development made (very) easy, dostupno na:

http://blog.blprnt.com/blog/blprnt/processing-android-mobile-app-development-made-

very-easy, 25.01.2015.

10. Pythagoras Tree, dostupno na:

http://www.phidelity.com/blog/phidelity/blog/fractal/pythagoras-tree/, učitano:

17.01.2015. ;

11. Shane Bow The Chaos of Mandelbrot, dostupno na:

http://shanebow.com/projects/mandelbrot/, učitano: 17.01.2015. ;

12. Silvergreen, Deviant art, dostupno na: http://silvergreen.deviantart.com/art/Fractal-

Tree-1646228, učitano: 17.01.2015. ;

Page 63: OPENGL ES: 3D FRAKTALI - rg.c-hip.netrg.c-hip.net/2014/seminari/bartosek-picek/Bartosek-Picek-seminar.pdf · 2 2.Povijest fraktala Kao što smo u uvodu naveli, fraktali koje stvara

59

13. Uvod u fraktale, M.Paušić, dostupno na:

http://www.fer.unizg.hr/_download/repository/Uvod%20U%20Fraktale%20by%20Ml

aden%20Pausic.pdf, učitano: 17.01.2015. ;

14. Uvod u matematičke metode u inženjerstvu, K. Brdar, M. Dobrinić, R. Joksić,

Fraktali, dostupno na:

http://matematika.fkit.hr/novo/izborni/referati/dobrinic_joskic_brdar_fraktali.pdf,

17.01.2015. ;