genuary

demo program for genuary 1st 2026
Download | Log | Files | Refs

genuary1.c (11492B)


      1 #include "raylib.h"
      2 #include "raymath.h"
      3 #include "rlgl.h"
      4 #include <math.h>
      5 
      6 #define SCREEN_WIDTH 1000
      7 #define SCREEN_HEIGHT 1000
      8 
      9 #define FIELD_SIZE 64
     10 #define CHAIN_HEIGHT 1024
     11 #define MAX_INSTANCES ((FIELD_SIZE * 2) * (FIELD_SIZE * 2) * CHAIN_HEIGHT / 2)
     12 
     13 #define CUBE_SIZE 0.5f
     14 #define VERTICAL_SPACING (CUBE_SIZE * 1.7320508f)
     15 #define SPACING 8.0f
     16 
     17 #define TILT_STRENGTH 0.30f
     18 #define OFFSET_STRENGTH 3.00f
     19 
     20 #define FADE_START_DISTANCE SPACING * 2
     21 #define FADE_END_DISTANCE SPACING * 8
     22 #define RENDER_CULL_DISTANCE FADE_END_DISTANCE
     23 #define RENDER_CULL_SQ (RENDER_CULL_DISTANCE * RENDER_CULL_DISTANCE)
     24 
     25 #define HUE 91.0f
     26 #define SATURATION 0.15f
     27 #define VALUE 0.78f
     28 
     29 #define HASH(x, z)                                                             \
     30   (((x) * 73856093u ^ (z) * 19349663u) * 0x85ebca6b & 0x7FFFFFFF) /            \
     31       (float)0x7FFFFFFF
     32 
     33 const char *vsCode =
     34     "#version 330\n"
     35     "layout(location = 0) in vec3 vertexPosition;\n"
     36     "layout(location = 1) in vec2 vertexTexCoord;\n"
     37     "layout(location = 2) in vec3 vertexNormal;\n"
     38     "layout(location = 3) in mat4 instanceTransform;\n"
     39     "\n"
     40     "uniform mat4 mvp;\n"
     41     "\n"
     42     "out vec3 fragPosition;\n"
     43     "\n"
     44     "void main() {\n"
     45     "    vec4 worldPos = instanceTransform * vec4(vertexPosition, 1.0);\n"
     46     "    fragPosition = vec3(worldPos);\n"
     47     "    gl_Position = mvp * worldPos;\n"
     48     "}\n";
     49 
     50 const char *fsCode = "#version 330\n"
     51                      "in vec3 fragPosition;\n"
     52                      "out vec4 finalColor;\n"
     53                      "\n"
     54                      "uniform vec3 viewPos;\n"
     55                      "uniform float fadeStart;\n"
     56                      "uniform float fadeEnd;\n"
     57                      "uniform vec3 baseColor;\n"
     58                      "\n"
     59                      "const float bayer8x8[64] = float[](\n"
     60                      "    0.0, 32.0, 8.0, 40.0, 2.0, 34.0, 10.0, 42.0,\n"
     61                      "    48.0, 16.0, 56.0, 24.0, 50.0, 18.0, 58.0, 26.0,\n"
     62                      "    12.0, 44.0, 4.0, 36.0, 14.0, 46.0, 6.0, 38.0,\n"
     63                      "    60.0, 28.0, 52.0, 20.0, 62.0, 30.0, 54.0, 22.0,\n"
     64                      "    3.0, 35.0, 11.0, 43.0, 1.0, 33.0, 9.0, 41.0,\n"
     65                      "    51.0, 19.0, 59.0, 27.0, 49.0, 17.0, 57.0, 25.0,\n"
     66                      "    15.0, 47.0, 7.0, 39.0, 13.0, 45.0, 5.0, 37.0,\n"
     67                      "    63.0, 31.0, 55.0, 23.0, 61.0, 29.0, 53.0, 21.0\n"
     68                      ");\n"
     69                      "\n"
     70                      "void main() {\n"
     71                      "    float dist = distance(fragPosition, viewPos);\n"
     72                      "    float intensity = 1.0 - clamp((dist - fadeStart) / "
     73                      "(fadeEnd - fadeStart), 0.0, 1.0);\n"
     74                      "\n"
     75                      "    int x = int(gl_FragCoord.x) % 8;\n"
     76                      "    int y = int(gl_FragCoord.y) % 8;\n"
     77                      "    float rawValue = bayer8x8[y * 8 + x];\n"
     78                      "    float threshold = (rawValue + 0.5) / 64.0;\n"
     79                      "    if (intensity < threshold) {\n"
     80                      "        finalColor = vec4(0.0, 0.0, 0.0, 1.0);\n"
     81                      "    } else {\n"
     82                      "        finalColor = vec4(baseColor, 1.0);\n"
     83                      "    }\n"
     84                      "}\n";
     85 
     86 const char *liquifyFsCode =
     87     "#version 330\n"
     88     "in vec2 fragTexCoord;\n"
     89     "in vec4 fragColor;\n"
     90     "out vec4 finalColor;\n"
     91     "\n"
     92     "uniform sampler2D texture0;\n"
     93     "uniform vec4 colDiffuse;\n"
     94     "uniform vec2 center1;\n"
     95     "uniform vec2 center2;\n"
     96     "uniform vec2 screenSize;\n"
     97     "\n"
     98     "const float radius = 1.80;\n"
     99     "const float strength = 0.10;\n"
    100     "\n"
    101     "vec2 calculateDistortion(vec2 uv, vec2 center) {\n"
    102     "    float aspect = screenSize.x / screenSize.y;\n"
    103     "    vec2 uvCorrected = uv;\n"
    104     "    uvCorrected.x *= aspect;\n"
    105     "    vec2 centerCorrected = center;\n"
    106     "    centerCorrected.x *= aspect;\n"
    107     "\n"
    108     "    vec2 delta = uvCorrected - centerCorrected;\n"
    109     "    float dist = length(delta);\n"
    110     "    \n"
    111     "    // Smoothstep creates a soft edge 0.0 to radius\n"
    112     "    float mask = 1.0 - smoothstep(0.0, radius, dist);\n"
    113     "    \n"
    114     "    // Distort UV towards the center point\n"
    115     "    return (uv - center) * mask * strength;\n"
    116     "}\n"
    117     "\n"
    118     "void main() {\n"
    119     "    vec2 uv = fragTexCoord;\n"
    120     "    vec2 offset1 = calculateDistortion(uv, center1);\n"
    121     "    vec2 offset2 = calculateDistortion(uv, center2);\n"
    122     "    uv -= (offset1 + offset2);\n"
    123     "    finalColor = texture(texture0, uv) * colDiffuse * fragColor;\n"
    124     "}\n";
    125 
    126 Matrix transforms[MAX_INSTANCES];
    127 
    128 Vector2 GetPerimeterPosition(float t) {
    129   float cycle = fmodf(t / 100, 4.0f);
    130 
    131   if (cycle < 1.0f) {
    132     return (Vector2){cycle, 0.0f};
    133   } else if (cycle < 2.0f) {
    134     return (Vector2){1.0f, cycle - 1.0f};
    135   } else if (cycle < 3.0f) {
    136     return (Vector2){1.0f - (cycle - 2.0f), 1.0f};
    137   } else {
    138     return (Vector2){0.0f, 1.0f - (cycle - 3.0f)};
    139   }
    140 }
    141 
    142 int main(void) {
    143   SetConfigFlags(FLAG_WINDOW_RESIZABLE);
    144   InitWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "GENUARY 1. ONE SHAPE, ONE COLOR");
    145 
    146   Camera3D camera = {0};
    147   camera.up = (Vector3){0.0f, 1.0f, 0.0f};
    148   camera.fovy = 30.0f;
    149   camera.projection = CAMERA_PERSPECTIVE;
    150 
    151   SetTargetFPS(144);
    152 
    153   Shader ditherShader = LoadShaderFromMemory(vsCode, fsCode);
    154   ditherShader.locs[SHADER_LOC_MATRIX_MVP] =
    155       GetShaderLocation(ditherShader, "mvp");
    156   ditherShader.locs[SHADER_LOC_VECTOR_VIEW] =
    157       GetShaderLocation(ditherShader, "viewPos");
    158   ditherShader.locs[SHADER_LOC_MATRIX_MODEL] = 3;
    159 
    160   int fadeStartLoc = GetShaderLocation(ditherShader, "fadeStart");
    161   int fadeEndLoc = GetShaderLocation(ditherShader, "fadeEnd");
    162   int colorLoc = GetShaderLocation(ditherShader, "baseColor");
    163   float fadeStartVal = FADE_START_DISTANCE;
    164   float fadeEndVal = FADE_END_DISTANCE;
    165   Color c = ColorFromHSV(HUE, SATURATION, VALUE);
    166   Vector3 colorVal = {(float)c.r / 255.0f, (float)c.g / 255.0f,
    167                       (float)c.b / 255.0f};
    168   SetShaderValue(ditherShader, fadeStartLoc, &fadeStartVal,
    169                  SHADER_UNIFORM_FLOAT);
    170   SetShaderValue(ditherShader, fadeEndLoc, &fadeEndVal, SHADER_UNIFORM_FLOAT);
    171   SetShaderValue(ditherShader, colorLoc, &colorVal, SHADER_UNIFORM_VEC3);
    172 
    173   Shader liquifyShader = LoadShaderFromMemory(0, liquifyFsCode);
    174   int locCenter1 = GetShaderLocation(liquifyShader, "center1");
    175   int locCenter2 = GetShaderLocation(liquifyShader, "center2");
    176   int locScreenSize = GetShaderLocation(liquifyShader, "screenSize");
    177 
    178   RenderTexture2D target =
    179       LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
    180   Vector2 currentScreenSize = {(float)GetScreenWidth(),
    181                                (float)GetScreenHeight()};
    182   SetShaderValue(liquifyShader, locScreenSize, &currentScreenSize,
    183                  SHADER_UNIFORM_VEC2);
    184 
    185   Mesh cubeMesh = GenMeshCube(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE);
    186   Material cubeMat = LoadMaterialDefault();
    187   cubeMat.shader = ditherShader;
    188 
    189   Matrix rotZ = MatrixRotateZ(54.7356f * DEG2RAD);
    190   Matrix rotY = MatrixRotateY(45.0f * DEG2RAD);
    191   Matrix baseRotation = MatrixMultiply(rotY, rotZ);
    192 
    193   Vector3 upVector = {0.0f, 1.0f, 0.0f};
    194 
    195   float timeAccumulator = 0.0f;
    196 
    197   while (!WindowShouldClose()) {
    198     float dt = GetFrameTime();
    199     timeAccumulator += dt;
    200 
    201     if (IsWindowResized()) {
    202       UnloadRenderTexture(target);
    203       target = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
    204       currentScreenSize =
    205           (Vector2){(float)GetScreenWidth(), (float)GetScreenHeight()};
    206       SetShaderValue(liquifyShader, locScreenSize, &currentScreenSize,
    207                      SHADER_UNIFORM_VEC2);
    208     }
    209 
    210     float t1 = timeAccumulator * 0.1f;
    211     float t2 = 4.0f - (timeAccumulator * 0.6f + 2.0f);
    212     while (t2 < 0)
    213       t2 += 400.0f;
    214 
    215     Vector2 p1 = GetPerimeterPosition(t1);
    216     Vector2 p2 = GetPerimeterPosition(t2);
    217 
    218     SetShaderValue(liquifyShader, locCenter1, &p1, SHADER_UNIFORM_VEC2);
    219     SetShaderValue(liquifyShader, locCenter2, &p2, SHADER_UNIFORM_VEC2);
    220 
    221     float t03 = timeAccumulator * 0.05f;
    222     float t042 = timeAccumulator * 0.05f;
    223     float t015 = timeAccumulator * 0.05f;
    224     camera.position = (Vector3){sinf(t03) * 10.0f, 0.0f, cosf(t042) * 10.0f};
    225     camera.target =
    226         (Vector3){sinf(t03 + 1.0f) * 5.0f, 0.0f, cosf(t042 + 1.0f) * 5.0f};
    227     UpdateCamera(&camera, CAMERA_ORBITAL);
    228 
    229     float camPos[3] = {camera.position.x, camera.position.y, camera.position.z};
    230     SetShaderValue(ditherShader, ditherShader.locs[SHADER_LOC_VECTOR_VIEW],
    231                    camPos, SHADER_UNIFORM_VEC3);
    232 
    233     Vector2 camPos2D = {camera.position.x, camera.position.z};
    234     int count = 0;
    235     int gridOffsetX = (int)(camera.position.x / SPACING);
    236     int gridOffsetZ = (int)(camera.position.z / SPACING);
    237 
    238     for (int x = -FIELD_SIZE / 2; x < FIELD_SIZE / 2; x++) {
    239       int seedX = gridOffsetX + x;
    240       float baseX = seedX * SPACING + (SPACING / 2);
    241 
    242       for (int z = -FIELD_SIZE / 2; z < FIELD_SIZE / 2; z++) {
    243         int seedZ = gridOffsetZ + z;
    244         float baseZ = seedZ * SPACING + (SPACING / 2);
    245 
    246         float tiltX = HASH(seedX, seedZ) * TILT_STRENGTH;
    247         float tiltZ = HASH(seedZ, seedX) * TILT_STRENGTH;
    248         float offsetX = HASH(seedX, seedZ) * OFFSET_STRENGTH;
    249         float offsetZ = HASH(seedZ, seedX) * OFFSET_STRENGTH;
    250 
    251         float chainAtCamY_X = baseX + (camera.position.y * tiltX) + offsetX;
    252         float chainAtCamY_Z = baseZ + (camera.position.y * tiltZ) + offsetZ;
    253 
    254         if (Vector2DistanceSqr((Vector2){chainAtCamY_X, chainAtCamY_Z},
    255                                camPos2D) > RENDER_CULL_SQ)
    256           continue;
    257 
    258         Vector3 chainDir = Vector3Normalize((Vector3){tiltX, 1.0f, tiltZ});
    259         Vector3 rotationAxis = Vector3CrossProduct(upVector, chainDir);
    260         float rotationAngle = acosf(Vector3DotProduct(upVector, chainDir));
    261         Matrix tiltRotation = MatrixRotate(rotationAxis, rotationAngle);
    262 
    263         Matrix instanceMatrix = MatrixMultiply(baseRotation, tiltRotation);
    264 
    265         for (int yIndex = -CHAIN_HEIGHT / 2; yIndex < CHAIN_HEIGHT / 2;
    266              yIndex++) {
    267           float yy = yIndex * VERTICAL_SPACING;
    268 
    269           if (fabsf(yy - camera.position.y) > RENDER_CULL_DISTANCE)
    270             continue;
    271 
    272           if (count < MAX_INSTANCES) {
    273             float finalX = baseX + (yy * tiltX) + offsetX;
    274             float finalZ = baseZ + (yy * tiltZ) + offsetZ;
    275 
    276             transforms[count] = instanceMatrix;
    277             transforms[count].m12 = finalX;
    278             transforms[count].m13 = yy;
    279             transforms[count].m14 = finalZ;
    280             count++;
    281           }
    282         }
    283       }
    284     }
    285 
    286     BeginTextureMode(target);
    287     ClearBackground(BLACK);
    288     BeginMode3D(camera);
    289     if (count > 0) {
    290       DrawMeshInstanced(cubeMesh, cubeMat, transforms, count);
    291     }
    292     EndMode3D();
    293     EndTextureMode();
    294 
    295     BeginDrawing();
    296     ClearBackground(BLACK);
    297     BeginShaderMode(liquifyShader);
    298     DrawTexturePro(
    299         target.texture,
    300         (Rectangle){0, 0, (float)target.texture.width,
    301                     (float)-target.texture.height},
    302         (Rectangle){0, 0, (float)GetScreenWidth(), (float)GetScreenHeight()},
    303         (Vector2){0, 0}, 0.0f, WHITE);
    304     EndShaderMode();
    305     EndDrawing();
    306   }
    307 
    308   UnloadRenderTexture(target);
    309   UnloadMesh(cubeMesh);
    310   UnloadMaterial(cubeMat);
    311   UnloadShader(ditherShader);
    312   UnloadShader(liquifyShader);
    313 
    314   CloseWindow();
    315   return 0;
    316 }