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.