A 3D game engine from scratch.
at main 168 lines 4.6 kB view raw
1// (c) 2020 Vlad-Stefan Harbuz <vlad@vladh.net> 2 3#include <thread> 4#include "../src_external/pstr.h" 5#include "types.hpp" 6#include "logs.hpp" 7#include "util.hpp" 8#include "renderer.hpp" 9#include "internals.hpp" 10#include "engine.hpp" 11#include "state.hpp" 12#include "peony_parser.hpp" 13#include "constants.hpp" 14#include "core.hpp" 15#include "intrinsics.hpp" 16 17 18State *core::state = nullptr; 19 20 21WindowSize * 22core::get_window_size() 23{ 24 return &core::state->window_size; 25} 26 27 28memory::Pool * 29core::get_asset_memory_pool() 30{ 31 return core::state->asset_memory_pool; 32} 33 34 35int 36core::run() 37{ 38 // Allocate memory 39 State *state = (State*)calloc(1, sizeof(State)); 40 defer { free(state); }; 41 memory::Pool asset_memory_pool = { .size = util::mb_to_b(1024) }; 42 defer { memory::destroy_memory_pool(&asset_memory_pool); }; 43 44 // Make state 45 if (!init_state(state, &asset_memory_pool)) { 46 return EXIT_FAILURE; 47 } 48 defer { destroy_state(state); }; 49 50 // Set up loading threads 51 std::mutex loading_thread_mutex; 52 std::thread loading_threads[N_LOADING_THREADS]; 53 range (0, N_LOADING_THREADS) { 54 loading_threads[idx] = std::thread( 55 tasks::run_loading_loop, 56 &loading_thread_mutex, 57 &state->engine_state.should_stop, 58 idx); 59 } 60 defer { range (0, N_LOADING_THREADS) { loading_threads[idx].join(); } }; 61 62 // Run main loop 63 engine::run_main_loop(state->window); 64 65 return EXIT_SUCCESS; 66} 67 68 69void 70core::framebuffer_size_callback(GLFWwindow* window, int width, int height) 71{ 72 memory::Pool *asset_memory_pool = get_asset_memory_pool(); 73 WindowSize *window_size = get_window_size(); 74 logs::info("Window is now: %d x %d", window_size->width, window_size->height); 75 window_size->width = width; 76 window_size->height = height; 77 cameras::Camera *camera = cameras::get_main(); 78 cameras::update_matrices(camera); 79 cameras::update_ui_matrices(camera); 80 gui::update_screen_dimensions(window_size->width, window_size->height); 81 82 auto *builtin_textures = renderer::get_builtin_textures(); 83 renderer::resize_renderer_buffers(asset_memory_pool, builtin_textures, 84 width, height); 85} 86 87 88void 89core::mouse_button_callback(GLFWwindow *window, int button, int action, int mods) 90{ 91 input::update_mouse_button(button, action, mods); 92 gui::update_mouse_button(); 93} 94 95 96void 97core::mouse_callback(GLFWwindow *window, f64 x, f64 y) 98{ 99 v2 mouse_pos = v2(x, y); 100 input::update_mouse(mouse_pos); 101 102 if (input::is_cursor_enabled()) { 103 gui::update_mouse(); 104 } else { 105 cameras::Camera *camera = cameras::get_main(); 106 cameras::update_mouse(camera, input::get_mouse_3d_offset()); 107 } 108} 109 110 111void 112core::key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) 113{ 114 input::update_keys(key, scancode, action, mods); 115} 116 117 118void 119core::char_callback(GLFWwindow* window, u32 codepoint) { 120 input::update_text_input(codepoint); 121} 122 123 124bool 125core::init_state(State *state, memory::Pool *asset_memory_pool) 126{ 127 core::state = state; 128 state->window = renderer::init_window(&state->window_size); 129 if (!state->window) { return false; } 130 131 state->asset_memory_pool = asset_memory_pool; 132 133 spatial::init(&state->spatial_state, asset_memory_pool); 134 drawable::init(&state->drawable_state, asset_memory_pool); 135 lights::init(&state->lights_state, asset_memory_pool); 136 anim::init(&state->anim_state, asset_memory_pool); 137 physics::init(&state->physics_state, asset_memory_pool); 138 entities::init(&state->entities_state, asset_memory_pool); 139 behavior::init( 140 &state->behavior_state, 141 asset_memory_pool, 142 // NOTE: behavior needs the global state to pass to the behavior functions 143 state); 144 engine::init(&state->engine_state, asset_memory_pool); 145 mats::init(&state->materials_state, asset_memory_pool); 146 input::init(&state->input_state, state->window); 147 renderer::init( 148 &state->renderer_state, asset_memory_pool, 149 state->window_size.width, state->window_size.height, state->window); 150 internals::init(); 151 gui::init(asset_memory_pool, 152 &state->gui_state, 153 renderer::get_gui_texture_atlas_size(), 154 renderer::get_gui_font_assets(), 155 state->window_size.width, state->window_size.height); 156 debugdraw::init(&state->debug_draw_state, asset_memory_pool); 157 tasks::init(&state->tasks_state, asset_memory_pool); 158 cameras::init(&state->cameras_state, state->window_size.width, state->window_size.height); 159 160 return true; 161} 162 163 164void 165core::destroy_state(State *state) 166{ 167 glfwTerminate(); 168}