mirror of
https://github.com/open-goal/jak-project
synced 2026-08-20 14:24:45 -04:00
[jak2] Fix dark jak anim and low res skull gems
This commit is contained in:
@@ -707,6 +707,11 @@ void OpenGLRenderer::render(DmaFollower dma, const RenderOptions& settings) {
|
||||
{
|
||||
auto prof = m_profiler.root()->make_scoped_child("buckets");
|
||||
dispatch_buckets(dma, prof, settings.gpu_sync);
|
||||
if (m_texture_animator) {
|
||||
// if animation requests weren't made, assume the level is unloaded and the textures should
|
||||
// reset.
|
||||
m_texture_animator->clear_stale_textures(m_render_state.frame_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// apply effects done with PCRTC registers
|
||||
|
||||
@@ -223,17 +223,18 @@ void opengl_upload_texture(GLint dest, const void* data, int w, int h) {
|
||||
* texture using the index data in dest.
|
||||
*/
|
||||
ClutBlender::ClutBlender(const std::string& dest,
|
||||
const std::vector<std::string>& sources,
|
||||
const std::array<std::string, 2>& sources,
|
||||
const std::optional<std::string>& level_name,
|
||||
const tfrag3::Level* level,
|
||||
OpenGLTexturePool* tpool) {
|
||||
// find the destination texture
|
||||
m_dest = itex_by_name(level, dest, level_name);
|
||||
// find the clut source textures
|
||||
for (const auto& sname : sources) {
|
||||
m_cluts.push_back(&itex_by_name(level, sname, level_name)->color_table);
|
||||
m_current_weights.push_back(0);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
m_cluts[i] = &itex_by_name(level, sources[i], level_name)->color_table;
|
||||
m_current_weights[i] = 0;
|
||||
}
|
||||
|
||||
// opengl texture that we'll write to
|
||||
m_texture = tpool->allocate(m_dest->w, m_dest->h);
|
||||
m_temp_rgba.resize(m_dest->w * m_dest->h);
|
||||
@@ -510,8 +511,9 @@ void TextureAnimator::add_to_clut_blender_group(int idx,
|
||||
const std::optional<std::string>& dgo) {
|
||||
auto& grp = m_clut_blender_groups.at(idx);
|
||||
for (auto& prefix : textures) {
|
||||
grp.blenders.emplace_back(prefix, std::vector<std::string>{prefix + suffix0, prefix + suffix1},
|
||||
dgo, m_common_level, &m_opengl_texture_pool);
|
||||
grp.blenders.emplace_back(prefix,
|
||||
std::array<std::string, 2>{prefix + suffix0, prefix + suffix1}, dgo,
|
||||
m_common_level, &m_opengl_texture_pool);
|
||||
grp.outputs.push_back(output_slot_by_idx(GameVersion::Jak2, prefix));
|
||||
m_private_output_slots.at(grp.outputs.back()) = grp.blenders.back().texture();
|
||||
}
|
||||
@@ -584,7 +586,8 @@ struct TextureAnimPcTransform {
|
||||
*/
|
||||
void TextureAnimator::handle_texture_anim_data(DmaFollower& dma,
|
||||
const u8* ee_mem,
|
||||
TexturePool* texture_pool) {
|
||||
TexturePool* texture_pool,
|
||||
u64 frame_idx) {
|
||||
dprintf("animator\n");
|
||||
m_current_shader = {};
|
||||
glBindVertexArray(m_vao);
|
||||
@@ -645,23 +648,23 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma,
|
||||
} break;
|
||||
case DARKJAK: {
|
||||
auto p = scoped_prof("darkjak");
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx);
|
||||
run_clut_blender_group(tf, m_darkjak_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case PRISON_JAK: {
|
||||
auto p = scoped_prof("prisonjak");
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx);
|
||||
run_clut_blender_group(tf, m_jakb_prison_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case ORACLE_JAK: {
|
||||
auto p = scoped_prof("oraclejak");
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx);
|
||||
run_clut_blender_group(tf, m_jakb_oracle_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case NEST_JAK: {
|
||||
auto p = scoped_prof("nestjak");
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx);
|
||||
run_clut_blender_group(tf, m_jakb_nest_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case KOR_TRANSFORM: {
|
||||
auto p = scoped_prof("kor");
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx);
|
||||
run_clut_blender_group(tf, m_kor_transform_clut_blender_idx, frame_idx);
|
||||
} break;
|
||||
case SKULL_GEM: {
|
||||
auto p = scoped_prof("skull-gem");
|
||||
@@ -990,17 +993,31 @@ void TextureAnimator::handle_copy_clut_alpha(const DmaTransfer& tf) {
|
||||
glColorMask(true, true, true, true);
|
||||
}
|
||||
|
||||
void TextureAnimator::run_clut_blender_group(DmaTransfer& tf, int idx) {
|
||||
void TextureAnimator::run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx) {
|
||||
float f;
|
||||
ASSERT(tf.size_bytes == 16);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureAnimator::clear_stale_textures(u64 frame_idx) {
|
||||
for (auto& group : m_clut_blender_groups) {
|
||||
if (frame_idx > group.last_updated_frame) {
|
||||
for (auto& blender : group.blenders) {
|
||||
if (!blender.at_default()) {
|
||||
float weights[2] = {1, 0};
|
||||
blender.run(weights);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* Create an entry for a 16x16 clut texture upload. Leaves it on the CPU.
|
||||
* They upload cluts as PSM32, so there's no funny addressing stuff, other than
|
||||
@@ -1948,6 +1965,8 @@ void TextureAnimator::setup_texture_anims() {
|
||||
skull_gem.move_to_pool = true;
|
||||
skull_gem.tex_name = "skull-gem-dest";
|
||||
skull_gem.color = math::Vector4<u8>{0, 0, 0, 0x80};
|
||||
// overriden in texture-finish.gc
|
||||
skull_gem.override_size = math::Vector2<int>(32, 32);
|
||||
|
||||
auto& skull_gem_0 = skull_gem.layers.emplace_back();
|
||||
skull_gem_0.end_time = 300.;
|
||||
|
||||
@@ -65,17 +65,18 @@ struct OpenGLTexturePool {
|
||||
class ClutBlender {
|
||||
public:
|
||||
ClutBlender(const std::string& dest,
|
||||
const std::vector<std::string>& sources,
|
||||
const std::array<std::string, 2>& sources,
|
||||
const std::optional<std::string>& level_name,
|
||||
const tfrag3::Level* level,
|
||||
OpenGLTexturePool* tpool);
|
||||
GLuint run(const float* weights);
|
||||
GLuint texture() const { return m_texture; }
|
||||
bool at_default() const { return m_current_weights[0] == 1.f && m_current_weights[1] == 0.f; }
|
||||
|
||||
private:
|
||||
const tfrag3::IndexTexture* m_dest;
|
||||
std::vector<const std::array<math::Vector4<u8>, 256>*> m_cluts;
|
||||
std::vector<float> m_current_weights;
|
||||
std::array<const std::array<math::Vector4<u8>, 256>*, 2> m_cluts;
|
||||
std::array<float, 2> m_current_weights;
|
||||
GLuint m_texture;
|
||||
std::array<math::Vector4<u8>, 256> m_temp_clut;
|
||||
std::vector<u32> m_temp_rgba;
|
||||
@@ -199,10 +200,14 @@ class TextureAnimator {
|
||||
public:
|
||||
TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* common_level);
|
||||
~TextureAnimator();
|
||||
void handle_texture_anim_data(DmaFollower& dma, const u8* ee_mem, TexturePool* texture_pool);
|
||||
void handle_texture_anim_data(DmaFollower& dma,
|
||||
const u8* ee_mem,
|
||||
TexturePool* texture_pool,
|
||||
u64 frame_idx);
|
||||
GLuint get_by_slot(int idx);
|
||||
void draw_debug_window();
|
||||
const std::vector<GLuint>* slots() { return &m_public_output_slots; }
|
||||
void clear_stale_textures(u64 frame_idx);
|
||||
|
||||
private:
|
||||
void copy_private_to_public();
|
||||
@@ -314,6 +319,7 @@ class TextureAnimator {
|
||||
struct ClutBlenderGroup {
|
||||
std::vector<ClutBlender> blenders;
|
||||
std::vector<int> outputs;
|
||||
u64 last_updated_frame = 0;
|
||||
};
|
||||
std::vector<ClutBlenderGroup> m_clut_blender_groups;
|
||||
|
||||
@@ -332,7 +338,7 @@ class TextureAnimator {
|
||||
const std::string& suffix0,
|
||||
const std::string& suffix1,
|
||||
const std::optional<std::string>& dgo);
|
||||
void run_clut_blender_group(DmaTransfer& tf, int idx);
|
||||
void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx);
|
||||
|
||||
Psm32ToPsm8Scrambler m_psm32_to_psm8_8_8, m_psm32_to_psm8_16_16, m_psm32_to_psm8_32_32,
|
||||
m_psm32_to_psm8_64_64;
|
||||
|
||||
@@ -30,7 +30,8 @@ void TextureUploadHandler::render(DmaFollower& dma,
|
||||
dma.read_and_advance();
|
||||
auto p = scoped_prof("texture-animator");
|
||||
m_texture_animator->handle_texture_anim_data(dma, (const u8*)render_state->ee_main_memory,
|
||||
render_state->texture_pool.get());
|
||||
render_state->texture_pool.get(),
|
||||
render_state->frame_idx);
|
||||
}
|
||||
// does it look like data to do eye rendering?
|
||||
if (dma_tag.qwc == (128 / 16)) {
|
||||
|
||||
Reference in New Issue
Block a user