Techneck/code/source-c/world.c

141 lines
4.4 KiB
C

#include "world.h"
#include "state.h"
#include <linmath.h>
#include <stdlib.h>
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);
}
if(chunk->vao != 0) glDeleteVertexArrays(1, &chunk->vao);
if(chunk->vertex_data != 0) glDeleteBuffers(1, &chunk->vertex_data);
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)
{
for(uint32_t loader_index = 0; loader_index < world->num_loaders; ++loader_index)
for(uint32_t chunk_index = 0; chunk_index < world->loaders[loader_index].num_chunks; ++chunk_index)
tc_draw_chunk(world->loaders[loader_index].chunks[chunk_index], world);
}
tc_chunkloader_s tc_create_chunkloader(tc_world_s *world)
{
tc_chunkloader_s loader;
loader.extent.x = UPDATE_DISTANCE * 2 + 1;
loader.extent.y = UPDATE_DISTANCE * 2 + 1;
loader.extent.z = UPDATE_DISTANCE * 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;
}
tc_chunkloader_s tc_create_spawn_loader(tc_world_s *world)
{
tc_chunkloader_s loader = tc_create_chunkloader(world);
loader.needs_reload = true;
loader.world = world;
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(512);
world->worldgen = &tc_default_terrain_generator_g;
world->num_loaders = 1;
world->loaders = malloc(sizeof(tc_chunkloader_s) * world->num_loaders);
world->loaders[0] = tc_create_spawn_loader(world);
world->spawn_loader = &world->loaders[0];
return world;
}