mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 11:26:18 -04:00
[jak2] fix flickering and depth writes (#2406)
Fixes some mistakes with merc draw modes. The glass in the palace level no longer writes to the depth buffer (it's "water"): ![image](https://user-images.githubusercontent.com/48171810/227727825-d6726621-88a8-45a8-9cf3-8d6e9edc3d54.png) Also fixes the one-frame flickers when level draw orders change. We might be able to make this more efficient in the future, but this will at least fix the frame with nothing drawn.
This commit is contained in:
parent
ebdb0ecadd
commit
0a511da2ce
|
@ -87,8 +87,13 @@ std::string TextureDB::generate_texture_dest_adjustment_table() const {
|
|||
for (const auto& [tpage, texture_ids_in_page] : textures_by_page) {
|
||||
// organize by tbp offset
|
||||
std::map<u32, std::vector<u32>> textures_by_tbp_offset;
|
||||
std::set<u32> all_used_tbp_offsets;
|
||||
u32 max_tbp_offset = 0;
|
||||
for (auto tid : texture_ids_in_page) {
|
||||
textures_by_tbp_offset[textures.at(tid).dest].push_back(tid);
|
||||
u32 tbp = textures.at(tid).dest;
|
||||
textures_by_tbp_offset[tbp].push_back(tid);
|
||||
all_used_tbp_offsets.insert(tbp);
|
||||
max_tbp_offset = std::max(max_tbp_offset, tbp);
|
||||
}
|
||||
|
||||
// find tbp's with overlaps:
|
||||
|
@ -104,9 +109,25 @@ std::string TextureDB::generate_texture_dest_adjustment_table() const {
|
|||
result += fmt::format("{{{},{{\n", tpage);
|
||||
for (const auto& [tbp, tex_ids] : textures_by_tbp_offset) {
|
||||
if (tex_ids.size() > 1) {
|
||||
int offset = 0;
|
||||
for (auto id : tex_ids) {
|
||||
result += fmt::format("{{{}, {}}},", id & 0xffff, offset++);
|
||||
int offset = 1;
|
||||
for (size_t id_id = 1; id_id < tex_ids.size(); id_id++) {
|
||||
auto id = tex_ids[id_id];
|
||||
|
||||
bool ok = false;
|
||||
int tries = 50;
|
||||
// make sure we don't overlap again.
|
||||
while (!ok && tries > 0) {
|
||||
tries--;
|
||||
if (!all_used_tbp_offsets.count(tbp + offset)) {
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
|
||||
ASSERT(ok);
|
||||
all_used_tbp_offsets.insert(tbp + offset);
|
||||
result += fmt::format("{{{}, {}}},", id & 0xffff, offset);
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,7 +227,8 @@ void update_mode_from_alpha1(GsAlpha reg, DrawMode& mode) {
|
|||
*/
|
||||
DrawMode process_draw_mode(const MercShader& info,
|
||||
bool enable_alpha_test,
|
||||
bool enable_alpha_blend) {
|
||||
bool enable_alpha_blend,
|
||||
bool depth_write) {
|
||||
DrawMode mode;
|
||||
/*
|
||||
* (new 'static 'gs-test
|
||||
|
@ -244,7 +245,7 @@ DrawMode process_draw_mode(const MercShader& info,
|
|||
mode.set_alpha_fail(GsTest::AlphaFail::KEEP);
|
||||
mode.set_alpha_test(DrawMode::AlphaTest::GEQUAL);
|
||||
mode.enable_zt();
|
||||
mode.enable_depth_write();
|
||||
mode.set_depth_write_enable(depth_write);
|
||||
mode.set_depth_test(GsTest::ZTest::GEQUAL);
|
||||
|
||||
// check these
|
||||
|
@ -768,7 +769,7 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
|
|||
}
|
||||
if (input_effect.extra_info.shader) {
|
||||
result.has_envmap = true;
|
||||
result.envmap_mode = process_draw_mode(*input_effect.extra_info.shader, false, false);
|
||||
result.envmap_mode = process_draw_mode(*input_effect.extra_info.shader, false, false, false);
|
||||
result.envmap_mode.set_ab(true);
|
||||
u32 new_tex = remap_texture(input_effect.extra_info.shader->original_tex, map);
|
||||
ASSERT(result.envmap_mode.get_tcc_enable());
|
||||
|
@ -823,8 +824,17 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
|
|||
}
|
||||
|
||||
bool use_alpha_blend = false;
|
||||
bool depth_write = true;
|
||||
if (version == GameVersion::Jak2) {
|
||||
use_alpha_blend = input_effect.texture_index == 4; // water
|
||||
constexpr int kWaterTexture = 4;
|
||||
constexpr int kAlphaTexture = 3;
|
||||
if (input_effect.texture_index == kAlphaTexture) {
|
||||
use_alpha_blend = true;
|
||||
}
|
||||
if (input_effect.texture_index == kWaterTexture) {
|
||||
depth_write = false;
|
||||
use_alpha_blend = true;
|
||||
}
|
||||
}
|
||||
|
||||
// full reset of state per effect.
|
||||
|
@ -901,7 +911,7 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
|
|||
const auto& shader = frag.shaders.at(i);
|
||||
// update merc state from shader (will hold over to next fragment, if needed)
|
||||
merc_state.merc_draw_mode.mode =
|
||||
process_draw_mode(shader, result.has_envmap, use_alpha_blend);
|
||||
process_draw_mode(shader, result.has_envmap, use_alpha_blend, depth_write);
|
||||
if (!merc_state.merc_draw_mode.mode.get_tcc_enable()) {
|
||||
ASSERT(false);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -166,13 +166,24 @@ bool Shrub::setup_for_level(const std::string& level, SharedRenderState* render_
|
|||
// make sure we have the level data.
|
||||
Timer tfrag3_setup_timer;
|
||||
auto lev_data = render_state->loader->get_tfrag3_level(level);
|
||||
if (!lev_data || (m_has_level && lev_data->load_id != m_load_id)) {
|
||||
|
||||
if (!lev_data) {
|
||||
// not loaded
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
discard_tree_cache();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_has_level && lev_data->load_id != m_load_id) {
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
discard_tree_cache();
|
||||
return setup_for_level(level, render_state);
|
||||
}
|
||||
|
||||
m_textures = &lev_data->textures;
|
||||
m_load_id = lev_data->load_id;
|
||||
|
||||
|
|
|
@ -144,13 +144,24 @@ bool Tfrag3::setup_for_level(const std::vector<tfrag3::TFragmentTreeKind>& tree_
|
|||
// make sure we have the level data.
|
||||
Timer tfrag3_setup_timer;
|
||||
auto lev_data = render_state->loader->get_tfrag3_level(level);
|
||||
if (!lev_data || (m_has_level && lev_data->load_id != m_load_id)) {
|
||||
|
||||
if (!lev_data) {
|
||||
// not loaded
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
discard_tree_cache();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_has_level && lev_data->load_id != m_load_id) {
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
discard_tree_cache();
|
||||
return setup_for_level(tree_kinds, level, render_state);
|
||||
}
|
||||
|
||||
m_load_id = lev_data->load_id;
|
||||
|
||||
if (m_level_name != level) {
|
||||
|
|
|
@ -215,8 +215,8 @@ bool Tie3::try_loading_level(const std::string& level, SharedRenderState* render
|
|||
Timer tfrag3_setup_timer;
|
||||
auto lev_data = render_state->loader->get_tfrag3_level(level);
|
||||
|
||||
if (!lev_data || (m_has_level && lev_data->load_id != m_load_id)) {
|
||||
// loader failed, or we have an old copy of a level. either way, we have nothing to draw.
|
||||
if (!lev_data) {
|
||||
// not loaded
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
|
@ -224,6 +224,14 @@ bool Tie3::try_loading_level(const std::string& level, SharedRenderState* render
|
|||
return false;
|
||||
}
|
||||
|
||||
if (m_has_level && lev_data->load_id != m_load_id) {
|
||||
m_has_level = false;
|
||||
m_textures = nullptr;
|
||||
m_level_name = "";
|
||||
discard_tree_cache();
|
||||
return try_loading_level(level, render_state);
|
||||
}
|
||||
|
||||
// loading was successful. Link textures/load ID.
|
||||
m_textures = &lev_data->textures;
|
||||
m_load_id = lev_data->load_id;
|
||||
|
|
|
@ -1072,7 +1072,6 @@ void Merc2::do_draws(const Draw* draw_array,
|
|||
bool normal_vtx_buffer_bound = true;
|
||||
for (u32 di = 0; di < num_draws; di++) {
|
||||
auto& draw = draw_array[di];
|
||||
auto mode = draw.mode;
|
||||
if (draw.flags & MOD_VTX) {
|
||||
glBindVertexArray(draw.mod_vtx_buffer.vao);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, lev->merc_indices);
|
||||
|
@ -1113,7 +1112,7 @@ void Merc2::do_draws(const Draw* draw_array,
|
|||
set_uniform(uniforms.light_ambient, m_lights_buffer[draw.light_idx].ambient);
|
||||
last_light = draw.light_idx;
|
||||
}
|
||||
setup_opengl_from_draw_mode(mode, GL_TEXTURE0, use_mipmaps_for_filtering);
|
||||
setup_opengl_from_draw_mode(draw.mode, GL_TEXTURE0, use_mipmaps_for_filtering);
|
||||
|
||||
glUniform1i(uniforms.decal, draw.mode.get_decal());
|
||||
|
||||
|
|
Loading…
Reference in a new issue