mirror of
https://github.com/open-goal/jak-project
synced 2026-06-08 12:27:57 -04:00
jak2/3: implement ocean envmap (#4303)
Implements the envmap for the ocean generated by `ocean-method-89`/`ocean-method-88`. While the resulting envmap looks accurate compared to PCSX2 in Renderdoc, the end result does not seem 100% identical, but it is a big improvement over the default placeholder texture. Closes #3417
This commit is contained in:
@@ -59,6 +59,7 @@ set(RUNTIME_SOURCE
|
||||
graphics/opengl_renderer/loader/Loader.cpp
|
||||
graphics/opengl_renderer/loader/LoaderStages.cpp
|
||||
graphics/opengl_renderer/ocean/CommonOceanRenderer.cpp
|
||||
graphics/opengl_renderer/ocean/OceanEnvmap.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMid_PS2.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMid.cpp
|
||||
graphics/opengl_renderer/ocean/OceanMidAndFar.cpp
|
||||
|
||||
@@ -134,6 +134,8 @@ ShaderLibrary::ShaderLibrary(GameVersion version) {
|
||||
at(ShaderId::TIE_WIND) = {"tie_wind", version};
|
||||
at(ShaderId::SIMPLE_TEXTURE) = {"simple_texture", version};
|
||||
at(ShaderId::SLOW_TIME) = {"slow_time", version};
|
||||
at(ShaderId::OCEAN_ENVMAP) = {"ocean_envmap", version};
|
||||
at(ShaderId::OCEAN_ENVMAP_HAZE) = {"ocean_envmap_haze", version};
|
||||
|
||||
for (auto& shader : m_shaders) {
|
||||
ASSERT_MSG(shader.okay(), "error compiling shader");
|
||||
|
||||
@@ -67,6 +67,8 @@ enum class ShaderId {
|
||||
TIE_WIND = 40,
|
||||
SIMPLE_TEXTURE = 41,
|
||||
SLOW_TIME = 42,
|
||||
OCEAN_ENVMAP = 43,
|
||||
OCEAN_ENVMAP_HAZE = 44,
|
||||
MAX_SHADERS
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
#include "OceanEnvmap.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include "common/dma/gs.h"
|
||||
|
||||
#include "game/graphics/texture/TexturePool.h"
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
namespace {
|
||||
|
||||
/*!
|
||||
* check if a gif packet from a dma-buffer-add-gs-set contains a given register address
|
||||
*/
|
||||
bool scan_gs_set(const u8* data, const u32 size, GsRegisterAddress reg, u64* out) {
|
||||
if (size < 16) {
|
||||
return false;
|
||||
}
|
||||
GifTag tag(data);
|
||||
if (tag.flg() != GifTag::Format::PACKED) {
|
||||
return false;
|
||||
}
|
||||
u32 nreg = tag.nreg();
|
||||
u32 offset = 16;
|
||||
for (u32 loop = 0; loop < tag.nloop(); loop++) {
|
||||
for (u32 r = 0; r < nreg; r++) {
|
||||
if (offset + 16 > size) {
|
||||
return false;
|
||||
}
|
||||
if (tag.reg(r) == GifTag::RegisterDescriptor::AD) {
|
||||
u64 value;
|
||||
u8 addr;
|
||||
memcpy(&value, data + offset, sizeof(value));
|
||||
memcpy(&addr, data + offset + 8, sizeof(addr));
|
||||
if (addr == (u8)reg) {
|
||||
*out = value;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
offset += 16;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_untextured_draw(const u8* data, u32 size) {
|
||||
if (size < 16) {
|
||||
return false;
|
||||
}
|
||||
GifTag tag(data);
|
||||
if (!tag.pre()) {
|
||||
return false;
|
||||
}
|
||||
return !GsPrim(tag.prim()).tme();
|
||||
}
|
||||
|
||||
bool find_sky_color(DmaFollower dma, u32 next_bucket, u8 out[4]) {
|
||||
for (int i = 0; i < 256 && dma.current_tag_offset() != next_bucket; i++) {
|
||||
auto d = dma.read_and_advance();
|
||||
if (d.size_bytes >= 32 && is_untextured_draw(d.data, d.size_bytes)) {
|
||||
out[0] = d.data[16 + 0];
|
||||
out[1] = d.data[16 + 4];
|
||||
out[2] = d.data[16 + 8];
|
||||
out[3] = d.data[16 + 12];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
OceanEnvmap::OceanEnvmap(const std::string& name, int my_id, int batch_size)
|
||||
: DirectRenderer(name, my_id, batch_size),
|
||||
m_first_pass_fb(ENVMAP_WIDTH, ENVMAP_HEIGHT, GL_UNSIGNED_INT_8_8_8_8_REV),
|
||||
m_envmap_fb(ENVMAP_WIDTH, ENVMAP_HEIGHT, GL_UNSIGNED_INT_8_8_8_8_REV) {}
|
||||
|
||||
static void make_single_level_linear(const GLuint tex) {
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
void OceanEnvmap::init_textures(TexturePool& pool, GameVersion version) {
|
||||
TextureInput in;
|
||||
in.w = ENVMAP_WIDTH;
|
||||
in.h = ENVMAP_HEIGHT;
|
||||
in.debug_page_name = "PC-OCEAN-ENVMAP";
|
||||
|
||||
in.gpu_texture = m_envmap_fb.texture();
|
||||
in.debug_name = "ocean-envmap";
|
||||
in.id = pool.allocate_pc_port_texture(version);
|
||||
m_envmap_gpu_tex = pool.give_texture_and_load_to_vram(in, ENVMAP_VRAM_ADDR);
|
||||
|
||||
make_single_level_linear(m_first_pass_fb.texture());
|
||||
make_single_level_linear(m_envmap_fb.texture());
|
||||
|
||||
glGenVertexArrays(1, &m_radial_vao);
|
||||
glBindVertexArray(m_radial_vao);
|
||||
glGenBuffers(1, &m_radial_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_radial_vbo);
|
||||
const float verts[8] = {-1.f, -1.f, -1.f, 1.f, 1.f, -1.f, 1.f, 1.f};
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), nullptr);
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
glGenVertexArrays(1, &m_haze_vao);
|
||||
glBindVertexArray(m_haze_vao);
|
||||
glGenBuffers(1, &m_haze_vbo);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_haze_vbo);
|
||||
glEnableVertexAttribArray(0);
|
||||
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)nullptr);
|
||||
glEnableVertexAttribArray(1);
|
||||
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 6, (void*)(2 * sizeof(float)));
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
}
|
||||
|
||||
void OceanEnvmap::render_haze(const u8* gif_data, u32 size, SharedRenderState* render_state) {
|
||||
if (size < 16) {
|
||||
return;
|
||||
}
|
||||
const float x_off = m_prim_buffer.x_off;
|
||||
const float y_off = m_prim_buffer.y_off;
|
||||
|
||||
GifTag tag(gif_data);
|
||||
if (tag.flg() != GifTag::Format::PACKED) {
|
||||
return;
|
||||
}
|
||||
const u32 nreg = tag.nreg();
|
||||
|
||||
std::vector<float> verts;
|
||||
verts.reserve(tag.nloop() * 2 * 6);
|
||||
float cur[4] = {1.f, 1.f, 1.f, 1.f};
|
||||
u32 offset = 16;
|
||||
for (u32 loop = 0; loop < tag.nloop(); loop++) {
|
||||
for (u32 r = 0; r < nreg; r++) {
|
||||
if (offset + 16 > size) {
|
||||
break;
|
||||
}
|
||||
const u8* d = gif_data + offset;
|
||||
switch (tag.reg(r)) {
|
||||
case GifTag::RegisterDescriptor::RGBAQ:
|
||||
cur[0] = d[0] / 255.f;
|
||||
cur[1] = d[4] / 255.f;
|
||||
cur[2] = d[8] / 255.f;
|
||||
cur[3] = d[12] / 255.f;
|
||||
break;
|
||||
case GifTag::RegisterDescriptor::XYZF2: {
|
||||
u16 rawx, rawy;
|
||||
memcpy(&rawx, d + 0, 2);
|
||||
memcpy(&rawy, d + 4, 2);
|
||||
float px = rawx / 65536.f + x_off;
|
||||
float py = rawy / 65536.f + y_off;
|
||||
float ndc_x = (px - 0.453125f) * 64.f;
|
||||
float ndc_y = (py - 0.5f + (2.25f / 64.f)) * 64.f;
|
||||
verts.insert(verts.end(), {ndc_x, ndc_y, cur[0], cur[1], cur[2], cur[3] * 2.f});
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
offset += 16;
|
||||
}
|
||||
}
|
||||
if (verts.size() < 6 * 3) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
render_state->shaders[ShaderId::OCEAN_ENVMAP_HAZE].activate();
|
||||
glBindVertexArray(m_haze_vao);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, m_haze_vbo);
|
||||
glBufferData(GL_ARRAY_BUFFER, verts.size() * sizeof(float), verts.data(), GL_STREAM_DRAW);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, (GLsizei)(verts.size() / 6));
|
||||
glBindVertexArray(0);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||
|
||||
if (depth) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void OceanEnvmap::render_envmap(SharedRenderState* render_state) {
|
||||
GLboolean blend = glIsEnabled(GL_BLEND);
|
||||
GLboolean depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
FramebufferTexturePairContext ctxt(m_envmap_fb);
|
||||
glViewport(0, 0, ENVMAP_WIDTH, ENVMAP_HEIGHT);
|
||||
auto shader = &render_state->shaders[ShaderId::OCEAN_ENVMAP];
|
||||
shader->activate();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
glBindTexture(GL_TEXTURE_2D, m_first_pass_fb.texture());
|
||||
glBindVertexArray(m_radial_vao);
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
glBindVertexArray(0);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
if (blend) {
|
||||
glEnable(GL_BLEND);
|
||||
}
|
||||
if (depth_test) {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
||||
}
|
||||
|
||||
void OceanEnvmap::handle_ocean_envmap_jak2(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof) {
|
||||
u8 sky[4] = {0, 0, 0, 255};
|
||||
find_sky_color(dma, render_state->next_bucket, sky);
|
||||
|
||||
auto scissor_backup = m_scissor;
|
||||
|
||||
bool active = false;
|
||||
bool registered = false;
|
||||
int setup64_count = 0;
|
||||
|
||||
for (int guard = 0; guard < 4096; guard++) {
|
||||
DmaFollower peek = dma;
|
||||
if (peek.current_tag_offset() == render_state->next_bucket) {
|
||||
break;
|
||||
}
|
||||
auto next = peek.read_and_advance();
|
||||
u64 scissor = 0;
|
||||
u64 frame = 0;
|
||||
bool has_scissor =
|
||||
scan_gs_set(next.data, next.size_bytes, GsRegisterAddress::SCISSOR_1, &scissor);
|
||||
bool has_frame = scan_gs_set(next.data, next.size_bytes, GsRegisterAddress::FRAME_1, &frame);
|
||||
if (has_scissor && GsScissor(scissor).x1() == 127) {
|
||||
break;
|
||||
}
|
||||
bool is_reset = has_scissor && GsScissor(scissor).x1() != ENVMAP_WIDTH - 1;
|
||||
|
||||
auto data = dma.read_and_advance();
|
||||
|
||||
if (has_scissor && GsScissor(scissor).x1() == ENVMAP_WIDTH - 1) {
|
||||
setup64_count++;
|
||||
u32 page_tbp = has_frame ? GsFrame(frame).fbp() << 5 : 0;
|
||||
if (active) {
|
||||
flush_pending(render_state, prof);
|
||||
}
|
||||
m_fb_ctxt.reset();
|
||||
reset_state();
|
||||
if (setup64_count == 1) {
|
||||
m_offscreen_mode = true;
|
||||
m_fb_ctxt.emplace(m_first_pass_fb);
|
||||
glViewport(0, 0, ENVMAP_WIDTH * 2, ENVMAP_HEIGHT * 2);
|
||||
glClearColor(sky[0] / 255.f, sky[1] / 255.f, sky[2] / 255.f, sky[3] / 255.f);
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
active = true;
|
||||
} else if (setup64_count == 2) {
|
||||
m_offscreen_mode = false;
|
||||
if (page_tbp) {
|
||||
render_state->texture_pool->move_existing_to_vram(m_envmap_gpu_tex, page_tbp);
|
||||
registered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (active && setup64_count == 1 && !is_reset && data.size_bytes >= 16 &&
|
||||
data.vifcode1().kind == VifCode::Kind::DIRECT &&
|
||||
!is_untextured_draw(data.data, data.size_bytes)) {
|
||||
render_gif(data.data, data.size_bytes, render_state, prof);
|
||||
}
|
||||
|
||||
// "haze" effect
|
||||
if (active && setup64_count == 1 && !is_reset && data.size_bytes >= 16 &&
|
||||
is_untextured_draw(data.data, data.size_bytes) &&
|
||||
GsPrim(GifTag(data.data).prim()).kind() == GsPrim::Kind::TRI_STRIP) {
|
||||
flush_pending(render_state, prof);
|
||||
render_haze(data.data, data.size_bytes, render_state);
|
||||
reinitialize_gl_state();
|
||||
}
|
||||
}
|
||||
|
||||
if (active) {
|
||||
flush_pending(render_state, prof);
|
||||
m_fb_ctxt.reset();
|
||||
m_offscreen_mode = false;
|
||||
render_envmap(render_state);
|
||||
m_scissor = scissor_backup;
|
||||
if (!registered) {
|
||||
render_state->texture_pool->move_existing_to_vram(m_envmap_gpu_tex, ENVMAP_VRAM_ADDR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OceanEnvmap::draw_debug_window() {
|
||||
ImGui::Text("first pass envmap");
|
||||
ImGui::Image((ImTextureID)(intptr_t)m_first_pass_fb.texture(),
|
||||
ImVec2(ENVMAP_WIDTH * 2, ENVMAP_HEIGHT * 2));
|
||||
ImGui::SameLine();
|
||||
ImGui::Image((ImTextureID)(intptr_t)m_envmap_fb.texture(),
|
||||
ImVec2(ENVMAP_WIDTH * 2, ENVMAP_HEIGHT * 2));
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "game/graphics/opengl_renderer/DirectRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/opengl_utils.h"
|
||||
|
||||
/*!
|
||||
* This class generates the ocean envmap texture using the sky + time of day (ocean-method-89).
|
||||
*/
|
||||
class OceanEnvmap : public DirectRenderer {
|
||||
public:
|
||||
// (-> *ocean-envmap-texture-base* vram-block)
|
||||
static constexpr int ENVMAP_VRAM_ADDR = 0xf80;
|
||||
static constexpr int ENVMAP_WIDTH = 64;
|
||||
static constexpr int ENVMAP_HEIGHT = 64;
|
||||
|
||||
OceanEnvmap(const std::string& name, int my_id, int batch_size);
|
||||
void init_textures(TexturePool& pool, GameVersion version) override;
|
||||
void handle_ocean_envmap_jak2(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof);
|
||||
void draw_debug_window() override;
|
||||
|
||||
private:
|
||||
FramebufferTexturePair m_first_pass_fb;
|
||||
FramebufferTexturePair m_envmap_fb;
|
||||
std::optional<FramebufferTexturePairContext> m_fb_ctxt;
|
||||
GpuTexture* m_envmap_gpu_tex = nullptr;
|
||||
|
||||
// ocean-method-85
|
||||
GLuint m_haze_vao = 0;
|
||||
GLuint m_haze_vbo = 0;
|
||||
void render_haze(const u8* gif_data, u32 size, SharedRenderState* render_state);
|
||||
|
||||
// ocean-method-83
|
||||
GLuint m_radial_vao = 0;
|
||||
GLuint m_radial_vbo = 0;
|
||||
void render_envmap(SharedRenderState* render_state);
|
||||
};
|
||||
@@ -3,15 +3,23 @@
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
OceanMidAndFar::OceanMidAndFar(const std::string& name, int my_id)
|
||||
: BucketRenderer(name, my_id), m_direct(name, my_id, 4096), m_texture_renderer(true) {}
|
||||
: BucketRenderer(name, my_id),
|
||||
m_direct(name, my_id, 4096),
|
||||
m_envmap_renderer(name + "-envmap", my_id, 4096),
|
||||
m_texture_renderer(true) {}
|
||||
|
||||
void OceanMidAndFar::draw_debug_window() {
|
||||
if (ImGui::TreeNode("envmap")) {
|
||||
m_envmap_renderer.draw_debug_window();
|
||||
ImGui::TreePop();
|
||||
}
|
||||
m_texture_renderer.draw_debug_window();
|
||||
m_direct.draw_debug_window();
|
||||
}
|
||||
|
||||
void OceanMidAndFar::init_textures(TexturePool& pool, GameVersion version) {
|
||||
m_texture_renderer.init_textures(pool, version);
|
||||
m_envmap_renderer.init_textures(pool, version);
|
||||
}
|
||||
|
||||
void OceanMidAndFar::render(DmaFollower& dma,
|
||||
@@ -96,15 +104,16 @@ void OceanMidAndFar::render_jak2(DmaFollower& dma,
|
||||
}
|
||||
m_direct.reset_state();
|
||||
|
||||
// TODO handle ocean::89 and ocean::79
|
||||
// handle_ocean_89_jak2(dma, render_state, prof);
|
||||
{
|
||||
auto p = prof.make_scoped_child("envmap");
|
||||
m_envmap_renderer.handle_ocean_envmap_jak2(dma, render_state, p);
|
||||
}
|
||||
|
||||
{
|
||||
auto p = prof.make_scoped_child("texture");
|
||||
m_texture_renderer.handle_ocean_texture_jak2(dma, render_state, p);
|
||||
}
|
||||
|
||||
// handle_ocean_79_jak2(dma, render_state, prof);
|
||||
handle_ocean_far(dma, render_state, prof);
|
||||
m_direct.flush_pending(render_state, prof);
|
||||
|
||||
@@ -188,8 +197,4 @@ void OceanMidAndFar::handle_ocean_mid(DmaFollower& dma,
|
||||
while (!is_end_tag(dma.current_tag(), dma.current_tag_vifcode0(), dma.current_tag_vifcode1())) {
|
||||
dma.read_and_advance();
|
||||
}
|
||||
}
|
||||
|
||||
void handle_ocean_89_jak2(DmaFollower&, SharedRenderState*, ScopedProfilerNode&) {}
|
||||
|
||||
void handle_ocean_79_jak2(DmaFollower&, SharedRenderState*, ScopedProfilerNode&) {}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/DirectRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/ocean/OceanEnvmap.h"
|
||||
#include "game/graphics/opengl_renderer/ocean/OceanMid.h"
|
||||
#include "game/graphics/opengl_renderer/ocean/OceanTexture.h"
|
||||
#include "game/graphics/opengl_renderer/opengl_utils.h"
|
||||
@@ -29,14 +30,9 @@ class OceanMidAndFar : public BucketRenderer {
|
||||
void handle_ocean_mid(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof);
|
||||
void handle_ocean_89_jak2(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof);
|
||||
void handle_ocean_79_jak2(DmaFollower& dma,
|
||||
SharedRenderState* render_state,
|
||||
ScopedProfilerNode& prof);
|
||||
|
||||
DirectRenderer m_direct;
|
||||
OceanEnvmap m_envmap_renderer;
|
||||
OceanTexture m_texture_renderer;
|
||||
OceanMid m_mid_renderer;
|
||||
};
|
||||
|
||||
@@ -584,13 +584,13 @@ void OceanTexture::run_L3_PC_jak2() {
|
||||
// iaddi vi01, vi01, -0x1 | ftoi0.xyzw vf19, vf19 78
|
||||
vtx3.ftoi0(Mask::xyzw, vtx3); loop_idx = loop_idx + -1;
|
||||
// sq.xyzw vf16, 1(vi06) | add.xyzw vf28, vf28, vf07 79
|
||||
cout0.add(Mask::xyzw, cout0, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1);
|
||||
cout0.add(Mask::xyzw, cout0, m_texture_constants.constants); sq_buffer(Mask::xyzw, vtx0, vu.dbuf_write + 1);
|
||||
// sq.xyzw vf17, 4(vi06) | add.xyzw vf29, vf29, vf07 80
|
||||
cout1.add(Mask::xyzw, cout1, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx1, vu.dbuf_write + 4);
|
||||
cout1.add(Mask::xyzw, cout1, m_texture_constants.constants); sq_buffer(Mask::xyzw, vtx1, vu.dbuf_write + 4);
|
||||
// sq.xyzw vf18, 7(vi06) | add.xyzw vf30, vf30, vf07 81
|
||||
cout2.add(Mask::xyzw, cout2, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx2, vu.dbuf_write + 7);
|
||||
cout2.add(Mask::xyzw, cout2, m_texture_constants.constants); sq_buffer(Mask::xyzw, vtx2, vu.dbuf_write + 7);
|
||||
// sq.xyzw vf19, 10(vi06) | add.xyzw vf31, vf31, vf07 82
|
||||
cout3.add(Mask::xyzw, cout3, m_texture_constants.cam_nrm); sq_buffer(Mask::xyzw, vtx3, vu.dbuf_write + 10);
|
||||
cout3.add(Mask::xyzw, cout3, m_texture_constants.constants); sq_buffer(Mask::xyzw, vtx3, vu.dbuf_write + 10);
|
||||
// lq.xyzw vf24, 1(vi05) | sub.zw vf28, vf01, vf00 83
|
||||
cout0.sub(Mask::zw, ones, vf00); lq_buffer(Mask::xyzw, nrm0, vu.in_ptr + 1);
|
||||
// lq.xyzw vf26, 5(vi05) | sub.zw vf29, vf01, vf00 84
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#version 410 core
|
||||
uniform sampler2D tex_T1;
|
||||
in vec2 tex_coord;
|
||||
out vec4 color;
|
||||
void main() {
|
||||
const float PI = 3.14159265358979;
|
||||
float u = tex_coord.x;
|
||||
float v = tex_coord.y;
|
||||
float theta = (0.5 - u) * 2.0 * PI;
|
||||
float t = 1.0 - abs(2.0 * v - 1.0);
|
||||
vec2 st = vec2(0.5) + t * 0.5 * vec2(sin(theta), cos(theta));
|
||||
color = texture(tex_T1, st);
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
#version 410 core
|
||||
layout (location = 0) in vec2 position_in;
|
||||
out vec2 tex_coord;
|
||||
void main() {
|
||||
gl_Position = vec4(position_in, 0.0, 1.0);
|
||||
tex_coord = (position_in + 1.0) * 0.5;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#version 410 core
|
||||
|
||||
in vec4 color;
|
||||
out vec4 out_color;
|
||||
|
||||
void main() {
|
||||
out_color = color;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
#version 410 core
|
||||
|
||||
layout (location = 0) in vec2 ndc_in;
|
||||
layout (location = 1) in vec4 color_in;
|
||||
|
||||
out vec4 color;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(ndc_in, 0.0, 1.0);
|
||||
color = color_in;
|
||||
}
|
||||
@@ -1167,11 +1167,9 @@
|
||||
(let* ((s4-0 (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
(s5-2 (-> s4-0 base))
|
||||
)
|
||||
;; TODO handle ocean::79 and ocean::89
|
||||
;; diasble tod ocean stuff
|
||||
;; (if (-> *time-of-day-context* sky)
|
||||
;; (ocean-method-89 this s4-0)
|
||||
;; )
|
||||
(if (-> *time-of-day-context* sky)
|
||||
(ocean-method-89 this s4-0)
|
||||
)
|
||||
(draw-ocean-texture this s4-0 (the-as int (-> this verts)))
|
||||
;; disable whatever this is
|
||||
;; (ocean-method-79 this s4-0)
|
||||
|
||||
@@ -1191,10 +1191,9 @@
|
||||
(let* ((s4-1 (-> *display* frames (-> *display* on-screen) global-buf))
|
||||
(s5-2 (-> s4-1 base))
|
||||
)
|
||||
;; og:preserve-this not-yet-implemented
|
||||
; (if (-> *time-of-day-context* sky)
|
||||
; (ocean-method-88 this s4-1)
|
||||
; )
|
||||
(if (-> *time-of-day-context* sky)
|
||||
(ocean-method-88 this s4-1)
|
||||
)
|
||||
(draw-ocean-texture this s4-1 (the-as int (-> this verts)))
|
||||
; (ocean-method-89 this s4-1)
|
||||
(init-buffer! this s4-1)
|
||||
|
||||
Reference in New Issue
Block a user