From 87cc7e771ff8eb48eb779889c127b914873cc3eb Mon Sep 17 00:00:00 2001 From: korenkonder Date: Sat, 31 May 2025 02:28:03 +0300 Subject: [PATCH] Added Alpha Order in Reflect --- src/DivaGL/mdl/disp_manager.cpp | 171 ++++++++++++++++++++++++++------ src/DivaGL/mdl/disp_manager.hpp | 5 +- src/DivaGL/render.cpp | 8 +- src/DivaGL/render.hpp | 4 +- src/DivaGL/render_manager.cpp | 127 ++++++++++++++++++++++-- 5 files changed, 271 insertions(+), 44 deletions(-) diff --git a/src/DivaGL/mdl/disp_manager.cpp b/src/DivaGL/mdl/disp_manager.cpp index d2b372e..8614748 100644 --- a/src/DivaGL/mdl/disp_manager.cpp +++ b/src/DivaGL/mdl/disp_manager.cpp @@ -2185,6 +2185,12 @@ namespace mdl { case OBJ_TYPE_SSS: func = draw_sub_mesh_sss; + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + break; + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_GLITTER: + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT: + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_OPAQUE: if (reflect_draw) rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; @@ -2194,6 +2200,9 @@ namespace mdl { alpha_test = 1; min_alpha = 0.1f; alpha_threshold = 0.5f; + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_GLITTER: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT: @@ -2203,6 +2212,9 @@ namespace mdl { alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.0f; + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_USER: func = draw_sub_mesh_no_mat; @@ -2269,30 +2281,45 @@ namespace mdl { break; case OBJ_TYPE_REFLECT_OPAQUE: if (reflect_draw) - rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; case OBJ_TYPE_REFLECT_TRANSLUCENT: if (reflect_draw) - rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); rend_data_ctx.state.set_depth_mask(GL_TRUE); break; case OBJ_TYPE_REFLECT_TRANSPARENT: if (reflect_draw) - rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; case OBJ_TYPE_REFRACT_TRANSLUCENT: if (reflect_draw) - rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + rend_data_ctx.state.set_cull_face_mode(GL_BACK); rend_data_ctx.state.set_depth_mask(GL_TRUE); break; case OBJ_TYPE_SSS: if (reflect_draw) rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_GLITTER: + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT: + case OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_OPAQUE: + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_BACK); + break; + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_GLITTER: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT: + case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_OPAQUE: + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_BACK); + break; case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_GLITTER: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_OPAQUE: rend_data_ctx.state.set_depth_mask(GL_TRUE); + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_BACK); break; } @@ -2305,7 +2332,7 @@ namespace mdl { } void DispManager::draw(render_data_context& rend_data_ctx, mdl::ObjTypeLocal type, - const cam_data& cam, int32_t depth_mask, bool reflect_texture_mask) { + const cam_data& cam, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) { if (type < 0 || type >= OBJ_TYPE_LOCAL_MAX || get_obj_count(type) < 1) return; @@ -2338,28 +2365,77 @@ namespace mdl { min_alpha = 0.1f; alpha_threshold = 0.5f; break; + case OBJ_TYPE_LOCAL_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + break; + case OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT: + rend_data_ctx.state.set_depth_mask(GL_FALSE); + + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_FRONT); + break; } rend_data_ctx.set_batch_alpha_threshold(alpha_threshold); rend_data_ctx.set_batch_min_alpha(min_alpha); rend_data_ctx.shader_flags.arr[U_ALPHA_TEST] = alpha_test; - for (ObjData*& i : get_obj_list(type)) { - switch (i->kind) { - case OBJ_KIND_NORMAL: { - draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); - } break; - case OBJ_KIND_TRANSLUCENT: { - for (int32_t j = 0; j < i->args.translucent.count; j++) - draw_sub_mesh(rend_data_ctx, i->args.translucent.sub_mesh[j], &i->mat, func, cam); - } break; + if (alpha < 0) + for (ObjData*& i : get_obj_list(type)) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (int32_t j = 0; j < i->args.translucent.count; j++) + draw_sub_mesh(rend_data_ctx, i->args.translucent.sub_mesh[j], &i->mat, func, cam); + } break; + } + } + else + for (ObjData*& i : get_obj_list(type)) { + switch (i->kind) { + case OBJ_KIND_NORMAL: { + int32_t a = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(rend_data_ctx, &i->args.sub_mesh, &i->mat, func, cam); + } break; + case OBJ_KIND_TRANSLUCENT: { + for (int32_t j = 0; j < i->args.translucent.count; j++) { + ObjSubMeshArgs* args = i->args.translucent.sub_mesh[j]; + int32_t a = (int32_t)(args->blend_color.w * 255.0f); + a = clamp_def(a, 0, 255); + if (a == alpha) + draw_sub_mesh(rend_data_ctx, args, &i->mat, func, cam); + } + } break; + } } - } switch (type) { case OBJ_TYPE_LOCAL_TRANSLUCENT: if (!depth_mask) rend_data_ctx.state.set_depth_mask(GL_TRUE); break; + case OBJ_TYPE_LOCAL_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT: + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_BACK); + break; + case OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT: + rend_data_ctx.state.set_depth_mask(GL_TRUE); + + if (reflect_draw) + rend_data_ctx.state.set_cull_face_mode(GL_BACK); + break; } rend_data_ctx.reset_shader_flags(); @@ -3168,7 +3244,7 @@ namespace mdl { translucent_args.count++; } - ObjData* data = alloc_obj_data(mdl::OBJ_KIND_TRANSLUCENT); + ObjData* data = alloc_obj_data(OBJ_KIND_TRANSLUCENT); if (data) { data->init_translucent(mat, translucent_args); DispManager::entry_list(OBJ_TYPE_TRANSLUCENT, data); @@ -3229,9 +3305,50 @@ namespace mdl { 0, 0, 0, 0, 0, 0); const obj_material_attrib_member attrib = material->material.attrib.m; - if (attrib.flag_28 || data->args.sub_mesh.blend_color.w >= 1.0f - && (attrib.punch_through || !(attrib.alpha_texture | attrib.alpha_material)) - && !sub_mesh->attrib.m.translucent) { + if ((obj_flags & mdl::OBJ_ALPHA_ORDER) && data->args.sub_mesh.blend_color.w < 1.0f) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + bool translucent = false; + if (!attrib.flag_28 && (!attrib.punch_through + && (attrib.alpha_texture || attrib.alpha_material) + || sub_mesh->attrib.m.translucent)) + translucent = true; + + if (translucent) { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_GLITTER); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_TRANSLUCENT) + entry_list(OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, data); + else; + } + else { + if (!attrib.punch_through) { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_GLITTER); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_TRANSLUCENT) + entry_list(OBJ_TYPE_LOCAL_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT, data); + else; + } + else { + if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_GLITTER); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_TRANSLUCENT) + entry_list(OBJ_TYPE_LOCAL_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT, data); + else; + } + } + } + } + else if (!attrib.flag_28 && (data->args.sub_mesh.blend_color.w < 1.0f + || !attrib.punch_through && attrib.alpha_texture | attrib.alpha_material + || sub_mesh->attrib.m.translucent)) { + if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { + if (!attrib.translucent_priority) + if (mesh->attrib.m.translucent_sort_by_radius + || obj_flags & mdl::OBJ_TRANSLUCENT_SORT_BY_RADIUS); + else + entry_list(OBJ_TYPE_LOCAL_TRANSLUCENT, data); + else if (translucent_priority_count < 40) + translucent_priority[translucent_priority_count++] = &data->args.sub_mesh; + } + } + else { if (attrib.punch_through) { if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) entry_list(OBJ_TYPE_LOCAL_TRANSPARENT, data); @@ -3242,15 +3359,9 @@ namespace mdl { } continue; } - else if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { - if (!attrib.translucent_priority) - entry_list(OBJ_TYPE_LOCAL_TRANSLUCENT, data); - else if (translucent_priority_count < 40) - translucent_priority[translucent_priority_count++] = &data->args.sub_mesh; - } } - if (!translucent_priority_count) + if (translucent_priority_count <= 0) continue; ObjTranslucentArgs translucent_args; @@ -3268,8 +3379,12 @@ namespace mdl { ObjData* data = alloc_obj_data(OBJ_KIND_TRANSLUCENT); if (data) { data->init_translucent(mat, translucent_args); - - entry_list(OBJ_TYPE_TRANSLUCENT, data); + if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_GLITTER); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_TRANSLUCENT) + entry_list(OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, data); + else if (obj_flags & mdl::OBJ_ALPHA_ORDER_POST_OPAQUE); + else + entry_list(OBJ_TYPE_LOCAL_TRANSLUCENT, data); } } diff --git a/src/DivaGL/mdl/disp_manager.hpp b/src/DivaGL/mdl/disp_manager.hpp index a7e42da..6bde3f9 100644 --- a/src/DivaGL/mdl/disp_manager.hpp +++ b/src/DivaGL/mdl/disp_manager.hpp @@ -83,6 +83,9 @@ namespace mdl { OBJ_TYPE_LOCAL_OPAQUE = 0, OBJ_TYPE_LOCAL_TRANSLUCENT, OBJ_TYPE_LOCAL_TRANSPARENT, + OBJ_TYPE_LOCAL_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT, + OBJ_TYPE_LOCAL_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT, + OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, OBJ_TYPE_LOCAL_MAX }; @@ -400,7 +403,7 @@ namespace mdl { void draw(render_data_context& rend_data_ctx, ObjType type, const cam_data& cam, int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); void draw(render_data_context& rend_data_ctx, ObjTypeLocal type, const cam_data& cam, - int32_t depth_mask = 0, bool reflect_texture_mask = true); + int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); void draw(render_data_context& rend_data_ctx, ObjTypeReflect type, const cam_data& cam, int32_t depth_mask = 0, bool reflect_texture_mask = true); void entry_list(ObjType type, ObjData* data); diff --git a/src/DivaGL/render.cpp b/src/DivaGL/render.cpp index d89dd5b..6ec1df9 100644 --- a/src/DivaGL/render.cpp +++ b/src/DivaGL/render.cpp @@ -1051,12 +1051,12 @@ namespace rndr { render_texture_free(tex, true); } - void Render::transparency_combine(render_data_context& rend_data_ctx, float_t alpha) { - transparency->combine(rend_data_ctx, rend_texture, alpha); + void Render::transparency_combine(render_data_context& rend_data_ctx, RenderTexture* rt, float_t alpha) { + transparency->combine(rend_data_ctx, rt, alpha); } - void Render::transparency_copy(render_data_context& rend_data_ctx) { - transparency->copy(rend_data_ctx, rend_texture[0].GetColorTex()); + void Render::transparency_copy(render_data_context& rend_data_ctx, RenderTexture* rt) { + transparency->copy(rend_data_ctx, rt->GetColorTex()); } void Render::update_res(bool set, int32_t base_downsample) { diff --git a/src/DivaGL/render.hpp b/src/DivaGL/render.hpp index 412c0e1..26b702d 100644 --- a/src/DivaGL/render.hpp +++ b/src/DivaGL/render.hpp @@ -200,8 +200,8 @@ namespace rndr { void set_screen_res(int32_t x_offset, int32_t y_offset, int32_t width, int32_t height); void take_ss(render_data_context& rend_data_ctx, texture* tex, bool vertical, float_t horizontal_offset); - void transparency_combine(render_data_context& rend_data_ctx, float_t alpha); - void transparency_copy(render_data_context& rend_data_ctx); + void transparency_combine(render_data_context& rend_data_ctx, RenderTexture* rt, float_t alpha); + void transparency_copy(render_data_context& rend_data_ctx, RenderTexture* rt); void update_res(bool set, int32_t base_downsample); private: diff --git a/src/DivaGL/render_manager.cpp b/src/DivaGL/render_manager.cpp index 551ac50..5b35828 100644 --- a/src/DivaGL/render_manager.cpp +++ b/src/DivaGL/render_manager.cpp @@ -74,9 +74,14 @@ static void draw_pass_3d_shadow_reset(render_data_context& rend_data_ctx); static void draw_pass_3d_shadow_set(render_data_context& rend_data_ctx, Shadow* shad); extern void draw_pass_3d_translucent(render_data_context& rend_data_ctx, mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam); +extern void draw_pass_3d_translucent(render_data_context& rend_data_ctx, + mdl::ObjTypeLocal opaque, mdl::ObjTypeLocal transparent, mdl::ObjTypeLocal translucent, cam_data& cam); static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent, cam_data& cam); +static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, + mdl::ObjTypeLocal opaque, mdl::ObjTypeLocal transparent, mdl::ObjTypeLocal translucent, cam_data& cam); static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type, cam_data& cam); +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjTypeLocal type, cam_data& cam); static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::RenderManager& render_manager); @@ -929,11 +934,16 @@ namespace rndr { rend_data_ctx.shader_flags.arr[U_STAGE_AMBIENT] = light_stage_ambient ? 1 : 0; if (alpha_z_sort) { - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT, 1, cam, field_31F); - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, 2, cam); - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_GLITTER, 1, cam, field_31F); - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, 1, cam, field_31F); - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_OPAQUE, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS, 2, cam); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_GLITTER, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, 1, cam, field_31F); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_OPAQUE, 1, cam, field_31F); } if (opaque_z_sort) @@ -1030,8 +1040,12 @@ namespace rndr { local_cam.calc_view_proj_mat(); rend_data_ctx.set_batch_scene_camera(local_cam); - if (alpha_z_sort) - disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, 1, local_cam); + if (alpha_z_sort) { + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, 1, local_cam); + disp_manager->obj_sort(rend_data_ctx, + mdl::OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, 1, local_cam); + } if (opaque_z_sort) disp_manager->obj_sort(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_OPAQUE, 0, local_cam); @@ -1042,6 +1056,11 @@ namespace rndr { disp_manager->draw(rend_data_ctx, mdl::OBJ_TYPE_LOCAL_TRANSLUCENT, local_cam); rend_data_ctx.state.disable_blend(); + draw_pass_3d_translucent(rend_data_ctx, + mdl::OBJ_TYPE_LOCAL_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT, + mdl::OBJ_TYPE_LOCAL_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT, + mdl::OBJ_TYPE_LOCAL_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, local_cam); + rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_LOCAL, local_cam); rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -1996,12 +2015,16 @@ static void draw_pass_3d_translucent(render_data_context& rend_data_ctx, rndr::Render* rend = render_get(); + extern bool reflect_full; + RenderTexture& rt = reflect_full && reflect_full_ptr + ? reflect_full_ptr->reflect_texture : rend->rend_texture[0]; + int32_t alpha_array[256]; int32_t count = draw_pass_3d_translucent_count_layers( alpha_array, opaque, transparent, translucent, cam); for (int32_t i = 0; i < count; i++) { int32_t alpha = alpha_array[i]; - rend->transparency_copy(rend_data_ctx); + rend->transparency_copy(rend_data_ctx, &rt); if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE] && disp_manager->get_obj_count(opaque)) disp_manager->draw(rend_data_ctx, opaque, cam, 0, true, alpha); if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT] && disp_manager->get_obj_count(transparent)) @@ -2011,7 +2034,39 @@ static void draw_pass_3d_translucent(render_data_context& rend_data_ctx, disp_manager->draw(rend_data_ctx, translucent, cam, 0, true, alpha); rend_data_ctx.state.disable_blend(); } - rend->transparency_combine(rend_data_ctx, (float_t)alpha * (float_t)(1.0 / 255.0)); + rend->transparency_combine(rend_data_ctx, &rt, (float_t)alpha * (float_t)(1.0 / 255.0)); + } +} + +static void draw_pass_3d_translucent(render_data_context& rend_data_ctx, + mdl::ObjTypeLocal opaque, mdl::ObjTypeLocal transparent, mdl::ObjTypeLocal translucent, cam_data& cam) { + if (disp_manager->get_obj_count(opaque) < 1 + && disp_manager->get_obj_count(transparent) < 1 + && disp_manager->get_obj_count(translucent) < 1) + return; + + rndr::Render* rend = render_get(); + + extern bool reflect_full; + RenderTexture& rt = reflect_full && reflect_full_ptr + ? reflect_full_ptr->reflect_texture : rend->rend_texture[0]; + + int32_t alpha_array[256]; + int32_t count = draw_pass_3d_translucent_count_layers( + alpha_array, opaque, transparent, translucent, cam); + for (int32_t i = 0; i < count; i++) { + int32_t alpha = alpha_array[i]; + rend->transparency_copy(rend_data_ctx, &rt); + if (render_manager.draw_pass_3d[DRAW_PASS_3D_OPAQUE] && disp_manager->get_obj_count(opaque)) + disp_manager->draw(rend_data_ctx, opaque, cam, 0, true, alpha); + if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSPARENT] && disp_manager->get_obj_count(transparent)) + disp_manager->draw(rend_data_ctx, transparent, cam, 0, true, alpha); + if (render_manager.draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT] && disp_manager->get_obj_count(translucent)) { + rend_data_ctx.state.enable_blend(); + disp_manager->draw(rend_data_ctx, translucent, cam, 0, true, alpha); + rend_data_ctx.state.disable_blend(); + } + rend->transparency_combine(rend_data_ctx, &rt, (float_t)alpha * (float_t)(1.0 / 255.0)); } } @@ -2032,6 +2087,23 @@ static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, return count; } +static int32_t draw_pass_3d_translucent_count_layers(int32_t* alpha_array, + mdl::ObjTypeLocal opaque, mdl::ObjTypeLocal transparent, mdl::ObjTypeLocal translucent, cam_data& cam) { + bool arr[0x100] = { false }; + + draw_pass_3d_translucent_has_objects(arr, opaque, cam); + draw_pass_3d_translucent_has_objects(arr, transparent, cam); + draw_pass_3d_translucent_has_objects(arr, translucent, cam); + + int32_t count = 0; + for (int32_t i = 0xFF; i >= 0; i--) + if (arr[i]) { + count++; + *alpha_array++ = i; + } + return count; +} + static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type, cam_data& cam) { disp_manager->calc_obj_radius(cam, type); for (mdl::ObjData*& i : disp_manager->get_obj_list(type)) @@ -2051,6 +2123,25 @@ static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjType type, c } } +static void draw_pass_3d_translucent_has_objects(bool* arr, mdl::ObjTypeLocal type, cam_data& cam) { + disp_manager->calc_obj_radius(cam, type); + for (mdl::ObjData*& i : disp_manager->get_obj_list(type)) + switch (i->kind) { + case mdl::OBJ_KIND_NORMAL: { + int32_t alpha = (int32_t)(i->args.sub_mesh.blend_color.w * 255.0f); + alpha = clamp_def(alpha, 0, 255); + arr[alpha] = true; + } break; + case mdl::OBJ_KIND_TRANSLUCENT: { + for (int32_t j = 0; j < i->args.translucent.count; j++) { + int32_t alpha = (int32_t)(i->args.translucent.sub_mesh[j]->blend_color.w * 255.0f); + alpha = clamp_def(alpha, 0, 255); + arr[alpha] = true; + } + } break; + } +} + static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::RenderManager& render_manager) { rend_data_ctx.state.begin_event("pass_reflect"); RenderTexture& refl_tex = reflect_full_ptr->reflect_texture; @@ -2139,6 +2230,11 @@ static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::Ren if (render_manager.npr_param == 1) render_manager.pass_3d_contour(rend_data_ctx); + draw_pass_3d_translucent(rend_data_ctx, + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_OPAQUE, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_OPAQUE, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_OPAQUE, reflect_cam); + rend_data_ctx.state.disable_depth_test(); rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); @@ -2166,12 +2262,25 @@ static void draw_pass_reflect_full(render_data_context& rend_data_ctx, rndr::Ren rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_POST_TRANSLUCENT, reflect_cam); rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + rend_data_ctx.state.set_depth_mask(GL_TRUE); + draw_pass_3d_translucent(rend_data_ctx, + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_TRANSLUCENT, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_TRANSLUCENT, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_TRANSLUCENT, reflect_cam); rend_data_ctx.state.disable_depth_test(); rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); Glitter::glt_particle_manager_x->DispScenes(rend_data_ctx, Glitter::DISP_NORMAL, reflect_cam); rend_data_ctx.state.set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + rend_data_ctx.state.enable_depth_test(); + rend_data_ctx.state.set_depth_mask(GL_TRUE); + draw_pass_3d_translucent(rend_data_ctx, + mdl::OBJ_TYPE_OPAQUE_ALPHA_ORDER_POST_GLITTER, + mdl::OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_POST_GLITTER, + mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_POST_GLITTER, reflect_cam); + rend_data_ctx.state.active_bind_texture_2d(14, 0); rend_data_ctx.state.active_bind_texture_2d(15, 0);