236 lines
5.9 KiB
C
236 lines
5.9 KiB
C
|
void
|
||
|
DEBUG_startup(void)
|
||
|
{
|
||
|
g_debug = persistent_mem_alloc(&g_memory->debug, 1, sizeof(*g_debug));
|
||
|
}
|
||
|
|
||
|
char*
|
||
|
DEBUG_load_shader(const char* path, size_t* size)
|
||
|
{
|
||
|
SDL_RWops* ops = SDL_RWFromFile(path, "r");
|
||
|
if (ops == NULL)
|
||
|
{
|
||
|
LOG_ERROR("Error opening file %s: %s", path, SDL_GetError());
|
||
|
exit(EXIT_FAILURE);
|
||
|
}
|
||
|
|
||
|
Sint64 file_size = SDL_RWsize(ops);
|
||
|
if (size < 0) {
|
||
|
LOG_ERROR("Error getting size of file %s: %s", path, SDL_GetError());
|
||
|
}
|
||
|
|
||
|
char* buf = scratch_mem_alloc(1, file_size);
|
||
|
|
||
|
size_t items_read = SDL_RWread(ops, buf, file_size, 1);
|
||
|
if (items_read != 1) {
|
||
|
LOG_ERROR("Error reading file %s: %s", path, SDL_GetError());
|
||
|
}
|
||
|
|
||
|
int ret = SDL_RWclose(ops);
|
||
|
if (ret != 0) {
|
||
|
LOG_ERROR("Error closing file %s: %s", path, SDL_GetError());
|
||
|
}
|
||
|
|
||
|
*size = (size_t)file_size;
|
||
|
|
||
|
return buf;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DEBUG_reload_shaders(render_mgr_t* in)
|
||
|
{
|
||
|
glUseProgram(0);
|
||
|
|
||
|
{
|
||
|
struct stat attrib;
|
||
|
stat("shaders/geo.glsl", &attrib);
|
||
|
time_t mod_time = attrib.st_mtime;
|
||
|
if (mod_time != g_debug->render_mgr.geo)
|
||
|
{
|
||
|
LOG_DEBUG("Reloading geo.glsl");
|
||
|
glDeleteProgram(in->geo.shader);
|
||
|
|
||
|
size_t size;
|
||
|
char* buf = DEBUG_load_shader("shaders/geo.glsl", &size);
|
||
|
|
||
|
in->geo.shader = create_shader(buf, size);
|
||
|
g_debug->render_mgr.geo = mod_time;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
struct stat attrib;
|
||
|
stat("shaders/screen.glsl", &attrib);
|
||
|
time_t mod_time = attrib.st_mtime;
|
||
|
if (mod_time != g_debug->render_mgr.screen)
|
||
|
{
|
||
|
LOG_DEBUG("Reloading screen.glsl");
|
||
|
glDeleteProgram(in->screen.shader);
|
||
|
|
||
|
size_t size;
|
||
|
char* buf = DEBUG_load_shader("shaders/screen.glsl", &size);
|
||
|
|
||
|
in->screen.shader = create_shader(buf, size);
|
||
|
g_debug->render_mgr.screen = mod_time;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
{
|
||
|
struct stat attrib;
|
||
|
stat("shaders/text.glsl", &attrib);
|
||
|
time_t mod_time = attrib.st_mtime;
|
||
|
if (mod_time != g_debug->render_mgr.text)
|
||
|
{
|
||
|
LOG_DEBUG("Reloading text.glsl");
|
||
|
glDeleteProgram(in->text.shader);
|
||
|
|
||
|
size_t size;
|
||
|
char* buf = DEBUG_load_shader("shaders/text.glsl", &size);
|
||
|
|
||
|
in->text.shader = create_shader(buf, size);
|
||
|
g_debug->render_mgr.text = mod_time;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DEBUG_reload_data1(void)
|
||
|
{
|
||
|
const char* path = "../../assets/processed/data1.bin";
|
||
|
|
||
|
struct stat attrib;
|
||
|
stat(path, &attrib);
|
||
|
time_t mod_time = attrib.st_mtime;
|
||
|
if (mod_time != g_debug->data_loader.data1)
|
||
|
{
|
||
|
LOG_DEBUG("Reloading data1.bin");
|
||
|
g_debug->data_loader.data1 = mod_time;
|
||
|
|
||
|
// Delay briefly to ensure file has been fully written
|
||
|
SDL_Delay(100);
|
||
|
|
||
|
// Free old GPU data
|
||
|
for (size_t i = 0; i < g_engine->asset_mgr.meshes.count; i++)
|
||
|
{
|
||
|
mesh_t* mesh = &g_engine->asset_mgr.meshes.data[i];
|
||
|
|
||
|
glBindVertexArray(0);
|
||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||
|
glDeleteBuffers(1, &mesh->vbo);
|
||
|
glDeleteBuffers(1, &mesh->ebo);
|
||
|
glDeleteVertexArrays(1, &mesh->vao);
|
||
|
}
|
||
|
|
||
|
for (size_t i = 0; i < g_engine->asset_mgr.materials.count; i++)
|
||
|
{
|
||
|
material_t* material = &g_engine->asset_mgr.materials.data[i];
|
||
|
|
||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||
|
glDeleteTextures(1, &material->texture);
|
||
|
}
|
||
|
|
||
|
// Reset
|
||
|
// TODO: Do this automatically so that adding new fields to the asset_mgr doesn't require changing this
|
||
|
hash_reset(&g_engine->asset_mgr.meshes.hash);
|
||
|
hash_reset(&g_engine->asset_mgr.materials.hash);
|
||
|
hash_reset(&g_engine->asset_mgr.cameras.hash);
|
||
|
g_engine->asset_mgr.meshes.count = 0;
|
||
|
g_engine->asset_mgr.materials.count = 0;
|
||
|
g_engine->asset_mgr.transforms.count = 0;
|
||
|
g_engine->asset_mgr.cameras.count = 0;
|
||
|
g_engine->asset_mgr.renderables.count = 0;
|
||
|
g_engine->asset_mgr.colliders.count = 0;
|
||
|
g_engine->asset_mgr.lights.count = 0;
|
||
|
persistent_mem_reset(&g_memory->data1);
|
||
|
|
||
|
load_data1(path);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DEBUG_camera_toggle(void)
|
||
|
{
|
||
|
if (g_debug->camera.enabled)
|
||
|
{
|
||
|
g_debug->camera.enabled = false;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
g_debug->camera.enabled = true;
|
||
|
|
||
|
camera_t* camera = get_active_camera();
|
||
|
transform_t* transform = get_transform(camera->transform);
|
||
|
|
||
|
// Copy existing camera's info so that debug camera starts from that position
|
||
|
g_debug->camera.fly = *camera;
|
||
|
g_debug->camera.transform = *transform;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
DEBUG_camera_update(float dt, input_t input)
|
||
|
{
|
||
|
// Keep all this logic local to this one debug function so we don't pollute
|
||
|
// the non-debug functions which use real transform handles
|
||
|
|
||
|
vec3 velocity = {0};
|
||
|
if (input.forward) {
|
||
|
velocity.y = 1.0f;
|
||
|
} else if (input.backward) {
|
||
|
velocity.y = -1.0f;
|
||
|
}
|
||
|
|
||
|
if (input.strafe_left) {
|
||
|
velocity.x = -1.0f;
|
||
|
} else if (input.strafe_right) {
|
||
|
velocity.x = 1.0f;
|
||
|
}
|
||
|
|
||
|
if (input.debug.up) {
|
||
|
velocity.z = 1.0f;
|
||
|
} else if (input.debug.down) {
|
||
|
velocity.z = -1.0f;
|
||
|
}
|
||
|
|
||
|
float speed_multiplier = 1.0f;
|
||
|
|
||
|
if (input.debug.speed) {
|
||
|
speed_multiplier = 2.5f;
|
||
|
}
|
||
|
|
||
|
float speed = dt * PLAYER_SPEED * speed_multiplier;
|
||
|
velocity = vec3_mult(vec3_normalize(velocity), speed);
|
||
|
|
||
|
float mouse_offset_x = -1.0f * input.mouse_x_delta * CAMERA_SENSITIVITY;
|
||
|
float mouse_offset_y = -1.0f * input.mouse_y_delta * CAMERA_SENSITIVITY;
|
||
|
|
||
|
camera_t* camera = &g_debug->camera.fly;
|
||
|
transform_t* transform = &g_debug->camera.transform;
|
||
|
|
||
|
// Move
|
||
|
transform->position = vec3_add(transform->position, vec3_mult(camera->front, velocity.y));
|
||
|
camera->right = vec3_cross(camera->front, WORLD_UP);
|
||
|
transform->position = vec3_add(transform->position, vec3_mult(vec3_normalize(camera->right), velocity.x));
|
||
|
transform->position = vec3_add(transform->position, vec3_mult(WORLD_UP, velocity.z));
|
||
|
|
||
|
// Rotate
|
||
|
camera_rotate(camera, mouse_offset_x, mouse_offset_y);
|
||
|
|
||
|
// Update view
|
||
|
vec3 target = vec3_add(transform->position, camera->front);
|
||
|
vec3 front = vec3_normalize(vec3_sub(target, transform->position));
|
||
|
vec3 side = vec3_normalize(vec3_cross(front, WORLD_UP));
|
||
|
vec3 up = vec3_cross(side, front);
|
||
|
|
||
|
mat4 view_mat = {
|
||
|
side.x, side.y, side.z, -vec3_dot(transform->position, side),
|
||
|
up.x, up.y, up.z, -vec3_dot(transform->position, up),
|
||
|
front.x, front.y, front.z, -vec3_dot(transform->position, front),
|
||
|
0.0f, 0.0f, 0.0f, 1.0f
|
||
|
};
|
||
|
|
||
|
camera->view_mat = view_mat;
|
||
|
}
|
||
|
|