[ Srki_82 @ 28.05.2005. 18:47 ] @
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!!!
[ Bojan Kopanja @ 28.05.2005. 19:38 ] @
Srki genije, pa ti si Bog! Samo nastavi ovako, mocna stvar! Svaka cast!
[ Srki_82 @ 28.05.2005. 20:02 ] @
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.
[ Srki_82 @ 29.05.2005. 01:41 ] @
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!
[ Nemanja Avramović @ 29.05.2005. 08:29 ] @
brate prosao sam kroz obe lekcije i vec sam poceo da kontam nesto.. samo tako nastavi!
[ Srki_82 @ 29.05.2005. 12:29 ] @
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.
[ Srki_82 @ 29.05.2005. 15:10 ] @
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!!!
[ Srki_82 @ 29.05.2005. 17:37 ] @
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?
[ Bojan Kopanja @ 29.05.2005. 22:16 ] @
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!
[ Srki_82 @ 29.05.2005. 22:53 ] @
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
[ staleks @ 30.05.2005. 00:15 ] @
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
[ Nemanja Avramović @ 30.05.2005. 08:39 ] @
e extra je, samo malo uspori, ok...? imam i ja obaweze, pogotovo sad!
[ Nemanja Avramović @ 30.05.2005. 11:19 ] @
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...
[ Srki_82 @ 30.05.2005. 18:00 ] @
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
[ Srki_82 @ 30.05.2005. 19:36 ] @
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
[ Srki_82 @ 30.05.2005. 23:44 ] @
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
[ Nemanja Avramović @ 31.05.2005. 10:17 ] @
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?
[ Srki_82 @ 31.05.2005. 15:33 ] @
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.
[ Srki_82 @ 31.05.2005. 17:15 ] @
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]
[ Srki_82 @ 31.05.2005. 17:59 ] @
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.
[ Srki_82 @ 31.05.2005. 18:44 ] @
I za kraj ove igre sacuvali smo "nestajanje" polja. Nestajanje cemo izvesti tako sto cemo alpha vrednos materiala polako smanjivati dok materijal ne postane potpuno providan. Da bi alpha vrednos uopste menjala providnost materiala moramo Blend mode postaviti na Transparency i zato postavimo to za sve materiale koje smo definisali osim za material Pozadina. Problem bi bio ako bismo menjali material Pozadina sva polja bi se menjala jer smo pri kreiranju kocku koja crta okvir polja povezali sa Pozadina materijalom. Zato cemo kreirati jos jedan material "FadeOut" i napraviti ga isto kao i Pozadina osim sto ce FadeOut imati Blend mode = Transparency. Dodacemo jos dve globalne promenljive u kojima cemo cuvati materijale koje menjamo
Code:
var
  MatBoja, MatFade: TGLMaterial;

MatFade mozemo postaviti na "FadeOut" material prilikom kreiranja forme
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  Randomize;
  // Postavlja polja na tablu
  NovaIgra;
  // Uzima material za "nestajanje" polja
  MatFade := GLMaterialLibrary1.LibMaterialByName('FadeOut').Material;
end;

Materijal boje koja treba da nestane mozemo uzeti u funkciji Proveri
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;
  if Nestajanje then
  begin
    // Postavljamo material za nestajanje
    TGLCube(Izabrana1.Children[0]).Material.LibMaterialName := 'FadeOut';
    TGLCube(Izabrana2.Children[0]).Material.LibMaterialName := 'FadeOut';
    // Uzimamo materijal za boju kako bismo mogli
    // polako da ga napraimo providnim
    MatBoja := GLMaterialLibrary1.LibMaterialByName(
      TGLCube(Izabrana1.Children[1]).Material.LibMaterialName).Material;
  end;
end;

Kao sto vidite u proceduri proveri takodje postavljamo material FadeOut za okvire polja koje treba da nestanu. Tako cemo moci samo njih da menjamo.
Sada cemo jos samo da izmenimo deo OnProgress eventa za Nestajanje
Code:
if Nestajanje then
begin
  // Smanjujemo alpha vrednost tako da pozadina postaje sve
  // providnija
  MatFade.FrontProperties.Diffuse.Alpha :=
    MatFade.FrontProperties.Diffuse.Alpha - 1 * deltaTime;
  // Smanjujemo alpha vrednost tako da boja postaje sve
  // providnija
  MatBoja.FrontProperties.Diffuse.Alpha :=
    MatBoja.FrontProperties.Diffuse.Alpha - 1 * deltaTime;
  // Malo da vrtimo polja dok nestaju ;)
  Izabrana1.Turn(1000 * deltaTime);
  Izabrana2.Turn(1000 * deltaTime);
  // Ako je sve nevidnjivo brisemo polja
  if MatFade.FrontProperties.Diffuse.Alpha <= 0 then
  begin
    Izabrana1.Free;
    Izabrana2.Free;
    Izabrana1 := nil;
    Izabrana2 := nil;
    // Vracamo ponovo alpha na 1
    MatFade.FrontProperties.Diffuse.Alpha := 1;
    MatBoja.FrontProperties.Diffuse.Alpha := 1;
    Nestajanje := False;
    // 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;
end;

Znaci sve sto radimo je polako zmanjivanje alpha vrednosti boje materijala i nase polje ce polako da nestaje. Dodao sam i malo rotiranja kako bi sve bilo zanimljivije
Kada objekat skroz nestane (alpha <= 0) brisemo ga i vracamo alpha vrednos materijala za nestajanje ponovo na 1 kako bi bio spreman za sledece nestajanje.
I to je sve za ovu igru.
Mozete dodati da se meri vreme za koje je igra predjena, broj okretanja, highscore tabelu, izbor slika za polja (polja mogu da imaju texture)... slobodno experimentisite
Sledece sto nas ceka su "ponasanja" objekata... teracemo objekat da se krece po nekoj putanji, vrtecemo tocak na osovini... videcu sta ce mi sve pasti na pamet
[ Nemanja Avramović @ 01.06.2005. 14:05 ] @
extra!
sad mozes poceti sa objasnjavanjem svega onoga sto sam ti rekao na ICQ, a mozes i ovo da obradis - interakcija objekata sa objektima u smislu provere kolizije (tj. da li se objekti dodiruju)... kao zidovi u onom tvom lavirintu!
[ Srki_82 @ 01.06.2005. 17:43 ] @
Posle zanimljive igre vracamo se dosadnim sitnicama Svaki objekta moze da ima asocirane efekte i osobine koje opisuju kako ce se ponasati na sceni. I efekti i osobine zahtevaju GLCadencer jer je on zaduzen za update. Sada cemo se pozabaviti osobinom Simple Inertia. Ova osobina nam dozvoljava da zadamo ugaonu brzinu (po x, y ili z osi objekta) ili brzinu kretanja u nekom pravcu i otpor koji ce na kraju zaustaviti kretanje. Potrebno je samo da podesimo te podatke i nas objekat ce poceti da se krece ili rotira (ili i jedno i drugo) i na kraju ce se zaustaviti. U ovom primeru cemo postaviti 2 cilindra (jedan ce biti osovina, a drugi tocak) i pritiskom na gore cemo dati gas (tocak ce se vrteti u napred), na dole cemo ici u nazad i na space cemo pritisnuti kocnicu. Pocnimo postavljanjem GLScene, GLSceneViewera i GLCadencera. Dodajmo kameru i svetlo, a zatim 2 cilindra. Prvi postavimo na 0, 0, -4. Postavimo TopRadius i BottomRadius na 0.1 da bi malo stanjili osovinu i na kraju postavimo RollAngle na 90 kako bismo je polozili. Drugi cilindar postavimo na 2, 0, -4. Postavimo RollAngle na 90, BottomRadius i TopRadius na 1, Height na 0.1 i Slices na 7. Tako cemo dobiti tocak sa desne strane. Postavili smo Slices na mali broj da bi lakse uocili kako se tocak okrece.



Sad cemo dodati osobinu nasem objektu. Kliknimo desnim na drugi cilindar (onaj koji nam predstavlja tocak) i izaberimo Add behaviour->Simple Intertia. Da bismo videli koje sve osobine ima nas objekat moramo kliknuti Show Behaviours/Effects dugme na vrhu Scene Editora.



Sada mozemo da kliknemo na osobinu koju smo dodali i da vidimo sta sve mozemo da podesimo.
DampingEnable - da li da otpor zaustavlja kretanje (ako pravimo planetu koja se neprestano okrece mozemo ovo iskljuciti)
Mass - masa objekta od koje zavisi kojom brzinom ce se zaustaviti
Name - ime osobine (kasnije je mozemo pronaci na osnovu imena ako je potrebno)
Pitch, Roll i Turn speed - brzine okretanja objekta oko osa
Rotation Damping - otpor prilikom okretanja
Translation Speed - brzina kretanja po x, y i z osi
Translation Damping - otpor prilikom kretanja
Otpor moze biti konstantan, linearan i kvadratni. Kada je konstantan onda se brzina dok je veca ili manja od nule priblizava nuli konstantnom brzinom u zavisnosti od mase.
Ako je otpor linearan sto je brzina veca veci je i otpor. Odnos izmedju brzine i otpora je linearan.
Ako je otpor kvadratni sto je brzina veca veci je i otpor, ali je ovog puta odnos izmedju brzine i otpora je kvadratni (otpor je vec za vece brzine nego kad je otpor linearan).
Za sad necemo menjati ovde nista jer cemo vrednosti postavljatiu runtime u zavisnosti od pritisnutih tastera.
Trebace nam Keyboard unit pa ga ubacite u uses listu. Kada se koriste osobine moramo dodati i GLBehaviours unit inace nas program nece raditi.
Postavimo sad OnProgress event
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
var
  I: TGLBInertia;
begin
  I := GetOrCreateInertia(GLCylinder2);

  if IsKeyDown(VK_UP) and (I.TurnSpeed < 1000) then
  begin
    I.TurnSpeed := I.TurnSpeed + 300 * deltaTime;
  end;

  if IsKeyDown(VK_DOWN) and (I.TurnSpeed > -500) then
  begin
    I.TurnSpeed := I.TurnSpeed - 100 * deltaTime;
  end;

  if IsKeyDown(' ') then
    I.RotationDamping.Constant := 1000
  else
    I.RotationDamping.Constant := 50;
end;

Funkcija GetOrCreateInertia proverava osobine objekta i kada naidje na Simple Inertia vraca nam je ili ako ta osobina ne postoji kreira je. Kao sto vidite nije bilo potrebno da kreiramo Simple Inertia u Scene Editoru jer bi nam GLScene kreirao tu osobinu kad bi je zatrazili, ali nije na odmet da znamo kako se osobine dodaju i u designtime
Promenljiva I je tipa TGLBInertia koja sadrzi podatke o Simple Inertia osobini. Ostatak koda je prilicno jasan.
Kada smo pritisnuli gore i brzina je manja od 1000 povecavamo brzinu okretanja. Slicno vazi i kada pritisnemo dole.
Kada pritisnemo space povecavamo otpor (pritiskanje kocnice), a ako space nije pritisnut otpor stavljamo na malu vrednost kako bi se tocak zaustavio posle nekog vremena ako ne "dajemo gas"
To je to... probajte da experimentisete malo... probajte da radite i sa Translation Speed...
[ Jovan Prokopović @ 01.06.2005. 17:57 ] @
Do sada smo koristili gotove objekte (Cube, Sphere ...) i ucitavali smo objekte napravljene u nekom 3D programu, ali nakad moze da nam zatreba da kreiramo objekt u toku izvrsavanja aplikacije (u zavisnosti od proracuna, akcija korisnika ...).

Zato u GLScene postoji nekoliko klasa koje nam to omogucavaju.

Sada cemo da napravimo mali program u kome kreiramo objekte koji nastaju revolucijom (rotacijom linije) oko jedne ose.

Na formu dodajte GLScene, GLSceneViewer, Camera, LightSource,
kameru postavite na (0,0,10) i jedan RevolutionSolid (Screen Objects>Add Object>Advanced geometry>RevolutionSolid).

Dodacemo jedan taster i jos dva editbox-a,

U OnClick tastera dodajemo kod cij je zadatak da dota nod (tacku) linije koju rotiramo.

Code:

procedure TForm1.Button1Click(Sender: TObject);
begin
  GLRevolutionSolid1.AddNode(StrToFloat(Edit1.Text), StrToFloat(Edit2.Text),0);
end;


Kao Sto vidite vrlo jednostavno, Edit1 je X kordinata, Edit2 je Y kordinata, linija se rotira oko Y ose.

Sad pokrenite program i dodajte nekoliko nodova (naprimer (0,3), (2,2), (1,1), (2,0) ...), trebalo bi da vidite neki objekt.


Dodacemo i kretanje kamere oko objekta, postavicemo GLCamera.TargetObject property na GLRevolutionSolid1, devinisemo dve globalne promenljive mX i mY i dodamo ovaj kod.

Code:

procedure TForm1.GLSceneViewer1MouseDown(Sender: TObject;
  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
  mX:=X; mY:=Y;
end;

procedure TForm1.GLSceneViewer1MouseMove(Sender: TObject;
  Shift: TShiftState; X, Y: Integer);
begin
  If ssLeft in Shift then
  GLCamera1.MoveAroundTarget(mY-Y, mX-X);
  mX:=X; mY:=Y;
end;


Sad kad pokrenemo program dodamo nekoliko nodova imamo objekt oko kog moze da kruzi kamera (znaci ne rotiramo sam objekt kao u jedno od ranijih primera).
Ali objek i nije nesto narocito lep sve linije su prave (nije zaobljen), zato cemo dodati je jedan CheckBox i ovaj kod


Code:

procedure TForm1.CheckBox1Click(Sender: TObject);
begin
  If CheckBox1.Checked then GLRevolutionSolid1.SplineMode:=lsmBezierSpline
  else GLRevolutionSolid1.SplineMode:=lsmLines;
end;


Sad imamo lepo zaobljen objek kad cekiramo checkbox.

Dodacemo jos dva ScrollBara, Position prvog ScrollBara postavite na 10, a drugog na 16, i jos malo koda


Code:

procedure TForm1.ScrollBar1Change(Sender: TObject);
begin
  GLRevolutionSolid1.Division:=ScrollBar1.Position;
end;

procedure TForm1.ScrollBar2Change(Sender: TObject);
begin
  GLRevolutionSolid1.Slices:=ScrollBar2.Position;
end;


Division predstavlja broj segmenata linije izmedju dva noda (prilikom zaobljavanja), a Slices broj koraka prilikom rotiranja linije.

To je uglavnom to, GLRevolutionSolid ima jos nekoliko osobina ali to ostavljam vama da isprobate.
[ Srki_82 @ 01.06.2005. 18:02 ] @
Odlican tut Jovane Mozda bi mogao da ubacic i neku slikicu pa da ljudi vide da li su dobro odradili posao?

Samo nastavi s dobrim tutorialima
[ Nemanja Avramović @ 02.06.2005. 13:10 ] @
Prodjoh i ove lekcije, i sve je ok. Jedino je srki pogresno nazvao funkciju:

Code:

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

......


      Cube.Material.LibMaterialName := IzaberiMaterijal; //gore nema j


no dobro, to sam uochio odmah... a kod primera sa inercijom sam morao ruchno u uses da dodajem unit za Inerciju ali posle kad sam downloadovao tvoj primer radilo mi je i bez toga... hmmmm

eh da, srki, kod nashe igre sam dodao u can...cer onprogress event, kod nestajanja, da kocke priblizhawa kameri, pa sad izgleda josh lepshe (barem meni )
[ PeraKojotSuperGenije @ 02.06.2005. 16:54 ] @
Da li neko moze malo detaljnije da opise postupak instaliranja GLScene-a. Mislim da sam download-ovao sve sto mi je potrebno, ali ne umem da slozim kockice...
[ Srki_82 @ 02.06.2005. 19:36 ] @
Ok... ovako radi... step-by-step :)
Ako si skinuo zapakovan GLScene prvo ga raspakuju neki folder... npr C:\Program Files\Borlad\Delphi 7\Components\GLScene. Kad to uradis pokreni Delphi. U Tools meniu izaberi Environment Options... Na Library stranici u Library i Browsing path dodaj sve foldere iz GLScene\Source ukljucujuci i njega... trebalo bi da imas nesto slicno ovom
$(DELPHI)\Lib;
$(DELPHI)\Bin;
$(DELPHI)\Imports;
$(DELPHI)\Projects\Bpl;
$(DELPHI)\Rave5\Lib;
$(DELPHI)\Components\GLScene\Source;
$(DELPHI)\Components\GLScene\Source\Base;
$(DELPHI)\Components\GLScene\Source\CgShaders;
$(DELPHI)\Components\GLScene\Source\DesignTime;
$(DELPHI)\Components\GLScene\Source\FileFormats;
$(DELPHI)\Components\GLScene\Source\GameAPIs;
$(DELPHI)\Components\GLScene\Source\PhysicsAPIs;
$(DELPHI)\Components\GLScene\Source\Platform;
$(DELPHI)\Components\GLScene\Source\PlugIn;
$(DELPHI)\Components\GLScene\Source\ScriptingAPIs;
$(DELPHI)\Components\GLScene\Source\Shaders;
$(DELPHI)\Components\GLScene\Source\SoundAPIs;
$(DELPHI)\Components\GLScene\Source\VideoAPIs

$(Delphi) zamenjuje putanju do dlephi foldera (u mom slucaju do C:\Program Files\Borland\Delphi 7). Kad to uradis ostaje ti samo da instaliras pakete koji se nalaze u GLScene\DelphiX gde je X verzija tvog Delphia. Paket instaliras tako sto otvoris dpk fajl i u prozorcicu koji ti se otvori kliknes install. Da bi mogao da instaliras neke pakete (FMod i BASS za zvuk, DWS za scripting, Cg shaders) moraces da uradis pre instaliranja jos nesto. Za FMod i BASS samo kopiras FMOD.dll i BASS.dll u Windows\System32 folder. Za Cg shadere moras sa NVidia sajta skinuti Cg toolkit i instalirati ga, a za DWS moras instalirati DWS komponente koje mozes naci na SourceForge.
Nadam se da ti je sad jasnije.
[ PeraKojotSuperGenije @ 03.06.2005. 00:55 ] @
Da li moze i malo detaljnije objasnjenje za instalaciju DWS-a. Problem je u tome sto kad kompajliram projekte DWS-a (kao sto pise u prilozenom uputstvu) dobijam gresku "Required package 'SynEdit_D7' not found".
[ Srki_82 @ 03.06.2005. 06:40 ] @
Samo te pakete koji zahtevaju SynEdit_D7 nemoj instalirati... ili skini i SynEdit_D7 komponentu pa i nju instaliraj
[ Srki_82 @ 03.06.2005. 15:53 ] @
Ovog vikenda ne pisem nista jer mi se malo putuje. Sledeci tut ce biti o tome kako zadati putanju objektu po kojoj ce se kretati... prilicno fina stvar. Pozdravljam vas sve do ponedeljka... i napisite mi listu zelja sta bi zeleli da obradimo kasnije... mozda i neku zanimljivu ideju za igru kad predjemo sve sto nam je potrebno za nju
[ Nemanja Avramović @ 03.06.2005. 19:43 ] @
- rad sa animacijama (3ds ili mdl, shta vec) poshto mdl moze da ima vise animacija u sebi, pa ono... kako pustiti neku od njih i bla bla, daj bre animacijeeeeee :)
- ucitavanje eksterne teksture preko objekta (u runtime-u, naravno) i kako je pozicionirati (znash ono kad pomerash teksturu a objekat stoji), ako je moguce

eto... to je to za sad
[ tamnicar @ 04.06.2005. 17:21 ] @
Odlican tutorial, ma ovo nije tutorial ovo je walkthrough :)
imam jedno pitanje. Da li se u ovom GLScene-u moze igrati sa shader efektima?
[ Srki_82 @ 05.06.2005. 22:44 ] @
Evo me, konacno, kod kuce

@JaHvram
To su malo napredne stvari, ali ih je lako uraditi Ocekuj ih posle primera za kretanje objekta po putanji i efekata (vatra, dim, munja...)

@tamnicar
Naravno da GLScene podrzava shadere. Ima podrsku za Cg i GLSL shadere (bice primera za cell shading, outlining, bumpmapping)
[ Srki_82 @ 06.06.2005. 17:26 ] @
Posle male pauzice nastavljamo sa primerima.
Pokazacemo kako se koristi Movement controls osobina (u designtime i u runtime) kao i PointTo funkciju objekata u GLScene.
Postavimo scenu (ne zaboravite i GLCadencer), na njoj kameru i svetlo, a od objekata (Basic Geometry) GLIcosahedron (ovom objektu cemo kretanje praviti u designtime), GLDodecahedron (ovom u runtime) i (Advanced Geometry) GLArrowLine (to je samo strelica i prilicno je korisna za pokazivanje u nesto... sa njom cemo koristiti PointTo funkciju).
Posto cemo koristiti osobine objekata moram u uses ubaciti GLBehaviours unit, GLMovement jer cemo koristiti Movement controls i u runtime kao i VectorGeometry da bismo lakse postavljali vektore u runtime. Postavimo objekte na sledece pozicije GLArrowLine 0, 0, -4, a GLIcosahedron i GLDodecahedron na 0, 0, -8. Njihove pozicije i nisu mnogo bitne jer ce Movement controls da ih pomeraju, ali cisto da ih vidimo da su i oni na sceni. Kad smo ovo odradili mozemo da krenemo na nov deo.
Kliknimo desnim na GLIcosahedron i izaberimo Add behaviour->Movement controls. Izaberimo Movement controls osobinu u Scene Editoru i u Object Inspectoru mozemo da pravimo putanje za nas objekat. Moguce je spremiti vise putanja i u progrmu birati koja ce da se izvrsava. Mi cemo koristiti samo jednu, a ako nekom bude previse komplikovano da shvati kako se biraju putanje (hint: ActivePath) neka pita Putanja se kreira tako sto zadajemo tacke u prostoru i definisemo koliko ce objekat sa se zarotira i/ili promeni velicinu dok putuje. Dodacemo novu putanju pritiskom na '...' u Paths property i biranjem Add new u prozorcicu koji se otvorio. Sada nam preostaje da dodajemo tackice kroz koje ce objekat prolaziti (uz rotiranje i promenu velicine). Tacke dodajemo na isti nacin kao i putanje i nalaze se u Nodes property. Dodacemo sledece tacke:

Pozicija (X, Y, Z): 1, -2, -8
Rotacija (Pitch, Roll, Turn): 50, 0, 0
Scale (X, Y, Z): 1, 1, 1
Speed: 2

Pozicija (X, Y, Z): 3, 0, -8
Rotacija (Pitch, Roll, Turn): 50, 50, 0
Scale (X, Y, Z): 1, 1, 1
Speed: 2

Pozicija (X, Y, Z): 4, 1, -8
Rotacija (Pitch, Roll, Turn): 50, 50, 50
Scale (X, Y, Z): 1, 1, 1
Speed: 2

Pozicija (X, Y, Z): 2, 2, -8
Rotacija (Pitch, Roll, Turn): 0, 50, 50
Scale (X, Y, Z): 1, 1, 1
Speed: 2

Pozicija (X, Y, Z): -4, -3, -8
Rotacija (Pitch, Roll, Turn): 0, 0, 50
Scale (X, Y, Z): 1, 1, 1
Speed: 2

Pozicija (X, Y, Z): 0, 0, -8
Rotacija (Pitch, Roll, Turn): 0, 0, 0
Scale (X, Y, Z): 1, 1, 1
Speed: 2

To ce nam biti neko kretanje za nas prvi objekat. Bilo bi lepo da vidimo kako ce da se on krece, zar ne? Da bi smo izabrali aktivnu putanju u designtime postavicemo ActivePathIndex property Movement controls osobine na 0 sto bi znacilo da smo izabrali prvu putanju. Ostaje nam jos da u OnCreate eventu nase forme pokrenemo nas objekta, a to cemo uraditi ovako
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  GetOrCreateMovement(GLIcosahedron1).StartPathTravel;
end;

Ako pokrenemo program nas objekat ce se kretati. Prvo sto upada u oci je da se objekat ne krece uvek konstantnom brzinom iako smo Speed property svake tacke postavili na 2! To je trenutno jedan od bugova u GLScene, ali ako se tacke lepo i dovoljno blizu postave ovaj bag se skoro ne primecuje. Posto ne zelimo da se nas objekat zaustavi posle par sekundi kretanja postavicemo Looped property putanje na True. Da bi looped putanja lepo izgledala pocetna i krajnja tacka bi trebale da budu iste pa cemo dodati jos jednu tacku na putanji koja je ista kao i prva. Sada nas prvi objekat nekako nezgrapno uspeva da se krece po sceni
Sad je red da to uradimo i sa drugim objektom, ali u runtime. Tacke cemo dodati u OnCreate eventu forme... event ce izgledati ovako:
Code:
procedure TForm1.FormCreate(Sender: TObject);
var I: Integer;
begin
  Randomize;
  GetOrCreateMovement(GLIcosahedron1).StartPathTravel;
  with GetOrCreateMovement(GLDodecahedron1) do
  begin
    with Paths.Add do
    begin
      for I := 0 to 19 do
      begin
        with Nodes.Add do
        begin
          PositionAsVector := VectorMake(Random(10) - 5,
            Random(8) - 4,
            Random(3) - 8);
          RollAngle:= Random(360);
          PitchAngle := Random(360);
          TurnAngle := Random(360);
          ScaleAsVector :=VectorMake(1 + Random,
            1 + Random,
            1 + Random);
          Speed := Random(4) + 1;
        end;
        Nodes.Add.Assign(Nodes[0]);
        Looped := True;
      end;
    end;
    ActivePathIndex := 0;
    StartPathTravel;
  end;
end;

GetOrCreateMovement kreira Movement controls za nas objekat i vraca nam ga. Zatim sa Paths.Add dodajemo novu putanju i sa Nodes.Add nove tackice. Postavljamo njihove podatke i na kraju dodajemo jos jednu tacku koja je ista kao i prva. Postavljamo Looped na True kako bi se putanja pokrenula ponovo kad joj dodje kraj. Sve sto nam je preostalo je da postavimo aktivnu putanju i da pokrenemo objekat. Prosto k'o pasulj
Hajde jos da sredimo i da strelica pokazuje na objekat ciju putanju kreiramo u runtime. Za to je dovoljna samo jedna linija u GLCadenceru
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  GLArrowLine1.PointTo(GLDodecahedron1, YHmgVector);
end;

Sve sto kazemo je objekat na koji zelimo da linija pokazuje i gde joj je "gore" (YHmgVector ima vrednost 0, 1, 0).
To je to za sad... sledece sto nas ceka su Time Events... sa ovom komponentom mozemo da u odredjeno vreme uradimo nesto sa objektima ili bilo cim. Moze biti prilicno korisna stvarcica za animacije u igri.
Bye!!!

[ Srki_82 @ 06.06.2005. 19:34 ] @
Uvek je korisno imati komponentu kojoj mozes da kazes "uradi to i to u toliko sekundi i nastavi to da radis sve do tog vremena uz pauze od toliko sekundi". To je ono sto radi Time Events komponenta. Napravicemo jednostavnu animaciju u kojoj ce jedna kocka doleteti s leva, malo se pribliziti, druga s desna, obe se priblize, treca odozgo i opet se sve malo priblize i zatim pocnu da se okrecu. Ovde je sve vrlo jednostavno... vise se vremena provede u podesavanju vremena nego u pisanju koda
Postavicemo na scenu kameru, svetlo i 3 kocke. Prvu na -8, 0, -7. Drugu na 7, 0, -6. Trecu na 0, 4, -5. Time Events zahteva GLCadencer pa cemo ga postaviti na formu. Sa GLScene Utils grupe postavimo GLTimeEventsMGR komponentu na formu i Cadencer podesimo na onaj koji smo ranije stavili na formu. Sada nam ostaje da dodajemo nase evente. Svaki event ima vrstu, pocetno i krajnje vreme, pauzu (vremena su u sekundama), ime i da li je ukljucen ili nije. Od tipova imamo Continuous (poziva se od startnog do krajnjeg vremena sto je pre moguce), Periodic (slicno kao i Continuous samo sto se pravi pauza izmedju pozivanja) i OneShot (poziva se samo jednom... krajnje vreme nema znacaj). Ako zelimo da se neki event ponavlja i ponavlja... da nema kraja, krajnje vreme postavimo na -1. Sad cemo dodati nase evente (klik na '...' Events property i onda Add new u otvorenom prozorcicu).
1.
Pomera prvu kocku ka sredini
Tip = Continuous
Start = 2
End = 8
Code:
procedure TForm1.GLTimeEventsMGR1Events0Event(event: TTimeEvent);
begin
  GLCube1.Position.AsVector := VectorMake(-8 + Event.ElapsedTime, 0, -7);
end;

Jednostavno smanjuje X koordinatu pozicije. Event.ElapsedTime je vreme koje je proslo od startovanja eventa.
2.
Malo priblizimo prvu kocku
Tip = OneShot
Start = 8.5
Code:
procedure TForm1.GLTimeEventsMGR1Events1Event(event: TTimeEvent);
begin
  GLCube1.Position.Translate(ZHmgVector);
end;

Samo smo pomerili kocku blize kameri po Z osi.
Narednih nekoliko eventa su svi slicni... pomera se druga kocka, priblizavaju se, treca kocka... kada su sve kocke vidljive pocecemo da ih rotiramo. Rotiranje cemo vrsiti eventima tipa Periodic i koristicemo Event.TickCount property. TickCount predstavlja koliko je puta event bio pozvan do sad.
Code:
procedure TForm1.GLTimeEventsMGR1Events9Event(event: TTimeEvent);
begin
  GLCube1.TurnAngle := Event.TickCount * 5;
end;

To je otprilike to... prilicno jednostavno za upotrebu, a zaista mocno
Mozda neko moze da uradi neku animaciju za ove tutoriale pa da je ubacimo na pocetak "Parovi" i svih narednih igara koje cemo praviti ovde

[ Srki_82 @ 06.06.2005. 23:20 ] @
Pre nego sto predjemo na vatre, dimove i slicne efekte hteo bih jos samo da spomenem par objekata za ispisivanje teksta i stavljanje slicica na scenu. Skoro u svakom programu je potrebno nesto ispisati korisniku... cudi me kako sam zaboravio na ove objekte na pocetku tutoriala, ali evo... setiosam se ipak... bolje ikad nego nikad
Radicemo sa HUDSprite, HUDText i Space Text komponentama. HUDSprite i HUDText se ne nalaze u 3D vec 2D prostoru... X i Y koordinate im odredjuju polozaj i 0, 0 je gornji-levi ugao GLSceneViewera, a GLSceneViewer.Width, GLSceneViewer.Height je dodnji-desni ugao GLSceneViewera. Kao obicne VCL komponente na formi. Treba znati da koordinata predstavlja centar objekta, a ne njegov gornji-levi ugao kod HUD objekata.
Idemo sa primerom. Postavicemo GLSceneViewer dako da Width bude 688, a Height 446. Dodacemo HUDSprite (Add object->HUD objects->HUD Sprite) i postaviti ga na 344, 223, 0 tako da bude na sredini ekrana. Width cemo postaviti na 468, a Height na 60. Za texturu sam koristio sliku sa ES pa ako je to zabranjeno neka neko kaze i stavicu nesto drugo. Kada postavimo texturu vidimo kako se nas HUD Sprite lepo iscrtao.



Sa HUD Sprite mozemo da radimo sta hocemo kao i sa ostalim objektima... da detektujemo da li je mis iznad njega, da ga rotiramo, menjamo velicinu...
Sledeci je na redu HUD Text. HUD Text je skoro isti kao i HUD Sprite samo sto umesto materijala i textura imamo text na osnovu kojeg GLScene iscrta texturu. Postavicemo ga na 344, 150, 0. Aligment cemo staviti na Center. Da bi slova mogla da se iscrtavaju potrebna nam je slika slova. Mozemo koristiti bmp slike ili pustiti GLScene da sam kreira slike na osnovu win fontova. Sada cemo zbog jednostavnosti koristiti windows fontove. Na formu cemo postaviti GLWindowsBitmapFont iz GLScene grupe. Tu mozemo izabrati zeljeni font... ja sam postavio na Tahoma, 26, Bold. GLHUDText .BitmapFont property cemo postaviti na GLWindowBitmapFont koji smo malocas postavili na formu i sada mozemo napisati text za HUDText.Text property "GLScene Tutorial 12" i walla



Boja slova se moze menjati propertyem ModulateColor. Rotacija, promena velicine, menjanje pozicije... sve se moze kao i sa ostalim objektima.
Poslednji objekat za ovaj tut je Space Text... to je otprilike kao i HUD Text samo sto se mogu koristiti samo Win fontovi i mogu da imaju 3D oblik... takodje imaju i 3D koordinate kao i svi obicni objekti. Dodacemo jedan objekat tipa GLSpaceText (Add objects->Doodad objects->Space text) i postavicemo ga na -5.4, -3, -8 tako da bude otprilike pri dnu na sredini scene. Izabracemo font (tahoma, 26, bold) i napisati text "by ES Delphi Team (2005)"... i slova su se pojavila, ali ne izgledaju nista bolje od HUDTexta... fazon je u tome sto za Space Text treba svetlo da bi se lepo videlo sve i zato cemo dodati jednu lampicu na scenu. Sad vec izgleda malo lepse, a da bi dodali i 3D izgled Extrusion property cemo postaviti na 0.2. E, sad vec izgleda bolje Naravno, ovde mozemo podesiti i materijal, texturu... sve sto smo mogli na kocki, lopti i ostalim objektima.



Eto, tako se ispisuju slova u GLScene... nista komplikovano, zar ne Sad bi neko mogao da napravi malu animacijicu sa GLSpaceText, HUDText, HUDSprite, GLTimeEventsMGR i slicnim komponenticama za ove nase tutoriale... da vidim da li je neko nesto naucio Posle kad budemo radili i zvuk bice jos bolje... ako neko uradi
[ Srki_82 @ 09.06.2005. 16:41 ] @
Doslo je vreme i za slatke male efekte... vecinu cemo raditi sa cesticama (particle). Sa cesticama mozemo kreirati kisu, vatru, dim i slicne efekte. Cestica je u sustini obican objekat (lopta, kocka, ploca) koja se krece na osnovu nekih podatka... kada je tu samo jedna cestica to i nije bas neki "efekat", ali kad imamo 10... 20... 100... 1000 cestica onda vec mozemo imati neku lepu scenicu. Napravicemo jedan slican programcic kao demo za vatru koji ide sa GLScene.
Dodacemo na formu GLScene, GLSceneViewer, GLCadencer, a na scenu kameru, svetlo, loptu ( 0, 0, -6 ) i torus (Add object->Advanced Geometry->Torus). Torus cemo postaviti isto na 0, 0, -6, a MajorRadius na 2 i MinorRadius na 0.3. Dodacemo jos kod u OnProgress event GLCadencera da se torus okrece
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  GLTorus1.Turn(deltaTime * 20);
  GLTorus1.Pitch(deltaTime * 30);
end;

Jedna od bitnih stvari prilikom kreiranja efekata je svetlost... posto je vatra otprilike narandzaste boje i svetlost bi trebala da bude takva... zato cemo diffuse boju svetla postvaiti na clrOrange i pomericemo svetlost na 0, 0, -4 kako bi izgledalo kao da svetlost dolazi iz vatre.



Sada nam je pozadina scene nekako bezveze obojena u sivo... podesimo GLSceneViewer.Buffer.BackgroundColor na clrBlack kako bi izgledalo da je oko nasih objekata samo mrak



Sada nam ostaje jos samo da napravimo tu vatricu. Prvo sto treba da uradimo je da postavimo GLFireFXManager (GLScene PFX grupa) na formu. Postavimo Cadencer property na GLCandencer1 koji smo vec kreirali. Sada imamo komponentu koja ce nam prikazivati vatru... treba jos samo da je povezemo sa nasim objektom (lopta). Kliknimo desnim na GLSphere1 i u Add efect meniju izaberimo Fire FX. U Scene Editoru izaberimo Fire FX efekat i za Manager property postavimo GLFireFXManager1 koji smo vec kreirali. Da bi nam vatrica izgledala lepse u GLFireFXManageru podesimo FireRadius na 0.4, ParticleInterval na 0.01, ParticleLife na 2 i ParticleSize na 0.4. Pokrenimo sad programcic... iiiiii... vatrica gori, ali nesto nije uredu... vatra je nekako uvek iza torusa iako tako ne bi trebalo. Problem je u tome sto Alphablended objekti moraju da se iscrtavaju na kraju. Da bi smo to ispravili izaberimo GLSphere1 u Scene Editoru i pritisnimo Ctrl+D (ili Move Object Down dugme u tool baru) da bi smo je pomerili na poslednje mesto na sceni. Ako sada pokrenemo program sve ce biti ok



Probajte malo da se igrate propertyima u GLFireFXManageru... vidite kakvu vatru mozete napraviti
[ Srki_82 @ 09.06.2005. 21:40 ] @
Jos jedan lep efekat (meni jos lepsi i laksi za koriscenje od vatre) je ThorFX. To je simulacija munje. Na raspolaganju nam stoji izbor debljine munje, boje, koliko ce munja da oscilira, koliko da se razbacuje... Pokazacemo na prostom primeru kako to izgleda.
Postavicemo na scenu kameru, svetlo i dve lopte na pozicijama -3, 0, -5 i 3, 0, -5. Sad cemo dodati GLThorFXManager sa GLScene PFX palete. Ova komponenta je zaduzena za definisanje izgleda munje. Da bi mogla da radi moramo joj podesiti Cadencer property na GLCadencer komponentu koja je na formi. Sledece sto radimo je dodavanje Thor efekta nasoj prvoj lopti ( -3, 0, -5 ). Desni klik na GLSphere1->Add Effect->ThorFX. Jedino sto mozemo da podesimo za ThorFX evekat su ime i Manager. Postavimo manager na GLThorFXManager koji je na formi. Ovo je sve sto je potrebno da bi se munja videla... ali nismo jos postavili na koju stranu i koliko daleko da se vidi munja. To nam odredjuje GLThorFXManager.Target property. Moramo samo obratiti koju koordinatu tu pisemo jer to nije apsolutna koordinata mete nego relativna u odnosu na nasu loptu tj. objekat koji ima ThorFX efekat. Postavicemo Target na 6, 0, 0 sto znaci da ce munja de se vidi 6 jedinica desno od nase prve lopte sto znaci da ce drugi kraj biti u centru druge. Da munja ne bi izgledala previse velika postavicemo GlowSize na 0.1. I to je to... pokrenimo program i neka munja seva



Experimentisite malo sa osobinama ThorFX efekta (menjajet boje, vibration, velicinu...). Mogu se bas lepi efekti stvoriti ovom komponentom.
[ tamnicar @ 12.06.2005. 10:33 ] @
ko izbrisa onaj tutorial sa modelom ??? :(

pitanje za isti!
hteo bih da napravim da mi se model priblizava iz daljine!
to mize po Z osi Position-a da se uradi!!
recimo GLActor1.Position.Z da ide od -100 do -45!!!!
e sad problem je kako to da uradim???
probao sam kroz petlju FOR, ali se to odradi jako brzo da se i nevidi kretanje, nego se samo model pojavi na position -45!

jel moze pomoc !
[ Srki_82 @ 12.06.2005. 11:07 ] @
Desila se mala havarija sa ES bazom i nestali su neki primeri... i... sad moram ponovo da ih pisem Sreca pa sam i ja na svom racunaro obrisao source svih primercica pa cu i programe morati ponovo da kuckam Blago meni
Ovog puta pravimo kisu (opet). Pocnimo postavljanjem scene i na njoj kameru, svetlo i jednu kocku koja ce se nalaziti na 0, 0, -4, a CubeDepth = 2, CubeHeighte = 0.2 i CubeWidth = 5. Ovo ce biti nas oblak iz kojeg ce da pada kisa (i bice to bas jak pljusak). Kisu cemo kreirati GLPointLightPFXManager komponentom sa GLScene PFX palete. Svi PFX manageri rade na istom principu samo koriste drugacice cestice... PointLight koristi sprajt sa texturom (krug koji je na sredini beo, a sto se ide dalje sve je tamniji), Polygon koristi poligone (moze se birati broj strana i centralni vertex je beo, a krajnji su crni), Custom moze da koristi bilo koji objekat, CustomSprite koristi sprajt sa bilo kakvom texturom, Perlin koristi perlin noise algoritam da bi napravio texturu za sprajt, Line koristi linije. To je otprilike to... sve sto cemo raditi sad sa GLPointLightPFXManagerom moze se raditi i sa bilo koji drugim managerom i rezultati ce biti skoro isti.
Sad cemo podesiti osobine cestica. Podesimo Acceleration na 0, -5, 0 kako bi kapljice brzo padale, AspectRatio na 0.1 da bi cestica bila vertikalno izduzena, ColorInner na belo (to je boja koju cestica ima kad se kreira), ParticleSize na 0,05 jer nam ne trebaju ogromne cestice. Treba jos da definisemo koliko ce dugo cestica biti vidljiva. To radimo uz pomoc LifeColors propertya. Kliknimo na '...' i otvorice nam se prozorcic u kojem pise vreme i boje cestica. Vreme predstavlja vreme u sekundama od nastanka cestice, a boja odredjuje u koju boju ce se cestica promenuti kad dodje to definisanog vremena. Vreme poslednjeg unosa je tagodje i vreme kada ce cestica nestati. Nase kapi ne treba da menjaju boju tako da cemo ColorInner postaviti na belo, a treba samo kratko da se vide pa cemo postaviti vreme na 0.5 sekundi. Skoro da smo zavrsili.
Da bi PFX Manager mogao da se iscrtava moramo na scenu ubaciti PFX Renderer (Add object->Particle systems->PFX Renderer). On je zaduzen za iscrtavanja i ima nekoliko propertya, ali ce nam njihova default vrednost skoro uvek odgovarati pa necemo sad o tome. Postavimo Cadencer i Rendere property za PointLightPFXManager i sada je spreman.
Sve sto nam ostaje je da povezemo cestice sa nasim oblakom. To cemo uraditi tako sto cemo dodati PFX Source efekat nasoj kocki i podesiti proertye. Manager cemo postaviti na PointLightPFXManager koji smo postavili na formu, InitialVelocity na 0, -5, 0 kako bi kapljice odmah imale neku brzinu kad se kreiraju (odmah padaju), ParticleInterval na 0.001 i imacemo pljusak jer ce cestice da se pojavljuju bas brzo, PositionDispersionRange na 3, 0, 1 i PositionDispersion na 0.8 tako da ce cestice da se rasporedjuju po povrsini kocke (random u x i z pravcima), ali nece ici ispod i iznda jer smo Y postavili na 0. To je skoro to. Za kraj podesimo da se forma svaki put iscrtava kako bi smo videli nas efekat
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  GLSceneViewer1.Invalidate;
end;

Pokrenimo program i uzivajmo u kisi



Eksperimentisite malo s osobinama PointLightPFXManagera i PFX Source efekta... malim modifikacijama moze se napraviti kao da pada sneg, da duva vetar gok kisa pada... da pada krv iz kocke Experimentisite
[ Srki_82 @ 12.06.2005. 11:31 ] @
Sledeci efekat je dim (opet ). Koristicemo isti princip kao i kod stvaranja kise samo sa drugim parametrima i ovog puta cemo koristiti PolygonPFXManager, ali, kao sto rekoh, mogli smo koristiti i neki grugi (mozda Perlin... imao bi bas lepe texture za dim). Znaci scena, PolygonPFXManager, na sceni kamera, svetlo, kocka i PFX Renderer. Kocku cemo staviti na -2, -1, -4 i to ce nam biti odzak. Cestice dima cemo ovako da podesimo... Acceleration 0.3, 0, 0 tako da ce dim da ide na desno, ColorInner na belo, ParticleSize na 0.4 i u LifeColor cemo ostaviti samo jedan unos. Boju cemo istaviti na Transparent pa ce dim vremenom da postaje sve providinji, a vreme cemo postaviti na 5 sekundi. Sad jos da podesimo PFX Source efekat za kocku. InitialPosition postavimo na 0.4 tako da se cestice kreiraju malo ispod gornje ivice kocke, InitialVelocity na 0, 0.5, 0 i VelocitiDispersion na 0.1 tako da dim krece na gore, ali da cestice imaju malo razlicite brzine, ParticleInterval na 0,03 da imamo lep gust dim, PositionDispersionRange na 1, 0, 1 i PositionDispersion na 0.2 da dim ne izlazi samo iz jedne tacke i to je to. Napisimo samo jos i OnProgress event
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
begin
  GLSceneViewer1.Invalidate;
end;

Pokrenimo program i dim ce da izlazi iz odzaka



Probajte da menjate verdnosti managera i efekta da vidite kako uticu na izgled dima.
[ Srki_82 @ 12.06.2005. 13:41 ] @
Poslednji od tutoriala koji je "nestao" zbog havarije baze je ponovo tu
Ucitavanje 3d objekta i animacija iz fajla kao i menjanje texture objektu u runtime.
Radicemo sa GLActor objektom. On je dizajniran tako da se fajlovi lako ucitavaju i animacije lako biraju i pustaju.
Postavicemo na formu scenu i cadencer, a na sceni ce biti kamera, svetlo i jedan GLActor objekat (Add object->Mash objects->Actor). Postavicemo ga na 0, 0, -4, posto je objekat prilicno velik moracemo da ga malo smanjimo pa cemo Scale postaviti na 0.05, 0.05, 0.05 i jos cemo PitchAngle postaviti na 90 jer je orientacija Quake 2 modela (koristicemo Quake 2 model... samo da znate) malo drugacija od GLScene. Model mozete skinuti ovde. Sada cete videti kako je lako ucitati objekat i njegovu texturu. Napisimo OnCreate event za formu
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  GLActor1.LoadFromFile('waste.md2');
  GLActor1.Material.Texture.Image.LoadFromFile('waste.jpg');
  GLActor1.Material.Texture.Disabled := False;
end;

I to je to



Ovo cak i ucitava animacije iz Quake 2 modela. Jedino sto moramo da uradimo je da dodamo u unit deo GLFileMD2 i JPEG unite da bi fajlovi mogli da se ucitaju. Prilicno lako, zar ne?
Sada cemo napraviti da se textura objekta menja kliknom na formu. Zajedno sa modelom se nalaze i dve texture Waste.jpg i WasteCell.jpg. WasteCell.jpg je malo modivikovana verzija obicnog skina za nas model i klikom na formu ce se ove texture menjati. Dodacemo jednu globalnu promenljivu
Code:
var
  TextureName: String;

Malo modifikovati OnCreate event forme
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  GLActor1.LoadFromFile('waste.md2');
  GLActor1.Material.Texture.Image.LoadFromFile('waste.jpg');
  GLActor1.Material.Texture.Disabled := False;
  TextureName := 'waste.jpg';
end;

i dodati OnClick event za SceneViewer
Code:
procedure TForm1.GLSceneViewer1Click(Sender: TObject);
begin
  if TextureName = 'waste.jpg' then
    TextureName := 'wastecell.jpg'
  else
    TextureName := 'waste.jpg';
  GLActor1.Material.Texture.Image.LoadFromFile(TextureName);
end;

Opet nista komplikovano... jednostavno ucitavamo novu texturu umesto stare
I za kraj... konacno... animacija Dodacemo jedan ComboBox pomocu kojeg cemo birati animacije i postavicemo Style na DropDownList. Prva stvar je da napunimo ComboBox nazivima animacija. Za to ce nam posluziti Funkcija GLActor.Animations.SetToStrings. Ona ubacuje u bilo koju promenljivu tipa TStrings (ili neke klase koja je nasledjuje) nazive animacija. Sledece sto treba da uradimo je da prilikom promene izabrane stavke u ComboBoxu pustimo animaciju. Animacija se pusta tako sto se izabere ime animacije ili njen redni broj funkcijom GLActor.SwitchToAnimation i postavi zeljeni nacin pustanja animacije GLActor.AnimationMode koji moze biti aamNone (nema animacije), aamPlayOnce (animacija se samo jednom pusti), aamLoop (animacija se stalno vrti), aamBounceForward (ide od pocetka do kraja, pa od nazad do pocetka), aamBounceBackward (od nazad ka pocetku, pa od pocetka prema kraju) ,aamLoopBackward (vrti se unazad), aamExternal (animacija stoji i pozivanjem NextFrame ili PrevFrame menjamo trenutni frejm).
Modifikovacemo malo OnCreate event forme i dodati OnChange evet ComboBoxu
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  GLActor1.LoadFromFile('waste.md2');
  GLActor1.Material.Texture.Image.LoadFromFile('waste.jpg');
  GLActor1.Material.Texture.Disabled := False;
  TextureName := 'waste.jpg';
  GLActor1.Animations.SetToStrings(ComboBox1.Items);
  ComboBox1.ItemIndex := 0;
  ComboBox1Change(ComboBox1);
end;

Code:
procedure TForm1.ComboBox1Change(Sender: TObject);
begin
  GLActor1.SwitchToAnimation(ComboBox1.Text);
  GLActor1.AnimationMode := aamLoop;
end;

I to je sve... objekat se animira i mozemo da mu menjamo texturu i to prilicno lako



Eto... konacno sam ispisao sve tutoriale koji su nestali... i sad mozemo na nove. Sledeci ce biti neverovatno laki, ali i prilicno korisni. Uradicemo GLBlur (zamucuje scenu ili samo neki objekat) i GLTrial (pravi trag iza objekta) komponente. Biti potrebno da kucamo program... sve cemo zavrsiti u Scene Editoru i ObjectInspectoru u designtime
[ PeraKojotSuperGenije @ 12.06.2005. 13:54 ] @
Svaka cast Srki_82! Tutorijal je odlican i lako razumljiv. Samo tako nastavi!

Prosao sam kroz vecinu lekcija, a malo sam i sam eksperimentisao i napravio sam malu animaciju...

Koristio sam nekoliko novih stvari:

1) Scene Objects->Add object->Doaded Objects->Tree. Oblik drveta mozete promeniti podesavanjem parametara drveta (depth, branch*, leaf*, seed, ...). Da bi listovi bili zeleni a stablo i grane braon boje neopodno je koristiti GLMaterialLibrary u kome cete napraviti potrebne materijale/boje i obavezno im dati imena. U polja LeafMaterialName i BranchMaterialName treba uneti zeljene materijale (OVA POLJA SU CASESENSITIVE!!!).

2) AsyncTimer (sa palete GLSceneUntils), koji se ponasa isto kao i standardni tajmer sa palete System. AsyncTimer-u mozete podesavati prioritet i to je cini mi se jedina razlika u odnosu na TTimer.

3) Scene Objects->Add object->Basic Geometry->Points. Tacku sam koristio kao izvor za grom i vatru

4) Scene Objects->Add object->Basic Geometry->Plane. Ravan je sluzila kao sivo nebo koje je izvor kise i cini mi se da je ovo malo stedljivije resenje od GLCube. Pomocu ravni sam napravio i zelenu podlogu.

Boju pozadine GLSceneViewer-a je ista kao i boja neba!

GLPoint1, koja je izvor groma se nalazi malo iznad ravni koja predstavlja nebo. Dok grom udara u drvo, dva puta mi se menjaju koordinate za Target i tako je dobijen efekat "setanja" groma.

GLPoint1/2/3, koje su izvor vatre se nalaze "negde na drvetu". Tri razlicita izvora i tri razlicite vatre sam koristio kako bih napravio "realistican" efekat sirenja vatre, postepenim paljenjem jednog po jednog izvora. Negde u centru drveta nalazi se i jedan narandzast iyvor svelosti koji je na pocetku animacije ugasen, pa se postepeno pojacava kako se vatra siri.

AsyncTimer aktivira i gasi efekte, a cini mi se da je sve moglo da se odradi jednostavnije i udobnije komponentom TimeEvents (sa tog casa sam povegao:-)).

Pitanja: Kako napraviti dim sive boje. Ja sam probao, ali ne umem.
[ Srki_82 @ 12.06.2005. 14:28 ] @
Pricao sam vam o texturama i blending modovima, zar ne?
Po defaultu BlendingMode za PFX efekte stoji na Aditive sto znaci da se boja cestice sabere sa bojom pozadine i tako se dobije nova boja... posto je siva boje jednostavno zatamnjena bela kada je postavimo dim samo posvetli pozadinu... logicno Da bi boja bila siva potrebno je BlendingMode postaviti na Transparency. Evo primera sa dimom koji koristi PerlinPFXManager... svi podaci su isti kao i kod prethodnog primera sa dimom jedino sto se koristi drugi generator i drugi BlendingMode.



BTW: Odlican ti je demo, samo tako nastavi
[ Srki_82 @ 12.06.2005. 15:54 ] @
U ovom primeru cemo raditi sa GLBlur objektom. On "zamucuje" objekta u koji je postavljen. Postoje nekoliko modova u kojima moze da radi. Vrlo je bitno samo postaviti GLSceneViewer.Buffer.BackgroundColor na crno inace ce GLBlur da zezne celu scenu (cela scena ce biti boje pozadine sa nekim mrljama... probajte pa cete videti). Postavicemo scenu i cadencer i na sceni kameru, svetlo, kocku (na 0, 0, -3 sa zutom bojom) i u kocki GLBlur (Add object->Speciao objects->GLBlur). I to je to Nista vise nije potrebno da bi blur radio. Da smo ga postavili direkno na scenu tada bi cela scena bila zamucena. Pogledajte property Presets i probajte da ga menjate i vidite kako sve objekat moze da bude zamucen.
Da scena ne bi bila bas nepomicna dodacemo Simple Inertia behaviour kocki i podesiti PitchSpeed na 20 i RollSpeed na 30. Moracemo samo da dodamo u unit deo i GLBehaviours.
Pokrenimo program i gledajmo kako se kocka zamucuje



Ovako je lako koristiti i GLTrial... videcete u sledecem primeru
[ Nemanja Avramović @ 12.06.2005. 21:59 ] @
Imam ja sacuvanu jednu ipo html stranu od starih primera... evo linka:
http://rapidshare.de/files/2343224/GLScene_tutorials.zip.html
[ Srki_82 @ 12.06.2005. 23:42 ] @
Vec sam ponovo napisao tutoriale koji nisu bili tu... tako da... sve je ponovo tu

BTW: Sta kazete da posle GLTrial komponente predjemo malo na zvuk... tu se necemo mnogo zadrzati jer je prilicno lako. Ako neko bude hteo da napravi demo kao PeraKojotSuperGenije mocice da koristi i zvuk Onda zvuk ili nesto drugo?
[ Nemanja Avramović @ 12.06.2005. 23:52 ] @
ja predlazem kuliranje od 15-20 dana, dok prodje prijemni
[ Srki_82 @ 13.06.2005. 00:27 ] @
@tamnicar
Izvini sto si cekao... zurio sam da vratim stare tutoriale i da dodam bar jedan nov.
Ovako... tutorial za model imas ponovo, a sto se tice pomeranja ubaci nesto ovako u Cadencer.OnProgress event
Code:
procedure GLCadencer1.OnProgress(...);
begin
  if GLActor1.Position.DirectZ < -40 then
    // Ako ide sporo postavi vecu vrednost od 5
    GLActor1.Position.Translate(0, 0, 5 * deltaTime)
  else
    GLActor1.Position.DirectZ := -40;
end;

Nadam se da je to ono sto ti treba.

@JaHvram
Nema sanse
[ tamnicar @ 13.06.2005. 10:31 ] @
samo da ispravim: :)
Code:

procedure GLCadencer1.OnProgress(...);
......
    GLActor1.Translate(0, 0, 5 * deltaTime)
 ......
end;

hvala na code-u, radi odlicno!
p.s.
nisi morao sve sam da vratish od tutoriala, mogli smo ti i mi pomoci, kad si i ti nama!
ja sve stranice dzim u cache-u za svakodnevni pregled!!!
[ PeraKojotSuperGenije @ 13.06.2005. 12:05 ] @
@Srki_82: Zvuk!
[ Srki_82 @ 13.06.2005. 18:44 ] @
Jos jedan ultra lak za napraviti efekat GLTrail objekat ostavlja trag iza objekta koji se pomera (cesto se koristi taj efekat u borilackim igrama kada se igrac pomera neveroavtno brzo i slicno). Hajde da probamo da uradimo primercic sa ovom komponentom. Postavimo scenu i cadencer, a na sceni kameru, svetlo, DummyCube (0, 0, -4) i u njoj npr. GLIcosahedron (0, 1.5, 0). Na kraju dodajmo i GLTrial (ovaj objekat ne bi trebalo da se nalazi u drugim objektima jer trag moze da se pomeri na neku bezveznu poziciju), a TrialObject na GLIcosahedron koji smo kreirali. Ovo je sve sto je potrebno da bi TrialObject radio... ustvari... da bi videli trag objekat mora da se krece. Zato smo postavili DummyCube... dodacemo joj Simple Inertia i postaviri RollSpeed na 120. Da Simple Inertia moze da radi moramo u uses dodati GLBehaviours (to je jedino sto moramo da kuckamo u programu) i pokrenimo ga



Prilicno lako i jednostavno
Sledece na repertoaru su zvukovi (2d i 3d).
[ Srki_82 @ 13.06.2005. 21:02 ] @
Danas ce se u nasem i vasem GLScene tutorialu po prvi put pustati TON FILMOVI
Konacno i malo zvuka... pocecemo sa direknim pristupom BASS Sound engine-u. Necemo koristiti nikakve komponente jedino Bass unit iz GLScene.
Evo nekih informacija o BASS Sound Engine

Da pocnemo... postavite dva dugmeta na formu. Prvo ce nam sluziti za pustanje, a drugo za zaustavljanje muzike. Dodajte jedan CheckBox... kada bude "ukljucen" fajl ce se ponavljati, a ako ne bude odsvirace jednom i kraj. Za kraj dodacemo jos i OpenDialog da bi smo lakse nalazili fajlove za pustanje, a sad kod.
Da bi BASS radio moramo dodati u uses deo Bass unit
Code:
uses
  Bass;

Podesimo OnCreate event za formu
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  BASS_Load(BASS_DLL);
  BASS_Init(1, 44100, 0, Application.Handle, nil);
  BASS_Start;
end;

Kao prvo moramo ucitati Bass.dll i to radi BASS_Load funkcija. BASS_DLL je samo konstanta (string) definisana u Bass.pas unitu i ima vrednost 'bass.dll'. Ako budete menjali ime dlla ne onda cete umesto BASS_DLL upisati to novo ime.
Sledece je incijalizacija engine-a. BASS_Init uzima kao prvi parametar redni broj uredjaja na kojem ce se pustati zvuk, zatim frekvencija zvuka (44100 se koristi za snimanje CD-ova), zatim Handle prozora koji ce se koristiti za poruke (Application.Handle se moze uvek koristiti), i na kraju mozemo uneti pointer na GUID kartice koju zelimo da koristimo... ako postavimo nil koristice se default kartica (uglavnom svi imaju samo jednu karticu pa uvek mozemo stavljati nil).
Na praju pokrecemo engine (pritiskamo play) pozivom na BASS_Start.

Sad cemo dodati OnDestroy event za formu
Code:
procedure TForm1.FormDestroy(Sender: TObject);
begin
  BASS_Stop;
  BASS_Free;
  BASS_Unload;
end;

Ovde je sve jasno... zaustavljamo engine, oslobadjamo memoriju koju jeengine zauzeo i na kraj ga oslobadjamo dll koji smo na pocetku ucitali.

Hajde da pustimo neku muzikicu Da bi smo mogli da pustimo muziku moramo imati jednu promenljivu koja ce drzati trenutno aktivni fajl pa cemo dodati globalnu promenljivu
Code:
var
  S: HStream;

Podesimo sada OnClick event drugog dugmeta (ono dugme koje ce zaustavljati muziku)
Code:
procedure TForm1.Button2Click(Sender: TObject);
begin
  if S <> 0 then BASS_StreamFree(S);
  CheckBox1.Enabled := True;
end;

Kada ni jedan fajl nije ucitan S ima vrednost 0, a ako ima neku drugu vrednost oslobadjamo taj fajl i on se zaustavlja.
Sad ide ton OnClick event prvog dugmeta izgleda ovako
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then
  begin
    Button2.Click;
    S := BASS_StreamCreateFile(False, PChar(OpenDialog1.FileName), 0, 0, BASS_STREAM_AUTOFREE);
    if CheckBox1.Checked then
      BASS_StreamPlay(S, False, BASS_SAMPLE_LOOP)
    else
      BASS_StreamPlay(S, False, 0);
  end;
  CheckBox1.Enabled := False;
end;

Ako izaberemo neki fajl u OpenDialogu prvo zaustavljamo muziku klikom na Button2 i zatim otvaramo fajl funkcijom BASS_StreamCreateFile. Prvi parametar oznacava da li je fajl ucitan u memoriju (npr. imate neki buffer u koji ste prethodno ucitali fajl i pustate muziku iz njega). Drugi parametar je naziv fajla ako pustamo sa diska, a ako pustamo iz memorije onda je to pointer na pocetak buffera. Sledeca dva parametra oznacavaju pocetak i duzinu u fajlu koji ce se svirati u semplovima (ako je fajl snimljen u 44100Hz onda je 1 sekunda 44100 semplova). Ako su oba parametra 0 svira se zeo fajl. I na kraju je flag koji oznacava kako se fajl svira. BASS_STREAM_AUTOFREE znaci da ce fajl biti automatski oslobodjen cim se odsvira do kraja. To je to vezano za ucitavanje. Sledece je na redu pustanje... funkcija BASS_StreamPlay pusta fajl koji mu prosledimo kao prvi parametar. Drugi parametar oznacava da li da se svi podaci snime u fajl pre pustanja ako je nesto bilo snimljeno u njemu pre pozivanja BASS_StreamPlay funkcije. I na kraju imamo flag koji moze da natera fajl da se pusta iz pocetka, da svira kao da je mono zvuk, kao da je 8bit, 16bit, 32bit, itd... Nama je sad interesantan BASS_SAMPLE_LOOP koji govori engine-u da stalno ponavlja zvuk.

I to je to... pokrenite program i probajte da nesto pustite. BASS zahteva da imate instaliran bar DirectX 3 pa... ako nemate nece raditi
[ Srki_82 @ 14.06.2005. 18:31 ] @
Sada cemo koristiti komponentu GLSMBASS koja ce umesto nas odraditi svu inicijalizaciju kao i oslobadjanje memorije na kraju. Takodje cemo pokazati kako se pustaju 3D zvukovi.
Odmah da napomenem... muzika koju smo pustali u proslom primeru moze da bude mono, stereo, 5.1... ne bitno je, ali kada se zvik pusta u 3D prostoru mora biti mnono. Ako zvuk nije mono program ce prijaviti gresku. Malo je nemoguce pustiti stereo zvuk iz jedne tacke u protoru, zar ne? Zvuk ce se automatski prebacivati sa levog na desni ili na neki drugi ako imate vise zvucnika u zavisnosti od mesta gde je zvuk nastao i mesta u prostoru gde se nalazi objekat koji prima zvukove.
Pocecemo postavljanjem scene, cadencera i jos dve komponente koje do sad nismo koristili... GLSoundLibrary i GLSMBass. Bitno je da prvo postavimo GLSMBass jer on mora da se kreira pre ostalih komponenti koje koriste zvuk. GLSoundLibrary je otprilike kao i GLMaterialLibrary samo sto ne cuva texture i boje nego zvukove. GLSMBass je sound manager i on je zaduzen da pusta zvukove. Sound Manager moze pustati samo zvukove koji su u SoundManageru. Naravno, koriscenjem funkcija za ucitavanje i pustanje muzike koje smo koristili u proslom primeru moguce je pustati i zvukove koji nisu u SoundLibrary. Jos nesto da napomenem... sve fajlove koje ubacimo u SoundLibrary bice snimljeni zajedno sa exe fajlom.
Hajde prvo da dodamo neki fajl u SoundLibrary. Kliknimo na '...' u Samples propertyu. Otvorice nam se prozorce u kojem cemo videti sve fajlove koje smo ucitali. Kliknimo na Add new. Svaki fajl tj. sample ima 2 propertya... Data (podaci koji su potrebni za sviranje) i Name (naziv sempla). Kliknimo na '...' u Data property i izaberimo fajl koji hocemo da ucitamo. SoundLibrary podrzava samo mp3 i wav fajlove pa smo ograniceni na njih. Izabracemo, recimo, C:\Windows\Media\RingOut.wav... taj fajl bi svi trebalo da imaju (zapamtite, mora da bude mono). To nam je dovoljno za nas primer.
Sledece sto cemo da uradimo je da graficki prikaz polozaja zvuka i mesta odakle slusamo. Dodajmo kameru, svetlo, ArrowLine, DummyCube i u njoj Sphere na scenu. Za ArrowLine postavimo poziciju na 0, 0, -10, Direction na 0, 1, 0 i Up na 0, 0, 1. DummyCube postavimo na 0, 0, -10, a Sphere na 0, 5, 0. Da bi strelica bila objekat koji "slusa" postavimo GLSMBass.Listener na ArrowLine koji smo kreiarli. Kad smo vec tu postavimo i GLSMBass.Cadencer na cadencer objekat koji je na formi i Active na True da bi uopste nesto culi
Jos malo i zavrsili smo Sada treba da pustimo zvuk iz lopte. Dodacemo Sound Emitter iz Add behaviour menija. Kliknimo na Sound Emitter u Scene Editoru da bi smo editovali propertye. Postavimo Source.SoundLibrari na GLSoundLibrary1 objekta koji je na formi, a Source.SoundName na 'ringout.wav'. NbLoops oznacava koliko ce se puta zvuk ponavljati. Ova funkcionalnost jos nije zavrsena pa za sve brojeve preko 1 zvuk se ponavlja dok ga mi ne zaustavimo. Postavicemo NbLoops na 2 da nam zvukic stalno svira. Poslednje sto cemo uraditi ovde je postavljanje Playing propertya na True
Ovde postoje jos nekoliko korisnih propertya koje nismo koristili. Volume je vrednost od 0 do 1 koja ozvacava glasnocu. Min i Max Distance odredjuju koliko daleko od izvora se cuje zvuk... experimentisite malo s osobinama da ih bolje razumete.
Da zvuk ne bi dolazio samo iz jednog smera postavicemo Simple Inertia za DummyCube objekat i staviti RollSpeed na 20 (moramo dodati u uses GLBehaviours, ne zaboravite). I pokrenimo sada primer... kao sto vidite kako se lopta okrece oko strelice tako i zvuk kruzi sa desnog na levi zvucnik i obrnuto
Ne znam za vas, ali meni je bilo zaista drago kad sam ukapirao kako se lako koriste 3D zvukovi
GLSMFMOD se koristi POTPUNO ISTO kao i GLSMBASS. Ako neko zeli moze probati da uradi isti ovaj primer, ali sa GLSMFMOD objektom. Nemojte samo zaboraviti da Sound Manager objekat mora prvi da se stavi na formu inace zvuk nece raditi.
[ Srki_82 @ 18.06.2005. 18:13 ] @
Pa... sad znamo dosta stvari koje nam mogu olaksati pravljenje 3d aplikacija... ali jos ne znamo kako da detektujemo sudar dva objekta i sad cemo to da naucimo. Kao i sve ostalo u GLScene i ovaj problem je jednostavno resiti
Koristicemo CollisionManager komponentu sa GLScene Utils palete i ona ce proveravati umesto nas da li se nesto sudarilo na sceni.
Pre nego sto pocnemo vrlo je bitno znato da CollisionManager nije savrsen... ovo je tabela koja nam govori sta radi precizno, a sta ne



Da pocnemo... postavimo sve sto nam treba za scenu (ukljucujuci i cadencer) i dodajmo CollisionManager. Dodajmo na scenu kameru, svetlo, DummyCube ( -3, 0, -10 ) i u njoj GLSphere ( -5, 0, 0 ), i jos jednu DummyCube ( 4, 0, -10 ) i u njoj GLCube ( 3, 0, 0 ). DummyCube ce nam sluziti da rotiramo nase objekte kako bi se oni s vremena na vreme dodirnuli. Dodajmo za DummyCube sa loptom Simple Intertia behaviour i postavimo RollSpeed na 50, i dodajmo za DummyCube koja sadrzi kocku takodje Simple Inertia behaviour i postavimo RollSpeed na 120. Posto smo koristili Simple Inertia moramo u uses dodati GLBehaviours unit. Pokrenimo program i videcemo kako se lopta i kocka okrecu i dodiruju se u odredjenim trenucima. Sada cemo dodati deo koji ce detektovati sudar. Dodajmo za loptu i kocku Collision behaviour. Ova osobina povezuje objekte sa CollisionManagerom i omogucava mu da odradjuje kad su se dodirnuli. Podesimo prvo Collision behaviour za loptu. Podesimo prvo Manager property na CollisionManager1 koji smo postavili na formu. Ovaj property oderdjuje koji ce manager biti zaduzen za ovaj objekat. Zatim BoundigMode postavimo na Sphere. Ovo je nacin na osnovu kojeg ce se odredjivati da li se objekat sudario. Kada je ovaj property on se tretira kao kocka u koju moze da stane ceo objekta, ako je Ellipsoid onda je to izduzena lopta, ako je Faces onda se koristi bas oblik objekta (ovo je najsporiji nacin), ako je Point koristi se samo tacka u sredini objekta (ubedljivo najbrzi i najneprecizniji nacin), i ako je sphere koristi se lopta u koji staje ceo objekat. Posto koristimo loptu logicno je da cemo izabrati Sphere. GroupIndex je property koji odredjuje sa kojim objektima ce biti proveravano da li su sudareni. Samo objekti sa istim GroupIndexom ce biti provereni da li se dodiruju. GroupIndex necemo dirati. Za kocku cemo postaviti Manager, a BoundingMode postaviti na Cube.
To je dovoljno informacija za CollisionManager da oderdi da li se nasi objekti dodiruju. Dodajmo sada globalnu promenljivu Sudar: Boolean koja ce biti True ako su se objekti sudarili i postavimo CollisionManager.OnCollision event na
Code:
procedure TForm1.CollisionManager1Collision(Sender: TObject; object1,
  object2: TGLBaseSceneObject);
begin
  Sudar := True;
end;

Ovaj event nam prosledjuje koji su se objekti sudarili. Ovo nam je vrlo vazno ako imamo vise objekata, ali u nasem slucaju imamo samo 2 pa znamo da su se oni sudarili i postavljamo Sudar na True.
Moramo i vizuelno prikazati da li su se objekti sudarili ili ne i to cemo uraditi bojama. Dodajmo jedan GLMaterialLibrary i napravimo material No koji ce biti plave boje i materijal Yes koji ce biti crvene. Postavimo za pocetak i za loptu i za kocku material No. Sada cemo u GLCadencer.OnProgress da detektujemo sudar i da promenimo boju objekata ako je potrebno
Code:
procedure TForm1.GLCadencer1Progress(Sender: TObject; const deltaTime,
  newTime: Double);
var
  oldSudar: Boolean;
begin
  oldSudar := Sudar;
  Sudar := False;
  CollisionManager1.CheckCollisions;
  if Sudar <> oldSudar then
    if Sudar then
    begin
      GLSphere1.Material.LibMaterialName := 'Yes';
      GLCube1.Material.LibMaterialName := 'Yes';
    end
    else
    begin
      GLSphere1.Material.LibMaterialName := 'No';
      GLCube1.Material.LibMaterialName := 'No';
    end;
end;

oldSudar nam sluzi samo da ne bismo postavljali nov material pri svakom iscrtavanju jer do znatno smanjuje FPS. Prvo postavljamo Sudar na False (predpostavljamo da se objekti nisu sudarili) i onda pocivamo CollisionManager.CheckCollisions da proveri da li ima nekih sudara. Ako ima poziva se OnCollision event koji u nasem slucaju postavlja Sudar na True. U zavisnosti od vrednosti Sudar promenljive postavljamo boje nasih objekata. To je sve



Sledeci primer ce pokazati kako je jos moguce izvrsiti proveru sudaranja (napravicemo lopticu koja se odbija od zidova)
[ Srki_82 @ 20.06.2005. 22:53 ] @
Napravio sam jedan kratak demo u kojem sam koristio ovo sto smo do sad odradili... ucitavanje 3d objekata, postavljanje textura, pomeranje i rotiranje objekata, efekte sa cesticama, zvukovi (Sound Emitter + pozadinska muzika)... mozda jos nesto, ali mislim da je to to... demo traje oko 60 sekundi, ali je exe (nema koda ovog puta... probajte sami da napravite nesto slicno ) "malo" tezi zbog modela, textura i zvukova... ima oko 3MB, a mene veceras nesto mnogo zeza wierless pa ne znam da li cu uspeti da posaljem fajl, ali ovih dana cu ga sigurno postaviti.
Nadam se da ce vam se svideti bar malo... izgubih skoro pola sata rada na ovome
[ Srki_82 @ 21.06.2005. 16:36 ] @
I, evo demo o kojem sam pricao. GeoCities nesto ne dozvoljava da se ovako velik fajl skine van njega morate otici ovde da bi ste skinuli program.

Imate u zipu sve sto je potrebno da pokrenete program. Model mozete slobodno koristiti u nekomercijalnim programima... pa... mozda neko napravi neki mnogo bolji demo od mene.
[ Srki_82 @ 21.06.2005. 20:36 ] @
Ako neko nema dovoljno dobru karticu da pokrene demo evo par slicica







I... kako vam se cini demo?
[ PeraKojotSuperGenije @ 21.06.2005. 23:49 ] @
Demo je odlican!
Kako si napravio onu "maglu koja se vidi u daljini"?
[ Srki_82 @ 22.06.2005. 00:05 ] @
Velika lopta (radius 1000) sa providnom sarenom texturom :)
[ tamnicar @ 22.06.2005. 10:53 ] @
odlično :)
mogao si samo staviti broj FPS-a, čisto da se ima uvid ;)
[ Srki_82 @ 23.06.2005. 17:11 ] @
Eeee... vidis... zaboravih na FPS
Pa... mogao bi neko da uradi nesto slicno i da ubaci i FPS.

U ovakvoj animaciji bi prilicno lepo izgledalo da Enterprise ispali laserski zrak na neki od asterioida i da se on raspadne. Zrak bi mogao vrlo lako da se naprvi koriscenjem ThorFX... vatra u eksploziji nekim od ParticlePFX managerom i sa nekim crvenim svetlom, ali raspad 3d objekta i nije bas tako lak... ili... da li je?
U GLScene postoji ExplosionFx koji sluzi da "explodira" neki 3d objekat. Imajte na umu da ne mogu svi objekti da koriste ovaj efekat... samo oni koji sadrze podatke o mesh-u (vertexi, normale, koordinate textura) kao sto su GLFreeForm i GLActor.
Opet cemo koristiti Waste model. Postavimo na scenu kameru, svetlo i jedan GLFreeForm (0, 0, -4) objekat. Posto je Waste.md2 malo velik postavimo Scale na 0.05, 0.05, 0.05 i zbog razlike u orientaciji PitchAngle na 90. Sada da ucitamo nas model, a to vec znate kako se radi
Code:
uses
  GLFileMD2;

procedure TForm1.FormCreate(Sender: TObject);
begin
  GLFreeForm1.LoadFromFile('waste.md2');
end;

Sada dodajmo ExplosionFx efekat GLFreeForm objektu.
Direction property odredjuje na koju stranu ce parcici objekta biti "oduvani". Ako je Directino 0, 0, 0 onda se razlecu na sve strane.
MaxSteps odredjuje koliko ce dugo u "koracima" ce explozija da traje dok objekat ne postane nevidljiv.
Speed je brzina kretanja delova.
Ovo je jedan od komponenti koja ima bug... sve sto se podesi u designtime ne utice na ExplosionFx tako da se svi parametri moraju podesavati u runtime... nista nije savrseno
Bacimo jedan TButton na formu u kojem cemo podesiti sve sto nam je potrebno i pokrenuti exploziju
Code:
uses
  GLExplosionFx;

procedure TForm1.Button1Click(Sender: TObject);
begin
  with TGLBExplosionFx(GLFreeForm1.Effects.Items[0]) do
  begin
    MaxSteps := 0;
    Speed := 0.1;
    Enabled := True;
  end;
end;

U Cadencer.OnProgress dodajmo da svaki put iscrtava scenu (GLSceneViewer1.Invalidate) i pokrenimo program. Kada kliknemo da dugme objekat se raspada



Problem je ako zelimo da imamo sacuvane podatke o objektu i posle explozije jer jexplizija menja koordinate vertexa i oni se vise ne mogu vratiti... zato ako je potrebno prvo treba napraviti kopiju objekta i tak onda pokrenuti exploziju. Dodacemo jos jedan GLFreeForm objekat koji ce nam cuvati podatke i u OnCreate eventu forme napisati
Code:
procedure TForm1.FormCreate(Sender: TObject);
begin
  GLFreeForm1.LoadFromFile('waste.md2');
  GLFreeForm2.Assign(GLFreeForm1);
  GLFreeForm2.Visible := False;
end;

Time cemo sve podatke iz GLFreeForm1 prebaciti u GLFreeForm2 i postaviti da se drugi objekat ne vidi.
Sada jos samo da malo promenimo OnClick event dugmeta i mocicemo da klikcemo koliko hocemo i da nas objekat svaki put explodira iz pocetka
Code:
procedure TForm1.Button1Click(Sender: TObject);
begin
  TGLBExplosionFx(GLFreeForm1.Effects.Items[0]).Reset;

  GLFreeForm1.Assign(GLFreeForm2);
  GLFreeForm1.Visible := True;

  with TGLBExplosionFx(GLFreeForm1.Effects.Items[0]) do
  begin
    MaxSteps := 0;
    Speed := 0.1;
    Enabled := True;
  end;
end;

Prvo sto radimo je zaustavljanje explozije, zatim prebacujemo podatke o izgledu objekta u GLFreeForm1 i postavljamo VIsible na true da bi se video... ostatak je poznat. Probajte sad program

Explozija i nije mnogo realna... ali bar se lako koristi i bolja je nego nista

BTW: Sta bi zeleli da sledece radimo? Imamo scripting, shadere, physic... Ako neko ima neku zanimljivu ideju (animaciju, igru, demo...), a ne moze sam da se snadje neka PM pa cu mu ili joj pomoci.
[ tamnicar @ 23.06.2005. 19:07 ] @
ja bih voleo konacno da napravimo (napravis :) ) neki PixelShader efekat!!!
recimo "lelujanje" vazduha iznad vatre ili nekog objekta koji odaje toplotu!!!
ako znas nasta mislim :)

i druga stvar!!! stavite ovu temu za TOP, pa red je :)

i treca stvar... Srkija za predsednika !!! malo li je :)
[ Srki_82 @ 23.06.2005. 22:47 ] @
Citat:
tamnicar: ja bih voleo konacno da napravimo (napravis ) neki PixelShader efekat!!!
recimo "lelujanje" vazduha iznad vatre ili nekog objekta koji odaje toplotu!!!
ako znas nasta mislim

Znam na sta mislis, ali nazalost imam GeForce4 MX 440 with AGP8X/AGP/SSE/3DNOW! karticu koja ne podrzava ni Cg ni GLSL shadere tako da ce neko drugi morati da napise te tutoriale. Ne znam tacno koje kartice imaju podrsku za ove shadere.
Jedine shadere koje mogu da objasnim su oni koji idu sa GLScene (oni su samo cisto postavljanje parametara za OpenGL pre iscrtavanja objekta kao sto su debljina linije, boja objekta i slicno...)... sorry... kad kupim neku GForce 68xx karticu onda cu mozda napisati nesto na tu temu
[ milika @ 27.06.2005. 03:26 ] @
Evo mog malog i pocetnickog Screen Savera koristeci
Delphi i glscene....

Idite na www.milika.net pa izaberita AQUA-Kompjuteri...
Prva vest je Screen Saver...

Ne ocekujte puno, ovo mi je prvi primercic :)

Pozdrav i hvala na tutorijalu!!!
[ Nemanja Avramović @ 03.07.2005. 14:25 ] @
Ja sam propustio jedno 20 lekcija :( sada je prosao prijemni pa cu narednih par dana da citam ovo i da eksperimentisem, a ti Srki - cekaj jos malko :) i mozda ces dobiti neki lep demo :)

@milika: meni tvoj screensaver ne radi... a zasto? nem' pojma... da nisi koristio nesto cega nema na mom racunaru? :)
[ milika @ 03.07.2005. 16:48 ] @
Pa sta "kaze"???
[ Srki_82 @ 03.07.2005. 17:54 ] @
Problem je sa shaderima ili velikim brojem textura. I kod mene se ne vidi text, a sve ostalo radi.
[ Nemanja Avramović @ 03.07.2005. 19:19 ] @
meni izbaci neki showmessage, cuje se beep, a onda se cela app ugasi.. ne stignem da procitam message :(
[ stefanglscene @ 30.07.2006. 12:27 ] @
Pozdrav svima!!Najvishe se zahvaljujem srkiju jer bih onako ja morao sam sve da testiram i da prevodim sa engleskog he he!!!Ovako ja sam preshao sve lekcije!!!GlScene je prost!!!Hocu da napravim 3D igricu ali ozbiljnu 3D igricu!!Ja imam 16 god a u programiranju sam vec odavno!!!Dobro poznajem pascal delphi kao i ostale programske jezike.Igrica bi trebala da bude na principu GTA San Andreasa samo sto bi tu vishe paznje bilo posveceno kolima i ostalim voznim objektima!!Ako neko hoce da napravimo tim i da zapocnemo projekat bilo bi vrlo sjajno da mi poshalje PM ili mail??
[ vladaboy93 @ 27.04.2007. 17:32 ] @

Rekao si nesto kao GTA San Andreas. Taj program(igricu) je pravilo najmanje stotinak veoma iskusnih programera,dizajnera,modelara,... o budzetu i njihovim platama da se ne prica. I pretpostavljam da je igra radjena u C/C++ jeziku sto je danas standard za igre tog tipa i sve ostale.Mada naravno i u delphiu mozes da napravis odlicne video igre iako je C/C++ pogodniji za to.

Ako hoces da pocnes da se bavis ozbiljnim programiranjem PC igara pocni od neceg jednostavnijeg.
Naprimer neku interesantnu 2D igru sa okorelom grafikom od koje mozes da zaradis koji dinar na internetu.

A posle kad steknes malo iskustva sastavi neki tim ili se prikljuci nekom.
Kakva su tvoja iskustva sa razvojem PC igara da li si napravio neku?
[ nikola.tr @ 21.11.2013. 23:39 ] @
Tema je možda malo zastarela, ali da ne otvaram novu, pomoć ću zatražiti ovde.

Dakle, ove godine smo se par profesora, nekoliko drugova i ja upustili u jedan malo veći školski projekat koji je pretežno baziran na elektronici i programiranju mikrokontrolera.
Mi smo zamislili da napravimo (realni) model ljudske šake koji će biti upravljan pokretima naše ruke, pomoću posebne rukavice.

Pošto se ja posebno zanimam za programiranje, ja sam želeo da te pokrete simuliramo i na računaru, softwerski.

U gore navedenim uputstvima sam pronašao kako mogu da izvršim učitavanje osnovnog modela šake, ali moj problem je kako da uradim transformacije nad tim modelom.
Nakon učitavanja modela ruke ja bih želeo da na osnovu podataka o položaju svakog prsta izvršim transformacije tog modela, odnosno da menjam pozicije prstiju.

Moje pitanje je da li su takve transformacije izvodljive i na koji način to mogu da uradim?

Unapred, hvala na pomoći!

[ Milan Milosevic @ 22.11.2013. 22:56 ] @
Moguce su, ali ti je za to potrebno dublje poznavanje OpenGL-a
[ stameni @ 29.05.2022. 17:38 ] @
Srki_82, najpre ti se moram zahvaliti na ovako detaljnom tutorijalu :)

Na žalost, imam problem prilikom instalacije GLScenea, pa mi je potrebna pomoć...

GLScene koji koristim ima oznaku verzije 1.2 iz jula 2013. godine, a Delphi je u broju 7.

Citat:
Srki_82:
Ok... ovako radi... step-by-step :)
Ako si skinuo zapakovan GLScene prvo ga raspakuju neki folder... npr C:\Program Files\Borlad\Delphi 7\Components\GLScene. Kad to uradis pokreni Delphi. U Tools meniu izaberi Environment Options... Na Library stranici u Library i Browsing path dodaj sve foldere iz GLScene\Source ukljucujuci i njega... trebalo bi da imas nesto slicno ovom
$(DELPHI)\Lib;
$(DELPHI)\Bin;
$(DELPHI)\Imports;
$(DELPHI)\Projects\Bpl;
$(DELPHI)\Rave5\Lib;
$(DELPHI)\Components\GLScene\Source;
$(DELPHI)\Components\GLScene\Source\Base;
$(DELPHI)\Components\GLScene\Source\CgShaders;
$(DELPHI)\Components\GLScene\Source\DesignTime;
$(DELPHI)\Components\GLScene\Source\FileFormats;
$(DELPHI)\Components\GLScene\Source\GameAPIs;
$(DELPHI)\Components\GLScene\Source\PhysicsAPIs;
$(DELPHI)\Components\GLScene\Source\Platform;
$(DELPHI)\Components\GLScene\Source\PlugIn;
$(DELPHI)\Components\GLScene\Source\ScriptingAPIs;
$(DELPHI)\Components\GLScene\Source\Shaders;
$(DELPHI)\Components\GLScene\Source\SoundAPIs;
$(DELPHI)\Components\GLScene\Source\VideoAPIs


Moguće je da je problem u drugačijoj strukturi direktorijuma u "mojoj" verziji GLScenea. Kod mene, u instalaciji u potfolderu Source ima samo sledećih pet direktorijuma: external, include, lib, LinkedObject i Resources, a Resources se grana na vcl i objects, ima desetak direktorijuma i tridesetak BMP datoteka.

Drugim rečima, kod mene nema Base, CgShaders, DesignTime i ostalog čega kod tebe ima.

Dakle, sve to mnogo se razlikuje od tvog setupa.

U Tools / Environment Options / Library popunio sam i Library path i Browsing path svim ovim poddirektorijumima, ali ne vredi, kompajliranje ne prolazi.

Već neko vreme pokušavam da nađem gde bi mogao biti problem, surffujem po StackOverflowu, gledao sam i klipove na YouTubeu, ali ne uspevam, pa bi mala pomoć dobrodošla :)
[ savkic @ 30.05.2022. 02:11 ] @
Koju gresku dobijas? Ako je to missing unit onda pretrazi gde je taj pas/dcu/obj lociran pa ga dodaj u search path.

Takodje ako ti 2D library radi posao, pogledaj https://github.com/skia4delphi/skia4delphi, nov je i aktivan za sad.
[ stameni @ 30.05.2022. 18:38 ] @
Citat:
savkic: Koju gresku dobijas? Ako je to missing unit onda pretrazi gde je taj pas/dcu/obj lociran pa ga dodaj u search path.


Nije missing unit. Evo ukratko celog "hodograma":

1. GLScene v1.2 downloadovan i raspakovan u \Dev\GLScene.
2. Tools / Environments Options / Library
3. U Library path i Browsing path postavljene putanje do \Dev\GLScene\Source i svih poddirektorijuma.
4. Pokrenut \Dev\GLScene\Source\external\Setup.bat (kopira potrebne DLL-ove u \Windows\System32\
5. Otvorena projektna grupa \Dev\GLScene\Delphi7\All Packages . Aktivan je projekat GLS_SDL7.bpl
6. Project / Build All Projects

Posle poslednje stavke, puca na GLSLog.pas u redu 606: Undeclared identifier: 'mbYesNo' i odmah potom u istom redu: Too many actual parameters.

Indikativno je da se struktura (direktorijumi) originalne instalacione datoteke drastično razlikuje od verzije koju je opisivao Srki_82 na početku ovog tutorijala.

Citat:
Takodje ako ti 2D library radi posao, pogledaj https://github.com/skia4delphi/skia4delphi, nov je i aktivan za sad.


Trenutno mi nije u igri, ali ako imaš pohvalnih reči o biblioteci, kaži, pa ću obratiti pažnju ;)
[ savkic @ 30.05.2022. 23:01 ] @
Onda sigurno imas neki nestabilni commit, koji ili ima bugove ili ne radi na svim verzijama Delphija (pisan za neku raniju) probaj da nadjes neki stariji ili da ti predjes na stariji Delphi. Eventualno pogledaj ako ima updejt GLScene za novije Delphi verzije.