Advertisement
vivienneanthony

Olsen Noise Algorithm C++ WIP (memmove)

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