Guest User

Olsen Noise Algorithm C++ WIP

a guest
Feb 17th, 2015
212
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.41 KB | None | 0 0
  1. /*
  2.  * @author Tat
  3.  * c++ rewrite vivienne (WIP)
  4.  */
  5.  
  6. #include <iostream>
  7. #include <vector>
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <png++/png.hpp>
  12.  
  13. using namespace std;
  14.  
  15. void SaveTerrFile(const int * image, int size, char * filename);
  16.  
  17.  
  18. class OlsenNoise2D
  19. {
  20.  
  21. public:
  22.     int * olsennoise(int x, int y, int width, int height);
  23.  
  24. private:
  25.     int hashrandom(std::vector<long int> elements);
  26.     long long hash(long long v);
  27.  
  28. };
  29.  
  30. int * OlsenNoise2D::olsennoise(int x, int y, int width, int height)
  31. {
  32.     int maxiterations =5;
  33.     int cx, cy;
  34.     int cxh, cyh;
  35.     int cwidth, cheight;
  36.     int xoff, yoff;
  37.     int nwidth, nheight;
  38.     int nx, ny;
  39.     int nxh, nyh;
  40.     int m=0;
  41.     int n=0;
  42.     int * field = NULL;
  43.  
  44.     for (int iteration = 0; iteration < maxiterations; iteration++)
  45.     {
  46.         nx = x;
  47.         ny = y;
  48.  
  49.         nxh = x + width;
  50.         nyh = y + height;
  51.  
  52.         n = maxiterations - iteration;
  53.  
  54.         for (int i = 1; i < n; i++)
  55.         {
  56.             nx = (nx / 2) - 1;
  57.             ny = (ny / 2) - 1;
  58.             nxh = 1 -(-nxh/2);
  59.             nyh = 1 -(-nyh/2);
  60.         }
  61.  
  62.         xoff = -2*((nx/2)) + nx + 1;
  63.         yoff = -2*((ny/2)) + ny + 1;
  64.  
  65.         cx = (nx / 2) - 1;
  66.         cy = (ny / 2) - 1;
  67.         cxh = 1 -(-nxh/2);
  68.         cyh = 1 -(-nyh/2);
  69.  
  70.         nwidth = nxh - nx;
  71.         nheight = nyh - ny;
  72.  
  73.         cwidth = cxh - cx;
  74.         cheight = cyh - cy;
  75.  
  76.         /// Only happens once
  77.         if (field==NULL)
  78.         {
  79.             /// allocate memory
  80.             field = new int[height * width];
  81.  
  82.             /// blank value
  83.             for (int x = 0; x < width; x++)
  84.             {
  85.                 for (int y = 0; y < height; y++)
  86.                 {
  87.                     field[x+(y*width)]=0;
  88.                 }
  89.             }
  90.         }
  91.  
  92.         /// First loop
  93.         for (int j = 0, m=cwidth; j < m; j++)
  94.         {
  95.             for (int k = 0, n=cheight; k < n; k++)
  96.             {
  97.                 field[j+(k*m)] += (hashrandom( {cx + j, ((cy + k)*m), iteration}) & (1 << (7 - iteration)));
  98.             }
  99.         }
  100.  
  101.         /// Up sampled
  102.         int * upsampled = new int[(cwidth*2)*(cheight*2)];
  103.         long int upsampledsize=(cwidth*2)*(cheight*2);
  104.  
  105.         for (int j = 0, m=cwidth*2; j < m; j++)
  106.         {
  107.             for (int k = 0,n=cheight*2; k < n; k++)
  108.             {
  109.                 upsampled[j+(k*m)] = field[(j / 2)+((k / 2)*m)];
  110.             }
  111.         }
  112.  
  113.         memcpy(field,upsampled,sizeof(int(upsampledsize)));
  114.  
  115.         delete upsampled;
  116.  
  117.         /// Blur field
  118.         int * blurfield =new int[(cwidth-2)*(cheight-2)];
  119.         long int blurfieldsize = (cwidth-2)*(cheight-2);
  120.  
  121.         for (int j = 0,m=cwidth-2; j < m; j++)
  122.         {
  123.             for (int k = 0, n=cheight-2;  k < n; k++)
  124.             {
  125.                 for (int h = 0; h < 9; h++)
  126.                 {
  127.  
  128.                     blurfield[j+(k*m)] += field[(j + (h % 3))+((k + (h / 3))*(cwidth*2))];
  129.                 }
  130.                 blurfield[j+(k*m)] /= 9;
  131.             }
  132.         }
  133.  
  134.         memcpy(field,blurfield,sizeof(int(blurfieldsize)));
  135.         delete blurfield;
  136.  
  137.         /// Trim field
  138.         int * trimfield = new int[nwidth*nheight];
  139.         long int trimfieldsize = nwidth*nheight;
  140.  
  141.         for (int j = 0, m=nwidth; j < m; j++)
  142.         {
  143.             for (int k = 0, n=nheight; k < n; k++)
  144.             {
  145.                 trimfield[j+(k*m)] = field[(j + xoff)+(((k + yoff)+(nheight-2))*(cwidth-2))];
  146.             }
  147.         }
  148.  
  149.         memcpy(field,trimfield,sizeof(int(trimfieldsize)));
  150.         delete trimfield;
  151.     }
  152.  
  153.     SaveTerrFile(field, width, "rgbOlsena.png");
  154.  
  155.     return field;
  156. }
  157.  
  158. int OlsenNoise2D::hashrandom(std::vector<long int> elements)
  159. {
  160.     long long hashcalc = 0;
  161.  
  162.  
  163.     for (int i = 0; i < elements.size(); i++)
  164.     {
  165.         hashcalc ^= elements[i];
  166.         hashcalc = hash(hashcalc);
  167.     }
  168.     return (int) hashcalc;
  169. };
  170.  
  171. long long OlsenNoise2D::hash(long long v)
  172. {
  173.     long long hash = v;
  174.     long long h = hash;
  175.  
  176.     switch ((int) hash & 3)
  177.     {
  178.     case 3:
  179.         hash += h;
  180.         hash ^= hash << 32;
  181.         hash ^= h << 36;
  182.         hash += hash >> 22;
  183.         break;
  184.     case 2:
  185.         hash += h;
  186.         hash ^= hash << 22;
  187.         hash += hash >> 34;
  188.         break;
  189.     case 1:
  190.         hash += h;
  191.         hash ^= hash << 20;
  192.         hash += hash >> 2;
  193.     }
  194.     hash ^= hash << 6;
  195.     hash += hash >> 10;
  196.     hash ^= hash << 8;
  197.     hash += hash >> 34;
  198.     hash ^= hash << 50;
  199.     hash += hash >> 12;
  200.     return hash;
  201. };
  202.  
  203.  
  204. int main()
  205. {
  206.     /// Test
  207.     int ImageSize=2049;
  208.  
  209.     int * imageInput = new int[ImageSize*ImageSize];
  210.  
  211.     /// Image
  212.     OlsenNoise2D testingolsen;
  213.     imageInput=testingolsen.olsennoise(0,0,ImageSize,ImageSize);
  214.  
  215.     // SaveTerrFile(imageInput, ImageSize, "rgbOlsen.png");
  216.  
  217.     delete imageInput;
  218.  
  219.     return 1;
  220. }
  221.  
  222.  
  223. void SaveTerrFile(const int * image, int size, char * filename)
  224. {
  225.     png::image< png::rgb_pixel > newimage(size, size);
  226.  
  227.     for (unsigned int y = 0; y < newimage.get_width(); ++y)
  228.     {
  229.         for (unsigned int x = 0; x < newimage.get_height(); ++x)
  230.         {
  231.             int col = int(image[x+(y*newimage.get_width())]);
  232.             newimage[y][x] = png::rgb_pixel(col,col,col);
  233.             // non-checking equivalent of image.set_pixel(x, y, ...);
  234.         }
  235.     }
  236.  
  237.     newimage.write(filename);
  238. }
Advertisement
Add Comment
Please, Sign In to add comment