diff --git a/game/CMakeLists.txt b/game/CMakeLists.txt index d01c86bcac..9ae5eb5c26 100644 --- a/game/CMakeLists.txt +++ b/game/CMakeLists.txt @@ -84,6 +84,7 @@ set(RUNTIME_SOURCE graphics/opengl_renderer/foreground/Generic2_DMA.cpp graphics/opengl_renderer/foreground/Generic2_Build.cpp graphics/opengl_renderer/foreground/Generic2_OpenGL.cpp + graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp graphics/opengl_renderer/ocean/OceanMid.cpp graphics/opengl_renderer/ocean/OceanMid_PS2.cpp graphics/opengl_renderer/ocean/OceanMidAndFar.cpp @@ -91,7 +92,6 @@ set(RUNTIME_SOURCE graphics/opengl_renderer/ocean/OceanNear_PS2.cpp graphics/opengl_renderer/ocean/OceanTexture.cpp graphics/opengl_renderer/ocean/OceanTexture_PC.cpp - graphics/opengl_renderer/ocean/OceanTexture_PS2.cpp graphics/opengl_renderer/BucketRenderer.cpp graphics/opengl_renderer/debug_gui.cpp graphics/opengl_renderer/DirectRenderer.cpp diff --git a/game/graphics/opengl_renderer/DirectRenderer.cpp b/game/graphics/opengl_renderer/DirectRenderer.cpp index 62242fc4dc..99f0638633 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.cpp +++ b/game/graphics/opengl_renderer/DirectRenderer.cpp @@ -113,7 +113,6 @@ void DirectRenderer::reset_state() { } void DirectRenderer::draw_debug_window() { - ImGui::SliderFloat("debug", &m_debug_tune, 0., 1.); ImGui::Checkbox("Wireframe", &m_debug_state.wireframe); ImGui::SameLine(); ImGui::Checkbox("No-texture", &m_debug_state.disable_texture); @@ -408,17 +407,6 @@ void DirectRenderer::update_gl_blend() { // ASSERT(false); } } - - if (m_my_id == BucketId::OCEAN_NEAR) { - if (state.a == GsAlpha::BlendMode::SOURCE && state.b == GsAlpha::BlendMode::DEST && - state.c == GsAlpha::BlendMode::SOURCE && state.d == GsAlpha::BlendMode::DEST) { - if (m_prim_gl_state.fogging_enable) { - m_ogl.alpha_mult = .5f; - } else { - glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO); - } - } - } } void DirectRenderer::update_gl_test() { @@ -589,9 +577,6 @@ void DirectRenderer::render_gif(const u8* data, case GifTag::RegisterDescriptor::TEX0_1: handle_tex0_1_packed(data + offset); break; - case GifTag::RegisterDescriptor::XYZ2: - handle_xyz2_packed(data + offset, render_state, prof); - break; default: fmt::print("Register {} is not supported in packed mode yet\n", reg_descriptor_name(reg_desc[reg])); @@ -799,24 +784,6 @@ void DirectRenderer::handle_xyzf2_packed(const u8* data, handle_xyzf2_common(x << 16, y << 16, z << 8, f, render_state, prof, !adc); } -void DirectRenderer::handle_xyz2_packed(const u8* data, - SharedRenderState* render_state, - ScopedProfilerNode& prof) { - u32 x, y, z; - memcpy(&x, data, 4); - memcpy(&y, data + 4, 4); - memcpy(&z, data + 8, 4); - - u64 upper; - memcpy(&upper, data + 8, 8); - bool adc = upper & (1ull << 47); - float un_mess_up = 448.f / 512.f; - // TODO total hack - s32 yy = (((s32)y - 1024) << 17) * un_mess_up; - handle_xyzf2_common(((x << 2) + 32768 - 2048 * 2) << 16, ((32768) << 16) - yy, z, 0, render_state, - prof, !adc); -} - void DirectRenderer::handle_zbuf1(u64 val, SharedRenderState* render_state, ScopedProfilerNode& prof) { diff --git a/game/graphics/opengl_renderer/DirectRenderer.h b/game/graphics/opengl_renderer/DirectRenderer.h index ed404e27d8..a88d5e7035 100644 --- a/game/graphics/opengl_renderer/DirectRenderer.h +++ b/game/graphics/opengl_renderer/DirectRenderer.h @@ -84,9 +84,6 @@ class DirectRenderer : public BucketRenderer { void handle_xyzf2_packed(const u8* data, SharedRenderState* render_state, ScopedProfilerNode& prof); - void handle_xyz2_packed(const u8* data, - SharedRenderState* render_state, - ScopedProfilerNode& prof); void handle_tex0_1_packed(const u8* data); void handle_tex0_1(u64 val); void handle_tex1_1(u64 val); @@ -153,7 +150,6 @@ class DirectRenderer : public BucketRenderer { static constexpr int TEXTURE_STATE_COUNT = 1; - float m_debug_tune = 1; struct TextureState { GsTex0 current_register; u32 texture_base_ptr = 0; diff --git a/game/graphics/opengl_renderer/Shader.cpp b/game/graphics/opengl_renderer/Shader.cpp index 8cf7f996d0..8d6c82788f 100644 --- a/game/graphics/opengl_renderer/Shader.cpp +++ b/game/graphics/opengl_renderer/Shader.cpp @@ -80,4 +80,5 @@ ShaderLibrary::ShaderLibrary() { at(ShaderId::GENERIC) = {"generic"}; at(ShaderId::OCEAN_TEXTURE) = {"ocean_texture"}; at(ShaderId::OCEAN_TEXTURE_MIPMAP) = {"ocean_texture_mipmap"}; + at(ShaderId::OCEAN_COMMON) = {"ocean_common"}; } diff --git a/game/graphics/opengl_renderer/Shader.h b/game/graphics/opengl_renderer/Shader.h index 06626f1f7c..5a889c4dc5 100644 --- a/game/graphics/opengl_renderer/Shader.h +++ b/game/graphics/opengl_renderer/Shader.h @@ -37,6 +37,7 @@ enum class ShaderId { GENERIC = 12, OCEAN_TEXTURE = 13, OCEAN_TEXTURE_MIPMAP = 14, + OCEAN_COMMON = 15, MAX_SHADERS }; diff --git a/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp new file mode 100644 index 0000000000..3f3f841c08 --- /dev/null +++ b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp @@ -0,0 +1,337 @@ +#include "CommonOceanRenderer.h" + +CommonOceanRenderer::CommonOceanRenderer() { + m_vertices.resize(4096 * 10); // todo decrease + for (auto& buf : m_indices) { + buf.resize(4096 * 10); + } + + // create OpenGL objects + glGenBuffers(1, &m_ogl.vertex_buffer); + glGenBuffers(NUM_BUCKETS, m_ogl.index_buffer); + glGenVertexArrays(1, &m_ogl.vao); + + // set up the vertex array + glBindVertexArray(m_ogl.vao); + for (int i = 0; i < NUM_BUCKETS; i++) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[i]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_indices[i].size() * sizeof(u32), nullptr, + GL_STREAM_DRAW); + } + glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer); + glBufferData(GL_ARRAY_BUFFER, m_vertices.size() * sizeof(Vertex), nullptr, GL_STREAM_DRAW); + + // xyz + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, // location 0 in the shader + 3, // 3 floats per vert + GL_FLOAT, // floats + GL_TRUE, // normalized, ignored, + sizeof(Vertex), // + (void*)offsetof(Vertex, xyz) // offset in array + ); + + // rgba + glEnableVertexAttribArray(1); + glVertexAttribPointer(1, // location 1 in the shader + 4, // 4 color components + GL_UNSIGNED_BYTE, // u8 + GL_TRUE, // normalized (255 becomes 1) + sizeof(Vertex), // + (void*)offsetof(Vertex, rgba) // + ); + + // stq + glEnableVertexAttribArray(2); + glVertexAttribPointer(2, // location 2 in the shader + 3, // 2 floats per vert + GL_FLOAT, // floats + GL_FALSE, // normalized, ignored + sizeof(Vertex), // + (void*)offsetof(Vertex, stq) // offset in array + ); + + // byte data + glEnableVertexAttribArray(3); + glVertexAttribIPointer(3, // location 3 in the shader + 1, // + GL_UNSIGNED_BYTE, // u8's + sizeof(Vertex), // + (void*)offsetof(Vertex, fog) // offset in array + ); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindVertexArray(0); +} + +CommonOceanRenderer::~CommonOceanRenderer() { + glDeleteBuffers(1, &m_ogl.vertex_buffer); + glDeleteBuffers(3, m_ogl.index_buffer); + glDeleteVertexArrays(1, &m_ogl.vao); +} + +void CommonOceanRenderer::init_for_near() { + m_next_free_vertex = 0; + for (auto& x : m_next_free_index) { + x = 0; + } +} + +void CommonOceanRenderer::kick_from_near(const u8* data) { + bool eop = false; + + u32 offset = 0; + while (!eop) { + GifTag tag(data + offset); + offset += 16; + + if (tag.nreg() == 3) { + ASSERT(tag.pre()); + if (GsPrim(tag.prim()).kind() == GsPrim::Kind::TRI_STRIP) { + handle_near_vertex_gif_data_strip(data, offset, tag.nloop()); + } else { + handle_near_vertex_gif_data_fan(data, offset, tag.nloop()); + } + offset += 16 * 3 * tag.nloop(); + } else if (tag.nreg() == 1) { + handle_near_adgif(data, offset, tag.nloop()); + offset += 16 * 1 * tag.nloop(); + } else { + ASSERT(false); + } + + eop = tag.eop(); + } +} + +void CommonOceanRenderer::handle_near_vertex_gif_data_strip(const u8* data, u32 offset, u32 loop) { + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = UINT32_MAX; + bool reset_last = false; + for (u32 i = 0; i < loop; i++) { + auto& dest_vert = m_vertices[m_next_free_vertex++]; + + // stq + memcpy(dest_vert.stq.data(), data + offset, 12); + offset += 16; + + // rgba + dest_vert.rgba[0] = data[offset]; + dest_vert.rgba[1] = data[offset + 4]; + dest_vert.rgba[2] = data[offset + 8]; + dest_vert.rgba[3] = data[offset + 12]; + offset += 16; + + // xyz + u32 x = 0, y = 0; + memcpy(&x, data + offset, 4); + memcpy(&y, data + offset + 4, 4); + + u64 upper; + memcpy(&upper, data + offset + 8, 8); + u32 z = (upper >> 4) & 0xffffff; + offset += 16; + + dest_vert.xyz[0] = (float)(x << 16) / (float)UINT32_MAX; + dest_vert.xyz[1] = (float)(y << 16) / (float)UINT32_MAX; + dest_vert.xyz[2] = (float)(z << 8) / (float)UINT32_MAX; + + u8 f = (upper >> 36); + dest_vert.fog = f; + + auto vidx = m_next_free_vertex - 1; + bool adc = upper & (1ull << 47); + if (!adc) { + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = vidx; + reset_last = false; + } else { + if (reset_last) { + m_next_free_index[m_current_bucket] -= 3; + } + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = UINT32_MAX; + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = vidx - 1; + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = vidx; + reset_last = true; + } + } +} + +void CommonOceanRenderer::handle_near_vertex_gif_data_fan(const u8* data, u32 offset, u32 loop) { + u32 ind_of_fan_start = UINT32_MAX; + bool fan_running = false; + // :regs0 (gif-reg-id st) :regs1 (gif-reg-id rgbaq) :regs2 (gif-reg-id xyzf2) + for (u32 i = 0; i < loop; i++) { + auto& dest_vert = m_vertices[m_next_free_vertex++]; + + // stq + memcpy(dest_vert.stq.data(), data + offset, 12); + offset += 16; + + // rgba + dest_vert.rgba[0] = data[offset]; + dest_vert.rgba[1] = data[offset + 4]; + dest_vert.rgba[2] = data[offset + 8]; + dest_vert.rgba[3] = data[offset + 12]; + offset += 16; + + // xyz + u32 x = 0, y = 0; + memcpy(&x, data + offset, 4); + memcpy(&y, data + offset + 4, 4); + + u64 upper; + memcpy(&upper, data + offset + 8, 8); + u32 z = (upper >> 4) & 0xffffff; + offset += 16; + + dest_vert.xyz[0] = (float)(x << 16) / (float)UINT32_MAX; + dest_vert.xyz[1] = (float)(y << 16) / (float)UINT32_MAX; + dest_vert.xyz[2] = (float)(z << 8) / (float)UINT32_MAX; + + u8 f = (upper >> 36); + dest_vert.fog = f; + + auto vidx = m_next_free_vertex - 1; + + if (ind_of_fan_start == UINT32_MAX) { + ind_of_fan_start = vidx; + } else { + if (fan_running) { + // hack to draw fans with strips. this isn't efficient, but fans happen extremely rarely + // (you basically have to put the camera intersecting the ocean and looking fwd) + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = UINT32_MAX; + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = vidx; + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = vidx - 1; + m_indices[m_current_bucket][m_next_free_index[m_current_bucket]++] = ind_of_fan_start; + } else { + fan_running = true; + } + } + } +} + +void CommonOceanRenderer::handle_near_adgif(const u8* data, u32 offset, u32 count) { + u32 most_recent_tbp = 0; + + for (u32 i = 0; i < count; i++) { + u64 value; + GsRegisterAddress addr; + memcpy(&value, data + offset + 16 * i, sizeof(u64)); + memcpy(&addr, data + offset + 16 * i + 8, sizeof(GsRegisterAddress)); + switch (addr) { + case GsRegisterAddress::MIPTBP1_1: + // ignore this, it's just mipmapping settings + break; + case GsRegisterAddress::TEX1_1: { + GsTex1 reg(value); + ASSERT(reg.mmag()); + } break; + case GsRegisterAddress::CLAMP_1: { + bool s = value & 0b001; + bool t = value & 0b100; + ASSERT(s == t); + if (s) { + m_current_bucket = VertexBucket::ENV_MAP; + } + } break; + case GsRegisterAddress::TEX0_1: { + GsTex0 reg(value); + ASSERT(reg.tfx() == GsTex0::TextureFunction::MODULATE); + if (!reg.tcc()) { + m_current_bucket = VertexBucket::RGB_TEXTURE; + } + most_recent_tbp = reg.tbp0(); + } break; + case GsRegisterAddress::ALPHA_1: { + // ignore, we've hardcoded alphas. + } break; + case GsRegisterAddress::FRAME_1: { + u32 mask = value >> 32; + if (mask) { + m_current_bucket = VertexBucket::ALPHA; + } + } break; + + default: + fmt::print("reg: {}\n", register_address_name(addr)); + break; + } + } + + if (m_current_bucket == VertexBucket::ENV_MAP) { + m_envmap_tex = most_recent_tbp; + } + + if (m_vertices.size() - 128 < m_next_free_vertex) { + ASSERT(false); // add more vertices. + } +} + +void CommonOceanRenderer::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) { + glBindVertexArray(m_ogl.vao); + glBindBuffer(GL_ARRAY_BUFFER, m_ogl.vertex_buffer); + glEnable(GL_PRIMITIVE_RESTART); + glPrimitiveRestartIndex(UINT32_MAX); + glBufferData(GL_ARRAY_BUFFER, m_next_free_vertex * sizeof(Vertex), m_vertices.data(), + GL_STREAM_DRAW); + render_state->shaders[ShaderId::OCEAN_COMMON].activate(); + glUniform4f(glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "fog_color"), + render_state->fog_color[0], render_state->fog_color[1], render_state->fog_color[2], + render_state->fog_intensity); + + glDepthMask(GL_FALSE); + glEnable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glDepthFunc(GL_GEQUAL); + + for (int bucket = 0; bucket < 3; bucket++) { + switch (bucket) { + case 0: { + glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ZERO); + glBlendEquation(GL_FUNC_ADD); + auto tex = render_state->texture_pool->lookup(8160); + if (!tex) { + tex = render_state->texture_pool->get_placeholder_texture(); + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, *tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glUniform1i( + glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "tex_T0"), 0); + glUniform1i( + glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "bucket"), 0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + + break; + case 1: + glBlendFuncSeparate(GL_ZERO, GL_ONE, GL_ONE, GL_ZERO); + glUniform1f( + glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "alpha_mult"), + 1.f); + glUniform1i( + glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "bucket"), 1); + break; + case 2: + auto tex = render_state->texture_pool->lookup(m_envmap_tex); + if (!tex) { + tex = render_state->texture_pool->get_placeholder_texture(); + } + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, *tex); + + glBlendFuncSeparate(GL_DST_ALPHA, GL_ONE, GL_ONE, GL_ZERO); + glBlendEquation(GL_FUNC_ADD); + glUniform1i( + glGetUniformLocation(render_state->shaders[ShaderId::OCEAN_COMMON].id(), "bucket"), 2); + break; + } + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_ogl.index_buffer[bucket]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, m_next_free_index[bucket] * sizeof(u32), + m_indices[bucket].data(), GL_STREAM_DRAW); + glDrawElements(GL_TRIANGLE_STRIP, m_next_free_index[bucket], GL_UNSIGNED_INT, nullptr); + prof.add_draw_call(); + prof.add_tri(m_next_free_index[bucket]); + } +} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h new file mode 100644 index 0000000000..12eadf8a84 --- /dev/null +++ b/game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h @@ -0,0 +1,48 @@ +#pragma once +#include "game/graphics/opengl_renderer/BucketRenderer.h" + +class CommonOceanRenderer { + public: + CommonOceanRenderer(); + ~CommonOceanRenderer(); + + void init_for_near(); + void kick_from_near(const u8* data); + void flush(SharedRenderState* render_state, ScopedProfilerNode& prof); + + private: + void handle_near_vertex_gif_data_fan(const u8* data, u32 offset, u32 loop); + void handle_near_vertex_gif_data_strip(const u8* data, u32 offset, u32 loop); + + void handle_near_adgif(const u8* data, u32 offset, u32 count); + + enum VertexBucket { + RGB_TEXTURE = 0, + ALPHA = 1, + ENV_MAP = 2, + }; + u32 m_current_bucket = VertexBucket::RGB_TEXTURE; + + struct Vertex { + math::Vector xyz; + math::Vector rgba; + math::Vector stq; + u8 fog; + u8 pad[3]; + }; + static_assert(sizeof(Vertex) == 32); + + static constexpr int NUM_BUCKETS = 3; + + std::vector m_vertices; + u32 m_next_free_vertex = 0; + + std::vector m_indices[NUM_BUCKETS]; + u32 m_next_free_index[NUM_BUCKETS] = {0}; + + u32 m_envmap_tex = 0; + + struct { + GLuint vertex_buffer, index_buffer[NUM_BUCKETS], vao; + } m_ogl; +}; diff --git a/game/graphics/opengl_renderer/ocean/OceanNear.cpp b/game/graphics/opengl_renderer/ocean/OceanNear.cpp index 0a8ce68cd9..9a51b7d02b 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanNear.cpp @@ -1,4 +1,5 @@ #include "OceanNear.h" +#include "third-party/imgui/imgui.h" OceanNear::OceanNear(const std::string& name, BucketId my_id) : BucketRenderer(name, my_id), m_texture_renderer(false), m_direct(name, my_id, 0x4000) { @@ -8,6 +9,7 @@ OceanNear::OceanNear(const std::string& name, BucketId my_id) } void OceanNear::draw_debug_window() { + ImGui::Checkbox("New", &m_use_new); m_direct.draw_debug_window(); } @@ -62,13 +64,20 @@ void OceanNear::render(DmaFollower& dma, } // direct setup - m_direct.reset_state(); { + if (m_use_new) { + m_common_ocean_renderer.init_for_near(); + } else { + m_direct.reset_state(); + } auto setup = dma.read_and_advance(); ASSERT(setup.vifcode0().kind == VifCode::Kind::NOP); ASSERT(setup.vifcode1().kind == VifCode::Kind::DIRECT); ASSERT(setup.size_bytes == 32); - m_direct.render_gif(setup.data, 32, render_state, prof); + if (m_use_new) { + } else { + m_direct.render_gif(setup.data, 32, render_state, prof); + } } // oofset and base @@ -113,5 +122,18 @@ void OceanNear::render(DmaFollower& dma, while (dma.current_tag_offset() != render_state->next_bucket) { dma.read_and_advance(); } - m_direct.flush_pending(render_state, prof); + + if (m_use_new) { + m_common_ocean_renderer.flush(render_state, prof); + } else { + m_direct.flush_pending(render_state, prof); + } +} + +void OceanNear::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) { + if (m_use_new) { + m_common_ocean_renderer.kick_from_near((const u8*)&m_vu_data[addr]); + } else { + m_direct.render_gif((const u8*)&m_vu_data[addr], UINT32_MAX, render_state, prof); + } } \ No newline at end of file diff --git a/game/graphics/opengl_renderer/ocean/OceanNear.h b/game/graphics/opengl_renderer/ocean/OceanNear.h index ae2a53e102..c2fc4948ed 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear.h +++ b/game/graphics/opengl_renderer/ocean/OceanNear.h @@ -3,6 +3,7 @@ #include "game/graphics/opengl_renderer/BucketRenderer.h" #include "game/graphics/opengl_renderer/ocean/OceanTexture.h" #include "game/common/vu.h" +#include "game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h" class OceanNear : public BucketRenderer { public: @@ -23,11 +24,14 @@ class OceanNear : public BucketRenderer { OceanTexture m_texture_renderer; DirectRenderer m_direct; + CommonOceanRenderer m_common_ocean_renderer; bool m_buffer_toggle = false; static constexpr int VU1_INPUT_BUFFER_BASE = 0; static constexpr int VU1_INPUT_BUFFER_OFFSET = 0x10; + bool m_use_new = true; + void xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof); u16 xtop() { diff --git a/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp b/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp index 02fbc25ef0..569876209e 100644 --- a/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanNear_PS2.cpp @@ -1,9 +1,5 @@ #include "OceanNear.h" -void OceanNear::xgkick(u16 addr, SharedRenderState* render_state, ScopedProfilerNode& prof) { - m_direct.render_gif((const u8*)&m_vu_data[addr], UINT32_MAX, render_state, prof); -} - void OceanNear::run_call0_vu2c() { bool bc; // lq.xyzw vf01, 951(vi00) | nop 0 diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture.cpp b/game/graphics/opengl_renderer/ocean/OceanTexture.cpp index dca60afe69..13300ae36f 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanTexture.cpp @@ -9,8 +9,7 @@ OceanTexture::OceanTexture(bool generate_mipmaps) TEX0_SIZE, GL_UNSIGNED_INT_8_8_8_8_REV, m_generate_mipmaps ? NUM_MIPS : 1), - m_temp_texture(TEX0_SIZE, TEX0_SIZE, GL_UNSIGNED_INT_8_8_8_8_REV), - m_hack_renderer("ocean-tex-unoptimized", BucketId::BUCKET0, 0x8000) { + m_temp_texture(TEX0_SIZE, TEX0_SIZE, GL_UNSIGNED_INT_8_8_8_8_REV) { m_dbuf_x = m_dbuf_a; m_dbuf_y = m_dbuf_b; @@ -66,40 +65,6 @@ void OceanTexture::draw_debug_window() { if (m_tex0_gpu) { ImGui::Image((void*)m_tex0_gpu->gpu_textures.at(0).gl, ImVec2(m_tex0_gpu->w, m_tex0_gpu->h)); } - ImGui::Checkbox("Optimized Version", &m_use_ocean_specific); -} - -void OceanTexture::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) { - if (m_use_ocean_specific) { - flush_pc(render_state, prof); - } else { - m_hack_renderer.flush_pending(render_state, prof); - } -} - -void OceanTexture::setup_renderer() { - if (m_use_ocean_specific) { - setup_pc(); - } else { - m_hack_renderer.reset_state(); - } -} - -void OceanTexture::handle_tex_call_start(SharedRenderState* render_state, - ScopedProfilerNode& prof) { - if (m_use_ocean_specific) { - run_L1_PC(); - } else { - run_L1(render_state, prof); - } -} - -void OceanTexture::handle_tex_call_rest(SharedRenderState* render_state, ScopedProfilerNode& prof) { - if (m_use_ocean_specific) { - run_L2_PC(); - } else { - run_L2(render_state, prof); - } } void OceanTexture::handle_ocean_texture(DmaFollower& dma, @@ -148,27 +113,8 @@ void OceanTexture::handle_ocean_texture(DmaFollower& dma, ASSERT(data.vifcode0().kind == VifCode::Kind::NOP); ASSERT(data.vifcode1().kind == VifCode::Kind::DIRECT); memcpy(&m_envmap_adgif, data.data + 16, sizeof(AdGifData)); - - // fmt::print("adgif is:\n{}\n\n", AdgifHelper(m_envmap_adgif).print()); - /* - * adgif is: -[0] TEX0_1 - tbp0: 10010 tbw: 2 psm: 19 tw: 6 th: 6 tcc: 1 tfx: 0 cbp: 10046 cpsm: 0 csm: 0 -[1] TEX1_1 - lcm: false mxl: 0 mmag: true mmin: 4 mtba: false l: 0 k: 0 -[2] MIPTBP1_1 -[3] CLAMP_1 - 0x5 -[4] ALPHA_1 - (Cs - Cd) * As / 128.0 + Cd - - */ - // HACK setup_renderer(); - if (!m_use_ocean_specific) { - m_hack_renderer.render_gif(data.data, UINT32_MAX, render_state, prof); - } } // vertices are uploaded double buffered @@ -197,7 +143,7 @@ void OceanTexture::handle_ocean_texture(DmaFollower& dma, ASSERT(data.vifcode0().kind == VifCode::Kind::MSCALF); ASSERT(data.vifcode0().immediate == TexVu1Prog::START); ASSERT(data.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... - handle_tex_call_start(render_state, prof); + run_L1_PC(); } // loop over vertex groups @@ -218,7 +164,7 @@ void OceanTexture::handle_ocean_texture(DmaFollower& dma, ASSERT(call.vifcode0().kind == VifCode::Kind::MSCALF); ASSERT(call.vifcode0().immediate == TexVu1Prog::REST); ASSERT(call.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... - handle_tex_call_rest(render_state, prof); + run_L2_PC(); } // last upload does something weird... @@ -254,7 +200,7 @@ void OceanTexture::handle_ocean_texture(DmaFollower& dma, ASSERT(data.vifcode0().kind == VifCode::Kind::MSCALF); ASSERT(data.vifcode0().immediate == TexVu1Prog::REST); ASSERT(data.vifcode1().kind == VifCode::Kind::STMOD); // not sure why... - handle_tex_call_rest(render_state, prof); + run_L2_PC(); } // last call diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture.h b/game/graphics/opengl_renderer/ocean/OceanTexture.h index 52ebb7c18e..b4fb7c2ba5 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture.h +++ b/game/graphics/opengl_renderer/ocean/OceanTexture.h @@ -16,15 +16,6 @@ class OceanTexture { ~OceanTexture(); private: - void handle_tex_call_start(SharedRenderState* render_state, ScopedProfilerNode& prof); - void handle_tex_call_rest(SharedRenderState* render_state, ScopedProfilerNode& prof); - - void run_L1(SharedRenderState* render_state, ScopedProfilerNode& prof); - void run_L2(SharedRenderState* render_state, ScopedProfilerNode& prof); - void run_L3(); - void run_L5(SharedRenderState* render_state, ScopedProfilerNode& prof); - void xgkick(Vf* src, SharedRenderState* render_state, ScopedProfilerNode& prof); - void run_L1_PC(); void run_L2_PC(); void run_L3_PC(); @@ -34,14 +25,11 @@ class OceanTexture { void setup_renderer(); void flush(SharedRenderState* render_state, ScopedProfilerNode& prof); - void setup_pc(); - void flush_pc(SharedRenderState* render_state, ScopedProfilerNode& prof); void init_pc(); void destroy_pc(); void make_texture_with_mipmaps(SharedRenderState* render_state, ScopedProfilerNode& prof); - bool m_use_ocean_specific = true; bool m_generate_mipmaps; static constexpr int TEX0_SIZE = 128; @@ -161,6 +149,4 @@ class OceanTexture { enum TexVu1Prog { START = 0, REST = 2, DONE = 4 }; static constexpr int NUM_FRAG_LOOPS = 9; - - DirectRenderer m_hack_renderer; }; diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp b/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp index 2d510a3be7..1270359a9e 100644 --- a/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp +++ b/game/graphics/opengl_renderer/ocean/OceanTexture_PC.cpp @@ -394,11 +394,11 @@ void OceanTexture::xgkick_PC(Vf* src) { } } -void OceanTexture::setup_pc() { +void OceanTexture::setup_renderer() { m_pc.vtx_idx = 0; } -void OceanTexture::flush_pc(SharedRenderState* render_state, ScopedProfilerNode& prof) { +void OceanTexture::flush(SharedRenderState* render_state, ScopedProfilerNode& prof) { ASSERT(m_pc.vtx_idx == 2112); glBindVertexArray(m_pc.vao); glBindBuffer(GL_ARRAY_BUFFER, m_pc.dynamic_vertex_buffer); diff --git a/game/graphics/opengl_renderer/ocean/OceanTexture_PS2.cpp b/game/graphics/opengl_renderer/ocean/OceanTexture_PS2.cpp deleted file mode 100644 index c5f76903a1..0000000000 --- a/game/graphics/opengl_renderer/ocean/OceanTexture_PS2.cpp +++ /dev/null @@ -1,378 +0,0 @@ -#include "OceanTexture.h" - -void OceanTexture::run_L1(SharedRenderState* render_state, ScopedProfilerNode& prof) { - // L1: - // lq.xyzw vf14_startx, 988(vi00) | maxw.xyzw vf01_ones, vf00, vf00 - vu.startx = Vf(m_texture_constants.start); - // lq.xyzw vf02_offset, 989(vi00) - // lq.xyzw vf03_tbuf, 986(vi00) - // lq.xyzw vf04_dbuf, 987(vi00) - // lq.xyzw vf05_giftag, 985(vi00) - // lq.xyzw vf06_cam_nrm, 991(vi00) - // lq.xyzw vf07_constants, 990(vi00) - // iaddiu vi11_0x80, vi00, 0x80 - // mtir vi08_tptr, vf03_tbuf.x - vu.tptr = get_tbuf(); - // mtir vi09_tbase, vf03_tbuf.x - vu.tbase = get_tbuf(); - // mr32.xyzw vf03_tbuf, vf03_tbuf - swap_tbuf(); - // xtop vi05_in_ptr - vu.in_ptr = swap_vu_upload_buffers(); - - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi03_dbuf_read_a, vf04_dbuf.x - vu.dbuf_read_a = get_dbuf(); - // bal vi12_ra, L5 - // mtir vi04_dbuf_read_b, vf04_dbuf.y - vu.dbuf_read_b = get_dbuf_other(); - run_L5(render_state, prof); - - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi03_dbuf_read_a, vf04_dbuf.x - vu.dbuf_read_a = get_dbuf(); - // bal vi12_ra, L5 - // mtir vi04_dbuf_read_b, vf04_dbuf.y - vu.dbuf_read_b = get_dbuf_other(); - run_L5(render_state, prof); - - // nop :e - // nop -} - -void OceanTexture::run_L2(SharedRenderState* render_state, ScopedProfilerNode& prof) { - // L2: - // xtop vi05_in_ptr - vu.in_ptr = swap_vu_upload_buffers(); - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi03_dbuf_read_a, vf04_dbuf.x - vu.dbuf_read_a = get_dbuf(); - // bal vi12_ra, L5 - // mtir vi04_dbuf_read_b, vf04_dbuf.y - vu.dbuf_read_b = get_dbuf_other(); - run_L5(render_state, prof); - - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi03_dbuf_read_a, vf04_dbuf.x - vu.dbuf_read_a = get_dbuf(); - // bal vi12_ra, L5 - // mtir vi04_dbuf_read_b, vf04_dbuf.y - vu.dbuf_read_b = get_dbuf_other(); - run_L5(render_state, prof); - - // mtir vi06_dbuf_write, vf04_dbuf.x - vu.dbuf_write = get_dbuf(); - // bal vi12_ra, L3 - // mr32.xyzw vf04_dbuf, vf04_dbuf - swap_dbuf(); - run_L3(); - - // mtir vi03_dbuf_read_a, vf04_dbuf.x - vu.dbuf_read_a = get_dbuf(); - // bal vi12_ra, L5 - // mtir vi04_dbuf_read_b, vf04_dbuf.y - vu.dbuf_read_b = get_dbuf_other(); - run_L5(render_state, prof); - - // nop :e - // nop -} - -namespace { -void lq_buffer(Mask mask, Vf& dest, Vf* src) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - dest.data[i] = src->data[i]; - } - } -} - -void sq_buffer(Mask mask, const Vf& src, Vf* dest) { - for (int i = 0; i < 4; i++) { - if ((u64)mask & (1 << i)) { - dest->data[i] = src.data[i]; - } - } -} - -void sq_buffer_giftag(const u8* src, Vf* dest) { - memcpy(dest, src, 16); -} -} // namespace - -void OceanTexture::run_L3() { - Vf base_pos; // vf15 - u16 loop_idx; - - Vf vtx0; // vf16 - Vf vtx1; // vf17 - Vf vtx2; // vf18 - Vf vtx3; // vf19 - - Vf res0; // vf20 - Vf res1; // vf21 - Vf res2; // vf22 - Vf res3; // vf23 - - Vf nrm0; // vf24 - Vf nrm1; // vf25 - Vf nrm2; // vf26 - - Vf reflect; // vf27 - - Vf cout0; // vf28 - Vf cout1; // vf29 - Vf cout2; // vf30 - Vf cout3; // vf31 - - Accumulator acc; - const Vf ones(1, 1, 1, 1); - const Vf vf00(0, 0, 0, 1); - const u16 vi11 = 0x80; - bool bc; - - // clang-format off - // L3: - // ior vi07, vi06, vi00 | nop 56 - vu.dbuf_write_base = vu.dbuf_write; - // move.xyzw vf15, vf14 | nop 57 - base_pos.move(Mask::xyzw, vu.startx); - // iaddi vi01, vi00, 0x8 | nop 58 - loop_idx = 8; - // lq.xyzw vf24, 1(vi05) | mulw.xyzw vf20, vf15, vf00 59 (?? what are they doing here) - res0.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm0, vu.in_ptr + 1); - // lq.xyzw vf25, 3(vi05) | mulw.xyzw vf21, vf15, vf00 60 - res1.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm1, vu.in_ptr + 3); - // lq.xyzw vf26, 5(vi05) | mulw.xyzw vf22, vf15, vf00 61 - res2.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm2, vu.in_ptr + 5); - // nop | mulw.xyzw vf23, vf15, vf00 62 - res3.mul(Mask::xyzw, base_pos, 1.f); - // nop | mulax.xyzw ACC, vf24, vf06 63 - acc.mula(Mask::xyzw, nrm0, m_texture_constants.cam_nrm.x()); - // nop | madday.xyzw ACC, vf25, vf06 64 - acc.madda(Mask::xyzw, nrm1, m_texture_constants.cam_nrm.y()); - // nop | maddz.xyzw vf27, vf26, vf06 65 - acc.madd(Mask::xyzw, reflect, nrm2, m_texture_constants.cam_nrm.z()); - // nop | addx.x vf21, vf21, vf02 66 - res1.add(Mask::x, res1, m_texture_constants.offsets.x()); - // nop | addy.x vf22, vf22, vf02 67 - res2.add(Mask::x, res2, m_texture_constants.offsets.y()); - L4: - // nop | addz.x vf23, vf23, vf02 68 - res3.add(Mask::x, res3, m_texture_constants.offsets.z()); - // nop | addw.x vf15, vf15, vf02 69 - base_pos.add(Mask::x, base_pos, m_texture_constants.offsets.w()); - // sq.xyzw vf20, 2(vi06) | mulx.x vf28, vf01, vf24 70 - cout0.mul(Mask::x, ones, nrm0.x()); sq_buffer(Mask::xyzw, res0, vu.dbuf_write + 2); - // sq.xyzw vf21, 5(vi06) | muly.x vf29, vf01, vf24 71 - cout1.mul(Mask::x, ones, nrm0.y()); sq_buffer(Mask::xyzw, res1, vu.dbuf_write + 5); - // sq.xyzw vf22, 8(vi06) | mulz.x vf30, vf01, vf24 72 - cout2.mul(Mask::x, ones, nrm0.z()); sq_buffer(Mask::xyzw, res2, vu.dbuf_write + 8); - // sq.xyzw vf23, 11(vi06) | mulw.x vf31, vf01, vf24 73 - cout3.mul(Mask::x, ones, nrm0.w()); sq_buffer(Mask::xyzw, res3, vu.dbuf_write + 11); - // lq.xyzw vf16, 0(vi05) | mulx.y vf28, vf01, vf25 74 - cout0.mul(Mask::y, ones, nrm1.x()); lq_buffer(Mask::xyzw, vtx0, vu.in_ptr); - // lq.xyzw vf17, 2(vi05) | muly.y vf29, vf01, vf25 75 - cout1.mul(Mask::y, ones, nrm1.y()); lq_buffer(Mask::xyzw, vtx1, vu.in_ptr + 2); - // lq.xyzw vf18, 4(vi05) | mulz.y vf30, vf01, vf25 76 - cout2.mul(Mask::y, ones, nrm1.z()); lq_buffer(Mask::xyzw, vtx2, vu.in_ptr + 4); - // lq.xyzw vf19, 6(vi05) | mulw.y vf31, vf01, vf25 77 - cout3.mul(Mask::y, ones, nrm1.w()); lq_buffer(Mask::xyzw, vtx3, vu.in_ptr + 6); - // iaddi vi05, vi05, 0x8 | mulx.xy vf28, vf28, vf27 78 - cout0.mul(Mask::xy, cout0, reflect.x()); vu.in_ptr = vu.in_ptr + 8; - // nop | muly.xy vf29, vf29, vf27 79 - cout1.mul(Mask::xy, cout1, reflect.y()); - // nop | mulz.xy vf30, vf30, vf27 80 - cout2.mul(Mask::xy, cout2, reflect.z()); - // nop | mulw.xy vf31, vf31, vf27 81 - cout3.mul(Mask::xy, cout3, reflect.w()); - // nop | mulw.xy vf28, vf28, vf16 82 - cout0.mul(Mask::xy, cout0, vtx0.w()); - // nop | mulw.xy vf29, vf29, vf17 83 - cout1.mul(Mask::xy, cout1, vtx1.w()); - // nop | mulw.xy vf30, vf30, vf18 84 - cout2.mul(Mask::xy, cout2, vtx2.w()); - // nop | mulw.xy vf31, vf31, vf19 85 - cout3.mul(Mask::xy, cout3, vtx3.w()); - // nop | ftoi0.xyzw vf16, vf16 86 - vtx0.ftoi0(Mask::xyzw, vtx0); - // nop | ftoi0.xyzw vf17, vf17 87 - vtx1.ftoi0(Mask::xyzw, vtx1); - // nop | ftoi0.xyzw vf18, vf18 88 - vtx2.ftoi0(Mask::xyzw, vtx2); - // iaddi vi01, vi01, -0x1 | ftoi0.xyzw vf19, vf19 89 - vtx3.ftoi0(Mask::xyzw, vtx3); loop_idx = loop_idx + -1; - // mfir.w vf16, vi11 | add.xyzw vf28, vf28, vf06 90 - cout0.add(Mask::xyzw, cout0, m_texture_constants.cam_nrm); vtx0.mfir(Mask::w, vi11); - // mfir.w vf17, vi11 | add.xyzw vf29, vf29, vf06 91 - cout1.add(Mask::xyzw, cout1, m_texture_constants.cam_nrm); vtx1.mfir(Mask::w, vi11); - // mfir.w vf18, vi11 | add.xyzw vf30, vf30, vf06 92 - cout2.add(Mask::xyzw, cout2, m_texture_constants.cam_nrm); vtx2.mfir(Mask::w, vi11); - // mfir.w vf19, vi11 | add.xyzw vf31, vf31, vf06 93 - cout3.add(Mask::xyzw, cout3, m_texture_constants.cam_nrm); vtx3.mfir(Mask::w, vi11); - // nop | mulx.xyzw vf28, vf28, vf07 94 - cout0.mul(Mask::xyzw, cout0, m_texture_constants.constants.x()); - // nop | mulx.xyzw vf29, vf29, vf07 95 - cout1.mul(Mask::xyzw, cout1, m_texture_constants.constants.x()); - // nop | mulx.xyzw vf30, vf30, vf07 96 - cout2.mul(Mask::xyzw, cout2, m_texture_constants.constants.x()); - // nop | mulx.xyzw vf31, vf31, vf07 97 - cout3.mul(Mask::xyzw, cout3, m_texture_constants.constants.x()); - // nop | addy.xyzw vf28, vf28, vf07 98 - cout0.add(Mask::xyzw, cout0, m_texture_constants.constants.y()); - // nop | addy.xyzw vf29, vf29, vf07 99 - cout1.add(Mask::xyzw, cout1, m_texture_constants.constants.y()); - // nop | addy.xyzw vf30, vf30, vf07 100 - cout2.add(Mask::xyzw, cout2, m_texture_constants.constants.y()); - // nop | addy.xyzw vf31, vf31, vf07 101 - cout3.add(Mask::xyzw, cout3, m_texture_constants.constants.y()); - // sq.xyzw vf16, 1(vi06) | sub.zw vf28, vf01, vf00 102 - cout0.sub(Mask::zw, ones, vf00); sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1); - // sq.xyzw vf17, 4(vi06) | sub.zw vf29, vf01, vf00 103 - cout1.sub(Mask::zw, ones, vf00); sq_buffer(Mask::xyzw, vtx1, vu.dbuf_write + 4); - // sq.xyzw vf18, 7(vi06) | sub.zw vf30, vf01, vf00 104 - cout2.sub(Mask::zw, ones, vf00); sq_buffer(Mask::xyzw, vtx2, vu.dbuf_write + 7); - // sq.xyzw vf19, 10(vi06) | sub.zw vf31, vf01, vf00 105 - cout3.sub(Mask::zw, ones, vf00); sq_buffer(Mask::xyzw, vtx3, vu.dbuf_write + 10); - // lq.xyzw vf24, 1(vi05) | mulw.xyzw vf20, vf15, vf00 106 - res0.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm0, vu.in_ptr + 1); - // lq.xyzw vf25, 3(vi05) | mulw.xyzw vf21, vf15, vf00 107 - res1.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm1, vu.in_ptr + 3); - // lq.xyzw vf26, 5(vi05) | mulw.xyzw vf22, vf15, vf00 108 - res2.mul(Mask::xyzw, base_pos, 1.f); lq_buffer(Mask::xyzw, nrm2, vu.in_ptr + 5); - // sq.xyzw vf28, 0(vi06) | mulw.xyzw vf23, vf15, vf00 109 - res3.mul(Mask::xyzw, base_pos, 1.f); sq_buffer(Mask::xyzw, cout0, vu.dbuf_write); - // sq.xyzw vf29, 3(vi06) | mulax.xyzw ACC, vf24, vf06 110 - acc.mula(Mask::xyzw, nrm0, m_texture_constants.cam_nrm.x()); sq_buffer(Mask::xyzw, cout1, vu.dbuf_write + 3); - // sq.xyzw vf30, 6(vi06) | madday.xyzw ACC, vf25, vf06 111 - acc.madda(Mask::xyzw, nrm1, m_texture_constants.cam_nrm.y()); sq_buffer(Mask::xyzw, cout2, vu.dbuf_write + 6); - // sq.xyzw vf31, 9(vi06) | maddz.xyzw vf27, vf26, vf06 112 - acc.madd(Mask::xyzw, reflect, nrm2, m_texture_constants.cam_nrm.z()); sq_buffer(Mask::xyzw, cout3, vu.dbuf_write + 9); - // BRANCH! - // ibgtz vi01, L4 | addx.x vf21, vf21, vf02 113 - res1.add(Mask::x, res1, m_texture_constants.offsets.x()); bc = ((s16)loop_idx) > 0; - // iaddi vi06, vi06, 0xc | addy.x vf22, vf22, vf02 114 - res2.add(Mask::x, res2, m_texture_constants.offsets.y()); vu.dbuf_write = vu.dbuf_write + 12; - if (bc) { goto L4; } - - // lq.xyzw vf28, 0(vi07) | addx.y vf14, vf14, vf02 115 - vu.startx.add(Mask::y, vu.startx, m_texture_constants.offsets.x()); lq_buffer(Mask::xyzw, cout0, vu.dbuf_write_base); - // lq.xyzw vf16, 1(vi07) | nop 116 - lq_buffer(Mask::xyzw, vtx0, vu.dbuf_write_base + 1); - // sq.xyzw vf20, 2(vi06) | nop 117 - sq_buffer(Mask::xyzw, res0, vu.dbuf_write + 2); - // sq.xyzw vf28, 0(vi06) | nop 118 - sq_buffer(Mask::xyzw, cout0, vu.dbuf_write); - // jr vi12 | nop 119 - // sq.xyzw vf16, 1(vi06) | nop 120 - sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1); - // clang-format on -} - -void OceanTexture::run_L5(SharedRenderState* render_state, ScopedProfilerNode& prof) { - // clang-format off - u16 loop_idx; - Vf res0; - Vf res1; - Vf cout0; - Vf cout1; - Vf vtx0; - Vf vtx1; - bool bc; - // L5: - // iaddiu vi01, vi00, 0x21 | nop 121 - loop_idx = 0x21; /* 33 */ - // sq.xyzw vf05, 0(vi08) | nop 122 - sq_buffer_giftag(m_texture_constants.giftag, vu.tptr); - // iaddi vi08, vi08, 0x1 | nop 123 - vu.tptr = vu.tptr + 1; - L6: - // iaddi vi01, vi01, -0x1 | nop 124 - loop_idx = loop_idx + -1; - // lq.xyzw vf20, 2(vi03) | nop 125 - lq_buffer(Mask::xyzw, res0, vu.dbuf_read_a + 2); - // lq.xyzw vf21, 2(vi04) | nop 126 - lq_buffer(Mask::xyzw, res1, vu.dbuf_read_b + 2); - // lq.xyzw vf28, 0(vi03) | nop 127 - lq_buffer(Mask::xyzw, cout0, vu.dbuf_read_a); - // lq.xyzw vf16, 1(vi03) | nop 128 - lq_buffer(Mask::xyzw, vtx0, vu.dbuf_read_a + 1); - // lq.xyzw vf29, 0(vi04) | ftoi4.xyzw vf20, vf20 129 - res0.ftoi4(Mask::xyzw, res0); lq_buffer(Mask::xyzw, cout1, vu.dbuf_read_b); - // lq.xyzw vf17, 1(vi04) | ftoi4.xyzw vf21, vf21 130 - res1.ftoi4(Mask::xyzw, res1); lq_buffer(Mask::xyzw, vtx1, vu.dbuf_read_b + 1); - // sq.xyzw vf28, 0(vi08) | nop 131 - sq_buffer(Mask::xyzw, cout0, vu.tptr); - // sq.xyzw vf16, 1(vi08) | nop 132 - sq_buffer(Mask::xyzw, vtx0, vu.tptr + 1); - // sq.xyzw vf20, 2(vi08) | nop 133 - sq_buffer(Mask::xyzw, res0, vu.tptr + 2); - // sq.xyzw vf29, 3(vi08) | nop 134 - sq_buffer(Mask::xyzw, cout1, vu.tptr + 3); - // sq.xyzw vf17, 4(vi08) | nop 135 - sq_buffer(Mask::xyzw, vtx1, vu.tptr + 4); - // sq.xyzw vf21, 5(vi08) | nop 136 - sq_buffer(Mask::xyzw, res1, vu.tptr + 5); - - // iaddi vi03, vi03, 0x3 | nop 137 - vu.dbuf_read_a = vu.dbuf_read_a + 3; - // iaddi vi04, vi04, 0x3 | nop 138 - vu.dbuf_read_b = vu.dbuf_read_b + 3; - // BRANCH! - // ibgtz vi01, L6 | nop 139 - bc = ((s16)loop_idx) > 0; - // iaddi vi08, vi08, 0x6 | nop 140 - vu.tptr = vu.tptr + 6; - if (bc) { goto L6; } - - // xgkick vi09 | nop 141 - xgkick(vu.tbase, render_state, prof); - // mtir vi08, vf03.x | nop 142 - // vu.tptr = vu.vf03.x_as_u16(); - vu.tptr = get_tbuf(); - // mtir vi09, vf03.x | nop 143 - // vu.vi09 = vu.vf03.x_as_u16(); - vu.tbase = get_tbuf(); - // jr vi12 | nop 144 - // ASSERT(false); - // mr32.xyzw vf03, vf03 | nop 145 - // vu.vf03.mr32(Mask::xyzw, vu.vf03); - swap_tbuf(); - // clang-format on -} - -void OceanTexture::xgkick(Vf* src, SharedRenderState* render_state, ScopedProfilerNode& prof) { - // KICK - m_hack_renderer.render_gif((const u8*)src, UINT32_MAX, render_state, prof); -} \ No newline at end of file diff --git a/game/graphics/opengl_renderer/shaders/ocean_common.frag b/game/graphics/opengl_renderer/shaders/ocean_common.frag new file mode 100644 index 0000000000..219aa8a76b --- /dev/null +++ b/game/graphics/opengl_renderer/shaders/ocean_common.frag @@ -0,0 +1,31 @@ +#version 430 core + +out vec4 color; + +in vec4 fragment_color; +in vec3 tex_coord; +uniform float color_mult; +uniform float alpha_mult; + +uniform vec4 fog_color; +uniform int bucket; + +in float fog; + +uniform sampler2D tex_T0; + +void main() { + vec4 T0 = texture(tex_T0, tex_coord.xy / tex_coord.z); + if (bucket == 0) { + color.xyz = fragment_color.xyz * T0.xyz; + color.w = fragment_color.w; + color.xyz *= 2; + color.xyz = mix(color.xyz, fog_color.xyz / 255., clamp(fog_color.w * (1 - fog), 0, 1)); + } else if (bucket == 1) { + color = fragment_color * T0; + color.xyzw *= 2; + } else if (bucket == 2) { + color = fragment_color * T0; + } + +} diff --git a/game/graphics/opengl_renderer/shaders/ocean_common.vert b/game/graphics/opengl_renderer/shaders/ocean_common.vert new file mode 100644 index 0000000000..c1779606ea --- /dev/null +++ b/game/graphics/opengl_renderer/shaders/ocean_common.vert @@ -0,0 +1,19 @@ +#version 430 core + +layout (location = 0) in vec3 position_in; +layout (location = 1) in vec4 rgba_in; +layout (location = 2) in vec3 tex_coord_in; +layout (location = 3) in uint fog_in; + +out vec4 fragment_color; +out vec3 tex_coord; +out float fog; + +void main() { + gl_Position = vec4((position_in.x - 0.5) * 16., -(position_in.y - 0.5) * 32, position_in.z * 2 - 1., 1.0); + // scissoring area adjust + gl_Position.y *= 512.0/448.0; + fragment_color = vec4(rgba_in.x, rgba_in.y, rgba_in.z, rgba_in.w * 2.); + tex_coord = tex_coord_in; + fog = float(fog_in) / 255.; +}