Guest User

Untitled

a guest
Jan 23rd, 2019
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.88 KB | None | 0 0
  1. //
  2. // Perlin noise generator
  3. //
  4.  
  5. #include <stdlib.h>
  6. #include <stdio.h>
  7. #include <math.h>
  8. #include <time.h>
  9.  
  10. #define B 0x100
  11. #define BM 0xff
  12.  
  13. #define N 0x1000
  14. #define NP 12 /* 2^N */
  15. #define NM 0xfff
  16.  
  17. static int p[B + B + 2];
  18. static float g2[B + B + 2][2];
  19. static int start = 1;
  20.  
  21. static void init(void);
  22.  
  23. #define s_curve(t) ( t * t * (3. - 2. * t) )
  24.  
  25. #define lerp(t, a, b) ( a + t * (b - a) )
  26.  
  27. #define setup(i,b0,b1,r0,r1)\
  28. t = vec[i] + N;\
  29. b0 = ((int)t) & BM;\
  30. b1 = (b0+1) & BM;\
  31. r0 = t - (int)t;\
  32. r1 = r0 - 1.;
  33.  
  34. float noise2(float vec[2])
  35. {
  36. int bx0, bx1, by0, by1, b00, b10, b01, b11;
  37. float rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
  38. register int i, j;
  39.  
  40. if (start) {
  41. start = 0;
  42. init();
  43. }
  44.  
  45. setup(0, bx0,bx1, rx0,rx1);
  46. setup(1, by0,by1, ry0,ry1);
  47.  
  48. i = p[ bx0 ];
  49. j = p[ bx1 ];
  50.  
  51. b00 = p[ i + by0 ];
  52. b10 = p[ j + by0 ];
  53. b01 = p[ i + by1 ];
  54. b11 = p[ j + by1 ];
  55.  
  56. sx = s_curve(rx0);
  57. sy = s_curve(ry0);
  58.  
  59. #define at2(rx,ry) ( rx * q[0] + ry * q[1] )
  60.  
  61. q = g2[ b00 ] ; u = at2(rx0,ry0);
  62. q = g2[ b10 ] ; v = at2(rx1,ry0);
  63. a = lerp(sx, u, v);
  64.  
  65. q = g2[ b01 ] ; u = at2(rx0,ry1);
  66. q = g2[ b11 ] ; v = at2(rx1,ry1);
  67. b = lerp(sx, u, v);
  68.  
  69. return lerp(sy, a, b);
  70. }
  71.  
  72. static void normalize2(float v[2])
  73. {
  74. float s;
  75.  
  76. s = sqrt(v[0] * v[0] + v[1] * v[1]);
  77. v[0] = v[0] / s;
  78. v[1] = v[1] / s;
  79. }
  80.  
  81. static int randomize(void) {
  82. static unsigned int seed = 0;
  83.  
  84. if (seed == 0) {
  85. seed = time(NULL);
  86. srand(seed);
  87. }
  88.  
  89. return rand();
  90. }
  91.  
  92. static void init(void)
  93. {
  94. int i, j, k;
  95.  
  96. for (i = 0 ; i < B ; i++) {
  97. p[i] = i;
  98.  
  99. for (j = 0 ; j < 2 ; j++)
  100. g2[i][j] = (float)((randomize() % (B + B)) - B) / B;
  101. normalize2(g2[i]);
  102. }
  103.  
  104. while (--i) {
  105. k = p[i];
  106. p[i] = p[j = randomize() % B];
  107. p[j] = k;
  108. }
  109.  
  110. for (i = 0 ; i < B + 2 ; i++) {
  111. p[B + i] = p[i];
  112. for (j = 0 ; j < 2 ; j++)
  113. g2[B + i][j] = g2[i][j];
  114. }
  115. }
  116.  
  117. //
  118. // Display code (allegro)
  119. //
  120.  
  121. #include <allegro5/allegro.h>
  122.  
  123. #define fatal_error(str) { fputs(str, stderr); goto errquit; }
  124.  
  125. int main(int argc, char **argv) {
  126. ALLEGRO_DISPLAY *display = NULL;
  127. ALLEGRO_BITMAP *bmp = NULL;
  128. int x, y;
  129. float vec[2];
  130. float noise;
  131.  
  132. if (!al_init()) fatal_error("failed to initialize allegro!");
  133.  
  134. display = al_create_display(800, 600);
  135. if (!display) fatal_error("failed to create display!");
  136. al_set_window_title(display, "Allegro Perlin Display");
  137.  
  138. bmp = al_create_bitmap(80, 60);
  139. al_lock_bitmap(bmp, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
  140. al_set_target_bitmap(bmp);
  141.  
  142. // Begin Perlin usage
  143. for(x = 0; x<80; x++) {
  144. for(y = 0; y<60; y++) {
  145. vec[0] = (x+.5)/5.;
  146. vec[1] = (y+.5)/5.;
  147. noise = (noise2(vec) + 1) / 2.;
  148. al_put_pixel(x, y, al_map_rgb_f(noise, noise, noise));
  149. }
  150. }
  151. // End Perlin usage
  152.  
  153. al_set_target_bitmap(al_get_backbuffer(display));
  154. al_unlock_bitmap(bmp);
  155.  
  156. al_draw_scaled_bitmap(bmp, 0, 0, 80, 60, 0, 0, 800, 600, 0);
  157.  
  158. al_flip_display();
  159. al_rest(10.);
  160.  
  161. al_destroy_display(display);
  162.  
  163. return 0;
  164.  
  165. errquit:
  166. return -1;
  167. }
Add Comment
Please, Sign In to add comment