mirror of
https://github.com/open-goal/jak-project
synced 2026-07-24 14:09:33 -04:00
[graphics] hook up visibility data for jak 2 (#1938)
It works! Visibility off:  On:  Overall the visibility data looks a lot better than in jak 1.
This commit is contained in:
@@ -143,6 +143,7 @@ set(RUNTIME_SOURCE
|
||||
graphics/opengl_renderer/Sprite3.cpp
|
||||
graphics/opengl_renderer/SpriteRenderer.cpp
|
||||
graphics/opengl_renderer/TextureUploadHandler.cpp
|
||||
graphics/opengl_renderer/VisDataHandler.cpp
|
||||
graphics/opengl_renderer/DepthCue.cpp
|
||||
graphics/texture/jak1_tpage_dir.cpp
|
||||
graphics/texture/jak2_tpage_dir.cpp
|
||||
|
||||
@@ -39,7 +39,6 @@ struct SharedRenderState {
|
||||
|
||||
bool use_sky_cpu = true;
|
||||
bool use_occlusion_culling = true;
|
||||
bool enable_merc_xgkick = true;
|
||||
math::Vector<u8, 4> fog_color = math::Vector<u8, 4>{0, 0, 0, 0};
|
||||
float fog_intensity = 1.f;
|
||||
bool no_multidraw = false;
|
||||
@@ -77,6 +76,7 @@ struct SharedRenderState {
|
||||
int draw_offset_y = 0;
|
||||
|
||||
int bucket_for_vis_copy = 0;
|
||||
int num_vis_to_copy = 0;
|
||||
GameVersion version;
|
||||
};
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include "game/graphics/opengl_renderer/Sprite3.h"
|
||||
#include "game/graphics/opengl_renderer/SpriteRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/TextureUploadHandler.h"
|
||||
#include "game/graphics/opengl_renderer/VisDataHandler.h"
|
||||
#include "game/graphics/opengl_renderer/background/Shrub.h"
|
||||
#include "game/graphics/opengl_renderer/background/TFragment.h"
|
||||
#include "game/graphics/opengl_renderer/background/Tie3.h"
|
||||
@@ -87,7 +88,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
|
||||
using namespace jak2;
|
||||
m_bucket_renderers.resize((int)BucketId::MAX_BUCKETS);
|
||||
m_bucket_categories.resize((int)BucketId::MAX_BUCKETS, BucketCategory::OTHER);
|
||||
|
||||
init_bucket_renderer<VisDataHandler>("vis", BucketCategory::OTHER, BucketId::SPECIAL_BUCKET_2);
|
||||
init_bucket_renderer<TFragment>("tfrag-l0-tfrag", BucketCategory::TFRAG, BucketId::TFRAG_L0_TFRAG,
|
||||
std::vector{tfrag3::TFragmentTreeKind::NORMAL}, false, 0);
|
||||
init_bucket_renderer<Tie3>("tie-l0-tfrag", BucketCategory::TIE, BucketId::TIE_L0_TFRAG, 0);
|
||||
@@ -455,7 +456,6 @@ void OpenGLRenderer::draw_renderer_selection_window() {
|
||||
ImGui::SliderFloat("Fog Adjust", &m_render_state.fog_intensity, 0, 10);
|
||||
ImGui::Checkbox("Sky CPU", &m_render_state.use_sky_cpu);
|
||||
ImGui::Checkbox("Occlusion Cull", &m_render_state.use_occlusion_culling);
|
||||
ImGui::Checkbox("Merc XGKICK", &m_render_state.enable_merc_xgkick);
|
||||
ImGui::Checkbox("Blackout Loads", &m_enable_fast_blackout_loads);
|
||||
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
@@ -697,6 +697,7 @@ void OpenGLRenderer::dispatch_buckets_jak1(DmaFollower dma,
|
||||
dma.current_tag_offset() + 16; // offset by 1 qw for the initial call
|
||||
m_render_state.next_bucket = m_render_state.buckets_base;
|
||||
m_render_state.bucket_for_vis_copy = (int)jak1::BucketId::TFRAG_LEVEL0;
|
||||
m_render_state.num_vis_to_copy = 2;
|
||||
|
||||
// Find the default regs buffer
|
||||
auto initial_call_tag = dma.current_tag();
|
||||
@@ -759,7 +760,8 @@ void OpenGLRenderer::dispatch_buckets_jak2(DmaFollower dma,
|
||||
|
||||
m_render_state.buckets_base = dma.current_tag_offset(); // starts at 0 in jak 2
|
||||
m_render_state.next_bucket = m_render_state.buckets_base + 16;
|
||||
m_render_state.bucket_for_vis_copy = 0; // TODO
|
||||
m_render_state.bucket_for_vis_copy = (int)jak2::BucketId::SPECIAL_BUCKET_2;
|
||||
m_render_state.num_vis_to_copy = 6;
|
||||
|
||||
for (size_t bucket_id = 0; bucket_id < m_bucket_renderers.size(); bucket_id++) {
|
||||
auto& renderer = m_bucket_renderers[bucket_id];
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
#include "VisDataHandler.h"
|
||||
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
VisDataHandler::VisDataHandler(const std::string& name, int my_id) : BucketRenderer(name, my_id) {}
|
||||
|
||||
void VisDataHandler::draw_debug_window() {
|
||||
ImGui::Checkbox("Count Visible?", &m_count_vis);
|
||||
for (int i = 0; i < kMaxLevels; i++) {
|
||||
const auto& stats = m_stats[i];
|
||||
if (stats.has_vis) {
|
||||
if (m_count_vis) {
|
||||
ImGui::Text("[%d] %d visible", i, stats.num_visible);
|
||||
} else {
|
||||
ImGui::Text("[%d] has vis", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int bitcount(const u8* data) {
|
||||
int result = 0;
|
||||
for (int byte = 0; byte < 16 * 128; byte++) {
|
||||
u8 val = data[byte];
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (val & 1) {
|
||||
result++;
|
||||
}
|
||||
val >>= 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void VisDataHandler::render(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& /*prof*/) {
|
||||
// reset stats
|
||||
for (auto& stats : m_stats) {
|
||||
stats = LevelStats();
|
||||
}
|
||||
if (dma.current_tag_offset() == render_state->next_bucket) {
|
||||
return;
|
||||
}
|
||||
|
||||
// skip bucket start
|
||||
dma.read_and_advance();
|
||||
|
||||
if (dma.current_tag_offset() == render_state->next_bucket) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < render_state->num_vis_to_copy; i++) {
|
||||
auto vis_data = dma.read_and_advance();
|
||||
ASSERT(vis_data.vif0() == 0);
|
||||
if (vis_data.vifcode1().kind != VifCode::Kind::PC_PORT) {
|
||||
break;
|
||||
}
|
||||
if (vis_data.size_bytes == 128 * 16 && render_state->use_occlusion_culling) {
|
||||
memcpy(render_state->occlusion_vis[i].data, vis_data.data, 128 * 16);
|
||||
render_state->occlusion_vis[i].valid = true;
|
||||
m_stats[i].has_vis = true;
|
||||
if (m_count_vis) {
|
||||
m_stats[i].num_visible = bitcount(render_state->occlusion_vis[i].data);
|
||||
} else {
|
||||
m_stats[i].num_visible = -1;
|
||||
}
|
||||
} else {
|
||||
m_stats[i].has_vis = false;
|
||||
m_stats[i].num_visible = -1;
|
||||
}
|
||||
|
||||
auto next = dma.read_and_advance();
|
||||
ASSERT(next.size_bytes == 0);
|
||||
}
|
||||
|
||||
while (dma.current_tag_offset() != render_state->next_bucket) {
|
||||
auto x = dma.read_and_advance();
|
||||
fmt::print("{} {}\n", x.vifcode0().print(), x.vifcode1().print());
|
||||
ASSERT(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
||||
|
||||
/*!
|
||||
* The VisDataHandler copies visibility data from add-pc-port-background-data for the background
|
||||
* renderers.
|
||||
*/
|
||||
class VisDataHandler : public BucketRenderer {
|
||||
public:
|
||||
VisDataHandler(const std::string& name, int my_id);
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
void draw_debug_window() override;
|
||||
|
||||
private:
|
||||
struct LevelStats {
|
||||
bool has_vis = false;
|
||||
int num_visible = 0;
|
||||
};
|
||||
static constexpr int kMaxLevels = 10;
|
||||
LevelStats m_stats[kMaxLevels];
|
||||
bool m_count_vis = false;
|
||||
};
|
||||
@@ -60,17 +60,17 @@ void TFragment::render(DmaFollower& dma,
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_my_id == render_state->bucket_for_vis_copy) {
|
||||
DmaTransfer transfers[2];
|
||||
if (m_my_id == render_state->bucket_for_vis_copy &&
|
||||
dma.current_tag_vifcode1().kind == VifCode::Kind::PC_PORT) {
|
||||
DmaTransfer transfers[20];
|
||||
|
||||
transfers[0] = dma.read_and_advance();
|
||||
auto next0 = dma.read_and_advance();
|
||||
ASSERT(next0.size_bytes == 0);
|
||||
transfers[1] = dma.read_and_advance();
|
||||
auto next1 = dma.read_and_advance();
|
||||
ASSERT(next1.size_bytes == 0);
|
||||
for (int i = 0; i < render_state->num_vis_to_copy; i++) {
|
||||
transfers[i] = dma.read_and_advance();
|
||||
auto next0 = dma.read_and_advance();
|
||||
ASSERT(next0.size_bytes == 0);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
for (int i = 0; i < render_state->num_vis_to_copy; i++) {
|
||||
if (transfers[i].size_bytes == 128 * 16) {
|
||||
if (render_state->use_occlusion_culling) {
|
||||
render_state->occlusion_vis[i].valid = true;
|
||||
|
||||
@@ -81,6 +81,7 @@ enum class BucketId {
|
||||
namespace jak2 {
|
||||
|
||||
enum class BucketId {
|
||||
SPECIAL_BUCKET_2 = 2,
|
||||
TFRAG_L0_TFRAG = 8,
|
||||
TIE_L0_TFRAG = 9,
|
||||
TFRAG_L1_TFRAG = 19,
|
||||
|
||||
@@ -229,13 +229,68 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
(defun add-pc-port-background-data ((dma-buf dma-buffer))
|
||||
"PC Port added"
|
||||
;; loop over levels
|
||||
(dotimes (lev-idx 6)
|
||||
(let ((lev (-> *level* draw-level lev-idx))
|
||||
(dma-start (-> dma-buf base)))
|
||||
(cond
|
||||
((and lev (= (-> lev status) 'active))
|
||||
;; the level is active.
|
||||
(let ((packet (the-as dma-packet (-> dma-buf base))))
|
||||
(set! (-> packet dma) (new 'static 'dma-tag :id (dma-tag-id cnt) :qwc 128))
|
||||
(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)))
|
||||
)
|
||||
(quad-copy! (-> dma-buf base) (-> lev vis-bits) 128)
|
||||
(&+! (-> dma-buf base) (* 16 128))
|
||||
)
|
||||
(else
|
||||
(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))) (the uint128 0))
|
||||
(&+! (-> dma-buf base) (* 16 1))
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
(let ((a3-3 (-> dma-buf base)))
|
||||
(let ((v1-38 (the-as object (-> dma-buf base))))
|
||||
(set! (-> (the-as dma-packet v1-38) dma) (new 'static 'dma-tag :id (dma-tag-id next)))
|
||||
(set! (-> (the-as dma-packet v1-38) vif0) (new 'static 'vif-tag))
|
||||
(set! (-> (the-as dma-packet v1-38) vif1) (new 'static 'vif-tag))
|
||||
(set! (-> dma-buf base) (&+ (the-as pointer v1-38) 16))
|
||||
)
|
||||
(dma-bucket-insert-tag (-> *display* frames (-> *display* on-screen) bucket-group)
|
||||
(bucket-id bucket-2)
|
||||
dma-start
|
||||
(the-as (pointer dma-tag) a3-3)
|
||||
)
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(defun finish-background ()
|
||||
"Main function for drawing the background (wind, shrub, tie, tfrag)"
|
||||
|
||||
(#when PC_PORT
|
||||
(add-pc-port-background-data
|
||||
(-> *display* frames (-> *display* on-screen) global-buf)
|
||||
)
|
||||
)
|
||||
|
||||
(if (-> *blit-displays-work* menu-mode)
|
||||
(return #f)
|
||||
)
|
||||
|
||||
|
||||
;; update wind!
|
||||
(when (not (paused?))
|
||||
(flush-cache 0)
|
||||
|
||||
Reference in New Issue
Block a user