From f276251a3a4ce429e7ac2349c20870710ddb0b6e Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Mon, 20 Mar 2023 19:12:33 -0400 Subject: [PATCH] [jak1] use etie (#2329) Use Jak 2's etie to render shiny background things. To switch back to the old one: ``` (set! *use-etie* #f) ``` and also uncheck this box ![image](https://user-images.githubusercontent.com/48171810/226119270-8d1b8233-bc5f-4bc1-a09b-a6d3183ba2a4.png) (same for `l1`) --- common/custom_data/TFrag3Data.cpp | 24 ++++- common/custom_data/Tfrag3Data.h | 2 +- decompiler/level_extractor/BspHeader.cpp | 34 ++++--- decompiler/level_extractor/BspHeader.h | 8 +- decompiler/level_extractor/extract_tie.cpp | 90 ++++++++++++++----- .../opengl_renderer/OpenGLRenderer.cpp | 6 +- .../opengl_renderer/background/Tie3.cpp | 43 ++++++--- .../opengl_renderer/background/Tie3.h | 18 +++- .../opengl_renderer/shaders/etie.vert | 70 +++++++-------- .../jak1/engine/gfx/background/background.gc | 46 +++++----- goal_src/jak1/engine/gfx/tie/tie-methods.gc | 88 +++++++++++------- 11 files changed, 285 insertions(+), 144 deletions(-) diff --git a/common/custom_data/TFrag3Data.cpp b/common/custom_data/TFrag3Data.cpp index 2cce4c544..14699f5a1 100644 --- a/common/custom_data/TFrag3Data.cpp +++ b/common/custom_data/TFrag3Data.cpp @@ -94,8 +94,30 @@ std::array tie_normal_transform_v2(const std::array(ref, "generic-count", dts); + if (generic_qwc) { + generic_data.resize(16 * generic_qwc); + auto generic_data_ref = deref_label(get_field_ref(ref, "generic-ref", dts)); + memcpy_plain_data((u8*)generic_data.data(), generic_data_ref, generic_qwc * 16); + } } } @@ -1056,22 +1063,23 @@ void PrototypeBucketTie::read_from_file(TypedRef ref, time_of_day.colors.push_back(deref_u32(palette, 3 + i)); } - if (version > GameVersion::Jak1) { - auto fr = get_field_ref(ref, "envmap-shader", dts); - const auto& word = fr.data->words_by_seg.at(fr.seg).at(fr.byte_offset / 4); - if (word.kind() == decompiler::LinkedWord::PTR) { - has_envmap_shader = true; - Ref envmap_shader_ref(deref_label(fr)); - for (int i = 0; i < 5 * 16; i++) { - int byte = envmap_shader_ref.byte_offset + i; - u8 val = - ref.ref.data->words_by_seg.at(envmap_shader_ref.seg).at(byte / 4).get_byte(byte % 4); - envmap_shader[i] = val; - } + auto fr = get_field_ref(ref, "envmap-shader", dts); + const auto& word = fr.data->words_by_seg.at(fr.seg).at(fr.byte_offset / 4); + if (word.kind() == decompiler::LinkedWord::PTR) { + has_envmap_shader = true; + Ref envmap_shader_ref(deref_label(fr)); + for (int i = 0; i < 5 * 16; i++) { + int byte = envmap_shader_ref.byte_offset + i; + u8 val = ref.ref.data->words_by_seg.at(envmap_shader_ref.seg).at(byte / 4).get_byte(byte % 4); + envmap_shader[i] = val; } + } + if (version > GameVersion::Jak1) { u32 tint = read_plain_data_field(ref, "tint-color", dts); - memcpy(tint_color.data(), &tint, 4); + memcpy(jak2_tint_color.data(), &tint, 4); + } else { + jak2_tint_color.fill(0xff); } } diff --git a/decompiler/level_extractor/BspHeader.h b/decompiler/level_extractor/BspHeader.h index d1d9a3f63..7ebb55dba 100644 --- a/decompiler/level_extractor/BspHeader.h +++ b/decompiler/level_extractor/BspHeader.h @@ -407,7 +407,9 @@ struct TieFragment : public Drawable { std::string debug_label_name; - std::vector normals; + std::vector normals; // jak 2 + + std::vector generic_data; // jak 1 // todo, lots more }; @@ -483,8 +485,8 @@ struct PrototypeBucketTie { TimeOfDayPalette time_of_day; bool has_envmap_shader = false; - u8 envmap_shader[5 * 16]; // jak 2 only - math::Vector tint_color; + u8 envmap_shader[5 * 16]; + math::Vector jak2_tint_color; // jak 2 only // todo collide-frag DrawableInlineArrayCollideFragment collide_frag; // todo tie-colors diff --git a/decompiler/level_extractor/extract_tie.cpp b/decompiler/level_extractor/extract_tie.cpp index a79bd1120..3bed0ccfe 100644 --- a/decompiler/level_extractor/extract_tie.cpp +++ b/decompiler/level_extractor/extract_tie.cpp @@ -257,7 +257,6 @@ struct TieProtoVertex { // the vertices make up a triangle strip struct TieStrip { AdgifInfo adgif; - int adgif_idx = -1; std::vector verts; }; @@ -283,6 +282,8 @@ struct TieFrag { // after the prototype program runs std::unordered_map vertex_by_dest_addr; + math::Vector envmap_tint_color = math::Vector::zero(); + // simulate a load in the points data (using vu mem addr) math::Vector lq_points(u32 qw) const { ASSERT(qw >= 50); @@ -363,7 +364,6 @@ struct TieProtoInfo { u32 proto_flag; float stiffness = 0; // wind std::optional envmap_adgif; - math::Vector tint_color = math::Vector::zero(); std::vector time_of_day_colors; // c++ type for time of day data std::vector frags; // the fragments of the prototype }; @@ -628,7 +628,8 @@ u64 alpha_value_for_jak2_tie_or_etie_alpha_override(tfrag3::TieCategory category void update_proto_info(std::vector* out, const std::vector& map, const std::vector& protos, - int geo) { + int geo, + GameVersion version) { out->resize(std::max(out->size(), protos.size())); for (size_t i = 0; i < protos.size(); i++) { const auto& proto = protos[i]; @@ -638,13 +639,17 @@ void update_proto_info(std::vector* out, info.name = proto.name; // wind "stiffness" nonzero value means it has the wind effect info.stiffness = proto.stiffness; + math::Vector jak2_tint_color; if (proto.has_envmap_shader) { std::vector adgif; for (auto x : proto.envmap_shader) { adgif.push_back(x); } info.envmap_adgif = process_adgif(adgif, 0, map, nullptr); - info.tint_color = proto.tint_color; + + if (version > GameVersion::Jak1) { + jak2_tint_color = proto.jak2_tint_color; + } } // bool use_crazy_jak2_etie_alpha_thing = proto.has_envmap_shader; @@ -704,7 +709,7 @@ void update_proto_info(std::vector* out, } } - // normals + // normals (jak 2) const auto& normal_data = proto.geometry[geo].tie_fragments[frag_idx].normals; frag_info.normal_data_packed.resize(normal_data.size() / 4); for (size_t ni = 0; ni < normal_data.size() / 4; ni++) { @@ -713,6 +718,41 @@ void update_proto_info(std::vector* out, } } + if (version > GameVersion::Jak1) { + frag_info.envmap_tint_color = jak2_tint_color; + } + + // normals (jak 1) + auto& generic = proto.geometry[geo].tie_fragments[frag_idx].generic_data; + if (!generic.empty()) { + // fmt::print("Generic for frag {} of {}\n", frag_idx, proto.name); + + struct GenericTieHeader { + u8 effect; + u8 interp_table_size; + u8 num_bps; + u8 num_ips; + math::Vector tint_color; + u16 index_table_offset; + u16 kick_table_offset; + u16 normal_table_offset; + u16 interp_table_offset; + }; + static_assert(sizeof(GenericTieHeader) == 16); + ASSERT(generic.size() >= sizeof(GenericTieHeader)); + GenericTieHeader header; + memcpy(&header, generic.data(), sizeof(GenericTieHeader)); + frag_info.envmap_tint_color = header.tint_color; + int normal_count = header.num_bps + header.num_ips; + frag_info.normal_data_packed.resize(normal_count); + for (int ni = 0; ni < normal_count; ni++) { + for (int j = 0; j < 4; j++) { + frag_info.normal_data_packed[ni][j] = + generic.at(header.normal_table_offset + ni * 4 + j); + } + } + } + info.frags.push_back(std::move(frag_info)); } } @@ -1578,7 +1618,7 @@ void emulate_tie_instance_program(std::vector& protos) { vertex_info.tex.x() = tex_coord.x(); vertex_info.tex.y() = tex_coord.y(); vertex_info.tex.z() = tex_coord.z(); - vertex_info.envmap_tint_color = proto.tint_color; + vertex_info.envmap_tint_color = frag.envmap_tint_color; vertex_info.nrm = frag.get_normal_if_present(normal_table_offset++); bool inserted = frag.vertex_by_dest_addr.insert({(u32)dest_ptr, vertex_info}).second; @@ -1622,7 +1662,7 @@ void emulate_tie_instance_program(std::vector& protos) { vertex_info.tex.x() = tex_coord.x(); vertex_info.tex.y() = tex_coord.y(); vertex_info.tex.z() = tex_coord.z(); - vertex_info.envmap_tint_color = proto.tint_color; + vertex_info.envmap_tint_color = frag.envmap_tint_color; vertex_info.nrm = frag.get_normal_if_present(normal_table_offset++); // lg::print("double draw: {} {}\n", dest_ptr, dest2_ptr); @@ -1746,7 +1786,7 @@ void emulate_tie_instance_program(std::vector& protos) { vertex_info.tex.x() = tex_coord.x(); vertex_info.tex.y() = tex_coord.y(); vertex_info.tex.z() = tex_coord.z(); - vertex_info.envmap_tint_color = proto.tint_color; + vertex_info.envmap_tint_color = frag.envmap_tint_color; vertex_info.nrm = frag.get_normal_if_present(normal_table_offset++); bool inserted = frag.vertex_by_dest_addr.insert({(u32)dest_ptr, vertex_info}).second; @@ -1780,7 +1820,7 @@ void emulate_tie_instance_program(std::vector& protos) { vertex_info.tex.x() = tex_coord.x(); vertex_info.tex.y() = tex_coord.y(); vertex_info.tex.z() = tex_coord.z(); - vertex_info.envmap_tint_color = proto.tint_color; + vertex_info.envmap_tint_color = frag.envmap_tint_color; vertex_info.nrm = frag.get_normal_if_present(normal_table_offset++); bool inserted = frag.vertex_by_dest_addr.insert({(u32)dest_ptr, vertex_info}).second; @@ -1805,10 +1845,15 @@ void emulate_tie_instance_program(std::vector& protos) { program_end:; if (!frag.normal_data_packed.empty()) { // check that we have a normal per point, if we have normals - size_t rounded_up_dvert = (nd.bp1 + nd.bp2 + nd.ip1 + nd.ip2) + 3; + // in ETIE, the normal count must be a multiple of 4 due to VIF upload + // in Jak 1, generic processes normals on the EE, so there is no multiple of 4 requirement. + // so we allow either a round-up-to-nearest-four or exact match to pass here. + size_t total_dvert = nd.bp1 + nd.bp2 + nd.ip1 + nd.ip2; + size_t rounded_up_dvert = total_dvert + 3; rounded_up_dvert /= 4; rounded_up_dvert *= 4; - ASSERT(rounded_up_dvert == frag.normal_data_packed.size()); + ASSERT(rounded_up_dvert == frag.normal_data_packed.size() || + total_dvert == frag.normal_data_packed.size()); } // ASSERT(false); } @@ -1838,7 +1883,6 @@ void emulate_kicks(std::vector& protos) { ASSERT(frag.prog_info.adgif_offset_in_gif_buf_qw.size() == frag.adgifs.size()); const AdgifInfo* adgif_info = nullptr; - int adgif_info_idx = -1; int expected_next_tag = 0; // loop over strgifs @@ -1848,7 +1892,6 @@ void emulate_kicks(std::vector& protos) { // yep int idx = adgif_it - frag.prog_info.adgif_offset_in_gif_buf_qw.begin(); adgif_info = &frag.adgifs.at(idx); - adgif_info_idx = idx; // the next strgif should come 6 qw's after expected_next_tag += 6; adgif_it++; @@ -1878,7 +1921,6 @@ void emulate_kicks(std::vector& protos) { frag.strips.emplace_back(); auto& strip = frag.strips.back(); strip.adgif = *adgif_info; - strip.adgif_idx = adgif_info_idx; // loop over all the vertices the strgif says we'll have for (int vtx = 0; vtx < str_it->nloop; vtx++) { // compute the address of this vertex (stored after the strgif) @@ -2219,6 +2261,15 @@ DrawMode process_draw_mode(const AdgifInfo& info, if (version == GameVersion::Jak1) { // use alpha from adgif shader, that's what we did in the past (could be wrong?) update_mode_from_alpha1(info.alpha_val, mode); + if (tfrag3::is_envmap_second_draw_category(category)) { + mode.enable_ab(); + } + + if (tfrag3::is_envmap_first_draw_category(category)) { + // decal seems to be somewhat rarely enbaled on envmapped stuff where it's clearly wrong (edge + // the fj temple before the room with the blue eco switch) + mode.disable_decal(); + } } else { if (tfrag3::is_envmap_second_draw_category(category)) { // envmap shader gets to control its own alpha @@ -2259,8 +2310,10 @@ DrawMode process_envmap_draw_mode(const AdgifInfo& info, TieCategoryInfo get_jak1_tie_category(u32 flags) { TieCategoryInfo result; - result.category = tfrag3::TieCategory::NORMAL; result.uses_envmap = flags & 2; + result.category = + result.uses_envmap ? tfrag3::TieCategory::NORMAL_ENVMAP : tfrag3::TieCategory::NORMAL; + result.envmap_second_draw_category = tfrag3::TieCategory::NORMAL_ENVMAP_SECOND_DRAW; return result; } @@ -2495,11 +2548,6 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree, ASSERT_NOT_REACHED(); } - if (info.uses_envmap && version == GameVersion::Jak1) { - // envmap ties go through generic (for now...) - continue; - } - // bool using_wind = true; // hack, for testing bool using_wind = proto.stiffness != 0.f; @@ -2692,7 +2740,7 @@ void extract_tie(const level_tools::DrawableTreeInstanceTie* tree, // convert level format data to a nicer format auto info = collect_instance_info(as_instance_array, &tree->prototypes.prototype_array_tie.data, geo); - update_proto_info(&info, tex_map, tree->prototypes.prototype_array_tie.data, geo); + update_proto_info(&info, tex_map, tree->prototypes.prototype_array_tie.data, geo, version); if (version != GameVersion::Jak2) { check_wind_vectors_zero(info, tree->prototypes.wind_vectors); } diff --git a/game/graphics/opengl_renderer/OpenGLRenderer.cpp b/game/graphics/opengl_renderer/OpenGLRenderer.cpp index f9c76d166..532a84b75 100644 --- a/game/graphics/opengl_renderer/OpenGLRenderer.cpp +++ b/game/graphics/opengl_renderer/OpenGLRenderer.cpp @@ -283,7 +283,8 @@ void OpenGLRenderer::init_bucket_renderers_jak1() { // 7 : TFRAG_NEAR_LEVEL0 // 8 : TIE_NEAR_LEVEL0 // 9 : TIE_LEVEL0 - init_bucket_renderer("l0-tfrag-tie", BucketCategory::TIE, BucketId::TIE_LEVEL0, 0); + init_bucket_renderer("l0-tfrag-tie", BucketCategory::TIE, + BucketId::TIE_LEVEL0, 0); // 10 : MERC_TFRAG_TEX_LEVEL0 init_bucket_renderer("l0-tfrag-merc", BucketCategory::MERC, BucketId::MERC_TFRAG_TEX_LEVEL0); @@ -303,7 +304,8 @@ void OpenGLRenderer::init_bucket_renderers_jak1() { // 14 : TFRAG_NEAR_LEVEL1 // 15 : TIE_NEAR_LEVEL1 // 16 : TIE_LEVEL1 - init_bucket_renderer("l1-tfrag-tie", BucketCategory::TIE, BucketId::TIE_LEVEL1, 1); + init_bucket_renderer("l1-tfrag-tie", BucketCategory::TIE, + BucketId::TIE_LEVEL1, 1); // 17 : MERC_TFRAG_TEX_LEVEL1 init_bucket_renderer("l1-tfrag-merc", BucketCategory::MERC, BucketId::MERC_TFRAG_TEX_LEVEL1); diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index e0024cd1c..fb1c70dec 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -316,12 +316,18 @@ bool Tie3::set_up_common_data_from_dma(DmaFollower& dma, SharedRenderState* rend auto proto_mask_data = dma.read_and_advance(); m_common_data.proto_vis_data = proto_mask_data.data; m_common_data.proto_vis_data_size = proto_mask_data.size_bytes; - // jak 2 envmap color - auto envmap_color = dma.read_and_advance(); - ASSERT(envmap_color.size_bytes == 16); - memcpy(m_common_data.envmap_color.data(), envmap_color.data, 16); - m_common_data.envmap_color /= 128.f; } + + // envmap color + auto envmap_color = dma.read_and_advance(); + ASSERT(envmap_color.size_bytes == 16); + memcpy(m_common_data.envmap_color.data(), envmap_color.data, 16); + m_common_data.envmap_color /= 128.f; + if (render_state->version == GameVersion::Jak1) { + m_common_data.envmap_color *= 2; + } + m_common_data.envmap_color *= m_envmap_strength; + m_common_data.frame_idx = render_state->frame_idx; while (dma.current_tag_offset() != render_state->next_bucket) { @@ -386,11 +392,7 @@ void Tie3::draw_matching_draws_for_all_trees(int geom, ScopedProfilerNode& prof, tfrag3::TieCategory category) { for (u32 i = 0; i < m_trees[geom].size(); i++) { - if (tfrag3::is_envmap_first_draw_category(category)) { - draw_matching_draws_for_tree(i, geom, settings, render_state, prof, category); - } else { - draw_matching_draws_for_tree(i, geom, settings, render_state, prof, category); - } + draw_matching_draws_for_tree(i, geom, settings, render_state, prof, category); } } @@ -630,7 +632,7 @@ void Tie3::draw_matching_draws_for_tree(int idx, glBindVertexArray(0); - if (use_envmap) { + if (use_envmap && m_draw_envmap_second_draw) { envmap_second_pass_draw(tree, settings, render_state, prof, tfrag3::get_second_draw_category(category)); } @@ -695,6 +697,8 @@ void Tie3::envmap_second_pass_draw(const Tree& tree, } void Tie3::draw_debug_window() { + ImGui::Checkbox("envmap 2nd draw", &m_draw_envmap_second_draw); + ImGui::SliderFloat("envmap str", &m_envmap_strength, 0, 2); ImGui::Checkbox("Fast ToD", &m_use_fast_time_of_day); ImGui::SameLine(); ImGui::Checkbox("All Visible", &m_debug_all_visible); @@ -993,3 +997,20 @@ void Tie3AnotherCategory::render(DmaFollower& dma, } m_parent->render_from_another(render_state, prof, m_category); } + +Tie3WithEnvmapJak1::Tie3WithEnvmapJak1(const std::string& name, int my_id, int level_id) + : Tie3(name, my_id, level_id, tfrag3::TieCategory::NORMAL) {} + +void Tie3WithEnvmapJak1::render(DmaFollower& dma, + SharedRenderState* render_state, + ScopedProfilerNode& prof) { + Tie3::render(dma, render_state, prof); + if (m_enable_envmap) { + render_from_another(render_state, prof, tfrag3::TieCategory::NORMAL_ENVMAP); + } +} + +void Tie3WithEnvmapJak1::draw_debug_window() { + ImGui::Checkbox("envmap", &m_enable_envmap); + Tie3::draw_debug_window(); +} diff --git a/game/graphics/opengl_renderer/background/Tie3.h b/game/graphics/opengl_renderer/background/Tie3.h index 899a11e06..27075c003 100644 --- a/game/graphics/opengl_renderer/background/Tie3.h +++ b/game/graphics/opengl_renderer/background/Tie3.h @@ -99,10 +99,12 @@ class Tie3 : public BucketRenderer { TfragRenderSettings settings; const u8* proto_vis_data = nullptr; u32 proto_vis_data_size = 0; - math::Vector4f envmap_color; + math::Vector4f envmap_color = math::Vector4f{2.f, 2.f, 2.f, 2.f}; u64 frame_idx = -1; } m_common_data; + float m_envmap_strength = 1.f; + struct Tree { GLuint vertex_buffer; GLuint index_buffer; @@ -150,6 +152,7 @@ class Tie3 : public BucketRenderer { bool m_use_fast_time_of_day = true; bool m_debug_all_visible = false; bool m_hide_wind = false; + bool m_draw_envmap_second_draw = true; TfragPcPortData m_pc_port_data; @@ -182,4 +185,17 @@ class Tie3AnotherCategory : public BucketRenderer { private: Tie3* m_parent; tfrag3::TieCategory m_category; +}; + +/*! + * Jak 1 - specific renderer that does TIE and TIE envmap in one. + */ +class Tie3WithEnvmapJak1 : public Tie3 { + public: + Tie3WithEnvmapJak1(const std::string& name, int my_id, int level_id); + void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override; + void draw_debug_window() override; + + private: + bool m_enable_envmap = true; }; \ No newline at end of file diff --git a/game/graphics/opengl_renderer/shaders/etie.vert b/game/graphics/opengl_renderer/shaders/etie.vert index 56e28b2c0..dafb15fa9 100644 --- a/game/graphics/opengl_renderer/shaders/etie.vert +++ b/game/graphics/opengl_renderer/shaders/etie.vert @@ -25,10 +25,7 @@ uniform vec4 persp1; uniform mat4 cam_no_persp; void main() { - - // maybe we could do fog faster using intermediate results from below, but it doesn't seem significant. - float fog1 = camera[3].w + camera[0].w * position_in.x + camera[1].w * position_in.y + camera[2].w * position_in.z; - fogginess = 255 - clamp(fog1 + hvdf_offset.w, fog_min, fog_max); + fogginess = 0; // rotate the normal vec3 nrm_vf23 = cam_no_persp[0].xyz * normal.x @@ -42,7 +39,7 @@ void main() { vf17 += cam_no_persp[1] * position_in.y; vf17 += cam_no_persp[2] * position_in.z; - /* + // This is the ETIE math. // It seems right only if the nrm_vf23 is normalized first // (and in this case it's identical the emerc math below) @@ -50,7 +47,7 @@ void main() { // likely on PS2, their normal transformation matrix was scaled correctly. // ours isn't. (yes, the camera matrix is a pure rotation and that doesn't matter, but the // instance matrix used to de-instance the mesh needs the correction, and we don't have it) - if (use_emerc_math == 0) { + { nrm_vf23 = nrm_vf23; // nrm.z -= 1 //subw.z vf23, vf23, vf00 @@ -96,7 +93,7 @@ void main() { //addw.xy vf23, vf23, vf03 nrm_vf23.xy += 0.5; tex_coord = nrm_vf23; - }*/ + } //;; perspective transform //mula.xy ACC, vf10, vf17 ;; acc build 1 @@ -111,35 +108,35 @@ void main() { float pQ = 1.f / p_proj.w; // EMERC version of the math - { - // emerc hack - vec3 vf10 = normalize(r_nrm); - //subw.z vf10, vf10, vf00 ;; subtract 1 from z - vf10.z -= 1; - //addw.z vf09, vf00, vf09 ;; xyww the unperspected thing - vec4 vf09 = vf17; - //mul.xyz vf15, vf09, vf10 ;; - vec3 vf15 = vf09.xyz * vf10.xyz; - //adday.xyzw vf15, vf15 - //maddz.x vf15, vf21, vf15 - float vf15_x = vf15.x + vf15.y + vf15.z; - //div Q, vf15.x, vf10.z - float qq = vf15_x / vf10.z; - //mulaw.xyzw ACC, vf09, vf00 - vec3 ACC = vf09.xyz; - //madd.xyzw vf10, vf10, Q - vf10 = ACC + vf10 * qq; - //eleng.xyz P, vf10 - float P = length(vf10.xyz); - //mfp.w vf10, P - //div Q, vf23.z, vf10.w - float qqq = 0.5 / P; - //addaz.xyzw vf00, vf23 - ACC = vec3(0.5, 0.5, 0.5); - //madd.xyzw vf10, vf10, Q - vf10 = ACC + vf10 * qqq; - tex_coord = vf10.xyz; - } +// { +// // emerc hack +// vec3 vf10 = normalize(r_nrm); +// //subw.z vf10, vf10, vf00 ;; subtract 1 from z +// vf10.z -= 1; +// //addw.z vf09, vf00, vf09 ;; xyww the unperspected thing +// vec4 vf09 = vf17; +// //mul.xyz vf15, vf09, vf10 ;; +// vec3 vf15 = vf09.xyz * vf10.xyz; +// //adday.xyzw vf15, vf15 +// //maddz.x vf15, vf21, vf15 +// float vf15_x = vf15.x + vf15.y + vf15.z; +// //div Q, vf15.x, vf10.z +// float qq = vf15_x / vf10.z; +// //mulaw.xyzw ACC, vf09, vf00 +// vec3 ACC = vf09.xyz; +// //madd.xyzw vf10, vf10, Q +// vf10 = ACC + vf10 * qq; +// //eleng.xyz P, vf10 +// float P = length(vf10.xyz); +// //mfp.w vf10, P +// //div Q, vf23.z, vf10.w +// float qqq = 0.5 / P; +// //addaz.xyzw vf00, vf23 +// ACC = vec3(0.5, 0.5, 0.5); +// //madd.xyzw vf10, vf10, Q +// vf10 = ACC + vf10 * qqq; +// tex_coord = vf10.xyz; +// } vec4 transformed = p_proj * pQ; @@ -161,5 +158,4 @@ void main() { fragment_color = proto_tint * envmap_tod_tint; - } diff --git a/goal_src/jak1/engine/gfx/background/background.gc b/goal_src/jak1/engine/gfx/background/background.gc index e6637e4b5..19f71624a 100644 --- a/goal_src/jak1/engine/gfx/background/background.gc +++ b/goal_src/jak1/engine/gfx/background/background.gc @@ -181,6 +181,8 @@ ) ) +(define *use-etie* #t) + (defun finish-background () "Complete the background drawing. This function should run after the background engine has executed. @@ -509,31 +511,33 @@ ) ;; TIE Generic - (dotimes (gp-2 (-> *background-work* tie-tree-count)) - (when (nonzero? (-> *background-work* tie-generic gp-2)) - ;; send to the generic foreground with tfrag textures bucket for this level - (let* ((s5-4 (-> *background-work* tie-levels gp-2 tfrag-tex-foreground-sink-group generic-sink)) - (s3-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) - (s4-3 (-> s3-1 base)) - ) - (generic-tie-execute s5-4 s3-1 (-> *background-work* tie-generic gp-2)) - (let ((a3-0 (-> s3-1 base))) - (let ((v1-219 (the-as object (-> s3-1 base)))) - (set! (-> (the-as dma-packet v1-219) dma) (new 'static 'dma-tag :id (dma-tag-id next))) - (set! (-> (the-as dma-packet v1-219) vif0) (new 'static 'vif-tag)) - (set! (-> (the-as dma-packet v1-219) vif1) (new 'static 'vif-tag)) - (set! (-> s3-1 base) (&+ (the-as pointer v1-219) 16)) - ) - (dma-bucket-insert-tag - (-> *display* frames (-> *display* on-screen) frame bucket-group) - (-> s5-4 bucket) - s4-3 - (the-as (pointer dma-tag) a3-0) + (when (not *use-etie*) + (dotimes (gp-2 (-> *background-work* tie-tree-count)) + (when (nonzero? (-> *background-work* tie-generic gp-2)) + ;; send to the generic foreground with tfrag textures bucket for this level + (let* ((s5-4 (-> *background-work* tie-levels gp-2 tfrag-tex-foreground-sink-group generic-sink)) + (s3-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) + (s4-3 (-> s3-1 base)) + ) + (generic-tie-execute s5-4 s3-1 (-> *background-work* tie-generic gp-2)) + (let ((a3-0 (-> s3-1 base))) + (let ((v1-219 (the-as object (-> s3-1 base)))) + (set! (-> (the-as dma-packet v1-219) dma) (new 'static 'dma-tag :id (dma-tag-id next))) + (set! (-> (the-as dma-packet v1-219) vif0) (new 'static 'vif-tag)) + (set! (-> (the-as dma-packet v1-219) vif1) (new 'static 'vif-tag)) + (set! (-> s3-1 base) (&+ (the-as pointer v1-219) 16)) + ) + (dma-bucket-insert-tag + (-> *display* frames (-> *display* on-screen) frame bucket-group) + (-> s5-4 bucket) + s4-3 + (the-as (pointer dma-tag) a3-0) + ) ) ) ) ) - ) + ) ) ) diff --git a/goal_src/jak1/engine/gfx/tie/tie-methods.gc b/goal_src/jak1/engine/gfx/tie/tie-methods.gc index 57581d93e..57ab4f4f8 100644 --- a/goal_src/jak1/engine/gfx/tie/tie-methods.gc +++ b/goal_src/jak1/engine/gfx/tie/tie-methods.gc @@ -8,12 +8,29 @@ (def-mips2c draw-inline-array-instance-tie (function pointer (inline-array instance-tie) int dma-buffer none)) (def-mips2c draw-inline-array-prototype-tie-generic-asm (function dma-buffer int prototype-array-tie none)) +(defun pc-add-tie-envmap-info ((dma-buf dma-buffer)) + (let ((packet (the-as dma-packet (-> dma-buf base)))) + (set! (-> packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc 1)) + (set! (-> packet vif0) (new 'static 'vif-tag)) + (set! (-> packet vif1) (new 'static 'vif-tag :cmd (vif-cmd pc-port))) + (set! (-> dma-buf base) (the pointer (&+ packet 16))) + (set! (-> (the (pointer uint128) (-> dma-buf base))) + (if (and *time-of-day-context* + (nonzero? *time-of-day-context*)) + (-> *time-of-day-context* current-sun env-color quad) + (the uint128 0) + ) + ) + (set! (-> dma-buf base) (the pointer (&+ packet 32))) + ) + ) + (defun tie-init-buffers ((arg0 dma-buffer)) "Initialize the TIE buckets. Note: the buffer passed in here is _not_ used. this function should be called _after_ all TIE drawing is done. It will skip setup if there is nothing drawn." - + ;; the TIE buckets are only used by TIE - so we can safely splice things at the beginning/end without ;; messing things up. (let ((gp-0 (-> *display* frames (-> *display* on-screen) frame bucket-group (bucket-id tie-0)))) @@ -39,7 +56,7 @@ ) ) ) - + (let ((gp-1 (-> *display* frames (-> *display* on-screen) frame bucket-group (bucket-id tie-0)))) ;; only if we have something in teh bucket (when (!= gp-1 (-> gp-1 last)) @@ -61,7 +78,7 @@ ) ) ) - + ;; same as above, but for level 1's tie. (let ((gp-2 (-> *display* frames (-> *display* on-screen) frame bucket-group (bucket-id tie-1)))) (when (!= gp-2 (-> gp-2 last)) @@ -102,7 +119,7 @@ ) ) ) - + #| ;; level 0's tie near (let ((gp-4 (-> *display* frames (-> *display* on-screen) frame bucket-group (bucket-id tie-near-0)))) @@ -150,7 +167,7 @@ ) ) ) - + ;; level 1's tie near (let ((gp-6 (-> *display* frames (-> *display* on-screen) frame bucket-group (bucket-id tie-near-1)))) (when (!= gp-6 (-> gp-6 last)) @@ -275,7 +292,7 @@ (defun draw-drawable-tree-instance-tie ((arg0 drawable-tree-instance-tie) (arg1 level)) "Actually draw TIE instances. Will draw TIE, TIE-NEAR, and GENERIC" - + ;; todo kill (local-vars (r0-0 none) @@ -289,16 +306,16 @@ (a0-84 int) (sv-16 int) ) - + ;; only if one of our renderers is enabled. (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie-near tie generic)) ;; setup work (TODO, what uses TIE wind?) (set! (-> *instance-tie-work* first-generic-prototype) (the-as uint 0)) (set! (-> *instance-tie-work* wind-vectors) (-> arg0 prototypes wind-vectors)) - - ;; + + ;; (let ((s4-0 (+ (-> arg0 length) -1))) ;; number of arrays of draw-nodes (depth of the BVH tree, not counting instance leaves) - + ;; perform draw node culling. ;; Note: It's okay to skip this. The visible list right now will just be the occlusion string ;; The PC renderer won't see this (and has its own version of culling that's plenty fast) @@ -324,12 +341,12 @@ ) ) |# - + (let* ((v1-16 (-> arg0 data s4-0)) ;; leaves (s4-1 (-> arg0 prototypes prototype-array-tie)) ;; prototypes (s5-1 (-> s4-1 length)) ;; number of prototypes ) - + (dotimes (a0-11 s5-1) ;; loop over prototypes, zero stuff?? (let ((a1-7 (-> s4-1 array-data a0-11))) (set! (-> a1-7 next-clear) (the-as uint128 0)) @@ -338,16 +355,16 @@ ) 0 ) - + (let* ((s1-0 (-> (the-as drawable-inline-array-instance-tie v1-16) data)) ;; the inline array of instances (s0-0 (&-> (scratchpad-object terrain-context) work background vis-list (/ (-> s1-0 0 id) 8))) ;; vis for first. (s3-1 (-> *display* frames (-> *display* on-screen) frame global-buf)) ;; dma buf to write to ) (set! sv-16 (-> (the-as drawable-inline-array-node v1-16) length)) ;; number of instances - + ;; if we actually have things to draw (when (nonzero? sv-16) - + ;; this is some buffer for the generic renderer (let* ((v1-21 (logand (the-as int *gsf-buffer*) 8191)) (v1-23 (logand (the-as int (&- (logand (the-as int (&-> (-> s4-1 data) -512)) 8191) (the-as uint v1-21))) 8191)) @@ -357,8 +374,8 @@ ;; in the actual DMA generation code. (set! *instance-tie-work-copy* (the-as instance-tie-work (+ (the-as int *gsf-buffer*) v1-23))) ) - - + + ;;; TIE instance Drawing ;; we do the instances first so the prototypes that aren't drawn can be skipped. (let ((s2-0 (-> *display* frames (-> *display* on-screen) frame global-buf base))) @@ -368,24 +385,26 @@ (set! (-> *instance-tie-work-copy* wait-to-spr) (the-as uint 0)) (set! (-> *instance-tie-work-copy* wait-from-spr) (the-as uint 0)) (reset! (-> *perf-stats* data 9)) - + ;; DRAW! ;; note: this is a bit wasteful because we only care about generic ties. ;; non-generics are drawn fully in C++, but we're computing unused stuff here. ;; This ends up being so fast it's probably not worth worrying about yet. - (with-profiler "tie-instance" (draw-inline-array-instance-tie s0-0 s1-0 sv-16 s3-1)) + (when (not *use-etie*) + (with-profiler "tie-instance" (draw-inline-array-instance-tie s0-0 s1-0 sv-16 s3-1)) + ) ;; finish perf stats (read! (-> *perf-stats* data 9)) (update-wait-stats (-> *perf-stats* data 9) (the-as uint 0) (-> *instance-tie-work-copy* wait-to-spr) (-> *instance-tie-work-copy* wait-from-spr)) - + ;; copy out things from instance tie work (let ((v1-42 (-> *instance-tie-work-copy* min-dist quad))) (set! (-> *instance-tie-work* min-dist quad) v1-42) ) (set! (-> *instance-tie-work* flags) (-> *instance-tie-work-copy* flags)) - + ;; update memory usage (let ((a0-38 *dma-mem-usage*)) (when (nonzero? a0-38) @@ -399,15 +418,17 @@ ) ) ) - + ;; Generic TIE prototype drawing - (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (when (and (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) + (not *use-etie*) + ) (when (logtest? (-> *instance-tie-work* flags) 2) (let ((s2-1 (-> *display* frames (-> *display* on-screen) frame global-buf base))) (set! (-> *prototype-tie-work* generic-wait-to-spr) (the-as uint 0)) (set! (-> *prototype-tie-work* generic-wait-from-spr) (the-as uint 0)) (set! (-> *instance-tie-work* first-generic-prototype) (the-as uint (-> s3-1 base))) - + ;; hack, I expect this to overwrite this. (set! (-> (the (pointer uint64) (-> s3-1 base))) #xdeadbeefdeadbeef) (reset! (-> *perf-stats* data 10)) @@ -432,7 +453,7 @@ ) ) ) - + ;; Normal TIE prototype drawing (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie)) (let ((s3-2 (-> *display* frames (-> *display* on-screen) frame global-buf base))) @@ -446,12 +467,13 @@ ;;(draw-inline-array-prototype-tie-asm s1-1 s5-1 s4-1) (add-pc-tfrag3-data s1-1 (-> *level* data (-> (scratchpad-object terrain-context) bsp lev-index))) (add-pc-wind-data s1-1) + (pc-add-tie-envmap-info s1-1) (read! (-> *perf-stats* data 11)) (update-wait-stats (-> *perf-stats* data 11) (the-as uint 0) (-> *prototype-tie-work* wait-to-spr) (-> *prototype-tie-work* wait-from-spr) ) - + ;; this actually generates real drawing DMA, so add it to the appropriate bucket. (let ((a3-11 (-> s1-1 base))) (let ((v1-94 (the-as object (-> s1-1 base)))) @@ -486,7 +508,7 @@ ) ) ) - + #| (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie-near)) (let ((s3-3 (-> *display* frames (-> *display* on-screen) frame global-buf base))) @@ -560,19 +582,19 @@ (defmethod collect-stats drawable-tree-instance-tie ((obj drawable-tree-instance-tie)) "Collect statistics on TIE drawing." - + ;; only if tie/generic ran (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie-near tie generic)) ;; unused? (-> obj data (+ (-> obj length) -1)) - + ;; loop over all prototypes. ;; the drawing process will write to the prototypes to say how many of each it draws (let ((v1-8 (-> obj prototypes prototype-array-tie))) (dotimes (a0-1 (-> v1-8 length)) ;; grap the prototype (let ((a1-2 (-> v1-8 array-data a0-1))) - + ;; GENERIC (when (logtest? *vu1-enable-user* (vu1-renderer-mask generic)) ;; there are 4 arrays of fragments per prototype. Looks like we check them all for generic. @@ -590,7 +612,7 @@ (+! (-> *terrain-stats* tie-generic groups) 1) ;; number of geometries drawn (unique) (+! (-> *terrain-stats* tie-generic fragments) t2-1) ;; number of frags drawn (unique) (+! (-> *terrain-stats* tie-generic instances) t0-2) ;; number of instances drawn (not unique) - + ;; now, collect stats per fragment (dotimes (t3-9 t2-1) (let ((t5-0 (* (-> (the-as tie-fragment t1-3) num-tris) t0-2)) ;; multiply by number of instances @@ -608,7 +630,7 @@ ) ) ) - + ;; normal tie (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie)) (let ((a2-9 1) ;; looks like we never draw geom 0's with normal tie? @@ -641,7 +663,7 @@ ) ) ) - + ;; near tie (when (logtest? *vu1-enable-user* (vu1-renderer-mask tie-near)) (let ((a2-14 (-> a1-2 count 0)) ;; always geom 0.