diff options
author | Your Name <you@example.com> | 2020-11-01 12:56:06 +0100 |
---|---|---|
committer | Your Name <you@example.com> | 2020-11-01 12:56:06 +0100 |
commit | 74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b (patch) | |
tree | 5182d2224c453cc66164b1f275d1350beecd813a | |
download | CPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.tar.gz CPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.tar.bz2 CPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.zip |
-rw-r--r-- | .gitignore | 1 | ||||
-rwxr-xr-x | CPerlin | bin | 0 -> 17904 bytes | |||
-rw-r--r-- | Makefile | 7 | ||||
-rw-r--r-- | README.md | 0 | ||||
-rw-r--r-- | include/perlin.h | 10 | ||||
-rw-r--r-- | main.c | 113 | ||||
-rw-r--r-- | perlin.c | 75 |
7 files changed, 206 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9fa32fc --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +CPerlin.* diff --git a/CPerlin b/CPerlin new file mode 100755 index 0000000..1bc4b10 --- /dev/null +++ b/CPerlin Binary files differdiff --git a/Makefile b/Makefile new file mode 100644 index 0000000..bae0a04 --- /dev/null +++ b/Makefile @@ -0,0 +1,7 @@ +all: CPerlin + +CPerlin: main.c perlin.c include/perlin.h + gcc -lSDL2 -lm main.c perlin.c -o CPerlin + +clean: + rm CPerlin diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/README.md diff --git a/include/perlin.h b/include/perlin.h new file mode 100644 index 0000000..b1dbb6f --- /dev/null +++ b/include/perlin.h @@ -0,0 +1,10 @@ +#ifndef _PERLIN_H_ +#define _PERLIN_H_ + +#include <stdlib.h> +#include <math.h> +#include <time.h> + +float perlin_noise(float x, float y); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..7845ac4 --- /dev/null +++ b/main.c @@ -0,0 +1,113 @@ +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <SDL2/SDL.h> +#include <time.h> + +#include "include/perlin.h" + +#define WIDTH 700 +#define HEIGHT 500 + +//TODO: ADD ZOOM +//TODO: add rgb from args, size from args + +int main(int argc, char** argv); +uint32_t getargb(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + +int main(int argc, char** argv) +{ + SDL_Window* window = NULL; + SDL_Init(SDL_INIT_VIDEO); + window = SDL_CreateWindow("Perlin Noise Visualizer", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN ); + + SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0); + SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE); + SDL_RenderSetLogicalSize(renderer, WIDTH, HEIGHT); + SDL_Texture* sdlTexture = SDL_CreateTexture(renderer, + SDL_PIXELFORMAT_ARGB8888, + SDL_TEXTUREACCESS_STREAMING, WIDTH, HEIGHT); + SDL_SetTextureBlendMode(sdlTexture, SDL_BLENDMODE_BLEND); + + srand(time(NULL)); + + static int seedx = 523213;//rand(); + static int seedy = 1;//rand(); + + load: + seedx += 10000; + seedy += 50000; + printf("Generating perlin noise...\n"); + uint32_t* pixels = malloc(sizeof *pixels * WIDTH * HEIGHT); + for(int i = 0, counter = 0; i < HEIGHT; i++) //no counter? + for(int j = 0; j < WIDTH; j++) + pixels[counter++] = getargb(214, 56, 203, (perlin_noise(i + seedx, j + seedy)-(-1))*(255-0)/(1-(-1))+ 0); + + reload: + SDL_UpdateTexture(sdlTexture, NULL, pixels, WIDTH * sizeof(uint32_t)); + SDL_RenderClear(renderer); + static double zoom_value = 1; + printf("zoom is %f\n", zoom_value); + SDL_Rect zoom = { 0 }; + zoom.h = HEIGHT * zoom_value; + zoom.w = WIDTH * zoom_value; + //zoom.x = -WIDTH; + //zoom.y = -HEIGHT; //? https://wiki.libsdl.org/SDL_Rect + SDL_RenderCopy(renderer, sdlTexture, NULL, &zoom); + SDL_RenderPresent(renderer); + + while(1) + { + SDL_Event e; + while (SDL_PollEvent(&e)) + { + switch(e.type) + { + case SDL_QUIT: + exit(0); + break; + case SDL_KEYDOWN: + switch(e.key.keysym.sym) + { + case SDLK_ESCAPE: + case SDLK_q: exit(0); break; + case SDLK_F5: + case SDLK_r: goto load; break; + } + break; + case SDL_MOUSEWHEEL: + if(e.wheel.y > 0) // scroll up + { + printf("scroll up! (%d, %d)\n", e.motion.x, e.motion.y); + zoom_value += 0.1; + goto reload; + } + else if(e.wheel.y < 0) // scroll down + { + printf("scroll down! (%d, %d)\n", e.motion.x, e.motion.y); //https://stackoverflow.com/questions/49111054/how-to-get-mouse-position-on-mouse-wheel-event + zoom_value -= 0.1; + zoom_value = zoom_value < 1.0 ? 1.0 : zoom_value; + goto reload; + } + break; + } + } + } + + free(pixels); + SDL_DestroyWindow(window); + SDL_Quit(); + + return 0; +} + +uint32_t getargb(uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + uint32_t res = 0; + res |= a << 24; + res |= b << 16; + res |= g << 8; + res |= r; + + return res; +} diff --git a/perlin.c b/perlin.c new file mode 100644 index 0000000..0a08147 --- /dev/null +++ b/perlin.c @@ -0,0 +1,75 @@ +#include "include/perlin.h" + +static float noise(int x, int y) //seed this?? +{ + int n; + + n = x + y * 57 * 2749; + n = (n << 13) ^ n * 1087; + return (1.0 - ( (n * ((n * n * 15731) + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0)*3433; +} + +static float interpolate(float a, float b, float x) +{ + float pi_mod; + float f_unk; + + pi_mod = x * 3.1415927; + f_unk = (1 - cos(pi_mod)) * 0.5; + return (a * (1 - f_unk) + b * x); +} + +static float smooth_noise(int x, int y) +{ + float corners; + float center; + float sides; + + corners = (noise(x - 1, y - 1) + noise(x + 1, y - 1) + + noise(x - 1, x + 1) + noise(x + 1, y + 1)) / 16; + sides = (noise(x - 1, y) + noise(x + 1, y) + noise(x, y - 1) + + noise(x, y + 1)) / 8; + center = noise(x, y) / 4; + return (corners + sides + center); +} + +static float noise_handler(float x, float y) +{ + int int_val[2]; + float frac_val[2]; + float value[4]; + float res[2]; + + int_val[0] = (int)x; + int_val[1] = (int)y; + frac_val[0] = x - int_val[0]; + frac_val[1] = y - int_val[1]; + value[0] = smooth_noise(int_val[0], int_val[1]); + value[1] = smooth_noise(int_val[0] + 1, int_val[1]); + value[2] = smooth_noise(int_val[0], int_val[1] + 1); + value[3] = smooth_noise(int_val[0] + 1, int_val[1] + 1); + res[0] = interpolate(value[0], value[1], frac_val[0]); + res[1] = interpolate(value[2], value[3], frac_val[0]); + return (interpolate(res[0], res[1], frac_val[1])); +} + +float perlin_noise(float x, float y) //implement Fractal Brownian Motion? +{ + srand(time(NULL)); + float total; + float per; + float amp; + int hz; + int octave; + + total = 0.0; + per = 0.5; + octave = 10; + for(int i = 0; i < octave; i++) + { + hz = pow(2, i); + amp = pow(per, (float)i); + total += noise_handler(x * (float)hz, y * (float)hz) * amp; + } + return (total); +} |