diff --git a/include/OpenSimplex2F.h b/include/OpenSimplex2F.h deleted file mode 100644 index 11fc10f..0000000 --- a/include/OpenSimplex2F.h +++ /dev/null @@ -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); \ No newline at end of file diff --git a/src/OpenSimplex2F.c b/src/OpenSimplex2F.c deleted file mode 100644 index 6a2bfd6..0000000 --- a/src/OpenSimplex2F.c +++ /dev/null @@ -1,203 +0,0 @@ -#include -#include -#include -#include -#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; -} \ No newline at end of file diff --git a/src/main.c b/src/main.c index defbf22..3e65a9c 100644 --- a/src/main.c +++ b/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(); //----------------------------------------------------------------------------------