Home > OS >  Raylib fails to render perlin noise
Raylib fails to render perlin noise

Time:01-03

so i was trying to implement perlin noise in c and render it with raylib. i successfully implemented it but can't render it. it just shows black screen even tho perlinNoise function returns some value. can anyone help?

#include <math.h>
#include <iostream>
#include <vector>

#include "raylib.h"

using namespace std;

int p[] = {151, 160, 137, 91,  90,  15,  131, 13,  201, 95,  96,  53,  194, 233,
           7,   225, 140, 36,  103, 30,  69,  142, 8,   99,  37,  240, 21,  10,
           23,  190, 6,   148, 247, 120, 234, 75,  0,   26,  197, 62,  94,  252,
           219, 203, 117, 35,  11,  32,  57,  177, 33,  88,  237, 149, 56,  87,
           174, 20,  125, 136, 171, 168, 68,  175, 74,  165, 71,  134, 139, 48,
           27,  166, 77,  146, 158, 231, 83,  111, 229, 122, 60,  211, 133, 230,
           220, 105, 92,  41,  55,  46,  245, 40,  244, 102, 143, 54,  65,  25,
           63,  161, 1,   216, 80,  73,  209, 76,  132, 187, 208, 89,  18,  169,
           200, 196, 135, 130, 116, 188, 159, 86,  164, 100, 109, 198, 173, 186,
           3,   64,  52,  217, 226, 250, 124, 123, 5,   202, 38,  147, 118, 126,
           255, 82,  85,  212, 207, 206, 59,  227, 47,  16,  58,  17,  182, 189,
           28,  42,  223, 183, 170, 213, 119, 248, 152, 2,   44,  154, 163, 70,
           221, 153, 101, 155, 167, 43,  172, 9,   129, 22,  39,  253, 19,  98,
           108, 110, 79,  113, 224, 232, 178, 185, 112, 104, 218, 246, 97,  228,
           251, 34,  242, 193, 238, 210, 144, 12,  191, 179, 162, 241, 81,  51,
           145, 235, 249, 14,  239, 107, 49,  192, 214, 31,  181, 199, 106, 157,
           184, 84,  204, 176, 115, 121, 50,  45,  127, 4,   150, 254, 138, 236,
           205, 93,  222, 114, 67,  29,  24,  72,  243, 141, 128, 195, 78,  66,
           215, 61,  156, 180};

float fade(float t) { return t * t * t * (6 * t * t - 15 * t   10); }

float lerp(float a0, float a1, float t) { return a0   t * (a1 - a0); }

float dotp(Vector2 a, Vector2 b) { return a.x * b.x   a.y * b.y; }

Vector2 grad(int a) {
  int l = a % 4;
  Vector2 v;

  if (l == 0) {
    v = {1.0, 1.0};
  } else if (l == 1) {
    v = {-1.0, 1.0};
  } else if (l == 2) {
    v = {-1.0, -1.0};
  } else {
    v = {1.0, -1.0};
  }

  return v;
}

float perlinNoise(float x, float y) {
  // 1 - Topleft, 2 - topright, 3 - bottom left, 4 - bottom right
  int xInd = (int)floor(x) & 255;
  int yInd = (int)floor(y) & 255;

  x -= (int)floor(x);
  y -= (int)floor(y);

  // Direction Vectors
  Vector2 D_1 = {x, y};
  Vector2 D_2 = {x - 1.0, y};
  Vector2 D_3 = {x, y - 1.0};
  Vector2 D_4 = {x - 1.0, y - 1.0};

  // Gradient Vectors
  Vector2 G_1 = grad(p[p[xInd   1]   yInd   1]);
  Vector2 G_2 = grad(p[p[xInd]   yInd   1]);
  Vector2 G_3 = grad(p[p[xInd   1]   yInd]);
  Vector2 G_4 = grad(p[p[xInd]   yInd]);

  // Dot Products
  float dot1 = dotp(D_1, G_1);
  float dot2 = dotp(D_2, G_2);
  float dot3 = dotp(D_3, G_3);
  float dot4 = dotp(D_4, G_4);

  // Fade Values
  float u = fade(x);
  float v = fade(y);

  return lerp(lerp(dot1, dot2, u), lerp(dot3, dot4, u), v);
}

int main(void) {
  const int screenWidth = 512;
  const int screenHeight = 512;

  cout << perlinNoise(1.5, 1.5) << '\n';

  InitWindow(screenWidth, screenHeight, "perlins go brrrrrrrrrrrrr");

  SetTargetFPS(60);

  while (!WindowShouldClose()) {
    BeginDrawing();

    ClearBackground(BLACK);

    for (int y = 0; y < 512; y  ) {
      for (int x = 0; x < 512; x  ) {
        float n = perlinNoise(x * 0.01, y * 0.01);
        n  = 1;
        n /= 2;
        int c = round(n * 255);
        Color col{c, c, c, (char)256};
        DrawPixel(x, y, col);
      }
    }

    EndDrawing();
  }

  CloseWindow();

  return 0;
}

I try to render it by assigning each pixel with some color. I think problem might be variable "col". Maybe i don't assign value correctly.

CodePudding user response:

When you create color, alpha channel is 0 because 256 overflows during conversion to 8-bit integer. 255 is correct maximal level of each channel, so if you want non-transparent color, use 255 for alpha channel:

Color col{c, c, c, (char)255};

Also note that channel type is actually unsigned char, so you ideally should cast to unsigned char here if you want to do that explicitly:

Color col{c, c, c, (unsigned char)255};

But you don't have to, because implicit conversion in 4th initializer of this aggregate initialization is not considered narrowing since it converts constant expression whose numerical value is representable in unsigned char. So you can just write:

Color col{c, c, c, 255};
  • Related