mirror of
https://github.com/open-goal/jak-project
synced 2026-06-07 20:11:39 -04:00
jak2 fixes
This commit is contained in:
@@ -249,11 +249,10 @@ std::vector<ShadowData> extract_jak2_shadow_data(const LinkedObjectFile& file,
|
||||
// lg::info("{} {} fragments", name, num_fragments);
|
||||
auto frags_ref =
|
||||
TypedRef(get_field_ref(tr, "frags", dts), dts.ts.lookup_type("shadow-frag-ref"));
|
||||
|
||||
auto header_ref = TypedRef(deref_label(get_field_ref(frags_ref, "header", dts)),
|
||||
dts.ts.lookup_type("shadow-frag-header"));
|
||||
u32 size_qwc = read_plain_data_field<s32>(frags_ref, "qwc", dts);
|
||||
for (u32 i = 0; i < num_fragments; i++) {
|
||||
auto header_ref = TypedRef(deref_label(get_field_ref(frags_ref, "header", dts)),
|
||||
dts.ts.lookup_type("shadow-frag-header"));
|
||||
u32 size_qwc = read_plain_data_field<s32>(frags_ref, "qwc", dts);
|
||||
shadow_datas.push_back(
|
||||
extract_shadow_data(file, dts, header_ref, name, size_qwc, num_joints));
|
||||
frags_ref.ref.byte_offset += 8;
|
||||
|
||||
@@ -232,16 +232,58 @@ void Shadow3::draw_model(SharedRenderState* render_state,
|
||||
void Shadow3::finish(SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
// finally, draw shadow.
|
||||
if (!m_hacks) {
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
// glStencilFunc(GL_GREATER, 0, 0);
|
||||
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
if (render_state->version == GameVersion::Jak1) {
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
|
||||
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
m_full_screen_draw.draw(m_color, render_state, prof);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
m_full_screen_draw.draw(m_color, render_state, prof);
|
||||
} else {
|
||||
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ZERO);
|
||||
|
||||
bool have_darken = false;
|
||||
bool have_lighten = false;
|
||||
bool lighten_channel[3] = {false, false, false};
|
||||
bool darken_channel[3] = {false, false, false};
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (m_color[i] > 128) {
|
||||
have_lighten = true;
|
||||
lighten_channel[i] = true;
|
||||
} else if (m_color[i] < 128) {
|
||||
have_darken = true;
|
||||
darken_channel[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (have_darken) {
|
||||
glColorMask(darken_channel[0], darken_channel[1], darken_channel[2], false);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
m_full_screen_draw.draw(
|
||||
math::Vector4f((m_color[3] - m_color[0]) / 256.f, (m_color[3] - m_color[1]) / 256.f,
|
||||
(m_color[3] - m_color[2]) / 256.f, 0) *
|
||||
0.5f,
|
||||
render_state, prof);
|
||||
}
|
||||
|
||||
if (have_lighten) {
|
||||
glColorMask(lighten_channel[0], lighten_channel[1], lighten_channel[2], false);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
m_full_screen_draw.draw(
|
||||
math::Vector4f((m_color[0] - m_color[3]) / 256.f, (m_color[1] - m_color[3]) / 256.f,
|
||||
(m_color[2] - m_color[3]) / 256.f, 0) *
|
||||
0.5f,
|
||||
render_state, prof);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// restore
|
||||
@@ -293,6 +335,7 @@ void Shadow3::flush_requests(SharedRenderState* render_state, ScopedProfilerNode
|
||||
void Shadow3::first_time_setup(SharedRenderState* render_state) {
|
||||
glClearStencil(0);
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
render_state->stencil_dirty = true;
|
||||
|
||||
render_state->shaders[ShaderId::SHADOW3].activate();
|
||||
glUniformMatrix4fv(m_uniforms.camera_rot, 1, GL_FALSE, &render_state->camera_rot[0].x());
|
||||
@@ -314,6 +357,7 @@ void Shadow3::render_jak1(DmaFollower& dma,
|
||||
m_did_first_time_setup = false;
|
||||
while (dma.current_tag_offset() != render_state->next_bucket) {
|
||||
auto data = dma.read_and_advance();
|
||||
|
||||
if (data.vifcode0().kind == VifCode::Kind::PC_PORT) {
|
||||
u32 next = data.data_offset;
|
||||
while (next) {
|
||||
@@ -328,7 +372,7 @@ void Shadow3::render_jak1(DmaFollower& dma,
|
||||
|
||||
auto model = render_state->loader->get_shadow_model(name);
|
||||
if (!model) {
|
||||
printf(" SKIP: no model data\n");
|
||||
// printf(" SKIP: no model data\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -375,7 +419,9 @@ void Shadow3::render_jak1(DmaFollower& dma,
|
||||
request.bones = g_ee_main_mem + game_request.mtx;
|
||||
request.scissor_top = game_request.settings.flags & kUpperClip;
|
||||
request.color = game_request.color;
|
||||
request.dist_to_locus = game_request.settings.dist_to_locus;
|
||||
m_color = request.color;
|
||||
// m_color = {0.2, 0.8, 0.2, 1.};
|
||||
|
||||
// copy bones to buffer
|
||||
constexpr int in_stride = 8 * 4 * sizeof(float);
|
||||
@@ -415,9 +461,22 @@ void Shadow3::render_jak1(DmaFollower& dma,
|
||||
chain->head = &request;
|
||||
|
||||
// detect if the origin is below the clipping plane and if so, move it up.
|
||||
const float dot = request.bottom_plane.xyz().dot(request.origin);
|
||||
if (dot + request.bottom_plane.w() > 0) {
|
||||
request.bottom_plane.w() = -dot;
|
||||
// the logic for this changed in jak2, to support shadows with negative dist_from_locus
|
||||
if (render_state->version == GameVersion::Jak1) {
|
||||
const float dot = request.bottom_plane.xyz().dot(request.origin);
|
||||
if (dot + request.bottom_plane.w() > 0) {
|
||||
request.bottom_plane.w() = -dot;
|
||||
}
|
||||
} else {
|
||||
const float bot_offset = request.origin.dot(request.bottom_plane.xyz());
|
||||
const float top_offset = request.origin.dot(request.top_plane.xyz());
|
||||
if ((request.bottom_plane.w() < bot_offset) && (top_offset < request.top_plane.w())) {
|
||||
if (request.dist_to_locus > 0) {
|
||||
request.bottom_plane.w() = -bot_offset;
|
||||
} else {
|
||||
request.top_plane.w() = -top_offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const auto& cam_rot = render_state->camera_rot;
|
||||
|
||||
@@ -40,6 +40,7 @@ class Shadow3 {
|
||||
math::Vector<float, 3> origin;
|
||||
math::Vector4f top_plane, bottom_plane;
|
||||
math::Vector3f light_dir;
|
||||
float dist_to_locus;
|
||||
math::Vector4f color;
|
||||
ShadowRequest* next = nullptr;
|
||||
const u8* bones = nullptr;
|
||||
|
||||
@@ -629,7 +629,6 @@
|
||||
|
||||
;; if we're the first in the list, store in the run
|
||||
(when (zero? (-> run first))
|
||||
(format 0 "Setting first to #x~X~%" pse)
|
||||
(set! (-> run first) (the pointer pse)))
|
||||
|
||||
;; patch next pointer of previous
|
||||
|
||||
@@ -652,8 +652,34 @@
|
||||
|
||||
(dotimes (i 2)
|
||||
(when (nonzero? (-> *pc-shadow-globals* bucket i first))
|
||||
;; patch the color of each request.
|
||||
(let ((iter (the pc-shadow-request (-> *pc-shadow-globals* bucket i first)))
|
||||
(color (new-stack-vector0))
|
||||
)
|
||||
|
||||
(cond
|
||||
((= i 0)
|
||||
(vector-float*! color (-> *time-of-day-context* current-shadow-color) 128.0)
|
||||
)
|
||||
(else
|
||||
(let ((c (-> *pc-shadow-globals* bucket i shadow-color)))
|
||||
(set! (-> color x) (the float (-> c r)))
|
||||
(set! (-> color y) (the float (-> c g)))
|
||||
(set! (-> color z) (the float (-> c b)))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(set! (-> color w) (the float (-> *pc-shadow-globals* bucket i shadow-color a)))
|
||||
|
||||
(while (nonzero? iter)
|
||||
;(vector-copy! (-> iter color) color)
|
||||
(set! (-> iter color quad) (-> color quad))
|
||||
(set! iter (-> iter next))
|
||||
)
|
||||
)
|
||||
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (if (zero? i) (bucket-id shadow) (bucket-id shadow2)))
|
||||
(format 0 "dma bucket ~d from ~X~%" i (-> *pc-shadow-globals* bucket i first))
|
||||
(dma-buffer-add-ref-vif2
|
||||
dma-buf
|
||||
6
|
||||
|
||||
Reference in New Issue
Block a user