diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index 6537a4bb..008e4ba4 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -12,6 +12,9 @@ extern render_context* rctx_ptr; +extern bool reflect_draw; +extern mat4 reflect_mat; + namespace Glitter { RenderScene::RenderScene() : ctrl_quad(), ctrl_line(), ctrl_locus(), ctrl_mesh(), disp_quad(), disp_line(), disp_locus(), disp_mesh() { @@ -1927,8 +1930,12 @@ namespace Glitter { if (!rend_group->vao || rend_group->disp < 1) return; + mat4 cam_view = rctx_ptr->camera->view; + if (reflect_draw) + mat4_mul(&reflect_mat, &cam_view, &cam_view); + mat4 mat; - mat4_mul(&rend_group->mat_draw, &rctx_ptr->camera->view, &mat); + mat4_mul(&rend_group->mat_draw, &cam_view, &mat); mat4_mul(&mat, &rctx_ptr->camera->projection, &mat); float_t emission = 1.0f; diff --git a/src/CRE/auth_3d.cpp b/src/CRE/auth_3d.cpp index 00d57558..b8ffe626 100644 --- a/src/CRE/auth_3d.cpp +++ b/src/CRE/auth_3d.cpp @@ -236,7 +236,7 @@ static auth_3d_detail::FrameRateTimeStop frame_rate_time_stop; extern render_context* rctx_ptr; auth_3d::auth_3d() : uid(), id(), mat(), enable(), camera_root_update(), visible(), repeat(), ended(), -left_right_reverse(), once(), alpha(), chara_id(), chara_item(), shadow(), pos(), frame_rate(), frame(), +left_right_reverse(), once(), alpha(), chara_id(), chara_item(), shadow(), reflect(), pos(), frame_rate(), frame(), req_frame(), max_frame(), frame_changed(), frame_offset(), last_frame(), paused(), event_time_next() { hash = hash_murmurhash_empty; src_chara = CHARA_MAX; @@ -457,6 +457,9 @@ void auth_3d::disp(render_context* rctx) { spr::put_rgb_cross(mat); auth_3d_set_material_list(this, rctx); + extern bool reflect_full; + extern bool reflect_draw; + reflect_draw = reflect_full && reflect; for (auth_3d_point& i : point) auth_3d_point_disp(&i, this, rctx); @@ -477,6 +480,7 @@ void auth_3d::disp(render_context* rctx) { if (i->active) i->Disp(this, &mat, rctx); + reflect_draw = false; rctx->disp_manager->set_material_list(); } @@ -754,6 +758,7 @@ void auth_3d::reset() { chara_id = -1; chara_item = false; shadow = false; + reflect = false; src_chara = CHARA_MAX; dst_chara = CHARA_MAX; pos = 0; @@ -2710,6 +2715,14 @@ void auth_3d_id::set_pos(int32_t value) { } } +void auth_3d_id::set_reflect(bool value) { + if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { + auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; + if (auth->id == id) + auth->reflect = value; + } +} + void auth_3d_id::set_repeat(bool value) { if (id >= 0 && ((id & 0x7FFF) < AUTH_3D_DATA_COUNT)) { auth_3d* auth = &auth_3d_data->data[id & 0x7FFF]; diff --git a/src/CRE/auth_3d.hpp b/src/CRE/auth_3d.hpp index 77aa1f09..75cfdc2d 100644 --- a/src/CRE/auth_3d.hpp +++ b/src/CRE/auth_3d.hpp @@ -840,6 +840,7 @@ struct auth_3d_id { void set_max_frame(float_t value); void set_paused(bool value); void set_pos(int32_t value); + void set_reflect(bool value); void set_repeat(bool value); void set_req_frame(float_t value); void set_shadow(bool value); @@ -888,6 +889,7 @@ struct auth_3d { int32_t chara_id; bool chara_item; bool shadow; + bool reflect; int32_t src_chara; int32_t dst_chara; int32_t pos; diff --git a/src/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp index d14b34fa..f5b55d74 100644 --- a/src/CRE/mdl/disp_manager.cpp +++ b/src/CRE/mdl/disp_manager.cpp @@ -13,6 +13,9 @@ extern render_context* rctx_ptr; +extern bool reflect_draw; +extern bool reflect_full; + static const GLuint POSITION_INDEX = 0; static const GLuint BONE_WEIGHT_INDEX = 1; static const GLuint NORMAL_INDEX = 2; @@ -1868,7 +1871,7 @@ namespace mdl { } ObjData* DispManager::alloc_obj_data(ObjKind kind) { - int32_t size = (int32_t)align_val(sizeof(ObjKind) + sizeof(mat4) + sizeof(float_t) * 2, 0x08); + int32_t size = (int32_t)align_val(sizeof(ObjKind) + sizeof(mat4) + sizeof(float_t), 0x08); switch (kind) { case OBJ_KIND_NORMAL: return (ObjData*)alloc_data(size + sizeof(ObjSubMeshArgs)); @@ -2030,6 +2033,7 @@ namespace mdl { func = draw_sub_mesh_translucent; else gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.0f; @@ -2055,13 +2059,15 @@ namespace mdl { func = draw_sub_mesh_translucent; gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); rctx->draw_state->shader_index = SHADER_FT_SIL; + alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.99999994f; break; case OBJ_TYPE_REFLECT_CHARA_OPAQUE: gl_state_set_cull_face_mode(GL_FRONT); - if (!sv_better_reflect) { + + if (!reflect_draw) { if (reflect) func = draw_sub_mesh_reflect; else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) @@ -2070,39 +2076,62 @@ namespace mdl { break; case OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT: gl_state_set_cull_face_mode(GL_FRONT); - if (!sv_better_reflect) { + + min_alpha = 0.0f; + + if (!reflect_draw) { if (reflect) func = draw_sub_mesh_reflect; else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) func = draw_sub_mesh_reflect_reflect_map; } - min_alpha = 0.0f; break; case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: gl_state_set_cull_face_mode(GL_FRONT); - if (!sv_better_reflect) { + + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + + if (!reflect_draw) { if (reflect) func = draw_sub_mesh_reflect; else if (rctx->render_manager->reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) func = draw_sub_mesh_reflect_reflect_map; } - alpha_test = 1; - min_alpha = 0.1f; - alpha_threshold = 0.5f; break; case OBJ_TYPE_REFLECT_OPAQUE: alpha_test = 1; alpha_threshold = 0.5f; - if (!reflect_texture_mask) + + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + else if (!reflect_texture_mask) func = draw_sub_mesh_reflect_reflect_map; break; case OBJ_TYPE_REFLECT_TRANSLUCENT: + gl_state_set_depth_mask(GL_FALSE); + + min_alpha = 0.0f; + alpha_threshold = 0.0f; + + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + break; + case OBJ_TYPE_REFLECT_TRANSPARENT: + alpha_test = 1; + min_alpha = 0.1f; + alpha_threshold = 0.5f; + + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + break; case OBJ_TYPE_REFRACT_TRANSLUCENT: gl_state_set_depth_mask(GL_FALSE); + min_alpha = 0.0f; alpha_threshold = 0.0f; break; - case OBJ_TYPE_REFLECT_TRANSPARENT: case OBJ_TYPE_REFRACT_TRANSPARENT: alpha_test = 1; min_alpha = 0.1f; @@ -2110,6 +2139,9 @@ namespace mdl { break; case OBJ_TYPE_SSS: func = draw_sub_mesh_sss; + + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); break; case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: @@ -2124,6 +2156,7 @@ namespace mdl { case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL: gl_state_set_depth_mask(GL_FALSE); + alpha_test = 1; min_alpha = 0.0f; alpha_threshold = 0.0f; @@ -2131,7 +2164,17 @@ namespace mdl { case OBJ_TYPE_USER: func = draw_sub_mesh_translucent; break; - default: + case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS: + if (depth_mask) + func = draw_sub_mesh_translucent; + else + gl_state_set_depth_mask(GL_FALSE); + + alpha_test = 1; + min_alpha = 0.0f; + alpha_threshold = 0.0f; + + gl_state_set_cull_face_mode(GL_FRONT); break; } rctx->set_batch_alpha_threshold(alpha_threshold); @@ -2180,8 +2223,6 @@ namespace mdl { switch (type) { case OBJ_TYPE_TRANSLUCENT: case OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS: - case OBJ_TYPE_REFLECT_TRANSLUCENT: - case OBJ_TYPE_REFRACT_TRANSLUCENT: if (!depth_mask) gl_state_set_depth_mask(GL_TRUE); break; @@ -2195,16 +2236,36 @@ namespace mdl { case OBJ_TYPE_REFLECT_CHARA_TRANSPARENT: gl_state_set_cull_face_mode(GL_BACK); break; - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_1: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2: - case OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3: - gl_state_set_cull_face_mode(GL_BACK); + case OBJ_TYPE_REFLECT_OPAQUE: + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + break; + case OBJ_TYPE_REFLECT_TRANSLUCENT: + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_REFLECT_TRANSPARENT: + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + break; + case OBJ_TYPE_REFRACT_TRANSLUCENT: + if (reflect_draw) + gl_state_set_cull_face_mode(GL_FRONT); + gl_state_set_depth_mask(GL_TRUE); + break; + case OBJ_TYPE_SSS: + if (reflect_draw) + gl_state_set_cull_face_mode(GL_BACK); break; case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2: case OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3: gl_state_set_depth_mask(GL_TRUE); break; + case OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS: + gl_state_set_cull_face_mode(GL_BACK); + break; } uniform_value_reset(); @@ -2246,29 +2307,6 @@ namespace mdl { }*/ void DispManager::entry_list(ObjType type, ObjData* data) { - if (sv_better_reflect && type == OBJ_TYPE_REFLECT_CHARA_OPAQUE && data->kind == OBJ_KIND_NORMAL) { - const obj_sub_mesh* sub_mesh = data->args.sub_mesh.sub_mesh; - const obj_material_data* material = data->args.sub_mesh.material; - obj_material_attrib_member attrib = material->material.attrib.m; - if (!(obj_flags & (mdl::OBJ_ALPHA_ORDER_1 | mdl::OBJ_ALPHA_ORDER_2 | mdl::OBJ_ALPHA_ORDER_3)) - || data->args.sub_mesh.blend_color.w >= 1.0f) { - 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 (attrib.punch_through && (obj_flags & mdl::OBJ_CHARA_REFLECT)) { - obj[OBJ_TYPE_REFLECT_CHARA_TRANSPARENT].push_back(data); - return; - } - } - else if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { - if (!attrib.translucent_priority && (obj_flags & mdl::OBJ_CHARA_REFLECT)) { - obj[OBJ_TYPE_REFLECT_CHARA_TRANSLUCENT].push_back(data); - return; - } - } - } - } - obj[type].push_back(data); } diff --git a/src/CRE/mdl/disp_manager.hpp b/src/CRE/mdl/disp_manager.hpp index 642bbe29..363c8a01 100644 --- a/src/CRE/mdl/disp_manager.hpp +++ b/src/CRE/mdl/disp_manager.hpp @@ -152,12 +152,13 @@ namespace mdl { OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_3, OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_3, OBJ_TYPE_USER, - OBJ_TYPE_OPAQUE_LOCAL, // X + OBJ_TYPE_OPAQUE_LOCAL, // X OBJ_TYPE_TRANSLUCENT_LOCAL, OBJ_TYPE_TRANSPARENT_LOCAL, OBJ_TYPE_OPAQUE_ALPHA_ORDER_2_LOCAL, OBJ_TYPE_TRANSPARENT_ALPHA_ORDER_2_LOCAL, OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_2_LOCAL, + OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, // Reflect OBJ_TYPE_MAX, }; diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index 32f2697e..38206612 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -26,6 +26,11 @@ #define REFLECT_STENCIL (1) +extern render_context* rctx_ptr; + +bool reflect_draw = false; +mat4 reflect_mat = mat4_identity; + static void draw_pass_shadow_begin_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); static void draw_pass_shadow_end_make_shadowmap(Shadow* shad, int32_t index, int32_t a3); static void draw_pass_shadow_filter(RenderTexture* a1, RenderTexture* a2, @@ -44,8 +49,11 @@ static int32_t draw_pass_3d_translucent_count_layers(render_context* rctx, mdl::ObjType transparent, mdl::ObjType translucent); static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr, mdl::ObjType type); +static void draw_pass_reflect_full(rndr::RenderManager* render_manager); #if REFLECT_STENCIL static void draw_pass_reflect_stencil(render_context* rctx, mdl::ObjType type); +static void draw_pass_reflect_make_stencil(render_context* rctx, + RenderTexture& refl_tex, RenderTexture& refl_buf_tex); #endif static void blur_filter_apply(render_context* rctx, RenderTexture* dst, RenderTexture* src, @@ -56,11 +64,6 @@ static void render_manager_init_render_textures(int32_t multisample); static void set_reflect_mat(render_context* rctx); -extern render_context* rctx_ptr; - -static bool reflect_enable = false; -static mat4 reflect_mat = mat4_identity; - namespace rndr { struct RenderTextureData { GLenum type; @@ -495,10 +498,11 @@ namespace rndr { gl_state_begin_event("pass_ss_sss"); rndr::Render* rend = render; - if (sv_better_reflect && reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP - && rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) { + extern bool reflect_full; + if ((reflect_full || sv_better_reflect && reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) + && pass_sw[rndr::RND_PASSID_REFLECT] && rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) { gl_state_begin_event("reflect"); - reflect_enable = true; + reflect_draw = true; rndr::Render* rend = render; RenderTexture& refl_tex = rctx->render_manager->get_render_texture(0); @@ -535,15 +539,11 @@ namespace rndr { set_reflect_mat(rctx); - uniform_value[U_REFLECT] = 1; - rctx->draw_state->shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_func(GL_LEQUAL); gl_state_set_depth_mask(GL_TRUE); - gl_state_set_cull_face_mode(GL_FRONT); rctx->disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_state_set_cull_face_mode(GL_BACK); gl_state_disable_depth_test(); rctx->draw_state->shader_index = -1; draw_pass_3d_shadow_reset(rctx); @@ -561,9 +561,7 @@ namespace rndr { rctx->draw_state->shader_index = SHADER_FT_SSS_SKIN; gl_state_enable_depth_test(); gl_state_set_depth_mask(GL_TRUE); - gl_state_set_cull_face_mode(GL_FRONT); rctx->disp_manager->draw(mdl::OBJ_TYPE_SSS); - gl_state_set_cull_face_mode(GL_BACK); gl_state_disable_depth_test(); rctx->draw_state->shader_index = -1; gl_state_bind_framebuffer(0); @@ -572,8 +570,6 @@ namespace rndr { } } - uniform_value[U_REFLECT] = 0; - if (!sss->npr_contour) { sss->textures[0].Bind(); gl_state_set_viewport(0, 0, 640, 360); @@ -600,7 +596,7 @@ namespace rndr { } draw_pass_sss_filter(rctx, sss); - reflect_enable = false; + reflect_draw = false; gl_state_end_event(); } @@ -690,6 +686,12 @@ namespace rndr { } void RenderManager::pass_reflect() { + extern bool reflect_full; + if (reflect_full) { + draw_pass_reflect_full(this); + return; + } + render_context* rctx = rctx_ptr; gl_state_begin_event("pass_reflect"); RenderTexture& refl_tex = rctx->render_manager->get_render_texture(0); @@ -716,54 +718,20 @@ namespace rndr { #endif if (sv_better_reflect && rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) glClear(GL_COLOR_BUFFER_BIT); - else #if REFLECT_STENCIL + else { + gl_state_set_stencil_mask(0xFF); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gl_state_set_stencil_mask(0x00); + } #else + else glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #endif #if REFLECT_STENCIL - if (sv_better_reflect) { - gl_state_set_stencil_mask(0xFF); - - rctx->draw_state->shader_index = SHADER_FT_SIL; - - gl_state_disable_depth_test(); - gl_state_set_depth_func(GL_LEQUAL); - gl_state_set_depth_mask(GL_TRUE); - - draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_OPAQUE); - draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSLUCENT); - draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS); - draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSPARENT); - - fbo_blit(refl_tex.fbos[0], refl_buf_tex.fbos[0], - 0, 0, refl_tex.GetWidth(), refl_tex.GetHeight(), - 0, 0, refl_buf_tex.GetWidth(), refl_buf_tex.GetHeight(), - GL_COLOR_BUFFER_BIT, GL_LINEAR); - - refl_tex.Bind(); - glClear(GL_COLOR_BUFFER_BIT); - - gl_state_enable_stencil_test(); - gl_state_set_stencil_op(GL_KEEP, GL_KEEP, GL_REPLACE); - gl_state_set_stencil_func(GL_ALWAYS, 0x01, 0x01); - - gl_state_bind_texture_2d(refl_buf_tex.GetColorTex()); - gl_state_bind_sampler(0, rctx->render_samplers[0]); - - gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - shaders_ft.set(SHADER_FT_REFLECT_STENCIL); - rctx->render.draw_quad(refl_buf_tex.GetWidth(), refl_buf_tex.GetHeight(), 1.0f, 1.0f, - 0.0f, 0.0f, 6.0f, 1.0f, 1.0f, 1.0f, 1.0f); - gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - - gl_state_set_stencil_op(GL_KEEP, GL_KEEP, GL_KEEP); - gl_state_set_stencil_func(GL_EQUAL, 0x01, 0x01); - - gl_state_set_stencil_mask(0x00); - } + if (sv_better_reflect) + draw_pass_reflect_make_stencil(rctx, refl_tex, refl_buf_tex); #endif rctx->draw_state->shader_index = SHADER_FT_S_REFL; @@ -787,7 +755,7 @@ namespace rndr { } if (sv_better_reflect && reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { - reflect_enable = true; + reflect_draw = true; rctx->draw_state->shader_index = -1; int32_t render_width = refl_tex.GetWidth(); @@ -843,7 +811,7 @@ namespace rndr { rctx->set_scene_framebuffer_size(render->render_width[0], render->render_height[0], render->render_width[0], render->render_height[0]); - reflect_enable = false; + reflect_draw = false; } else if (reflect_type == STAGE_DATA_REFLECT_REFLECT_MAP) { uniform_value[U_REFLECT] = reflect_tone_curve ? 1 : 0; @@ -1289,7 +1257,7 @@ namespace rndr { render_context* rctx = rctx_ptr; RenderTexture* rt; RenderTexture* contour_rt; - if (reflect_enable) { + if (reflect_draw) { rt = &rctx->render_manager->get_render_texture(0); contour_rt = &rctx->reflect_buffer; } @@ -1677,7 +1645,7 @@ static bool draw_pass_shadow_litproj(light_proj* litproj) { } static void draw_pass_sss_contour(render_context* rctx, rndr::Render* rend) { - if (reflect_enable) + if (reflect_draw) rctx->reflect_buffer.Bind(); else rend->sss_contour_texture->Bind(); @@ -1685,7 +1653,7 @@ static void draw_pass_sss_contour(render_context* rctx, rndr::Render* rend) { gl_state_enable_depth_test(); gl_state_set_depth_func(GL_ALWAYS); gl_state_set_depth_mask(GL_TRUE); - if (reflect_enable) { + if (reflect_draw) { RenderTexture& refl_tex = rctx->render_manager->get_render_texture(0); gl_state_set_viewport(0, 0, refl_tex.GetWidth(), refl_tex.GetHeight()); gl_state_active_bind_texture_2d(0, refl_tex.GetColorTex()); @@ -1723,7 +1691,7 @@ static void draw_pass_sss_contour(render_context* rctx, rndr::Render* rend) { shaders_ft.set(SHADER_FT_CONTOUR); rctx->contour_coef_ubo.Bind(2); - if (reflect_enable) { + if (reflect_draw) { RenderTexture& refl_tex = rctx->render_manager->get_render_texture(0); rctx->render.draw_quad(refl_tex.GetWidth(), refl_tex.GetHeight(), 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); @@ -1790,7 +1758,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss) { mat4* mat = rob_bone_data->get_mats_mat(MOTION_BONE_N_HARA_CP); if (mat) { mat4_get_translation(mat, &chara_position[i]); - if (reflect_enable) + if (reflect_draw) mat4_transform_point(&reflect_mat, &chara_position[i], &chara_position[i]); chara_distance[i] = vec3::distance(view_point, chara_position[i]); } @@ -1819,7 +1787,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss) { rndr::Render* rend = &rctx->render; uniform_value[U_REDUCE] = 0; shaders_ft.set(SHADER_FT_REDUCE); - RenderTexture& rt = reflect_enable + RenderTexture& rt = reflect_draw ? rctx->render_manager->get_render_texture(0) : rend->rend_texture[0]; gl_state_bind_texture_2d(rt.GetColorTex()); @@ -1846,7 +1814,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss) { draw_pass_sss_filter_calc_coef(1.0, sss_count, v34, 3, a5, a6, a7, a8, shader_data.g_coef); rctx->sss_filter_gaussian_coef_ubo.WriteMemory(shader_data); - sss->textures[reflect_enable ? 3 : 1].Bind(); + sss->textures[reflect_draw ? 3 : 1].Bind(); gl_state_set_viewport(0, 0, 320, 180); uniform_value[U_SSS_FILTER] = 3; shaders_ft.set(SHADER_FT_SSS_FILT); @@ -2047,6 +2015,184 @@ static void draw_pass_3d_translucent_has_objects(render_context* rctx, bool* arr } } +static void draw_pass_reflect_full(rndr::RenderManager* render_manager) { + render_context* rctx = rctx_ptr; + gl_state_begin_event("pass_reflect"); + RenderTexture& refl_tex = render_manager->get_render_texture(0); + RenderTexture& refl_buf_tex = rctx->reflect_buffer; + refl_tex.Bind(); + extern bool reflect_full; + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_OPAQUE) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSPARENT) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS) + || rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT)) { + refl_tex.SetViewport(); + + draw_pass_set_camera(); + if (!rctx->sss_data->enable || !rctx->sss_data->npr_contour) + glClear(GL_DEPTH_BUFFER_BIT); + + gl_state_set_depth_func(GL_LEQUAL); + + for (int32_t i = LIGHT_SET_MAIN; i < LIGHT_SET_MAX; i++) + rctx->light_set[i].data_set(rctx->face, (light_set_id)i); + for (int32_t i = FOG_DEPTH; i < FOG_BUMP; i++) + rctx->fog[i].data_set((fog_id)i); + + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); +#if REFLECT_STENCIL + glClearStencil(0x00); +#endif + if (rctx->disp_manager->get_obj_count(mdl::OBJ_TYPE_SSS)) + glClear(GL_COLOR_BUFFER_BIT); +#if REFLECT_STENCIL + else { + gl_state_set_stencil_mask(0xFF); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + gl_state_set_stencil_mask(0x00); + } +#else + else + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); +#endif + +#if REFLECT_STENCIL + draw_pass_reflect_make_stencil(rctx, refl_tex, refl_buf_tex); +#endif + + gl_state_enable_depth_test(); + gl_state_set_depth_func(GL_LEQUAL); + gl_state_set_depth_mask(GL_TRUE); + gl_state_set_cull_face_mode(GL_FRONT); + + reflect_draw = true; + rctx->draw_state->shader_index = -1; + + int32_t render_width = refl_tex.GetWidth(); + int32_t render_height = refl_tex.GetHeight(); + rctx->set_scene_framebuffer_size(render_width, render_height, render_width, render_height); + + if (render_manager->shadow) + draw_pass_3d_shadow_set(render_manager->shadow_ptr, rctx); + else + draw_pass_3d_shadow_reset(rctx); + + if (render_manager->effect_texture) + gl_state_active_bind_texture_2d(14, render_manager->effect_texture->glid); + else + gl_state_active_bind_texture_2d(14, rctx->empty_texture_2d->glid); + + uniform_value[U_WATER_REFLECT] = 0; + + rctx->sss_data->set_texture(3); + + gl_state_bind_sampler(14, rctx->render_samplers[0]); + gl_state_bind_sampler(15, rctx->render_samplers[0]); + gl_state_bind_sampler(16, rctx->render_samplers[0]); + + uniform_value[U_STAGE_AMBIENT] = render_manager->light_stage_ambient ? 1 : 0; + + set_reflect_mat(rctx); + + if (render_manager->alpha_z_sort) { + rctx->disp_manager->obj_sort(&rctx->view_mat, + mdl::OBJ_TYPE_REFLECT_TRANSLUCENT, 1, render_manager->field_31F); + rctx->disp_manager->obj_sort(&rctx->view_mat, + mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS, 2); + } + + if (render_manager->opaque_z_sort) + rctx->disp_manager->obj_sort(&rctx->view_mat, mdl::OBJ_TYPE_REFLECT_OPAQUE, 0); + + if (render_manager->draw_pass_3d[DRAW_PASS_3D_OPAQUE]) { + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_OPAQUE); + gl_state_disable_depth_test(); + } + + Glitter::glt_particle_manager->DispScenes(Glitter::DISP_OPAQUE); + + gl_state_enable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + if (render_manager->draw_pass_3d[DRAW_PASS_3D_TRANSPARENT]) { + gl_state_set_cull_face_mode(GL_FRONT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSPARENT); + } + + if (render_manager->npr_param == 1) + render_manager->pass_3d_contour(); + + gl_state_disable_depth_test(); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager->DispScenes(Glitter::DISP_ALPHA); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + /*if (npr_param == 1) { + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + }*/ + + gl_state_enable_depth_test(); + + if (render_manager->draw_pass_3d[DRAW_PASS_3D_TRANSLUCENT]) { + gl_state_enable_blend(); + gl_state_set_blend_func(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gl_state_set_depth_mask(GL_FALSE); + gl_state_set_cull_face_mode(GL_FRONT); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT_SORT_BY_RADIUS); + rctx->disp_manager->draw(mdl::OBJ_TYPE_REFLECT_TRANSLUCENT); + gl_state_disable_blend(); + } + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); // X + Glitter::glt_particle_manager->DispScenes(Glitter::DISP_TYPE_2); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + gl_state_disable_depth_test(); + + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE); + Glitter::glt_particle_manager->DispScenes(Glitter::DISP_NORMAL); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + gl_state_active_bind_texture_2d(14, 0); + gl_state_active_bind_texture_2d(15, 0); + + if (render_manager->shadow) + draw_pass_3d_shadow_reset(rctx); + + rndr::Render* render = render_manager->render; + rctx->set_scene_framebuffer_size(render->render_width[0], + render->render_height[0], render->render_width[0], render->render_height[0]); + reflect_draw = false; + + gl_state_set_cull_face_mode(GL_BACK); + gl_state_disable_depth_test(); + +#if REFLECT_STENCIL + gl_state_disable_stencil_test(); +#endif + + for (int32_t i = render_manager->reflect_blur_num, j = 0; i > 0; i--, j++) { + blur_filter_apply(rctx, &refl_buf_tex, &refl_tex, + render_manager->reflect_blur_filter, 1.0f, 1.0f, 0.0f); + image_filter_scale(&refl_tex, refl_buf_tex.color_texture); + } + } + else { + vec4 clear_color; + glGetFloatv(GL_COLOR_CLEAR_VALUE, (GLfloat*)&clear_color); + glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glClear(GL_COLOR_BUFFER_BIT); + glClearColor(clear_color.x, clear_color.y, clear_color.z, clear_color.w); + } + shader::unbind(); + gl_state_bind_framebuffer(0); + gl_state_end_event(); +} + #if REFLECT_STENCIL static void draw_pass_reflect_stencil(render_context* rctx, mdl::ObjType type) { if (type < 0 || type >= mdl::OBJ_TYPE_MAX || rctx->disp_manager->get_obj_count(type) < 1) @@ -2114,6 +2260,47 @@ static void draw_pass_reflect_stencil(render_context* rctx, mdl::ObjType type) { for (int32_t i = 0; i < 5; i++) gl_state_bind_sampler(i, 0); } + +static void draw_pass_reflect_make_stencil(render_context* rctx, + RenderTexture& refl_tex, RenderTexture& refl_buf_tex) { + gl_state_set_stencil_mask(0xFF); + + rctx->draw_state->shader_index = SHADER_FT_SIL; + + gl_state_disable_depth_test(); + gl_state_set_depth_mask(GL_TRUE); + + draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_OPAQUE); + draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSLUCENT); + draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSLUCENT_SORT_BY_RADIUS); + draw_pass_reflect_stencil(rctx, mdl::OBJ_TYPE_TRANSPARENT); + + fbo_blit(refl_tex.fbos[0], refl_buf_tex.fbos[0], + 0, 0, refl_tex.GetWidth(), refl_tex.GetHeight(), + 0, 0, refl_buf_tex.GetWidth(), refl_buf_tex.GetHeight(), + GL_COLOR_BUFFER_BIT, GL_LINEAR); + + refl_tex.Bind(); + glClear(GL_COLOR_BUFFER_BIT); + + gl_state_enable_stencil_test(); + gl_state_set_stencil_op(GL_KEEP, GL_KEEP, GL_REPLACE); + gl_state_set_stencil_func(GL_ALWAYS, 0x01, 0x01); + + gl_state_bind_texture_2d(refl_buf_tex.GetColorTex()); + gl_state_bind_sampler(0, rctx->render_samplers[0]); + + gl_state_set_color_mask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + shaders_ft.set(SHADER_FT_REFLECT_STENCIL); + rctx->render.draw_quad(refl_buf_tex.GetWidth(), refl_buf_tex.GetHeight(), 1.0f, 1.0f, + 0.0f, 0.0f, 6.0f, 1.0f, 1.0f, 1.0f, 1.0f); + gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); + + gl_state_set_stencil_op(GL_KEEP, GL_KEEP, GL_KEEP); + gl_state_set_stencil_func(GL_EQUAL, 0x01, 0x01); + + gl_state_set_stencil_mask(0x00); +} #endif static void blur_filter_apply(render_context* rctx, RenderTexture* dst, RenderTexture* src, diff --git a/src/CRE/rob/rob.cpp b/src/CRE/rob/rob.cpp index d78d3233..ad216466 100644 --- a/src/CRE/rob/rob.cpp +++ b/src/CRE/rob/rob.cpp @@ -13987,6 +13987,10 @@ static void sub_140512C20(rob_chara_item_equip* rob_itm_equip, render_context* r } void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { + extern bool reflect_full; + extern bool reflect_draw; + reflect_draw = reflect_full; + mdl::ObjFlags flags = (mdl::ObjFlags)0; if (rctx->chara_reflect) enum_or(flags, mdl::OBJ_CHARA_REFLECT); @@ -14054,6 +14058,8 @@ void rob_chara_item_equip::disp(int32_t chara_id, render_context* rctx) { disp_manager.set_chara_color(); disp_manager.set_obj_flags(); disp_manager.set_shadow_type(); + + reflect_draw = false; } rob_chara_item_equip_object* rob_chara_item_equip::get_item_equip_object(item_id id) { diff --git a/src/CRE/stage.cpp b/src/CRE/stage.cpp index 997139b5..7494b78c 100644 --- a/src/CRE/stage.cpp +++ b/src/CRE/stage.cpp @@ -689,7 +689,7 @@ static void stage_set(stage* s, stage* other) { reflect_refract_resolution_mode reflect_resolution_mode = REFLECT_REFRACT_RESOLUTION_512x512; if (other->stage_data->reflect_type != STAGE_DATA_REFLECT_REFLECT_MAP) reflect_resolution_mode = (reflect_refract_resolution_mode)reflect->mode; - render_manager->set_refract_resolution_mode(reflect_resolution_mode); + render_manager->set_reflect_resolution_mode(reflect_resolution_mode); } if (other->stage_data->refract) { diff --git a/src/KKdLib/deflate.cpp b/src/KKdLib/deflate.cpp index ef261535..a2563aaa 100644 --- a/src/KKdLib/deflate.cpp +++ b/src/KKdLib/deflate.cpp @@ -7,18 +7,14 @@ #include namespace deflate { - static void* deflate_malloc(void* data, size_t size) { - return malloc(size); - } - - static void deflate_free(void* data, void* ptr) { - free(ptr); - } - const allocator default_allocator = { 0, - deflate_malloc, - deflate_free, + [](void* data, size_t size) { + return malloc(size); + }, + [](void* data, void* ptr) { + free(ptr); + } }; static int32_t compress_static(struct libdeflate_compressor* c, const void* src, size_t src_length, diff --git a/src/ReDIVA/x_pv_game.cpp b/src/ReDIVA/x_pv_game.cpp index e389acbc..e7a24964 100644 --- a/src/ReDIVA/x_pv_game.cpp +++ b/src/ReDIVA/x_pv_game.cpp @@ -276,6 +276,8 @@ XPVGameSelector* x_pv_game_selector_ptr; x_pv_game_music* x_pv_game_music_ptr; #endif +bool reflect_full; + extern render_context* rctx_ptr; static vec4 bright_scale_get(int32_t index, float_t value);