jak-project/game/graphics/opengl_renderer/ocean/OceanNear.h
Hat Kid 3d08d079c9
jak2: ocean renderer (#2142)
Initial implementation of the `ocean-mid`, `ocean-far` and `ocean-near`
renderers for Jak 2.

There's still a few things to sort out, mainly:

- [x] ~Backwards compatibility with Jak 1. The only thing that currently
stands in the way of that is figuring out a clean way to "un-hardcode"
the texture base pointer in C++ without creating a completely separate
`OceanTexture` class for Jak 2. One thing I thought of would be
modifying `BucketRenderer`'s virtual `init_textures` method to also pass
the `GameVersion`, but I'm not sure if there's a better way.~
- [x] ~The sudden transition from `ocean-near` to `ocean-mid`. Not sure
why it's happening or how to fix it.~
- [x] The ocean has two new methods in Jak 2, `ocean::89` and
`ocean::79`, one of which seems to be related to time of day sky colors.
~Even without them implemented, the end result looks quite close, so we
may be able to skip them?~ `ocean::89` generates `ocean-mid` envmap
textures, so it will likely be required, but will not be handled right
now.

Reverted the VU prologue removals because it made the tests fail.
2023-01-22 18:07:46 -05:00

137 lines
3.5 KiB
C++

#pragma once
#include "game/common/vu.h"
#include "game/graphics/opengl_renderer/BucketRenderer.h"
#include "game/graphics/opengl_renderer/ocean/CommonOceanRenderer.h"
#include "game/graphics/opengl_renderer/ocean/OceanTexture.h"
class OceanNear : public BucketRenderer {
public:
OceanNear(const std::string& name, int my_id);
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
void render_jak1(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof);
void render_jak2(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof);
void draw_debug_window() override;
void init_textures(TexturePool& pool, GameVersion version) override;
private:
void run_call0_vu2c();
void run_call0_vu2c_jak2();
void run_call39_vu2c();
void run_call39_vu2c_jak2();
void run_L15_vu2c();
void run_L15_vu2c_jak2();
void run_L21_vu2c();
void run_L21_vu2c_jak2();
void run_L23_vu2c();
void run_L25_vu2c();
void run_L25_vu2c_jak2();
void run_L30_vu2c();
void run_L32_vu2c();
OceanTexture m_texture_renderer;
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;
void xgkick(u16 addr);
u16 xtop() {
m_buffer_toggle = !m_buffer_toggle;
return get_vu_buffer();
}
u16 get_upload_buffer() {
if (m_buffer_toggle) {
return VU1_INPUT_BUFFER_OFFSET;
} else {
return VU1_INPUT_BUFFER_BASE;
}
}
u16 get_vu_buffer() {
if (!m_buffer_toggle) {
return VU1_INPUT_BUFFER_OFFSET;
} else {
return VU1_INPUT_BUFFER_BASE;
}
}
void lq_buffer(Mask mask, Vf& dest, u16 addr) {
ASSERT(addr < 1024);
for (int i = 0; i < 4; i++) {
if ((u64)mask & (1 << i)) {
dest[i] = m_vu_data[addr].data[i];
}
}
}
void sq_buffer(Mask mask, const Vf& val, u16 addr) {
ASSERT(addr < 1024);
for (int i = 0; i < 4; i++) {
if ((u64)mask & (1 << i)) {
m_vu_data[addr].data[i] = val[i];
}
}
}
void ilw_buffer(Mask mask, u16& dest, u16 addr) {
ASSERT(addr < 1024);
switch (mask) {
case Mask::x:
dest = m_vu_data[addr].x_as_u16();
break;
case Mask::y:
dest = m_vu_data[addr].y_as_u16();
break;
case Mask::z:
dest = m_vu_data[addr].z_as_u16();
break;
case Mask::w:
dest = m_vu_data[addr].w_as_u16();
break;
default:
ASSERT(false);
}
}
void isw_buffer(Mask mask, u16 src, u16 addr) {
ASSERT(addr < 1024);
u32 val32 = src;
switch (mask) {
case Mask::x:
memcpy(&m_vu_data[addr].data[0], &val32, 4);
break;
case Mask::y:
memcpy(&m_vu_data[addr].data[1], &val32, 4);
break;
case Mask::z:
memcpy(&m_vu_data[addr].data[2], &val32, 4);
break;
case Mask::w:
memcpy(&m_vu_data[addr].data[3], &val32, 4);
break;
default:
ASSERT(false);
}
}
Vf m_vu_data[1024];
struct Vu {
const Vf vf00;
Accumulator acc;
Vf vf01, vf02, vf03, vf04, vf05, vf06, vf07, vf08, vf09, vf10, vf11, vf12, vf13, vf14, vf15,
vf16, vf17, vf18, vf19, vf20, vf21, vf22, vf23, vf24, vf25, vf26, vf27, vf28, vf29, vf30,
vf31;
u16 vi01, vi02, vi03, vi04, vi05, vi06, vi07, vi08, vi09, vi10, vi11, vi12, vi13, vi14;
float P, Q;
Vu() : vf00(0, 0, 0, 1) {}
} vu;
};