diff --git a/game/graphics/opengl_renderer/Sprite3.cpp b/game/graphics/opengl_renderer/Sprite3.cpp index 61eeb842f0..7ca1912d0d 100644 --- a/game/graphics/opengl_renderer/Sprite3.cpp +++ b/game/graphics/opengl_renderer/Sprite3.cpp @@ -314,11 +314,11 @@ void Sprite3::render_distorter(DmaFollower& dma, return; } - // Setup vertex data + // Set up vertex data { auto prof_node = prof.make_scoped_child("setup"); if (m_enable_distort_instancing) { - distort_setup_instanced(render_state, prof_node); + distort_setup_instanced(prof_node); } else { distort_setup(prof_node); } @@ -372,6 +372,18 @@ void Sprite3::distort_dma(DmaFollower& dma, ScopedProfilerNode& /*prof*/) { ASSERT(alpha.c_mode() == GsAlpha::BlendMode::SOURCE); ASSERT(alpha.d_mode() == GsAlpha::BlendMode::DEST); + // Next is the aspect used by the sine tables (PC only) + // + // This was added to let the renderer reliably detect when the sine tables changed, + // which is whenever the aspect ratio changed. However, the tables aren't always + // updated on the same frame that the aspect changed, so this just lets the game + // easily notify the renderer when it finally does get updated. + auto sprite_distort_tables_aspect = dma.read_and_advance(); + ASSERT(sprite_distort_tables_aspect.size_bytes == 16); + ASSERT(sprite_distort_tables_aspect.vifcode1().kind == VifCode::Kind::PC_PORT); + memcpy(&m_sprite_distorter_sine_tables_aspect, sprite_distort_tables_aspect.data, + sizeof(math::Vector4f)); + // Next thing should be the sine tables auto sprite_distorter_tables = dma.read_and_advance(); unpack_to_stcycl(&m_sprite_distorter_sine_tables, sprite_distorter_tables, @@ -517,15 +529,12 @@ void Sprite3::distort_setup(ScopedProfilerNode& /*prof*/) { * * Required sprite-specific frame data is kept as is and is grouped by resolution. */ -void Sprite3::distort_setup_instanced(SharedRenderState* render_state, - ScopedProfilerNode& /*prof*/) { - if (m_distort_instanced_ogl.last_width != render_state->fbo_state.width || - m_distort_instanced_ogl.last_height != render_state->fbo_state.height) { - m_distort_instanced_ogl.last_width = render_state->fbo_state.width; - m_distort_instanced_ogl.last_height = render_state->fbo_state.height; - - // Window dimensions changed, which means the aspect ratio may have changed, which means we have - // a new sine table +void Sprite3::distort_setup_instanced(ScopedProfilerNode& /*prof*/) { + if (m_distort_instanced_ogl.last_aspect_x != m_sprite_distorter_sine_tables_aspect.x() || + m_distort_instanced_ogl.last_aspect_y != m_sprite_distorter_sine_tables_aspect.y()) { + m_distort_instanced_ogl.last_aspect_x = m_sprite_distorter_sine_tables_aspect.x(); + m_distort_instanced_ogl.last_aspect_y = m_sprite_distorter_sine_tables_aspect.y(); + // Aspect ratio changed, which means we have a new sine table m_sprite_distorter_vertices_instanced.clear(); // Build a mesh for every possible distort sprite resolution diff --git a/game/graphics/opengl_renderer/Sprite3.h b/game/graphics/opengl_renderer/Sprite3.h index 72423a9a24..6aba7c4b9f 100644 --- a/game/graphics/opengl_renderer/Sprite3.h +++ b/game/graphics/opengl_renderer/Sprite3.h @@ -28,7 +28,7 @@ class Sprite3 : public BucketRenderer { ScopedProfilerNode& prof); void distort_dma(DmaFollower& dma, ScopedProfilerNode& prof); void distort_setup(ScopedProfilerNode& prof); - void distort_setup_instanced(SharedRenderState* render_state, ScopedProfilerNode& prof); + void distort_setup_instanced(ScopedProfilerNode& prof); void distort_draw(SharedRenderState* render_state, ScopedProfilerNode& prof); void distort_draw_instanced(SharedRenderState* render_state, ScopedProfilerNode& prof); void distort_draw_common(SharedRenderState* render_state, ScopedProfilerNode& prof); @@ -117,8 +117,8 @@ class Sprite3 : public BucketRenderer { GLuint vao; GLuint vertex_buffer; // contains vertex data for each possible sprite resolution (3-11) GLuint instance_buffer; // contains all instance specific data for each sprite per frame - int last_width = -1; - int last_height = -1; + float last_aspect_x = -1.0; + float last_aspect_y = -1.0; bool vertex_data_changed = false; } m_distort_instanced_ogl; @@ -130,6 +130,7 @@ class Sprite3 : public BucketRenderer { std::vector m_sprite_distorter_vertices; std::vector m_sprite_distorter_indices; SpriteDistorterSetup m_sprite_distorter_setup; // direct data + math::Vector4f m_sprite_distorter_sine_tables_aspect; SpriteDistorterSineTables m_sprite_distorter_sine_tables; std::vector m_sprite_distorter_frame_data; std::vector m_sprite_distorter_vertices_instanced; diff --git a/goal_src/jak1/engine/gfx/sprite/sprite-distort.gc b/goal_src/jak1/engine/gfx/sprite/sprite-distort.gc index 8706e1aff3..be5516b94b 100644 --- a/goal_src/jak1/engine/gfx/sprite/sprite-distort.gc +++ b/goal_src/jak1/engine/gfx/sprite/sprite-distort.gc @@ -143,6 +143,24 @@ ;; blend source and framebuffer RGB (alpha-1 (new 'static 'gs-alpha :b 1 :d 1)) ) + ;; send current aspect used by the sine tables (PC only) + (#when PC_PORT + (let ((packet (the-as dma-packet (-> dma-buff 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))) + (&+! (-> dma-buff base) 16) + ) + (let ((aspect-vec (the-as vector (-> dma-buff base)))) + (set-vector! aspect-vec + (-> *sprite-distorter-sine-tables* aspx) + (-> *sprite-distorter-sine-tables* aspy) + 0.0 + 0.0 + ) + (&+! (-> dma-buff base) 16) + ) + ) ;; send distorter sine tables (dma-buffer-add-ref-vif2 dma-buff #x8b (-> *sprite-distorter-sine-tables* entry)