diff --git a/common/texture/texture_slots.cpp b/common/texture/texture_slots.cpp index 3ec965c84e..ead2ab0e83 100644 --- a/common/texture/texture_slots.cpp +++ b/common/texture/texture_slots.cpp @@ -38,6 +38,8 @@ std::vector jak2_slots = { "fort-roboscreen-dest", "squid-env-rim-dest", "krew-holo-dest", + "cas-toxic-slime-dest", + "cas-toxic-slime-scroll-dest", }; } diff --git a/decompiler/config/jak2/ntsc_v1/inputs.jsonc b/decompiler/config/jak2/ntsc_v1/inputs.jsonc index 1794efad79..71737ee82b 100644 --- a/decompiler/config/jak2/ntsc_v1/inputs.jsonc +++ b/decompiler/config/jak2/ntsc_v1/inputs.jsonc @@ -563,7 +563,11 @@ // krew "krew-holo-dest", - "metkor-phong-env" + "metkor-phong-env", + + // castle slime + "cas-toxic-slime-scroll-dest", + "cas-toxic-slime-dest" // "kor-eyeeffect-formorph", // "kor-eyeeffect-formorph-start", diff --git a/game/graphics/opengl_renderer/TextureAnimator.cpp b/game/graphics/opengl_renderer/TextureAnimator.cpp index 2df3e77fcc..4160d635d9 100644 --- a/game/graphics/opengl_renderer/TextureAnimator.cpp +++ b/game/graphics/opengl_renderer/TextureAnimator.cpp @@ -357,7 +357,16 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* co m_psm32_to_psm8_32_32(32, 32, 16, 64), m_psm32_to_psm8_64_64(64, 64, 64, 64), m_sky_blend_texture(kFinalSkyTextureSize, kFinalSkyTextureSize, GL_UNSIGNED_INT_8_8_8_8_REV), - m_sky_final_texture(kFinalSkyTextureSize, kFinalSkyTextureSize, GL_UNSIGNED_INT_8_8_8_8_REV) { + m_sky_final_texture(kFinalSkyTextureSize, kFinalSkyTextureSize, GL_UNSIGNED_INT_8_8_8_8_REV), + m_slime_blend_texture(kFinalSlimeTextureSize, + kFinalSlimeTextureSize, + GL_UNSIGNED_INT_8_8_8_8_REV), + m_slime_final_texture(kFinalSlimeTextureSize, + kFinalSlimeTextureSize, + GL_UNSIGNED_INT_8_8_8_8_REV), + m_slime_final_scroll_texture(kFinalSlimeTextureSize, + kFinalSlimeTextureSize, + GL_UNSIGNED_INT_8_8_8_8_REV) { glGenVertexArrays(1, &m_vao); glGenBuffers(1, &m_vertex_buffer); glBindVertexArray(m_vao); @@ -393,6 +402,7 @@ TextureAnimator::TextureAnimator(ShaderLibrary& shaders, const tfrag3::Level* co m_uniforms.alpha_multiply = glGetUniformLocation(shader.id(), "alpha_multiply"); m_uniforms.minimum = glGetUniformLocation(shader.id(), "minimum"); m_uniforms.maximum = glGetUniformLocation(shader.id(), "maximum"); + m_uniforms.slime_scroll = glGetUniformLocation(shader.id(), "slime_scroll"); // create a single "dummy texture" with all 0 data. // this is faster and easier than switching shaders to one without texturing, and is used @@ -481,9 +491,25 @@ int TextureAnimator::create_fixed_anim_array(const std::vector& de return ret; } +void imgui_show_tex(GLuint tex) { + glBindTexture(GL_TEXTURE_2D, tex); + int w, h; + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); + glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); + ImGui::Image((void*)(u64)tex, ImVec2(w, h)); +} + void TextureAnimator::draw_debug_window() { ImGui::Checkbox("fast-scrambler", &m_debug.use_fast_scrambler); + ImGui::Text("Slime:"); + ImGui::Text("dests %d %d", m_debug_slime_input.dest, m_debug_slime_input.scroll_dest); + for (int i = 0; i < 9; i++) { + ImGui::Text("Time[%d]: %f", i, m_debug_slime_input.times[i]); + } + imgui_show_tex(m_slime_final_texture.texture()); + imgui_show_tex(m_slime_final_scroll_texture.texture()); + ImGui::Text("Sky:"); ImGui::Text("Fog Height: %f", m_debug_sky_input.fog_height); ImGui::Text("Cloud minmax: %f %f", m_debug_sky_input.cloud_min, m_debug_sky_input.cloud_max); @@ -492,25 +518,13 @@ void TextureAnimator::draw_debug_window() { } ImGui::Text("Dest %d", m_debug_sky_input.cloud_dest); - glBindTexture(GL_TEXTURE_2D, m_sky_blend_texture.texture()); - int w, h; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - ImGui::Image((void*)(u64)m_sky_blend_texture.texture(), ImVec2(w, h)); - - glBindTexture(GL_TEXTURE_2D, m_sky_final_texture.texture()); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - ImGui::Image((void*)(u64)m_sky_final_texture.texture(), ImVec2(w, h)); + imgui_show_tex(m_sky_blend_texture.texture()); + imgui_show_tex(m_sky_final_texture.texture()); auto& slots = jak2_animated_texture_slots(); for (size_t i = 0; i < slots.size(); i++) { ImGui::Text("Slot %d %s (%d)", (int)i, slots[i].c_str(), (int)m_private_output_slots[i]); - glBindTexture(GL_TEXTURE_2D, m_private_output_slots[i]); - int w, h; - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &w); - glGetTexLevelParameteriv(GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &h); - ImGui::Image((void*)(u64)m_private_output_slots[i], ImVec2(w, h)); + imgui_show_tex(m_private_output_slots[i]); ImGui::Checkbox(fmt::format("mark {}", i).c_str(), &m_output_debug_flags.at(i).b); } glBindTexture(GL_TEXTURE_2D, 0); @@ -597,6 +611,7 @@ enum PcTextureAnimCodes { SHIELD = 39, KREW_HOLO = 40, CLOUDS_AND_FOG = 41, + SLIME = 42, }; // metadata for an upload from GOAL memory @@ -756,6 +771,10 @@ void TextureAnimator::handle_texture_anim_data(DmaFollower& dma, auto p = scoped_prof("clouds-and-fog"); handle_clouds_and_fog(tf, texture_pool); } break; + case SLIME: { + auto p = scoped_prof("slime"); + handle_slime(tf, texture_pool); + } break; default: fmt::print("bad imm: {}\n", vif0.immediate); ASSERT_NOT_REACHED(); @@ -971,7 +990,7 @@ void TextureAnimator::handle_clouds_and_fog(const DmaTransfer& tf, TexturePool* if (m_sky_pool_gpu_tex) { texture_pool->move_existing_to_vram(m_sky_pool_gpu_tex, input.cloud_dest); - ASSERT(texture_pool->lookup(input.cloud_dest).value() == tex); + ASSERT((int)texture_pool->lookup(input.cloud_dest).value() == tex); } else { TextureInput in; in.gpu_texture = tex; @@ -984,6 +1003,51 @@ void TextureAnimator::handle_clouds_and_fog(const DmaTransfer& tf, TexturePool* } } +void TextureAnimator::handle_slime(const DmaTransfer& tf, TexturePool* texture_pool) { + ASSERT(tf.size_bytes >= sizeof(SlimeInput)); + SlimeInput input; + memcpy(&input, tf.data, sizeof(SlimeInput)); + + run_slime(input); + + { + auto no_scroll_tex = m_slime_final_texture.texture(); + if (m_slime_pool_gpu_tex) { + texture_pool->move_existing_to_vram(m_slime_pool_gpu_tex, input.dest); + ASSERT(texture_pool->lookup(input.dest).value() == no_scroll_tex); + } else { + TextureInput in; + in.gpu_texture = no_scroll_tex; + in.w = kFinalSkyTextureSize; + in.h = kFinalSkyTextureSize; + in.debug_page_name = "PC-ANIM"; + in.debug_name = "slime"; + in.id = get_id_for_tbp(texture_pool, input.dest, 778); + m_slime_pool_gpu_tex = texture_pool->give_texture_and_load_to_vram(in, input.dest); + } + m_private_output_slots.at(m_slime_output_slot) = no_scroll_tex; + } + + { + auto tex = m_slime_final_scroll_texture.texture(); + if (m_slime_scroll_pool_gpu_tex) { + texture_pool->move_existing_to_vram(m_slime_scroll_pool_gpu_tex, input.scroll_dest); + ASSERT(texture_pool->lookup(input.scroll_dest).value() == tex); + } else { + TextureInput in; + in.gpu_texture = tex; + in.w = kFinalSkyTextureSize; + in.h = kFinalSkyTextureSize; + in.debug_page_name = "PC-ANIM"; + in.debug_name = "slime-scroll"; + in.id = get_id_for_tbp(texture_pool, input.dest, 779); + m_slime_scroll_pool_gpu_tex = + texture_pool->give_texture_and_load_to_vram(in, input.scroll_dest); + } + m_private_output_slots.at(m_slime_scroll_output_slot) = tex; + } +} + void TextureAnimator::clear_stale_textures(u64 frame_idx) { for (auto& group : m_clut_blender_groups) { if (frame_idx > group.last_updated_frame) { @@ -2485,23 +2549,45 @@ void TextureAnimator::setup_sky() { m_random_table[i] = kInitialRandomTable[i]; } - const float max_times[4] = {4800.f, 2400.f, 1200.f, 600.f}; - const float scales[4] = {0.5, 0.2, 0.15, 0.0075f}; - for (int i = 0, dim = kFinalSkyTextureSize >> (kNumSkyNoiseLayers - 1); i < kNumSkyNoiseLayers; - i++, dim *= 2) { - auto& tex = m_sky_noise_textures[i]; - tex.temp_data.resize(dim * dim); - tex.max_time = max_times[i]; - tex.scale = scales[i]; - tex.dim = dim; - glGenTextures(1, &tex.new_tex); - m_random_index = update_opengl_noise_texture(tex.new_tex, tex.temp_data.data(), m_random_table, - dim, m_random_index); - glGenTextures(1, &tex.old_tex); - m_random_index = update_opengl_noise_texture(tex.old_tex, tex.temp_data.data(), m_random_table, - dim, m_random_index); - // debug_save_opengl_u8_texture(fmt::format("{}_old.png", dim), tex.old_tex); - // debug_save_opengl_u8_texture(fmt::format("{}_new.png", dim), tex.new_tex); + { + const float max_times[4] = {4800.f, 2400.f, 1200.f, 600.f}; + const float scales[4] = {0.5, 0.2, 0.15, 0.0075f}; + for (int i = 0, dim = kFinalSkyTextureSize >> (kNumSkyNoiseLayers - 1); i < kNumSkyNoiseLayers; + i++, dim *= 2) { + auto& tex = m_sky_noise_textures[i]; + tex.temp_data.resize(dim * dim); + tex.max_time = max_times[i]; + tex.scale = scales[i]; + tex.dim = dim; + glGenTextures(1, &tex.new_tex); + m_random_index = update_opengl_noise_texture(tex.new_tex, tex.temp_data.data(), + m_random_table, dim, m_random_index); + glGenTextures(1, &tex.old_tex); + m_random_index = update_opengl_noise_texture(tex.old_tex, tex.temp_data.data(), + m_random_table, dim, m_random_index); + } + } + + { + m_slime_output_slot = output_slot_by_idx(GameVersion::Jak2, "cas-toxic-slime-dest"); + m_slime_scroll_output_slot = + output_slot_by_idx(GameVersion::Jak2, "cas-toxic-slime-scroll-dest"); + const float max_times[4] = {600.f, 300.f, 150.f, 75.f}; + const float scales[4] = {0.55, 0.6, 0.3, 0.1f}; + for (int i = 0, dim = kFinalSlimeTextureSize >> (kNumSlimeNoiseLayers - 1); + i < kNumSlimeNoiseLayers; i++, dim *= 2) { + auto& tex = m_slime_noise_textures[i]; + tex.temp_data.resize(dim * dim); + tex.max_time = max_times[i]; + tex.scale = scales[i]; + tex.dim = dim; + glGenTextures(1, &tex.new_tex); + m_random_index = update_opengl_noise_texture(tex.new_tex, tex.temp_data.data(), + m_random_table, dim, m_random_index); + glGenTextures(1, &tex.old_tex); + m_random_index = update_opengl_noise_texture(tex.old_tex, tex.temp_data.data(), + m_random_table, dim, m_random_index); + } } } @@ -2591,6 +2677,101 @@ GLint TextureAnimator::run_clouds(const SkyInput& input) { glUniform1f(m_uniforms.maximum, input.cloud_max); glDisable(GL_BLEND); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - + glBindTexture(GL_TEXTURE_2D, m_sky_final_texture.texture()); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); return m_sky_final_texture.texture(); +} + +void TextureAnimator::run_slime(const SlimeInput& input) { + m_debug_slime_input = input; + + int times_idx = 0; + times_idx++; + { + FramebufferTexturePairContext ctxt(m_slime_blend_texture); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glUniform1i(m_uniforms.tcc, 1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glColorMask(true, true, true, true); + glDisable(GL_DEPTH_TEST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glEnable(GL_BLEND); + glBlendEquation(GL_FUNC_ADD); + glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ZERO, GL_ZERO); + glUniform4i(m_uniforms.channel_scramble, 0, 0, 0, 0); + glUniform1f(m_uniforms.alpha_multiply, 1.f); + glUniform1i(m_uniforms.enable_tex, 1); + float positions[3 * 4] = {0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0}; + glUniform3fv(m_uniforms.positions, 4, positions); + float uv[2 * 4] = {0, 0, 1, 0, 1, 1, 0, 1}; + glUniform2fv(m_uniforms.uvs, 4, uv); + + // Anim 1: + // noise (16x16) + // while (noise_layer_idx) { + for (int noise_layer_idx = 0; noise_layer_idx < kNumSlimeNoiseLayers; noise_layer_idx++) { + const float new_time = input.times[times_idx]; + auto& ntp = m_slime_noise_textures[noise_layer_idx]; + + if (new_time < ntp.last_time) { + std::swap(ntp.new_tex, ntp.old_tex); + m_random_index = update_opengl_noise_texture(ntp.new_tex, ntp.temp_data.data(), + m_random_table, ntp.dim, m_random_index); + } + ntp.last_time = new_time; + float new_interp = ntp.last_time / ntp.max_time; + + glBindTexture(GL_TEXTURE_2D, ntp.new_tex); + float s = new_interp * ntp.scale * 128.f; + set_uniform(m_uniforms.rgba, math::Vector4f(s, s, s, 256)); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + glBindTexture(GL_TEXTURE_2D, ntp.old_tex); + s = (1.f - new_interp) * ntp.scale * 128.f; + set_uniform(m_uniforms.rgba, math::Vector4f(s, s, s, 256)); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + times_idx++; + } + } + + { + FramebufferTexturePairContext ctxt(m_slime_final_texture); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glUniform1i(m_uniforms.enable_tex, 3); + glUniform1f(m_uniforms.slime_scroll, 0); + glBindTexture(GL_TEXTURE_2D, m_slime_blend_texture.texture()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glDisable(GL_BLEND); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + glBindTexture(GL_TEXTURE_2D, m_slime_final_texture.texture()); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); + + { + FramebufferTexturePairContext ctxt(m_slime_final_scroll_texture); + glClearColor(0.0, 0.0, 0.0, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glUniform1i(m_uniforms.enable_tex, 3); + float scroll = input.times[8] / 1200.f; + glUniform1f(m_uniforms.slime_scroll, scroll); + glBindTexture(GL_TEXTURE_2D, m_slime_blend_texture.texture()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glDisable(GL_BLEND); + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + } + glBindTexture(GL_TEXTURE_2D, m_slime_final_scroll_texture.texture()); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, 0); } \ No newline at end of file diff --git a/game/graphics/opengl_renderer/TextureAnimator.h b/game/graphics/opengl_renderer/TextureAnimator.h index a88469c97b..0ec472c6b7 100644 --- a/game/graphics/opengl_renderer/TextureAnimator.h +++ b/game/graphics/opengl_renderer/TextureAnimator.h @@ -221,6 +221,13 @@ struct SkyInput { int32_t cloud_dest; }; +struct SlimeInput { + // float alphas[4]; + float times[9]; + int32_t dest; + int32_t scroll_dest; +}; + using Vector16ub = math::Vector; struct NoiseTexturePair { @@ -255,6 +262,7 @@ class TextureAnimator { void handle_upload_clut_16_16(const DmaTransfer& tf, const u8* ee_mem); void handle_generic_upload(const DmaTransfer& tf, const u8* ee_mem); void handle_clouds_and_fog(const DmaTransfer& tf, TexturePool* texture_pool); + void handle_slime(const DmaTransfer& tf, TexturePool* texture_pool); void handle_erase_dest(DmaFollower& dma); void handle_set_shader(DmaFollower& dma); void handle_draw(DmaFollower& dma, TexturePool& texture_pool); @@ -325,6 +333,7 @@ class TextureAnimator { GLuint positions; GLuint uvs; GLuint enable_tex; + GLuint slime_scroll; GLuint channel_scramble; GLuint tcc; GLuint alpha_multiply; @@ -375,6 +384,7 @@ class TextureAnimator { const std::optional& dgo); void run_clut_blender_group(DmaTransfer& tf, int idx, u64 frame_idx); GLint run_clouds(const SkyInput& input); + void run_slime(const SlimeInput& input); Psm32ToPsm8Scrambler m_psm32_to_psm8_8_8, m_psm32_to_psm8_16_16, m_psm32_to_psm8_32_32, m_psm32_to_psm8_64_64; @@ -398,21 +408,37 @@ class TextureAnimator { std::vector m_fixed_anim_arrays; public: - // must be power of 2 - number of 16-byte rows in random table. (original game has 8) + // note: for now these can't be easily changed because each layer has its own hand-tuned + // parameters from the original game. If you want to change it, you'll need to make up parameters + // for those new layers. + // must be power of 2 - number of 16-byte rows in random table. (original + // game has 8) static constexpr int kRandomTableSize = 8; // must be power of 2 - dimensions of the final clouds textures static constexpr int kFinalSkyTextureSize = 128; + static constexpr int kFinalSlimeTextureSize = 128; // number of small sub-textures. Must be less than log2(kFinalTextureSize). static constexpr int kNumSkyNoiseLayers = 4; + static constexpr int kNumSlimeNoiseLayers = 4; private: - SkyInput m_debug_sky_input; Vector16ub m_random_table[kRandomTableSize]; int m_random_index = 0; + + SkyInput m_debug_sky_input; NoiseTexturePair m_sky_noise_textures[kNumSkyNoiseLayers]; FramebufferTexturePair m_sky_blend_texture; FramebufferTexturePair m_sky_final_texture; GpuTexture* m_sky_pool_gpu_tex = nullptr; + + SlimeInput m_debug_slime_input; + NoiseTexturePair m_slime_noise_textures[kNumSkyNoiseLayers]; + FramebufferTexturePair m_slime_blend_texture; + FramebufferTexturePair m_slime_final_texture, m_slime_final_scroll_texture; + GpuTexture* m_slime_pool_gpu_tex = nullptr; + GpuTexture* m_slime_scroll_pool_gpu_tex = nullptr; + int m_slime_output_slot = -1; + int m_slime_scroll_output_slot = -1; }; diff --git a/game/graphics/opengl_renderer/shaders/tex_anim.frag b/game/graphics/opengl_renderer/shaders/tex_anim.frag index 1b9047dc28..665945221d 100644 --- a/game/graphics/opengl_renderer/shaders/tex_anim.frag +++ b/game/graphics/opengl_renderer/shaders/tex_anim.frag @@ -9,6 +9,7 @@ uniform ivec4 channel_scramble; uniform float alpha_multiply; uniform float minimum; uniform float maximum; +uniform float slime_scroll; in vec2 uv; @@ -28,6 +29,265 @@ float cloud_lookup(float v, float minimum, float maximum) { return sin_alpha * sin_alpha; } +vec4 slime_lut[256] = vec4[]( + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3254, 0.3333, 0.0745, 0.5019), + vec4(0.3333, 0.3450, 0.0745, 0.5019), + vec4(0.3411, 0.3607, 0.0745, 0.5019), + vec4(0.3490, 0.3725, 0.0745, 0.5019), + vec4(0.3568, 0.3882, 0.0745, 0.5019), + vec4(0.3607, 0.4000, 0.0745, 0.5019), + vec4(0.3686, 0.4117, 0.0745, 0.5019), + vec4(0.3764, 0.4274, 0.0745, 0.5019), + vec4(0.3764, 0.4274, 0.0784, 0.5019), + vec4(0.3686, 0.4117, 0.0745, 0.5019), + vec4(0.3607, 0.4000, 0.0745, 0.5019), + vec4(0.3529, 0.3843, 0.0745, 0.5019), + vec4(0.3490, 0.3725, 0.0745, 0.5019), + vec4(0.3411, 0.3607, 0.0745, 0.5019), + vec4(0.3333, 0.3450, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3215, 0.0745, 0.5019), + vec4(0.3215, 0.3254, 0.0705, 0.5019), + vec4(0.3254, 0.3294, 0.0705, 0.5019), + vec4(0.3294, 0.3333, 0.0705, 0.5019), + vec4(0.3333, 0.3372, 0.0705, 0.5019), + vec4(0.3333, 0.3450, 0.0705, 0.5019), + vec4(0.3372, 0.3490, 0.0705, 0.5019), + vec4(0.3411, 0.3529, 0.0705, 0.5019), + vec4(0.3450, 0.3568, 0.0705, 0.5019), + vec4(0.3450, 0.3607, 0.0705, 0.5019), + vec4(0.3490, 0.3686, 0.0705, 0.5019), + vec4(0.3529, 0.3725, 0.0705, 0.5019), + vec4(0.3568, 0.3764, 0.0705, 0.5019), + vec4(0.3607, 0.3803, 0.0705, 0.5019), + vec4(0.3607, 0.3843, 0.0705, 0.5019), + vec4(0.3647, 0.3921, 0.0705, 0.5019), + vec4(0.3686, 0.3960, 0.0705, 0.5019), + vec4(0.3725, 0.4000, 0.0705, 0.5019), + vec4(0.3725, 0.4039, 0.0705, 0.5019), + vec4(0.3764, 0.4078, 0.0705, 0.5019), + vec4(0.3803, 0.4156, 0.0705, 0.5019), + vec4(0.3843, 0.4196, 0.0705, 0.5019), + vec4(0.3882, 0.4235, 0.0705, 0.5019), + vec4(0.3882, 0.4274, 0.0705, 0.5019), + vec4(0.3921, 0.4313, 0.0705, 0.5019), + vec4(0.3960, 0.4392, 0.0705, 0.5019), + vec4(0.4000, 0.4431, 0.0705, 0.5019), + vec4(0.4000, 0.4470, 0.0705, 0.5019), + vec4(0.4039, 0.4509, 0.0705, 0.5019), + vec4(0.4078, 0.4549, 0.0705, 0.5019), + vec4(0.4117, 0.4627, 0.0705, 0.5019), + vec4(0.4117, 0.4666, 0.0705, 0.5019), + vec4(0.4235, 0.4862, 0.0705, 0.5019), + vec4(0.4509, 0.5254, 0.0705, 0.5019), + vec4(0.4784, 0.5686, 0.0705, 0.5019), + vec4(0.5058, 0.6117, 0.0666, 0.5019), + vec4(0.5333, 0.6509, 0.0666, 0.5019), + vec4(0.5607, 0.6941, 0.0666, 0.5019), + vec4(0.5882, 0.7372, 0.0666, 0.5019), + vec4(0.6196, 0.7803, 0.0666, 0.5019), + vec4(0.6196, 0.7803, 0.0666, 0.5019), + vec4(0.6000, 0.7529, 0.0666, 0.5019), + vec4(0.5803, 0.7254, 0.0666, 0.5019), + vec4(0.5647, 0.6980, 0.0666, 0.5019), + vec4(0.5450, 0.6705, 0.0666, 0.5019), + vec4(0.5294, 0.6431, 0.0666, 0.5019), + vec4(0.5098, 0.6156, 0.0705, 0.5019), + vec4(0.4745, 0.5607, 0.0705, 0.5019), + vec4(0.4666, 0.5450, 0.0705, 0.5019), + vec4(0.4666, 0.5529, 0.0705, 0.5019), + vec4(0.4705, 0.5568, 0.0705, 0.5019), + vec4(0.4745, 0.5607, 0.0705, 0.5019), + vec4(0.4784, 0.5647, 0.0705, 0.5019), + vec4(0.4784, 0.5686, 0.0705, 0.5019), + vec4(0.4823, 0.5764, 0.0705, 0.5019), + vec4(0.4862, 0.5803, 0.0705, 0.5019), + vec4(0.4901, 0.5843, 0.0705, 0.5019), + vec4(0.4941, 0.5882, 0.0705, 0.5019), + vec4(0.4941, 0.5921, 0.0705, 0.5019), + vec4(0.4980, 0.6000, 0.0705, 0.5019), + vec4(0.5019, 0.6039, 0.0705, 0.5019), + vec4(0.5058, 0.6078, 0.0705, 0.5019), + vec4(0.5058, 0.6117, 0.0705, 0.5019), + vec4(0.5098, 0.6156, 0.0705, 0.5019), + vec4(0.5137, 0.6235, 0.0705, 0.5019), + vec4(0.5176, 0.6274, 0.0705, 0.5019), + vec4(0.5215, 0.6313, 0.0705, 0.5019), + vec4(0.5215, 0.6352, 0.0705, 0.5019), + vec4(0.5254, 0.6392, 0.0705, 0.5019), + vec4(0.5294, 0.6470, 0.0705, 0.5019), + vec4(0.5333, 0.6509, 0.0705, 0.5019), + vec4(0.5333, 0.6549, 0.0705, 0.5019), + vec4(0.5372, 0.6588, 0.0705, 0.5019), + vec4(0.5411, 0.6627, 0.0705, 0.5019), + vec4(0.5450, 0.6705, 0.0705, 0.5019), + vec4(0.5450, 0.6745, 0.0705, 0.5019), + vec4(0.5490, 0.6784, 0.0705, 0.5019), + vec4(0.5529, 0.6823, 0.0705, 0.5019), + vec4(0.5568, 0.6862, 0.0705, 0.5019), + vec4(0.5607, 0.6941, 0.0705, 0.5019), + vec4(0.5607, 0.6980, 0.0705, 0.5019), + vec4(0.5725, 0.7098, 0.0666, 0.5019), + vec4(0.5803, 0.7254, 0.0666, 0.5019), + vec4(0.5882, 0.7372, 0.0666, 0.5019), + vec4(0.6000, 0.7490, 0.0666, 0.5019), + vec4(0.6078, 0.7647, 0.0666, 0.5019), + vec4(0.6156, 0.7764, 0.0666, 0.5019), + vec4(0.6274, 0.7921, 0.0666, 0.5019), + vec4(0.6274, 0.7921, 0.0666, 0.5019), + vec4(0.6196, 0.7803, 0.0666, 0.5019), + vec4(0.6117, 0.7686, 0.0666, 0.5019), + vec4(0.6039, 0.7607, 0.0666, 0.5019), + vec4(0.5960, 0.7490, 0.0666, 0.5019), + vec4(0.5882, 0.7411, 0.0705, 0.5019), + vec4(0.5803, 0.7294, 0.0705, 0.5019), + vec4(0.5647, 0.7098, 0.0705, 0.5019), + vec4(0.5647, 0.7098, 0.0705, 0.5019), + vec4(0.5607, 0.7058, 0.0705, 0.5019), + vec4(0.5568, 0.7019, 0.0705, 0.5019), + vec4(0.5529, 0.6980, 0.0705, 0.5019), + vec4(0.5529, 0.6941, 0.0705, 0.5019), + vec4(0.5490, 0.6901, 0.0745, 0.5019), + vec4(0.5450, 0.6862, 0.0745, 0.5019), + vec4(0.5411, 0.6823, 0.0745, 0.5019), + vec4(0.5411, 0.6823, 0.0745, 0.5019), + vec4(0.5372, 0.6784, 0.0745, 0.5019), + vec4(0.5333, 0.6745, 0.0745, 0.5019), + vec4(0.5294, 0.6705, 0.0745, 0.5019), + vec4(0.5294, 0.6666, 0.0745, 0.5019), + vec4(0.5254, 0.6627, 0.0745, 0.5019), + vec4(0.5215, 0.6588, 0.0745, 0.5019), + vec4(0.5176, 0.6549, 0.0745, 0.5019), + vec4(0.5176, 0.6549, 0.0745, 0.5019), + vec4(0.5137, 0.6509, 0.0745, 0.5019), + vec4(0.5098, 0.6470, 0.0784, 0.5019), + vec4(0.5058, 0.6431, 0.0784, 0.5019), + vec4(0.5058, 0.6392, 0.0784, 0.5019), + vec4(0.5019, 0.6352, 0.0784, 0.5019), + vec4(0.4980, 0.6313, 0.0784, 0.5019), + vec4(0.4941, 0.6274, 0.0784, 0.5019), + vec4(0.4941, 0.6274, 0.0784, 0.5019), + vec4(0.4901, 0.6235, 0.0784, 0.5019), + vec4(0.4862, 0.6196, 0.0784, 0.5019), + vec4(0.4823, 0.6156, 0.0784, 0.5019), + vec4(0.4823, 0.6117, 0.0784, 0.5019), + vec4(0.4784, 0.6078, 0.0784, 0.5019), + vec4(0.4745, 0.6039, 0.0784, 0.5019), + vec4(0.4745, 0.6039, 0.0823, 0.5019), + vec4(0.4745, 0.6039, 0.0823, 0.5019), + vec4(0.4862, 0.6156, 0.0784, 0.5019), + vec4(0.4980, 0.6313, 0.0784, 0.5019), + vec4(0.5098, 0.6470, 0.0784, 0.5019), + vec4(0.5215, 0.6588, 0.0745, 0.5019), + vec4(0.5333, 0.6745, 0.0745, 0.5019), + vec4(0.5450, 0.6901, 0.0745, 0.5019), + vec4(0.5568, 0.7019, 0.0705, 0.5019), + vec4(0.5686, 0.7176, 0.0705, 0.5019), + vec4(0.5803, 0.7333, 0.0705, 0.5019), + vec4(0.5921, 0.7490, 0.0705, 0.5019), + vec4(0.6039, 0.7607, 0.0666, 0.5019), + vec4(0.6156, 0.7764, 0.0666, 0.5019), + vec4(0.6274, 0.7921, 0.0666, 0.5019), + vec4(0.6392, 0.8039, 0.0627, 0.5019), + vec4(0.6509, 0.8196, 0.0627, 0.5019), + vec4(0.6745, 0.8509, 0.0627, 0.5019), + vec4(0.6705, 0.8470, 0.0627, 0.5019), + vec4(0.6666, 0.8431, 0.0627, 0.5019), + vec4(0.6627, 0.8392, 0.0627, 0.5019), + vec4(0.6588, 0.8352, 0.0627, 0.5019), + vec4(0.6588, 0.8313, 0.0627, 0.5019), + vec4(0.6549, 0.8274, 0.0627, 0.5019), + vec4(0.6509, 0.8235, 0.0627, 0.5019), + vec4(0.6470, 0.8196, 0.0627, 0.5019), + vec4(0.6431, 0.8156, 0.0627, 0.5019), + vec4(0.6431, 0.8117, 0.0627, 0.5019), + vec4(0.6392, 0.8078, 0.0627, 0.5019), + vec4(0.6352, 0.8039, 0.0666, 0.5019), + vec4(0.6313, 0.8000, 0.0666, 0.5019), + vec4(0.6274, 0.7960, 0.0666, 0.5019), + vec4(0.6274, 0.7921, 0.0666, 0.5019), + vec4(0.6235, 0.7882, 0.0666, 0.5019), + vec4(0.6196, 0.7843, 0.0666, 0.5019), + vec4(0.6156, 0.7803, 0.0666, 0.5019), + vec4(0.6156, 0.7764, 0.0666, 0.5019), + vec4(0.6117, 0.7725, 0.0666, 0.5019), + vec4(0.6078, 0.7686, 0.0666, 0.5019), + vec4(0.6039, 0.7647, 0.0666, 0.5019), + vec4(0.6000, 0.7607, 0.0666, 0.5019), + vec4(0.6000, 0.7568, 0.0666, 0.5019), + vec4(0.5960, 0.7529, 0.0705, 0.5019), + vec4(0.5921, 0.7490, 0.0705, 0.5019), + vec4(0.5882, 0.7450, 0.0705, 0.5019), + vec4(0.5843, 0.7411, 0.0705, 0.5019), + vec4(0.5843, 0.7372, 0.0705, 0.5019), + vec4(0.5803, 0.7333, 0.0705, 0.5019), + vec4(0.5764, 0.7294, 0.0705, 0.5019), + vec4(0.5725, 0.7254, 0.0705, 0.5019), + vec4(0.5686, 0.7215, 0.0705, 0.5019), + vec4(0.5686, 0.7176, 0.0705, 0.5019), + vec4(0.5647, 0.7137, 0.0705, 0.5019), + vec4(0.5607, 0.7098, 0.0705, 0.5019), + vec4(0.5568, 0.7058, 0.0705, 0.5019), + vec4(0.5568, 0.7019, 0.0745, 0.5019), + vec4(0.5490, 0.6941, 0.0745, 0.5019), + vec4(0.5490, 0.6941, 0.0745, 0.5019), + vec4(0.5647, 0.7137, 0.0705, 0.5019), + vec4(0.5803, 0.7294, 0.0705, 0.5019), + vec4(0.5921, 0.7490, 0.0705, 0.5019), + vec4(0.6078, 0.7647, 0.0666, 0.5019), + vec4(0.6196, 0.7843, 0.0666, 0.5019), + vec4(0.6352, 0.8000, 0.0666, 0.5019), + vec4(0.6509, 0.8196, 0.0666, 0.5019), + vec4(0.6509, 0.8196, 0.0666, 0.5019), + vec4(0.6392, 0.8039, 0.0666, 0.5019), + vec4(0.6274, 0.7921, 0.0666, 0.5019), + vec4(0.6156, 0.7764, 0.0666, 0.5019), + vec4(0.6078, 0.7647, 0.0705, 0.5019), + vec4(0.5960, 0.7490, 0.0705, 0.5019), + vec4(0.5843, 0.7372, 0.0705, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019), + vec4(0.5647, 0.7098, 0.0745, 0.5019) +); + void main() { if (enable_tex == 1) { vec4 tex_color = texture(tex_T0, uv); @@ -48,6 +308,10 @@ void main() { color.y = 0.5; color.z = 0.5; color.a = 0.5 * cloud_lookup(tex_color.r, minimum, maximum); + } else if (enable_tex == 3) { + // cloud version + vec4 tex_color = texture(tex_T0, uv + vec2(0, slime_scroll)); + color = slime_lut[int(tex_color.r * 255.f)]; } else { color = (rgba / 128.); } diff --git a/goal_src/jak2/engine/gfx/texture/texture-anim.gc b/goal_src/jak2/engine/gfx/texture/texture-anim.gc index a076431e96..3ae175df5b 100644 --- a/goal_src/jak2/engine/gfx/texture/texture-anim.gc +++ b/goal_src/jak2/engine/gfx/texture/texture-anim.gc @@ -197,6 +197,7 @@ (shield 39) (krew-holo 40) (clouds-and-fog 41) + (slime 42) ) (deftype texture-anim-pc-upload (structure) @@ -712,15 +713,56 @@ ) ) +#| +struct SlimeInput { + float alphas[4]; + float times[9]; + int32_t dest; + int32_t scroll_dest; +}; +|# + +(deftype slime-input (structure) + (;(alphas float 4) + (times float 9) + (dest int32) + (scroll-dest int32) + ) + ) + +(defun make-slime-input ((si slime-input)) + (dotimes (i 9) + (set! (-> si times i) + (-> *toxic-slime-texture-anim-array* array-data i frame-time) + ) + ) + (set! (-> si dest) + (the int (-> *toxic-slime-texture-anim-array* array-data 6 tex dest 0))) + (set! (-> si scroll-dest) + (the int (-> *toxic-slime-texture-anim-array* array-data 8 tex dest 0))) + ) + + (defun update-texture-anim ((bucket bucket-id) (anim-array texture-anim-array)) "Generate all DMA to update all textures in the given list for the given bucket." (let ((anim-idx 0)) - (cond - ((= anim-array *toxic-slime-texture-anim-array*) - ;; not yet implemented - (return #f) - ) + (cond + ((= anim-array *toxic-slime-texture-anim-array*) + (with-dma-buffer-add-bucket ((dma-buf (-> *display* frames (-> *display* on-screen) global-buf)) + bucket + ) + (pc-texture-anim-flag start-anim-array dma-buf) + (pc-texture-anim-flag slime dma-buf :qwc 4) + (make-slime-input (the slime-input (-> dma-buf base))) + (&+! (-> dma-buf base) 64) + (pc-texture-anim-flag finish-anim-array dma-buf) + (dotimes (i 9) + (pc-update-anim-frame-time (-> *toxic-slime-texture-anim-array* array-data i)) + ) + ) + (return #f) + ) ((= anim-array *sky-texture-anim-array*) (when (= bucket (bucket-id tex-lcom-sky-post)) ;; skip. I believe this is only used to generate the envmap texture for the ocean.