mirror of
https://github.com/open-goal/jak-project
synced 2026-07-09 14:55:51 -04:00
[jak3] Support texture anim in TIE (#3734)
Support animated textures in TIE. Apparently this is also used in jak 2 for robotank and we never noticed?? https://github.com/user-attachments/assets/bfa45a1a-4a96-4b25-817a-4327afcc7c98 Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
@@ -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,
|
||||
@@ -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.
|
||||
|
||||
@@ -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) |
|
||||
@@ -2348,7 +2348,7 @@ 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;
|
||||
@@ -2356,7 +2356,7 @@ u32 get_or_add_texture(u32 combo_tex, tfrag3::Level& lev, const TextureDB& tdb)
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user