diff options
-rw-r--r-- | Makefile | 12 | ||||
-rw-r--r-- | brotshader.c | 70 | ||||
-rw-r--r-- | mandelbrot.glsl | 45 |
3 files changed, 127 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c956781 --- /dev/null +++ b/Makefile @@ -0,0 +1,12 @@ +PROG=brotshader +CC=gcc +FLAGS=-lm `pkg-config -libs raylib` + +.DEFAULT_GOAL := run + +${PROG}: ${PROG}.c + ${CC} ${PROG}.c -o ${PROG} ${FLAGS} + +run: ${PROG} + ./${PROG} + diff --git a/brotshader.c b/brotshader.c new file mode 100644 index 0000000..d0fd96b --- /dev/null +++ b/brotshader.c @@ -0,0 +1,70 @@ +#include <raylib.h> + +const int width = 1280; +const int height = 1280; + +int main() { + InitWindow(width, height, "brotshader"); + + Shader shader = LoadShader(0, "mandelbrot.glsl"); + + RenderTexture2D target = LoadRenderTexture(width, height); + + float c[2] = {0, 0}; + + float offset[2] = {0, 0}; + float zoom = 2.0f; + int max = 255; + + int resolutionLoc = GetShaderLocation(shader, "resolution"); + int locationLoc = GetShaderLocation(shader, "location"); + int zoomLoc = GetShaderLocation(shader, "zoom"); + int maxLoc = GetShaderLocation(shader, "max"); + + float screen[2] = {(float)width, (float)height}; + + SetShaderValue(shader, resolutionLoc, screen, UNIFORM_VEC2); + SetShaderValue(shader, locationLoc, &offset, UNIFORM_VEC2); + SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT); + SetShaderValue(shader, maxLoc, &max, UNIFORM_INT); + + SetTargetFPS(60); + + while (!WindowShouldClose()) { + + if (IsKeyDown(KEY_UP)) offset[1] -= zoom * 0.01f; + if (IsKeyDown(KEY_DOWN)) offset[1] += zoom * 0.01f; + if (IsKeyDown(KEY_RIGHT)) offset[0] -= zoom * 0.01f; + if (IsKeyDown(KEY_LEFT)) offset[0] += zoom * 0.01f; + + if (IsKeyDown(KEY_W)) zoom -= zoom * 0.01f; + if (IsKeyDown(KEY_S)) zoom += zoom * 0.01f; + if (IsKeyDown(KEY_A)) max -= 1; + if (IsKeyDown(KEY_D)) max += 1; + + SetShaderValue(shader, resolutionLoc, screen, UNIFORM_VEC2); + SetShaderValue(shader, locationLoc, &offset, UNIFORM_VEC2); + SetShaderValue(shader, zoomLoc, &zoom, UNIFORM_FLOAT); + SetShaderValue(shader, maxLoc, &max, UNIFORM_INT); + + BeginDrawing(); + + ClearBackground(RAYWHITE); + + BeginTextureMode(target); + DrawRectangle(0, 0, width, height, BLACK); + EndTextureMode(); + + BeginShaderMode(shader); + DrawTexture(target.texture, 0, 0, WHITE); + EndShaderMode(); + + EndDrawing(); + } + + UnloadShader(shader); + UnloadRenderTexture(target); + + CloseWindow(); +} + diff --git a/mandelbrot.glsl b/mandelbrot.glsl new file mode 100644 index 0000000..d3d0ee2 --- /dev/null +++ b/mandelbrot.glsl @@ -0,0 +1,45 @@ +#version 100 +precision highp float; + +uniform vec2 resolution; +uniform vec2 location; +uniform double zoom; + +uniform int max; + +vec2 compsquare(vec2 z) { + float temp = z.x; + z.x = z.x * z.x - z.y * z.y; + z.y = 2.0 * temp * z.y; + return z; +} + +vec3 hsv2rgb(vec3 hue){ + vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0); + vec3 p = abs(fract(hue.xxx + K.xyz) * 6.0 - K.www); + return hue.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), hue.y); +} + +vec3 mandelbort(vec2 point){ + vec2 z = vec2(0.0); + float iters = 0.0; + for (iters = 0.0; iters < float(max); ++iters) + { + z = compsquare(z) + point; + if(dot(z, z) > 4.0) break; + } + float hue = iters / float(max); + if(hue > 0.98) return vec3(0.0); + return hsv2rgb(vec3(hue, 1.0, 1.0)); +} + +void main() +{ + vec2 uv = gl_FragCoord.xy / resolution; + uv.x *= resolution.x / resolution.y; + uv -= vec2(0.7, 0.5); + uv *= zoom; + uv -= location; + + gl_FragColor = vec4(mandelbort(uv), 1.0); +} |