mirror of
https://github.com/open-goal/jak-project
synced 2026-05-30 08:56:59 -04:00
fix shadow colors in jak 1 and jak 2 shadow crash (#2647)
Fixes Jak 1 shadow color. Old behavior is subtractive blend with a hardcoded value, which often times look way too dark, but it looks like the actual game uses some sort of multiplicative blend and a customizable shadow color (for all shadows at once). Before vs after:     Also fixes #2646
This commit is contained in:
@@ -242,15 +242,15 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
|
||||
BucketId::TEX_ALL_MAP);
|
||||
// 320
|
||||
init_bucket_renderer<ProgressRenderer>("progress", BucketCategory::OTHER, BucketId::PROGRESS,
|
||||
0x8000);
|
||||
0x1000);
|
||||
init_bucket_renderer<DirectRenderer>("screen-filter", BucketCategory::OTHER,
|
||||
BucketId::SCREEN_FILTER, 256);
|
||||
init_bucket_renderer<DirectRenderer>("subtitle", BucketCategory::OTHER, BucketId::SUBTITLE,
|
||||
0x8000);
|
||||
0x1000);
|
||||
init_bucket_renderer<DirectRenderer>("debug2", BucketCategory::OTHER, BucketId::DEBUG2, 0x8000);
|
||||
init_bucket_renderer<DirectRenderer>("debug-no-zbuf2", BucketCategory::OTHER,
|
||||
BucketId::DEBUG_NO_ZBUF2, 0x8000);
|
||||
init_bucket_renderer<DirectRenderer>("debug3", BucketCategory::OTHER, BucketId::DEBUG3, 0x1000);
|
||||
init_bucket_renderer<DirectRenderer>("debug3", BucketCategory::OTHER, BucketId::DEBUG3, 0x2000);
|
||||
|
||||
auto eye_renderer = std::make_unique<EyeRenderer>("eyes", 0);
|
||||
m_render_state.eye_renderer = eye_renderer.get();
|
||||
@@ -259,7 +259,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
|
||||
// for now, for any unset renderers, just set them to an EmptyBucketRenderer.
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
if (!m_bucket_renderers[i]) {
|
||||
init_bucket_renderer<EmptyBucketRenderer>(fmt::format("bucket{}", i), BucketCategory::OTHER,
|
||||
init_bucket_renderer<EmptyBucketRenderer>(fmt::format("bucket-{}", i), BucketCategory::OTHER,
|
||||
i);
|
||||
}
|
||||
|
||||
@@ -353,6 +353,8 @@ void OpenGLRenderer::init_bucket_renderers_jak1() {
|
||||
// 22 : SHRUB_BILLBOARD_LEVEL0
|
||||
// 23 : SHRUB_TRANS_LEVEL0
|
||||
// 24 : SHRUB_GENERIC_LEVEL0
|
||||
init_bucket_renderer<Generic2>("l0-shrub-generic", BucketCategory::GENERIC,
|
||||
BucketId::SHRUB_GENERIC_LEVEL0);
|
||||
|
||||
//-----------------------
|
||||
// LEVEL 1 shrub texture
|
||||
@@ -366,7 +368,7 @@ void OpenGLRenderer::init_bucket_renderers_jak1() {
|
||||
// 28 : SHRUB_BILLBOARD_LEVEL1
|
||||
// 29 : SHRUB_TRANS_LEVEL1
|
||||
// 30 : SHRUB_GENERIC_LEVEL1
|
||||
init_bucket_renderer<Generic2>("mystery-generic", BucketCategory::GENERIC,
|
||||
init_bucket_renderer<Generic2>("l1-shrub-generic", BucketCategory::GENERIC,
|
||||
BucketId::SHRUB_GENERIC_LEVEL1);
|
||||
|
||||
//-----------------------
|
||||
@@ -484,7 +486,7 @@ void OpenGLRenderer::init_bucket_renderers_jak1() {
|
||||
// for now, for any unset renderers, just set them to an EmptyBucketRenderer.
|
||||
for (size_t i = 0; i < m_bucket_renderers.size(); i++) {
|
||||
if (!m_bucket_renderers[i]) {
|
||||
init_bucket_renderer<EmptyBucketRenderer>(fmt::format("bucket{}", i), BucketCategory::OTHER,
|
||||
init_bucket_renderer<EmptyBucketRenderer>(fmt::format("bucket-{}", i), BucketCategory::OTHER,
|
||||
(BucketId)i);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ void ShadowRenderer::xgkick(u16 imm) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
rgba[i] = data[offset + i * 4];
|
||||
}
|
||||
// fmt::print("rgbap: {} {} {} {}\n", rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
// fmt::print("rgbaq: {} {} {} {}\n", rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
break;
|
||||
case GifTag::RegisterDescriptor::XYZF2:
|
||||
// handle_xyzf2_packed(data + offset, render_state, prof);
|
||||
@@ -302,10 +302,20 @@ void ShadowRenderer::render(DmaFollower& dma,
|
||||
run_mscal_vu2c(mscal.immediate);
|
||||
} else if (next.vifcode0().kind == VifCode::Kind::FLUSHA &&
|
||||
next.vifcode1().kind == VifCode::Kind::DIRECT) {
|
||||
// there's 4 direct transfers to set up various registers.
|
||||
// we only care about the one that has the color value.
|
||||
auto xfer1 = dma.read_and_advance();
|
||||
dma.read_and_advance();
|
||||
dma.read_and_advance();
|
||||
dma.read_and_advance();
|
||||
|
||||
auto r = *(xfer1.data + 24);
|
||||
auto g = *(xfer1.data + 25);
|
||||
auto b = *(xfer1.data + 26);
|
||||
auto a = *(xfer1.data + 27);
|
||||
m_color.x() = r / 255.0f;
|
||||
m_color.y() = g / 255.0f;
|
||||
m_color.z() = b / 255.0f;
|
||||
m_color.w() = a / 128.0f;
|
||||
fmt::print("rgba: {} {} {} {}\n", r, g, b, a);
|
||||
} else {
|
||||
ASSERT_MSG(false, fmt::format("{} {}", next.vifcode0().print(), next.vifcode1().print()));
|
||||
}
|
||||
@@ -349,7 +359,6 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
glDepthMask(GL_FALSE); // no depth writes.
|
||||
if (m_debug_draw_volume) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ZERO, GL_ONE);
|
||||
} else {
|
||||
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); // no color writes.
|
||||
@@ -361,7 +370,7 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
|
||||
{
|
||||
glUniform4f(glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"),
|
||||
0., 0.4, 0., 0.5);
|
||||
0.0f, 128.0f / 256, 0.0f, 127.0f / 256);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[0]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_front_index * sizeof(u32), m_front_indices,
|
||||
GL_STREAM_DRAW);
|
||||
@@ -372,8 +381,8 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
if (m_debug_draw_volume) {
|
||||
glDisable(GL_BLEND);
|
||||
glUniform4f(
|
||||
glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"), 0.,
|
||||
0.0, 0., 0.5);
|
||||
glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"), 0.0f,
|
||||
0.0f, 0.0f, 0.5f);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glDrawElements(GL_TRIANGLES, (m_next_front_index - 6), GL_UNSIGNED_INT, nullptr);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
@@ -385,7 +394,7 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
|
||||
{
|
||||
glUniform4f(glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"),
|
||||
0.4, 0.0, 0., 0.5);
|
||||
128.0f / 256, 0.0f, 0.0f, 130.0f / 256);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[1]);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_back_index * sizeof(u32), m_back_indices,
|
||||
GL_STREAM_DRAW);
|
||||
@@ -397,8 +406,8 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
if (m_debug_draw_volume) {
|
||||
glDisable(GL_BLEND);
|
||||
glUniform4f(
|
||||
glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"), 0.,
|
||||
0.0, 0., 0.5);
|
||||
glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"), 0.0f,
|
||||
0.0f, 0.0f, 0.5f);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
glDrawElements(GL_TRIANGLES, (m_next_back_index - 0), GL_UNSIGNED_INT, nullptr);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
@@ -412,20 +421,20 @@ void ShadowRenderer::draw(SharedRenderState* render_state, ScopedProfilerNode& p
|
||||
// finally, draw shadow.
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[0]);
|
||||
glUniform4f(glGetUniformLocation(render_state->shaders[ShaderId::SHADOW].id(), "color_uniform"),
|
||||
0.13, 0.13, 0.13, 0.5);
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
m_color.x(), m_color.y(), m_color.z(), m_color.w());
|
||||
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);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ZERO);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void*)(sizeof(u32) * (m_next_front_index - 6)));
|
||||
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(2);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
|
||||
@@ -119,6 +119,8 @@ class ShadowRenderer : public BucketRenderer {
|
||||
u32 m_next_front_index = 0;
|
||||
u32 m_next_back_index = 0;
|
||||
|
||||
math::Vector4f m_color;
|
||||
|
||||
struct {
|
||||
// index is front, back
|
||||
GLuint vertex_buffer, index_buffer[2], vao;
|
||||
|
||||
@@ -63,7 +63,6 @@ void Shadow2::reset_buffers() {
|
||||
}
|
||||
|
||||
void Shadow2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
reset_buffers();
|
||||
// jump to bucket
|
||||
dma.read_and_advance();
|
||||
|
||||
@@ -79,6 +78,8 @@ void Shadow2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedPr
|
||||
return;
|
||||
}
|
||||
|
||||
reset_buffers();
|
||||
|
||||
// shadow-vu1-constants
|
||||
ASSERT(maybe_constants.size_bytes >= sizeof(ShadowVu1Constants));
|
||||
FrameConstants frame_constants;
|
||||
@@ -550,7 +551,6 @@ void Shadow2::draw_buffers(SharedRenderState* render_state,
|
||||
|
||||
if (have_darken) {
|
||||
glColorMask(darken_channel[0], darken_channel[1], darken_channel[2], false);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
glUniform4f(m_ogl.uniforms.color, (128 - m_color[0]) / 256.f, (128 - m_color[1]) / 256.f,
|
||||
(128 - m_color[2]) / 256.f, 0);
|
||||
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
|
||||
@@ -575,4 +575,4 @@ void Shadow2::draw_buffers(SharedRenderState* render_state,
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glDisable(GL_STENCIL_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
class Shadow2 : public BucketRenderer {
|
||||
public:
|
||||
static constexpr int kMaxVerts = 8192 * 3;
|
||||
static constexpr int kMaxInds = 8192 * 3;
|
||||
static constexpr int kMaxVerts = 8192 * 3 * 2;
|
||||
static constexpr int kMaxInds = kMaxVerts;
|
||||
Shadow2(const std::string& name, int my_id);
|
||||
~Shadow2();
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
|
||||
@@ -4,5 +4,5 @@ out vec4 color;
|
||||
uniform vec4 color_uniform;
|
||||
|
||||
void main() {
|
||||
color = color_uniform;
|
||||
color = color_uniform * 2;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user