mirror of
https://github.com/open-goal/jak-project.git
synced 2024-11-27 00:10:31 +00:00
[jak2,3] Support loading clut blender animated textures to the pool (#3735)
Some checks failed
Build / 🖥️ Windows (push) Waiting to run
Build / 🐧 Linux (push) Waiting to run
Build / 🍎 MacOS (push) Waiting to run
Lint / 📝 Formatting (push) Waiting to run
Lint / 📝 Required Checks (push) Waiting to run
Lint / 📝 Optional Checks (push) Waiting to run
Inform Pages Repo / Generate Documentation (push) Has been cancelled
Some checks failed
Build / 🖥️ Windows (push) Waiting to run
Build / 🐧 Linux (push) Waiting to run
Build / 🍎 MacOS (push) Waiting to run
Lint / 📝 Formatting (push) Waiting to run
Lint / 📝 Required Checks (push) Waiting to run
Lint / 📝 Optional Checks (push) Waiting to run
Inform Pages Repo / Generate Documentation (push) Has been cancelled
Animated textures that use the clut blender can now upload them to the texture pool, so they can get read by the eye renderer. This will also fix darkjak's eyelids in jak 2. ![image](https://github.com/user-attachments/assets/5edbd20d-53c9-42c6-937d-6263823b8b45) Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
parent
5bc61c5854
commit
1962fbfb51
@ -736,10 +736,14 @@ void TextureAnimator::copy_private_to_public() {
|
||||
int TextureAnimator::create_clut_blender_group(const std::vector<std::string>& textures,
|
||||
const std::string& suffix0,
|
||||
const std::string& suffix1,
|
||||
const std::optional<std::string>& dgo) {
|
||||
const std::optional<std::string>& dgo,
|
||||
bool add_to_pool) {
|
||||
int ret = m_clut_blender_groups.size();
|
||||
m_clut_blender_groups.emplace_back();
|
||||
add_to_clut_blender_group(ret, textures, suffix0, suffix1, dgo);
|
||||
if (add_to_pool) {
|
||||
m_clut_blender_groups.back().move_to_pool = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1240,23 +1244,23 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma,
|
||||
break;
|
||||
case PcTextureAnimCodesJak2::DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::PRISON_JAK: {
|
||||
auto p = scoped_prof("prisonjak");
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::ORACLE_JAK: {
|
||||
auto p = scoped_prof("oraclejak");
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::NEST_JAK: {
|
||||
auto p = scoped_prof("nestjak");
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::KOR_TRANSFORM: {
|
||||
auto p = scoped_prof("kor");
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak2::SKULL_GEM:
|
||||
case PcTextureAnimCodesJak2::BOMB:
|
||||
@ -1321,11 +1325,12 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma,
|
||||
break;
|
||||
case PcTextureAnimCodesJak3::DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx, texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::DARKJAK_HIGHRES: {
|
||||
auto p = scoped_prof("darkjak-highres");
|
||||
run_clut_blender_group(tf, m_darkjak_highres_clut_blender_idx, frame_idx);
|
||||
run_clut_blender_group(tf, m_darkjak_highres_clut_blender_idx, frame_idx,
|
||||
texture_pool);
|
||||
} break;
|
||||
case PcTextureAnimCodesJak3::SKULL_GEM:
|
||||
case PcTextureAnimCodesJak3::DEFAULT_WATER:
|
||||
@ -1579,15 +1584,48 @@ PcTextureId TextureAnimator::get_id_for_tbp(TexturePool* pool, u64 tbp, u64 othe
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAnimator::run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx) {
|
||||
void TextureAnimator::run_clut_blender_group(DmaTransfer& tf,
|
||||
int idx,
|
||||
u64 frame_idx,
|
||||
TexturePool* texture_pool) {
|
||||
auto& blenders = m_clut_blender_groups.at(idx);
|
||||
const int tbps_size = sizeof(u32) * 4 * ((blenders.blenders.size() + 3) / 4);
|
||||
float f;
|
||||
ASSERT(tf.size_bytes == 16);
|
||||
ASSERT(tf.size_bytes == 16 + tbps_size);
|
||||
memcpy(&f, tf.data, sizeof(float));
|
||||
float weights[2] = {1.f - f, f};
|
||||
auto& blender = m_clut_blender_groups.at(idx);
|
||||
blender.last_updated_frame = frame_idx;
|
||||
for (size_t i = 0; i < blender.blenders.size(); i++) {
|
||||
m_private_output_slots[blender.outputs[i]] = blender.blenders[i].run(weights);
|
||||
blenders.last_updated_frame = frame_idx;
|
||||
for (size_t i = 0; i < blenders.blenders.size(); i++) {
|
||||
m_private_output_slots[blenders.outputs[i]] = blenders.blenders[i].run(weights);
|
||||
}
|
||||
|
||||
const u32* tbps = (const u32*)(tf.data + 16);
|
||||
|
||||
// give to the pool for renderers that don't know how to access this directly
|
||||
if (blenders.move_to_pool) {
|
||||
for (size_t i = 0; i < blenders.blenders.size(); i++) {
|
||||
auto& blender = blenders.blenders[i];
|
||||
const u32 tbp = tbps[i];
|
||||
if (tbp == UINT32_MAX) {
|
||||
continue;
|
||||
}
|
||||
ASSERT(tbp < 0x40000);
|
||||
m_skip_tbps.push_back(tbp); // known to be an output texture.
|
||||
if (blender.pool_gpu_tex) {
|
||||
// TODO: handle debug checkbox.
|
||||
texture_pool->move_existing_to_vram(blender.pool_gpu_tex, tbp);
|
||||
ASSERT(texture_pool->lookup(tbp).value() == blender.texture());
|
||||
} else {
|
||||
TextureInput in;
|
||||
in.gpu_texture = blender.texture();
|
||||
in.w = blender.w();
|
||||
in.h = blender.h();
|
||||
in.debug_page_name = "PC-ANIM";
|
||||
in.debug_name = std::to_string(tbp);
|
||||
in.id = get_id_for_tbp(texture_pool, tbp, idx);
|
||||
blender.pool_gpu_tex = texture_pool->give_texture_and_load_to_vram(in, tbp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,10 @@ class ClutBlender {
|
||||
GLuint texture() const { return m_texture; }
|
||||
bool at_default() const { return m_current_weights[0] == 1.f && m_current_weights[1] == 0.f; }
|
||||
|
||||
int w() const { return m_dest->w; }
|
||||
int h() const { return m_dest->h; }
|
||||
GpuTexture* pool_gpu_tex = nullptr;
|
||||
|
||||
private:
|
||||
const tfrag3::IndexTexture* m_dest;
|
||||
std::array<const std::array<math::Vector4<u8>, 256>*, 2> m_cluts;
|
||||
@ -220,7 +224,6 @@ struct FixedAnim {
|
||||
std::optional<FramebufferTexturePair> fbt;
|
||||
int dest_slot;
|
||||
std::vector<FixedAnimSource> src_textures;
|
||||
|
||||
GpuTexture* pool_gpu_tex = nullptr;
|
||||
};
|
||||
|
||||
@ -397,6 +400,7 @@ class TextureAnimator {
|
||||
std::vector<ClutBlender> blenders;
|
||||
std::vector<int> outputs;
|
||||
u64 last_updated_frame = 0;
|
||||
bool move_to_pool = false;
|
||||
};
|
||||
std::vector<ClutBlenderGroup> m_clut_blender_groups;
|
||||
|
||||
@ -409,13 +413,14 @@ class TextureAnimator {
|
||||
int create_clut_blender_group(const std::vector<std::string>& textures,
|
||||
const std::string& suffix0,
|
||||
const std::string& suffix1,
|
||||
const std::optional<std::string>& dgo);
|
||||
const std::optional<std::string>& dgo,
|
||||
bool send_to_pool = false);
|
||||
void add_to_clut_blender_group(int idx,
|
||||
const std::vector<std::string>& textures,
|
||||
const std::string& suffix0,
|
||||
const std::string& suffix1,
|
||||
const std::optional<std::string>& dgo);
|
||||
void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx);
|
||||
void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx, TexturePool* texture_pool);
|
||||
GLint run_clouds(const SkyInput& input, bool hires);
|
||||
void run_slime(const SlimeInput& input);
|
||||
|
||||
|
@ -21,7 +21,7 @@ void TextureAnimator::setup_texture_anims_jak3() {
|
||||
"jakchires-facert",
|
||||
"jakchires-hair",
|
||||
},
|
||||
"-norm", "-dark", "MHCTYCST.DGO");
|
||||
"-norm", "-dark", "MHCTYCST.DGO", true);
|
||||
|
||||
// default-water
|
||||
{
|
||||
@ -1791,13 +1791,13 @@ void TextureAnimator::setup_texture_anims_jak2() {
|
||||
// MISSING FINGER
|
||||
m_jakb_oracle_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "ORACLE.DGO");
|
||||
"-dark", "ORACLE.DGO", true);
|
||||
|
||||
// NEST
|
||||
// MISSING FINGER
|
||||
m_jakb_nest_clut_blender_idx = create_clut_blender_group(
|
||||
{"jakb-eyebrow", "jakb-eyelid", "jakb-facelft", "jakb-facert", "jakb-hairtrans"}, "-norm",
|
||||
"-dark", "NEB.DGO");
|
||||
"-dark", "NEB.DGO", true);
|
||||
|
||||
// KOR (doesn't work??)
|
||||
m_kor_transform_clut_blender_idx = create_clut_blender_group(
|
||||
|
@ -777,6 +777,34 @@ struct SlimeInput {
|
||||
(the int (-> *toxic-slime-texture-anim-array* array-data 8 tex dest 0)))
|
||||
)
|
||||
|
||||
(defun pc-clut-blender ((bucket bucket-id) (id texture-anim-pc) (anim-array texture-anim-array))
|
||||
(let* ((sz (-> anim-array length))
|
||||
(qwc (+ 1 (/ (+ 3 sz) 4))))
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag-id id dma-buf :qwc qwc)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(dotimes (i sz)
|
||||
(let ((tex (-> anim-array array-data i tex)))
|
||||
(set! (-> (the (pointer uint32) (-> dma-buf base)) i)
|
||||
(if tex (-> tex dest 0)
|
||||
-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(&+! (-> dma-buf base) (- (* 16 qwc) 16))
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
(defun update-texture-anim ((bucket bucket-id) (anim-array texture-anim-array))
|
||||
@ -902,96 +930,23 @@ struct SlimeInput {
|
||||
(return #f)
|
||||
)
|
||||
((= anim-array *darkjak-texture-anim-array*)
|
||||
;; darkjak is simple, and we reimplemented it in C++.
|
||||
;; so we just have to send the frame-time value.
|
||||
;; (format *stdcon* "doing darkjak~%")
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag darkjak dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc darkjak) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
|
||||
((= anim-array *jakb-prison-texture-anim-array*)
|
||||
;; prison is simple, and we reimplemented it in C++.
|
||||
;; so we just have to send the frame-time value.
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag prison-jak dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc prison-jak) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
|
||||
((= anim-array *darkjak-hires-texture-anim-array*)
|
||||
;; oracle is simple, and we reimplemented it in C++.
|
||||
;; so we just have to send the frame-time value.
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag oracle-jak dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc oracle-jak) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
((= anim-array *darkjak-hires-nest-texture-anim-array*)
|
||||
;; oracle is simple, and we reimplemented it in C++.
|
||||
;; so we just have to send the frame-time value.
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag nest-jak dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc nest-jak) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
((= anim-array *kor-transform-texture-anim-array*)
|
||||
;; kor is simple, and we reimplemented it in C++.
|
||||
;; so we just have to send the frame-time value.
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag kor-transform dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc kor-transform) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
(else
|
||||
|
@ -435,6 +435,35 @@
|
||||
0
|
||||
)
|
||||
|
||||
(defun pc-clut-blender ((bucket bucket-id) (id texture-anim-pc) (anim-array texture-anim-array))
|
||||
(let* ((sz (-> anim-array length))
|
||||
(qwc (+ 1 (/ (+ 3 sz) 4))))
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag-id id dma-buf :qwc qwc)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(dotimes (i sz)
|
||||
(let ((tex (-> anim-array array-data i tex)))
|
||||
(set! (-> (the (pointer uint32) (-> dma-buf base)) i)
|
||||
(if tex (-> tex dest 0)
|
||||
-1)
|
||||
)
|
||||
)
|
||||
)
|
||||
(&+! (-> dma-buf base) (- (* 16 qwc) 16))
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; WARN: Function update-texture-anim has a return type of none, but the expression builder found a return statement.
|
||||
(defun update-texture-anim ((bucket bucket-id) (anim-array texture-anim-array))
|
||||
(let ((anim-idx 0))
|
||||
@ -471,35 +500,11 @@
|
||||
;; (return #f)
|
||||
)
|
||||
((*darkjak-texture-anim-array*)
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag darkjak dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc darkjak) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
((*darkjak-highres-texture-anim-array*)
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
bucket
|
||||
)
|
||||
(pc-texture-anim-flag start-anim-array dma-buf)
|
||||
(pc-texture-anim-flag darkjak-highres dma-buf :qwc 1)
|
||||
(let ((morph (-> anim-array array-data 0 frame-time))
|
||||
(vec (the vector (-> dma-buf base)))
|
||||
)
|
||||
(set! (-> vec x) morph)
|
||||
)
|
||||
(&+! (-> dma-buf base) 16)
|
||||
(pc-texture-anim-flag finish-anim-array dma-buf)
|
||||
)
|
||||
(pc-clut-blender bucket (texture-anim-pc darkjak-highres) anim-array)
|
||||
(return #f)
|
||||
)
|
||||
((*skull-gem-texture-anim-array*)
|
||||
|
Loading…
Reference in New Issue
Block a user