Lave et 3D Spil i Delphi - Del II

Tags:    delphi
Skrevet af Bruger #1474 @ 24.11.2003

For at modtage og sætte cursorens position, bruger vi to Windows funktioner: GetCursorPos() og SetCursorPos(). Den første nævnte prcedure forventer en TPoint, hvor den sidste forventer to integer (X,Y). Med disse kald vil vi modtage/sætte cursorens position på vores skærm og ikke på vores form. Så når vi skal sætte cursoren præcis i centrum af vores form, skal vi halvere bredden og højden og lægge left og top positionerne til. Den samme beregning trækker vi fra koordinaterne vi modtager for at få afstanden. Resultatet trækker vi fra vores viewports rotaion. Da vi hele tiden skal være sikke på at cursoren til sidst bliver sat i centrum på formen, skriver vi det hele i Idle proceduren. Så tilføj en lokal variant: P, som TPoint i denne procedure og skriv følgende kode:

Fold kodeboks ind/udKode 


Som du sikkert har bemærket ganger jeg afstanden med 0.1 inden jeg trækker den fra vores rotation. Det bevirker at det bliver lettere at styre. Prøv at kompile og se den nye og meget bedere måde at navigere på. For at lukke din applikation bliver du nødt til at taste Alt+F4 eller tilføj en tase funktion eks: vk_Escape: Close; i FormKeyDown proceduren. Det eneste vi mangler, er, at fjerne cursoren, da den er lidt irriterende at havde synlig. Det kan vi gøre med Windows funktionen: ShowCursor(). Denne procedure forventer en Boolean, så vi skriver selvfølgelig False. Vi behøver kun at gøre det én gang, så vi skriver den i FormCreate proceduren. (De forskellige bmp billeder er fra den tidligere artikel!)

Fold kodeboks ind/udKode 


For at fuldende vores nye styremåde, kunne det være interessant at bruge venstre og højre museknapper til at bevæge os frem ad og tilbage. Det vil være nemmest at skrive vores nye navigations funktioner i Idle proceduren. Vi kan bruge den samme teknik, som da vi lavede vores hoppe animation, ved at lade nogle booleans aktivere vores bevægelse i Idle proceduren. Meget logisk, vil vi derfor lade vores booleans blive True i vores forms OnMouseDown property og False i OnMouseUp property. Når en boolean en er True skal der bevæges og når den er False skal bevægelsen stoppes. Vi tilføjer to globale varianter: MoveForward og MoveBackward og flytter vores tidligere kode, der fik os til at bevæge gå frem og tilbage fra FormKeyDown proceduren til Idle proceduren.

Fold kodeboks ind/udKode 


Som du kan se har jeg gjort vores to nye booleans klar til at aktivere bevægelserne. Yderligere har jeg halveret farten (ganget med 0.5), da det vil gå meget hurtigere, da beregningen foregår i Idle prodeuren. Nu skal vi bare havde gjort dem aktivér-bare i vores forms OnMouseDown og OnMouseUp properties.

Fold kodeboks ind/udKode 


Som du sikkert kan mærke er det en meget mere behageligt måde at navigere rundt på. Vi kan nu hurtig vende os om, kigge op og ned. Desuden virker det også meget mere flydende når vi går.

Texures bevirkede i at vores lille "spil" fra sidste artikel kom grafisk til at se meget mere spændende ud. Det spil industrien har stræbet efter de sidste mange år er realisme. Vi er et skridt på vej, til at opnå den grafiske resultat som den professionelle spil-industri har mellem fingerene. Men som du sikkert har bemærket ser vores textures lidt pixeleret ud, hvis vi enten står tæt på eller langt fra. Dette er fordi OpenGL projektere hele vores 2D textures på samme måde uanset hvor vi befinder os i forhold til vores geometri. Dette kan ændres med en teknik der bliver kaldt for MipMapping. Ordet "Mip" er latinsk og betyder mange. Ideén er derfor at OpenGL skal lave mange textures ud af vores ene texure, men i forskellige størrelser. Da vores texture er en format 256x256, kan vi lade OpenGL generere 8 yderligere textures med formaterne: 128x128, 64x64, 32x32, 16x16, 8x8, 4x4, 2x2 og 1x1. Dette vil betyde at står vi tæt på projektere OpenGL vores originale 256x256 texture, men jo længere vi går væk fra vores geometri, jo mindre format vil OpenGL projektere. Dette bevirkere i at vores textures ikke vil komme til at se så pixeleret ud, men det vil også bevirke i at vi får en dybde fornemmelse. Funktionen der får OpenGL til at projektere vores MipMap formater er ikke inkluderet i OpenGL 1.1, derfor bliver vi nødt til at definere den selv.

Fold kodeboks ind/udKode 



Hvad synes du om denne artikel? Giv din mening til kende ved at stemme via pilene til venstre og/eller lægge en kommentar herunder.

Del også gerne artiklen med dine Facebook venner:  

Kommentarer (33)

User
Bruger #479 @ 24.11.03 20:48
Denne artikel er (ligesom 1'eren) genialt skrevet! Let forståelig, men stadig med en masse information. Et fem tal fra mig.
User
Bruger #4503 @ 24.11.03 21:09
Det er bare så dejligt at læse.... Igen en Top-artikel fra dig og den fortjener intet andet end 5...
Super flot arktikel
User
Bruger #3530 @ 25.11.03 15:00
Jeg spekulerer på hvor lang tid han har gået og gemt disse genistreger oppe i ærmet. Det er jo guldkorn det her :D
User
Bruger #123 @ 27.11.03 09:58
Flot artikel. Der var nogle småfejl, så som en constant der var stavet forkert, og man skulle lige nærlæse artiklen for at få defineret KassePosition, men bortset fra det så virker det fint. Så vil vi gerne have et kursus i at tilføje bevægelige elementer, så som modstandere ... ;) I øvrigt et 5 tal fra mig.
User
Bruger #4525 @ 19.12.03 23:22
kan ikke lave en exe(eller hvad det nu er) så man kan prøve det ;)
User
Bruger #3897 @ 23.12.03 21:16
Super artikel... Så skal der laves 3Dspil ;D
User
Bruger #4077 @ 03.01.04 13:31
Kommer der måske en 3ér ?? :D Nice artikel (er)
User
Bruger #1474 @ 05.01.04 18:38
Ikke lige i forløbet, jeg skal havde mine eksamner overstået først :) !
User
Bruger #4893 @ 12.02.04 10:39
Nice artitel men jeg kan stadig ikke bestemme mig for om jeg skal begynde at lave spil i c++ eller delphi hvad syntes du er bedst???
User
Bruger #1474 @ 13.02.04 16:56
Hvis det bare er for at laere OpenGL og lave dine egne 3D OpenGL applikationer kan det gor fuldstaendig ligemeget om du vaelger Delphi eller C++. Men satser du paa engang at blive professionel Spil Programmoer paa et kommersielt udvikler Studie er det nok C++ du skal kigge paa. Jeg valgte Delphi fordi jeg er vild med dens syntaxer og den maade Delphi er konstrureret paa. Men selve OpenGL kaldende er de samme uanset hvilket sprog du benytter!
User
Bruger #4893 @ 16.02.04 13:46
Hej jeg ved godt du programmere i delphi men du ved til feldigvis ikke hvor jeg kan finde en compiler som kan compile opengl i c++ jeg bruger dev-c++ men den kommer hele tiden med errors når jeg compillere.
User
Bruger #1474 @ 16.02.04 15:42
øhhh jooo næsten alle C++ kompilere kan kompile OpenGL i et Windows miljø. Eksempelvis Borland's C++ Builder, Micrsoft's Visual C++ og Intels C++ kompiler... Nu ved jeg selvfølgelig ikke hvilket kode du anvender siden din kompiler viser fejlmeddelser!
User
Bruger #5062 @ 05.04.04 20:12
5 Her fra!!!

Men dog, kommer der en pop-up før jeg starter programmet der siger NVIDIA Corparation???
User
Bruger #1474 @ 09.04.04 12:37
he he... ja, det er vist rigtigt! Det er følgende kode:

ShowMessage(glGetString(gl_Vendor));

Der er grunden til det! Det kan du bare slette! Det fortæller bare hvilket firma der har produceret dit grafikkort! Der er også gl_Renderer, den fortæller, hvad dit grafikkort hedder!

Mange tak for din rating!
User
Bruger #5756 @ 08.05.04 14:00
er der en der en der kan hjælpe mig jeg kan ik komme vider med artikel 1 der hvor man skal lave et nyt opject hvordan gør jeg det
User
Bruger #1474 @ 08.05.04 18:37
Lars>> Send mig en udvikler mail, omkring dit problem saa vil jeg proeve at svare hurtigst muligt! :D
User
Bruger #5097 @ 26.05.04 18:13
Fantastisk...
5 fra mig
User
Bruger #6175 @ 24.07.04 02:40
Genial artikel...

Jeg gav ofcourse 5 ;)
User
Bruger #6079 @ 04.08.04 03:17
fed artikel 5 her fra...

men min siger "stream read error" en der kan fortælle mig hvad jeg gør galt ??
User
Bruger #6253 @ 08.08.04 18:52
Genial artikel!

Jeg har lige 2 spørgsmål:

1) Hvordan man kan gøre dele af bitmap'erne gennemsigtige? - er der en TransparentColor eller noget lignende?


2) Ville det trække FPS væsentligt ned, hvis man tilføjede 1000 grafikelementer som også skal tegnes i TForm1.FormPaint, men som alligevel ikke kan ses på skærmen, fordi man fx "står med ryggen til" eller "noget andet står foran"?
(finder OpenGL selv ud af hvad der skal tegnes?)
User
Bruger #1474 @ 10.08.04 15:37
1) Du kan gøre en bitmap transparent på flere forskellige måder! Enten per vertex, eller per texture (AlphaMap) eller per pixel (Pixel Shading)! Til alle funktioner skal glEnable(gl_Blend) tilføjes i starten af dit kode! Derefter skal du yderligere definere hvilken slags blend du vil foretage dig med funktionen glBlendFunc()

Det kunne eksempelvis være dette:
glBlendFunc(gl_Src_Alpha,gl_One_Minus_Src_Alpha);

Kig i din openGL.Pas fil for andre blend specifikationer!

Per Vertex!
Ved hver coordinat af dit geometry (trekant, firkant, polygon osv.) kan du indsætte en glColor4f(). Den sidste parameter er en Alpha channel og når den er 0 er dit geometry helt gennemsigtigt omkring den vertex. (Lidt ligesom da vi farvede hver enkelt vertex i den første artikel).

Per Texture (Alpha Map)
Du kan også indlæse en texture (på normal vis) og benytte den som en alpha map. Bitmappen du benytter som alpha map skal helst bestå af grå-skalaer (sort/hvid). Det der er mørkest vil blive mest transparent! Vær venligst opmærksom på at bitmappen må IKKE bestå af IndexColors (Selv om det ville være fristende at bruge, det SKAL være RGB colors). Husk også at rette din glBlendFunc() funktion til, så det passer dig bedst!

Per Pixel (PixelShading)
Dette er for de meget avancerede OpenGL programmøre og tager RIGTIGT RIGTIGT langt tid at forklare! Men du kan selv læse om det på enten www.nvidia.com eller www.ati.com

2) Jo flere polygoner du vil have tegnet jo længere tid vil det tage for dit grafik-kort. Hverken OpenGL eller DirectX tjekker, hvilke polygoner der kan ses på skærmen. Der bliver bare tegnet! For at optimere din applikation kan du kigge lidt "Frustum Culling"! Den metode er lavet til lige præcist det du snakker om! Derfor vil jeg anbefale dig at søge efter artikler på nettet der omhandler "Frustum Culling". Der findes allerede et par klasser skrevet i Delphi rundt om på nettet - frit tilgængeligt for alle!


Held og Lykke
Søren Klit Lambæk

NB: Tak for rosen fra jer alle! :D
User
Bruger #6253 @ 11.08.04 18:03
MANGE tak!!!
User
Bruger #6869 @ 30.11.04 20:12
Hej alle sammen, jeg er lige blevet færdig med denne fantaktiske artikel, men jeg har lidt problemer da når jeg starter, så starter jeg "i" kassen og når jeg bevæger mig rundt så sidder kassen fast på mig, meget fint hvis jeg skulle have en kjole, men lidt noget skidt når jeg skal skubbe med den :) Nogen der kan forklarer hvorfor den gør det....
God Jul (skulle lige sige det)
User
Bruger #1474 @ 01.12.04 14:21
Du har sikkert overset et eller andet i koden!

Det lyder som om at det er nogle matrix definationer der gaar galt for dig, samtidig med at du muligvis ikke flytter din kasse overhovedet!

Send mig en udvikler post med dit kode og jeg vil se paa sagen!

Med venlig hilsen
Søren Klit Lambæk

(God jul til dig - og tak for rosen)!
User
Bruger #6869 @ 10.12.04 00:12
Så er den sendt til mailen... :)

(for en uges tid siden) :)
User
Bruger #1474 @ 10.12.04 11:08
Hmmm jeg har ikke modtaget nogen mails endnu! Prøv lige at send den igen!

Tak :D
User
Bruger #6869 @ 15.12.04 01:18
Sendt til info@opengl-delphi.dk
User
Bruger #6869 @ 05.01.05 16:37
Hej allesammen, jeg har lige fået lidt hjælp af den flinke Søren og ville lige sige at hvis I vil have det sådan at kassen er flyttet lidt fra centrum (så I ikke starter inde i kassen) skal I skrive følgende ved variablen KassePosition:

var
KassePosition : TVektor = (X: -10; Y: 0; Z: -10);
User
Bruger #6869 @ 08.01.05 00:36
Endnu et guldkorn fra Søren....
Hvis I ønsker Quake effekten med at man maks kan se 90 grader op og 90 grader ned skal I indsætte følgende kode under glPushMatrix;

if Rotation.X > 90 then Rotation.X := 90;
if Rotation.X < -90 then Rotation.X := -90;
User
Bruger #6869 @ 08.01.05 00:37
Hov glemte at sige at den skulle indsættes i FormPaint proceduren
User
Bruger #6997 @ 29.01.05 16:21
Da jeg var færdig me artiklen følte jeg kunne lave Hitman 2 uden problemer! :S MEGET flot skrevet. 5 herfra!!
User
Bruger #11927 @ 12.06.07 00:01
Super lavet.. :D 5 du ;P

men tænkte lige.. Hvad er "FormPaint proceduren " og hvor skal koden sættes ind henne ?
User
Bruger #1474 @ 15.06.07 18:58
Hej Dennis,

FormPaint proceduren kan du finde ved hjælp af Delphi's "Object Inspector". Vælg flaget "Events" og dobbeltklik på "OnPaint". Det vil genere en FormPaint procedure for dig. Hvis du er meget ny i Delphi eller programmering generalt er denne artikel nok en lidt for stor en mundfuld for dig!

Held og Lykke
Søren Klit Lambæk
Du skal være logget ind for at skrive en kommentar.
t