[jak2] a few small graphics fixes (#2424)

- better handling of the `disable-fog` settings for merc, should fix the
spotlights. There's a setting in the merc effect, and also a runtime
flag for the draw-control. I'm not actually sure what reads these, but
the draw-control one is definitely used to disable fog on the
spotlights.
- increase merc draw limit to try to fix the issue about partially drawn
citizens in the city
- remove useless debug prints (it's okay to die in init, and the medium
load buffer size mode is understood now)
This commit is contained in:
water111
2023-03-26 12:30:35 -04:00
committed by GitHub
parent 7170db51ea
commit 9e087cbfcb
11 changed files with 103 additions and 26 deletions
+1 -1
View File
@@ -73,7 +73,7 @@ struct MemoryUsageTracker {
void add(MemoryUsageCategory category, u32 size_bytes) { data[category] += size_bytes; }
};
constexpr int TFRAG3_VERSION = 30;
constexpr int TFRAG3_VERSION = 31;
// These vertices should be uploaded to the GPU at load time and don't change
struct PreloadedVertex {
+13 -3
View File
@@ -13,7 +13,7 @@ void MercEyeCtrl::from_ref(TypedRef tr, const DecompilerTypeSystem& dts) {
eye_slot = read_plain_data_field<s8>(tr, "eye-slot", dts);
}
void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts) {
void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version) {
st_magic = read_plain_data_field<u32>(tr, "st-magic", dts);
xyz_scale = read_plain_data_field<float>(tr, "xyz-scale", dts);
st_out_a = read_plain_data_field<u32>(tr, "st-out-a", dts);
@@ -58,6 +58,16 @@ void MercCtrlHeader::from_ref(TypedRef tr, const DecompilerTypeSystem& dts) {
death_effect = read_plain_data_field<u32>(tr, "death-effect", dts);
use_translucent = read_plain_data_field<u8>(tr, "use-translucent", dts);
display_this_fragment = read_plain_data_field<u8>(tr, "display-this-fragment", dts);
if (version > GameVersion::Jak1) {
disable_fog = read_plain_data_field<u8>(tr, "disable-fog", dts);
use_warp = read_plain_data_field<u8>(tr, "use-warp", dts);
ignore_alpha = read_plain_data_field<u8>(tr, "ignore-alpha", dts);
force_fade = read_plain_data_field<u8>(tr, "force-fade", dts);
disable_envamp = read_plain_data_field<u8>(tr, "disable-envmap", dts);
} else {
disable_fog = false;
}
}
std::string MercCtrlHeader::print() const {
@@ -427,12 +437,12 @@ std::string MercEffect::print() {
return result;
}
void MercCtrl::from_ref(TypedRef tr, const DecompilerTypeSystem& dts) {
void MercCtrl::from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version) {
name = read_string_field(tr, "name", dts, false);
num_joints = read_plain_data_field<s32>(tr, "num-joints", dts);
auto merc_ctrl_header_ref =
TypedRef(get_field_ref(tr, "header", dts), dts.ts.lookup_type("merc-ctrl-header"));
header.from_ref(merc_ctrl_header_ref, dts);
header.from_ref(merc_ctrl_header_ref, dts, version);
auto eff_ref = TypedRef(get_field_ref(tr, "effect", dts), dts.ts.lookup_type("merc-effect"));
for (u32 i = 0; i < header.effect_count; i++) {
+9 -2
View File
@@ -7,6 +7,7 @@
#include "common/common_types.h"
#include "common/dma/gs.h"
#include "common/math/Vector.h"
#include "common/versions.h"
#include "decompiler/util/goal_data_reader.h"
@@ -63,7 +64,13 @@ struct MercCtrlHeader {
u8 use_translucent;
u8 display_this_fragment;
void from_ref(TypedRef tr, const DecompilerTypeSystem& dts);
u8 disable_fog = false; // jak 2 only
u8 use_warp = false;
u8 ignore_alpha = false;
u8 force_fade = false;
u8 disable_envamp = false;
void from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version);
std::string print() const;
};
@@ -213,7 +220,7 @@ struct MercCtrl {
MercCtrlHeader header;
std::vector<MercEffect> effects;
void from_ref(TypedRef tr, const DecompilerTypeSystem& dts);
void from_ref(TypedRef tr, const DecompilerTypeSystem& dts, GameVersion version);
void debug_print_blerc();
std::string print();
};
+9 -4
View File
@@ -136,7 +136,7 @@ MercCtrl extract_merc_ctrl(const LinkedObjectFile& file,
auto tr = typed_ref_from_basic(ref, dts);
MercCtrl ctrl;
ctrl.from_ref(tr, dts); // the merc data import
ctrl.from_ref(tr, dts, file.version); // the merc data import
return ctrl;
}
@@ -228,7 +228,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 depth_write) {
bool depth_write,
bool fge) {
DrawMode mode;
/*
* (new 'static 'gs-test
@@ -270,6 +271,8 @@ DrawMode process_draw_mode(const MercShader& info,
mode.set_clamp_s_enable(info.clamp & 0b1);
mode.set_clamp_t_enable(info.clamp & 0b100);
mode.set_fog(fge);
return mode;
}
@@ -769,7 +772,8 @@ 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, false);
result.envmap_mode =
process_draw_mode(*input_effect.extra_info.shader, false, 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());
@@ -910,8 +914,9 @@ ConvertedMercEffect convert_merc_effect(const MercEffect& input_effect,
for (size_t i = 0; i < frag.fp_header.shader_cnt; i++) {
const auto& shader = frag.shaders.at(i);
// update merc state from shader (will hold over to next fragment, if needed)
bool fog = ctrl_header.disable_fog == 0;
merc_state.merc_draw_mode.mode =
process_draw_mode(shader, result.has_envmap, use_alpha_blend, depth_write);
process_draw_mode(shader, result.has_envmap, use_alpha_blend, depth_write, fog);
if (!merc_state.merc_draw_mode.mode.get_tcc_enable()) {
ASSERT(false);
}
@@ -2550,6 +2550,9 @@ void add_vertices_and_static_draw(tfrag3::TieTree& tree,
// bool using_wind = true; // hack, for testing
bool using_wind = proto.stiffness != 0.f;
if (version == GameVersion::Jak2) {
using_wind = false; // disable wind on jak 2 for now - not supported in GOAL or C++ yet.
}
bool using_envmap = info.uses_envmap;
ASSERT(using_envmap == proto.envmap_adgif.has_value());
@@ -247,14 +247,15 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
u64 enable_mask;
u64 ignore_alpha_mask;
u8 effect_count;
u8 update_verts;
u8 bitflags;
};
auto* flags = (const PcMercFlags*)input_data;
int num_effects = flags->effect_count; // mostly just a sanity check
ASSERT(num_effects < kMaxEffect);
u64 current_ignore_alpha_bits = flags->ignore_alpha_mask; // shader settings
u64 current_effect_enable_bits = flags->enable_mask; // mask for game to disable an effect
bool model_uses_mod = flags->update_verts; // if we should update vertices from game.
bool model_uses_mod = flags->bitflags & 1; // if we should update vertices from game.
bool model_disables_fog = (flags->bitflags & 2);
input_data += 32;
// Next is "fade data", indicating the color/intensity of envmap effect
@@ -500,7 +501,8 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
// do fixed draws:
for (auto& fdraw : effect.mod.fix_draw) {
alloc_normal_draw(fdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water);
alloc_normal_draw(fdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
model_disables_fog);
if (should_envmap) {
try_alloc_envmap_draw(fdraw, effect.envmap_mode, effect.envmap_texture, lev_bucket,
fade_buffer + 4 * ei, first_bone, lights, uses_water);
@@ -509,7 +511,8 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
// do mod draws
for (auto& mdraw : effect.mod.mod_draw) {
auto n = alloc_normal_draw(mdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water);
auto n = alloc_normal_draw(mdraw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
model_disables_fog);
// modify the draw, set the mod flag and point it to the opengl buffer
n->flags |= MOD_VTX;
n->mod_vtx_buffer = mod_opengl_buffers[ei];
@@ -530,7 +533,8 @@ void Merc2::handle_pc_model(const DmaTransfer& setup,
try_alloc_envmap_draw(draw, effect.envmap_mode, effect.envmap_texture, lev_bucket,
fade_buffer + 4 * ei, first_bone, lights, uses_water);
}
alloc_normal_draw(draw, ignore_alpha, lev_bucket, first_bone, lights, uses_water);
alloc_normal_draw(draw, ignore_alpha, lev_bucket, first_bone, lights, uses_water,
model_disables_fog);
}
}
}
@@ -944,7 +948,8 @@ Merc2::Draw* Merc2::alloc_normal_draw(const tfrag3::MercDraw& mdraw,
LevelDrawBucket* lev_bucket,
u32 first_bone,
u32 lights,
bool jak1_water_mode) {
bool jak1_water_mode,
bool disable_fog) {
Draw* draw = &lev_bucket->draws[lev_bucket->next_free_draw++];
draw->flags = 0;
draw->first_index = mdraw.first_index;
@@ -954,6 +959,12 @@ Merc2::Draw* Merc2::alloc_normal_draw(const tfrag3::MercDraw& mdraw,
draw->mode.set_ab(true);
draw->mode.disable_depth_write();
}
if (disable_fog) {
draw->mode.set_fog(false);
// but don't toggle it the other way?
}
draw->texture = mdraw.eye_id == 0xff ? mdraw.tree_tex_id : (0xffffff00 | mdraw.eye_id);
draw->first_bone = first_bone;
draw->light_idx = lights;
@@ -1070,6 +1081,9 @@ void Merc2::do_draws(const Draw* draw_array,
int last_tex = -1;
int last_light = -1;
bool normal_vtx_buffer_bound = true;
bool fog_on = true;
for (u32 di = 0; di < num_draws; di++) {
auto& draw = draw_array[di];
if (draw.flags & MOD_VTX) {
@@ -1086,6 +1100,18 @@ void Merc2::do_draws(const Draw* draw_array,
}
}
glUniform1i(uniforms.ignore_alpha, draw.flags & DrawFlags::IGNORE_ALPHA);
if (fog_on && !draw.mode.get_fog_enable()) {
// on -> off
glUniform4f(uniforms.fog_color, render_state->fog_color[0] / 255.f,
render_state->fog_color[1] / 255.f, render_state->fog_color[2] / 255.f, 0);
fog_on = false;
} else if (!fog_on && draw.mode.get_fog_enable()) {
glUniform4f(uniforms.fog_color, render_state->fog_color[0] / 255.f,
render_state->fog_color[1] / 255.f, render_state->fog_color[2] / 255.f,
render_state->fog_intensity / 255);
fog_on = true;
}
bool use_mipmaps_for_filtering = true;
if ((int)draw.texture != last_tex) {
if (draw.texture < lev->textures.size()) {
@@ -86,7 +86,7 @@ class Merc2 : public BucketRenderer {
static constexpr int MAX_SHADER_BONE_VECTORS = 1024 * 32; // ??
static constexpr int MAX_LEVELS = 3;
static constexpr int MAX_DRAWS_PER_LEVEL = 2048;
static constexpr int MAX_DRAWS_PER_LEVEL = 2048 * 2;
static constexpr int MAX_ENVMAP_DRAWS_PER_LEVEL = MAX_DRAWS_PER_LEVEL;
math::Vector4f m_shader_bone_vector_buffer[MAX_SHADER_BONE_VECTORS];
@@ -200,7 +200,9 @@ class Merc2 : public BucketRenderer {
LevelDrawBucket* lev_bucket,
u32 first_bone,
u32 lights,
bool jak1_water_mode);
bool jak1_water_mode,
bool disable_fog);
Draw* try_alloc_envmap_draw(const tfrag3::MercDraw& mdraw,
const DrawMode& envmap_mode,
u32 envmap_texture,
+12 -2
View File
@@ -944,11 +944,18 @@
;; flags 2 qw
;; fades (u32 x N), padding to qw aligned
(defenum pc-merc-bits
:type uint8
:bitfield #t
(update-verts 0)
(disable-fog 1)
)
(deftype pc-merc-flags (structure)
((enable-mask uint64)
(ignore-alpha-mask uint64)
(effect-count uint8)
(update-verts uint8)
(bit-flags pc-merc-bits)
)
)
@@ -1055,7 +1062,10 @@
;; flags
(let ((flags (the (pc-merc-flags) dma-buf)))
(set! (-> flags effect-count) (-> merc-ctrl header effect-count))
(set! (-> flags update-verts) (if update-verts 1 0))
(set! (-> flags bit-flags) (the pc-merc-bits 0))
(when update-verts
(logior! (-> flags bit-flags) (pc-merc-bits update-verts))
)
(set! (-> flags enable-mask) enable-mask)
(set! (-> flags ignore-alpha-mask) ignore-alpha-mask)
)
@@ -630,11 +630,18 @@
)
)
(defenum pc-merc-bits
:type uint8
:bitfield #t
(update-verts 0)
(disable-fog 1)
)
(deftype pc-merc-flags (structure)
((enable-mask uint64)
(ignore-alpha-mask uint64)
(effect-count uint8)
(update-verts uint8)
(bit-flags pc-merc-bits)
)
)
@@ -730,7 +737,13 @@
;; flags
(let ((flags (the (pc-merc-flags) dma-buf)))
(set! (-> flags effect-count) (-> merc-ctrl header effect-count))
(set! (-> flags update-verts) (if update-verts 1 0))
(set! (-> flags bit-flags) (the pc-merc-bits 0))
(when update-verts
(logior! (-> flags bit-flags) (pc-merc-bits update-verts))
)
(when (logtest? (-> dc status) (draw-control-status disable-fog))
(logior! (-> flags bit-flags) (pc-merc-bits disable-fog))
)
(set! (-> flags enable-mask) enable-mask)
(set! (-> flags ignore-alpha-mask) ignore-alpha-mask)
)
+2 -4
View File
@@ -523,16 +523,14 @@ into 7 sections, which might explain the weird sizes in the center.
;; interestingly, if we are in the 'medium' mode, we use the size of the
;; previous object, plus 2048 bytes. Maybe the objects are sorted in decreasing size,
;; so this allows the big ones to load first, then shrink the temp buffer as the rest come in.
;; also seems to be no way to hit this case - the load-buffer-mode is eventually
;; forced to small-edge in all cases that I see. -- NOTE: not true!
;; the "medium" case is hit because the relocate method for `art-group` changes the mode.
;; if it detects that it runs after textures.
(case (-> arg0 load-buffer-mode)
(((load-buffer-mode small-center))
(set! (-> arg0 load-buffer-size) (the-as uint (* 1100 1024))) ;; 1100 KB
)
(((load-buffer-mode medium))
(set! (-> arg0 load-buffer-size) (+ (-> arg1 length) (* 2 1024)))
(format 0 "believed unused load-buffer-resize case hit.~%")
; (break!)
)
)
+3
View File
@@ -2238,6 +2238,9 @@
(shrink-heap (the dead-pool-heap (-> pp pool)) pp)
)
)
(('dead)
;; died in init, this is fine.
)
(else
(format 0 "GOT UNKNOWN INIT: ~A~%" (-> pp status))
)