mirror of
https://github.com/open-goal/jak-project
synced 2026-06-14 22:29:25 -04:00
[jak2] Fix depth testing issues on glow sprites (#2923)
https://github.com/open-goal/jak-project/assets/48171810/0d3064f9-3f27-4be1-b6a4-55fdfb681313 Fixes https://github.com/open-goal/jak-project/issues/2328
This commit is contained in:
@@ -126,6 +126,8 @@ ShaderLibrary::ShaderLibrary(GameVersion version) {
|
||||
at(ShaderId::ETIE) = {"etie", version};
|
||||
at(ShaderId::SHADOW2) = {"shadow2", version};
|
||||
at(ShaderId::TEX_ANIM) = {"tex_anim", version};
|
||||
at(ShaderId::GLOW_DEPTH_COPY) = {"glow_depth_copy", version};
|
||||
at(ShaderId::GLOW_PROBE_ON_GRID) = {"glow_probe_on_grid", version};
|
||||
|
||||
for (auto& shader : m_shaders) {
|
||||
ASSERT_MSG(shader.okay(), "error compiling shader");
|
||||
|
||||
@@ -59,6 +59,8 @@ enum class ShaderId {
|
||||
SHADOW2 = 32,
|
||||
DIRECT_BASIC_TEXTURED_MULTI_UNIT = 33,
|
||||
TEX_ANIM = 34,
|
||||
GLOW_DEPTH_COPY = 35,
|
||||
GLOW_PROBE_ON_GRID = 36,
|
||||
MAX_SHADERS
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#version 410 core
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
uniform sampler2D tex;
|
||||
|
||||
in vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
vec2 texture_coords = vec2(tex_coord.x, tex_coord.y);
|
||||
out_color = vec4(0, 0, 0, 0);
|
||||
if (texture_coords.x < 0 || texture_coords.x > 1 || texture_coords.y > 1 || texture_coords.x < 0) {
|
||||
gl_FragDepth = 1;
|
||||
} else {
|
||||
gl_FragDepth = texture(tex, texture_coords).r;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec4 position_in;
|
||||
layout (location = 1) in vec4 rgba_in;
|
||||
layout (location = 2) in vec2 uv;
|
||||
|
||||
out vec2 tex_coord;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4((position_in.xy * 2) - 1.f, 0.f, 1.f);
|
||||
tex_coord.x = uv.x / 512;
|
||||
tex_coord.y = 1.f - (uv.y / SCISSOR_HEIGHT);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#version 410 core
|
||||
|
||||
out vec4 color;
|
||||
|
||||
in vec4 fragment_color;
|
||||
|
||||
void main() {
|
||||
color = fragment_color;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec4 position_in;
|
||||
// layout (location = 1) in vec4 rgba_in;
|
||||
|
||||
out vec4 fragment_color;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4((position_in.xy * 2) - 1.f, (position_in.z / 8388608.f) - 1.f, 1.f);
|
||||
fragment_color = vec4(0, 0.5, 1, 1);
|
||||
}
|
||||
@@ -182,17 +182,20 @@ GlowRenderer::GlowRenderer() {
|
||||
glGenFramebuffers(1, &m_ogl.probe_fbo);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_ogl.probe_fbo);
|
||||
glGenTextures(1, &m_ogl.probe_fbo_rgba_tex);
|
||||
glGenTextures(1, &m_ogl.probe_fbo_depth_tex);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.probe_fbo_rgba_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h, 0, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, nullptr);
|
||||
glGenRenderbuffers(1, &m_ogl.probe_fbo_zbuf_rb);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_ogl.probe_fbo_zbuf_rb);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
m_ogl.probe_fbo_zbuf_rb);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
m_ogl.probe_fbo_rgba_tex, 0);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.probe_fbo_depth_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h, 0,
|
||||
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D,
|
||||
m_ogl.probe_fbo_depth_tex, 0);
|
||||
|
||||
GLenum render_targets[1] = {GL_COLOR_ATTACHMENT0};
|
||||
glDrawBuffers(1, render_targets);
|
||||
auto status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
@@ -210,6 +213,15 @@ GlowRenderer::GlowRenderer() {
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.downsample_fbos[i].tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ds_size * kDownsampleBatchWidth,
|
||||
ds_size * kDownsampleBatchWidth, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||
|
||||
if (i == 0) {
|
||||
glGenRenderbuffers(1, &m_ogl.first_ds_depth_rb);
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_ogl.first_ds_depth_rb);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, ds_size * kDownsampleBatchWidth,
|
||||
ds_size * kDownsampleBatchWidth);
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER,
|
||||
m_ogl.first_ds_depth_rb);
|
||||
}
|
||||
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
|
||||
m_ogl.downsample_fbos[i].tex, 0);
|
||||
glDrawBuffers(1, render_targets);
|
||||
@@ -234,6 +246,8 @@ GlowRenderer::GlowRenderer() {
|
||||
// ;; (new 'static 'gs-zbuf :zbp 304 :psm 1 :zmsk 1)
|
||||
// (new 'static 'gs-adcmd :cmds (gs-reg64 zbuf-1) :x #x1000130 :y #x1)
|
||||
m_default_draw_mode.disable_depth_write();
|
||||
|
||||
glGenTextures(1, &m_ogl.depth_texture);
|
||||
}
|
||||
|
||||
namespace {
|
||||
@@ -361,6 +375,48 @@ void GlowRenderer::add_sprite_pass_2(const SpriteGlowOutput& data, int sprite_id
|
||||
idx[4] = UINT32_MAX;
|
||||
}
|
||||
|
||||
void GlowRenderer::add_sprite_new(const SpriteGlowOutput& data, int sprite_idx) {
|
||||
// output is a grid of kBatchWidth * kBatchWidth.
|
||||
// for simplicity, we'll map to (0, 1) here, and the shader will convert to (-1, 1) for opengl.
|
||||
int x = sprite_idx / kDownsampleBatchWidth;
|
||||
int y = sprite_idx % kDownsampleBatchWidth;
|
||||
float step = 1.f / kDownsampleBatchWidth;
|
||||
|
||||
u32 idx_start = m_next_vertex;
|
||||
Vertex* vtx = alloc_vtx(4);
|
||||
for (int i = 0; i < 4; i++) {
|
||||
vtx[i].r = 1.f; // debug
|
||||
vtx[i].g = 0.f;
|
||||
vtx[i].b = 0.f;
|
||||
vtx[i].a = 0.f;
|
||||
vtx[i].x = x * step; // start of our cell
|
||||
vtx[i].y = y * step;
|
||||
vtx[i].z = data.second_clear_pos[0].z();
|
||||
vtx[i].w = 0;
|
||||
}
|
||||
vtx[1].x += step;
|
||||
vtx[2].y += step;
|
||||
vtx[3].x += step;
|
||||
vtx[3].y += step;
|
||||
|
||||
// transformation code gives us these coordinates for where to sample probe fbo
|
||||
vtx[0].u = data.offscreen_uv[0][0];
|
||||
vtx[0].v = data.offscreen_uv[0][1];
|
||||
vtx[1].u = data.offscreen_uv[1][0];
|
||||
vtx[1].v = data.offscreen_uv[0][1];
|
||||
vtx[2].u = data.offscreen_uv[0][0];
|
||||
vtx[2].v = data.offscreen_uv[1][1];
|
||||
vtx[3].u = data.offscreen_uv[1][0];
|
||||
vtx[3].v = data.offscreen_uv[1][1];
|
||||
|
||||
u32* idx = alloc_index(5);
|
||||
idx[0] = idx_start;
|
||||
idx[1] = idx_start + 1;
|
||||
idx[2] = idx_start + 2;
|
||||
idx[3] = idx_start + 3;
|
||||
idx[4] = UINT32_MAX;
|
||||
}
|
||||
|
||||
/*!
|
||||
* Add pass 3 vertices and update sprite records. This is the final draw.
|
||||
*/
|
||||
@@ -469,9 +525,10 @@ void GlowRenderer::blit_depth(SharedRenderState* render_state) {
|
||||
GL_UNSIGNED_BYTE, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
glBindRenderbuffer(GL_RENDERBUFFER, m_ogl.probe_fbo_zbuf_rb);
|
||||
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, m_ogl.probe_fbo_w,
|
||||
m_ogl.probe_fbo_h);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.probe_fbo_depth_tex);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h, 0,
|
||||
GL_DEPTH_COMPONENT, GL_FLOAT, NULL);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, render_state->render_fb);
|
||||
@@ -509,6 +566,8 @@ void GlowRenderer::downsample_chain(SharedRenderState* render_state,
|
||||
GLint old_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, old_viewport);
|
||||
render_state->shaders[ShaderId::GLOW_PROBE_DOWNSAMPLE].activate();
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
for (int i = 0; i < kDownsampleIterations - 1; i++) {
|
||||
auto* source = &m_ogl.downsample_fbos[i];
|
||||
auto* dest = &m_ogl.downsample_fbos[i + 1];
|
||||
@@ -528,6 +587,21 @@ void GlowRenderer::downsample_chain(SharedRenderState* render_state,
|
||||
glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]);
|
||||
}
|
||||
|
||||
void GlowRenderer::setup_buffers_for_draws() {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_ogl.probe_fbo);
|
||||
glBindVertexArray(m_ogl.vao);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
// don't want to write to the depth buffer we just copied, just test against it.
|
||||
glDepthMask(GL_FALSE);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, m_next_vertex * sizeof(Vertex), m_vertex_buffer.data(),
|
||||
GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_index * sizeof(u32), m_index_buffer.data(),
|
||||
GL_STREAM_DRAW);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Draw probes (including the clear) to the probe fbo. Also copies vertex/index buffer.
|
||||
*/
|
||||
@@ -535,24 +609,10 @@ void GlowRenderer::draw_probes(SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof,
|
||||
u32 idx_start,
|
||||
u32 idx_end) {
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_ogl.probe_fbo);
|
||||
glBindVertexArray(m_ogl.vao);
|
||||
glEnable(GL_PRIMITIVE_RESTART);
|
||||
glPrimitiveRestartIndex(UINT32_MAX);
|
||||
// don't want to write to the depth buffer we just copied, just test against it.
|
||||
glDepthMask(GL_FALSE);
|
||||
render_state->shaders[ShaderId::GLOW_PROBE].activate();
|
||||
GLint old_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, old_viewport);
|
||||
glViewport(0, 0, m_ogl.probe_fbo_w, m_ogl.probe_fbo_h);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, m_next_vertex * sizeof(Vertex), m_vertex_buffer.data(),
|
||||
GL_STREAM_DRAW);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer);
|
||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_index * sizeof(u32), m_index_buffer.data(),
|
||||
GL_STREAM_DRAW);
|
||||
|
||||
// do probes
|
||||
render_state->shaders[ShaderId::GLOW_PROBE].activate();
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(m_next_sprite * 4);
|
||||
glDisable(GL_BLEND);
|
||||
@@ -589,6 +649,7 @@ void GlowRenderer::draw_probe_copies(SharedRenderState* render_state,
|
||||
glGetIntegerv(GL_VIEWPORT, old_viewport);
|
||||
render_state->shaders[ShaderId::GLOW_PROBE_READ].activate();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_ogl.downsample_fbos[0].fbo);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.probe_fbo_rgba_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
@@ -617,20 +678,7 @@ void GlowRenderer::debug_draw_probe_copies(SharedRenderState* render_state,
|
||||
(void*)(idx_start * sizeof(u32)));
|
||||
}
|
||||
|
||||
/*!
|
||||
* Draw all pending sprites.
|
||||
*/
|
||||
void GlowRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
m_debug.num_sprites = m_next_sprite;
|
||||
if (!m_next_sprite) {
|
||||
// no sprites submitted.
|
||||
return;
|
||||
}
|
||||
|
||||
// copy depth from framebuffer to a temporary buffer
|
||||
// (this is a bit wasteful)
|
||||
blit_depth(render_state);
|
||||
|
||||
void GlowRenderer::probe_and_copy_old(SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
// generate vertex/index data for probes
|
||||
u32 probe_idx_start = m_next_index;
|
||||
for (u32 sidx = 0; sidx < m_next_sprite; sidx++) {
|
||||
@@ -650,6 +698,7 @@ void GlowRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& pr
|
||||
}
|
||||
|
||||
// draw probes
|
||||
setup_buffers_for_draws();
|
||||
draw_probes(render_state, prof, probe_idx_start, copy_idx_start);
|
||||
if (m_debug.show_probes) {
|
||||
debug_draw_probes(render_state, prof, probe_idx_start, copy_idx_start);
|
||||
@@ -660,6 +709,76 @@ void GlowRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& pr
|
||||
if (m_debug.show_probe_copies) {
|
||||
debug_draw_probe_copies(render_state, prof, copy_idx_start, copy_idx_end);
|
||||
}
|
||||
}
|
||||
|
||||
void GlowRenderer::probe_and_copy_new(SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
u32 idx_start = m_next_index;
|
||||
for (u32 sidx = 0; sidx < m_next_sprite; sidx++) {
|
||||
add_sprite_new(m_sprite_data_buffer[sidx], sidx);
|
||||
}
|
||||
u32 idx_end = m_next_index;
|
||||
|
||||
// generate vertex/index data for framebuffer draws
|
||||
for (u32 sidx = 0; sidx < m_next_sprite; sidx++) {
|
||||
add_sprite_pass_3(m_sprite_data_buffer[sidx], sidx);
|
||||
}
|
||||
|
||||
// clear the grid.
|
||||
setup_buffers_for_draws();
|
||||
GLint old_viewport[4];
|
||||
glGetIntegerv(GL_VIEWPORT, old_viewport);
|
||||
render_state->shaders[ShaderId::GLOW_PROBE_READ].activate();
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, m_ogl.downsample_fbos[0].fbo);
|
||||
glBindTexture(GL_TEXTURE_2D, m_ogl.probe_fbo_depth_tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
glViewport(0, 0, m_ogl.downsample_fbos[0].size, m_ogl.downsample_fbos[0].size);
|
||||
|
||||
// TODO: can probably remove this clear
|
||||
glClearColor(0.0, 0.0, 0.0, 0.0);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_ALWAYS);
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
render_state->shaders[ShaderId::GLOW_DEPTH_COPY].activate();
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(m_next_sprite * 2);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, idx_end - idx_start, GL_UNSIGNED_INT,
|
||||
(void*)(idx_start * sizeof(u32)));
|
||||
|
||||
render_state->shaders[ShaderId::GLOW_PROBE_ON_GRID].activate();
|
||||
glDepthFunc(GL_GREATER);
|
||||
prof.add_draw_call();
|
||||
prof.add_tri(m_next_sprite * 2);
|
||||
glDrawElements(GL_TRIANGLE_STRIP, idx_end - idx_start, GL_UNSIGNED_INT,
|
||||
(void*)(idx_start * sizeof(u32)));
|
||||
|
||||
glViewport(old_viewport[0], old_viewport[1], old_viewport[2], old_viewport[3]);
|
||||
}
|
||||
|
||||
/*!
|
||||
* Draw all pending sprites.
|
||||
*/
|
||||
void GlowRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) {
|
||||
m_debug.num_sprites = m_next_sprite;
|
||||
if (!m_next_sprite) {
|
||||
// no sprites submitted.
|
||||
return;
|
||||
}
|
||||
|
||||
// copy depth from framebuffer to a temporary buffer
|
||||
// (this is a bit wasteful)
|
||||
blit_depth(render_state);
|
||||
|
||||
if (new_mode) {
|
||||
probe_and_copy_new(render_state, prof);
|
||||
} else {
|
||||
probe_and_copy_old(render_state, prof);
|
||||
}
|
||||
|
||||
// downsample probes.
|
||||
downsample_chain(render_state, prof, m_next_sprite);
|
||||
|
||||
@@ -11,6 +11,8 @@ class GlowRenderer {
|
||||
void flush(SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void draw_debug_window();
|
||||
|
||||
bool new_mode = true;
|
||||
|
||||
// Vertex can hold all possible values for all passes. The total number of vertices is very small
|
||||
// so it ends up a lot faster to do a single upload, even if the size is like 50% larger than it
|
||||
// could be.
|
||||
@@ -32,8 +34,15 @@ class GlowRenderer {
|
||||
void add_sprite_pass_2(const SpriteGlowOutput& data, int sprite_idx);
|
||||
void add_sprite_pass_3(const SpriteGlowOutput& data, int sprite_idx);
|
||||
|
||||
void add_sprite_new(const SpriteGlowOutput& data, int sprite_idx);
|
||||
|
||||
void probe_and_copy_old(SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
void probe_and_copy_new(SharedRenderState* render_state, ScopedProfilerNode& prof);
|
||||
|
||||
void blit_depth(SharedRenderState* render_state);
|
||||
|
||||
void setup_buffers_for_draws();
|
||||
|
||||
void draw_probes(SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof,
|
||||
u32 idx_start,
|
||||
@@ -91,10 +100,14 @@ class GlowRenderer {
|
||||
|
||||
GLuint probe_fbo;
|
||||
GLuint probe_fbo_rgba_tex;
|
||||
GLuint probe_fbo_zbuf_rb;
|
||||
GLuint probe_fbo_depth_tex;
|
||||
GLuint first_ds_depth_rb;
|
||||
// GLuint probe_fbo_zbuf_rb;
|
||||
int probe_fbo_w = 640;
|
||||
int probe_fbo_h = 480;
|
||||
|
||||
GLuint depth_texture;
|
||||
|
||||
DsFbo downsample_fbos[kDownsampleIterations];
|
||||
} m_ogl;
|
||||
|
||||
|
||||
@@ -550,6 +550,8 @@ void Sprite3::render_jak1(DmaFollower& dma,
|
||||
}
|
||||
|
||||
void Sprite3::draw_debug_window() {
|
||||
ImGui::Checkbox("Glow", &m_enable_glow);
|
||||
ImGui::Checkbox("new glow", &m_glow_renderer.new_mode);
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Distort sprites: %d", m_distort_stats.total_sprites);
|
||||
ImGui::Text("2D Group 0 (World) blocks: %d sprites: %d", m_debug_stats.blocks_2d_grp0,
|
||||
@@ -558,7 +560,6 @@ void Sprite3::draw_debug_window() {
|
||||
m_debug_stats.count_2d_grp1);
|
||||
ImGui::Checkbox("Culling", &m_enable_culling);
|
||||
ImGui::Checkbox("2d", &m_2d_enable);
|
||||
ImGui::Checkbox("Glow", &m_enable_glow);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("3d", &m_3d_enable);
|
||||
ImGui::Checkbox("Distort", &m_distort_enable);
|
||||
|
||||
@@ -27,6 +27,7 @@ static_assert(sizeof(SpriteGlowData) == 16 * 4);
|
||||
* small, so not a big deal.
|
||||
*/
|
||||
bool glow_math(const SpriteGlowConsts* consts,
|
||||
bool skip_uv_clamp,
|
||||
const void* vec_data,
|
||||
const void* adgif_data,
|
||||
SpriteGlowOutput* out) {
|
||||
@@ -137,9 +138,14 @@ bool glow_math(const SpriteGlowConsts* consts,
|
||||
// max.xy vf20, vf01, vf09 -> is this bugged? I think the x broadcast here is wrong
|
||||
// this breaks fadeout as the sprite moves off the top of the screen. I've fixed it here because
|
||||
// I'm pretty sure this is just a mistake.
|
||||
math::Vector2f vf20_pos(std::max(p0.x(), vf09_min_probe_center.x()),
|
||||
std::max(p0.y(), vf09_min_probe_center.y()));
|
||||
vf20_pos.min_in_place(vf10_max_probe_center);
|
||||
math::Vector2f vf20_pos;
|
||||
if (skip_uv_clamp) {
|
||||
vf20_pos = p0.xy();
|
||||
} else {
|
||||
vf20_pos = math::Vector2f(std::max(p0.x(), vf09_min_probe_center.x()),
|
||||
std::max(p0.y(), vf09_min_probe_center.y()));
|
||||
vf20_pos.min_in_place(vf10_max_probe_center);
|
||||
}
|
||||
|
||||
// vf17 thing, vf18 thing
|
||||
math::Vector2f vf17(consts->clamp_min.x() - 1, consts->clamp_min.y() - 1);
|
||||
@@ -215,7 +221,7 @@ void Sprite3::glow_dma_and_draw(DmaFollower& dma,
|
||||
|
||||
if (m_enable_glow) {
|
||||
auto* out = m_glow_renderer.alloc_sprite();
|
||||
if (!glow_math(&consts, vecdata_xfer.data, shader_xfer.data, out)) {
|
||||
if (!glow_math(&consts, m_glow_renderer.new_mode, vecdata_xfer.data, shader_xfer.data, out)) {
|
||||
m_glow_renderer.cancel_sprite();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user