working in jak1

This commit is contained in:
water111
2025-06-18 19:36:53 -04:00
parent 31e32943f5
commit d1a3aa1761
9 changed files with 61 additions and 76 deletions
+2 -2
View File
@@ -108,7 +108,7 @@ void Profiler::draw_node(ProfilerNode& node, bool expand, int depth, float start
bool color_orange = false;
ImGui::PushStyleColor(ImGuiCol_Text, color);
auto str =
fmt::format("{:20s} {:.2f}ms {:6d} tri {:4d} draw", node.m_name, node.m_stats.duration * 1000,
fmt::format("{:20s} {:.3f}ms {:6d} tri {:4d} draw", node.m_name, node.m_stats.duration * 1000,
node.m_stats.triangles, node.m_stats.draw_calls);
if (node.m_children.empty()) {
ImGui::Text(" %s", str.c_str());
@@ -154,7 +154,7 @@ std::string Profiler::to_string() {
void ProfilerNode::to_string_helper(std::string& str, int depth) const {
str +=
fmt::format("{}{:.2f} ms {:30s}\n", std::string(depth, ' '), m_stats.duration * 1000, m_name);
fmt::format("{}{:.3f} ms {:30s}\n", std::string(depth, ' '), m_stats.duration * 1000, m_name);
for (const auto& child : m_children) {
child.to_string_helper(str, depth + 1);
}
@@ -326,7 +326,7 @@ void ShadowRenderer::render(DmaFollower& dma,
m_color.y() = g / 255.0f;
m_color.z() = b / 255.0f;
m_color.w() = a / 128.0f;
// fmt::print("rgba: {} {} {} {}\n", r, g, b, a);
// fmt::print("rgba: {}\n", m_color.to_string_aligned());
} else {
ASSERT_MSG(false, fmt::format("{} {}", next.vifcode0().print(), next.vifcode1().print()));
}
@@ -35,6 +35,7 @@ Shadow3::Shadow3(ShaderLibrary& shaders) {
m_uniforms.origin = glGetUniformLocation(id, "origin");
m_uniforms.top_plane = glGetUniformLocation(id, "top_plane");
m_uniforms.bottom_plane = glGetUniformLocation(id, "bottom_plane");
m_uniforms.scissor_top = glGetUniformLocation(id, "scissor_top");
}
std::vector<u8> temp(MAX_SHADER_BONE_VECTORS * sizeof(math::Vector4f));
@@ -52,7 +53,7 @@ Shadow3::~Shadow3() {
void Shadow3::setup_for_level(SharedRenderState* render_state, const LevelData* level_data) {
glBindVertexArray(m_opengl.vao);
glBindBuffer(GL_ARRAY_BUFFER, level_data->shadow_vertices);
glBindBuffer(GL_ARRAY_BUFFER, m_hacks ? m_opengl.debug_verts : level_data->shadow_vertices);
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
@@ -92,10 +93,10 @@ void Shadow3::setup_for_level(SharedRenderState* render_state, const LevelData*
}
namespace {
void set_uniform(GLuint uniform, const math::Vector3f& val) {
void set_uniform(GLint uniform, const math::Vector3f& val) {
glUniform3f(uniform, val.x(), val.y(), val.z());
}
void set_uniform(GLuint uniform, const math::Vector4f& val) {
void set_uniform(GLint uniform, const math::Vector4f& val) {
glUniform4f(uniform, val.x(), val.y(), val.z(), val.w());
}
@@ -112,21 +113,21 @@ void Shadow3::draw_model(SharedRenderState* render_state,
.bones = request->bones,
.model = request->model.model,
.vertices = &request->model.level->level->shadow_data.vertices,
.flags = request->flags,
.scissor_top = request->scissor_top,
.debug_highlight_tri = m_debug_tri,
};
calc_shadow_indices(input, &m_cpu_workspace, &m_cpu_output);
glBindBuffer(GL_UNIFORM_BUFFER, m_opengl.bones_buffer);
glBindBufferRange(GL_UNIFORM_BUFFER, 1, m_opengl.bones_buffer,
sizeof(math::Vector4f) * request->bone_idx, 128 * 16 * 4);
const auto* geo = request->model.model;
// const auto* geo = request->model.model;
// printf("draw %s\n", geo->name.c_str());
set_uniform(m_uniforms.origin, request->origin);
set_uniform(m_uniforms.top_plane, request->top_plane);
set_uniform(m_uniforms.bottom_plane, request->bottom_plane);
glUniform1i(m_uniforms.scissor_top, request->scissor_top);
// glDrawElements(GL_TRIANGLES, m_cpu_output.num_indices, GL_UNSIGNED_INT, nullptr);
if (m_hacks) {
auto* model = request->model.model;
int num_verts = model->num_one_bone_vertices + model->num_two_bone_vertices;
@@ -230,14 +231,16 @@ void Shadow3::draw_model(SharedRenderState* render_state,
void Shadow3::finish(SharedRenderState* render_state, ScopedProfilerNode& prof) {
// finally, draw shadow.
if (!m_hacks) {
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_FALSE);
// glStencilFunc(GL_GREATER, 0, 0);
glStencilFunc(GL_NOTEQUAL, 0, 0xFF);
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
glDepthFunc(GL_ALWAYS);
glEnable(GL_BLEND);
glBlendFuncSeparate(GL_ONE, GL_ONE, GL_ONE, GL_ZERO);
glColorMask(true, true, true, false);
glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
m_full_screen_draw.draw(math::Vector4f(0.5, 0.4, 0.3, 0.5), render_state, prof);
glBlendEquation(GL_FUNC_ADD);
glBlendFuncSeparate(GL_DST_COLOR, GL_ZERO, GL_ONE, GL_ZERO);
m_full_screen_draw.draw(m_color, render_state, prof);
}
// restore
@@ -270,7 +273,6 @@ void Shadow3::flush_requests(SharedRenderState* render_state, ScopedProfilerNode
for (auto& c : m_level_chains) {
if (!c.head)
continue;
// printf("in level %s\n", c.level->level->level_name.c_str());
setup_for_level(render_state, c.level);
ShadowRequest* iter = c.head;
while (iter) {
@@ -309,9 +311,7 @@ void Shadow3::render_jak1(DmaFollower& dma,
SharedRenderState* render_state,
ScopedProfilerNode& prof) {
m_did_first_time_setup = false;
while (dma.current_tag_offset() != render_state->next_bucket) {
// auto dmatag = dma.current_tag();
auto data = dma.read_and_advance();
if (data.vifcode0().kind == VifCode::Kind::PC_PORT) {
u32 next = data.data_offset;
@@ -330,23 +330,15 @@ void Shadow3::render_jak1(DmaFollower& dma,
printf(" SKIP: no model data\n");
continue;
}
/*
* (shdf00) ;; unused
(disable-fade)
(shdf02) ;; only set, never used.
(shdf03)
(shdf04) ;; unused
(disable-draw)
*/
constexpr u32 kCullWhenUnderPlane = 1;
constexpr u32 kDisableFade = 2;
// constexpr u32 kDisableFade = 2;
constexpr u32 kAbsolutePlanes = 4;
constexpr u32 kFlag3 = 8;
constexpr u32 kFlag4 = 16;
constexpr u32 kUpperClip = 8;
// constexpr u32 kFlag4 = 16;
constexpr u32 kDisableDraw = 32;
if (game_request.settings.flags & kDisableDraw) {
printf(" SKIP: disable flag set\n");
continue;
}
@@ -380,7 +372,9 @@ void Shadow3::render_jak1(DmaFollower& dma,
request.origin = game_request.settings.center +
game_request.settings.shadow_dir * game_request.settings.dist_to_locus;
request.bones = g_ee_main_mem + game_request.mtx;
request.flags = game_request.settings.flags;
request.scissor_top = game_request.settings.flags & kUpperClip;
request.color = game_request.color;
m_color = request.color;
// copy bones to buffer
constexpr int in_stride = 8 * 4 * sizeof(float);
@@ -397,8 +391,6 @@ void Shadow3::render_jak1(DmaFollower& dma,
request.top_plane = game_request.settings.top_plane;
request.bottom_plane = game_request.settings.bot_plane;
if (!(kAbsolutePlanes & game_request.settings.flags)) {
// printf("relative plane mode, base is %f, move by %f\n",
// -request.bottom_plane.w() / 4096.0, game_request.settings.center.y() / 4096.0);
// in relative planes mode, the height of the plane is adjusted to be relative to the
// height of the center, so the planes move and down with the model
request.top_plane.w() -= game_request.settings.center.y();
@@ -413,7 +405,6 @@ void Shadow3::render_jak1(DmaFollower& dma,
if (render_state->camera_pos.xyz().dot(request.bottom_plane.xyz()) +
request.bottom_plane.w() <
0) {
// printf(" SKIP: camera below lower clipping plane.\n");
m_next_request--;
continue;
}
@@ -425,21 +416,10 @@ void Shadow3::render_jak1(DmaFollower& dma,
// detect if the origin is below the clipping plane and if so, move it up.
const float dot = request.bottom_plane.xyz().dot(request.origin);
if (dot + request.bottom_plane.w() > 0) {
// printf(" the origin is below the clipping plane, moving it up.\n");
// printf(" center was %s\n",
// game_request.settings.center.to_string_aligned().c_str()); printf(" dir was %s\n",
// game_request.settings.shadow_dir.to_string_aligned().c_str()); printf(" locus %f\n",
// game_request.settings.dist_to_locus); printf(" bottom plane was %s\n",
// game_request.settings.bot_plane.to_string_aligned().c_str());
// printf(" adjusted bottom plane was %s\n",
// request.bottom_plane.to_string_aligned().c_str());
// printf(" abs flag %d\n", game_request.settings.flags & kAbsolutePlanes);
request.bottom_plane.w() = -dot;
}
const auto& cam_rot = render_state->camera_rot;
const auto& cam_pos = render_state->camera_pos;
request.light_dir = game_request.settings.shadow_dir;
@@ -457,26 +437,10 @@ void Shadow3::render_jak1(DmaFollower& dma,
return math::Vector4f(xyz.x(), xyz.y(), xyz.z(), in.w() - xyz.dot(cam_rot[3].xyz()));
};
// printf("plane offset before: %f\n",
// game_request.settings.center.dot(request.bottom_plane.xyz()) +
// request.bottom_plane.w());
request.light_dir = rotate(request.light_dir);
request.top_plane = rotate_plane(request.top_plane);
request.bottom_plane = rotate_plane(request.bottom_plane);
request.origin = transform(request.origin);
math::Vector3f up_rt_w = math::Vector3f(0, 1, 0);
math::Vector3f up_rt_cam = rotate(up_rt_w);
// printf("ups: %f\n", up_rt_cam.dot(request.bottom_plane.xyz()));
// printf("plane offset after: %f\n",
// transform(game_request.settings.center).dot(request.bottom_plane.xyz()) +
// request.bottom_plane.w());
// printf("rot3: %s\n", cam_rot[3].to_string_aligned().c_str());
// printf(" 2: %s\n", cam_pos.to_string_aligned().c_str());
// printf(" origin: %s\n", (request.origin / 4096.f).to_string_aligned().c_str());
}
}
}
@@ -20,6 +20,7 @@ static_assert(sizeof(Jak1ShadowSettings) == 5 * 16);
struct Jak1ShadowRequest {
u8 dma[16];
Jak1ShadowSettings settings;
math::Vector4f color;
u32 geo_name;
u32 mtx;
u32 num_joints;
@@ -39,10 +40,11 @@ class Shadow3 {
math::Vector<float, 3> origin;
math::Vector4f top_plane, bottom_plane;
math::Vector3f light_dir;
math::Vector4f color;
ShadowRequest* next = nullptr;
const u8* bones = nullptr;
u32 bone_idx = 0;
u32 flags = 0;
bool scissor_top = false;
};
struct LevelChain {
@@ -73,14 +75,15 @@ class Shadow3 {
} m_opengl;
struct {
GLuint hvdf_offset = 0;
GLuint fog_constants = 0;
GLuint perspective_matrix = 0;
GLuint camera_rot = 0;
GLuint debug_color = 0;
GLuint bottom_plane = 0;
GLuint top_plane = 0;
GLuint origin = 0;
GLint hvdf_offset = 0;
GLint fog_constants = 0;
GLint perspective_matrix = 0;
GLint camera_rot = 0;
GLint debug_color = 0;
GLint bottom_plane = 0;
GLint top_plane = 0;
GLint origin = 0;
GLint scissor_top = 0;
} m_uniforms;
bool m_did_first_time_setup = false;
@@ -92,4 +95,5 @@ class Shadow3 {
ShadowCPUWorkspace m_cpu_workspace;
ShadowCPUOutput m_cpu_output;
FullScreenDraw m_full_screen_draw;
math::Vector4f m_color;
};
@@ -62,7 +62,7 @@ void transform_vertices(const ShadowCPUInput& input, ShadowCPUWorkspace* work) {
* of casting shadows on the "wrong side of the ground", and reduces fill.
*/
void calc_dual_verts(const ShadowCPUInput& input, ShadowCPUWorkspace* work) {
int num_verts = input.model->num_one_bone_vertices + input.model->num_two_bone_vertices;
const int num_verts = input.model->num_one_bone_vertices + input.model->num_two_bone_vertices;
for (int i = 0; i < num_verts; i++) {
math::Vector4f origin(input.origin.x(), input.origin.y(), input.origin.z(), 1.f);
math::Vector4f p = work->vertices[i];
@@ -77,12 +77,23 @@ void calc_dual_verts(const ShadowCPUInput& input, ShadowCPUWorkspace* work) {
* reduces fill.
*/
void scissor_top(const ShadowCPUInput& input, ShadowCPUWorkspace* work) {
// TODO
const int num_verts = input.model->num_one_bone_vertices + input.model->num_two_bone_vertices;
for (int i = 0; i < num_verts; i++) {
auto& original_vertex = work->vertices[i];
const auto& dual_vertex = work->dual_vertices[i];
const float above = original_vertex.dot(input.top_plane);
if (above > 0) {
const math::Vector4f offset = dual_vertex - original_vertex;
float scale = above / offset.xyz().dot(input.top_plane.xyz());
original_vertex -= offset * scale;
}
}
}
/**
* Clip against the near plane. I'm not sure why this is needed, but it may be another fill-reducing
* trick, or maybe just allows them to avoid scissoring against the near plane in the VU program.
* trick, or maybe just allows them to avoid scissoring against the near plane in the VU program?
* Either way, it seems like this isn't really needed.
*/
void scissor_edges(const ShadowCPUInput& input, ShadowCPUWorkspace* work) {
// TODO
@@ -265,7 +276,9 @@ void calc_shadow_indices(const ShadowCPUInput& input,
transform_vertices(input, work);
calc_dual_verts(input, work);
scissor_top(input, work);
if (input.scissor_top) {
scissor_top(input, work);
}
scissor_edges(input, work);
find_facing_single_tris(input, work, output, input.model->single_tris);
find_single_edges(input, work, output);
@@ -9,7 +9,7 @@ struct ShadowCPUInput {
const u8* bones = nullptr;
const tfrag3::ShadowModel* model = nullptr;
std::vector<tfrag3::ShadowVertex>* vertices = nullptr;
u32 flags = 0;
bool scissor_top = false;
int debug_highlight_tri = 0;
};
@@ -15,6 +15,7 @@ uniform vec3 debug_color;
uniform vec4 bottom_plane;
uniform vec4 top_plane;
uniform vec3 origin;
uniform bool scissor_top;
// output
out vec4 vtx_color;
@@ -48,7 +49,6 @@ vec4 dual(vec4 p, vec4 plane) {
}
vec4 scissor(vec4 p, vec4 plane) {
return p;
float plane_offset = dot(p, plane);
if (plane_offset > 0) {
vec4 offset = vec4(origin, 1) - p;
@@ -77,7 +77,9 @@ void main() {
if ((flags & uint(1)) != 0) {
vtx_pos = dual(vtx_pos, bottom_plane);
} else {
vtx_pos = scissor(vtx_pos, top_plane);
if (scissor_top) {
vtx_pos = scissor(vtx_pos, top_plane);
}
}
}
+2 -1
View File
@@ -42,7 +42,7 @@
(define *ripple-force-generic* #f)
;; when set, use the rewritten PC shadow render (faster)
(define *use-pc-shadow* #f)
(define *use-pc-shadow* #t)
;; use rewritten bones math (GOAL asm instead of mips2c)
(define *use-new-bones* #t)
@@ -724,6 +724,7 @@
(set! (-> pse geo-name) (-> sgeo name))
(set! (-> pse mtx) mtx)
(set! (-> pse num-joints) (-> sgeo header num-joints))
(vector-copy! (-> pse color) (-> *time-of-day-context* current-shadow-color))
;; set up linked list.
(let* ((run (-> *pc-shadow-queue* run (-> *pc-shadow-queue* cur-run)))
@@ -110,6 +110,7 @@
(
(dma-next dma-packet :inline)
(settings shadow-settings :inline)
(color vector :inline)
(geo-name string) ;; name to send to PC renderer
(mtx pointer) ;; pointer to DMA memory that will contain bones
(num-joints uint32) ;; number of joints needed for shadow