2025-05-31 00:27:25 +02:00

122 lines
3.2 KiB
C

#include "voxel.h"
#define FNL_IMPL
#include <FastNoiseLite.h>
#include <stdio.h>
voxel_data *get_chunk_voxels(voxel_world *world, int x, int y, int z) {
return world->voxel_arena + ((x * CHUNK_STRIDE_X + y * CHUNK_STRIDE_Y + z) * CHUNK_SIZE);
}
void island_mask(Image *input) {
Image mask = GenImageGradientRadial(1024, 1024, 0.5, BLACK, WHITE);
Color *mask_colors = LoadImageColors(mask);
// UnloadImage(mask);
float gray = 0;
Color *input_color = LoadImageColors(*input);
for (int i = 0; i < 1024 * 1024; i++) {
gray = GRAY_VALUE(input_color[i]) - GRAY_VALUE(mask_colors[i]);
gray = Clamp(gray, 0, 254);
input_color[i] = (Color){.a = 255, .b = gray, .g = gray, .r = gray};
ImageDrawPixel(input, i % 1024, i / 1024, input_color[i]);
}
UnloadImageColors(mask_colors);
UnloadImageColors(input_color);
}
void rain_mask(Image *input, fnl_state *noise) {
float mask;
Color *input_color = LoadImageColors(*input);
for (int i = 0; i < 1024 * 1024; i++) {
mask = fnlGetNoise2D(noise, i / 1024, - (i % 1024)) + 1;
if (mask + GRAY_VALUE(input_color[i]) >= 2) {
input_color[i].b = 255;
}
ImageDrawPixel(input, i % 1024, i / 1024, input_color[i]);
};
UnloadImageColors(input_color);
}
Texture2D gen_texture_noise(fnl_state *noise) {
Image test = GenImageColor(1024, 1024, BLACK);
for (int x = 0; x < 1024; x++) {
for (int z = 0; z < 1024; z++) {
float noise_data = fnlGetNoise2D(noise, x, z) + 1;
char color_data = floorf(noise_data * 255 / 2);
Color tmp = {
.a = 255,
.r = color_data,
.g = color_data,
.b = color_data,
};
ImageDrawPixel(&test, x, z, tmp);
}
}
// ImageColorInvert(&test);
island_mask(&test);
rain_mask(&test, noise);
Texture2D text = LoadTextureFromImage(test);
UnloadImage(test);
return (text);
}
void chunk_gen_height(int x_off, int z_off, fnl_state *noise) {
float value[64][64] = {0};
float max = 0;
for (int x = 0; x < 64; x++) {
for (int z = 0; z < 64; z++) {
value[x][z] = (fnlGetNoise2D(noise, x_off + x, z_off + z) + 1) * 32 + 64;
if (value[x][z] > max) max = value[x][z];
}
}
}
voxel_world *gen_world(uint32_t seed) {
printf("The Mad God has Begun Creation\n");
voxel_world *world = malloc(sizeof(voxel_world));
assert(world);
// Allocate a single arena for all voxel data
world->voxel_arena = malloc(sizeof(voxel_data) * CHUNK_SIZE * 32 * 8 * 32);
assert(world->voxel_arena);
fnl_state noise = fnlCreateState();
noise.seed = seed;
noise.noise_type = FNL_NOISE_OPENSIMPLEX2;
noise.frequency = 0.02f;
noise.octaves = 5;
// Initialize all chunks
for (int x = 0; x < 32; x++) {
for (int y = 0; y < 8; y++) {
for (int z = 0; z < 32; z++) {
world->chunk[x][y][z] = malloc(sizeof(voxel_chunk));
assert(world->chunk[x][y][z]);
// Initialize chunk position
world->chunk[x][y][z]->positon = (Vector3){
x * CHUNK_RESOLUTION,
y * CHUNK_RESOLUTION,
z * CHUNK_RESOLUTION
};
// Generate terrain for this chunk
chunk_gen_height(x * CHUNK_RESOLUTION, z * CHUNK_RESOLUTION, &noise);
// Get this chunk's voxel data
voxel_data *chunk_voxels = get_chunk_voxels(world, x, y, z);
}
}
}
printf("World Generation Complete\n");
return (world);
}