#include "world.h" #include "state.h" #include #include tc_worldgen_s tc_default_terrain_generator_g; void tc_upload_chunk(tc_chunk_s *chunk) { // If the chunk has no mesh yet if(chunk->num_vertices == 0) { // Create one tc_meshize_chunk(chunk); } glGenVertexArrays(1, &chunk->vao); glBindVertexArray(chunk->vao); glGenBuffers(1, &chunk->vertex_data); glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data); glBufferData(GL_ARRAY_BUFFER, chunk->num_vertices * 5 * sizeof(float), NULL, GL_STATIC_DRAW); glBufferSubData(GL_ARRAY_BUFFER, 0, chunk->num_vertices * 3 * sizeof(float), chunk->vertex_positions ); glBufferSubData(GL_ARRAY_BUFFER, chunk->num_vertices * 3 * sizeof(float), chunk->num_vertices * 2 * sizeof(float), chunk->vertex_uvs ); glBindVertexArray(0); } void tc_draw_chunk(tc_chunk_s *chunk, tc_world_s *world) { mat4x4 model_matrix; mat4x4_identity(model_matrix); mat4x4_translate_in_place(model_matrix, chunk->position.x*32, chunk->position.y*32, -chunk->position.z*32); int model_matrix_uniform_location = glGetUniformLocation(tc_game_state_g.renderer.draw_shader.program_id, "model_matrix"); glUniformMatrix4fv(model_matrix_uniform_location, 1, GL_FALSE, &model_matrix[0][0]); // glBindVertexArray(chunk->vao); glBindBuffer(GL_ARRAY_BUFFER, chunk->vertex_data); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void *) 0); glEnableVertexAttribArray(0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void *) (sizeof(float) * 3 * chunk->num_vertices) ); glEnableVertexAttribArray(1); glActiveTexture(GL_TEXTURE0); glUniform1i( glGetUniformLocation(tc_game_state_g.renderer.draw_shader.program_id, "block_atlas"), 0 ); glBindTexture(GL_TEXTURE_2D, tc_game_state_g.block_texture_atlas->gl_identifier); glDrawArrays(GL_TRIANGLES, 0, chunk->num_vertices); glBindVertexArray(0); } void tc_init_world_generators() { tc_default_terrain_generator_g.name = "Default Terrain Generator"; tc_default_terrain_generator_g.fn_generate_chunk = &tc_generate_default_terrain_chunk; } void tc_init_worlds() { tc_init_world_generators(); } void tc_set_block_in_chunk( tc_chunk_s *chunk, uint8_t x, uint8_t y, uint8_t z, tc_block_s block ) { chunk->blocks[x][y][z] = block.type_identifier; } void tc_draw_world(tc_world_s *world) { tc_on_each_loaded_chunk(world, tc_draw_chunk, world); } /* void tc_add_chunk(tc_world_s *world, tc_chunk_s *chunk) { if(world->num_chunks >= world->chunks_capacity) { world->chunks_capacity *= 2; world->chunks = realloc(world->chunks, sizeof(tc_chunk_s *) * world->chunks_capacity); } world->chunks[world->num_chunks] = chunk; ++world->num_chunks; } */ void tc_setup_terrain(tc_world_s *world) { // TODO } tc_chunkloader_s tc_create_chunkloader(tc_world_s *world) { tc_chunkloader_s loader; loader.width = world->load_radius * 2 + 1; loader.height = world->load_radius * 2 + 1; loader.depth = world->load_radius * 2 + 1; loader.center_x = 0; loader.center_y = 0; loader.center_z = 0; loader.chunks_capacity = 512; loader.chunks = calloc(sizeof(tc_chunk_s *), loader.chunks_capacity); loader.num_chunks = 0; loader.needs_reload = false; return loader; } void tc_add_chunk_to_loader(tc_chunkloader_s *chunkloader, tc_chunk_s *chunk) { if(chunkloader->num_chunks >= chunkloader->chunks_capacity) { chunkloader->chunks_capacity *= 2; chunkloader->chunks = realloc(chunkloader->chunks, sizeof(tc_chunk_s) * chunkloader->chunks_capacity); } chunkloader->chunks[chunkloader->num_chunks] = chunk; ++chunkloader->num_chunks; } tc_chunkloader_s tc_create_spawn_loader(tc_world_s *world) { tc_chunkloader_s loader = tc_create_chunkloader(world); loader.needs_reload = true; return loader; } tc_world_s * tc_new_world(tc_worldgen_s *generator) { tc_world_s *world = calloc(sizeof(tc_world_s), 1); world->pool = tc_new_chunk_pool(128); world->worldgen = &tc_default_terrain_generator_g; // world->center_chunk = tc_new_chunk(world, 0, 0, 0); world->load_radius = 3; world->num_loaders = 1; world->loaders = malloc(sizeof(tc_chunkloader_s) * world->num_loaders); world->loaders[0] = tc_create_spawn_loader(world); // tc_upload_chunk(world->center_chunk); return world; }