Advertisement
thecplusplusguy

Cool rain effect C++, SDL

Jul 6th, 2012
508
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.42 KB | None | 0 0
  1. //Implemented by http://www.youtube.com/user/thecplusplusguy
  2. //The algorithm: http://freespace.virgin.net/hugo.elias/graphics/x_water.htm
  3. //SDL library used
  4. //You need a 640x480 image (more colorful the better), called waterback.bmp in the same folder
  5. #include <iostream>
  6. #include <SDL/SDL.h>
  7. using namespace std;
  8.  
  9. const int WIDTH=640;
  10. const int HEIGHT=480;
  11. const int FPS=60;
  12. int dumpv2=8;
  13. int WATERHIGHT=200;
  14. const float dump=0.99;
  15. int** buffer1;
  16. int** buffer2;
  17.  
  18.  
  19. void putPixel(SDL_Surface* surf,int x,int y,int r,int g,int b)
  20. {
  21.     if(x>=0 && y>=0 && x<WIDTH && y<HEIGHT)
  22.     {
  23.         (((Uint32*)(surf->pixels))[y*surf->pitch/4 + x])=SDL_MapRGB(surf->format,r,g,b);
  24.     }
  25. }
  26.  
  27. void putPixel(SDL_Surface* surf,int x,int y,Uint32 col)
  28. {
  29.     if(x>=0 && y>=0 && x<WIDTH && y<HEIGHT)
  30.     {
  31.         ((Uint32*)(surf->pixels))[y*surf->pitch/4 + x]=col;
  32.     }
  33. }
  34.  
  35. Uint32 getPixel(SDL_Surface* surf,int x,int y)
  36. {
  37.     if(x<0)
  38.         x=0;
  39.     if(y<0)
  40.         y=0;
  41.     if(x>=WIDTH)
  42.         x=WIDTH-1;
  43.     if(y>=HEIGHT)
  44.         y=HEIGHT-1;
  45.     return (((Uint32*)(surf->pixels))[y*surf->pitch/4 + x]);
  46. }
  47.  
  48. void refreshWater()
  49. {
  50.     for(int i=1;i<HEIGHT-1;i++)
  51.         for(int j=1;j<WIDTH-1;j++)
  52.         {
  53.             buffer2[i][j]=((buffer1[i][j-1]+buffer1[i][j+1]+buffer1[i-1][j]+buffer1[i+1][j]) >> 1) - buffer2[i][j];
  54.     //      buffer2[i][j]*=dump;
  55.             buffer2[i][j]-=buffer2[i][j]>>dumpv2;
  56.         }
  57.     int **tmp;
  58.     tmp=buffer2;
  59.     buffer2=buffer1;
  60.     buffer1=tmp;
  61. }
  62.  
  63. void renderWater(SDL_Surface* screen,SDL_Surface* backImg)
  64. {
  65.     for(int i=1;i<HEIGHT-1;i++)
  66.         for(int j=1;j<WIDTH-1;j++)
  67.         {
  68.             int diffY=buffer1[i-1][j]-buffer1[i+1][j];
  69.             int diffX=buffer1[i][j-1]-buffer1[i][j+1];
  70.     //      cout << diffX << " " << diffY << endl;
  71.             putPixel(screen,j,i,getPixel(screen,j+diffY,i+diffX));
  72.         }
  73. }
  74.  
  75.  
  76. int main(int argc,char** argv)
  77. {
  78.     buffer1=(int**)new int[HEIGHT];
  79.     buffer2=(int**)new int[HEIGHT];
  80.     for(int i=0;i<HEIGHT;i++)
  81.     {
  82.         buffer1[i]=new int[WIDTH];
  83.         buffer2[i]=new int[WIDTH];
  84.     }
  85.     for(int i=0;i<HEIGHT;i++)
  86.         for(int j=0;j<WIDTH;j++)
  87.             buffer1[i][j]=buffer2[i][j]=0;
  88.     SDL_Init(SDL_INIT_EVERYTHING);
  89.     SDL_Surface* screen=SDL_SetVideoMode(WIDTH,HEIGHT,32,SDL_SWSURFACE);
  90.     SDL_Surface* backImgTmp=SDL_LoadBMP("waterback.bmp");
  91.     SDL_Surface* backImg=SDL_DisplayFormat(backImgTmp);
  92.     if(!backImg)
  93.         cout << "error with the image" << endl;
  94.     SDL_FreeSurface(backImgTmp);
  95.     SDL_Event event;
  96.     bool running=true;
  97.     Uint32 start;
  98.     int x,y;
  99.     int num=10;
  100.     while(running)
  101.     {
  102.         start=SDL_GetTicks();
  103.         while(SDL_PollEvent(&event))
  104.         {
  105.             switch(event.type)
  106.             {
  107.                 case SDL_QUIT:
  108.                     running=false;
  109.                     break;
  110.                 case SDL_KEYDOWN:
  111.                     switch(event.key.keysym.sym)
  112.                     {
  113.                         case SDLK_ESCAPE:
  114.                             running=false;
  115.                             break;
  116.                         case SDLK_q:
  117.                             num++;
  118.                             break;
  119.                         case SDLK_a:
  120.                             if(num>0)
  121.                                 num--;
  122.                             break;
  123.                         case SDLK_w:
  124.                             WATERHIGHT+=20;
  125.                             break;
  126.                         case SDLK_s:
  127.                             if(WATERHIGHT>20)
  128.                                 WATERHIGHT-=20;
  129.                             break;
  130.                     }
  131.                     break;
  132.             }
  133.         }
  134.         //if(rand()%10<8)
  135.         for(int i=0;i<num;i++)
  136.             buffer1[rand()%HEIGHT][rand()%WIDTH]+=rand()%WATERHIGHT+1;
  137.         SDL_BlitSurface(backImg,NULL,screen,NULL);
  138.         refreshWater();
  139.         renderWater(screen,backImg);
  140.        
  141.         SDL_Flip(screen);
  142.         if(1000.0/FPS>(SDL_GetTicks()-start))
  143.             SDL_Delay(1000.0/FPS-(SDL_GetTicks()-start));
  144.     }
  145.     for(int i=0;i<HEIGHT;i++)
  146.     {
  147.         delete[] buffer1[i];
  148.         delete[] buffer2[i];
  149.     }
  150.     delete[] buffer1;
  151.     delete[] buffer2;
  152.     SDL_FreeSurface(backImg);
  153.     SDL_Quit();
  154. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement