main.cpp 43.2 KB
Newer Older
1
#ifdef _WIN32
2 3
#define WIN32_LEAN_AND_MEAN
#define VC_EXTRA_LEAN
4
#endif
Daniel Bross's avatar
Daniel Bross committed
5

Daniel Bross's avatar
Daniel Bross committed
6
#include "assimp_loader.cpp"
7

Daniel Bross's avatar
Daniel Bross committed
8
#include "imgui/imgui.h"
Niels Bross's avatar
Niels Bross committed
9 10
#include "shared.h"

Daniel Bross's avatar
Daniel Bross committed
11 12 13 14
#if DEBUG
#define EDITOR
#endif

15
#if DEBUG
Niels Bross's avatar
Niels Bross committed
16 17 18
#include "debug.h"
#endif

Daniel Bross's avatar
Daniel Bross committed
19 20 21 22 23
#ifdef EDITOR
#include "project.h"
#include "project.cpp"
#endif

Niels Bross's avatar
Niels Bross committed
24 25 26 27
#include <glad/glad.h>
#include "fmod.h"
#include "fmod_errors.h"

Niels Bross's avatar
Niels Bross committed
28 29
#include <sys/types.h>
#include <sys/stat.h>
Niels Bross's avatar
Niels Bross committed
30 31 32 33 34 35
#include <fcntl.h>
#include "time.h"

#include "main.h"

// Global
Niels Bross's avatar
Niels Bross committed
36
PlatformApi platform;
Niels Bross's avatar
Niels Bross committed
37
Core core;
Niels Bross's avatar
Niels Bross committed
38
struct LogState *log_state;
39
static MemoryState memory_state;
Niels Bross's avatar
Niels Bross committed
40 41 42 43 44 45
// Global

#ifdef _WIN32
#include "win32_platform.cpp"
#elif __linux
#include "linux_platform.cpp"
Daniel Bross's avatar
Daniel Bross committed
46 47
#elif __APPLE__
#include "osx_platform.cpp"
Niels Bross's avatar
Niels Bross committed
48 49 50
#endif

#include "keycontroller.h"
Daniel Bross's avatar
Daniel Bross committed
51 52

#if defined(__linux) || defined(_WIN32)
53
//#include "vulkan_rendering.h"
Daniel Bross's avatar
Daniel Bross committed
54
#endif
Daniel Bross's avatar
Daniel Bross committed
55

Niels Bross's avatar
Niels Bross committed
56
#include "opengl_rendering.h"
57
#include "animation.cpp"
Niels Bross's avatar
Niels Bross committed
58 59
#include "keycontroller.cpp"
#include "sound.h"
Daniel Bross's avatar
Daniel Bross committed
60
#include "timers.h"
Niels Bross's avatar
Niels Bross committed
61 62 63
#include "fmod_sound.h"
#include "fmod_sound.cpp"
#include "filehandling.h"
64

65
#include "shader_loader.cpp"
Daniel Bross's avatar
Daniel Bross committed
66
#include "render_pipeline.cpp"
67
#include "rendering.cpp"
68
#include "particles.cpp"
Daniel Bross's avatar
Daniel Bross committed
69 70
#include "particle_api.cpp"

71
#include "scene.h"
Daniel Bross's avatar
Daniel Bross committed
72
#include "scene.cpp"
Daniel Bross's avatar
.  
Daniel Bross committed
73

Daniel Bross's avatar
Daniel Bross committed
74 75 76 77
#ifdef EDITOR
#include "engine_editor.h"
#include "engine_editor.cpp"
#endif
78

79
#if defined(__linux) || defined(__APPLE__)
Daniel Bross's avatar
Daniel Bross committed
80
#include "dlfcn.h"
81
#endif
Niels Bross's avatar
Niels Bross committed
82

83
static InputController input_controller;
Niels Bross's avatar
Niels Bross committed
84 85

#include "keys_glfw.h"
Daniel Bross's avatar
Daniel Bross committed
86
#include "imgui/imgui_impl_glfw.h"
Niels Bross's avatar
Niels Bross committed
87
#include "opengl_rendering.cpp"
Daniel Bross's avatar
Daniel Bross committed
88 89

#if defined(__linux) || defined(_WIN32)
90
//#include "vulkan_rendering.cpp"
Daniel Bross's avatar
Daniel Bross committed
91
#endif
Niels Bross's avatar
Niels Bross committed
92

Niels Bross's avatar
Niels Bross committed
93
static void load_game_code(GameCode &game_code, char *game_library_path, char *temp_game_library_path, MemoryArena *arena = nullptr)
Daniel Bross's avatar
Daniel Bross committed
94
{   
95
    if (!copy_file(game_library_path, temp_game_library_path, false))
Niels Bross's avatar
Niels Bross committed
96 97
        return;

Daniel Bross's avatar
Daniel Bross committed
98
    game_code.update = update_stub;
99
    game_code.update_editor = update_editor_stub;
Niels Bross's avatar
Niels Bross committed
100 101
    game_code.last_library_write_time = get_last_write_time(game_library_path);
    game_code.game_code_library = platform.load_dynamic_library(temp_game_library_path);
Niels Bross's avatar
Niels Bross committed
102

Niels Bross's avatar
Niels Bross committed
103
    if (game_code.game_code_library)
Niels Bross's avatar
Niels Bross committed
104
    {
105
        game_code.update = (Update *)platform.load_symbol(game_code.game_code_library, "update");
106
        game_code.update_editor = (UpdateEditor *)platform.load_symbol(game_code.game_code_library, "update_editor");
107 108
        game_code.build_render_pipeline = (BuildRenderPipeline *)platform.load_symbol(game_code.game_code_library, "build_render_pipeline");
        game_code.is_valid = game_code.update != nullptr || game_code.update_editor != nullptr && game_code.build_render_pipeline != nullptr;
Niels Bross's avatar
Niels Bross committed
109
    }
Daniel Bross's avatar
Daniel Bross committed
110 111
    else
        debug("The game library file could not be loaded\n");
Niels Bross's avatar
Niels Bross committed
112

Niels Bross's avatar
Niels Bross committed
113
    if (!game_code.is_valid)
Niels Bross's avatar
Niels Bross committed
114
    {
Niels Bross's avatar
Niels Bross committed
115
        debug("Invalid game code\n");
Niels Bross's avatar
Niels Bross committed
116

Daniel Bross's avatar
Daniel Bross committed
117
        // ONLY UNIX
118
#if defined(__linux) || defined(__APPLE__)
Daniel Bross's avatar
Daniel Bross committed
119 120
        char *err_str;
        err_str = dlerror();
Niels Bross's avatar
Niels Bross committed
121
        if (err_str)
Daniel Bross's avatar
Daniel Bross committed
122
        {
Daniel Bross's avatar
Daniel Bross committed
123
            debug("%s", err_str);
Daniel Bross's avatar
Daniel Bross committed
124
        }
125
#endif
Niels Bross's avatar
Niels Bross committed
126

Daniel Bross's avatar
Daniel Bross committed
127
        game_code.update = update_stub;
128
        game_code.update_editor = update_editor_stub;
Niels Bross's avatar
Niels Bross committed
129 130 131
    }
}

Niels Bross's avatar
tidy  
Niels Bross committed
132
static void unload_game_code(GameCode *game_code)
Niels Bross's avatar
Niels Bross committed
133
{
Niels Bross's avatar
Niels Bross committed
134
    if (game_code->game_code_library)
Niels Bross's avatar
Niels Bross committed
135
    {
Niels Bross's avatar
Niels Bross committed
136
        platform.free_dynamic_library(game_code->game_code_library);
Daniel Bross's avatar
Daniel Bross committed
137
        game_code->game_code_library = nullptr;
Niels Bross's avatar
Niels Bross committed
138
    }
Niels Bross's avatar
Niels Bross committed
139 140

    game_code->is_valid = false;
Daniel Bross's avatar
Daniel Bross committed
141
    game_code->update = update_stub;
142
    game_code->update_editor = update_editor_stub;
Niels Bross's avatar
Niels Bross committed
143 144
}

145 146 147 148 149 150 151 152 153 154 155 156 157 158
static void sleep_ms(i32 ms)
{
#ifdef _WIN32
    Sleep(ms);
#elif _POSIX_C_SOURCE > 199309L
    struct timespec ts;
    ts.tv_sec = ms / 1000;
    ts.tv_nsec = (ms % 1000) * 1000000;
    nanosleep(&ts, NULL);
#else
    usleep(ms * 1000);
#endif
}

Niels Bross's avatar
Niels Bross committed
159
static void reload_game_code(GameCode *game_code, char *game_library_path, char *temp_game_library_path, MemoryArena *arena = nullptr)
Niels Bross's avatar
Niels Bross committed
160
{
Niels Bross's avatar
tidy  
Niels Bross committed
161
    unload_game_code(game_code);
162 163

    sleep_ms(100);
Niels Bross's avatar
Niels Bross committed
164

Niels Bross's avatar
Niels Bross committed
165
    load_game_code(*game_code, game_library_path, temp_game_library_path, arena);
Niels Bross's avatar
Niels Bross committed
166 167
}

Niels Bross's avatar
Niels Bross committed
168
static b32 reload_libraries(GameCode *game, char *game_library_path, char *temp_game_library_path, MemoryArena *arena = nullptr)
Niels Bross's avatar
Niels Bross committed
169
{
Daniel Bross's avatar
Daniel Bross committed
170
    // @Bug: Not working on Mac
Niels Bross's avatar
tidy  
Niels Bross committed
171
    time_t last_write_time = get_last_write_time(game_library_path);
Niels Bross's avatar
Niels Bross committed
172 173

    if (last_write_time != 0)
Niels Bross's avatar
Niels Bross committed
174
    {
Niels Bross's avatar
Niels Bross committed
175
        if (difftime(game->last_library_write_time, last_write_time) != 0)
176
        {
177 178 179 180
            reload_game_code(game, game_library_path, temp_game_library_path, arena);
            assert(game);
            debug_log("Reloaded game library\n");
            return true;
181
        }
Niels Bross's avatar
Niels Bross committed
182
    }
183 184

    return false;
Niels Bross's avatar
Niels Bross committed
185 186
}

187
void save_config(const char *file_path, Renderer* renderer, sound::SoundSystem *sound_system)
Niels Bross's avatar
Niels Bross committed
188
{
Niels Bross's avatar
Niels Bross committed
189 190 191
    FILE *file = fopen(file_path, "w");

    if (file)
Niels Bross's avatar
Niels Bross committed
192
    {
193 194 195
        i32 width = core.config_data.screen_width;
        i32 height = core.config_data.screen_height;
        WindowMode window_mode = core.config_data.window_mode;
Niels Bross's avatar
Niels Bross committed
196
		b32 vsync = true;
Niels Bross's avatar
Niels Bross committed
197

198
        if (renderer)
Niels Bross's avatar
Niels Bross committed
199
        {
200 201 202
            width = renderer->window_width;
            height = renderer->window_height;
            window_mode = renderer->window_mode;
Niels Bross's avatar
Niels Bross committed
203 204
			vsync = renderer->api_functions.get_v_sync(renderer->api_functions.render_state);
		}
Niels Bross's avatar
Niels Bross committed
205

Niels Bross's avatar
Niels Bross committed
206 207 208
        fprintf(file, "screen_width %d\n", width);
        fprintf(file, "screen_height %d\n", height);
        fprintf(file, "window_mode %d\n", window_mode);
Niels Bross's avatar
Niels Bross committed
209
		fprintf(file, "vsync %d\n", vsync);
Niels Bross's avatar
Niels Bross committed
210

Niels Bross's avatar
Niels Bross committed
211 212 213
        b32 muted = false;
        r32 sfx_vol = 1.0f;
        r32 music_vol = 1.0f;
Daniel Bross's avatar
.  
Daniel Bross committed
214
        r32 master_vol = 1.0f;
Niels Bross's avatar
Niels Bross committed
215

216
        if (sound_system)
Niels Bross's avatar
Niels Bross committed
217
        {
218 219 220 221
            muted = sound_system->muted;
            sfx_vol = sound_system->sfx_volume;
            music_vol = sound_system->music_volume;
            master_vol = sound_system->master_volume;
Niels Bross's avatar
Niels Bross committed
222
        }
Niels Bross's avatar
Niels Bross committed
223

Niels Bross's avatar
Niels Bross committed
224 225 226
        fprintf(file, "muted %d\n", muted);
        fprintf(file, "sfx_volume %.2f\n", sfx_vol);
        fprintf(file, "music_volume %.2f\n", music_vol);
Daniel Bross's avatar
.  
Daniel Bross committed
227
        fprintf(file, "master_volume %.2f\n", master_vol);
Niels Bross's avatar
Niels Bross committed
228

Niels Bross's avatar
Niels Bross committed
229
        fclose(file);
Niels Bross's avatar
Niels Bross committed
230

231 232 233 234 235 236 237
        core.config_data.screen_width = width;
        core.config_data.screen_height = height;
        core.config_data.window_mode = window_mode;
        core.config_data.muted = muted;
        core.config_data.sfx_volume = sfx_vol;
        core.config_data.music_volume = music_vol;
        core.config_data.master_volume = master_vol;
238
        core.config_data.vsync = vsync;
Niels Bross's avatar
Niels Bross committed
239 240 241
    }
}

Niels Bross's avatar
Niels Bross committed
242
inline void load_version(const char *file_path, char *version, char *title)
243
{
Niels Bross's avatar
Niels Bross committed
244
    FILE *file;
245 246 247
    file = fopen(file_path, "r");
    char line_buffer[255];

Niels Bross's avatar
Niels Bross committed
248
    if (file)
249
    {
Niels Bross's avatar
Niels Bross committed
250
        while (fgets(line_buffer, 255, file))
Daniel Bross's avatar
.  
Daniel Bross committed
251
        {
Niels Bross's avatar
Niels Bross committed
252
            if (starts_with(line_buffer, "version"))
Daniel Bross's avatar
.  
Daniel Bross committed
253 254 255 256 257 258 259 260 261
            {
                // @Note(Niels): Format for version is: [type] v#.#.#
                // Example 1: alpha v0.1.0
                // Example 2: beta v0.4.3
                char type_buf[64];
                char version_buf[64];
                sscanf(line_buffer, "version %s %s", type_buf, version_buf);
                snprintf(version, strlen(type_buf) + strlen(version_buf) + 2, "%s %s", type_buf, version_buf);
            }
Niels Bross's avatar
Niels Bross committed
262
            if (starts_with(line_buffer, "title"))
Daniel Bross's avatar
.  
Daniel Bross committed
263 264 265 266
            {
                sscanf(line_buffer, "title %[^\n]", title);
            }
        }
Niels Bross's avatar
Niels Bross committed
267 268 269
    }
}

Niels Bross's avatar
Niels Bross committed
270
inline void load_config(const char *file_path, ConfigData *config_data, MemoryArena *perm_arena)
Niels Bross's avatar
Niels Bross committed
271
{
Niels Bross's avatar
Niels Bross committed
272
    FILE *file;
Niels Bross's avatar
tidy  
Niels Bross committed
273 274
    file = fopen(file_path, "r");
    char line_buffer[255];
Niels Bross's avatar
Niels Bross committed
275

276
    core.config_data = {};
Niels Bross's avatar
Niels Bross committed
277 278

    if (!platform.file_exists(file_path))
Niels Bross's avatar
Niels Bross committed
279
    {
Daniel Bross's avatar
.  
Daniel Bross committed
280
        // @Note: We read the version from a .version file
281
        char version[64];
Daniel Bross's avatar
.  
Daniel Bross committed
282 283
        char title[128];
        load_version("../.version", version, title);
Niels Bross's avatar
Niels Bross committed
284
        snprintf(config_data->version, strlen(version) + 1, "%s", version);
Niels Bross's avatar
Niels Bross committed
285 286
        snprintf(config_data->title, strlen(title) + 1, "%s", title);

Daniel Bross's avatar
.  
Daniel Bross committed
287
        // @Note: Default is windowed borderless (aka windowed fullscreen)
288 289
        config_data->window_mode = FM_BORDERLESS;

Daniel Bross's avatar
.  
Daniel Bross committed
290 291
        // @Note: Setting the dimensions to zero will force the renderer to initialize it properly
        config_data->screen_width = 0;
Niels Bross's avatar
Niels Bross committed
292 293 294 295
        config_data->screen_height = 0;
        config_data->muted = false;
        config_data->sfx_volume = 1.0f;
        config_data->music_volume = 1.0f;
Daniel Bross's avatar
.  
Daniel Bross committed
296
        config_data->master_volume = 1.0f;
297
        config_data->vsync = true;
Niels Bross's avatar
Niels Bross committed
298

299
        save_config(file_path);
Niels Bross's avatar
Niels Bross committed
300 301
    }
    else
Niels Bross's avatar
Niels Bross committed
302
    {
Niels Bross's avatar
Niels Bross committed
303 304 305 306 307
        char version[64];
        char title[128];
        load_version("../.version", version, title);
        snprintf(config_data->version, strlen(version) + 1, "%s", version);
        snprintf(config_data->title, strlen(title) + 1,"%s", title);
308
	
Niels Bross's avatar
tidy  
Niels Bross committed
309
        while(fgets(line_buffer, 255, file))
Niels Bross's avatar
Niels Bross committed
310
        {
Niels Bross's avatar
Niels Bross committed
311
            if (starts_with(line_buffer, "screen_width"))
Niels Bross's avatar
Niels Bross committed
312
            {
Niels Bross's avatar
Niels Bross committed
313
                sscanf(line_buffer, "screen_width %d", &config_data->screen_width);
Niels Bross's avatar
Niels Bross committed
314
            }
Niels Bross's avatar
Niels Bross committed
315
            else if (starts_with(line_buffer, "screen_height"))
Niels Bross's avatar
Niels Bross committed
316
            {
Niels Bross's avatar
Niels Bross committed
317
                sscanf(line_buffer, "screen_height %d", &config_data->screen_height);
Niels Bross's avatar
Niels Bross committed
318
            }
Niels Bross's avatar
Niels Bross committed
319
            else if (starts_with(line_buffer, "contrast"))
Niels Bross's avatar
Niels Bross committed
320
            {
Niels Bross's avatar
Niels Bross committed
321
                sscanf(line_buffer, "contrast %f", &config_data->contrast);
Niels Bross's avatar
Niels Bross committed
322
            }
Niels Bross's avatar
Niels Bross committed
323
            else if (starts_with(line_buffer, "brightness"))
Niels Bross's avatar
Niels Bross committed
324
            {
Niels Bross's avatar
Niels Bross committed
325
                sscanf(line_buffer, "brightness %f", &config_data->brightness);
Niels Bross's avatar
Niels Bross committed
326
            }
Niels Bross's avatar
Niels Bross committed
327
            else if (starts_with(line_buffer, "window_mode"))
Niels Bross's avatar
Niels Bross committed
328
            {
329
                sscanf(line_buffer, "window_mode %d", &config_data->window_mode);
Niels Bross's avatar
Niels Bross committed
330 331
            }
            else if (starts_with(line_buffer, "muted"))
Niels Bross's avatar
Niels Bross committed
332
            {
Niels Bross's avatar
Niels Bross committed
333
                sscanf(line_buffer, "muted %d", &config_data->muted);
Niels Bross's avatar
Niels Bross committed
334
            }
Niels Bross's avatar
Niels Bross committed
335
            else if (starts_with(line_buffer, "sfx_volume"))
Niels Bross's avatar
Niels Bross committed
336
            {
Niels Bross's avatar
Niels Bross committed
337
                sscanf(line_buffer, "sfx_volume %f", &config_data->sfx_volume);
Niels Bross's avatar
Niels Bross committed
338
            }
Niels Bross's avatar
Niels Bross committed
339
            else if (starts_with(line_buffer, "music_volume"))
Niels Bross's avatar
Niels Bross committed
340
            {
Niels Bross's avatar
Niels Bross committed
341
                sscanf(line_buffer, "music_volume %f", &config_data->music_volume);
Niels Bross's avatar
Niels Bross committed
342
            }
Niels Bross's avatar
Niels Bross committed
343
            else if (starts_with(line_buffer, "master_volume"))
Niels Bross's avatar
Niels Bross committed
344 345 346
            {
                sscanf(line_buffer, "master_volume %f", &config_data->master_volume);
            }
347 348 349 350
            else if (starts_with(line_buffer, "vsync"))
            {
                sscanf(line_buffer, "vsync %d", &config_data->vsync);
            }
Niels Bross's avatar
Niels Bross committed
351
        }
Niels Bross's avatar
tidy  
Niels Bross committed
352
        fclose(file);
Niels Bross's avatar
Niels Bross committed
353 354 355
    }
}

356
[[noreturn]]
Daniel Bross's avatar
Daniel Bross committed
357 358 359 360 361 362
static void check_shader_files(WorkQueue *queue, void *data)
{
    // @Incomplete: We might want to sleep
    while(true)
    {
        Renderer *renderer = (Renderer *)data;
363
        rendering::check_for_shader_file_changes(renderer);
364
		sleep_ms(100);
Daniel Bross's avatar
Daniel Bross committed
365 366 367
    }
}

368
static void init_renderer(GameCode &game, Renderer *renderer, WorkQueue *reload_queue, ThreadInfo *reload_thread, ParticleApi particle_api)
369
{
370 371
    renderer->pixels_per_unit = global_pixels_per_unit;
    renderer->frame_lock = 0;
372 373 374 375 376 377 378 379 380

    renderer->render.uniform_buffers = push_array(&renderer->ubo_arena, global_max_uniform_buffers, UniformBuffer*);

    for(i32 i = 0; i < global_max_uniform_buffers; i++)
    {
        renderer->render.uniform_buffers[i] = push_struct(&renderer->ubo_arena, UniformBuffer);
    }

    rendering::UniformBufferLayout vp_ubo_layout = {};
381 382 383
    rendering::initialize_ubo_layout(vp_ubo_layout);
    rendering::add_value_to_ubo_layout(vp_ubo_layout, rendering::ValueType::MAT4, "projection", renderer);
    rendering::add_value_to_ubo_layout(vp_ubo_layout, rendering::ValueType::MAT4, "view", renderer);
384 385 386 387 388
    rendering::register_ubo_layout(vp_ubo_layout, rendering::UniformBufferMappingType::VP, renderer);

    renderer->render.mapped_ubos[(i32)rendering::UniformBufferMappingType::VP] = rendering::create_uniform_buffer(rendering::BufferUsage::DYNAMIC, vp_ubo_layout, renderer);

    rendering::UniformBufferLayout point_layout = {};
389
    rendering::initialize_ubo_layout(point_layout);
390 391 392 393 394 395 396 397 398 399 400 401 402

    rendering::begin_struct_ubo_array_value(point_layout, rendering::UniformBufferMappingType::POINT, global_max_point_lights, "PointLight", renderer); 
    
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT3, "position", renderer);    
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT3, "ambient", renderer);
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT3, "diffuse", renderer);
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT3, "specular", renderer);
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT, "constant", renderer);
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT, "linear", renderer);
    rendering::add_value_to_ubo_layout(point_layout, rendering::ValueType::FLOAT, "quadratic", renderer);

    rendering::end_struct_ubo_value(renderer);
    
403 404 405 406 407
    rendering::register_ubo_layout(point_layout, rendering::UniformBufferMappingType::POINT, renderer);

    renderer->render.mapped_ubos[(i32)rendering::UniformBufferMappingType::POINT] = rendering::create_uniform_buffer(rendering::BufferUsage::DYNAMIC, point_layout, renderer);

    rendering::UniformBufferLayout directional_layout = {};
408
    rendering::initialize_ubo_layout(directional_layout);
409 410
    
    rendering::begin_struct_ubo_array_value(directional_layout, rendering::UniformBufferMappingType::DIRECTIONAL, global_max_directional_lights, "DirectionalLight", renderer);
411 412 413 414 415 416 417 418

    rendering::add_value_to_ubo_layout(directional_layout, rendering::ValueType::FLOAT3, "direction", renderer);
    rendering::add_value_to_ubo_layout(directional_layout, rendering::ValueType::FLOAT3, "ambient", renderer);
    rendering::add_value_to_ubo_layout(directional_layout, rendering::ValueType::FLOAT3, "diffuse", renderer);
    rendering::add_value_to_ubo_layout(directional_layout, rendering::ValueType::FLOAT3, "specular", renderer);

    rendering::end_struct_ubo_value(renderer);

419 420 421 422 423
    rendering::register_ubo_layout(directional_layout, rendering::UniformBufferMappingType::DIRECTIONAL, renderer);

    renderer->render.mapped_ubos[(i32)rendering::UniformBufferMappingType::DIRECTIONAL] = rendering::create_uniform_buffer(rendering::BufferUsage::DYNAMIC, directional_layout, renderer);

    rendering::UniformBufferLayout count_layout = {};
424 425 426
    rendering::initialize_ubo_layout(count_layout);
    rendering::add_value_to_ubo_layout(count_layout, rendering::ValueType::INTEGER, "dirlight_count", renderer);
    rendering::add_value_to_ubo_layout(count_layout, rendering::ValueType::INTEGER, "pointlight_count", renderer);
427 428 429 430
    rendering::register_ubo_layout(count_layout, rendering::UniformBufferMappingType::LIGHT_COUNTS, renderer);

    renderer->render.mapped_ubos[(i32)rendering::UniformBufferMappingType::LIGHT_COUNTS] = rendering::create_uniform_buffer(rendering::BufferUsage::DYNAMIC, count_layout, renderer);

Niels Bross's avatar
Niels Bross committed
431
    
432
    renderer->particles = {};
Niels Bross's avatar
Niels Bross committed
433

434
    renderer->particles._max_particle_system_count = global_max_particle_systems;
Niels Bross's avatar
Niels Bross committed
435

436 437
    renderer->particles.particle_systems = push_array(&renderer->particle_arena, global_max_particle_systems, ParticleSystemInfo);
    renderer->particles._internal_handles = push_array(&renderer->particle_arena, global_max_particle_systems, i32);
438
    renderer->particles._internal_work_queue_handles = push_array(&renderer->particle_arena, global_max_particle_systems, i32);
439 440 441
    renderer->particles.work_queues = push_array(&renderer->particle_arena, global_max_particle_systems, WorkQueue);
    renderer->particles.api = &particle_api;

442 443
    renderer->particles.system_work_queue = (WorkQueue*)malloc(sizeof(WorkQueue));
    renderer->particles.system_threads = push_array(&renderer->particle_arena, global_max_particle_systems, ThreadInfo);
Niels Bross's avatar
Niels Bross committed
444 445
    i32 particle_threads = 4;
    platform.make_queue(renderer->particles.system_work_queue, particle_threads, renderer->particles.system_threads);
446
    
447 448
    PushParams params = default_push_params();
    params.alignment = math::multiple_of_number_uint(member_size(RandomSeries, state), 16);
449 450
    renderer->particles.entropy = push_size(&renderer->particle_arena, sizeof(RandomSeries), RandomSeries, params);
    random_seed(*renderer->particles.entropy, 1234);
Niels Bross's avatar
Niels Bross committed
451 452

    for (i32 index = 0; index < global_max_particle_systems; index++)
453
    {
454
        renderer->particles._internal_handles[index] = -1;
455
        renderer->particles._internal_work_queue_handles[index] = -1;
456
    }
Niels Bross's avatar
Niels Bross committed
457

458
    renderer->particles.particle_system_count = 0;
459
    renderer->animation_controllers = push_array(&renderer->animation_arena, global_max_animation_controllers, AnimationController);
460
    renderer->spritesheet_animations = push_array(&renderer->animation_arena, global_max_spritesheet_animations, SpritesheetAnimation);
461
    
462
    renderer->render.textures = push_array(&renderer->texture_arena, global_max_textures, Texture*);
463 464 465

    for(i32 i = 0; i < global_max_textures; i++)
    {
466
        renderer->render.textures[i] = push_struct(&renderer->texture_arena, Texture);
467
    }
468 469
    renderer->render.texture_count = 0;

Daniel Bross's avatar
Daniel Bross committed
470
    // NEW RENDER PIPELINE
Daniel Bross's avatar
Daniel Bross committed
471 472
    //renderer.render.render_commands = push_array(&renderer.command_arena, global_max_render_commands, rendering::RenderCommand);
    //renderer.render.depth_free_commands = push_array(&renderer.command_arena, global_max_depth_free_commands, rendering::RenderCommand);
473
    renderer->render.shadow_commands = push_array(&renderer->command_arena, global_max_shadow_commands, rendering::ShadowCommand);
474
    renderer->render.pass_commands = push_array(&renderer->command_arena, 16, Pass);
475
    renderer->tt_font_infos = push_array(&renderer->font_arena, global_max_fonts, TrueTypeFontInfo);
Daniel Bross's avatar
Daniel Bross committed
476
    
477
    // NEW RENDER PIPELINE
478 479
    renderer->render.shadow_commands = push_array(&renderer->command_arena, global_max_shadow_commands, rendering::ShadowCommand);
    renderer->render.queued_commands = push_array(&renderer->command_arena, global_max_render_commands, QueuedRenderCommand);
Daniel Bross's avatar
Daniel Bross committed
480
    
481
    renderer->render.material_count = 0;
Niels Bross's avatar
Niels Bross committed
482

483 484
    renderer->render.passes = push_array(&renderer->render.render_pass_arena, global_max_render_commands, rendering::RenderPass);
    renderer->render.framebuffers = push_array(&renderer->render.render_pass_arena, global_max_framebuffers, rendering::FramebufferInfo);
Daniel Bross's avatar
Daniel Bross committed
485 486
    
    //@Incomplete: Make these dynamically allocated?
Daniel Bross's avatar
Daniel Bross committed
487

Niels Bross's avatar
Niels Bross committed
488 489
    renderer->render.directional_lights = push_array(&renderer->light_arena, global_max_directional_lights, DirectionalLight);
    renderer->render.point_lights = push_array(&renderer->light_arena, global_max_point_lights, PointLight);
Daniel Bross's avatar
Daniel Bross committed
490
    
Niels Bross's avatar
Niels Bross committed
491 492 493
    renderer->render.materials = push_array(&renderer->material_arena, global_max_materials, rendering::Material);
    renderer->render.material_instances = push_array(&renderer->material_arena, global_max_material_instances, rendering::Material);
    renderer->render._internal_material_instance_handles = push_array(&renderer->material_arena, global_max_material_instances, i32);
494 495
    renderer->render.current_material_instance_index = 0;
    renderer->render.material_instance_count = 0;
Niels Bross's avatar
Niels Bross committed
496 497

    renderer->render.loaded_meshes = push_array(&renderer->mesh_arena, global_max_meshes, Mesh);
498
    
Daniel Bross's avatar
Daniel Bross committed
499
    // Set all material instance values to their defaults
500
    for(i32 i = 0; i < global_max_material_instances; i++)
Daniel Bross's avatar
Daniel Bross committed
501
    {
502
        renderer->render._internal_material_instance_handles[i] = -1;
Daniel Bross's avatar
Daniel Bross committed
503
    }
Niels Bross's avatar
Niels Bross committed
504

505
    renderer->render.shaders = push_array(&renderer->mesh_arena, global_max_shaders, rendering::Shader);
506
    renderer->render.custom_mappings = push_array(&renderer->mesh_arena, MAX_CUSTOM_UNIFORM_MAPPINGS, rendering::CustomUniformMapping);
507 508
    renderer->render._internal_buffer_handles = push_array(&renderer->buffer_arena, global_max_custom_buffers, i32);
    renderer->render._current_internal_buffer_handle = 0;
509
    
Daniel Bross's avatar
Daniel Bross committed
510 511
    for(i32 index = 0; index < global_max_custom_buffers; index++)
    {
512
        renderer->render._internal_buffer_handles[index] = -1;
Daniel Bross's avatar
Daniel Bross committed
513
    }
Daniel Bross's avatar
Daniel Bross committed
514
    
515 516 517 518 519 520 521
    renderer->render.buffers = push_array(&renderer->buffer_arena, global_max_custom_buffers, Buffer*);

    for(i32 i = 0; i < global_max_custom_buffers; i++)
    {
        renderer->render.buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
    }
          
522
    renderer->render.removed_buffer_handles = push_array(&renderer->buffer_arena, global_max_custom_buffers, i32);
Daniel Bross's avatar
Daniel Bross committed
523 524

#if DEBUG
525 526
    renderer->render.shader_count = 0;
    renderer->render.shaders_to_reload_count = 0;
Daniel Bross's avatar
Daniel Bross committed
527 528
    *reload_queue = {};
    *reload_thread = {};
Niels Bross's avatar
Niels Bross committed
529

Daniel Bross's avatar
Daniel Bross committed
530
    make_queue(reload_queue, 1, reload_thread);
531
    platform.add_entry(reload_queue, check_shader_files, renderer);
Daniel Bross's avatar
Daniel Bross committed
532
#endif
Niels Bross's avatar
Niels Bross committed
533
    
Daniel Bross's avatar
Daniel Bross committed
534
    rendering::set_fallback_shader(renderer, "../engine_assets/standard_shaders/fallback.shd");
Daniel Bross's avatar
Daniel Bross committed
535
    rendering::set_wireframe_shader(renderer, "../engine_assets/standard_shaders/wireframe.shd");
536
    rendering::set_bounding_box_shader(renderer, "../engine_assets/standard_shaders/bounding_box.shd");
Daniel Bross's avatar
.  
Daniel Bross committed
537
    rendering::set_debug_line_shader(renderer, "../engine_assets/standard_shaders/line.shd");
Daniel Bross's avatar
Daniel Bross committed
538
    rendering::set_shadow_map_shader(renderer, "../engine_assets/standard_shaders/shadow_map.shd");
539 540
    // // rendering::set_light_space_matrices(renderer, math::ortho(-15, 15, -15, 15, 1, 20.0f), math::Vec3(-2.0f, 4.0f, -1.0f), math::Vec3(0.0f, 0.0f, 0.0f));
    // rendering::calculate_light_space_matrices(renderer, );
541

Niels Bross's avatar
Niels Bross committed
542 543
    renderer->render.bounding_box_buffer = rendering::create_bounding_box_buffer(renderer);

544 545
    rendering::set_bloom_shader(renderer, "../engine_assets/standard_shaders/bloom.shd");
    rendering::set_blur_shader(renderer, "../engine_assets/standard_shaders/blur.shd");
546
    rendering::set_hdr_shader(renderer, "../engine_assets/standard_shaders/hdr.shd");
Daniel Bross's avatar
Daniel Bross committed
547

Niels Bross's avatar
broken  
Niels Bross committed
548

549 550
    // Build render pipeline
    game.build_render_pipeline(platform, renderer);
Daniel Bross's avatar
Daniel Bross committed
551
    
Daniel Bross's avatar
Daniel Bross committed
552
    // UI
553 554 555 556 557 558 559 560 561
    renderer->render.ui.top_left_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::TOP | rendering::UIAlignment::LEFT, true);
    renderer->render.ui.top_right_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::TOP | rendering::UIAlignment::RIGHT, true);
    renderer->render.ui.bottom_left_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::BOTTOM | rendering::UIAlignment::LEFT, true);
    renderer->render.ui.bottom_right_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::BOTTOM | rendering::UIAlignment::RIGHT, true);
    renderer->render.ui.top_x_centered_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::TOP, true);
    renderer->render.ui.bottom_x_centered_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::BOTTOM, true);
    renderer->render.ui.left_y_centered_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::LEFT, true);
    renderer->render.ui.right_y_centered_textured_quad_buffer = rendering::create_quad_buffer(renderer, rendering::UIAlignment::RIGHT, true);
    renderer->render.ui.centered_textured_quad_buffer = rendering::create_quad_buffer(renderer, 0, true);
562

Niels Bross's avatar
Niels Bross committed
563
    rendering::create_ui_render_pass(renderer);
564
    
565 566 567 568
    renderer->render.ui_quad_shader = rendering::load_shader(renderer, "../engine_assets/standard_shaders/ui_quad.shd");
    renderer->render.textured_ui_quad_shader = rendering::load_shader(renderer, "../engine_assets/standard_shaders/ui_texture_quad.shd");
    renderer->render.ui.material = rendering::create_material(renderer, renderer->render.ui_quad_shader);
    renderer->render.ui.textured_material = rendering::create_material(renderer, renderer->render.textured_ui_quad_shader);
569
    
570
    // Initialize font material
571 572
    renderer->render.font_shader = rendering::load_shader(renderer, "../engine_assets/standard_shaders/font.shd");
    renderer->render.ui.font_material = rendering::create_material(renderer, renderer->render.font_shader);
573

574 575 576
    renderer->render.font3d_shader = rendering::load_shader(renderer, "../engine_assets/standard_shaders/3d_font.shd");
    renderer->render.ui.font3d_material = rendering::create_material(renderer, renderer->render.font3d_shader);

Niels Bross's avatar
Niels Bross committed
577 578 579 580 581 582 583
    rendering::RegisterBufferInfo line_info = rendering::create_register_buffer_info();

    add_vertex_attrib(rendering::ValueType::FLOAT3, line_info);
    line_info.usage = rendering::BufferUsage::DYNAMIC;

    renderer->render.line_buffer = rendering::register_buffer(renderer, line_info);
    
584 585 586 587 588
    rendering::RegisterBufferInfo font_info = rendering::create_register_buffer_info();

    add_vertex_attrib(rendering::ValueType::FLOAT4, font_info);
    font_info.usage = rendering::BufferUsage::DYNAMIC;

589
    renderer->render.ui.font_buffer = rendering::register_buffer(renderer, font_info);
590

591 592 593 594
    // Create opaque and transparent passes
    // Set same framebuffer
    // If in editor blit into texture and render into scene view
    // If in game-mode blit to final framebuffer
Daniel Bross's avatar
Daniel Bross committed
595
    
596 597 598 599 600
    renderer->render.instancing.internal_float_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, Buffer*);
    renderer->render.instancing.internal_float2_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, Buffer*);
    renderer->render.instancing.internal_float3_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, Buffer*);
    renderer->render.instancing.internal_float4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, Buffer*);
    renderer->render.instancing.internal_mat4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, Buffer*);
Daniel Bross's avatar
Daniel Bross committed
601

602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625
    renderer->render.instancing.dirty_float_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.dirty_float2_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.dirty_float3_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.dirty_float4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.dirty_mat4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);

    renderer->render.instancing.free_float_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.free_float2_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.free_float3_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.free_float4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);
    renderer->render.instancing.free_mat4_buffers = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, b32);

    renderer->render.instancing.float_buffer_counts = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float2_buffer_counts = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float3_buffer_counts = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float4_buffer_counts = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.mat4_buffer_counts = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);

    renderer->render.instancing.float_buffer_max = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float2_buffer_max = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float3_buffer_max = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.float4_buffer_max = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);
    renderer->render.instancing.mat4_buffer_max = push_array(&renderer->buffer_arena, MAX_INSTANCE_BUFFERS, i32);

Daniel Bross's avatar
Daniel Bross committed
626 627
    for(i32 i = 0; i < MAX_INSTANCE_BUFFERS; i++)
    {
628 629 630 631 632
        renderer->render.instancing.free_float_buffers[i] = true;
        renderer->render.instancing.free_float2_buffers[i] = true;
        renderer->render.instancing.free_float3_buffers[i] = true;
        renderer->render.instancing.free_float4_buffers[i] = true;
        renderer->render.instancing.free_mat4_buffers[i] = true;
633 634 635 636 637 638
        
        renderer->render.instancing.dirty_float_buffers[i] = false;
        renderer->render.instancing.dirty_float2_buffers[i] = false;
        renderer->render.instancing.dirty_float3_buffers[i] = false;
        renderer->render.instancing.dirty_float4_buffers[i] = false;
        renderer->render.instancing.dirty_mat4_buffers[i] = false;
639 640 641 642 643 644

        renderer->render.instancing.internal_float_buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
        renderer->render.instancing.internal_float2_buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
        renderer->render.instancing.internal_float3_buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
        renderer->render.instancing.internal_float4_buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
        renderer->render.instancing.internal_mat4_buffers[i] = push_struct(&renderer->buffer_arena, Buffer);
Daniel Bross's avatar
Daniel Bross committed
645
    }
646 647

    TemporaryMemory temp_mem = begin_temporary_memory(&renderer->buffer_arena);
Daniel Bross's avatar
Daniel Bross committed
648
    
649 650
    rendering::RegisterBufferInfo particle_buffer = rendering::create_register_buffer_info();
    particle_buffer.usage = rendering::BufferUsage::STATIC;
Daniel Bross's avatar
Daniel Bross committed
651
    add_vertex_attrib(rendering::ValueType::FLOAT3, particle_buffer);
652

653
    i32 vertex_size = 3;
654
    particle_buffer.data.vertex_count = 4;
655
    particle_buffer.data.vertex_buffer_size = particle_buffer.data.vertex_count * vertex_size * (i32)(sizeof(r32));
656
    particle_buffer.data.vertex_buffer = push_size(&renderer->buffer_arena, particle_buffer.data.vertex_buffer_size, r32);
657 658 659 660 661 662 663 664 665 666
        
    r32 quad_vertices[12] =
        {
            -0.5f, 0.5f, 0.0f,
            0.5f, 0.5f, 0.0f,
            0.5f, -0.5f, 0.0f,
            -0.5f, -0.5f, 0.0f,
        };
    
    for(i32 i = 0; i < particle_buffer.data.vertex_count * vertex_size; i++)
667 668 669 670 671 672 673 674
    {
        particle_buffer.data.vertex_buffer[i] = quad_vertices[i];
    }

    i32 index_count = 6;
    particle_buffer.data.index_buffer_size = index_count * (i32)sizeof(u16);
    particle_buffer.data.index_buffer_count = index_count;

675
    particle_buffer.data.index_buffer = push_size(&renderer->buffer_arena, particle_buffer.data.index_buffer_size, u16);
676 677 678 679 680 681 682 683 684 685 686

    u16 quad_indices[6] =
        {
            0, 1, 2,
            0, 2, 3};
    
    for (i32 i = 0; i < index_count; i++)
    {
        particle_buffer.data.index_buffer[i] = quad_indices[i];
    }

687
    renderer->particles.quad_buffer = rendering::register_buffer(renderer, particle_buffer);
688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
    
    add_vertex_attrib(rendering::ValueType::FLOAT2, particle_buffer);
    
    r32 textured_quad_vertices[20] =
    {
        -0.5f, 0.5f, 0.0f, 0.0f, 0.0f,
        0.5f, 0.5f, 0.0f, 1.0f, 0.0f,
        0.5f, -0.5f, 0.0f, 1.0f, 1.0f,
        -0.5f, -0.5f, 0.0f, 0.0f, 1.0f
    };

    vertex_size = 5;
    particle_buffer.data.vertex_buffer_size = particle_buffer.data.vertex_count * vertex_size * (i32)sizeof(r32);
    particle_buffer.data.vertex_buffer = push_size(&renderer->buffer_arena, particle_buffer.data.vertex_buffer_size, r32);

    for (i32 i = 0; i < particle_buffer.data.vertex_count * vertex_size; i++)
    {
        particle_buffer.data.vertex_buffer[i] = textured_quad_vertices[i];
    }

    renderer->particles.textured_quad_buffer = rendering::register_buffer(renderer, particle_buffer);
709
    
710
    end_temporary_memory(temp_mem);
711 712
}

713 714 715
#if defined(_WIN32) && !defined(DEBUG)
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
#else
Niels Bross's avatar
Niels Bross committed
716
int main(int argc, char **args)
717
#endif
Niels Bross's avatar
Niels Bross committed
718
{
Niels Bross's avatar
Niels Bross committed
719
    GameMemory game_memory = {};
Niels Bross's avatar
Niels Bross committed
720

Niels Bross's avatar
Niels Bross committed
721
    game_memory.should_reload = true;
Niels Bross's avatar
Niels Bross committed
722