Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Kako koristiti GLScene

[es] :: Pascal / Delphi / Kylix :: Kako koristiti GLScene
(TOP topic, by morlic)
Strane: 1 2 3 4

[ Pregleda: 36097 | Odgovora: 73 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Kako koristiti GLScene28.05.2005. u 18:47 - pre 195 meseci
GLScene je 3D engine za Delphi zasnovan na OpenGLu. Sa njim je moguce vrlo brzo kreirati zanmljive 3D scene, aplikacije, igre... U sebi trenutno sadrzi 3D, script, physic i sound engine... takodje sadrzi rutine za lak rad sa misem, dzojstikom, tastaturom sto ga cini vrlo dobrim alatom za pravljenje igara u Delphiu.
Hompage: http://glscene.sourceforge.net/index.php

Najnoviju verziju mozete skinuti uz pomoc TortoiseCVS. To je program koji radi preko CVS protokola. Mozete ga skinuti sa http://www.tortoisecvs.org/index.shtml , a uputstvo za skidanje GLScene (CVS) mozete pronaci na http://sourceforge.net/cvs/?group_id=29749

Prilikom instalacije bitno je da u Delphi IDE dodate putanje do svih foldera u kojima se nalaze source fajlovi GLScene u Library path inace necete biti u mogucnosti da ih koristite. Kad to uradite u foderu DelphiX (gde je X verzija vaseg Delphia) cete naci pakete komponenti:

GLScene - komponente za rad sa 3D objektima
GLCg - komponente za rad sa Cg shaderima (morate imati instaliran NVidia Cg toolkit da bi mogli da instalirate ove komponente)*
GLSDL - rad sa SDL engineom (ova komponenta nije potrebna za rad sa GLScene i ja je licno nikad nisam koristio)*
GLSS_BASS - sound library BASS*
GLSS_FMOD - sound library FMOD*
GLS_ODE - physic engine ODE*
GLS_DWS - script engine Delph Web Script*
GLS_Python - script engine Python*

* Da bi ove komponente radile morate instalirati druge pakete. SDL, ODE, BASS, FMOD idu zajedno sa GLScene fajlovima. To su obicni Dll fajlovi koje je samo potrebno kopirati u Windows\System32 folder i to je to. DWS mozete skinuti sa http://www.dwscript.com/ Za Python jos ne znam gde mogu da ga pronadjem, ali se bez te komponente moze jer imate DWS Za detaljnija uputstva o instalaciji pogledajte homepage GLScene.

Kada je instalacija zavrsena dolazi na red i probanje komponenti (moj omiljeni deo ). Za pocetak cemo napraviti jednu loptu, svetlo i kameru koja gleda u loptu.
Prvo cemo komponentu GLScene sa GLScene grupe da postavimo na formu. Ta komponenta ce nam sluziti za kreiranje scene. Sledeca je na redu komponenta GLSceneViewer. Ona je zaduzena za iscrtavanje scene na nasoj formi. Ove dve komponente su skoro uvek obavezne. Sada postavimo GLSceneViewer1.Align na alClient tako da se GLSceneViewer1 rasiri preko cele forme.
Sada kliknite dva puta na GLScene komponentu (ili desni klik pa Show Scene Editor) i tako cete otviriti editor scene



Ovde cemo dodavati nase objekte.
Prvo sto cemo dodati je kamera. Desnim klikom na Cameras u Scene Editoru otvorice nam meni i tu kliknemo na Add camera. Kamera je dodata sada nam samo jos preostaje da u GLSceneVieweru postavimo Camera proerty na kameru koju smo sada kreirali. Klik na GLSceneViewer (nalazi se preko cele forme) i u Object Inspectoru pronadjemo property Camera i vrednost postavimo na GLCamera1. Ako ne postavimo kameru tada se na GLSceneVieweru nece nista videti pa... cim kreirate kameru odmah je postavide ovde
Sada dodajemo i nasu lopticu... desni klik na Scene Objects u Scene Editoru, zatim Add Object->Basic Geometry->Sphere. Lopta je dodata, ali se ne vidi!? Problem je sto se i lopta i kamera nalaze na koordinatama 0,0,0 pa kamera ne moze da vidi loptu. Sada cemo pomeriti loptu ispred kamere tako sto cemo postaviti Position property lopte na 0,0,-3. Sada se lopta vec vidi Primecujete da je lopta crna...



To je zato sto nismo nigde postavili svetlo! Da bi i to resili dodacemo i jedan izvor svetla. Desni na Scene Objects pa izaberite LightSource. Cim smo dodali svetlo lopta je osvetljena Po defaultu novo kreirani objekti su sivi i zbog toga je lopta siva.



To je u sustini princip rada GLScene... dakle dodajemo objekte u Scene Editoru, podesavamo im poziciju, velicinu, boju...
Kasnije cemo uraditi i primere u kojima cemo pomerati objekte po sceni, dodavati evekte, itd...
Za sad eksperimentisite malo sa osnovinm stvarima
Srecno!!!
Prikačeni fajlovi
 
Odgovor na temu

Bojan Kopanja
Bojan Kopanja
Senior Web Developer, ZeusSoftware
Stara Pazova

Član broj: 6155
Poruke: 507
80.93.238.*

ICQ: 346697685
Sajt: www.zeussoftware.rs


Profil

icon Re: Kako koristiti GLScene28.05.2005. u 19:38 - pre 195 meseci
Srki genije, pa ti si Bog! Samo nastavi ovako, mocna stvar! Svaka cast!
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene28.05.2005. u 20:02 - pre 195 meseci
Hvala
Imam osecaj da ce na kraju neko sve ovo bolje skapirati pa ce mene na kraju uciti
Sledeci primer ce pokazati kako je moguce hijerarhijski povezati objekte. Npr. kocka je parent lopti. Tada pozicija lopte pokazuje poziciju u odnosu na kocku tako da ako pomeramo kocku, a poziciju lopte ne diramo i lopta ce se kretati... mozda je sad malo nejasno, ali kad pudem napisao primer sve ce se razjasniti
Nadam se da ce vam se svideti tutorial.
Ako neko ima problema sa skidanjem i instaliranjem GLScene neka pita pa cu i taj deo malo bolje objasniti.
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 01:41 - pre 195 meseci
Hello!!!
Kao sto rekoh sada cemo uraditi jos jedan jednostavan primer. I ovog puta pocinjemo stavljanjem GLScene i GLSceneViewer komponenti na formu. Sledece je na redu dodavanje kamere i postavljanje Camera property GLSceneViewera na nasu novo kreiranu kameru. Dodacemo i jedno svetlo kao u proslom primeru. Sledece na redu je dodavanje kocke. Kocka se dodaje kao i lopta. U Scene Editoru desni klik na Scene Objects->Add Object->Basic Geometry->Cube. Postavicemo poziciju kocke na 0, 0, -4. Sada cemo dodati i jednu loptu i nju postaviti na 0, 1.5, -4 tako da ce se videti iznad kocke kao na slici



Trenutno kocka i lopta nisu povezani... to cemo prikazati uskoro. Pre nego sto pocnemo da pomeramo objekte po sceni dodacemo jos jednu komponentu. Komponente se zove GLCadencer i nalazi se u GLScene grupi. Ova komponenta ima event koji se poziva prilikom svakog renderovanja. Znaci pre nego sto se scena iscrta izvrsi se nas event i tako svaki put. Sto se scena brze iscrtava to se nas event brze poziva. Tako cemo na brzim racunarima dobiti lepu, glatku animaciju, a na losijim nece sve biti usporeno nego ce jednostavno neki delovi animacije biti "preskoceni" (seckanje). Ova komponenta ima jedan lep property koji se zove Mode. Taj proerty odredjuje kad ce se nas event pozivati. Po defaultu stoji na ASAP (as soon as possible) sto nam daje najveci frame-rate, ali i 100% zuzeca procesora, zatim imamo ApplicationIdle i u tom modu se event pokrece samo kada aplikacija nema vise window poruka da obradjuje sto malo smanjuje frame-rate, ali i smanjuje opterecenje procesora. Na kraju imamo mod Manual i u tom modu GLCadencer nece pozivati event sve dok mi samo ne pozovemo GLCadencer.Progress. Ako neko bas jako zeli da sto manje opterecuje procesor postoji i property SleepLength. Dovoljno je postaviti ga na 1 i procenat zauzeca procesora ce drasticno pasti. Kada je SleepLength <> -1 tada GLCadencer u svojoj petlji poziva Sleep(SleepLength) cime prekida rad programa na odredjen broj milisekundi. Ja licno volim da imam sto vise frejmova u sekundi pa su mi default vrednosti sasvim ok.
Znaci postavili smo GLCadencer na formu i pre nego sto mozemo da ga koristimo treba da podesimo Scene property. Taj property odredjuje scenu za koju je nas GLCadencer zaduzen. Postavicemo ga na GLScene1. Sada nam ostaje da namisemo proceduru za OnProgress event.
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
var
  X: Single;
begin
  X := Sin(newTime) * 2;
  GLCube1.Position.SetPoint(X, 0, -4);
end;

OnProgress event nam osim standardnog Sender (ko je pozvao event) daje jos dva podatka, deltaTime i newTime. DeltaTime je vreme u sekundama izmedju proslog poziva OnProgress eventa i trenutnog, a NewTime je vreme u sekundama od prvog do trenutnog poziva ovog eventa ili jednostavno receno od kad je GLCadencer.Enabled postavljen na True do sad. U nasem slucaju pomeracemo kocku po X osi po obicnoj sinusnoj funkiciji u zavisnosti od vremena koliko je GLCadencer aktivan.
Sada pokrenite program i videcete kako kocka klizi levo desno dok lopta stoji nepomicna. Sada cemo postaviti loptu tako da bude joj pozicija zavisi od pozicije koscke. Otvorite Scene Editor, kliknite na loptu i prevucite je preko kocke. Trebalo bi da ih postavite ovako



Kad ste to uradili lopta se odjednom pomerila u nazad iako nismo menjali njenu poziciju.



To je zato sto sada property Position za loptu predstavlja poziciju lopte u odnosu na kocku. Posto se kocka nalazi na 0, 0, -4, a koordinate lopte u odnosu na kocku su 0, 0, -4 to nam govori da se lopta sada nalazi na 0, 0, -8 (pozicija kocke + pozicija lopte). Ako sada pokrenemo program videcemo da se i kocka i lopta pokrecu iako menjamo poziciju samo kocke. Ovo je vrlo korisno znati koristiti pa eksperimentisite malo

Toliko za danas!
Prikačeni fajlovi
 
Odgovor na temu

Nemanja Avramović
Software architect
Tap medical
Beograd, Srbija

Član broj: 32202
Poruke: 4383
*.yu1.net.

Sajt: https://avramovic.info


+45 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 08:29 - pre 195 meseci
brate prosao sam kroz obe lekcije i vec sam poceo da kontam nesto.. samo tako nastavi!
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 12:29 - pre 195 meseci
Do sad su svi objekti koje smo kreirali bili sivi... sada cemo malo da im menjamo boje
Pocinjemo kao i uvek... GLScene, GLSceneViewer, Camera, LightSource (secate se da je objekat bio skroz crn bez svetla... zato nam je vrlo bitno da imamo svetlo na sceni ako hocemo da vidimo boje) i jedna lopta na koordinatama 0, 0, -4. Sad imamo scenu kao u prvom primeru (mnogo brze i lakse nego na pocetku, zar ne ).
Svaki objekat ima 4 vrste boje: Ambient, Diffuse, Emission i Specular.
Ambient i Diffuse se najcesce koriste. Kada postavimo svetlo na scenu ono svetli odredjenom bojom (koju mi definisemo).
Ambient vrednost je boja svetla koje se nalazi na celoj sceni... nije bitno da li je objekat obasjan izvorom svetlosti, da li je preblizu ili predaleko... ako je Ambient boja podesena na zeleno tada je cela scena obasjana zelenom bojom.
Diffuse svetlost je slicna kao Ambient samo sto zavisi od vrste svetlosnog izvora. Mi smo uvek samo postavljali LightSource bez promene parametara. Po defaultu svetlo je tipa Spot. Takvo svetlo je kao baterijska lampa... svetli u odredjenom smeru i sve sto je iza nje ili previse sa strane nije osvetljeno. Postoje jos dva tipa svetla. Omni... to je kao luster... svetli suda oko sebe... nema neki odredjen pravac. Parallel... hmmm... to je kao svetlost sa sunca... dolazi iz velike daljine i pod odredjenim uglom pada na sve objekte. Pravac i smer kod Parallel i Spot tipova svetla se definise u SpotDirection property.
Emission je boja svetlosti koja isijava iz objekta. Kad imate beli luster sa crvenom lampom i onda se vidi kao da je je i luster crven.
Specular je boja odsjaja na objektu. Kada je recimo bilijarska kugla jako izglancana onda se na njoj vidi odsjaj svetla.
Svi ovi svetlosni efekti mogu da se koriste zajedno. Jedino emission boja ne zavisi od izvora svetla dok sve ostale boje zavise. Ako je recimo diffuse boja svetla cisto crvena, a diffuse boja objekta cisto plava objekat ce izgledati crn jer nema ni mali delic svetla plave boje. Takva je situacija i sa ambient i specular bojama. Mozda sada sve zvuci malo konfuzno, ali ako budete malo ekperimentisali sa bojama sve ce vam biti jasno.
Jos jedna stvar... ambient i diffuse boja se u 99.99% slucajeva postavljaju na istu boju jer obe boje predstavljaju boju materijala objekta. Ambient vrednost svetla se postavi na neku tamno sivu tako da i ako svetlo nije upereno u objekat njegova boja se ipak malo nazire, a diffuse boja svetla se postavlja na cisto belu i objekti direktno ispred svetla se vide u svojoj prirodnoj boji.
Dosta pricanja... hajde da ofarbamo nasu lopticu
Posto nismo menjali poziciju svetla ono se nalazi na 0, 0, 0, a njen pravac koji takodje nismo dirali je 0, 0, -1. Posto se nas objekat nalazi na 0, 0, -4 on se nalazi ispred svetla i zato je obasjan. Hajde da mu promenimo boju u plavo.
Boja (i neke druge stvari) se definisu u Material property. Kliknite na '...' i otvorice se material editor.



Ovde imam dosta opcija. Na vrhu mozemo da biramo da li cemo podesavati boju za prednju stranu poligona ili za zadnju (uglavnom se zadnja strana poligona ne prikazuje pa nije ni bitno sta cete tu podesiti) i mozemo podesavati texturu za objekat. Texture cemo ostaviti za kasnije. Vidimo skale za podesavanje boja i uz pomoc njih cemo naterati nasu loptu da poplavi Imamo opciju da izaberemo kako ce se nas objekat iscrtavati (polygon mode). Po defaultu objekat se iscrtava kao puno telo, ali mozemo podesiti da se iscrtavaju samo ivice ili samo tacke koje definisu ivice (probajte sva tri moda i bice vam jasno sta koji radi). Zatim imamo Shininess klizac... ta osobina odredjuje koliko je objekad "izglancan" i koliki ce biti odsjaj specular boje. Poslednja opcija koja odredju kako ce objekat biti iscrtan je Blending mode... ako je mod postavljen na Opaque tada se objekat iscrtava svojom bojom i to je to. Ako je podesen na Transparency tada Alpha vrednost boja utice na providnost objekta, sto je Alpha manje to je objekat providniji. Additive mod iscrtava objekat tako sto se bojama objekta dodaju boje objekata koji su iza njega... ovaj mod morate isprobati da bi vam bilo malo jasnije sta se tu tacno desava.
Za sad hajde da podesimo ambient i diffuse boje objekta (front) na plavo. Kada kliknemo na Ok primeticete da se lopta obojila u plavo.



Vrlo jednostavno
Hajde da dodamo i emission i specular boje. Postavimo emission green komponentu na 200. Sada ce nas plavi objekat izgledati kao da nesto zeleno svetli iz njega. Sad cemo jos i da mu nabacimo crvenu "tufnu". Specular boju postavimo na cisto crvenu i da se lopta ne bi bas jako sjajila postavimo Shininess na 5. Kliknimo Ok i nasa lopta vise nije samo plava... Sva je nekako cudna



Experimentisite malo s bojama. Probajte da postavite neki drugi blending mode i da menjate alpha vrednost.
U sledecem primeru cemo pokazati kako se lako textura postavlja na objekat kao i koriscenje Material Library komponente.
Prikačeni fajlovi
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 15:10 - pre 195 meseci
Uglavnom nije bas najbolja ideja da se za za svaki objekat materijal (boja) postavlja kao sto sam objasnio u proslom primeru. Kada bi imali 1000 lopti koje treba da budu plave i ako bi za svaku postavili boju kao sto sam prosli put objasnio GLScene bi napravio 1000 materiala (za svaki objekat po jedan) koji su prakticno isti i prolikom renderovanja objekata bi svaki put menjao 1, 2, 3,... 1000 materijal bez potrebe sto bi dovelo do vrlo velikog usporenja programa. Da bi se to izbeglo postoji komponenta GLMaterialLibrary. Ona je vrlo korisna jer je u njoj moguce definisati JEDAN material koji ce posle koristiti neogranicen broj objekata. Nekom ce mozda ovo biti bezveze jer ako se promeni taj material svi objekti koji ga koriste ce takodje biti promenjeni, a nekom ce to biti prednost jer nece morati da menja boje svakom objektu posebno. Ovog puta cemo koristiti Material Library i necemo samo postavljati boju za objekte nego i texturu. Textura je slika koje je "nalepljena" na objekat da bi izgledao kao da je od drveta, plastike, metala ili nekog drugog materijala.
Za pocetak postavimo na formu GLScene, GLSceneViewer, GLCadencer i GLMaterialLibrary. Postavimo u sceni kameru (0, 0, 0), svetlo (0, 0, 0) i dve lopte (2, 0, -5) i (-2, 0, -5) ove lopte ce nam sluziti kao modeli. Ne zaboravite da GLSceneViewer1.Camera postavite na kameru koju smo kreirali i GLCadencer.Scene na GLScene1 (ovo vise necu da spominjem).
MaterialLibrary ima dva propertya koja su nam zanimljiva... to su Material i TextrePaths. TexturePaths su putanje po kojima ce MaterialLibrary traziti slike ako napisete naziv fajla bez putanje (npr. "Slika.jpg"). Property Material sadrzi sve materiale koji su kreirani. Hajde da kreiramo jedan material. Kliknite na '...' u Material property i otvorice vam se mali prozorcic u kojem mozete dodavati i brisati materiale.



Dodajmo jedan material pritiskom na Add New dugme. Sada u Object Inspectoru vidimo osobine materiala koji smo kreirali. Imammo Material (isto kao i Material property kod objekata... tu cemo definisati izgled materiala), Name (naziv materiala... uvek je dobra ideja da nazovete material kako bi kasnije mogli lakse da ga pronadjete), Shader (ovde mozemo definisati mali programcic kojice iscrtavati material... primeri su BumpShader (povrsina izgleda rapavo), CelShader (izgleda kao crtani film)...), Texture2Name (moguce je dve texture stopiti u jednu i time dobiti neki novi izgled... ovde se daje ime drugog materiala koji ce se koristiti za stapanje sa ovim), TextureOffset (ako je textura velika ili ako ne zelimo da uzmemo sliku od pocetka texture ovde mozemo podesiti koliko ce textura na materialu biti pomerena u odnosu na pravu texturu), TextureScale (ako zelimo da se textura ponovi vise puta na objektu ovde to definisemo).
Hajde da podesimo material i dodamo texturu. Klik na '...' u Material property. Otvara nam se vec poznat prozor



Postavimo Ambient i Diffuse boju na cisto belo i kliknimo na Texture kako bi smo dodali sliku. Sada na vidimo sledece:



Sada mozemo da izaberemo sliku koja ce biti na objektu... to radimo uz pomoc Image opcije. Izabracemo ovu sliku



http://www.geocities.com/srki_82/Tutorial/GLScene/Tut4Pic3.JPG

Ako se nekom vise svidja neka druga slobodno moze da je izabere.
Od opcija su nam na raspolaganju sledece stvari... ImageAlpha... svaka slika moze u sebi da sadrzi i alpha kanal cime odredjuje providnost objekta na koji je postavljena. Ako je ImageAlpha na Default koristi se alpha kanal iz slike. Ako je podesen na AlphaFromIntensity ili Luminance sto je slika svetlija manje se providi, a ako je postavljen na SuperBlackTransparency tada su sve crne povrsine providne.
Sledece opcije su Min i Mag filteri. GLScene kreira manje ili vece slicice od one koje smo mi dali ako je objekat mnogo manji ili veci od njenih dimenzija. Nacin na koji skuplja i siri sliku zavisi od ovih opcija. Uvek sam bio zadovoljan default vrednostima pa nisam mnogo zalazio u ostale mogucnosti, ali ako neko vidi da mu se textura mnogo zamuti moze da proba da postavi druge vrednosti.
Sledeca opcija nam je Texture Mode... ona odredjuje kako ce textura da se "stopi" sa bojama materijala. Decal i Replace jednostavno zanemaruju boju objekta i iscrtavaju samo texturu. Modulate promeni boju texture tako da "vuce" na boju koju smo definisali dok Blend racuna srednju vrednost izmedju definisane boje i boje texture. Mi cemo postaviti Texture mode na Modulate. Texture Warp odredjuje da li ce textura da se ponavlja ako je potrebno da prekrije ceo objekat (u obcijama moze da se izabere da li i u kojim pravcima da se dozvoli ponavljanje... po defaultu je da moze u svim pravcima).
Na kraju imamo checkbox Disabled koji odredjuje da li da se textura uopste vidi. Iskljucite taj checkbox i u preview cete videti nasu texturu
Kliknite na Ok. Jos jedna sitnica... u Name property upisacemo "Drvo". Eto... zavrsili smo nas material... sad da ga postavimo na loptice



Kao sto vidite... kliknite na mali plus pored Material property za loptu i u MaterialLibrary izaberite GLMaterialLibrary1 (komponenta koju smo stavili na formu i u kojoj su nasi materiajli). Zatim kliknite na '...' u LibMaterialName property i izaberite material "Drvo" i loptica vec lepse izgleda Sad to isto uradite i za drugu loptu.
Jedna vrlo bitna stvar!!!
Pre nego sto pokrenete program morate u Uses listu dodati unite koji omogucavaju ucitavanje slika koje smo koristili za texture. Za BMP slike nema potrebe nista da se dodaje dok za JPG treba da se doda JPEG unit, za TGA treba TGA unit...

Kada smo dodali JPEG u uses pokrecemo program i vidimo loptice



Da bi smo dokazali da obe lopte koriste isti material malo cemo se poigrati s njim. U GLCadencer cemo postaviti OnProgress event na
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
var
  C: Single;
begin
  C := Sin(newTime) * 0.5 + 0.5;
  with GLMaterialLibrary1.LibMaterialByName('Drvo') do
  begin
    Material.FrontProperties.Ambient.Red := C;
    Material.FrontProperties.Diffuse.Red := C;
    TextureScale.SetPoint(C, C, C);
  end;
end;

Kao sto vidite menjamo material u MaterialLibrary i obe lopte menjaju svoju boju
Toliko za sada... ako budem imao vremena mozda napisem jos nesto za sad.
Vi slobodno experimentisite i posaljite kod ako napravite neki zanimljiv primer!
Poz!!!
Prikačeni fajlovi
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 17:37 - pre 195 meseci
Mogli bi smo umesto kocki i lopti da koristimo neki 3D model... bilo bi stvarno bezveze kad bi bili ograniceni samo na osnovne oblike. Ovog puta cemo napraviti mali programcic za pregled 3DS fajlova. 3DS su fajlovi koje pravi 3D Studio... oni u sebi sadrze podatke o izgledu objekta i podatke o materijalima. Sa GLScene je vrlo lako ucitavati 3D modele... GLScene ima podrsku za razne fajlove kao sto su 3DS, Quake 2 i 3 modele, HalfLife modele, OBJ fajlove, Quake nivoe... pa da pocnemo
Pacicemo na formu GLScene, GLSceneViewer, GLMaterialLibrary (ovde ce se ucitati materiali za 3d objekat), MainMenu (za meni za ucitavanje fajla) i OpenDialog. Na scenu cemo postaviti sledece stavke: kameru i svetlo (svetlo prevucite tako da mu kamera bude parent i da pozicija svetla zavisi od pozicije kamere... gde god da se nalazi kamera i svetlo ce ici za njom) i jedan FreeForm (Screen Objects->Add Object->Mesh Objects->FreeForm). FreeForm je objekat u koji ce biti ucitan nas 3DS fajl. Da bi GLScene znao gde da stavi materijale vezane za FreeForm moramo FreeForm.MaterialLibrary postaviti na GLMaterialLibrary1 koji smo vec stavili na formu. Jos malo i zavrsili smo. Postavicemo kameru na 0, 0, 200, a FreeForm ostaviti na 0, 0, 0. Uradicemo nesto sto nismo radili do sad... postavicemo GLCamera.TargetObject property na FreeForm1 sto ce naterati kameru da bude uvek okrenuta prema FreeForm objektu. Tako mozemo pomerati i FreeForm i kameru bez bojazni da cemo izgubiti objekat iz vida. Sada nista ne vidimo na formi jer 3DS fajl mozemo da ucitamo samo u runtimeu i zato cemo napraviti funkciju za ucitavanje. U MainMenu dodajte sledece stavke
Load 3DS file
-
Exit
Za Exit postavite da izadje iz programa (Application.Terminate), a za Load 3DS file napisite sledece
Code:
procedure TForm1.Load3DS1Click(Sender: TObject);
var
  S: Single;
begin
  if OpenDialog1.Execute then
  begin
    GLMaterialLibrary1.Materials.Clear;
    GLFreeForm1.LoadFromFile(OpenDialog1.FileName);
    S := 100 / GLFreeForm1.BoundingSphereRadiusUnscaled;
    GLFreeForm1.Scale.SetVector(S, S, S);
    GLFreeForm1.ResetRotations;
  end;
end;

Kao sto vidite nema puno koda, a ovo radi ceo posao oko ucitavanja 3DS fajla
Prvo sto uradimo je praznjenje GLMaterialLibrarya jer je moguce da smo pre ovog vec ucitali neki objekat i ne bi zeleli da nam u ostanu stari materiali. Sledeca stvar koju radimo je ucitavanje fajla. Za to nam je potrebaj samo jedan red GLFreeForm1.LoadFromFile(OpenDialog1.FileName);. GLScene je toliko dobar da skoro sve uradi umesto nas. Posle ovog poziva u FreeForm se nalazi nas 3D objekat. Posto objekat moze da bude ogroman ili previse mali sledeca stvar koju radimo je postavljanje odgovarajuce velicine. GLFreeForm1.BoundingSphereRadiusUnscaled nam daje precnik lopte koja okruzuje ceo objekat i na osnovu nje cemo podesiti velicinu objekta da moze da stane u loptu precnika 100. Kamera ima DephOfView property. On odredjuje koliko daleko kamera moze da vidi. Po defaultu vrednost je 100, ali posto ce kraj naseg objekta biti dalje od 100 od nase kamere moracemo da povecamo ovu vrednost kako bi sve lepo videli. Stavicemo vrednost na 1000. Kada smo postavili odgovarajucu velicinu objekta ostaje nam jos samo da vratimo osnovni polozaj objekta (kasnije u kodu cemo moci da ga rotiramo). I to je to... u par redova koda mozemo da ucitamo bilo koji 3DS fajl.I jos jednom da napomenem... ako 3d objekat koristi neke slike osim BMP za texture moramo dodati unite koji ce "objasniti" Delphiu kako da ih ucita.



Sad nam ostaje jos da sredimo rotiranje objekta... to se takodje vrlo lako radi. Bice nam potrebne 2 globalne promenljive mX i mY pa ih dodajte. Obe su tipa Integer. U OnMouseMove eventu GLSceneViewera napisite sledece
Code:
procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  if ssLeft in Shift then
    GLCamera1.RotateObject(GLFreeForm1, mY - Y, mX - X);
  mY := Y;
  mX := X;
end;

Zajedno sa kodom saljem i jedam mali 3DS fajl kako bi mogli da isprobate program. To je jedan cup... i primeticete da ima delova koji se "provide" bez razloga. To je zato sto u te "providne" delove gledamo s "pogresne strane". Secate se da smo mogli da zadajemo boje za Front i Back u Material Editoru... e pa ovi delovi koji se ne vide se ne vide zato sto ih gledamo sa Back strane. Po defaultu GLSceneViewer uopste ne prikazuje te Back strane. Da bi smo ga "naterali" da ih prikazuje moramo GLSceneViewer.Buffer.FaceCulling postaviti na False. Ako sada pokrenemo program videcemo da se sve lepo vidi
To je sve... mX i mY pamte poslednju poziciju misa kako bi znali za koliko treba da rotiramo objekat, a RotateObject sredjuje rotaciju. Prilicno jednostavno
Eto... u par linija koda imamo jednostavan viewer za 3ds fajlove. Sad vec znate mnogo vise nego sto sam ja znao kad sam poceo da radim sa GLScene
Pa... sta bi voleli da naucite sledece?
Prikačeni fajlovi
 
Odgovor na temu

Bojan Kopanja
Bojan Kopanja
Senior Web Developer, ZeusSoftware
Stara Pazova

Član broj: 6155
Poruke: 507
80.93.238.*

ICQ: 346697685
Sajt: www.zeussoftware.rs


Profil

icon Re: Kako koristiti GLScene29.05.2005. u 22:16 - pre 195 meseci
E, ovo stvarno mocno napreduje i valja nam samo tako, pa bi valjalo i temu staviti kao top, da se ne trazi po celom forumu!

Svaka cast (j)opet Srki, odlicni tutorial-i!
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene29.05.2005. u 22:53 - pre 195 meseci
Drago mi je da ti se svidjaju. Nadam se samo da ne idem previse brzo ili mozda nejasno. Voleo bih da procitam komentare (dobre, lose, bilo kakve) da znam da li sam krenuo u dobrom pravcu i sta bi sve hteli da objasnim (da ne bih preskocio nesto).
Sledeci tutorial ce biti kretanje objekata i Keyboard unit koji olaksava rad sa tastaturom. Bice vrlo jednostavno... lopta ce se kretati po ravnoj povrsini, a kontrole ce biti kao u FPS (Quake, CS, MOH...). Nadam se da ce vam se dopasti... ne ocekujte nista pre 20h jer se sutra radi
 
Odgovor na temu

staleks
Aleksandar Stoisavljevic
Java Technical Team Leader
Novi Sad

Član broj: 10869
Poruke: 59
*.neobee.net.

Sajt: www.staleksit.in.rs


+1 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 00:15 - pre 195 meseci
stvarno dobar tutorial, nemam reci, pogotovo zato sto mi je dosadno da citam na engleskom na www.nehe.com sajtu.

Znaci Srki majstore samo nastavi, dobices sigurno jos poklonika

Pozdrav
 
Odgovor na temu

Nemanja Avramović
Software architect
Tap medical
Beograd, Srbija

Član broj: 32202
Poruke: 4383
*.yu1.net.

Sajt: https://avramovic.info


+45 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 08:39 - pre 195 meseci
e extra je, samo malo uspori, ok...? imam i ja obaweze, pogotovo sad!

Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
 
Odgovor na temu

Nemanja Avramović
Software architect
Tap medical
Beograd, Srbija

Član broj: 32202
Poruke: 4383
*.yu1.net.

Sajt: https://avramovic.info


+45 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 11:19 - pre 195 meseci
evo prosao sam i ja kroz ove tri lekcije

sledece?
npr. 1) interakcija objekata iz engine-a sa mishem
2) josh malo rad sa 3d modelima, ucitavanje eksternih tekstura na modele (ili u mat. library) itd itd...

Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 18:00 - pre 195 meseci
Ovog puta cemo raditi sa jednim objektom koji se zove GLProxyObject, koristicemo mis da izaberemo neki 3D objekat na sceni i prikazacemo informaciju o broju frejmova u sekundi za nasu scenu. Krecemo standardno... GLScene, GLSceneViewer, kamera i svetlo. Dodacemo i jednu TTimer komponentu na formu koja ce svake sekunde da procita FPS. Funkcija GLSceneViewer.FramesPerSecond ce nam dati trazenu informaciju. OnTimer event cemo napisati ovako
Code:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
   Caption:=Format('%.2f FPS', [GLSceneViewer1.FramesPerSecond]);
   GLSceneViewer1.ResetPerformanceMonitor;
end;

Komanda Format se koristi za formiranje stringova i standardni je deo Delphia. "%.2f" znaci da podatak koji joj dajemo hocemo da nam ispise kao broj sa dve decimale. Ovim cemo postaviti naziv prozora na nesto nalik "123.45 FPS". Funkcija GLSceneViewer.ResetPerformanceMonitor sluzi da GLSceneViewer ponovo pocne sa racunanjem FPS iz pocetka. Npr... ako 10 minuta imamo 1000.00 FPS i onda nam na desetak sekundi FPS padne na 1 ako ne uradimo ResetPerformanceMonitor necemo ti znati jer ce FramesPerSecond funkcija da racuna ukupan broj frejmova podeljeno sa vremenom (10 min + par sekindi). Zato je vrlo bitno pozvati ResetPerformanceMonitor ako zelimo tacne rezultate. Sad kad smo to napravili mozemo pokrenuti program da vidimo rezultate. I... rezultat i nije bas ocekivan zar ne Na prozoru pise 0.00 FPS. To je zato sto je scena iscrtana jednom i nema vise potrebe da se iscrtava ponovo i da GLScene ne bi trosio bezveze procesorsko vreme iscrtavajuci jednu istu sliku GLSceneViewer je jednostavni vise ni ne crta. Prvo ponovno crtanje ce se desiti samo kada jedan deo GLSceneViewera bude zaklonjen pa ponovo otrkiven ili mu velicina bude promenjena. Da bi smo naterali GLSceneViewer da iscrtava bice nam potreban GLCadencer. OnProgress event cemo napisati ovako
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
   GLSceneViewer1.Invalidate;
end;

GLSceneViewer.Invalidate jednostavno kaze da je potrebno iscrtati sliku iz pocetka, a posto se OnProgress event poziva prilikom crtanja svakog frejma znaci da ce se nova slika iscrtati sto je pre moguce. Ako sad pokrenemo program videcemo prave rezultate FPS bi trebalo da je prilicno velik posto na sceni nema nista. Zbog ovako cestog iscrtavanja slike procesor je iskoristen 100%. Ako nam je bitno da procesor sto vise oslobodimo dovoljno je da GLCadencer.SleepLength postavimo na 1. To ce dovesti do prilicnog pada broja frejmova u sekundi, ali ce se iskoristenje procesora drasticno smanjiti.
To bi bio deo vezan za FPS i procesorsko vreme.
Sada cemo da pobacamo nekoliko objekata na scenu. Dodacemo GLCube, GLFrustrum, GLSphere i GLIcosahedron. To su sve osnovni objekti (Scene Objects->Add object->Basic geometry). Postavicemo ih na (-5, 3, -8 ), (-5, 1, -8 ), (-5, -1, -8 ) i (-5, -3, -8 ) tako da budu poredjani po levoj strani. Prilikom crtanja objekta GLScene prvi put uzima podatke o koordinatama tacaka koje definisu objekat i na osnovu njih napravi listu instrukcija koje kasnije ubrzavaju proces crtanja. Za ovako jednostavne objekte ta lista se napravi vrlo brzo, ali za neke komplikovanije (kompleksne 3d modele) to moze da potraje prilicno dugo. Sad zamislite da imate veliki broj slozenih modela... trebalo bi bas duuugo vremena pre nego sto bi poceli da se iscrtavaju. Da bi se izbegla ova pojava koristimo GLProxyObject. On jednostavno uzima listu instrukcija od nekog objekta i koristi je za iscrtavanje tog objekta na bilo kojoj boziciji i u bilo kojoj velicini. Prilicno koristan objekat jer je tada dovoljno jednom definisati listu za objekat i posle ga iscrtavati bilo gde u velikom broju. Hajde da vidimo kako radi.
Klikni te desnim na Scene Object->Add object->Proxy object. Da bi objekat mogao da se vidi moramo mu reci koji objekat da kopira. Podesimo property MasterObject na GLCube1 kako bi nas ProxyObject dobio izgled kocke. Po defaultu ProxyObject od svog MasterObjecta uzima oblik, efekte (vatra, munje...), velicinu, poziciju i rotaciju. To definise property ProxyOptions (Effects = vatra, munje...; Objects = oblik; Transformation = velicina, pozicija i rotacija). Nama nije bitno da se transofrmacije kopiraju u Proxy posto cemo svakako sami postavljati poziciju pa cemo iskljuciti pooTransformation opciju. Postavimo ga na (0.7, 0, -2) tako da se krupno vidi s desne strane.



Probajte da menjate MasterObject property da vidite kako ce uzeti oblik objekta koji mu zadamo. GLProxyObject je u stanju da kopira skoro sve druge objekte.
Sad konacno dolazi na rad i interakcija sa 3D objektima. Napravicemo da klikom na neki od objekata sa leve strane ProxyObject dobije njegov izgled. Ovo je prilicno lako uraditi Postavicemo GLSceneViewer1.OnMouseDown event na
Code:
procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Obj: TGLBaseSceneObject;
begin
  Obj := GLSceneViewer1.Buffer.GetPickedObject(X, Y);
  if (Obj <> nil) and (Obj <> GLProxyObject1) then
    GLProxyObject1.MasterObject := Obj;
end;

Buffer je property GLSceneViewera u kojem se nalazi iscrtana slika. Postoje razna podesavanja za njega (da li da se vidi magla, da li da prokazuje Back strane objekta, koliko boja da koristi, koja je pozadinska boja...). Sirina i visina Buffera je ista kao i GLSceneViewera... GetPickedObject nam vraca objekat koji se vidi na koordinatama X i Y na GLSceneVieweru. U nasem slucaju moze da nam vrati neki od 4 objekta sa leve strane, nas ProxyObjekat ili nil (ako kliknemo u prazan prostor). Posto ProxyObject ne moze da kopira sam sebe i prazan prostor sredili smo da se tako nesto ne desi. Krenite sad program i probajte da klikcete po sceni
Lako i jednostavno, zar ne?
I eto... u samo nekoliko linija koda imamo FPS brojac, aplikaciju koja ne trozi 100% procesorskog vremena i interakciju sa 3D objektima... pitam se kako li sam mogao da radim 3D programe pre GLScene
Prikačeni fajlovi
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 19:36 - pre 195 meseci
Hajde malo da pomeramo objekte po sceni. Ovo je vrlo lak i jednostavan primer i verovatno ce ga svi ukapirati iz prve. Jednostavno cemo menjati poziciju i rotaciju objekta kada neki od tastera budu pritisnuti. Postavicemo na scenu kameru, svetlo i kupu (GLCone... da bi smo bolje videli kako se rotira) i postavicemo na formu pored scene i viewera takodje i GLCadencer (tu cemo proveravati koji su tasteri pritisnuti). Kupu cemo staviti na 0,0,-4 i ukljucicemo property ShowAxes na True. To ce reci GLSceneVieweru da iscrtava objekat zajedno sa njegovim osama. Ovo vam skoro nikad nece biti potrebno, ali u ovom primeru ce nam pomoci da vidimo kako se objekat rotira.
Od pomocnih unita koristicemo Keyboard za rad sa tastaturom i VectorGeometry koji ce nam pomoci da menjamo poziciju objekta. Dodajte ova dva unita. Sada cemo napisati OnProgress event za nas GLCadencer
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  if IsKeyDown(VK_ESCAPE) then
    Application.Terminate;
  if IsKeyDown('e') then
    GLCone1.Position.Translate(VectorMake(0, 0, -0.01));
  if IsKeyDown('x') then
    GLCone1.Position.Translate(VectorMake(0, 0, 0.01));
  if IsKeyDown('a') then
    GLCone1.Position.Translate(VectorMake(-0.01, 0, 0));
  if IsKeyDown('d') then
    GLCone1.Position.Translate(VectorMake(0.01, 0, 0));
  if IsKeyDown('w') then
    GLCone1.Position.Translate(VectorMake(0, 0.01, 0));
  if IsKeyDown('s') then
    GLCone1.Position.Translate(VectorMake(0, -0.01, 0));
  if IsKeyDown(VK_NUMPAD8) then
    GLCone1.Pitch(0.5);
  if IsKeyDown(VK_NUMPAD2) then
    GLCone1.Pitch(-0.5);
  if IsKeyDown(VK_NUMPAD4) then
    GLCone1.Roll(-0.5);
  if IsKeyDown(VK_NUMPAD6) then
    GLCone1.Roll(0.5);
  if IsKeyDown(VK_NUMPAD9) then
    GLCone1.Turn(-0.5);
  if IsKeyDown(VK_NUMPAD1) then
    GLCone1.Turn(0.5);
  if IsKeyDown(VK_NUMPAD5) then
  begin
    GLCone1.Position.SetPoint(0, 0, -4);
    GLCone1.ResetRotations;
  end;
end;

Od novih funkcija sa kojim se srecemo tu su IsKeyDown... sam naziv funkcije kaze sta radi. Ako je odredjeni taster pritisnut (moze da se da Char ili Virtual Code) rezultat je True.
Zatim imamo Position.Translate... Translate jednostavno sabira vektore i zbog toga se pozicija pomera za zadati vektor.
VectorMake... sam naziv kaze sta radi Za zadate 3 vrednosti (X, Y i Z) kreira vektor po zelji.
Roll, Pitch i Turn rotiraju objekat po
Roll - Z osi
Pitch - X osi
Turn - Y osi
SetPoint postavlja odredjenu tacku... tako direktno mozemo da upisemo zeljenu poziciju.
ResetRotations ponistava sve rotacije koje su izvrsene nad objektom i vraca ga u pocetni polozaj.
Dakle... jednostavno za odredjeni karakter pomeramo ili rotiramo objekat... ako slucajno objekat pobegne iz vida pritiskom na 5 (numericka tastatura) vratice ga na centar.



Sa ovim znanjem vec mozete napraviti neku jednostavnu igru. Sledeci primer ce biti (bar se nadam ) mala igra... parovi. Na formi ce biti nekoliko kocki i cilj ce biti da se okrenu dve za redom koje imaju istu boju (samo jedna strana ce biti obojena). Ponovo cemo koristiti misa da izaberemo objekte, a koristicemo i GLDummyCube i pokazacemo prakticnu primenu hijerarhiskog postavljanja objekata na scenu. Nadam se da ce vam se dopasti i da ce biti razumljivo
Prikačeni fajlovi
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene30.05.2005. u 23:44 - pre 195 meseci
Veceras nemam vremena da napisem objasnjenje za "parove", ali sam napravio programcic na brzinu. Sutra cu postovati kod i step-by-step objasnjenje, a za sad mozete skinuti izvrsni fajl cisto da vidite kako radi

Link: http://dhost.info/avram/srpskisoftware/opis.php?id=65
 
Odgovor na temu

Nemanja Avramović
Software architect
Tap medical
Beograd, Srbija

Član broj: 32202
Poruke: 4383
*.yu1.net.

Sajt: https://avramovic.info


+45 Profil

icon Re: Kako koristiti GLScene31.05.2005. u 10:17 - pre 195 meseci
E Srki car si... evo ja sam najzad skupio hrabrosti da malo chachkam pa sam u Cadencer-u dodao:

Code:

GLProxyObject1.Turn(0.2);


ispod: GLSceneViewer1.Invalidate;

...i sada je efekat malo lepshi (ProxyObject se rotira). Naravno, radi se o primeru broj 6.

Sada imam jedno pitanjce za tebe: Kad distribuirash aplikaciju, sta treba od dodatnih dll-ova? Za zvuk znam sta treba, ali za sam 3d engine?
Laravel Srbija.

[NE PRUŽAM PODRŠKU ZA PHP PREKO PRIVATNIH PORUKA!]
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene31.05.2005. u 15:33 - pre 195 meseci
Ovako... za zvuk ako koristis Bass treba ti BASS.dll (imate ga u GLScene), ako se koristi FMod onda FMod.dll (imate ga u GLScene), ako koristite ODE za fiziku treba vam ODE.dll (imate ga u GLScene), ako koristite SDL za kreiranje prozora sto ja nikad nisam imao potrebe da radim (nema cak ni nekih prednosti) treba vam SDL.dll (imate ga u GLScene)... i to je to Naravno racunar koji pokrece program mora da ima drajver za graficku koji podrzava OpenGL.
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene31.05.2005. u 17:15 - pre 195 meseci
Ahhh... bas je lepo kada te puste ranije s posla Prosto uzivam... bazencic, pivce, muzika, lap-top... samo da ga ne ispustim u vodu Kao sto sam obecao red je da napravimo nasu prvu malu igru. Ovog puta cemo sve sto smo naucili da stavimo u jedan program i videcemo kako je moguce kreirati i brisati objekte na sceni u runtime.
Pocecemo tako sto cemo pobacati GLScene, GLSceneViewer, GLMaterialLibrary i GLCadencer na formu i kameru i svetlo na scenu. Sad dodajmo GLDummyCube na scenu 0, 0, -4 (Scene Objects->Add object->DummyCube) i nazovimo je Tabla. Ovaj objekat je prilicno koristan. Na sceni se vidi kao providna kocka cije su ivice iscrtane isprekidanom linijom, a kada se program pokrene onda se ne vidi. Neko se moze zapitati sta ce nam objekat koji se ne vidi... secate li se kada sam pokazao kako je moguce hijerarhijski postavljati objekte. E, DummyCube se koristi uglavnom za to. Ako postavimo nekoliko lopti, kocki ili bilo kojih objekata da njihove pozicije zavise od DummyCube, pomeranjem i rotiranjem DummyCube svi ti objekti ce se takodje kretati. U kodu cete videti malo bolje o cemu pricam.



Sada nam je cilj da napravimo plocicu koja ce se okretati. Treba da ima jednu stranu obojenu jednom dok su sve ostale obojene drugom bojom. Problem je sto GLCube to bas i ne moze da uradi... ali zato 2 GLCube mogu Dodajmo jednu kocku i postavimo je u DummyCube. Posto pozicija nase kocke sad zavisi od DummyCube znaci da ce se i nasa kocka naci na 0, 0, -4.
GLCube nam dozvoljava da izaberemo koje stranice kocke ce iscrtavati (Parts property) i mi cemo iskljuciti Back i tada strana koja je okrenuta od nas nije iscrtana. Sada cemo dodati jos jednu kocu u DummyCube i njoj cemo u Parts postaviti da iscrtava SAMO Back stranu tako da ce ona popuniti deo koji prva kocka nije iscrtala. I sada mozemo jednu stranu da obojimo u jednu, a ostale u drugu boju Samo postavimo materijale kocki na razlicite boje (recimo jedna strana na crveno, a ostale na plavo). Problem je sto sad ne mozemo da vidimo koje je boje deo okrenut od nas... zato cemo malo da zarotiramo nase kocke. Umesto da rotiramo jednu i drugu sve sto cemo uraditi jeste postavljanje ugla za DummyCube. Postavimo TurnAngle na 140 i sta vidimo... obe kocke su zarotirane i sada vidimo i zadnju stranu. Ovaj nacin cemo koristiti u igri da postavljamo i rotiramo polja.



Pa... hajde da pocnemo... obrisimo iz scene sve osim kamere, svetla i DummyCube (koju smo nazvali Tabla). Vratimo TurnAngle Table na 0. I spremni smo da pocnemo
Da bismo uopste mogli da igramo prvo moramo postaviti polja. Napravicemo nam jednu proceduru koja ce obrisati sva postojeca polja na Tabeli i postaviti nova. Proceduru cemo dodati recimo u public deo nase forme
Code:
type
  TForm1 = class(TForm)
    GLScene1: TGLScene;
    GLSceneViewer1: TGLSceneViewer;
    GLMaterialLibrary1: TGLMaterialLibrary;
    GLCadencer1: TGLCadencer;
    GLCamera1: TGLCamera;
    GLLightSource1: TGLLightSource;
    Tabla: TGLDummyCube;
  private
    { Private declarations }
  public
    { Public declarations }
    procedure NovaIgra;
  end;

Prva stvar koju cemo uraditi je brosanje postojecih polja. Posto ce sva polja biti u DummyCube koju smo nazvali Tabla mozemo ih obrisati sve pozivom samo jedne funkcije
Code:
Tabla.DeleteChildren;

Ovo ce obrisati sve objekte koji se nalaze u Tabla objektu. Da nismo koristili DummyCube morali bismo da cuvamo polja u nekom nizu pa da ih brisemo jedno po jedno dok ovako GLScene radi sve umesto nas.
Sledece sto treba da uradimo je da dodamo nova polja kao sto smo vec probali u designtime. Dodacemo u var deo procedure dve promenljive
Code:
var
  Dummy: TGLDummyCube;
  Cube: TGLCube;

One ce cuvati objkte koje budemo kreirali. Kad smo pravili polje prvo smo postavili DummyCube... to cemo uraditi i sad
Code:
Dummy := TGLDummyCube.CreateAsChild(Tabla);

Kada ovako kreiramo objekat on ce se nalaziti u objektu koji navedemo prilikom poziva CreateAsChild... znaci nas Dummy ce se nalaziti u objektu Tabla. Ako zelimo da kreiramo objekat koji nije vezan za neki drugi onda umesto CreateAsChild pozivamo samo Create.
Kad smo napravili Dummy treba da dodamo kocku koja ce iscrtavati sve sem Back strane. Da polje ne bi izgledalo previse "kockasto" malo cemo da spljostimo nasu "kocku". To bi izgledalo ovako
Code:
Cube := TGLCube.CreateAsChild(Dummy);
Cube.CubeDepth := 0.2;
Cube.Parts := Cube.Parts - [cpBack];

Ovaj deo svih polja ce biti iste boje pa bi bilo zgodno napraviti material u GLMaterialLibrary koji ce drzati boju za njih. Dodajmo jedan material proizvoljne boje i nazovimo ga "Pozadina". U designtime znamo kako se postavlja material objektima, a evo kako to ide u runtime
Code:
Cube.Material.MaterialLibrary := GLMaterialLibrary1;
Cube.Material.LibMaterialName := 'Pozadina';

Ostaje nam jos samo da dodamo i obojenu stranu. Posto cemo praviti 12 polja to je po 6 parova koji ce imati razlicitu boju pa hajde da dodamo jos 6 materijala razlicite boje u GLMaterialLibrary i nazovimo ih 0, 1, 2, 3, 4 i 5. I obojena strana je skoro gotova
Code:
Cube := TGLCube.CreateAsChild(Dummy);
Cube.CubeDepth := 0.2;
Cube.Parts := [cpBack];
Cube.Material.MaterialLibrary := GLMaterialLibrary1;
Cube.Material.LibMaterialName := '0';

To bi za sad bio deo koji inicijalizuje igru. Cela funkcija bi za sada izgledala ovako
Code:
procedure TForm1.NovaIgra;
var
  X, Y: Integer;
  Mat: array[0..11] of String;
  Dummy: TGLDummyCube;
  Cube: TGLCube;

  // Izabira material za polje
  function IzaberiMaterial: String;
  var
    I: Integer;
  begin
    I := Random(12 - (X + (Y * 4)));
    Result := Mat[I];
    Mat[I] := Mat[11 - (X + (Y * 4))];
  end;

begin
  // Brisemo sve objekte u Tabla
  Tabla.DeleteChildren;

  // Postavljamo boje za IzaberiMaterijal
  for X := 0 to 5 do
  begin
    Mat[X] := IntToStr(X);
    Mat[X + 6] := IntToStr(X);
  end;

  // Postavljamo plocice na tablu
  for Y := 0 to 2 do
    for X := 0 to 3 do
    begin
      // Dodajemo jedan DummyCube koji ce drzati
      // pozadinu (kocku bez jedne strane) i
      // zadnju stranu koja je obojena
      Dummy := TGLDummyCube.CreateAsChild(Tabla);
      Dummy.Position.SetPoint(-3 + X * 2, -1.5 + Y * 1.5, 0);
      // Dodajemo pozadinu
      Cube := TGLCube.CreateAsChild(Dummy);
      Cube.CubeDepth := 0.2;
      Cube.Parts := Cube.Parts - [cpBack];
      Cube.Material.MaterialLibrary := GLMaterialLibrary1;
      Cube.Material.LibMaterialName := 'Pozadina';
      // Dodajemo obojenu stranu
      Cube := TGLCube.CreateAsChild(Dummy);
      Cube.CubeDepth := 0.2;
      Cube.Parts := [cpBack];
      Cube.Material.MaterialLibrary := GLMaterialLibrary1;
      Cube.Material.LibMaterialName := IzaberiMaterijal;
    end;
end;

Funkcija IzaberiMaterijal koristi Random da bi odredila boju polja... mogla je da se uradi i na drugi nacin. Ostaje nam da u Form.OnCreate podesimo da se ova procedura pozove i videcemo polja sa zadnje strane ako pokrenemo program



Sada... mogli bi da pocnemo da okrecemo plocice. Posto ce nam kasnije biti potrebno da znamo kad smo okrenuli dva polja dodacemo dve promenljive koje ce cuvati polja koja se okrecu i jos jednu promenljivu koja ce nam reci da li se polja okrecu u datom trenutku
Code:
var
  Okretanje: Boolean;
  Izabrana1, Izabrana2: TGLDummyCube;

Polje cemo da izaberemo u OnMouseDown eventu GLSceneViewera
Code:
procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
  Obj: TGLCube;
begin
  // Ako se nesto desava druge ploce ne mogu da se izaberu
  if Okretanje then Exit;
  Obj := TGLCube(GLSceneViewer1.Buffer.GetPickedObject(X, Y));
  // Uzimamo u obzir samo kocke
  if Obj <> nil then
  begin
    // Ako nismo izabrali ni jednu onda nam je ovo prva
    // i pocinjemo sa okretanjem
    if Izabrana1 = nil then
    begin
      // Parent od kocke koja je pozadina je DummyCube koja
      // sadrzi i pozadinu i boju pa kada rotiramo
      // DummyCube rotira se i pozadina i boja
      Izabrana1 := TGLDummyCube(Obj.Parent);
      Okretanje := True;
    end
    else
    // Ako je prva vec izabrana pazimo da je nismo izabrali
    // ponovo i ako nismo onda je izabrana i druga i
    // pocinjemo sa okretanjem
    if Izabrana1 <> Obj.Parent then
    begin
      Izabrana2 := TGLDummyCube(Obj.Parent);
      Okretanje := True;
    end;
  end;
end;

Ovde nema niceg komplikovanog... kada kliknemo na neku kocku proveravamo da li je vec izabrana i ako nije uzimamo vrednost iz Parent propertya sto nam daje objekat u kojem se nasa kocka nalazi tj. DummyCube koji smo kreirali. Tako cemo u Izabrana1 ili Izabrana2 imati DummyCube koji treba da okrenemo da bi se polje videlo. Polje cemo okretati u OnProgress eventu GLCadencera
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  // Okrecemo izabrano polje
  if Okretanje then
  begin
    // Vec smo izabrali drugo polje
    if Izabrana2 <> nil then
    begin
      // Okrecemo ga
      Izabrana2.TurnAngle := Izabrana2.TurnAngle + 500 * deltaTime;
      // Okrenuo se na zeljenu stranu (ili mozda malo vise)
      if Izabrana2.TurnAngle < 0 then
      begin
        // Resetujemo rotacije i postavljamo tacnu vrednost
        // koju zelimo
        Izabrana2.ResetRotations;
        Izabrana2.Turn(180);
        // Okretanje je zavrseno i pocinje pauza da igrac
        // vidi sta je uradio
        Okretanje := False;
        // Ovde cemo proveriti da li su polja ista
      end;
    end
    else
    begin
      // Okrecemo prvo polje
      Izabrana1.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
      if Izabrana1.TurnAngle < 0 then
      begin
        Izabrana1.ResetRotations;
        Izabrana1.Turn(180);
        Okretanje := False;
      end;
    end;
  end;
end;

I ovde nema niceg komplikovanog mozete primetiti da sam vrednost sa kojom uvecavam ugao mnozio sa deltaTime. To je dobro zato sto ce i na racunaru koji ima 20 FPS i na onom koji ima 200 FPS rotacija da bude iste brzine. Pokrenimo program i probajmo da okrecemo polja.



Nastavak u sledecem postu

[Ovu poruku je menjao Srki_82 dana 31.05.2005. u 19:32 GMT+1]
 
Odgovor na temu

Srki_82
Srdjan Tot
Me @ My Home
Ljubljana

Član broj: 28226
Poruke: 1403
82.208.201.*

ICQ: 246436949


+10 Profil

icon Re: Kako koristiti GLScene31.05.2005. u 17:59 - pre 195 meseci
Sada cemo da napravimo da igra malo zastane kada se okrenu dva polja, da proveri da li su ista i da ih vrati ako nisu. Za sad ce funkcija za proveravanje uvek govoriti da su polja razlicita da bi lakse objasnjavao kod. Dodacemo jos neke globalne promenljive
Code:
var
  Pauza: Boolean;
  Vracanje: Boolean;
  Cekanje: Double;

Pauza je True ako smo u pauzi izmedju okretanja, Cekanje je vreme koji je ostalo do kraja pauze i Vracanje je True kada se polja vracaju u pocetnu poziciju. Pre nego sto pocnemo modifikovacemo pocetak dela koji nam vraca koja kocka je kliknuta i pocetak ce izgledati
Code:
if Okretanje or Pauza or Vracanje then Exit;

Tako igrac nece moci da okrece novo polje kad ne bi trebalo da moze.
Dodacemo proceduru Proveri u public deo nace forme i za sad napisati samo
Code:
procedure TForm1.Proveri;
begin
  Vracanje := True;
end;

Malo cemo modifikovati i OnProgress event tako da reaguje na Vracanje i Pauzu
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  // Cekamo da istekne neko vreme
  if Pauza then
  begin
    Cekanje := Cekanje - deltaTime;
    if Cekanje < 0 then
      Pauza := False;
  end
  else
  // Vracamo polja ako su nisu ista
  if Vracanje then
  begin
    // Okrecemo polja
    Izabrana1.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
    Izabrana2.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
    // Ako se polje okrenulo skroz (ili mozda malo vise)
    // resetujemo rotacije i vracanje je gotovo
    if Izabrana1.TurnAngle < 0 then
    begin
      Izabrana1.ResetRotations;
      Izabrana2.ResetRotations;
      Izabrana1 := nil;
      Izabrana2 := nil;
      Vracanje := False;
    end;
  end
  else
  // Okrecemo izabrano polje
  if Okretanje then
  begin
    // Vec smo izabrali drugo polje
    if Izabrana2 <> nil then
    begin
      // Okrecemo ga
      Izabrana2.TurnAngle := Izabrana2.TurnAngle + 500 * deltaTime;
      // Okrenuo se na zeljenu stranu (ili mozda malo vise)
      if Izabrana2.TurnAngle < 0 then
      begin
        // Resetujemo rotacije i postavljamo tacnu vrednost
        // koju zelimo
        Izabrana2.ResetRotations;
        Izabrana2.Turn(180);
        // Okretanje je zavrseno i pocinje pauza da igrac
        // vidi sta je uradio
        Okretanje := False;
        Pauza := True;
        Cekanje := 0.5;
        // Proveravamo da li su polja ista
        Proveri;
      end;
    end
    else
    begin
      // Okrecemo prvo polje
      Izabrana1.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
      if Izabrana1.TurnAngle < 0 then
      begin
        Izabrana1.ResetRotations;
        Izabrana1.Turn(180);
        Okretanje := False;
      end;
    end;
  end;
end;

Sve je sasvim jasno ovde... posle Vracanja podesavamo izabrana polja na nil tako da ponovo mozemo bez problema da biramo i prvo i drugo polje. Krenimo igru sada... skoro kao da je gotova... ostalo nam je jos samo saznamo da li su okrenuta polja ista i da ih sakrijemo ako jesu. Najlakse nam je da samo uporedimo materijale obojene strane. Dodacemo jos jednu globalnu promenljivu koja ce nam signalizirati ako treba da sakrijemo polja
Code:
var
  Nestajanje: Boolean;

I sada ce nasa Proveri procedura izgledati ovako
Code:
procedure TForm1.Proveri;
begin
  // Ako su boje iste vreme je za "nestajanje" :)
  Nestajanje :=
  TGLCube(Izabrana1.Children[1]).Material.LibMaterialName =
  TGLCube(Izabrana2.Children[1]).Material.LibMaterialName;
  // Ako nisu ista onda ih vracamo
  Vracanje := not Nestajanje;
end;

Koristili smo property Izabrana1.Children. Ona nam vraca objekte koji se nalaze u Izabrana1. U nasem slucaju Izabrana1 je DummyCube koji sadrzi dve kocke. Prvu (index = 0) koja je okvir za polje i drugu (index = 1) koja je obojena strana. Na taj nacin mozemo doci do materijala obojene strane.
Ostalo nam je jos samo da sredimo OnProgress event da reaguje na Nestajanje
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  // Cekamo da istekne neko vreme
  if Pauza then
  begin
    Cekanje := Cekanje - deltaTime;
    if Cekanje < 0 then
      Pauza := False;
  end
  else
  // Vracamo polja ako su nisu ista
  if Vracanje then
  begin
    // Okrecemo polja
    Izabrana1.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
    Izabrana2.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
    // Ako se polje okrenulo skroz (ili mozda malo vise)
    // resetujemo rotacije i vracanje je gotovo
    if Izabrana1.TurnAngle < 0 then
    begin
      Izabrana1.ResetRotations;
      Izabrana2.ResetRotations;
      Izabrana1 := nil;
      Izabrana2 := nil;
      Vracanje := False;
    end;
  end
  else
  // Sklanjamo polja sa table ako su ista
  if Nestajanje then
  begin
    Izabrana1.Free;
    Izabrana2.Free;
    Izabrana1 := nil;
    Izabrana2 := nil;
    // Nema vise polja... nova igra!?
    if Tabla.Count = 0 then
      if Application.MessageBox('Nova igra?', 'Info', MB_YESNO) = ID_YES then
        NovaIgra
      else
        Application.Terminate;
  end
  else
  // Okrecemo izabrano polje
  if Okretanje then
  begin
    // Vec smo izabrali drugo polje
    if Izabrana2 <> nil then
    begin
      // Okrecemo ga
      Izabrana2.TurnAngle := Izabrana2.TurnAngle + 500 * deltaTime;
      // Okrenuo se na zeljenu stranu (ili mozda malo vise)
      if Izabrana2.TurnAngle < 0 then
      begin
        // Resetujemo rotacije i postavljamo tacnu vrednost
        // koju zelimo
        Izabrana2.ResetRotations;
        Izabrana2.Turn(180);
        // Okretanje je zavrseno i pocinje pauza da igrac
        // vidi sta je uradio
        Okretanje := False;
        Pauza := True;
        Cekanje := 0.5;
        // Proveravamo da li su polja ista
        Proveri;
      end;
    end
    else
    begin
      // Okrecemo prvo polje
      Izabrana1.TurnAngle := Izabrana1.TurnAngle + 500 * deltaTime;
      if Izabrana1.TurnAngle < 0 then
      begin
        Izabrana1.ResetRotations;
        Izabrana1.Turn(180);
        Okretanje := False;
      end;
    end;
  end;
end;

To je to
Kada je potrebno da polje nestane mi ga samo unistimo i vise ga nema. Na kraju proverimo da li smo unistili sva polja i ako jesmo pitamo igraca da li zeli da igra ponovo.
Bez komplikovanih stvari moze da se napravi nesto zanimljivo.
U sledecem postu cemo malo promenuti kod pa ce polja polako da postaju sve providnija umesto sto samo odjednom nestanu.
 
Odgovor na temu

[es] :: Pascal / Delphi / Kylix :: Kako koristiti GLScene
(TOP topic, by morlic)
Strane: 1 2 3 4

[ Pregleda: 36097 | Odgovora: 73 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.