From dc174fa91c4da51c16d4ee76c7da84f8ce94683c Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 13 May 2023 11:27:45 +0900 Subject: [PATCH] DrawDungeon: Fix cell drawing order Transparent objects should be drawn in order from furthest to nearest. In DrawDungeon, the actual viewpoint is slightly behind the camera, but this was not taken into account when sorting cells by distance. Fixes #120 --- src/dungeon/dungeon.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/dungeon/dungeon.c b/src/dungeon/dungeon.c index 309a810..68ec3e7 100644 --- a/src/dungeon/dungeon.c +++ b/src/dungeon/dungeon.c @@ -244,7 +244,7 @@ void dungeon_set_camera(int surface, float x, float y, float z, float angle, flo ctx->camera.angle_p = angle_p * M_PI / 180; } -static void model_view_matrix(struct camera *camera, mat4 out) +static void model_view_matrix(struct camera *camera, vec3 eye_out, mat4 mv_out) { // The actual camera position is slightly behind camera->pos. float dist = 0.9; @@ -253,10 +253,9 @@ static void model_view_matrix(struct camera *camera, mat4 out) dist * sin(camera->angle_p), dist * -cos(camera->angle) * cos(camera->angle_p), }; - vec3 eye; - glm_vec3_sub(camera->pos, d, eye); + glm_vec3_sub(camera->pos, d, eye_out); vec3 up = {0.0, 1.0, 0.0}; - glm_lookat(eye, camera->pos, up, out); + glm_lookat(eye_out, camera->pos, up, mv_out); } static void dungeon_render(struct sact_sprite *sp) @@ -276,9 +275,10 @@ static void dungeon_render(struct sact_sprite *sp) glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); + vec3 eye; mat4 local_transform, view_transform, proj_transform; glm_mat4_identity(local_transform); - model_view_matrix(&ctx->camera, view_transform); + model_view_matrix(&ctx->camera, eye, view_transform); glm_perspective(M_PI / 3.0, (float)texture->w / texture->h, 0.5, 100.0, proj_transform); // Tweak the projection transform so that the rendering result is vertically @@ -288,9 +288,9 @@ static void dungeon_render(struct sact_sprite *sp) proj_transform[1][1] *= -1; glFrontFace(GL_CW); - int dgn_x = round(ctx->camera.pos[0] / 2.0); - int dgn_y = round(ctx->camera.pos[1] / 2.0); - int dgn_z = round(ctx->camera.pos[2] / -2.0); + int dgn_x = round(eye[0] / 2.0); + int dgn_y = round(eye[1] / 2.0); + int dgn_z = round(eye[2] / -2.0); int nr_cells; struct dgn_cell **cells = dgn_get_visible_cells(ctx->dgn, dgn_x, dgn_y, dgn_z, &nr_cells); dungeon_renderer_render(ctx->renderer, cells, nr_cells, view_transform, proj_transform);