From 5b9e7ac7e47c59db5e2dec41d15587ab9ca10606 Mon Sep 17 00:00:00 2001 From: kichikuou Date: Sat, 26 Nov 2022 13:47:40 +0900 Subject: [PATCH] ReignEngine: Correctly mark transparent materials There are two types of transparent materials: materials that have an alpha map and materials that have a color map with an alpha channel. This change makes the latter to be considered transparent. --- src/3d/3d_internal.h | 1 + src/3d/model.c | 19 ++++++++++++------- src/3d/renderer.c | 4 ++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/3d/3d_internal.h b/src/3d/3d_internal.h index c7892c5..577b50c 100644 --- a/src/3d/3d_internal.h +++ b/src/3d/3d_internal.h @@ -57,6 +57,7 @@ struct mesh { struct material { uint32_t flags; + bool is_transparent; GLuint color_map; GLuint specular_map; GLuint alpha_map; diff --git a/src/3d/model.c b/src/3d/model.c index 8c2918b..15ac432 100644 --- a/src/3d/model.c +++ b/src/3d/model.c @@ -58,7 +58,7 @@ struct archive_data *RE_get_aar_entry(struct archive *aar, const char *dir, cons return dfile; } -static GLuint load_texture(struct archive *aar, const char *path, const char *name) +static GLuint load_texture(struct archive *aar, const char *path, const char *name, bool *has_alpha_out) { struct archive_data *dfile = RE_get_aar_entry(aar, path, name, ""); if (!dfile) { @@ -83,6 +83,8 @@ static GLuint load_texture(struct archive *aar, const char *path, const char *na glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); + if (has_alpha_out) + *has_alpha_out = cg->metrics.has_alpha; cg_free(cg); return texture; } @@ -94,18 +96,21 @@ static bool init_material(struct material *material, const struct pol_material * WARNING("No color texture"); return false; } - material->color_map = load_texture(aar, path, m->textures[COLOR_MAP]); + bool has_alpha; + material->color_map = load_texture(aar, path, m->textures[COLOR_MAP], &has_alpha); if (!material->color_map) return false; if (m->textures[SPECULAR_MAP]) - material->specular_map = load_texture(aar, path, m->textures[SPECULAR_MAP]); + material->specular_map = load_texture(aar, path, m->textures[SPECULAR_MAP], NULL); if (m->textures[ALPHA_MAP]) - material->alpha_map = load_texture(aar, path, m->textures[ALPHA_MAP]); + material->alpha_map = load_texture(aar, path, m->textures[ALPHA_MAP], NULL); if (m->textures[LIGHT_MAP]) - material->light_map = load_texture(aar, path, m->textures[LIGHT_MAP]); + material->light_map = load_texture(aar, path, m->textures[LIGHT_MAP], NULL); if (m->textures[NORMAL_MAP]) - material->normal_map = load_texture(aar, path, m->textures[NORMAL_MAP]); + material->normal_map = load_texture(aar, path, m->textures[NORMAL_MAP], NULL); + + material->is_transparent = has_alpha || material->alpha_map; struct amt_material *amt_m = amt ? amt_find_material(amt, m->name) : NULL; if (amt_m) { @@ -442,7 +447,7 @@ struct model *model_load(struct archive *aar, const char *path) } } for (int i = 0; i < model->nr_materials; i++) { - if (model->materials[i].alpha_map) { + if (model->materials[i].is_transparent) { model->has_transparent_material = true; break; } diff --git a/src/3d/renderer.c b/src/3d/renderer.c index ee0fd49..7d74aab 100644 --- a/src/3d/renderer.c +++ b/src/3d/renderer.c @@ -319,7 +319,7 @@ static void render_model(struct RE_instance *inst, struct RE_renderer *r, enum d for (int i = 0; i < model->nr_meshes; i++) { struct mesh *mesh = &model->meshes[i]; struct material *material = &model->materials[mesh->material]; - bool is_transparent = material->alpha_map || inst->alpha < 1.0f; + bool is_transparent = material->is_transparent || inst->alpha < 1.0f; if (phase != (is_transparent ? DRAW_TRANSPARENT : DRAW_OPAQUE)) continue; @@ -858,7 +858,7 @@ void RE_render(struct sact_sprite *sp) continue; render_instance(inst, r, view_transform, DRAW_OPAQUE); } - // Render transparent instances, from nearest to farthest. + // Render transparent instances, from farthest to nearest. for (int i = 0; i < plugin->nr_instances; i++) { struct RE_instance *inst = sorted_instances[i]; if (!inst)