From fc1806e1b2bc2c7da6dcb3f35f2c8d57dbbeb5bd Mon Sep 17 00:00:00 2001 From: Tobias Berger Date: Thu, 18 Nov 2021 14:54:22 +0100 Subject: [PATCH] Generate noise heightmap --- src/main.c | 218 +++++++++++++++++------------------------------------ 1 file changed, 71 insertions(+), 147 deletions(-) diff --git a/src/main.c b/src/main.c index b747033..3c36e92 100644 --- a/src/main.c +++ b/src/main.c @@ -1,62 +1,78 @@ +/******************************************************************************************* +* +* raylib [models] example - Heightmap loading and drawing +* +* This example has been created using raylib 1.8 (www.raylib.com) +* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) +* +* Copyright (c) 2015 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + #include "raylib.h" #define FNL_IMPL #include "FastNoiseLite.h" -#define INITIAL_SCREEN_WIDTH 900 -#define INITIAL_SCREEN_HEIGHT 900 - -#define SCREEN_SCALE 8 -#define CAMERA_SPEED (SCREEN_SCALE * 3.0f) - -/* Controls - UP/DOWN - Change octaves (Min 1) - LEFT/RIGHT - Change period (Min 1) - SPACE - Change noise type - R - Reset - WASD - Move camera -*/ +#define HEIGHT_MAP_SIZE 128 int main(void) { // Initialization //-------------------------------------------------------------------------------------- - int noisePeriod = 4; - -#if defined(__DEBUG) - SetTraceLogLevel(LOG_ALL); -#else - SetTraceLogLevel(LOG_NONE); -#endif - - SetConfigFlags(FLAG_WINDOW_RESIZABLE); - InitWindow(INITIAL_SCREEN_WIDTH, INITIAL_SCREEN_HEIGHT, "raylib [core] example - basic window"); + const int screenWidth = 800; + const int screenHeight = 450; fnl_state fnlState = fnlCreateState(); fnlState.seed = 0; - fnlState.frequency = 1.0f / (float)noisePeriod; - fnlState.fractal_type = FNL_FRACTAL_FBM; - fnlState.octaves = 1; - fnlState.noise_type = 0; + fnlState.noise_type = FNL_NOISE_CELLULAR; + fnlState.fractal_type = FNL_FRACTAL_PINGPONG; + fnlState.octaves = 3; + fnlState.frequency = 1.0f / 50.0f; - int virtualScreenWidth = GetScreenWidth() / SCREEN_SCALE; - int virtualScreenHeight = GetScreenHeight() / SCREEN_SCALE; + InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing"); - RenderTexture2D *target = (RenderTexture2D *)MemAlloc(sizeof(RenderTexture2D)); + // Define our custom camera to look into our 3d world + Camera camera = {{18.0f, 18.0f, 18.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f}, 45.0f, 0}; - *target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); + Color pixels[HEIGHT_MAP_SIZE * HEIGHT_MAP_SIZE] = {0}; - Vector2 offset = {0.0f, 0.0f}; + for (int x = 0; x < HEIGHT_MAP_SIZE; x++) + { + for (int y = 0; y < HEIGHT_MAP_SIZE; y++) + { + float raw_noise = fnlGetNoise2D(&fnlState, (float)x, (float)y); + float noise = ((raw_noise + 1.0f) / 2.0f) * 255.0f; + unsigned char intensity = (unsigned char)noise; + pixels[x + y * HEIGHT_MAP_SIZE] = (Color){ + intensity, + intensity, + intensity, + 255, + }; + } + } - Rectangle sourceRec = {0.0f, - 0.0f, - (float)target->texture.width, - -(float)target->texture.height}; - Rectangle destRec = {0.0f, - 0.0f, - GetScreenWidth(), - GetScreenHeight()}; + Image image = { + .data = pixels, + .width = HEIGHT_MAP_SIZE, + .height = HEIGHT_MAP_SIZE, + .format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8, + .mipmaps = 1, + }; // Load heightmap image (RAM) + Texture2D texture = LoadTextureFromImage(image); // Convert image to texture (VRAM) + Mesh mesh = GenMeshHeightmap(image, (Vector3){16, 8, 16}); // Generate heightmap mesh (RAM and VRAM) + Model model = LoadModelFromMesh(mesh); // Load model from generated mesh + + model.materials[0].maps[MATERIAL_MAP_DIFFUSE].texture = texture; // Set map diffuse texture + Vector3 mapPosition = {-8.0f, 0.0f, -8.0f}; // Define model position + + UnloadImage(image); // Unload heightmap image from RAM, already uploaded to VRAM + + SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode + + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop @@ -64,129 +80,37 @@ int main(void) { // Update //---------------------------------------------------------------------------------- - if (IsKeyPressed(KEY_SPACE)) - { - fnlState.noise_type++; - fnlState.noise_type %= (FNL_NOISE_VALUE + 1); - TraceLog(LOG_INFO, TextFormat("Noisetype: %i", fnlState.noise_type)); - } - - if (IsWindowResized()) - { - TraceLog(LOG_DEBUG, "Resized."); - virtualScreenWidth = GetScreenWidth() / SCREEN_SCALE; - virtualScreenHeight = GetScreenHeight() / SCREEN_SCALE; - - UnloadRenderTexture(*target); - *target = LoadRenderTexture(virtualScreenWidth, virtualScreenHeight); - - sourceRec = (Rectangle){0.0f, - 0.0f, - (float)target->texture.width, - -(float)target->texture.height}; - - destRec = (Rectangle){0.0f, - 0.0f, - GetScreenWidth(), - GetScreenHeight()}; - } - - if (IsKeyPressed(KEY_UP)) - { - fnlState.octaves++; - } - if (IsKeyPressed(KEY_DOWN)) - { - fnlState.octaves--; - } - if (IsKeyPressed(KEY_UP) || IsKeyPressed(KEY_DOWN)) - { - fnlState.octaves = fnlState.octaves <= 0 ? 1 : fnlState.octaves; - - TraceLog(LOG_INFO, TextFormat("Octaves: %i", fnlState.octaves)); - } - - if (IsKeyPressed(KEY_LEFT)) - { - noisePeriod--; - } - if (IsKeyPressed(KEY_RIGHT)) - { - noisePeriod++; - } - if (IsKeyPressed(KEY_LEFT) || IsKeyPressed(KEY_RIGHT)) - { - noisePeriod = noisePeriod <= 0 ? 1 : noisePeriod; - fnlState.frequency = 1.0f / (float)noisePeriod; - - TraceLog(LOG_INFO, TextFormat("Noise period: %i", noisePeriod)); - } - - if (IsKeyPressed(KEY_R)) - { - noisePeriod = 4; - fnlState.frequency = 1.0f / (float)noisePeriod; - - fnlState.octaves = 1; - } - - if (IsKeyDown(KEY_W)) - { - offset.y -= GetFrameTime() * CAMERA_SPEED; - } - if (IsKeyDown(KEY_S)) - { - offset.y += GetFrameTime() * CAMERA_SPEED; - } - if (IsKeyDown(KEY_A)) - { - offset.x -= GetFrameTime() * CAMERA_SPEED; - } - if (IsKeyDown(KEY_D)) - { - offset.x += GetFrameTime() * CAMERA_SPEED; - } - + UpdateCamera(&camera); // Update camera //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- - - BeginTextureMode(*target); + BeginDrawing(); ClearBackground(RAYWHITE); - for (int x = 0; x < virtualScreenWidth; x++) - { - for (int y = 0; y < virtualScreenHeight; y++) - { - float raw_noise = fnlGetNoise2D(&fnlState, (float)x + floorf(offset.x), (float)y + floorf(offset.y)); - float noise = (raw_noise + 1.0f) / 2.0f * 255.0f; + BeginMode3D(camera); - const unsigned char r = noise >= 170 ? 255 : (unsigned char)(noise * 1.5f); - const unsigned char g = 255; - const unsigned char b = 255; - DrawPixel(x, y, (Color){r, g, b, 255}); - } - } + DrawModel(model, mapPosition, 1.0f, RED); - EndTextureMode(); + DrawGrid(20, 1.0f); + + EndMode3D(); + + DrawTexture(texture, screenWidth - texture.width - 20, 20, WHITE); + DrawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, GREEN); + + DrawFPS(10, 10); - BeginDrawing(); - { - ClearBackground(RAYWHITE); - 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, fnlState.frequency, fnlState.octaves); - DrawRectangle(0, 0, MeasureText(drawText, 20), (int)(20 * 5.5), WHITE); - DrawText(drawText, 0, 0, 20, BLACK); - } EndDrawing(); //---------------------------------------------------------------------------------- } // De-Initialization //-------------------------------------------------------------------------------------- - MemFree(target); + UnloadTexture(texture); // Unload texture + UnloadModel(model); // Unload model + CloseWindow(); // Close window and OpenGL context //--------------------------------------------------------------------------------------