Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[jak3] Support texture anim in TIE #3734

Merged
merged 1 commit into from
Oct 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions common/custom_data/Tfrag3Data.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace tfrag3 {
// - if changing any large things (vertices, vis, bvh, colors, textures) update get_memory_usage
// - if adding a new category to the memory usage, update extract_level to print it.

constexpr int TFRAG3_VERSION = 42;
constexpr int TFRAG3_VERSION = 43;

enum MemoryUsageCategory {
TEXTURE,
Expand Down Expand Up @@ -241,7 +241,7 @@ struct ShrubDraw {

struct InstancedStripDraw {
DrawMode mode; // the OpenGL draw settings.
u32 tree_tex_id = 0; // the texture that should be bound for the draw
s32 tree_tex_id = 0; // the texture that should be bound for the draw

// the list of vertices in the draw. This includes the restart code of UINT32_MAX that OpenGL
// will use to start a new strip.
Expand Down
26 changes: 16 additions & 10 deletions decompiler/level_extractor/extract_tie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2339,7 +2339,7 @@ TieCategoryInfo get_jak1_tie_category(u32 flags) {
return result;
}

u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
s32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb) {
if (combo_tex == 0) {
// untextured
combo_tex = (((u32)TextureDB::kPlaceholderWhiteTexturePage) << 16) |
Expand All @@ -2348,15 +2348,15 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)

// try looking it up in the existing textures that we have in the C++ renderer data.
// (this is shared with tfrag)
u32 idx_in_lev_data = UINT32_MAX;
s32 idx_in_lev_data = INT32_MAX;
for (u32 i = 0; i < lev.textures.size(); i++) {
if (lev.textures[i].combo_id == combo_tex) {
idx_in_lev_data = i;
break;
}
}

if (idx_in_lev_data == UINT32_MAX) {
if (idx_in_lev_data == INT32_MAX) {
// didn't find it, have to add a new one texture.
auto tex_it = tdb.textures.find(combo_tex);
if (tex_it == tdb.textures.end()) {
Expand All @@ -2378,14 +2378,20 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
new_tex.debug_tpage_name = tdb.tpage_names.at(tex_it->second.page);
new_tex.data = tex_it->second.rgba_bytes;
}
const auto& level_tex = lev.textures.at(idx_in_lev_data);
const auto& it = tdb.animated_tex_output_to_anim_slot.find(level_tex.debug_name);
if (it != tdb.animated_tex_output_to_anim_slot.end()) {
// lg::warn("TIE animated texture: {}", level_tex.debug_name);
return -int(it->second) - 1;
}
return idx_in_lev_data;
}

void handle_wind_draw_for_strip(
tfrag3::TieTree& tree,
std::unordered_map<u32, std::vector<u32>>& wind_draws_by_tex,
std::unordered_map<s32, std::vector<u32>>& wind_draws_by_tex,
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
u32 idx_in_lev_data,
s32 idx_in_lev_data,
DrawMode mode,
const TieStrip& strip,
const TieInstanceInfo& inst,
Expand Down Expand Up @@ -2452,7 +2458,7 @@ void handle_wind_draw_for_strip(
}

void handle_draw_for_strip(tfrag3::TieTree& tree,
std::unordered_map<u32, std::vector<u32>>& static_draws_by_tex,
std::unordered_map<s32, std::vector<u32>>& static_draws_by_tex,
std::vector<tfrag3::StripDraw>& category_draws,
const std::vector<std::vector<std::pair<int, int>>>& packed_vert_indices,
DrawMode mode,
Expand Down Expand Up @@ -2542,8 +2548,8 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
GameVersion version) {
// our current approach for static draws is just to flatten to giant mesh, except for wind stuff.
// this map sorts these two types of draws by texture.
std::unordered_map<u32, std::vector<u32>> static_draws_by_tex;
std::unordered_map<u32, std::vector<u32>> wind_draws_by_tex;
std::unordered_map<s32, std::vector<u32>> static_draws_by_tex;
std::unordered_map<s32, std::vector<u32>> wind_draws_by_tex;

std::array<std::vector<tfrag3::StripDraw>, tfrag3::kNumTieCategories> draws_by_category;

Expand Down Expand Up @@ -2632,7 +2638,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
for (size_t strip_idx = 0; strip_idx < frag.strips.size(); strip_idx++) {
auto& strip = frag.strips[strip_idx];

u32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
s32 idx_in_lev_data = get_or_add_texture(strip.adgif.combo_tex, lev, tdb);
// determine the draw mode
DrawMode mode = process_draw_mode(strip.adgif, frag.prog_info.misc_x == 0,
frag.has_magic_tex0_bit, version, info.category);
Expand All @@ -2649,7 +2655,7 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
draws_by_category.at((int)info.category), packed_vert_indices,
mode, idx_in_lev_data, strip, inst, ifrag, proto_idx, frag_idx,
strip_idx, matrix_idx);
u32 envmap_tex_idx =
s32 envmap_tex_idx =
get_or_add_texture(proto.envmap_adgif.value().combo_tex, lev, tdb);

// second pass envmap draw mode, in envmap bucket, envmap-specific draw list
Expand Down
6 changes: 4 additions & 2 deletions game/graphics/opengl_renderer/OpenGLRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,8 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
std::vector{tfrag3::TFragmentTreeKind::NORMAL}, false, i, anim_slot_array());
Tie3* tie = init_bucket_renderer<Tie3>(
fmt::format("tie-l{}-tfrag", i), BucketCategory::TIE,
GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i);
GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i,
anim_slot_array());
init_bucket_renderer<Tie3AnotherCategory>(
fmt::format("etie-l{}-tfrag", i), BucketCategory::TIE,
GET_BUCKET_ID_FOR_LIST(BucketId::ETIE_L0_TFRAG, BucketId::ETIE_L1_TFRAG, i), tie,
Expand Down Expand Up @@ -431,7 +432,8 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
std::vector{tfrag3::TFragmentTreeKind::NORMAL}, false, i, anim_slot_array());
Tie3* tie = init_bucket_renderer<Tie3>(
fmt::format("tie-l{}-tfrag", i), BucketCategory::TIE,
GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i);
GET_BUCKET_ID_FOR_LIST(BucketId::TIE_L0_TFRAG, BucketId::TIE_L1_TFRAG, i), i,
anim_slot_array());
init_bucket_renderer<Tie3AnotherCategory>(
fmt::format("etie-l{}-tfrag", i), BucketCategory::TIE,
GET_BUCKET_ID_FOR_LIST(BucketId::ETIE_L0_TFRAG, BucketId::ETIE_L1_TFRAG, i), tie,
Expand Down
38 changes: 29 additions & 9 deletions game/graphics/opengl_renderer/background/Tie3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@

#include "third-party/imgui/imgui.h"

Tie3::Tie3(const std::string& name, int my_id, int level_id, tfrag3::TieCategory category)
: BucketRenderer(name, my_id), m_level_id(level_id), m_default_category(category) {
Tie3::Tie3(const std::string& name,
int my_id,
int level_id,
const std::vector<GLuint>* anim_slot_array,
tfrag3::TieCategory category)
: BucketRenderer(name, my_id),
m_level_id(level_id),
m_default_category(category),
m_anim_slot_array(anim_slot_array) {
// regardless of how many we use some fixed max
// we won't actually interp or upload to gpu the unused ones, but we need a fixed maximum so
// indexing works properly.
Expand Down Expand Up @@ -573,8 +580,12 @@ void Tie3::draw_matching_draws_for_tree(int idx,
}
}

if ((int)draw.tree_tex_id != last_texture) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
if (draw.tree_tex_id != last_texture) {
if (draw.tree_tex_id >= 0) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
} else {
glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1)));
}
last_texture = draw.tree_tex_id;
}

Expand Down Expand Up @@ -665,8 +676,13 @@ void Tie3::envmap_second_pass_draw(const Tree& tree,
}
}

if ((int)draw.tree_tex_id != last_texture) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
if (draw.tree_tex_id != last_texture) {
if (draw.tree_tex_id >= 0) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
} else {
glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1)));
}

last_texture = draw.tree_tex_id;
}

Expand Down Expand Up @@ -922,8 +938,12 @@ void Tie3::render_tree_wind(int idx,
for (size_t draw_idx = 0; draw_idx < tree.wind_draws->size(); draw_idx++) {
const auto& draw = tree.wind_draws->operator[](draw_idx);

if ((int)draw.tree_tex_id != last_texture) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
if (draw.tree_tex_id != last_texture) {
if (draw.tree_tex_id >= 0) {
glBindTexture(GL_TEXTURE_2D, m_textures->at(draw.tree_tex_id));
} else {
glBindTexture(GL_TEXTURE_2D, m_anim_slot_array->at(-(draw.tree_tex_id + 1)));
}
last_texture = draw.tree_tex_id;
}
auto double_draw = setup_tfrag_shader(render_state, draw.mode, ShaderId::TFRAG3);
Expand Down Expand Up @@ -993,7 +1013,7 @@ void Tie3AnotherCategory::render(DmaFollower& dma,
}

Tie3WithEnvmapJak1::Tie3WithEnvmapJak1(const std::string& name, int my_id, int level_id)
: Tie3(name, my_id, level_id, tfrag3::TieCategory::NORMAL) {}
: Tie3(name, my_id, level_id, nullptr, tfrag3::TieCategory::NORMAL) {}

void Tie3WithEnvmapJak1::render(DmaFollower& dma,
SharedRenderState* render_state,
Expand Down
3 changes: 2 additions & 1 deletion game/graphics/opengl_renderer/background/Tie3.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class Tie3 : public BucketRenderer {
Tie3(const std::string& name,
int my_id,
int level_id,
const std::vector<GLuint>* anim_slot_array,
tfrag3::TieCategory category = tfrag3::TieCategory::NORMAL);
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
void draw_debug_window() override;
Expand Down Expand Up @@ -169,7 +170,7 @@ class Tie3 : public BucketRenderer {
} m_uniforms;

EtieUniforms m_etie_uniforms, m_etie_base_uniforms;

const std::vector<GLuint>* m_anim_slot_array;
static_assert(sizeof(WindWork) == 84 * 16);
};

Expand Down
Loading