mirror of
https://github.com/open-goal/jak-project
synced 2026-08-05 01:30:22 -04:00
working in jak1
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user