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/reign.c b/src/3d/reign.c index 85894ca..d432488 100644 --- a/src/3d/reign.c +++ b/src/3d/reign.c @@ -961,6 +961,9 @@ bool RE_back_cg_set_name(struct RE_back_cg *bcg, struct string *name, struct arc bcg->no = 0; gfx_delete_texture(&bcg->texture); + if (name->size == 0) // unload only. + return true; + char *cg_path = xmalloc(name->size + 5); sprintf(cg_path, "%s.bmp", name->text); struct archive_data *dfile = archive_get_by_name(aar, cg_path); diff --git a/src/3d/renderer.c b/src/3d/renderer.c index 570e4e7..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; @@ -464,6 +464,7 @@ static void render_billboard(struct RE_instance *inst, struct RE_renderer *r, ma break; } + glDepthFunc(GL_LEQUAL); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, bt->texture); glUniform1i(r->texture, 0); @@ -473,6 +474,7 @@ static void render_billboard(struct RE_instance *inst, struct RE_renderer *r, ma glBindVertexArray(0); glBindTexture(GL_TEXTURE_2D, 0); + glDepthFunc(GL_LESS); } static void render_billboard_particles(struct RE_renderer *r, struct RE_instance *inst, struct particle_object *po, float frame) @@ -856,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) diff --git a/src/hll/ReignEngine.c b/src/hll/ReignEngine.c index 1c849bd..bc16071 100644 --- a/src/hll/ReignEngine.c +++ b/src/hll/ReignEngine.c @@ -227,7 +227,7 @@ static bool ReignEngine_SetInstanceScaleZ(int plugin, int instance, float scale_ struct RE_instance *ri = get_instance(plugin, instance); if (!ri) return false; - ri->scale[0] = scale_z; + ri->scale[2] = scale_z; ri->local_transform_needs_update = true; return true; }