Advertisement
vivienneanthony

Olsen Noise Algorithm C++ WIP .001

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