Löysin netistä mielenkiintoisen artikkelin joka käsitteli demo efektejä. Artikkelin pohjalta väsäsin sitten tunneli efektin, efektissä "pudotaan" tunnelia alaspäin ja samalla heilutaan edes takaisin.
Efekti tarttee tekstuuriksi 256*256 kokoisen kuvan.
Valmis binääri löytyy osoitteesta: http://koti.mbnet.fi/kuujoo/demoScreenit/tunneli.zip
Tiedetään kommentointi on asia mitä en hallitse....
#include <sdl.h> #include <math.h> #pragma comment(lib, "SDLmain.lib") #pragma comment(lib, "SDL.lib") #define TEXLEVEYS 256 #define TEXKORKEUS 256 #define RUUDUNLEVEYS 640 #define RUUDUNKORKEUS 480 // HYI HYI GLOBAALEJA MUUTTUJIA EI SAA KÄYTTÄÄ int texture[TEXLEVEYS][TEXKORKEUS];//taulukko tekstuurin pikseleitä varten int etaisyydet[RUUDUNLEVEYS*2][RUUDUNKORKEUS*2]; int kulmat[RUUDUNLEVEYS*2][RUUDUNKORKEUS*2]; int vari_arvo[RUUDUNLEVEYS][RUUDUNKORKEUS]; float AIKA = 0; Uint32 _fastcall getpixel(SDL_Surface *surface, int x, int y) { int bpp = surface->format->BytesPerPixel; // p on osoitin pikseliin, jonka haluamme kopioida Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp; switch(bpp) { case 1: return *p; case 2: return *(Uint16 *)p; case 3: if(SDL_BYTEORDER == SDL_BIG_ENDIAN) return p[0] << 16 | p[1] << 8 | p[2]; else return p[0] | p[1] << 8 | p[2] << 16; case 4: return *(Uint32 *)p; default: return 0; // ei pitäisi tapahtua. } } //käydään kuva tekstuuri pikseli pikseliltä läpi, ja tallennetaan rgb arvot texture taulukkoon void alustaTekstuuri() { SDL_Surface *kuva; kuva = SDL_LoadBMP("text.bmp"); for(int x = 0; x < TEXLEVEYS;x++) { for(int y = 0; y < TEXKORKEUS;y++) { texture[x][y] = getpixel(kuva, x, y); } } } void alustus() { for(int x = 0; x < RUUDUNLEVEYS*2;x++) { for(int y = 0; y < RUUDUNKORKEUS*2;y++) { int kulma, etaisyys; float ratio = 32.0; etaisyys = int(ratio * TEXKORKEUS / sqrt(float((x - RUUDUNLEVEYS) * (x - RUUDUNLEVEYS) + (y - RUUDUNKORKEUS) * (y - RUUDUNKORKEUS)))) % TEXKORKEUS; kulma = (unsigned int)(0.5 * TEXLEVEYS * atan2(float(y - RUUDUNKORKEUS), float(x - RUUDUNLEVEYS)) / 3.1416); etaisyydet[x][y] = etaisyys; kulmat[x][y] = kulma; } } } void drawTunnel(SDL_Surface *screen) { AIKA +=0.03; int shiftX = int(TEXLEVEYS * 1.0 * AIKA); int shiftY = int(TEXKORKEUS * 0.25 * AIKA); int shiftLookX = RUUDUNLEVEYS / 2 + int(RUUDUNLEVEYS / 2 * sin(AIKA)); int shiftLookY = RUUDUNKORKEUS / 2 + int(RUUDUNKORKEUS / 2 * sin(AIKA * 2.0)); for(int x = 0; x < RUUDUNLEVEYS; x++) { for(int y = 0; y < RUUDUNKORKEUS; y++) { int color = texture[(unsigned int)(etaisyydet[x+shiftLookX][y+shiftLookY] + shiftX) % TEXLEVEYS] [(unsigned int)(kulmat[x+shiftLookX][y+shiftLookY] + shiftY) % TEXKORKEUS]; vari_arvo[x][y] = color; Uint32 *bufp; bufp = (Uint32 *)screen->pixels + y*screen->pitch/4 + x; *bufp = vari_arvo[x][y]; } } SDL_Flip(screen);//flipataan freimi näytölle } int main(int argc, char *argv[]) { SDL_Init(SDL_INIT_VIDEO); SDL_Surface *screen; screen = SDL_SetVideoMode(RUUDUNLEVEYS, RUUDUNKORKEUS, 32, SDL_HWSURFACE|SDL_DOUBLEBUF); alustaTekstuuri(); alustus(); int done=0; while(done == 0) { SDL_Event event; while ( SDL_PollEvent(&event) ) { if ( event.type == SDL_QUIT ) { return 0; } if ( event.type == SDL_KEYDOWN ) { if ( event.key.keysym.sym == SDLK_ESCAPE ) { done = 1; } } } drawTunnel(screen); } return 0; }
Heh. ^^
Tunnistinpas ainakin osittain omaa koodiani joukosta. :)
Käytitkös lähdemateriaalina demoni (The Path) ensimmäistä ja viimeistä efektiä? ;-)
Vai käytitkö kenties tätä: http://www.student.kuleuven.ac.be/~m0216922/CG/
Edit: Olisi ihan kiva, jos jokainen kertoisi käyttämänsä artikkelin tai lähdemateriaalin nimen ja osoitteen. Näin jokainen pääsee hyötymään :)
Peki tuota juuri :) Kyseisellä sivustalla on paljon muitakin hyviä artikkeleja.
Missään vaiheessa ei lopeteta SDL:ää eli lopussa pitäisi kutsua SDL_Quit() tai laittaa SDL:n alustuksen jälkeen atexit(SDL_Quit)
Aihe on jo aika vanha, joten et voi enää vastata siihen.