mirror of
https://github.com/open-goal/jak-project
synced 2026-08-05 09:34:51 -04:00
shadows pretty close, something wrong with plane calc in jak2 keira, maybe flags
This commit is contained in:
@@ -242,6 +242,10 @@ std::vector<ShadowData> extract_jak2_shadow_data(const LinkedObjectFile& file,
|
||||
} else if (version == 1) {
|
||||
u32 num_joints = read_plain_data_field<u32>(tr, "num-joints", dts);
|
||||
uint32_t num_fragments = read_plain_data_field<u32>(tr, "num-fragments", dts);
|
||||
if (num_fragments == 0) {
|
||||
lg::error("Shadow geo {} with no fragments! Skipping\n", name);
|
||||
return {};
|
||||
}
|
||||
// lg::info("{} {} fragments", name, num_fragments);
|
||||
auto frags_ref =
|
||||
TypedRef(get_field_ref(tr, "frags", dts), dts.ts.lookup_type("shadow-frag-ref"));
|
||||
@@ -406,7 +410,8 @@ void extract_shadow(const ObjectFileData& ag_data,
|
||||
|
||||
auto geo_locations = find_objects_with_type(ag_data.linked_data, "shadow-geo");
|
||||
for (auto loc : geo_locations) {
|
||||
extract_jak2_shadow_data(ag_data.linked_data, dts, loc);
|
||||
auto shadow_datas = extract_jak2_shadow_data(ag_data.linked_data, dts, loc);
|
||||
add_data_to_level(sd, shadow_datas);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -252,7 +252,7 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
BucketId::MERC_LCOM_SHRUB, m_merc2);
|
||||
|
||||
// 350
|
||||
init_bucket_renderer<Shadow2>("shadow", BucketCategory::OTHER, BucketId::SHADOW);
|
||||
init_bucket_renderer<Shadow2>("shadow", BucketCategory::OTHER, BucketId::SHADOW, m_shadow3);
|
||||
|
||||
// 351
|
||||
for (int i = 0; i < LEVEL_MAX; i++) {
|
||||
@@ -359,8 +359,8 @@ void OpenGLRenderer::init_bucket_renderers_jak3() {
|
||||
BucketId::GENERIC_SPRITE_3, m_generic2,
|
||||
Generic2::Mode::LIGHTNING);
|
||||
|
||||
init_bucket_renderer<Shadow2>("shadow2", BucketCategory::OTHER, BucketId::SHADOW2);
|
||||
init_bucket_renderer<Shadow2>("shadow3", BucketCategory::OTHER, BucketId::SHADOW3);
|
||||
init_bucket_renderer<Shadow2>("shadow2", BucketCategory::OTHER, BucketId::SHADOW2, m_shadow3);
|
||||
init_bucket_renderer<Shadow2>("shadow3", BucketCategory::OTHER, BucketId::SHADOW3, m_shadow3);
|
||||
// 575
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-warp", BucketCategory::TEX, BucketId::TEX_WARP,
|
||||
m_texture_animator);
|
||||
@@ -551,7 +551,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
|
||||
init_bucket_renderer<Generic2BucketRenderer>("gmerc-lcom-tfrag", BucketCategory::GENERIC,
|
||||
BucketId::GMERC_LCOM_TFRAG, m_generic2,
|
||||
Generic2::Mode::NORMAL);
|
||||
init_bucket_renderer<Shadow2>("shadow", BucketCategory::OTHER, BucketId::SHADOW);
|
||||
init_bucket_renderer<Shadow2>("shadow", BucketCategory::OTHER, BucketId::SHADOW, m_shadow3);
|
||||
// 220
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-lcom-pris", BucketCategory::TEX,
|
||||
BucketId::TEX_LCOM_PRIS, m_texture_animator);
|
||||
@@ -571,7 +571,7 @@ void OpenGLRenderer::init_bucket_renderers_jak2() {
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-all-sprite", BucketCategory::TEX,
|
||||
BucketId::TEX_ALL_SPRITE, m_texture_animator);
|
||||
init_bucket_renderer<Sprite3>("particles", BucketCategory::SPRITE, BucketId::PARTICLES);
|
||||
init_bucket_renderer<Shadow2>("shadow2", BucketCategory::OTHER, BucketId::SHADOW2);
|
||||
init_bucket_renderer<Shadow2>("shadow2", BucketCategory::OTHER, BucketId::SHADOW2, m_shadow3);
|
||||
init_bucket_renderer<Generic2BucketRenderer>("effects", BucketCategory::OTHER, BucketId::EFFECTS,
|
||||
m_generic2, Generic2::Mode::LIGHTNING);
|
||||
init_bucket_renderer<TextureUploadHandler>("tex-all-warp", BucketCategory::TEX,
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
#include "third-party/imgui/imgui.h"
|
||||
|
||||
Shadow2::Shadow2(const std::string& name, int my_id) : BucketRenderer(name, my_id) {
|
||||
Shadow2::Shadow2(const std::string& name, int my_id, std::shared_ptr<Shadow3> shadow3)
|
||||
: BucketRenderer(name, my_id), m_shadow3(shadow3) {
|
||||
m_vertex_buffer.resize(kMaxVerts);
|
||||
m_front_index_buffer.resize(kMaxInds);
|
||||
m_back_index_buffer.resize(kMaxInds);
|
||||
@@ -53,7 +54,11 @@ void Shadow2::init_shaders(ShaderLibrary& shaders) {
|
||||
}
|
||||
|
||||
void Shadow2::draw_debug_window() {
|
||||
ImGui::Checkbox("volume", &m_debug_draw_volume);
|
||||
if (m_using_shadow3) {
|
||||
m_shadow3->draw_debug_window();
|
||||
} else {
|
||||
ImGui::Checkbox("volume", &m_debug_draw_volume);
|
||||
}
|
||||
}
|
||||
|
||||
void Shadow2::reset_buffers() {
|
||||
@@ -71,6 +76,13 @@ void Shadow2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedPr
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_using_shadow3 = dma.current_tag_vifcode0().kind == VifCode::Kind::PC_PORT;
|
||||
if (m_using_shadow3) {
|
||||
m_shadow3->render_jak1(dma, render_state, prof);
|
||||
return;
|
||||
}
|
||||
|
||||
auto maybe_constants = dma.read_and_advance();
|
||||
if (maybe_constants.size_bytes == 0 && maybe_constants.vif0() == 0 &&
|
||||
maybe_constants.vif1() == 0) {
|
||||
@@ -80,6 +92,7 @@ void Shadow2::render(DmaFollower& dma, SharedRenderState* render_state, ScopedPr
|
||||
|
||||
reset_buffers();
|
||||
|
||||
|
||||
// shadow-vu1-constants
|
||||
ASSERT(maybe_constants.size_bytes >= sizeof(ShadowVu1Constants));
|
||||
FrameConstants frame_constants;
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
#include "common/math/Vector.h"
|
||||
|
||||
#include "game/graphics/opengl_renderer/BucketRenderer.h"
|
||||
#include "game/graphics/opengl_renderer/foreground/Shadow3.h"
|
||||
|
||||
class Shadow2 : public BucketRenderer {
|
||||
public:
|
||||
static constexpr int kMaxVerts = 8192 * 3 * 2;
|
||||
static constexpr int kMaxInds = kMaxVerts;
|
||||
Shadow2(const std::string& name, int my_id);
|
||||
Shadow2(const std::string& name, int my_id, std::shared_ptr<Shadow3> shadow3);
|
||||
~Shadow2();
|
||||
void render(DmaFollower& dma, SharedRenderState* render_state, ScopedProfilerNode& prof) override;
|
||||
void draw_debug_window() override;
|
||||
@@ -94,4 +95,6 @@ class Shadow2 : public BucketRenderer {
|
||||
ScopedProfilerNode& prof,
|
||||
const FrameConstants& constants);
|
||||
u8 m_color[4] = {0, 0, 0, 0};
|
||||
std::shared_ptr<Shadow3> m_shadow3;
|
||||
bool m_using_shadow3 = false;
|
||||
};
|
||||
|
||||
@@ -107,8 +107,7 @@
|
||||
;; new shadow queue for drawing PC shadows.
|
||||
(declare-type pc-shadow-request structure)
|
||||
(deftype pc-shadow-request (structure)
|
||||
(
|
||||
(dma-next dma-packet :inline)
|
||||
((dma-next dma-packet :inline)
|
||||
(settings shadow-settings :inline)
|
||||
(color vector :inline)
|
||||
(geo-name string) ;; name to send to PC renderer
|
||||
|
||||
@@ -1449,6 +1449,23 @@
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; og:preserve-this
|
||||
(let ((v1-0 *pc-shadow-globals*))
|
||||
(dotimes (a0-0 2)
|
||||
(let ((a1-2 (-> v1-0 bucket a0-0)))
|
||||
(set! (-> a1-2 first) (the-as pointer 0))
|
||||
(set! (-> a1-2 next) (the-as pointer 0))
|
||||
(set! (-> a1-2 shadow-color) (if (zero? a0-0)
|
||||
(new 'static 'rgba :r #xf0 :g #xf0 :b #xf0 :a #x80)
|
||||
(the-as rgba (-> *setting-control* user-current spotlight-color))
|
||||
)
|
||||
)
|
||||
(set! (-> a1-2 constants) (the-as shadow-vu1-constants 0))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
(none)
|
||||
)
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
(eye 3)
|
||||
)
|
||||
|
||||
;; when set, use the rewritten PC shadow render (faster)
|
||||
(define *use-pc-shadow* #t)
|
||||
|
||||
(def-mips2c foreground-draw-hud (function draw-control dma-buffer float none))
|
||||
|
||||
@@ -563,8 +565,102 @@
|
||||
)
|
||||
)
|
||||
|
||||
;; og:preserve-this
|
||||
(defun pc-draw-bones-shadow ((dc draw-control) (mtx pointer) (dma-ptr pointer))
|
||||
"Add shadows for this draw-control to the *pc-shadow-queue* to be drawn in pc-shadow-execute-all.
|
||||
This places a pc-shadow-request in the DMA buffer and adds it to the linked list of requests
|
||||
for the currently selected run in *pc-shadow-queue*"
|
||||
|
||||
(when (-> dc shadow-ctrl)
|
||||
;; update the "center" position of the shadow control, I guess to let some other thing look at it?
|
||||
(let ((center-pos (-> dc skeleton bones (-> dc shadow-joint-index) position))
|
||||
(settings (-> dc shadow-ctrl settings))
|
||||
)
|
||||
(set! (-> settings center x) (-> center-pos x))
|
||||
(set! (-> settings center y) (-> center-pos y))
|
||||
(set! (-> settings center z) (-> center-pos z))
|
||||
)
|
||||
)
|
||||
(let* ((pse (the pc-shadow-request dma-ptr))
|
||||
(sgeo (-> dc shadow))
|
||||
(settings (if (-> dc shadow-ctrl) (-> dc shadow-ctrl settings) *default-shadow-settings*))
|
||||
(flags (-> settings flags))
|
||||
)
|
||||
|
||||
;; if fade is enabled, and we're all the way faded out, disable draw
|
||||
(when (not (logtest? flags (shadow-flags disable-fade)))
|
||||
(let ((dist (-> (scratchpad-object foreground-work) distance w)))
|
||||
(#when PC_PORT
|
||||
(if (not (-> *pc-settings* ps2-shadow?))
|
||||
(set! dist 0.0)))
|
||||
(if (< (-> settings fade-dist) dist)
|
||||
(logior! flags (shadow-flags disable-draw))
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
;; if disabled, early return
|
||||
(if (logtest? flags (shadow-flags disable-draw))
|
||||
(return dma-ptr)
|
||||
)
|
||||
|
||||
|
||||
;; settings
|
||||
(mem-copy! (the pointer (-> pse settings)) (the pointer settings) (size-of shadow-settings))
|
||||
|
||||
;; update the "center" position.
|
||||
(let ((center-pos (-> dc skeleton bones (-> dc shadow-joint-index) position)))
|
||||
(set! (-> pse settings center x) (-> center-pos x))
|
||||
(set! (-> pse settings center y) (-> center-pos y))
|
||||
(set! (-> pse settings center z) (-> center-pos z))
|
||||
)
|
||||
|
||||
;; set the other properties
|
||||
(set! (-> pse geo-name) (-> sgeo name))
|
||||
(set! (-> pse mtx) mtx)
|
||||
(set! (-> pse num-joints) (-> sgeo num-joints))
|
||||
;; TODO: this is probably the wrong color!!!
|
||||
(vector-copy! (-> pse color) (-> *time-of-day-context* current-shadow-color))
|
||||
|
||||
;; set up linked list.
|
||||
(let* ((run (-> *pc-shadow-globals* bucket (-> settings shadow-type)))
|
||||
(next (-> run next))
|
||||
)
|
||||
|
||||
;; if we're the first in the list, store in the run
|
||||
(when (zero? (-> run first))
|
||||
(format 0 "Setting first to #x~X~%" pse)
|
||||
(set! (-> run first) (the pointer pse)))
|
||||
|
||||
;; patch next pointer of previous
|
||||
(if (nonzero? next) (set! (-> (the (pointer structure) next) 0) pse))
|
||||
|
||||
;; remember where to patch for the next one
|
||||
(set! (-> run next) (&-> pse next))
|
||||
|
||||
;; clear our next pointer in case we're last
|
||||
(set! (-> pse next) (the pc-shadow-request 0))
|
||||
|
||||
;; set up next tag at the start, to skip over this data.
|
||||
;; this is a bit of a hack, this function gets called when building merc chains,
|
||||
;; and inserts a bit of shadow dma that will later be referenced by the shadow bucket.
|
||||
;; but the original game did the same thing!
|
||||
(&+! dma-ptr (size-of pc-shadow-request))
|
||||
(set! (-> pse dma-next dma) (new 'static 'dma-tag :id (dma-tag-id next) :addr (the-as int dma-ptr)))
|
||||
(set! (-> pse dma-next vif0) (new 'static 'vif-tag))
|
||||
(set! (-> pse dma-next vif1) (new 'static 'vif-tag))
|
||||
)
|
||||
|
||||
dma-ptr
|
||||
)
|
||||
)
|
||||
|
||||
;; ERROR: Unsupported inline assembly instruction kind - [lq ra, 32(v1)]
|
||||
(defun foreground-shadow ((draw-ctrl draw-control) (arg1 (inline-array pris-mtx)) (arg2 pointer))
|
||||
;; og:preserve-this
|
||||
(when *use-pc-shadow*
|
||||
(return (pc-draw-bones-shadow draw-ctrl (the pointer arg1) arg2))
|
||||
)
|
||||
(local-vars (shadow-settings shadow-settings))
|
||||
(let ((shadow-geo (-> draw-ctrl shadow))
|
||||
(dist (-> (scratchpad-object foreground-work) distance w))
|
||||
|
||||
@@ -137,6 +137,21 @@
|
||||
|
||||
(define *shadow-globals* (new 'global 'shadow-globals))
|
||||
|
||||
;; og:preserve-this
|
||||
;; separate copy of shadow-globals for storing only the PC format requests.
|
||||
(define *pc-shadow-globals* (new 'global 'shadow-globals))
|
||||
(declare-type pc-shadow-request structure)
|
||||
(deftype pc-shadow-request (structure)
|
||||
((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
|
||||
(next pc-shadow-request)
|
||||
)
|
||||
)
|
||||
|
||||
(deftype shadow-vertex (structure)
|
||||
((x float :offset-assert 0)
|
||||
(y float :offset-assert 4)
|
||||
|
||||
@@ -641,9 +641,39 @@
|
||||
(none)
|
||||
)
|
||||
|
||||
;; og:preserve-this
|
||||
(defun pc-shadow-execute-all ()
|
||||
"Send PC shadow queue to the PC shadow renderer."
|
||||
|
||||
;; bail if disabled
|
||||
(if (not (logtest? (-> *display* vu1-enable-user) (vu1-renderer-mask shadow)))
|
||||
(return #f)
|
||||
)
|
||||
|
||||
(dotimes (i 2)
|
||||
(when (nonzero? (-> *pc-shadow-globals* bucket i first))
|
||||
(with-dma-buffer-add-bucket ((dma-buf (-> (current-frame) global-buf)) (if (zero? i) (bucket-id shadow) (bucket-id shadow2)))
|
||||
(format 0 "dma bucket ~d from ~X~%" i (-> *pc-shadow-globals* bucket i first))
|
||||
(dma-buffer-add-ref-vif2
|
||||
dma-buf
|
||||
6
|
||||
(-> *pc-shadow-globals* bucket i first)
|
||||
(new 'static 'vif-tag :cmd (vif-cmd pc-port))
|
||||
(new 'static 'vif-tag :cmd (vif-cmd pc-port))
|
||||
)
|
||||
)
|
||||
)
|
||||
)
|
||||
(none)
|
||||
)
|
||||
|
||||
;; ERROR: Failed store: (s.h! (+ v1-24 18) 0) at op 58
|
||||
;; ERROR: Failed store: (s.h! (+ v1-24 16) 0) at op 59
|
||||
(defun shadow-execute-all ((arg0 dma-buffer))
|
||||
(when *use-pc-shadow*
|
||||
(pc-shadow-execute-all)
|
||||
(return #f)
|
||||
)
|
||||
(when *debug-segment*
|
||||
(let ((gp-0 (-> *display* frames (-> *display* on-screen) profile-array data 0))
|
||||
(v1-7 'shadow)
|
||||
|
||||
Reference in New Issue
Block a user