about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYour Name <you@example.com>2020-11-01 12:56:06 +0100
committerYour Name <you@example.com>2020-11-01 12:56:06 +0100
commit74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b (patch)
tree5182d2224c453cc66164b1f275d1350beecd813a
downloadCPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.tar.gz
CPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.tar.bz2
CPerlin-74c5d2a42705fad1de5c4e1f240d5311b4aa5d5b.zip
Initial commit HEAD master
-rw-r--r--.gitignore1
-rwxr-xr-xCPerlinbin0 -> 17904 bytes
-rw-r--r--Makefile7
-rw-r--r--README.md0
-rw-r--r--include/perlin.h10
-rw-r--r--main.c113
-rw-r--r--perlin.c75
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);
+}