#include "engine.h" #include "block.h" #include "camera.h" #include "cglm/io.h" #include "chunk.h" #include "input.h" #include "window.h" #include "world.h" #include #include #include #include #include #include void _engine_insert_chunk_ptrs(struct engine* engine, struct chunk* chunk); int engine_init(struct engine *engine) { // Setup the Window struct window* window = malloc(sizeof(struct window)); memset(window, 0, sizeof(struct window)); if (window_init(window) != 0) { free(window); return -1; } engine->window = window; // Setup Shader pipeline struct shader* shader = malloc(sizeof(struct shader)); memset(shader, 0, sizeof(struct shader)); if (shader_init(shader)) { free(window); free(shader); return -1; }; engine->shader = shader; // Setup Objects to draw // memset(engine->loaded_chunks, 0, (1 + CHUNK_DISTANCE * 2) * (1 + CHUNK_DISTANCE * 2)); // Setup camera camera_init(&engine->camera); vec3 camera_pos = { 0.0f, 15.0f, 0.0f }; camera_set_position(engine->camera, camera_pos); // Setup root chunk struct world* world; world_init(time(NULL), &world); engine->world = world; // Final step - Start the game engine->game_loop = 1; return 0; } void engine_update(struct engine* engine) { int curr_chunk[2] = { (engine->camera->position[0] / CHUNK_WIDTH), (engine->camera->position[2]) / CHUNK_LENGTH }; // Chunk update struct chunk* c = {0}; int coord[2] = { curr_chunk[0], curr_chunk[1] }; world_get_chunk(engine->world, coord, &c); // We moved a chunk - load new chunks with chunk_load if (engine->curr_chunk[0] != curr_chunk[0] || engine->curr_chunk[1] != curr_chunk[1]) { fprintf(stderr, "CHUNK Update! From (%d, %d) to (%d, %d)\n", engine->curr_chunk[0], engine->curr_chunk[1], curr_chunk[0], curr_chunk[1]); // Unload existing chunks for (int i = -CHUNK_DISTANCE; i <= CHUNK_DISTANCE; i++) { for (int j = -CHUNK_DISTANCE; j <= CHUNK_DISTANCE; j++) { struct chunk* chunk; int chunk_coord[2] = { engine->curr_chunk[0] + i, engine->curr_chunk[1] + j }; world_get_chunk(engine->world, chunk_coord, &chunk); // Get "real" coords as in non-negative numbers, that can go in a array int real_coord[2] = { i + CHUNK_DISTANCE, j + CHUNK_DISTANCE }; // engine->loaded_chunks[real_coord[0]][real_coord[1]] = chunk; // Load chunk // TODO: Fix some VAO/VBO bug when negative y // chunk_unload(chunk); } } // Update the curr_chunk memcpy(engine->curr_chunk, curr_chunk, sizeof(vec2)); // Load chunks of CHUNK_DISTANCE around curr_chunk } } void engine_fps(struct engine* engine, float fps) { // TTF_Font* font = TTF_OpenFont("fonts/PixelifySans-Regular.ttf", 8.0f); // SDL_RenderClear(engine->window->renderer); // SDL_Color black = {0, 0, 0}; // char fps_text[36]; // snprintf(fps_text, 36, "FPS: %.2f", fps); // SDL_Surface* text = TTF_RenderText_Solid(font, fps_text, black); // SDL_Texture* texture = SDL_CreateTextureFromSurface(engine->window->renderer, text); // SDL_RenderCopy(engine->window->renderer, texture, NULL, &rect); } void engine_start(struct engine* engine) { float frames = 0; time_t frame_last_time = time(NULL); float fps = 0.0f; while (engine->game_loop) { time_t now = time(NULL); time_t diff = now - frame_last_time; // Calculate FPS every second if (diff >= 1.0f) { fps = frames / diff; frames = 0; frame_last_time = now; fprintf(stderr, "FPS: %.2f\n", fps); } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(0.529f, 0.808f, 0.922f, 1.0f); glEnable(GL_DEPTH_TEST); //glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); glUseProgram(engine->shader->program); // Update engine managed objects engine_fps(engine, fps); engine_update(engine); camera_update(engine->camera, engine->shader); for (int i = -CHUNK_DISTANCE; i <= CHUNK_DISTANCE; i++) { for (int j = -CHUNK_DISTANCE; j <= CHUNK_DISTANCE; j++) { struct chunk* chunk = {0}; // // Load chunk // Ensure the y coordinate is negative, because in OpenGL +z-axis (y in chunk system) is towards // user, so we want inwards to be positive, so flip sign int chunk_coord[2] = { engine->curr_chunk[0] + i, -engine->curr_chunk[1] + j }; world_get_chunk(engine->world, chunk_coord, &chunk); // Load chunk chunk_load(chunk, chunk_coord); chunk_draw(chunk, engine->shader); } } SDL_RenderPresent(engine->window->renderer); frames += 1; } }