void gen_plant_buffers( GLuint *position_buffer, GLuint *normal_buffer, GLuint *uv_buffer, float x, float y, float z, float n, int w) { GLfloat *position_data, *normal_data, *uv_data; malloc_buffers(3, 4, &position_data, &normal_data, &uv_data); float rotation = simplex3(x, y, z, 4, 0.5, 2) * 360; make_plant( position_data, normal_data, uv_data, x, y, z, n, w, rotation); gen_buffers( 3, 4, position_data, normal_data, uv_data, position_buffer, normal_buffer, uv_buffer); }
void biome1(int x, int z, int flag, world_func func, void *arg) { int lo = simplex2(x * 0.01, z * 0.01, 4, 0.5, 2) * 8 + 8; int hi = simplex2(-x * 0.01, -z * 0.01, 4, 0.5, 2) * 32 + 32; int lookup[] = {3, 6, 11, 12, 13}; for (int y = 0; y < lo; y++) { func(x, y, z, 6 * flag, arg); } for (int y = lo; y < hi; y++) { int i = simplex3(-x * 0.01, -y * 0.01, -z * 0.01, 4, 0.5, 2) * 10; int w = lookup[i % 5]; if (simplex3(x * 0.01, y * 0.01, z * 0.01, 4, 0.5, 2) > 0.5) { func(x, y, z, w * flag, arg); } } if (SHOW_CLOUDS) { for (int y = 64; y < 72; y++) { if (simplex3( x * 0.01, y * 0.1, z * 0.01, 8, 0.5, 2) > 0.75) { func(x, y, z, 16 * flag, arg); } } } }
void make_world(Map *map, int p, int q) { int pad = 1; for (int dx = -pad; dx < CHUNK_SIZE + pad; dx++) { for (int dz = -pad; dz < CHUNK_SIZE + pad; dz++) { int x = p * CHUNK_SIZE + dx; int z = q * CHUNK_SIZE + dz; float f = simplex2(x * 0.01, z * 0.01, 4, 0.5, 2); float g = simplex2(-x * 0.01, -z * 0.01, 2, 0.9, 2); int mh = g * 32 + 16; int h = f * mh; int w = 1; int t = 12; if (h <= t) { h = t; w = 2; } if (dx < 0 || dz < 0 || dx >= CHUNK_SIZE || dz >= CHUNK_SIZE) { w = -1; } for (int y = 0; y < h; y++) { map_set(map, x, y, z, w); } if (w == 1) { if (simplex2(-x * 0.1, z * 0.1, 4, 0.8, 2) > 0.6) { map_set(map, x, h, z, 17); } if (simplex2(x * 0.05, -z * 0.05, 4, 0.8, 2) > 0.7) { int w = 18 + simplex2(x * 0.1, z * 0.1, 4, 0.8, 2) * 7; map_set(map, x, h, z, w); } } for (int y = 64; y < 72; y++) { if (simplex3(x * 0.01, y * 0.1, z * 0.01, 8, 0.5, 2) > 0.75) { map_set(map, x, y, z, 16); } } } } }
void update_chunk(Chunk *chunk) { Map *map = &chunk->map; if (chunk->faces) { glDeleteBuffers(1, &chunk->position_buffer); glDeleteBuffers(1, &chunk->normal_buffer); glDeleteBuffers(1, &chunk->uv_buffer); } int faces = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } faces += total; } END_MAP_FOR_EACH; GLfloat *position_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *normal_data = malloc(sizeof(GLfloat) * faces * 18); GLfloat *uv_data = malloc(sizeof(GLfloat) * faces * 12); int position_offset = 0; int uv_offset = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } if (total == 0) { continue; } if (is_plant(e->w)) { float rotation = simplex3(e->x, e->y, e->z, 4, 0.5, 2) * 360; make_plant( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, e->x, e->y, e->z, 0.5, e->w, rotation); } else { make_cube( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, f1, f2, f3, f4, f5, f6, e->x, e->y, e->z, 0.5, e->w); } position_offset += total * 18; uv_offset += total * 12; } END_MAP_FOR_EACH; GLuint position_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, position_data ); GLuint normal_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 18, normal_data ); GLuint uv_buffer = make_buffer( GL_ARRAY_BUFFER, sizeof(GLfloat) * faces * 12, uv_data ); free(position_data); free(normal_data); free(uv_data); chunk->faces = faces; chunk->position_buffer = position_buffer; chunk->normal_buffer = normal_buffer; chunk->uv_buffer = uv_buffer; }
void make_world(Map *map, int p, int q) { int pad = 1; for (int dx = -pad; dx < CHUNK_SIZE + pad; dx++) { for (int dz = -pad; dz < CHUNK_SIZE + pad; dz++) { int x = p * CHUNK_SIZE + dx; int z = q * CHUNK_SIZE + dz; float f = simplex2(x * 0.01, z * 0.01, 4, 0.5, 2); float g = simplex2(-x * 0.01, -z * 0.01, 2, 0.9, 2); int mh = g * 32 + 16; int h = f * mh; int w = 1; int t = 12; if (h <= t) { h = t; w = 2; } if (dx < 0 || dz < 0 || dx >= CHUNK_SIZE || dz >= CHUNK_SIZE) { w = -1; } // sand and grass terrain for (int y = 0; y < h; y++) { map_set(map, x, y, z, w); } // TODO: w = -1 if outside of chunk if (w == 1) { // grass if (simplex2(-x * 0.1, z * 0.1, 4, 0.8, 2) > 0.6) { map_set(map, x, h, z, 17); } // flowers if (simplex2(x * 0.05, -z * 0.05, 4, 0.8, 2) > 0.7) { int w = 18 + simplex2(x * 0.1, z * 0.1, 4, 0.8, 2) * 7; map_set(map, x, h, z, w); } // trees int ok = 1; if (dx - 4 < 0 || dz - 4 < 0 || dx + 4 >= CHUNK_SIZE || dz + 4 >= CHUNK_SIZE) { ok = 0; } if (ok && simplex2(x, z, 6, 0.5, 2) > 0.84) { for (int y = h + 3; y < h + 8; y++) { for (int ox = -3; ox <= 3; ox++) { for (int oz = -3; oz <= 3; oz++) { int d = (ox * ox) + (oz * oz) + (y - (h + 4)) * (y - (h + 4)); if (d < 11) { map_set(map, x + ox, y, z + oz, 15); } } } } for (int y = h; y < h + 7; y++) { map_set(map, x, y, z, 5); } } } // clouds for (int y = 64; y < 72; y++) { if (simplex3(x * 0.01, y * 0.1, z * 0.01, 8, 0.5, 2) > 0.75) { map_set(map, x, y, z, 16); } } } } }
void biome0(int x, int z, int flag, world_func func, void *arg) { float f = simplex2(x * 0.01, z * 0.01, 4, 0.5, 2); float g = simplex2(-x * 0.01, -z * 0.01, 2, 0.9, 2); int mh = g * 32 + 16; int h = f * mh; int w = 1; int t = 12; if (h <= t) { h = t; w = 2; } // sand and grass terrain for (int y = 0; y < h; y++) { func(x, y, z, w * flag, arg); } if (w == 1) { if (SHOW_PLANTS) { // grass if (simplex2(-x * 0.1, z * 0.1, 4, 0.8, 2) > 0.6) { func(x, h, z, 17 * flag, arg); } // flowers if (simplex2(x * 0.05, -z * 0.05, 4, 0.8, 2) > 0.7) { int w = 18 + simplex2(x * 0.1, z * 0.1, 4, 0.8, 2) * 7; func(x, h, z, w * flag, arg); } } // trees int ok = 0;//SHOW_TREES; // if (dx - 4 < 0 || dz - 4 < 0 || // dx + 4 >= CHUNK_SIZE || dz + 4 >= CHUNK_SIZE) // { // ok = 0; // } if (ok && simplex2(x, z, 6, 0.5, 2) > 0.84) { for (int y = h + 3; y < h + 8; y++) { for (int ox = -3; ox <= 3; ox++) { for (int oz = -3; oz <= 3; oz++) { int d = (ox * ox) + (oz * oz) + (y - (h + 4)) * (y - (h + 4)); if (d < 11) { func(x + ox, y, z + oz, 15, arg); } } } } for (int y = h; y < h + 7; y++) { func(x, y, z, 5, arg); } } } // clouds if (SHOW_CLOUDS) { for (int y = 64; y < 72; y++) { if (simplex3( x * 0.01, y * 0.1, z * 0.01, 8, 0.5, 2) > 0.75) { func(x, y, z, 16 * flag, arg); } } } }
void add_cloud(float player_x, float player_z, float rx, float rz){ //certain types of weather will force less clouds to be allowed. int weather_cloud_max_modifier = 0; if (weather->cloud_count < MAXIMUM_CLOUDS - weather_cloud_max_modifier) { Cloud *c = (Cloud*)malloc(sizeof(Cloud)); c->hmWidth = 32; c->hmDepth = 32; c->render = 0; c->heightmap = (int*)calloc(sizeof(int), c->hmWidth * c->hmDepth); //seed an initial value int i, j; int placed = 0; while (placed == 0) { int x = rand() % 1000; int z = rand() % 1000; for (i=0; i<c->hmWidth; i++) { for (j=0; j<c->hmDepth; j++) { float spx = simplex3( (x+i) * 0.01, 10, (z+j) * 0.01, 8, 0.5, 2); c->heightmap[i * c->hmDepth + j] = (spx > 0.72) ? (int)(((spx - 0.72) / 0.20) * 5) : 0; if (c->heightmap[i * c->hmDepth + j] != 0) { placed = 1; } } } } c->dx = (rand()/RAND_MAX) * 0.01 - 0.005; c->dz = (rand()/RAND_MAX) * 0.01 - 0.005; // randomly distribute around the player if first time generation if (weather->initial_generation > 0) { weather->initial_generation--; c->x = player_x + (rand() % 800) - 400; c->z = player_z + (rand() % 800) - 400; } else { if(rand() % 100 < 50){ c->x = player_x + (rand() % 600) - 300; c->z = player_z + ((rand() % 100 < 50) ? 300 : -300); } else { c->x = player_x + ((rand() % 100 < 50) ? 300 : -300); c->z = player_z + (rand() % 600) - 300; } } c->y = rand() % 20; c->sx = (rand() % 10) + 1; c->sy = 1; c->sz = (rand() % 10) + 1; c->r = 1.0f - (rand()%10)/100; c->g = 1.0f - (rand()%10)/100; c->b = 1; weather->clouds[weather->cloud_count] = c; weather->cloud_count++; } }
void gen_chunk_buffers(Chunk *chunk) { Map *map = &chunk->map; int faces = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } faces += total; } END_MAP_FOR_EACH; GLfloat *position_data, *normal_data, *uv_data; malloc_buffers(3, faces, &position_data, &normal_data, &uv_data); int position_offset = 0; int uv_offset = 0; MAP_FOR_EACH(map, e) { if (e->w <= 0) { continue; } int f1, f2, f3, f4, f5, f6; exposed_faces(map, e->x, e->y, e->z, &f1, &f2, &f3, &f4, &f5, &f6); int total = f1 + f2 + f3 + f4 + f5 + f6; if (is_plant(e->w)) { total = total ? 4 : 0; } if (total == 0) { continue; } if (is_plant(e->w)) { float rotation = simplex3(e->x, e->y, e->z, 4, 0.5, 2) * 360; make_plant( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, e->x, e->y, e->z, 0.5, e->w, rotation); } else { make_cube( position_data + position_offset, normal_data + position_offset, uv_data + uv_offset, f1, f2, f3, f4, f5, f6, e->x, e->y, e->z, 0.5, e->w); } position_offset += total * 18; uv_offset += total * 12; } END_MAP_FOR_EACH; gen_buffers( 3, faces, position_data, normal_data, uv_data, &chunk->position_buffer, &chunk->normal_buffer, &chunk->uv_buffer); chunk->faces = faces; chunk->dirty = 0; }