Naiu
This commit is contained in:
parent
7edd606fee
commit
18f2b62f37
3 changed files with 50 additions and 255 deletions
|
@ -1,27 +0,0 @@
|
|||
typedef struct
|
||||
{
|
||||
int xsv, ysv;
|
||||
double dx, dy;
|
||||
} LatticePoint2D;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double dx, dy;
|
||||
} Grad2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short *perm;
|
||||
Grad2 *permGrad2;
|
||||
} OpenSimplexGradients;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Grad2 *GRADIENTS_2D;
|
||||
LatticePoint2D **LOOKUP_2D;
|
||||
} OpenSimplexEnv;
|
||||
|
||||
OpenSimplexEnv *initOpenSimplex();
|
||||
OpenSimplexGradients *newOpenSimplexGradients(OpenSimplexEnv *ose, long seed);
|
||||
double noise2(OpenSimplexEnv *ose, OpenSimplexGradients *osg, double x, double y);
|
||||
double noise2_XBeforeY(OpenSimplexEnv *ose, OpenSimplexGradients *osg, double x, double y);
|
|
@ -1,203 +0,0 @@
|
|||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "OpenSimplex2F.h"
|
||||
|
||||
#define PSIZE 2048
|
||||
#define PMASK 2047
|
||||
#define N2 0.01001634121365712
|
||||
|
||||
/*
|
||||
* Utility
|
||||
*/
|
||||
|
||||
int inline _fastFloor(double x)
|
||||
{
|
||||
int xi = (int)x;
|
||||
return x < xi ? xi - 1 : xi;
|
||||
}
|
||||
|
||||
Grad2 inline *_newGrad2Arr(unsigned int size)
|
||||
{
|
||||
return (Grad2 *)malloc(sizeof(Grad2) * size);
|
||||
}
|
||||
|
||||
short inline *_newShortArr(unsigned int size)
|
||||
{
|
||||
return (short *)malloc(sizeof(short) * size);
|
||||
}
|
||||
|
||||
Grad2 _newGrad2(double dx, double dy)
|
||||
{
|
||||
Grad2 grad2;
|
||||
grad2.dx = dx;
|
||||
grad2.dy = dy;
|
||||
return grad2;
|
||||
}
|
||||
|
||||
Grad2 *_newGrad2ConstArray()
|
||||
{
|
||||
Grad2 *arr = (Grad2 *)malloc(sizeof(Grad2) * 24);
|
||||
int i = 0;
|
||||
arr[i++] = _newGrad2(0.130526192220052, 0.99144486137381);
|
||||
arr[i++] = _newGrad2(0.38268343236509, 0.923879532511287);
|
||||
arr[i++] = _newGrad2(0.608761429008721, 0.793353340291235);
|
||||
arr[i++] = _newGrad2(0.793353340291235, 0.608761429008721);
|
||||
arr[i++] = _newGrad2(0.923879532511287, 0.38268343236509);
|
||||
arr[i++] = _newGrad2(0.99144486137381, 0.130526192220051);
|
||||
arr[i++] = _newGrad2(0.99144486137381, -0.130526192220051);
|
||||
arr[i++] = _newGrad2(0.923879532511287, -0.38268343236509);
|
||||
arr[i++] = _newGrad2(0.793353340291235, -0.60876142900872);
|
||||
arr[i++] = _newGrad2(0.608761429008721, -0.793353340291235);
|
||||
arr[i++] = _newGrad2(0.38268343236509, -0.923879532511287);
|
||||
arr[i++] = _newGrad2(0.130526192220052, -0.99144486137381);
|
||||
arr[i++] = _newGrad2(-0.130526192220052, -0.99144486137381);
|
||||
arr[i++] = _newGrad2(-0.38268343236509, -0.923879532511287);
|
||||
arr[i++] = _newGrad2(-0.608761429008721, -0.793353340291235);
|
||||
arr[i++] = _newGrad2(-0.793353340291235, -0.608761429008721);
|
||||
arr[i++] = _newGrad2(-0.923879532511287, -0.38268343236509);
|
||||
arr[i++] = _newGrad2(-0.99144486137381, -0.130526192220052);
|
||||
arr[i++] = _newGrad2(-0.99144486137381, 0.130526192220051);
|
||||
arr[i++] = _newGrad2(-0.923879532511287, 0.38268343236509);
|
||||
arr[i++] = _newGrad2(-0.793353340291235, 0.608761429008721);
|
||||
arr[i++] = _newGrad2(-0.608761429008721, 0.793353340291235);
|
||||
arr[i++] = _newGrad2(-0.38268343236509, 0.923879532511287);
|
||||
arr[i++] = _newGrad2(-0.130526192220052, 0.99144486137381);
|
||||
Grad2 *gradients2D = _newGrad2Arr(PSIZE);
|
||||
for (int i = 0; i < 24; i++)
|
||||
{
|
||||
arr[i].dx /= N2;
|
||||
arr[i].dy /= N2;
|
||||
}
|
||||
for (int i = 0; i < PSIZE; i++)
|
||||
{
|
||||
gradients2D[i] = arr[i % 24];
|
||||
}
|
||||
return gradients2D;
|
||||
}
|
||||
|
||||
LatticePoint2D *_newLatticePoint2D(int xsv, int ysv)
|
||||
{
|
||||
LatticePoint2D *plp2D = (LatticePoint2D *)malloc(sizeof(LatticePoint2D));
|
||||
plp2D->xsv = xsv;
|
||||
plp2D->ysv = ysv;
|
||||
double ssv = (xsv + ysv) * -0.211324865405187;
|
||||
plp2D->dx = -xsv - ssv;
|
||||
plp2D->dy = -ysv - ssv;
|
||||
return plp2D;
|
||||
}
|
||||
|
||||
LatticePoint2D **_newLatticePoint2DConstArray()
|
||||
{
|
||||
LatticePoint2D **plp2DArr = (LatticePoint2D **)malloc(sizeof(LatticePoint2D *) * 4);
|
||||
plp2DArr[0] = _newLatticePoint2D(1, 0);
|
||||
plp2DArr[1] = _newLatticePoint2D(0, 0);
|
||||
plp2DArr[2] = _newLatticePoint2D(1, 1);
|
||||
plp2DArr[3] = _newLatticePoint2D(0, 1);
|
||||
return plp2DArr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Noise Evaluators
|
||||
*/
|
||||
|
||||
/**
|
||||
* 2D Simplex noise base.
|
||||
* Lookup table implementation inspired by DigitalShadow.
|
||||
*/
|
||||
double _noise2_Base(OpenSimplexEnv *ose, OpenSimplexGradients *osg, double xs, double ys)
|
||||
{
|
||||
double value = 0;
|
||||
|
||||
// Get base points and offsets
|
||||
int xsb = _fastFloor(xs), ysb = _fastFloor(ys);
|
||||
double xsi = xs - xsb, ysi = ys - ysb;
|
||||
|
||||
// Index to point list
|
||||
int index = (int)((ysi - xsi) / 2 + 1);
|
||||
|
||||
double ssi = (xsi + ysi) * -0.211324865405187;
|
||||
double xi = xsi + ssi, yi = ysi + ssi;
|
||||
|
||||
// Point contributions
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
LatticePoint2D *c = ose->LOOKUP_2D[index + i];
|
||||
|
||||
double dx = xi + c->dx, dy = yi + c->dy;
|
||||
double attn = 0.5 - dx * dx - dy * dy;
|
||||
if (attn <= 0)
|
||||
continue;
|
||||
|
||||
int pxm = (xsb + c->xsv) & PMASK, pym = (ysb + c->ysv) & PMASK;
|
||||
Grad2 grad = osg->permGrad2[osg->perm[pxm] ^ pym];
|
||||
double extrapolation = grad.dx * dx + grad.dy * dy;
|
||||
|
||||
attn *= attn;
|
||||
value += attn * attn * extrapolation;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 2D Simplex noise, standard lattice orientation.
|
||||
*/
|
||||
double noise2(OpenSimplexEnv *ose, OpenSimplexGradients *osg, double x, double y)
|
||||
{
|
||||
|
||||
// Get points for A2* lattice
|
||||
double s = 0.366025403784439 * (x + y);
|
||||
double xs = x + s, ys = y + s;
|
||||
|
||||
return _noise2_Base(ose, osg, xs, ys);
|
||||
}
|
||||
|
||||
/**
|
||||
* 2D Simplex noise, with Y pointing down the main diagonal.
|
||||
* Might be better for a 2D sandbox style game, where Y is vertical.
|
||||
* Probably slightly less optimal for heightmaps or continent maps.
|
||||
*/
|
||||
double noise2_XBeforeY(OpenSimplexEnv *ose, OpenSimplexGradients *osg, double x, double y)
|
||||
{
|
||||
|
||||
// Skew transform and rotation baked into one.
|
||||
double xx = x * 0.7071067811865476;
|
||||
double yy = y * 1.224744871380249;
|
||||
|
||||
return _noise2_Base(ose, osg, yy + xx, yy - xx);
|
||||
}
|
||||
|
||||
OpenSimplexEnv *initOpenSimplex()
|
||||
{
|
||||
OpenSimplexEnv *ose = (OpenSimplexEnv *)malloc(sizeof(OpenSimplexEnv));
|
||||
ose->GRADIENTS_2D = _newGrad2ConstArray();
|
||||
ose->LOOKUP_2D = _newLatticePoint2DConstArray();
|
||||
return ose;
|
||||
}
|
||||
|
||||
OpenSimplexGradients *newOpenSimplexGradients(OpenSimplexEnv *ose, long seed)
|
||||
{
|
||||
OpenSimplexGradients *osg = (OpenSimplexGradients *)malloc(sizeof(OpenSimplexGradients));
|
||||
osg->perm = _newShortArr(PSIZE);
|
||||
osg->permGrad2 = _newGrad2Arr(PSIZE);
|
||||
short *source = _newShortArr(PSIZE);
|
||||
for (short i = 0; i < PSIZE; i++)
|
||||
{
|
||||
source[i] = i;
|
||||
}
|
||||
for (int i = PSIZE - 1; i >= 0; i--)
|
||||
{
|
||||
seed = seed * 6364136223846793005L + 1442695040888963407L;
|
||||
int r = (int)((seed + 31) % (i + 1));
|
||||
if (r < 0)
|
||||
{
|
||||
r += (i + 1);
|
||||
}
|
||||
osg->perm[i] = source[r];
|
||||
osg->permGrad2[i] = ose->GRADIENTS_2D[osg->perm[i]];
|
||||
source[r] = source[i];
|
||||
}
|
||||
return osg;
|
||||
}
|
75
src/main.c
75
src/main.c
|
@ -6,28 +6,30 @@
|
|||
#define INITIAL_SCREEN_WIDTH 900
|
||||
#define INITIAL_SCREEN_HEIGHT 900
|
||||
|
||||
#define SCALE 64
|
||||
#define SCREEN_SCALE 8
|
||||
// #define NOISE_PERIOD 4
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int noisePeriod = 4;
|
||||
|
||||
SetTraceLogLevel(LOG_ALL);
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE | FLAG_VSYNC_HINT);
|
||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
||||
InitWindow(INITIAL_SCREEN_WIDTH, INITIAL_SCREEN_HEIGHT, "raylib [core] example - basic window");
|
||||
|
||||
SetTargetFPS(5); // Set our game to run at 60 frames-per-second
|
||||
// SetTargetFPS(5);
|
||||
|
||||
fnl_state state = fnlCreateState();
|
||||
state.seed = 0;
|
||||
state.frequency = 1.0f / (float)SCALE;
|
||||
state.frequency = 1.0f / (float)noisePeriod;
|
||||
state.fractal_type = FNL_FRACTAL_FBM;
|
||||
state.octaves = 1;
|
||||
state.noise_type = FNL_NOISE_PERLIN;
|
||||
state.noise_type = 0;
|
||||
|
||||
int virtualScreenWidth = GetScreenWidth() / SCALE;
|
||||
int virtualScreenHeight = GetScreenHeight() / SCALE;
|
||||
float virtualRatio = (float)virtualScreenWidth / (float)virtualScreenHeight;
|
||||
int virtualScreenWidth = GetScreenWidth() / SCREEN_SCALE;
|
||||
int virtualScreenHeight = GetScreenHeight() / SCREEN_SCALE;
|
||||
|
||||
RenderTexture2D *target = (RenderTexture2D *)MemAlloc(sizeof(RenderTexture2D));
|
||||
|
||||
|
@ -40,10 +42,10 @@ int main(void)
|
|||
0.0f,
|
||||
(float)target->texture.width,
|
||||
-(float)target->texture.height};
|
||||
Rectangle destRec = {-virtualRatio,
|
||||
-virtualRatio,
|
||||
GetScreenWidth() + (virtualRatio * 2.0f),
|
||||
GetScreenHeight() + (virtualRatio * 2.0f)};
|
||||
Rectangle destRec = {0.0f,
|
||||
0.0f,
|
||||
GetScreenWidth(),
|
||||
GetScreenHeight()};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
@ -64,9 +66,8 @@ int main(void)
|
|||
if (IsWindowResized())
|
||||
{
|
||||
TraceLog(LOG_DEBUG, "Resized.");
|
||||
int virtualScreenWidth = GetScreenWidth() / SCALE;
|
||||
int virtualScreenHeight = GetScreenHeight() / SCALE;
|
||||
float virtualRatio = (float)virtualScreenWidth / (float)virtualScreenHeight;
|
||||
virtualScreenWidth = GetScreenWidth() / SCREEN_SCALE;
|
||||
virtualScreenHeight = GetScreenHeight() / SCREEN_SCALE;
|
||||
|
||||
UnloadRenderTexture(*target);
|
||||
*target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight);
|
||||
|
@ -74,7 +75,7 @@ int main(void)
|
|||
sourceRec = (Rectangle){0.0f,
|
||||
0.0f,
|
||||
(float)target->texture.width,
|
||||
(float)target->texture.height};
|
||||
-(float)target->texture.height};
|
||||
|
||||
destRec = (Rectangle){0.0f,
|
||||
0.0f,
|
||||
|
@ -92,12 +93,37 @@ int main(void)
|
|||
}
|
||||
if (IsKeyPressed(KEY_UP) || IsKeyPressed(KEY_DOWN))
|
||||
{
|
||||
state.octaves = state.octaves <= 0 ? 1 : state.octaves;
|
||||
|
||||
TraceLog(LOG_INFO, TextFormat("Octaves: %i", state.octaves));
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_LEFT))
|
||||
{
|
||||
noisePeriod--;
|
||||
}
|
||||
if (IsKeyPressed(KEY_RIGHT))
|
||||
{
|
||||
noisePeriod++;
|
||||
}
|
||||
if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT))
|
||||
{
|
||||
noisePeriod = noisePeriod <= 0 ? 1 : noisePeriod;
|
||||
state.frequency = 1.0f / (float)noisePeriod;
|
||||
|
||||
TraceLog(LOG_INFO, TextFormat("Noise period: %i", noisePeriod));
|
||||
}
|
||||
|
||||
if (IsKeyPressed(KEY_R))
|
||||
{
|
||||
noisePeriod = 4;
|
||||
state.frequency = 1.0f / (float)noisePeriod;
|
||||
|
||||
state.octaves = 1;
|
||||
}
|
||||
|
||||
float frameTime = GetFrameTime();
|
||||
offset += (double)frameTime * 10.0;
|
||||
TraceLog(LOG_INFO, TextFormat("fps: %f (%fms ; total %fs)", 1.0 / frameTime, frameTime * 1000.0, offset / 10.0));
|
||||
offset += (double)frameTime * 10.0 * 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
|
@ -112,9 +138,9 @@ int main(void)
|
|||
{
|
||||
for (int y = 0; y < virtualScreenHeight; y++)
|
||||
{
|
||||
int noise = (fnlGetNoise2D(&state, ((double)x) + offset, ((double)y) + offset / 2.0) + 1.0) / 2.0 * 255.0; //(noise2(simplexEnv, simplexGradiants, x / 64.0 + offset, y / 64.0 + offset / 2.0) + 1.0) / 2 * 255;
|
||||
int noise = (fnlGetNoise2D(&state, ((double)x) + (int)offset, ((double)y) + (int)offset / 2.0) + 1.0) / 2.0 * 255.0;
|
||||
|
||||
DrawPixel(x, y, (Color){0, noise, noise, 255});
|
||||
DrawPixel(x, y, (Color){255 - noise, noise, noise, 255});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,11 +149,10 @@ int main(void)
|
|||
BeginDrawing();
|
||||
{
|
||||
ClearBackground(RAYWHITE);
|
||||
// BeginMode2D();
|
||||
{
|
||||
DrawTexturePro(target->texture, sourceRec, destRec, (Vector2){0.0f, 0.0f}, 0.0f, WHITE);
|
||||
}
|
||||
// EndMode2D();
|
||||
DrawTexturePro(target->texture, sourceRec, destRec, (Vector2){0.0f, 0.0f}, 0.0f, WHITE);
|
||||
char const *drawText = TextFormat("Press [SPACEBAR] to cycle through different noise algorithms, arrow keys to control variables\n%i FPS\nNoise Period (Frequency): %i (%f)\nNoise Octaves: %i", GetFPS(), noisePeriod, state.frequency, state.octaves);
|
||||
DrawRectangle(0, 0, MeasureText(drawText, 20), (int)(20 * 5.5), WHITE);
|
||||
DrawText(drawText, 0, 0, 20, BLACK);
|
||||
}
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
Reference in a new issue