mirror of
https://github.com/open-goal/jak-project
synced 2026-07-05 21:49:28 -04:00
[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:
@@ -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,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++) {
|
||||
|
||||
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
)
|
||||
|
||||
@@ -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!)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -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))
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user