mirror of
https://github.com/open-goal/jak-project
synced 2026-07-08 14:36:52 -04:00
[gfx] Fix eye-related crash, clear color logic (#3957)
When building the eye texture, the background is first set to the top corner of the iris texture. A long, long time ago, I implemented this by peeking at the data in the texture itself. This doesn't work if the iris texture is animated since the texture will only on the GPU. To fix this, this PR changes the eye renderer to draw a square over the entire eye texture using iris texture's top corner, avoiding the need for getting the texture data on the CPU. I don't remember why I didn't do this in the first place, but this seems better in every way. Also `input_data` in TexturePool not being initialized, which was leading to hard-to-debug crashes when it was randomly initialized to a sometimes invalid but non-null pointer. Co-authored-by: water111 <awaterford1111445@gmail.com>
This commit is contained in:
@@ -256,16 +256,6 @@ std::vector<EyeRenderer::SingleEyeDraws> EyeRenderer::get_draws(DmaFollower& dma
|
||||
pair_idx = y0 / SINGLE_EYE_SIZE;
|
||||
l_draw.pair = pair_idx;
|
||||
r_draw.pair = pair_idx;
|
||||
if (tex0 && tex0->get_data_ptr()) {
|
||||
u32 tex_val;
|
||||
memcpy(&tex_val, tex0->get_data_ptr(), 4);
|
||||
l_draw.clear_color = tex_val;
|
||||
r_draw.clear_color = tex_val;
|
||||
} else {
|
||||
fmt::print("clear lookup failed\n");
|
||||
l_draw.clear_color = 0;
|
||||
r_draw.clear_color = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// up next is the pupil background
|
||||
@@ -462,6 +452,33 @@ int add_draw_to_buffer_64(int idx,
|
||||
return idx;
|
||||
}
|
||||
|
||||
int add_clear_draw_to_buffer(int idx, float* data) {
|
||||
// the entire eye texture is cleared using the 0,0 value from the iris texture
|
||||
const float center = 768;
|
||||
const float upper = center + 256;
|
||||
const float lower = center - 256;
|
||||
data[idx++] = lower;
|
||||
data[idx++] = lower;
|
||||
data[idx++] = 0;
|
||||
data[idx++] = 0;
|
||||
|
||||
data[idx++] = upper;
|
||||
data[idx++] = lower;
|
||||
data[idx++] = 0;
|
||||
data[idx++] = 0;
|
||||
|
||||
data[idx++] = lower;
|
||||
data[idx++] = upper;
|
||||
data[idx++] = 0;
|
||||
data[idx++] = 0;
|
||||
|
||||
data[idx++] = upper;
|
||||
data[idx++] = upper;
|
||||
data[idx++] = 0;
|
||||
data[idx++] = 0;
|
||||
return idx;
|
||||
}
|
||||
|
||||
void EyeRenderer::run_gpu(const std::vector<SingleEyeDraws>& draws,
|
||||
SharedRenderState* render_state) {
|
||||
if (draws.empty()) {
|
||||
@@ -474,6 +491,7 @@ void EyeRenderer::run_gpu(const std::vector<SingleEyeDraws>& draws,
|
||||
// the first thing we'll do is prepare the vertices
|
||||
int buffer_idx = 0;
|
||||
for (const auto& draw : draws) {
|
||||
buffer_idx = add_clear_draw_to_buffer(buffer_idx, m_gpu_vertex_buffer);
|
||||
if (draw.using_64) {
|
||||
buffer_idx =
|
||||
add_draw_to_buffer_64(buffer_idx, draw.iris, m_gpu_vertex_buffer, draw.pair, draw.lr);
|
||||
@@ -516,13 +534,18 @@ void EyeRenderer::run_gpu(const std::vector<SingleEyeDraws>& draws,
|
||||
out_tex.fnv_name_hash = draw.fnv_name_hash;
|
||||
out_tex.lr = draw.lr;
|
||||
|
||||
// first, the clear
|
||||
float clear[4] = {0, 0, 0, 0};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
clear[i] = ((draw.clear_color >> (8 * i)) & 0xff) / 255.f;
|
||||
}
|
||||
// clear: not really needed, but we do it to help debugging in case all the textures are missing
|
||||
float clear[4] = {1.0, 0, 0, 0};
|
||||
glClearBufferfv(GL_COLOR, 0, clear);
|
||||
|
||||
// background
|
||||
if (draw.iris_tex) {
|
||||
glDisable(GL_BLEND);
|
||||
glBindTexture(GL_TEXTURE_2D, draw.iris_gl_tex);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, buffer_idx / 4, 4);
|
||||
}
|
||||
buffer_idx += 4 * 4;
|
||||
|
||||
// iris
|
||||
if (draw.iris_tex) {
|
||||
// set alpha
|
||||
|
||||
@@ -61,8 +61,8 @@ class EyeRenderer : public BucketRenderer {
|
||||
GpuEyeTex() : fb(128, 128, GL_UNSIGNED_INT_8_8_8_8_REV) {}
|
||||
} m_gpu_eye_textures[NUM_EYE_PAIRS * 2];
|
||||
|
||||
// xyst per vertex, 4 vertices per square, 3 draws per eye, 11 pairs of eyes, 2 eyes per pair.
|
||||
static constexpr int VTX_BUFFER_FLOATS = 4 * 4 * 3 * NUM_EYE_PAIRS * 2;
|
||||
// xyst per vertex, 4 vertices per square, 4 draws per eye, 11 pairs of eyes, 2 eyes per pair.
|
||||
static constexpr int VTX_BUFFER_FLOATS = 4 * 4 * 4 * NUM_EYE_PAIRS * 2;
|
||||
float m_gpu_vertex_buffer[VTX_BUFFER_FLOATS];
|
||||
GLuint m_vao;
|
||||
GLuint m_gl_vertex_buffer;
|
||||
@@ -74,7 +74,6 @@ class EyeRenderer : public BucketRenderer {
|
||||
bool using_64 = false;
|
||||
|
||||
int tex_slot() const { return pair * 2 + lr; }
|
||||
u32 clear_color;
|
||||
EyeDraw iris;
|
||||
GpuTexture* iris_tex = nullptr;
|
||||
u64 iris_gl_tex = 0;
|
||||
|
||||
@@ -202,7 +202,7 @@ struct TextureInput {
|
||||
|
||||
GLuint gpu_texture = -1;
|
||||
bool common = false;
|
||||
const u8* src_data;
|
||||
const u8* src_data = nullptr;
|
||||
u16 w, h;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user