Generate noise heightmap
This commit is contained in:
parent
382b0e4bb0
commit
fc1806e1b2
1 changed files with 71 additions and 147 deletions
218
src/main.c
218
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
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
|
Reference in a new issue