Advertisement
Guest User

RGB Perlin

a guest
Jul 14th, 2016
138
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.89 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <time.h>
  4. #include <SDL2/SDL.h>
  5. #define WIN_W 800
  6. #define WIN_H 600
  7. #define NOISE_W 800
  8. #define NOISE_H 600
  9. void SDLerr(int, char*);
  10. void updateScreen(double[][NOISE_W], double[][NOISE_W], double[][NOISE_W], SDL_Surface*);
  11. void text(SDL_Renderer*, int, int, char*, SDL_Texture**, SDL_Rect*);
  12. void generateNoise(double[][NOISE_W]);
  13. double interpolate(double[][NOISE_W], double, double);
  14. double mipmap(double[][NOISE_W], double, double, double);
  15.  
  16. int main(void) {
  17.     if (SDL_Init(SDL_INIT_VIDEO) < 0) SDLerr(1, "Unable to initialize SDL!");
  18.     srand(time(NULL));
  19.    
  20.     SDL_Window* window = SDL_CreateWindow("RGB Perlin", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIN_W, WIN_H, SDL_WINDOW_SHOWN);
  21.     if (window == NULL) SDLerr(2, "Unable to create window!");
  22.    
  23.     SDL_Surface* screen = SDL_GetWindowSurface(window);
  24.     if (screen == NULL) SDLerr(3, "Unable to get window surface");
  25.    
  26.     double** redNoise = malloc(NOISE_H * sizeof(double*) + NOISE_H * NOISE_W * sizeof(double));
  27.     double** greenNoise = malloc(NOISE_H * sizeof(double*) + NOISE_H * NOISE_W * sizeof(double));
  28.     double** blueNoise = malloc(NOISE_H * sizeof(double*) + NOISE_H * NOISE_W * sizeof(double));
  29.     generateNoise(redNoise);
  30.     generateNoise(greenNoise);
  31.     generateNoise(blueNoise);
  32.     updateScreen(blueNoise, greenNoise, redNoise, screen);
  33.  
  34.     SDL_Event event;
  35.     do
  36.     {
  37.         SDL_UpdateWindowSurface(window);
  38.         SDL_WaitEvent(&event);
  39.     }
  40.     while (event.type != SDL_QUIT);
  41.    
  42.     SDL_FreeSurface(screen);
  43.     SDL_DestroyWindow(window);
  44.     SDL_Quit();
  45.     return 0;
  46. }
  47.  
  48. void SDLerr(int errnum, char* errmsg) {
  49.     fprintf(stderr, "%s SDL_Error: %s\n", errmsg, SDL_GetError());
  50.     exit(errnum);
  51. }
  52.  
  53. void updateScreen(double blue[][NOISE_W], double green[][NOISE_W], double red[][NOISE_W], SDL_Surface* screen) {
  54.     unsigned char* pixels = screen -> pixels;
  55.     int p;
  56.    
  57.     for (int x = 0; x < NOISE_W; x++)
  58.         for (int y = 0; y < NOISE_H; y++) {
  59.             p = (y * NOISE_W + x) * 4;
  60.             pixels[p] = (char) (mipmap(blue, y, x, 64));
  61.             pixels[p + 1] = (char) (mipmap(green, y, x, 64));
  62.             pixels[p + 2] = (char) (mipmap(red, y, x, 64));
  63.         }
  64. }
  65.  
  66. void generateNoise(double noise[][NOISE_W]) {
  67.     for (int x = 0; x < NOISE_W; x++)
  68.         for (int y = 0; y < NOISE_H; y++)
  69.             noise[y][x] = (rand() % RAND_MAX) / (double) RAND_MAX;
  70. }
  71.  
  72. double interpolate(double noise[][NOISE_W], double x, double y) {
  73.     int x1 = (int) x, y1 = (int) y;
  74.     int x2 = (x1 + NOISE_W - 1) % NOISE_W;
  75.     int y2 = (y1 + NOISE_H - 1) % NOISE_H;
  76.     double fX = x - x1, fY = y - y1;
  77.    
  78.     double val = fX * fY * noise[y1][x1];
  79.     val += (1 - fX) * fY * noise[y1][x2];
  80.     val += fX * (1 - fY) * noise[y2][x1];
  81.     return val + (1 - fX) * (1 - fY) * noise[y2][x2];
  82. }
  83.  
  84. double mipmap(double noise[][NOISE_W], double x, double y, double size) {
  85.     double val = 0.;
  86.     for (double d = size; d >= 1; d /= 2.)
  87.         val += interpolate(noise, x / d, y / d) * d;
  88.     return 128. * val / size;
  89. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement