From a918e2d9dea05687d2e2165dd527da031995e093 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Sat, 29 Jul 2023 20:34:42 -0400 Subject: [PATCH] [gfx] Clean up background renderer matrices, fix "hole covers" (#2866) The way we got/stored background matrices is a bit weird and full of leftovers from the first attempts at porting renderers. This doesn't work well with the Jak 2 "other camera" system where some stuff is rendered with a different camera matrix. This cleans most of it up. The exception is that the collide mesh renderer and the additional sprite culling I added still need to peek at some cached camera matrices. This fixes the problem where etie uses the wrong matrices for "other camera" levels. Now the "hole covers" go in the holes in the background of the throne room. ![image](https://github.com/open-goal/jak-project/assets/48171810/73a88f7b-05d4-4e9c-bb34-5b45efffcb69) --- .../graphics/opengl_renderer/BucketRenderer.h | 6 --- .../opengl_renderer/CollideMeshRenderer.cpp | 21 +++------ .../opengl_renderer/background/Shrub.cpp | 16 ++----- .../opengl_renderer/background/TFragment.cpp | 32 ++++++-------- .../opengl_renderer/background/TFragment.h | 2 - .../opengl_renderer/background/Tie3.cpp | 43 ++++++++----------- .../background/background_common.cpp | 27 ++++++------ .../background/background_common.h | 22 +++++----- 8 files changed, 62 insertions(+), 107 deletions(-) diff --git a/game/graphics/opengl_renderer/BucketRenderer.h b/game/graphics/opengl_renderer/BucketRenderer.h index 61877546d5..05ec7cf726 100644 --- a/game/graphics/opengl_renderer/BucketRenderer.h +++ b/game/graphics/opengl_renderer/BucketRenderer.h @@ -55,12 +55,6 @@ struct SharedRenderState { // including transformation, rotation, perspective math::Vector4f camera_matrix[4]; - - // including transformation, rotation - math::Vector4f camera_no_persp[4]; - - // just the perspective - math::Vector4f camera_persp[4]; math::Vector4f camera_hvdf_off; math::Vector4f camera_fog; math::Vector4f camera_pos; diff --git a/game/graphics/opengl_renderer/CollideMeshRenderer.cpp b/game/graphics/opengl_renderer/CollideMeshRenderer.cpp index 9ad6eac363..1a581a79ef 100644 --- a/game/graphics/opengl_renderer/CollideMeshRenderer.cpp +++ b/game/graphics/opengl_renderer/CollideMeshRenderer.cpp @@ -106,27 +106,20 @@ void CollideMeshRenderer::render(SharedRenderState* render_state, ScopedProfiler render_state->shaders[ShaderId::COLLISION].activate(); glBindVertexArray(m_vao); - TfragRenderSettings settings; - memcpy(settings.math_camera.data(), render_state->camera_matrix[0].data(), 64); - settings.hvdf_offset = render_state->camera_hvdf_off; - settings.fog = render_state->camera_fog; - settings.tree_idx = 0; - for (int i = 0; i < 4; i++) { - settings.planes[i] = render_state->camera_planes[i]; - } auto shader = render_state->shaders[ShaderId::COLLISION].id(); glUniformBlockBinding(shader, glGetUniformBlockIndex(shader, "PatColors"), 0); glBindBufferBase(GL_UNIFORM_BUFFER, 0, m_ubo); glUniformMatrix4fv(glGetUniformLocation(shader, "camera"), 1, GL_FALSE, - settings.math_camera.data()); - glUniform4f(glGetUniformLocation(shader, "hvdf_offset"), settings.hvdf_offset[0], - settings.hvdf_offset[1], settings.hvdf_offset[2], settings.hvdf_offset[3]); + render_state->camera_matrix[0].data()); + glUniform4f(glGetUniformLocation(shader, "hvdf_offset"), render_state->camera_hvdf_off[0], + render_state->camera_hvdf_off[1], render_state->camera_hvdf_off[2], + render_state->camera_hvdf_off[3]); const auto& trans = render_state->camera_pos; glUniform4f(glGetUniformLocation(shader, "camera_position"), trans[0], trans[1], trans[2], trans[3]); - glUniform1f(glGetUniformLocation(shader, "fog_constant"), settings.fog.x()); - glUniform1f(glGetUniformLocation(shader, "fog_min"), settings.fog.y()); - glUniform1f(glGetUniformLocation(shader, "fog_max"), settings.fog.z()); + glUniform1f(glGetUniformLocation(shader, "fog_constant"), render_state->camera_fog.x()); + glUniform1f(glGetUniformLocation(shader, "fog_min"), render_state->camera_fog.y()); + glUniform1f(glGetUniformLocation(shader, "fog_max"), render_state->camera_fog.z()); glUniform1i(glGetUniformLocation(shader, "version"), (GLint)render_state->version); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_GEQUAL); diff --git a/game/graphics/opengl_renderer/background/Shrub.cpp b/game/graphics/opengl_renderer/background/Shrub.cpp index 225a0d8ca3..66dba11a46 100644 --- a/game/graphics/opengl_renderer/background/Shrub.cpp +++ b/game/graphics/opengl_renderer/background/Shrub.cpp @@ -50,22 +50,12 @@ void Shrub::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProf } TfragRenderSettings settings; - settings.hvdf_offset = m_pc_port_data.hvdf_off; - settings.fog = m_pc_port_data.fog; + settings.camera = m_pc_port_data.camera; - memcpy(settings.math_camera.data(), m_pc_port_data.camera[0].data(), 64); settings.tree_idx = 0; - for (int i = 0; i < 4; i++) { - settings.itimes[i] = m_pc_port_data.itimes[i]; - } - update_render_state_from_pc_settings(render_state, m_pc_port_data); - for (int i = 0; i < 4; i++) { - settings.planes[i] = m_pc_port_data.planes[i]; - } - m_has_level = setup_for_level(m_pc_port_data.level_name, render_state); render_all_trees(settings, render_state, prof); } @@ -245,9 +235,9 @@ void Shrub::render_tree(int idx, Timer interp_timer; #ifndef __aarch64__ if (m_use_fast_time_of_day) { - interp_time_of_day_fast(settings.itimes, tree.tod_cache, m_color_result.data()); + interp_time_of_day_fast(settings.camera.itimes, tree.tod_cache, m_color_result.data()); } else { - interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); + interp_time_of_day_slow(settings.camera.itimes, *tree.colors, m_color_result.data()); } #else interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); diff --git a/game/graphics/opengl_renderer/background/TFragment.cpp b/game/graphics/opengl_renderer/background/TFragment.cpp index 9e5079119a..420535cfe5 100644 --- a/game/graphics/opengl_renderer/background/TFragment.cpp +++ b/game/graphics/opengl_renderer/background/TFragment.cpp @@ -151,10 +151,8 @@ void TFragment::render(DmaFollower& dma, { setup_for_level(m_tree_kinds, level_name, render_state); TfragRenderSettings settings; - settings.hvdf_offset = m_tfrag_data.hvdf_offset; - settings.fog = m_tfrag_data.fog; - memcpy(settings.math_camera.data(), &m_buffered_data[0].pad[TFragDataMem::TFragMatrix0 * 16], - 64); + + settings.camera = m_pc_port_data.camera; settings.tree_idx = 0; if (render_state->occlusion_vis[m_level_id].valid) { settings.occlusion_culling = render_state->occlusion_vis[m_level_id].data; @@ -162,11 +160,6 @@ void TFragment::render(DmaFollower& dma, update_render_state_from_pc_settings(render_state, m_pc_port_data); - for (int i = 0; i < 4; i++) { - settings.planes[i] = m_pc_port_data.planes[i]; - settings.itimes[i] = m_pc_port_data.itimes[i]; - } - auto t3prof = prof.make_scoped_child("t3"); render_matching_trees(lod(), m_tree_kinds, settings, render_state, t3prof); } @@ -228,8 +221,7 @@ void TFragment::handle_initialization(DmaFollower& dma) { // data auto data_upload = dma.read_and_advance(); - unpack_to_stcycl(&m_tfrag_data, data_upload, VifCode::Kind::UNPACK_V4_32, 4, 4, sizeof(TFragData), - TFragDataMem::TFragFrameData, false, false); + (void)data_upload; // call the setup program auto mscal_setup = dma.read_and_advance(); @@ -416,13 +408,13 @@ void TFragment::render_tree(int geom, return; } auto& tree = m_cached_trees.at(geom).at(settings.tree_idx); - const auto* itimes = settings.itimes; + const auto* itimes = settings.camera.itimes; if (tree.freeze_itimes) { itimes = tree.itimes_debug; } else { for (int i = 0; i < 4; i++) { - tree.itimes_debug[i] = settings.itimes[i]; + tree.itimes_debug[i] = settings.camera.itimes[i]; } } @@ -433,9 +425,9 @@ void TFragment::render_tree(int geom, } #ifndef __aarch64__ if (m_use_fast_time_of_day) { - interp_time_of_day_fast(settings.itimes, tree.tod_cache, m_color_result.data()); + interp_time_of_day_fast(settings.camera.itimes, tree.tod_cache, m_color_result.data()); } else { - interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); + interp_time_of_day_slow(settings.camera.itimes, *tree.colors, m_color_result.data()); } #else interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); @@ -455,7 +447,7 @@ void TFragment::render_tree(int geom, glEnable(GL_PRIMITIVE_RESTART); glPrimitiveRestartIndex(UINT32_MAX); - cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, + cull_check_all_slow(settings.camera.planes, tree.vis->vis_nodes, settings.occlusion_culling, m_cache.vis_temp.data()); u32 total_tris; @@ -687,14 +679,14 @@ void TFragment::render_tree_cull_debug(const TfragRenderSettings& settings, render_state->shaders[ShaderId::TFRAG3_NO_TEX].activate(); glUniformMatrix4fv( glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3_NO_TEX].id(), "camera"), 1, - GL_FALSE, settings.math_camera.data()); + GL_FALSE, settings.camera.camera[0].data()); glUniform4f( glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3_NO_TEX].id(), "hvdf_offset"), - settings.hvdf_offset[0], settings.hvdf_offset[1], settings.hvdf_offset[2], - settings.hvdf_offset[3]); + settings.camera.hvdf_off[0], settings.camera.hvdf_off[1], settings.camera.hvdf_off[2], + settings.camera.hvdf_off[3]); glUniform1f( glGetUniformLocation(render_state->shaders[ShaderId::TFRAG3_NO_TEX].id(), "fog_constant"), - settings.fog.x()); + settings.camera.fog.x()); // glDisable(GL_DEPTH_TEST); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_GEQUAL); diff --git a/game/graphics/opengl_renderer/background/TFragment.h b/game/graphics/opengl_renderer/background/TFragment.h index 39890e7f3c..3c34d43311 100644 --- a/game/graphics/opengl_renderer/background/TFragment.h +++ b/game/graphics/opengl_renderer/background/TFragment.h @@ -88,8 +88,6 @@ class TFragment : public BucketRenderer { u8 m_test_setup[32]; // VU data - TFragData m_tfrag_data; - TfragPcPortData m_pc_port_data; // buffers diff --git a/game/graphics/opengl_renderer/background/Tie3.cpp b/game/graphics/opengl_renderer/background/Tie3.cpp index 73980c426f..51dc589451 100644 --- a/game/graphics/opengl_renderer/background/Tie3.cpp +++ b/game/graphics/opengl_renderer/background/Tie3.cpp @@ -342,10 +342,8 @@ bool Tie3::set_up_common_data_from_dma(DmaFollower& dma, SharedRenderState* rend dma.read_and_advance(); } - m_common_data.settings.hvdf_offset = m_pc_port_data.hvdf_off; - m_common_data.settings.fog = m_pc_port_data.fog; + m_common_data.settings.camera = m_pc_port_data.camera; - memcpy(m_common_data.settings.math_camera.data(), m_pc_port_data.camera[0].data(), 64); m_common_data.settings.tree_idx = 0; if (render_state->occlusion_vis[m_level_id].valid) { @@ -356,11 +354,6 @@ bool Tie3::set_up_common_data_from_dma(DmaFollower& dma, SharedRenderState* rend update_render_state_from_pc_settings(render_state, m_pc_port_data); - for (int i = 0; i < 4; i++) { - m_common_data.settings.planes[i] = m_pc_port_data.planes[i]; - m_common_data.settings.itimes[i] = m_pc_port_data.itimes[i]; - } - m_has_level = try_loading_level(m_pc_port_data.level_name, render_state); return true; } @@ -436,9 +429,9 @@ void Tie3::setup_tree(int idx, #ifndef __aarch64__ if (m_use_fast_time_of_day) { - interp_time_of_day_fast(settings.itimes, tree.tod_cache, m_color_result.data()); + interp_time_of_day_fast(settings.camera.itimes, tree.tod_cache, m_color_result.data()); } else { - interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); + interp_time_of_day_slow(settings.camera.itimes, *tree.colors, m_color_result.data()); } #else interp_time_of_day_slow(settings.itimes, *tree.colors, m_color_result.data()); @@ -456,7 +449,7 @@ void Tie3::setup_tree(int idx, if (!m_debug_all_visible) { // need culling data - cull_check_all_slow(settings.planes, tree.vis->vis_nodes, settings.occlusion_culling, + cull_check_all_slow(settings.camera.planes, tree.vis->vis_nodes, settings.occlusion_culling, tree.vis_temp.data()); } @@ -511,17 +504,17 @@ void set_uniform(GLuint uniform, const math::Vector4f& val) { } } // namespace -void init_etie_cam_uniforms(const EtieUniforms& uniforms, const SharedRenderState* render_state) { - glUniformMatrix4fv(uniforms.cam_no_persp, 1, GL_FALSE, render_state->camera_no_persp[0].data()); +void init_etie_cam_uniforms(const EtieUniforms& uniforms, const GoalBackgroundCameraData& data) { + glUniformMatrix4fv(uniforms.cam_no_persp, 1, GL_FALSE, data.rot[0].data()); math::Vector4f perspective[2]; - float inv_fog = 1.f / render_state->camera_fog[0]; - auto& hvdf_off = render_state->camera_hvdf_off; - float pxx = render_state->camera_persp[0].x(); - float pyy = render_state->camera_persp[1].y(); - float pzz = render_state->camera_persp[2].z(); - float pzw = render_state->camera_persp[2].w(); - float pwz = render_state->camera_persp[3].z(); + float inv_fog = 1.f / data.fog[0]; + auto& hvdf_off = data.hvdf_off; + float pxx = data.perspective[0].x(); + float pyy = data.perspective[1].y(); + float pzz = data.perspective[2].z(); + float pzw = data.perspective[2].w(); + float pwz = data.perspective[3].z(); float scale = pzw * inv_fog; perspective[0].x() = scale * hvdf_off.x(); perspective[0].y() = scale * hvdf_off.y(); @@ -557,7 +550,7 @@ void Tie3::draw_matching_draws_for_tree(int idx, if (use_envmap) { // if we use envmap, use the envmap-style math for the base draw to avoid rounding issue. - init_etie_cam_uniforms(m_etie_base_uniforms, render_state); + init_etie_cam_uniforms(m_etie_base_uniforms, m_common_data.settings.camera); } glBindVertexArray(tree.vao); @@ -661,7 +654,7 @@ void Tie3::envmap_second_pass_draw(const Tree& tree, glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, render_state->no_multidraw ? tree.single_draw_index_buffer : tree.index_buffer); - init_etie_cam_uniforms(m_etie_uniforms, render_state); + init_etie_cam_uniforms(m_etie_uniforms, m_common_data.settings.camera); set_uniform(m_etie_uniforms.envmap_tod_tint, m_common_data.envmap_color); int last_texture = -1; @@ -894,12 +887,10 @@ void Tie3::render_tree_wind(int idx, // note: this isn't the most efficient because we might compute wind matrices for invisible // instances. TODO: add vis ids to the instance info to avoid this memset(tree.wind_matrix_cache.data(), 0, sizeof(float) * 16 * tree.wind_matrix_cache.size()); - auto& cam_bad = settings.math_camera; + auto& cam_bad = settings.camera.camera; std::array cam; for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - cam[i][j] = cam_bad.data()[i * 4 + j]; - } + cam[i] = cam_bad[i]; } for (size_t inst_id = 0; inst_id < tree.instance_info->size(); inst_id++) { diff --git a/game/graphics/opengl_renderer/background/background_common.cpp b/game/graphics/opengl_renderer/background/background_common.cpp index a43c932f44..a61604fac0 100644 --- a/game/graphics/opengl_renderer/background/background_common.cpp +++ b/game/graphics/opengl_renderer/background/background_common.cpp @@ -179,14 +179,15 @@ void first_tfrag_draw_setup(const TfragRenderSettings& settings, auto id = sh.id(); glUniform1i(glGetUniformLocation(id, "gfx_hack_no_tex"), Gfx::g_global_settings.hack_no_tex); glUniform1i(glGetUniformLocation(id, "decal"), false); - glUniform1i(glGetUniformLocation(id, "tex_T0"), 0); - glUniformMatrix4fv(glGetUniformLocation(id, "camera"), 1, GL_FALSE, settings.math_camera.data()); - glUniform4f(glGetUniformLocation(id, "hvdf_offset"), settings.hvdf_offset[0], - settings.hvdf_offset[1], settings.hvdf_offset[2], settings.hvdf_offset[3]); - glUniform1f(glGetUniformLocation(id, "fog_constant"), settings.fog.x()); - glUniform1f(glGetUniformLocation(id, "fog_min"), settings.fog.y()); - glUniform1f(glGetUniformLocation(id, "fog_max"), settings.fog.z()); + glUniformMatrix4fv(glGetUniformLocation(id, "camera"), 1, GL_FALSE, + settings.camera.camera[0].data()); + glUniform4f(glGetUniformLocation(id, "hvdf_offset"), settings.camera.hvdf_off[0], + settings.camera.hvdf_off[1], settings.camera.hvdf_off[2], + settings.camera.hvdf_off[3]); + glUniform1f(glGetUniformLocation(id, "fog_constant"), settings.camera.fog.x()); + glUniform1f(glGetUniformLocation(id, "fog_min"), settings.camera.fog.y()); + glUniform1f(glGetUniformLocation(id, "fog_max"), settings.camera.fog.z()); glUniform4f(glGetUniformLocation(id, "fog_color"), render_state->fog_color[0] / 255.f, render_state->fog_color[1] / 255.f, render_state->fog_color[2] / 255.f, render_state->fog_intensity / 255); @@ -777,14 +778,12 @@ u32 make_all_visible_index_list(std::pair* group_out, void update_render_state_from_pc_settings(SharedRenderState* state, const TfragPcPortData& data) { if (!state->has_pc_data) { for (int i = 0; i < 4; i++) { - state->camera_planes[i] = data.planes[i]; - state->camera_matrix[i] = data.camera[i]; - state->camera_no_persp[i] = data.camera_rot[i]; - state->camera_persp[i] = data.camera_perspective[i]; + state->camera_planes[i] = data.camera.planes[i]; + state->camera_matrix[i] = data.camera.camera[i]; } - state->camera_pos = data.cam_trans; - state->camera_hvdf_off = data.hvdf_off; - state->camera_fog = data.fog; + state->camera_pos = data.camera.trans; + state->camera_hvdf_off = data.camera.hvdf_off; + state->camera_fog = data.camera.fog; state->has_pc_data = true; } } diff --git a/game/graphics/opengl_renderer/background/background_common.h b/game/graphics/opengl_renderer/background/background_common.h index 95dfc9373d..2fbb1ba69f 100644 --- a/game/graphics/opengl_renderer/background/background_common.h +++ b/game/graphics/opengl_renderer/background/background_common.h @@ -4,31 +4,29 @@ #include "game/graphics/opengl_renderer/BucketRenderer.h" -// data passed from game to PC renderers -// the GOAL code assumes this memory layout. -struct TfragPcPortData { +struct GoalBackgroundCameraData { math::Vector4f planes[4]; math::Vector itimes[4]; math::Vector4f camera[4]; math::Vector4f hvdf_off; math::Vector4f fog; - math::Vector4f cam_trans; - - math::Vector4f camera_rot[4]; - math::Vector4f camera_perspective[4]; + math::Vector4f trans; + math::Vector4f rot[4]; + math::Vector4f perspective[4]; +}; +// data passed from game to PC renderers +// the GOAL code assumes this memory layout. +struct TfragPcPortData { + GoalBackgroundCameraData camera; char level_name[16]; }; static_assert(sizeof(TfragPcPortData) == 16 * 24); // inputs to background renderers. struct TfragRenderSettings { - math::Matrix4f math_camera; - math::Vector4f hvdf_offset; - math::Vector4f fog; + GoalBackgroundCameraData camera; int tree_idx; - math::Vector itimes[4]; - math::Vector4f planes[4]; bool debug_culling = false; const u8* occlusion_culling = nullptr; };