3d-starfield tutorial by Drake / Storm 1997 MINˇ, ERIK J SEESJˇRVI EN KIRJOITA TˇTˇ DISCLAIMERIA, VAAN SYY SIITˇ KUULUU ILKEˇLLE JOONAKSELLE JOKA KIRJOITTAA TˇTˇ. ELI EJS EI OLE VALITETTAVASTI LUVANNUT MY™SKˇˇN OLLA VASTUUSSA TUTORIAALISTA AIHEU- TUNEISTA ONGELMISTA, JOTEN TˇMˇNKIN TIEDOSTON SISˇLT™ KUULUU READJUST.NOW -DOKUMENTIN DISCLAIMERIN ALAISUUTEEN. KIITOKSIA HUOMIOSTA. 3D-Starfield, eli naapurigalaksiin ja takaisin ---------------------------------------------- Jokainen on varmaan jossain yhteydess„ n„hnyt sellaisen pienen, yksikertaisen efektin nimelt„ 3D-Starfield? Jos nimi ei sano mit„„n, niin kuvaus viimeist„„n kaiken: Eli siin„ l”ssi t„hti„ vilahtaa perspektiivin ohitse, ja saa aikaan efektin, ett„ katsoja "liikkuisi" kuvitteellisessa avaruusaluksessaan tai vastaavassa. Itseasiassa t„m„ efekti on helppoakin helpompi tehd„, vaikein osa siit„ on 3D-maailmassa sijaitsevan pisteen projisointi 2D-pinnalle elikk„ n„yt”lle. Eli ensimm„iseksi meid„n pit„„ saada 3D-avaruuden piste "oikealle" kohdalle ruudulla. Periaatetta en ryhdy t„ss„ selitt„m„„n, mutta jos 3D-kiinnostaa yleens„kin, kannattaa imuroida Ilkka Pelkosen kirjoittama 3dica, joka on mainio 3D:t„ k„sittelev„ tutoriaali, josta t„m„kin kaava on kopioitu. Eli, saamme X,Y koordinaatit n„in: X = X * PERSPECTIVE / Z + ORIGOX; Y = Y * PERSPECTIVE / Z + ORIGOY; T„t„ varten pit„„ m„„ritell„ kolme vakiota: PERSPECTIVE, ORIGOX ja ORIGOY. PERSPECTIVEn sopiva arvo riippuu tilanteesta, k„yt„n esimerkkiohjelmassa arvoa 256. ORIGOX on taas origon sijainti x-akselilla, eli yleens„ 160, kun k„ytet„„n tilaa 320x200. ORIGOY on vastaava y-akselille, ja kokeillaampa sit„kin ruudun keskipisteen„ eli arvoksi 100. Ohjelman muut osat ovat eritt„in yksikertaisia. Tarvitsee vain siirty„ tilaan 13h, ja toistaa t„t„ looppia, kunnes jokainen t„hti on k„sitelty (pseudoa): for(stop == TRUE) { x = x * PERSPECTIVE / z + ORIGOX; /* T„ss„ t„hti pyyhit„„n */ y = y * PERSPECTIVE / z + ORIGOX; if(0 < x > 320 && 0 < y > 200) putpixel(x,y,0); z--; /* T„ss„ sijaintia muutetaan */ if(z <= 0) z = 256; x = x * PERSPECTIVE / z + ORIGOX; /* T„ss„ t„hti piirret„„n */ y = y * PERSPECTIVE / z + ORIGOX; /* uusiin koordinaatteihin */ if(0 < x > 320 && 0 < y > 200) putpixel(x,y,15); } Yksikertaista, eik” vaan. Kaikkein parhaiten idean saa kaaliinsa skippaamalla oheisen koodin (ainakin siksi aikaa kunnes ep„toivo saa vallan ja on _pakko vilkaista =), ja s„helt„m„ll„ itse oman starfieldins„. #include #include #define PERSPECTIVE 256 /* n„iden tarkoitukset */ #define ORIGOX 160 /* varmaan muistatkin */ #define ORIGOY 100 /* jo nyt? */ #define NUMBEROFSTARS 2000 /* t„m„ s„„t„„ t„htien m„„r„n */ #define SPEEDOFSTARS 1 /* t„htien nopeus, yleens„ 1 */ #define putpixel(x,y,c) _farpokeb(_dos_ds, 0xA0000+(y*320+x), c) #define waitsync() while ( (inportb(0x03DA) & 0x08))\ while (!(inportb(0x03DA) & 0x08)) struct { int x,y,z; }starinfo[NUMBEROFSTARS]; void randomize_star(int value) { starinfo[value].x = rand() % 320 - 160; starinfo[value].y = rand() % 200 - 100; starinfo[value].z = rand() % 256 + 1; } void main(void) { int x,y,i; /* koordinaattimuuttujat sek„ apumuuttuja */ textmode(0x13); /* siirrymme tilaan 13h */ srand(time(0)); /* alustamme randomgeneraattorimme */ for(i=0;i 0 && x < 320 && y > 0 && y < 200) putpixel(x,y,0); starinfo[i].z--; if(0 >= starinfo[i].z) { randomize_star(i); starinfo[i].z=256; } x = starinfo[i].x * PERSPECTIVE / starinfo[i].z + ORIGOX; y = starinfo[i].y * PERSPECTIVE / starinfo[i].z + ORIGOY; if(x > 0 && x < 320 && y > 0 && y < 200) putpixel(x,y,15); } waitsync(); /* n„iden pit„isi v„h„n hidastaa */ waitsync(); /* py”rimisnopeutta Pentiumeilla */ } textmode(0x3); /* paluu tekstimoodiin */ } Siin„. Eih„n ole yht„„n monimutkaisempaa koodinakaan (no, minun tekem„„ koodiahan t„m„ silti edelleen on ;)? Ohjelmassa esiteltiin muuten makroversio wainsyncist„, joka saattaa olla pienen aavistuksen entist„ nopeampi. Ja miksik” tuo oli noin huononn„k”inen, karkea ja ruma? Siksi, ett„ sit„ ei ole hyv„ksi tarkoitettukaan. Siihen on tarkoituksella j„tetty monta kohtaa, jotta lukijalle j„isi rauhassa kehitelt„v„„. Min„ esimerkiksi tein omaani nopeuss„„timen n„pp„imill„ (SPEEDOFSTARS), pienen katseluefektin (ORIGOX/Y:ll„ ON sittenkin vaikutusta, vink vink ;), sopivasti feidatun paletin (mit„ kauempana t„hti on, sit„ tummempi se on) ja muuta mukavaa. Kannattaakin nauttia ajasta, jota voi viett„„ efektien parissa ennen kuin siirtyy „„nikortin ohjelmointiin =)