Advertisement
thecplusplusguy

Cool SDL, C++ water effect

Jul 6th, 2012
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.66 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=1000;
  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.     while(running)
  100.     {
  101.         start=SDL_GetTicks();
  102.         while(SDL_PollEvent(&event))
  103.         {
  104.             switch(event.type)
  105.             {
  106.                 case SDL_QUIT:
  107.                     running=false;
  108.                     break;
  109.                 case SDL_KEYDOWN:
  110.                     switch(event.key.keysym.sym)
  111.                     {
  112.                         case SDLK_ESCAPE:
  113.                             running=false;
  114.                             break;
  115.                         case SDLK_RIGHT:
  116.                             dumpv2++;
  117.                             break;
  118.                         case SDLK_LEFT:
  119.                             dumpv2--;
  120.                             break;
  121.                         case SDLK_UP:
  122.                             WATERHIGHT+=20;
  123.                             break;
  124.                         case SDLK_DOWN:
  125.                             WATERHIGHT-=20;
  126.                             break;
  127.                            
  128.                            
  129.                     }
  130.                     break;
  131.                 case SDL_MOUSEMOTION:
  132.                     if(event.button.button==1)
  133.                     {
  134.                         x=event.motion.x;
  135.                         y=event.motion.y;
  136.                         buffer1[y][x]+=WATERHIGHT;
  137.                         buffer2[y][x]+=WATERHIGHT;
  138.                     }
  139.                     break;
  140.                 case SDL_MOUSEBUTTONDOWN:
  141.                         x=event.motion.x;
  142.                         y=event.motion.y;
  143.                         buffer1[y][x]+=WATERHIGHT;
  144.                         buffer2[y][x]+=WATERHIGHT;
  145.                         break;                 
  146.             }
  147.         }
  148.         SDL_BlitSurface(backImg,NULL,screen,NULL);
  149.         refreshWater();
  150.         renderWater(screen,backImg);
  151.        
  152.         SDL_Flip(screen);
  153.         if(1000.0/FPS>(SDL_GetTicks()-start))
  154.             SDL_Delay(1000.0/FPS-(SDL_GetTicks()-start));
  155.     }
  156.     for(int i=0;i<HEIGHT;i++)
  157.     {
  158.         delete[] buffer1[i];
  159.         delete[] buffer2[i];
  160.     }
  161.     delete[] buffer1;
  162.     delete[] buffer2;
  163.     SDL_FreeSurface(backImg);
  164.     SDL_Quit();
  165. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement