Advertisement
thecplusplusguy

Generate heightmap

Jul 18th, 2012
260
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.11 KB | None | 0 0
  1. //http://www.youtube.com/user/thecplusplusguy
  2. //generate heightmap
  3. #include <iostream>
  4. #include <SDL/SDL.h>
  5. #include <GL/gl.h>
  6. #include <GL/glu.h>
  7. #include "camera.h"
  8. #include "functions.h"
  9. #include <vector>
  10. #include <cstdlib>
  11. #include <ctime>
  12.  
  13. camera cam;
  14. std::vector<std::vector<float> > heights;
  15.  
  16. const int MAXWAVELENGTH=20;
  17. const int MINWAVELENGTH=1;
  18. const int WIDTH=101;    //make sur, this is maxwavelength+1
  19. const int HEIGHT=101;   //and this too
  20. const float SMOOTHNESS=2.0; //higher the value, smaller bumps has less effect
  21. const bool SMOOTHING=false; //the smoothing has  aweird effect for the edges
  22.  
  23. float interpolate(float a,float b, float perc)
  24. {
  25.     //linear interpolation, cosine or quadric better
  26.     return a*perc+b*(1-perc);
  27. }
  28.  
  29. void generateNoise()
  30. {
  31.     //create and fill the heights matrix with 0
  32.     int img[HEIGHT][WIDTH];
  33.     for(int i=0;i<HEIGHT;i++)
  34.     {
  35.         std::vector<float> tmp;
  36.         for(int j=0;j<WIDTH;j++)
  37.         {
  38.             tmp.push_back(0);
  39.         }
  40.         heights.push_back(tmp);
  41.     }
  42.    
  43.    
  44.     int curwave=MAXWAVELENGTH;
  45.     int lastVval,curVval;
  46.     int lastVp,curpV;
  47.     float perc=1.0;
  48.    
  49.     int lastHval,curHval;
  50.     int lastpH,curpH;
  51.     while(curwave>MINWAVELENGTH)
  52.     {
  53.         //fill up a the (curwave) rows with random values depending on the wavelength,look something like:
  54.         //1 2 3 4 3 2 1
  55.         //0 0 0 0 0 0 0
  56.         //0 0 0 0 0 0 0
  57.         //0 0 0 0 0 0 0
  58.         //4 5 6 7 6 5 4
  59.         //with 4 wavelength, with height 7x5, the first generated value 1, the next is 4 (interpolation between them give 2,3,)...
  60.         for(int i=0;i<HEIGHT;i+=curwave)
  61.         {
  62.             curpH=lastpH=1;
  63.             curHval=rand()%256;
  64.             for(int j=0;j<WIDTH;j++)
  65.             {
  66.                 if((j%curwave)==0)
  67.                 {
  68.                     lastHval=curHval;
  69.                     img[i][j]=curHval;
  70.                     curHval=rand()%256;
  71.                     lastpH=j%curwave;
  72.                     curpH=i+1;
  73.                 }else{
  74.                     float val=interpolate(lastHval,curHval,(float)1.0-((float)(j%curwave)/curwave));
  75.                     img[i][j]=(int)val;
  76.                 }
  77.             }
  78.         }
  79.         //fill up the entire image, interpolate between the top and bottom value
  80.         for(int i=0;i<HEIGHT;i++)
  81.         {
  82.             if((i%curwave)==0)
  83.                 continue;
  84.             for(int j=0;j<WIDTH;j++)
  85.             {
  86.                 float val=interpolate(img[(i/curwave)*curwave][j],img[((i+curwave)/curwave)*curwave][j],1.0-((float)(i%curwave)/curwave));
  87.                 img[i][j]=(int)val;
  88.             }
  89.         }
  90.    
  91.         //calculate an avarage of the images, irst wave has 100%, next 50%,25%...
  92.         for(int i=0;i<HEIGHT;i++)
  93.         {
  94.             for(int j=0;j<WIDTH;j++)
  95.             {
  96.                 //putPixel(SDL_GetVideoSurface(),j,i,img[i][j],img[i][j],img[i][j],perc);
  97.                 heights[i][j]=((perc*img[i][j]+(1-perc)*heights[i][j]));
  98.                 //std::cout << heights[i][j] << std::endl;
  99.             }
  100.         //  std::cout << std::endl;
  101.         }
  102.         perc/=SMOOTHNESS;
  103.         curwave/=2;
  104.     }
  105.     for(int i=0;i<HEIGHT;i++)
  106.     {
  107.         for(int j=0;j<WIDTH;j++)
  108.         {
  109.             if(SMOOTHING    && i<HEIGHT-1 && j<WIDTH-1 && i>0 && j>0)   //if smoothing, smooth
  110.                 heights[i][j]=(heights[i-1][j]+heights[i][j-1]+heights[i+1][j]+heights[i][j+1])/4.0;
  111.             heights[i][j]/=255.0;   //divide 255, so we get a number between 0,1
  112.         }
  113.     }
  114. }
  115.  
  116.  
  117.  
  118.  
  119. void loadHeightmap(const char* name)
  120. {
  121.     SDL_Surface* img=SDL_LoadBMP(name);
  122.     if(!img)
  123.     {
  124.         std::cout << "image is not loaded" << std::endl;
  125.         return;
  126.     }
  127.     std::vector<float> tmp;
  128.     for(int i=0;i<img->h;i++)
  129.     {
  130.         tmp.clear();
  131.         for(int j=0;j<img->w;j++)
  132.         {
  133.             Uint32 pixel=((Uint32*)img->pixels)[i*img->pitch/4 + j];
  134.             Uint8 r,g,b;    //unsigned char
  135.             SDL_GetRGB(pixel,img->format,&r,&g,&b);
  136.             tmp.push_back((float)r/255.0);  //0.0,1.0
  137.         }
  138.         heights.push_back(tmp);
  139.     }
  140. }
  141.  
  142. void renderHeightmap(float size,float h)
  143. {
  144.     for(int i=0;i<heights.size()-1;i++)
  145.         for(int j=0;j<heights[0].size()-1;j++)
  146.         {
  147.             glBegin(GL_TRIANGLE_STRIP);
  148.                 glColor3f(heights[i][j],heights[i][j],heights[i][j]);
  149.                 glVertex3f(i*size,heights[i][j]*h,j*size);
  150.                 glVertex3f((i+1)*size,heights[i+1][j]*h,j*size);
  151.                 glVertex3f(i*size,heights[i][j+1]*h,(j+1)*size);
  152.                 glVertex3f((i+1)*size,heights[i+1][j+1]*h,(j+1)*size);
  153.             glEnd();
  154.         }
  155. }
  156.  
  157. void init(float angle)
  158. {
  159.     glClearColor(0,0,0,1);
  160.     glMatrixMode(GL_PROJECTION);
  161.         glLoadIdentity();
  162.         gluPerspective(angle,640.0/480.0,1,1000);
  163.     glMatrixMode(GL_MODELVIEW);
  164.     initskybox();
  165.     glEnable(GL_DEPTH_TEST);
  166. //  loadHeightmap("heightmap.bmp");
  167.     generateNoise();
  168. }
  169.  
  170. void display()
  171. {
  172.     glLoadIdentity();
  173.     glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
  174.     cam.Control();
  175.     drawSkybox(50);
  176.    
  177.     cam.UpdateCamera();
  178.     renderHeightmap(0.1,3);
  179.    
  180. }
  181.  
  182. int main()
  183. {
  184.     SDL_Init(SDL_INIT_EVERYTHING);
  185.     SDL_SetVideoMode(640,480,32,SDL_OPENGL);
  186.     Uint32 start;
  187.     SDL_Event event;
  188.     srand(time(0));
  189.     bool running=true;
  190.     float angle=50;
  191.     init(angle);
  192.     bool b=false;
  193.     srand(time(0));
  194.     while(running)
  195.     {
  196.         start=SDL_GetTicks();
  197.         while(SDL_PollEvent(&event))
  198.         {
  199.             switch(event.type)
  200.             {
  201.                 case SDL_QUIT:
  202.                     running=false;
  203.                     break;
  204.                 case SDL_KEYDOWN:
  205.                     switch(event.key.keysym.sym)
  206.                     {
  207.                         case SDLK_ESCAPE:
  208.                             running=false;
  209.                             break;
  210.                     }
  211.                     break;
  212.                 case SDL_MOUSEBUTTONDOWN:
  213.                     cam.mouseIn(true);
  214.                     break;
  215.                    
  216.             }
  217.         }
  218.         display();
  219.         SDL_GL_SwapBuffers();
  220.         if(1000.0/30>SDL_GetTicks()-start)
  221.             SDL_Delay(1000.0/30-(SDL_GetTicks()-start));
  222.     }
  223.     killskybox();
  224.     SDL_Quit();
  225. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement