From 720f7ec9068976e94506c34cbe45f6c011ece15d Mon Sep 17 00:00:00 2001 From: korenkonder Date: Fri, 29 Nov 2024 20:47:56 +0300 Subject: [PATCH] Adapted new findings --- src/CRE/Glitter/effect_inst.cpp | 8 + src/CRE/Glitter/glitter.hpp | 8 +- src/CRE/Glitter/particle_manager.cpp | 11 +- src/CRE/Glitter/render_scene.cpp | 437 +++++++++++++++------------ src/CRE/Glitter/scene.cpp | 9 + src/CRE/mdl/disp_manager.cpp | 8 +- src/CRE/mdl/disp_manager.hpp | 2 +- src/CRE/mdl/draw_object.cpp | 4 +- src/CRE/object.cpp | 10 +- src/CRE/render.cpp | 69 +++-- src/CRE/render.hpp | 3 +- src/CRE/render_context.cpp | 5 +- src/CRE/render_manager.cpp | 34 ++- src/CRE/render_manager.hpp | 2 + src/KKdLib/obj.hpp | 2 +- 15 files changed, 358 insertions(+), 254 deletions(-) diff --git a/src/CRE/Glitter/effect_inst.cpp b/src/CRE/Glitter/effect_inst.cpp index 7660e3aa..b162e0ed 100644 --- a/src/CRE/Glitter/effect_inst.cpp +++ b/src/CRE/Glitter/effect_inst.cpp @@ -208,6 +208,10 @@ namespace Glitter { render_scene.Disp(GPM_VAL, disp_type); } + void F2EffectInst::DispMesh(GPM) { + + } + void F2EffectInst::Free(GPM, GLT, float_t emission, bool free) { enum_or(flags, EFFECT_INST_FREE); for (F2EmitterInst*& i : emitters) @@ -784,6 +788,10 @@ namespace Glitter { render_scene.Disp(GPM_VAL, disp_type); } + void XEffectInst::DispMesh(GPM) { + render_scene.DispMesh(GPM_VAL); + } + void XEffectInst::Free(GPM, GLT, float_t emission, bool free) { enum_or(flags, EFFECT_INST_FREE); for (XEmitterInst*& i : emitters) diff --git a/src/CRE/Glitter/glitter.hpp b/src/CRE/Glitter/glitter.hpp index fa741abd..fa2166c8 100644 --- a/src/CRE/Glitter/glitter.hpp +++ b/src/CRE/Glitter/glitter.hpp @@ -871,7 +871,6 @@ namespace Glitter { void CalcDisp(GPM, XRenderGroup* rend_group); void CalcDispLine(XRenderGroup* rend_group); void CalcDispLocus(GPM, XRenderGroup* rend_group); - void CalcDispMesh(GPM, XRenderGroup* rend_group); void CalcDispQuad(GPM, XRenderGroup* rend_group); void CalcDispQuadDirectionRotation(XRenderGroup* rend_group, mat4* model_mat); void CalcDispQuadNormal(XRenderGroup* rend_group, mat4* model_mat, mat4* dir_mat); @@ -880,6 +879,8 @@ namespace Glitter { void Ctrl(float_t delta_frame, bool copy_mats); void Disp(GPM, DispType disp_type); void Disp(GPM, XRenderGroup* rend_group); + void DispMesh(GPM); + void DispMesh(GPM, XRenderGroup* rend_group); }; class EffectInst { @@ -911,6 +912,7 @@ namespace Glitter { virtual void CalcDisp(GPM) = 0; virtual void Copy(EffectInst* dst, float_t emission) = 0; virtual void Disp(GPM, DispType disp_type) = 0; + virtual void DispMesh(GPM) = 0; virtual void Free(GPM, GLT, float_t emission, bool free) = 0; virtual size_t GetCtrlCount(ParticleType type) = 0; virtual size_t GetDispCount(ParticleType type) = 0; @@ -963,6 +965,7 @@ namespace Glitter { virtual void CalcDisp(GPM) override; virtual void Copy(EffectInst* dst, float_t emission) override; virtual void Disp(GPM, DispType disp_type) override; + virtual void DispMesh(GPM) override; virtual void Free(GPM, GLT, float_t emission, bool free) override; virtual size_t GetCtrlCount(ParticleType type) override; virtual size_t GetDispCount(ParticleType type) override; @@ -1028,6 +1031,7 @@ namespace Glitter { virtual void CalcDisp(GPM) override; virtual void Copy(EffectInst* dst, float_t emission) override; virtual void Disp(GPM, DispType disp_type) override; + virtual void DispMesh(GPM) override; virtual void Free(GPM, GLT, float_t emission, bool free) override; virtual size_t GetCtrlCount(ParticleType type) override; virtual size_t GetDispCount(ParticleType type) override; @@ -1619,6 +1623,7 @@ namespace Glitter { bool Copy(EffectInst* eff_inst, Scene* dst); void Ctrl(GPM, float_t delta_frame); void Disp(GPM, DispType disp_type); + void DispMesh(GPM); size_t GetCtrlCount(ParticleType ptcl_type); size_t GetDispCount(ParticleType ptcl_type); float_t GetFrameLifeTime(int32_t* life_time, size_t id); @@ -1673,6 +1678,7 @@ namespace Glitter { bool AppendEffectGroup(uint64_t hash, EffectGroup* eff_group, FileReader* file_read); void BasicEffectGroups(); + void CalcDisp(); uint64_t CalculateHash(const char* str); bool CheckHasLocalEffect(); bool CheckNoFileReaders(uint64_t hash); diff --git a/src/CRE/Glitter/particle_manager.cpp b/src/CRE/Glitter/particle_manager.cpp index 24965085..9254c361 100644 --- a/src/CRE/Glitter/particle_manager.cpp +++ b/src/CRE/Glitter/particle_manager.cpp @@ -90,7 +90,7 @@ namespace Glitter { for (Scene*& i : scenes) if (i) - i->CalcDisp(this); + i->DispMesh(this); } void GltParticleManager::basic() { @@ -180,6 +180,15 @@ namespace Glitter { enum_and(flags, ~PARTICLE_MANAGER_LOCAL); } + void GltParticleManager::CalcDisp() { + if (flags & PARTICLE_MANAGER_NOT_DISP) + return; + + for (Scene*& i : scenes) + if (i) + i->CalcDisp(this); + } + uint64_t GltParticleManager::CalculateHash(const char* str) { return hash_utf8_fnv1a64m(str); } diff --git a/src/CRE/Glitter/render_scene.cpp b/src/CRE/Glitter/render_scene.cpp index 9d8725fc..6537a4bb 100644 --- a/src/CRE/Glitter/render_scene.cpp +++ b/src/CRE/Glitter/render_scene.cpp @@ -155,7 +155,6 @@ namespace Glitter { disp_quad = 0; disp_line = 0; disp_locus = 0; - disp_mesh = 0; Effect* eff = GPM_VAL->selected_effect; Emitter* emit = GPM_VAL->selected_emitter; @@ -188,9 +187,9 @@ namespace Glitter { } void F2RenderScene::CalcDisp(GPM, F2RenderGroup* rend_group) { - rend_group->disp = 0; switch (rend_group->type) { case PARTICLE_QUAD: + rend_group->disp = 0; if (!rend_group->vao) return; @@ -198,6 +197,7 @@ namespace Glitter { disp_quad += rend_group->disp; break; case PARTICLE_LINE: + rend_group->disp = 0; if (!rend_group->vao) return; @@ -205,12 +205,18 @@ namespace Glitter { disp_line += rend_group->disp; break; case PARTICLE_LOCUS: + rend_group->disp = 0; if (!rend_group->vao) return; CalcDispLocus(GPM_VAL, rend_group); disp_locus += rend_group->disp; break; + case PARTICLE_MESH: + break; + default: + rend_group->disp = 0; + break; } } @@ -1161,9 +1167,9 @@ namespace Glitter { } void XRenderScene::CalcDisp(GPM, XRenderGroup* rend_group) { - rend_group->disp = 0; switch (rend_group->type) { case PARTICLE_QUAD: + rend_group->disp = 0; if (!rend_group->vao) return; @@ -1174,6 +1180,7 @@ namespace Glitter { if (!rend_group->vao) return; + rend_group->disp = 0; CalcDispLine(rend_group); disp_line += rend_group->disp; break; @@ -1181,12 +1188,14 @@ namespace Glitter { if (!rend_group->vao) return; + rend_group->disp = 0; CalcDispLocus(GPM_VAL, rend_group); disp_locus += rend_group->disp; break; case PARTICLE_MESH: - CalcDispMesh(GPM_VAL, rend_group); - disp_mesh += rend_group->disp; + break; + default: + rend_group->disp = 0; break; } } @@ -1430,196 +1439,6 @@ namespace Glitter { #endif } - void XRenderScene::CalcDispMesh(GPM, XRenderGroup* rend_group) { - if (rend_group->object_name_hash == hash_murmurhash_empty - || rend_group->object_name_hash == 0xFFFFFFFF) - return; - - bool has_scale = false; - bool emitter_local = false; - vec3 emit_scale = 0.0f; - mat4 model_mat; - mat4 view_mat; - mat4 inv_view_mat; - if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { - model_mat = rend_group->mat; - mat4_normalize_rotation(&model_mat, &view_mat); - mat4_mul(&view_mat, &rctx_ptr->camera->view, &view_mat); - mat4_invert(&view_mat, &inv_view_mat); - - emitter_local = true; - if (rend_group->flags & PARTICLE_SCALE) { - if (rend_group->GetEmitterScale(emit_scale)) - has_scale = true; - } - } - else { - model_mat = mat4_identity; - view_mat = rctx_ptr->camera->view; - inv_view_mat = rctx_ptr->camera->inv_view; - } - - bool local = false; - if (rend_group->flags & PARTICLE_LOCAL) { - mat4_mul(&inv_view_mat, &rend_group->mat, &inv_view_mat); - mat4_mul(&view_mat, &inv_view_mat, &view_mat); - mat4_invert(&view_mat, &inv_view_mat); - local = true; - } - mat4_mul(&view_mat, &rctx_ptr->camera->inv_view, &rend_group->mat_draw); - - mat4 dir_mat = mat4_identity; - vec3 up_vec = { 0.0f, 0.0f, 1.0f }; - bool billboard = false; - bool emitter_rotation = false; - mat4(*rotate_func)(XRenderGroup*, RenderElement*, vec3*, vec3*) = 0; - switch (rend_group->draw_type) { - case DIRECTION_BILLBOARD: - mat4_clear_trans(&model_mat, &dir_mat); - mat4_mul(&dir_mat, &inv_view_mat, &dir_mat); - mat4_clear_trans(&dir_mat, &dir_mat); - billboard = true; - break; - case DIRECTION_EMITTER_DIRECTION: - dir_mat = rend_group->mat_rot; - break; - case DIRECTION_PREV_POSITION: - case DIRECTION_PREV_POSITION_DUP: - rotate_func = XRenderGroup::RotateMeshToPrevPosition; - break; - case DIRECTION_EMIT_POSITION: - rotate_func = XRenderGroup::RotateMeshToEmitPosition; - break; - case DIRECTION_Y_AXIS: - mat4_rotate_y((float_t)M_PI_2, &dir_mat); - break; - case DIRECTION_X_AXIS: - mat4_rotate_x((float_t)-M_PI_2, &dir_mat); - break; - case DIRECTION_BILLBOARD_Y_AXIS: - mat4_rotate_y(rctx_ptr->camera->rotation.y, &dir_mat); - break; - case DIRECTION_EMITTER_ROTATION: - emitter_rotation = true; - break; - } - - Particle* particle = rend_group->particle->data.particle; - object_info object_info; - object_info.set_id = (uint32_t)particle->data.mesh.object_set_name_hash; - object_info.id = (uint32_t)particle->data.mesh.object_name_hash; - obj* obj = objset_info_storage_get_obj(object_info); - if (!obj) - return; - - texture_transform_struct tex_trans[2]; - int32_t tex_trans_count = 0; - - for (texture_transform_struct& i : tex_trans) { - tex_trans->id = hash_murmurhash_empty; - tex_trans->mat = mat4_identity; - } - - obj_material& material = obj->material_array[0].material; - - for (obj_material_texture_data& i : material.texdata) { - if (i.tex_index == hash_murmurhash_empty || i.tex_index == hash_murmurhash_null) - continue; - - tex_trans[tex_trans_count].id = i.tex_index; - tex_trans[tex_trans_count].mat = mat4_identity; - tex_trans_count++; - - if (++tex_trans_count == 2) - break; - } - - vec3 ext_anim_scale; - float_t ext_scale = 0.0f; - if (rend_group->GetExtAnimScale(&ext_anim_scale, &ext_scale)) { - if (!has_scale) { - emit_scale = 1.0f; - has_scale = true; - } - - if (ext_scale >= 0.0f) - emit_scale *= ext_anim_scale + ext_scale; - else - emit_scale += ext_anim_scale; - } - - mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; - disp_manager.set_texture_pattern(0, 0); - - RenderElement* elem = rend_group->elements; - size_t disp = 0; - for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { - j_max = min_def(i, j_max); - for (size_t j = j_max; j > 0; elem++) { - if (!elem->alive) - continue; - j--; - - if (!elem->disp) - continue; - - vec3 trans = elem->translation; - vec3 rot = elem->rotation; - vec3 scale = elem->scale * elem->scale_all; - if (has_scale) - scale *= emit_scale; - - if (emitter_local) - mat4_transform_point(&model_mat, &trans, &trans); - - mat4 mat; - if (billboard) { - if (local) - mat = mat4_identity; - else - mat = dir_mat; - } - else if (rotate_func) { - mat = rotate_func(rend_group, elem, &up_vec, &trans); - } - else if (emitter_rotation) - mat = elem->mat; - else - mat = dir_mat; - - mat4_set_translation(&mat, &trans); - mat4_mul_rotate_zyx(&mat, &rot, &mat); - mat4_scale_rot(&mat, &scale, &mat); - - vec3 uv_scroll; - vec3 uv_scroll_2nd; - uv_scroll.x = elem->uv_scroll.x; - uv_scroll.y = -elem->uv_scroll.y; - uv_scroll.z = 0.0f; - uv_scroll_2nd.x = elem->uv_scroll_2nd.x; - uv_scroll_2nd.y = -elem->uv_scroll_2nd.y; - uv_scroll_2nd.z = 0.0f; - - mat4_set_translation(&tex_trans[0].mat, &uv_scroll); - mat4_set_translation(&tex_trans[1].mat, &uv_scroll_2nd); - - disp_manager.set_texture_transform(tex_trans_count, tex_trans); - - if (local) - mat4_mul(&mat, &rctx_ptr->camera->inv_view, &mat); - elem->mat_draw = mat; - - if (disp_manager.entry_obj_by_object_info( - &mat, object_info, &elem->color, 0, local)) - disp++; - - disp_manager.set_texture_transform(0, 0); - } - } - disp_manager.set_texture_pattern(0, 0); - rend_group->disp = disp; - } - void XRenderScene::CalcDispQuad(GPM, XRenderGroup* rend_group) { #if SHARED_GLITTER_BUFFER if (!rend_group->elements || rend_group->ctrl < 1) @@ -2095,7 +1914,17 @@ namespace Glitter { } void XRenderScene::Disp(GPM, XRenderGroup* rend_group) { - if (rend_group->disp < 1) + switch (rend_group->type) { + case PARTICLE_QUAD: + case PARTICLE_LINE: + case PARTICLE_LOCUS: + break; + case PARTICLE_MESH: + default: + return; + } + + if (!rend_group->vao || rend_group->disp < 1) return; mat4 mat; @@ -2242,4 +2071,220 @@ namespace Glitter { break; } } + + void XRenderScene::DispMesh(GPM) { + disp_mesh = 0; + + for (XRenderGroup*& i : groups) { + if (!i) + continue; + + XRenderGroup* rend_group = i; + if (rend_group->CannotDisp()) + continue; + + switch (rend_group->type) { + case PARTICLE_MESH: + rend_group->disp = 0; + DispMesh(GPM_VAL, rend_group); + disp_mesh += rend_group->disp; + break; + } + } + } + + void XRenderScene::DispMesh(GPM, XRenderGroup* rend_group) { + if (!rend_group->elements || rend_group->object_name_hash == hash_murmurhash_empty + || rend_group->object_name_hash == (uint32_t)-1 || rend_group->ctrl < 1) + return; + + bool has_scale = false; + bool emitter_local = false; + vec3 emit_scale = 0.0f; + mat4 model_mat; + mat4 view_mat; + mat4 inv_view_mat; + if (rend_group->flags & PARTICLE_EMITTER_LOCAL) { + model_mat = rend_group->mat; + mat4_normalize_rotation(&model_mat, &view_mat); + mat4_mul(&view_mat, &rctx_ptr->camera->view, &view_mat); + mat4_invert(&view_mat, &inv_view_mat); + + emitter_local = true; + if (rend_group->flags & PARTICLE_SCALE) { + if (rend_group->GetEmitterScale(emit_scale)) + has_scale = true; + } + } + else { + model_mat = mat4_identity; + view_mat = rctx_ptr->camera->view; + inv_view_mat = rctx_ptr->camera->inv_view; + } + + bool local = false; + if (rend_group->flags & PARTICLE_LOCAL) { + mat4_mul(&inv_view_mat, &rend_group->mat, &inv_view_mat); + mat4_mul(&view_mat, &inv_view_mat, &view_mat); + mat4_invert(&view_mat, &inv_view_mat); + local = true; + } + mat4_mul(&view_mat, &rctx_ptr->camera->inv_view, &rend_group->mat_draw); + + mat4 dir_mat = mat4_identity; + vec3 up_vec = { 0.0f, 0.0f, 1.0f }; + bool billboard = false; + bool emitter_rotation = false; + mat4(*rotate_func)(XRenderGroup*, RenderElement*, vec3*, vec3*) = 0; + switch (rend_group->draw_type) { + case DIRECTION_BILLBOARD: + mat4_clear_trans(&model_mat, &dir_mat); + mat4_mul(&dir_mat, &inv_view_mat, &dir_mat); + mat4_clear_trans(&dir_mat, &dir_mat); + billboard = true; + break; + case DIRECTION_EMITTER_DIRECTION: + dir_mat = rend_group->mat_rot; + break; + case DIRECTION_PREV_POSITION: + case DIRECTION_PREV_POSITION_DUP: + rotate_func = XRenderGroup::RotateMeshToPrevPosition; + break; + case DIRECTION_EMIT_POSITION: + rotate_func = XRenderGroup::RotateMeshToEmitPosition; + break; + case DIRECTION_Y_AXIS: + mat4_rotate_y((float_t)M_PI_2, &dir_mat); + break; + case DIRECTION_X_AXIS: + mat4_rotate_x((float_t)-M_PI_2, &dir_mat); + break; + case DIRECTION_BILLBOARD_Y_AXIS: + mat4_rotate_y(rctx_ptr->camera->rotation.y, &dir_mat); + break; + case DIRECTION_EMITTER_ROTATION: + emitter_rotation = true; + break; + } + + Particle* particle = rend_group->particle->data.particle; + object_info object_info; + object_info.set_id = (uint32_t)particle->data.mesh.object_set_name_hash; + object_info.id = (uint32_t)particle->data.mesh.object_name_hash; + obj* obj = objset_info_storage_get_obj(object_info); + if (!obj) + return; + + texture_transform_struct tex_trans[2]; + int32_t tex_trans_count = 0; + + for (texture_transform_struct& i : tex_trans) { + tex_trans->id = hash_murmurhash_empty; + tex_trans->mat = mat4_identity; + } + + obj_material& material = obj->material_array[0].material; + + for (obj_material_texture_data& i : material.texdata) { + if (i.tex_index == hash_murmurhash_empty || i.tex_index == hash_murmurhash_null) + continue; + + tex_trans[tex_trans_count].id = i.tex_index; + tex_trans[tex_trans_count].mat = mat4_identity; + tex_trans_count++; + + if (++tex_trans_count == 2) + break; + } + + vec3 ext_anim_scale; + float_t ext_scale = 0.0f; + if (rend_group->GetExtAnimScale(&ext_anim_scale, &ext_scale)) { + if (!has_scale) { + emit_scale = 1.0f; + has_scale = true; + } + + if (ext_scale >= 0.0f) + emit_scale *= ext_anim_scale + ext_scale; + else + emit_scale += ext_anim_scale; + } + + mdl::DispManager& disp_manager = *rctx_ptr->disp_manager; + const bool object_culling = disp_manager.object_culling; + if (local) + disp_manager.object_culling = false; + disp_manager.set_texture_pattern(0, 0); + + RenderElement* elem = rend_group->elements; + size_t disp = 0; + for (size_t i = rend_group->ctrl, j_max = 1024; i > 0; i -= j_max) { + j_max = min_def(i, j_max); + for (size_t j = j_max; j > 0; elem++) { + if (!elem->alive) + continue; + j--; + + if (!elem->disp) + continue; + + vec3 trans = elem->translation; + vec3 rot = elem->rotation; + vec3 scale = elem->scale * elem->scale_all; + if (has_scale) + scale *= emit_scale; + + if (emitter_local) + mat4_transform_point(&model_mat, &trans, &trans); + + mat4 mat; + if (billboard) { + if (local) + mat = mat4_identity; + else + mat = dir_mat; + } + else if (rotate_func) { + mat = rotate_func(rend_group, elem, &up_vec, &trans); + } + else if (emitter_rotation) + mat = elem->mat; + else + mat = dir_mat; + + mat4_set_translation(&mat, &trans); + mat4_mul_rotate_zyx(&mat, &rot, &mat); + mat4_scale_rot(&mat, &scale, &mat); + + vec3 uv_scroll; + vec3 uv_scroll_2nd; + uv_scroll.x = elem->uv_scroll.x; + uv_scroll.y = -elem->uv_scroll.y; + uv_scroll.z = 0.0f; + uv_scroll_2nd.x = elem->uv_scroll_2nd.x; + uv_scroll_2nd.y = -elem->uv_scroll_2nd.y; + uv_scroll_2nd.z = 0.0f; + + mat4_set_translation(&tex_trans[0].mat, &uv_scroll); + mat4_set_translation(&tex_trans[1].mat, &uv_scroll_2nd); + + disp_manager.set_texture_transform(tex_trans_count, tex_trans); + + if (local) + mat4_mul(&mat, &rctx_ptr->camera->inv_view, &mat); + elem->mat_draw = mat; + + if (disp_manager.entry_obj_by_object_info( + &mat, object_info, &elem->color, 0, local)) + disp++; + + disp_manager.set_texture_transform(0, 0); + } + } + disp_manager.set_texture_pattern(0, 0); + rend_group->disp = disp; + if (local) + disp_manager.object_culling = object_culling; + } } diff --git a/src/CRE/Glitter/scene.cpp b/src/CRE/Glitter/scene.cpp index ecbae2d4..7294a014 100644 --- a/src/CRE/Glitter/scene.cpp +++ b/src/CRE/Glitter/scene.cpp @@ -154,6 +154,15 @@ namespace Glitter { } } + void Scene::DispMesh(GPM) { + if (flags & SCENE_NOT_DISP) + return; + + for (SceneEffect& i : effects) + if (i.ptr && i.disp) + i.ptr->DispMesh(GPM_VAL); + } + size_t Scene::GetCtrlCount(ParticleType ptcl_type) { size_t ctrl = 0; for (SceneEffect& i : effects) diff --git a/src/CRE/mdl/disp_manager.cpp b/src/CRE/mdl/disp_manager.cpp index 58a02234..6acb16de 100644 --- a/src/CRE/mdl/disp_manager.cpp +++ b/src/CRE/mdl/disp_manager.cpp @@ -2003,7 +2003,7 @@ namespace mdl { } void DispManager::draw(ObjType type, int32_t depth_mask, bool reflect_texture_mask, int32_t alpha) { - if (type < 0 || type >= mdl::OBJ_TYPE_MAX || get_obj_count(type) < 1) + if (type < 0 || type >= OBJ_TYPE_MAX || get_obj_count(type) < 1) return; render_context* rctx = rctx_ptr; @@ -2253,7 +2253,7 @@ namespace mdl { || 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.transparent) { + && !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; @@ -2582,7 +2582,7 @@ namespace mdl { bool translucent = false; if (!attrib.flag_28 && (!attrib.punch_through && (attrib.alpha_texture || attrib.alpha_material) - || sub_mesh->attrib.m.transparent)) + || sub_mesh->attrib.m.translucent)) translucent = true; if (translucent) { @@ -2621,7 +2621,7 @@ namespace mdl { } 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.transparent)) { + || sub_mesh->attrib.m.translucent)) { if (!(obj_flags & mdl::OBJ_NO_TRANSLUCENCY)) { if (!attrib.translucent_priority) if (local) diff --git a/src/CRE/mdl/disp_manager.hpp b/src/CRE/mdl/disp_manager.hpp index c71207cc..642bbe29 100644 --- a/src/CRE/mdl/disp_manager.hpp +++ b/src/CRE/mdl/disp_manager.hpp @@ -453,7 +453,7 @@ namespace mdl { void draw(mdl::ObjType type, int32_t depth_mask = 0, bool reflect_texture_mask = true, int32_t alpha = -1); /*void draw_show_vector(mdl::ObjType type, int32_t show_vector);*/ void entry_list(ObjType type, ObjData* data); - bool entry_obj(const ::obj* object, obj_mesh_vertex_buffer* obj_vertex_buf, + bool entry_obj(const ::obj* obj, obj_mesh_vertex_buffer* obj_vertex_buf, obj_mesh_index_buffer* obj_index_buf, const mat4* mat, const std::vector* textures, const vec4* blend_color, const mat4* bone_mat, const ::obj* object_morph, obj_mesh_vertex_buffer* obj_morph_vertex_buf, int32_t instances_count, const mat4* instances_mat, diff --git a/src/CRE/mdl/draw_object.cpp b/src/CRE/mdl/draw_object.cpp index 85b18c29..349908a4 100644 --- a/src/CRE/mdl/draw_object.cpp +++ b/src/CRE/mdl/draw_object.cpp @@ -293,7 +293,7 @@ namespace mdl { obj_material_attrib_member attrib = args->material->material.attrib.m; uniform_value[U_ALPHA_TEST] = (!attrib.flag_28 && (args->blend_color.w < 1.0f || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through - || args->sub_mesh->attrib.m.transparent) + || args->sub_mesh->attrib.m.translucent) || attrib.punch_through) ? 1 : 0; uniform_value[U_NPR_NORMAL] = 1; @@ -380,7 +380,7 @@ namespace mdl { obj_material_attrib_member attrib = args->material->material.attrib.m; if (!attrib.flag_28 && (args->blend_color.w < 1.0f || (attrib.alpha_texture || attrib.alpha_material) && !attrib.punch_through - || args->sub_mesh->attrib.m.transparent) + || args->sub_mesh->attrib.m.translucent) || attrib.punch_through) { uniform_value[U_ALPHA_TEST] = 1; rctx->set_batch_alpha_threshold(0.5f); diff --git a/src/CRE/object.cpp b/src/CRE/object.cpp index d1fac883..20655432 100644 --- a/src/CRE/object.cpp +++ b/src/CRE/object.cpp @@ -1100,14 +1100,16 @@ void object_material_msgpack_read(const char* path, const char* set_name, msgpack* attrib = _sub_mesh.read("attrib"); if (attrib) { msgpack* recieve_shadow = attrib->read("recieve_shadow"); - msgpack* cast_shadow = attrib->read("cast_shadow"); - msgpack* transparent = attrib->read("transparent"); if (recieve_shadow) sub_mesh.attrib.m.recieve_shadow = recieve_shadow->read_bool(); + + msgpack* cast_shadow = attrib->read("cast_shadow"); if (cast_shadow) sub_mesh.attrib.m.cast_shadow = cast_shadow->read_bool(); - if (transparent) - sub_mesh.attrib.m.transparent = transparent->read_bool(); + + msgpack* translucent = attrib->read("translucent"); + if (translucent) + sub_mesh.attrib.m.translucent = translucent->read_bool(); } } break; diff --git a/src/CRE/render.cpp b/src/CRE/render.cpp index b4d2fb7f..3a9196cf 100644 --- a/src/CRE/render.cpp +++ b/src/CRE/render.cpp @@ -392,38 +392,6 @@ namespace rndr { mat4_frustrum(left, right, bottom, top, z_near, z_far, mat); } - void Render::ctrl(camera* cam) { - view_point_prev = view_point; - interest_prev = interest; - cam->get_view_point(view_point); - cam->get_interest(interest); - - stage_index_prev = stage_index; - if (task_stage_is_modern) - stage_index = (int32_t)task_stage_modern_get_current_stage_hash(); - else - stage_index = task_stage_get_current_stage_index(); - - cam_view_projection_prev = cam_view_projection; - cam_view_projection = cam->view_projection; - - reset_exposure = cam->fast_change_hist1 && !cam->fast_change_hist0; - if (reset_exposure) { - float_t view_point_dist = vec3::distance(view_point, view_point_prev); - - vec3 dir = vec3::normalize(interest - view_point); - vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); - - float_t dir_diff_angle = vec3::dot(dir, dir_prev); - if (dir_diff_angle < 0.5f) - dir_diff_angle = 0.0f; - if (view_point_dist < dir_diff_angle * 0.4f) - reset_exposure = false; - } - else if (stage_index != stage_index_prev) - reset_exposure = true; - } - void Render::draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w) { s0 -= s1; @@ -1088,6 +1056,43 @@ namespace rndr { movie_textures[index].Free(); } + void Render::post_proc() { + lens_flare_texture = 0; + aet_back = 0; + } + + void Render::pre_proc(camera* cam) { + view_point_prev = view_point; + interest_prev = interest; + cam->get_view_point(view_point); + cam->get_interest(interest); + + stage_index_prev = stage_index; + if (task_stage_is_modern) + stage_index = (int32_t)task_stage_modern_get_current_stage_hash(); + else + stage_index = task_stage_get_current_stage_index(); + + cam_view_projection_prev = cam_view_projection; + cam_view_projection = cam->view_projection; + + reset_exposure = cam->fast_change_hist1 && !cam->fast_change_hist0; + if (reset_exposure) { + float_t view_point_dist = vec3::distance(view_point, view_point_prev); + + vec3 dir = vec3::normalize(interest - view_point); + vec3 dir_prev = vec3::normalize(interest_prev - view_point_prev); + + float_t dir_diff_angle = vec3::dot(dir, dir_prev); + if (dir_diff_angle < 0.5f) + dir_diff_angle = 0.0f; + if (view_point_dist < dir_diff_angle * 0.4f) + reset_exposure = false; + } + else if (stage_index != stage_index_prev) + reset_exposure = true; + } + int32_t Render::render_texture_set(texture* render_texture, bool task_photo) { if (!render_texture) return -1; diff --git a/src/CRE/render.hpp b/src/CRE/render.hpp index b7081500..9423ce48 100644 --- a/src/CRE/render.hpp +++ b/src/CRE/render.hpp @@ -184,7 +184,6 @@ namespace rndr { void calc_exposure_chara_data(camera* cam); void calc_projection_matrix(mat4* mat, float_t fov, float_t aspect, float_t z_near, float_t z_far, float_t left_offset, float_t right_offset, float_t bottom_offset, float_t top_offset); - void ctrl(camera* cam); void draw_quad(int32_t width, int32_t height, float_t s0, float_t t0, float_t s1, float_t t1, float_t scale, float_t param_x, float_t param_y, float_t param_z, float_t param_w); void draw_lens_flare(camera* cam); @@ -225,6 +224,8 @@ namespace rndr { void init_tone_map_buffers(); int32_t movie_texture_set(texture* movie_texture); void movie_texture_free(texture* movie_texture); + void post_proc(); + void pre_proc(camera* cam); int32_t render_texture_set(texture* render_texture, bool task_photo); void render_texture_free(texture* render_texture, bool task_photo); void reset_saturate_coeff(int32_t index, bool lock); diff --git a/src/CRE/render_context.cpp b/src/CRE/render_context.cpp index 8645e6ae..e98a8e3e 100644 --- a/src/CRE/render_context.cpp +++ b/src/CRE/render_context.cpp @@ -785,10 +785,9 @@ void render_context::disp() { extern void dw_gui_ctrl_disp(); dw_gui_ctrl_disp(); sprite_manager_set_index(sprite_index); - render.ctrl(camera); + render_manager->rndpass_pre_proc(camera); render_manager->render_all(); - render.lens_flare_texture = 0; - render.aet_back = 0; + render_manager->rndpass_post_proc(); render_manager->field_31C = false; if (!get_pause()) app::TaskWork::basic(); diff --git a/src/CRE/render_manager.cpp b/src/CRE/render_manager.cpp index ce7b33f1..946e71b6 100644 --- a/src/CRE/render_manager.cpp +++ b/src/CRE/render_manager.cpp @@ -37,8 +37,7 @@ static void draw_pass_sss_filter(render_context* rctx, sss_data* sss); static int32_t draw_pass_3d_get_translucent_count(render_context* rctx); static void draw_pass_3d_shadow_reset(render_context* rctx); static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx); -extern void draw_pass_3d_translucent(render_context* rctx, bool opaque_enable, - bool transparent_enable, bool translucent_enable, mdl::ObjType opaque, +extern void draw_pass_3d_translucent(render_context* rctx, mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent); static int32_t draw_pass_3d_translucent_count_layers(render_context* rctx, int32_t* alpha_array, mdl::ObjType opaque, @@ -324,6 +323,20 @@ namespace rndr { gl_state_bind_uniform_buffer_base(4, 0); } + void RenderManager::rndpass_post_proc() { + gl_state_begin_event("rndpass_post_proc"); + render->post_proc(); + field_31C = false; + gl_state_end_event(); + } + + void RenderManager::rndpass_pre_proc(struct camera* cam) { + gl_state_begin_event("rndpass_pre_proc"); + render->pre_proc(cam); + Glitter::glt_particle_manager->CalcDisp(); + gl_state_end_event(); + } + void RenderManager::render_single_pass(RenderPassID id) { cpu_time[id] = 0.0; gpu_time[id] = 0.0; @@ -1135,6 +1148,8 @@ namespace rndr { mdl::OBJ_TYPE_TRANSLUCENT_ALPHA_ORDER_1); if (Glitter::glt_particle_manager->CheckHasLocalEffect()) { // X + gl_state_begin_event("local"); + camera* cam = rctx->camera; float_t fov = cam->get_fov(); cam->set_fov(32.2673416137695f); @@ -1155,6 +1170,9 @@ namespace rndr { Glitter::glt_particle_manager->DispScenes(Glitter::DISP_LOCAL); gl_state_set_color_mask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); cam->set_fov(fov); + + gl_state_end_event(); + draw_pass_set_camera(); } @@ -1381,7 +1399,7 @@ void draw_pass_set_camera() { rctx->g_near_far = { (float_t)(max_distance / (max_distance - min_distance)), (float_t)(-(max_distance * min_distance) / (max_distance - min_distance)), - 0.0f, 0.0f + min_distance, max_distance }; } @@ -1798,9 +1816,10 @@ 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); - gl_state_bind_texture_2d(reflect_enable - ? rctx->render_manager->get_render_texture(0).GetColorTex() - : rend->rend_texture[0].GetColorTex()); + RenderTexture& rt = reflect_enable + ? rctx->render_manager->get_render_texture(0) + : rend->rend_texture[0]; + gl_state_bind_texture_2d(rt.GetColorTex()); gl_state_bind_sampler(0, rctx->render_samplers[0]); rctx->render.draw_quad(rt.GetWidth(), rt.GetHeight(), 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f); @@ -1959,8 +1978,7 @@ static void draw_pass_3d_shadow_set(Shadow* shad, render_context* rctx) { gl_state_bind_sampler(7, 0); } -static void draw_pass_3d_translucent(render_context* rctx, bool opaque_enable, - bool transparent_enable, bool translucent_enable, mdl::ObjType opaque, +static void draw_pass_3d_translucent(render_context* rctx, mdl::ObjType opaque, mdl::ObjType transparent, mdl::ObjType translucent) { if (rctx->disp_manager->get_obj_count(opaque) < 1 && rctx->disp_manager->get_obj_count(transparent) < 1 diff --git a/src/CRE/render_manager.hpp b/src/CRE/render_manager.hpp index 636eb30c..bb133bda 100644 --- a/src/CRE/render_manager.hpp +++ b/src/CRE/render_manager.hpp @@ -112,6 +112,8 @@ namespace rndr { void set_shadow_true(); void render_all(); + void rndpass_post_proc(); + void rndpass_pre_proc(struct camera* cam); void render_single_pass(rndr::RenderPassID id); diff --git a/src/KKdLib/obj.hpp b/src/KKdLib/obj.hpp index f784bbfb..63cadd34 100644 --- a/src/KKdLib/obj.hpp +++ b/src/KKdLib/obj.hpp @@ -332,7 +332,7 @@ struct obj_material_data { struct obj_sub_mesh_attrib_member { uint32_t recieve_shadow : 1; uint32_t cast_shadow : 1; - uint32_t transparent : 1; + uint32_t translucent : 1; uint32_t cloth : 1; uint32_t dummy : 28; };