Generate noise heightmap
This commit is contained in:
parent
382b0e4bb0
commit
fc1806e1b2
1 changed files with 71 additions and 147 deletions
226
src/main.c
226
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"
|
#include "raylib.h"
|
||||||
|
|
||||||
#define FNL_IMPL
|
#define FNL_IMPL
|
||||||
#include "FastNoiseLite.h"
|
#include "FastNoiseLite.h"
|
||||||
|
|
||||||
#define INITIAL_SCREEN_WIDTH 900
|
#define HEIGHT_MAP_SIZE 128
|
||||||
#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
|
|
||||||
*/
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
// Initialization
|
// Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
int noisePeriod = 4;
|
const int screenWidth = 800;
|
||||||
|
const int screenHeight = 450;
|
||||||
#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");
|
|
||||||
|
|
||||||
fnl_state fnlState = fnlCreateState();
|
fnl_state fnlState = fnlCreateState();
|
||||||
fnlState.seed = 0;
|
fnlState.seed = 0;
|
||||||
fnlState.frequency = 1.0f / (float)noisePeriod;
|
fnlState.noise_type = FNL_NOISE_CELLULAR;
|
||||||
fnlState.fractal_type = FNL_FRACTAL_FBM;
|
fnlState.fractal_type = FNL_FRACTAL_PINGPONG;
|
||||||
fnlState.octaves = 1;
|
fnlState.octaves = 3;
|
||||||
fnlState.noise_type = 0;
|
fnlState.frequency = 1.0f / 50.0f;
|
||||||
|
|
||||||
int virtualScreenWidth = GetScreenWidth() / SCREEN_SCALE;
|
InitWindow(screenWidth, screenHeight, "raylib [models] example - heightmap loading and drawing");
|
||||||
int virtualScreenHeight = GetScreenHeight() / SCREEN_SCALE;
|
|
||||||
|
|
||||||
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,
|
Image image = {
|
||||||
0.0f,
|
.data = pixels,
|
||||||
(float)target->texture.width,
|
.width = HEIGHT_MAP_SIZE,
|
||||||
-(float)target->texture.height};
|
.height = HEIGHT_MAP_SIZE,
|
||||||
Rectangle destRec = {0.0f,
|
.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8,
|
||||||
0.0f,
|
.mipmaps = 1,
|
||||||
GetScreenWidth(),
|
}; // Load heightmap image (RAM)
|
||||||
GetScreenHeight()};
|
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
|
// Main game loop
|
||||||
|
@ -64,129 +80,37 @@ int main(void)
|
||||||
{
|
{
|
||||||
// Update
|
// Update
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
if (IsKeyPressed(KEY_SPACE))
|
UpdateCamera(&camera); // Update camera
|
||||||
{
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Draw
|
// Draw
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
|
|
||||||
BeginTextureMode(*target);
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
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});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EndTextureMode();
|
|
||||||
|
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
{
|
|
||||||
ClearBackground(RAYWHITE);
|
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);
|
BeginMode3D(camera);
|
||||||
DrawRectangle(0, 0, MeasureText(drawText, 20), (int)(20 * 5.5), WHITE);
|
|
||||||
DrawText(drawText, 0, 0, 20, BLACK);
|
DrawModel(model, mapPosition, 1.0f, RED);
|
||||||
}
|
|
||||||
|
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);
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
|
|
||||||
// De-Initialization
|
// De-Initialization
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
MemFree(target);
|
UnloadTexture(texture); // Unload texture
|
||||||
|
UnloadModel(model); // Unload model
|
||||||
|
|
||||||
CloseWindow(); // Close window and OpenGL context
|
CloseWindow(); // Close window and OpenGL context
|
||||||
//--------------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
Reference in a new issue