Add CWorldShadow

This commit is contained in:
Henrique Gemignani Passos Lima 2022-12-01 18:11:09 +02:00
parent b506df2778
commit 552dc65a2c
No known key found for this signature in database
GPG Key ID: E224F951761145F8
18 changed files with 299 additions and 30 deletions

View File

@ -54,8 +54,8 @@ lbl_805A9438:
.section .text, "ax" .section .text, "ax"
.global sub_8030e10c .global sub_8030e10c__8CTextureFv
sub_8030e10c: sub_8030e10c__8CTextureFv:
/* 8030E10C 0030B06C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8030E10C 0030B06C 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 8030E110 0030B070 7C 08 02 A6 */ mflr r0 /* 8030E110 0030B070 7C 08 02 A6 */ mflr r0
/* 8030E114 0030B074 90 01 00 14 */ stw r0, 0x14(r1) /* 8030E114 0030B074 90 01 00 14 */ stw r0, 0x14(r1)

View File

@ -9161,7 +9161,7 @@ BeginScene__13CCubeRendererFv:
/* 802BDD6C 002BACCC 2C 00 00 00 */ cmpwi r0, 0 /* 802BDD6C 002BACCC 2C 00 00 00 */ cmpwi r0, 0
/* 802BDD70 002BACD0 40 82 00 20 */ bne lbl_802BDD90 /* 802BDD70 002BACD0 40 82 00 20 */ bne lbl_802BDD90
/* 802BDD74 002BACD4 80 7F 03 14 */ lwz r3, 0x314(r31) /* 802BDD74 002BACD4 80 7F 03 14 */ lwz r3, 0x314(r31)
/* 802BDD78 002BACD8 48 05 03 95 */ bl sub_8030e10c /* 802BDD78 002BACD8 48 05 03 95 */ bl sub_8030e10c__8CTextureFv
/* 802BDD7C 002BACDC 80 7F 03 14 */ lwz r3, 0x314(r31) /* 802BDD7C 002BACDC 80 7F 03 14 */ lwz r3, 0x314(r31)
/* 802BDD80 002BACE0 38 80 00 01 */ li r4, 1 /* 802BDD80 002BACE0 38 80 00 01 */ li r4, 1
/* 802BDD84 002BACE4 48 05 1C 75 */ bl __dt__8CTextureFv /* 802BDD84 002BACE4 48 05 1C 75 */ bl __dt__8CTextureFv
@ -9854,7 +9854,7 @@ __dt__13CCubeRendererFv:
/* 802BE6DC 002BB63C 80 7E 03 14 */ lwz r3, 0x314(r30) /* 802BE6DC 002BB63C 80 7E 03 14 */ lwz r3, 0x314(r30)
/* 802BE6E0 002BB640 28 03 00 00 */ cmplwi r3, 0 /* 802BE6E0 002BB640 28 03 00 00 */ cmplwi r3, 0
/* 802BE6E4 002BB644 41 82 00 08 */ beq lbl_802BE6EC /* 802BE6E4 002BB644 41 82 00 08 */ beq lbl_802BE6EC
/* 802BE6E8 002BB648 48 04 FA 25 */ bl sub_8030e10c /* 802BE6E8 002BB648 48 04 FA 25 */ bl sub_8030e10c__8CTextureFv
lbl_802BE6EC: lbl_802BE6EC:
/* 802BE6EC 002BB64C 34 1E 03 14 */ addic. r0, r30, 0x314 /* 802BE6EC 002BB64C 34 1E 03 14 */ addic. r0, r30, 0x314
/* 802BE6F0 002BB650 41 82 00 10 */ beq lbl_802BE700 /* 802BE6F0 002BB650 41 82 00 10 */ beq lbl_802BE700

View File

@ -876,7 +876,7 @@ __dt__16CProjectedShadowFv:
/* 8029E394 0029B2F4 93 C1 00 08 */ stw r30, 8(r1) /* 8029E394 0029B2F4 93 C1 00 08 */ stw r30, 8(r1)
/* 8029E398 0029B2F8 7C 7E 1B 79 */ or. r30, r3, r3 /* 8029E398 0029B2F8 7C 7E 1B 79 */ or. r30, r3, r3
/* 8029E39C 0029B2FC 41 82 00 24 */ beq lbl_8029E3C0 /* 8029E39C 0029B2FC 41 82 00 24 */ beq lbl_8029E3C0
/* 8029E3A0 0029B300 48 06 FD 6D */ bl sub_8030e10c /* 8029E3A0 0029B300 48 06 FD 6D */ bl sub_8030e10c__8CTextureFv
/* 8029E3A4 0029B304 7F C3 F3 78 */ mr r3, r30 /* 8029E3A4 0029B304 7F C3 F3 78 */ mr r3, r30
/* 8029E3A8 0029B308 38 80 FF FF */ li r4, -1 /* 8029E3A8 0029B308 38 80 FF FF */ li r4, -1
/* 8029E3AC 0029B30C 48 07 16 4D */ bl __dt__8CTextureFv /* 8029E3AC 0029B30C 48 07 16 4D */ bl __dt__8CTextureFv

View File

@ -908,7 +908,7 @@ __dt__12CWorldShadowFv:
/* 80111B74 0010EAD4 80 7E 00 00 */ lwz r3, 0(r30) /* 80111B74 0010EAD4 80 7E 00 00 */ lwz r3, 0(r30)
/* 80111B78 0010EAD8 28 03 00 00 */ cmplwi r3, 0 /* 80111B78 0010EAD8 28 03 00 00 */ cmplwi r3, 0
/* 80111B7C 0010EADC 41 82 00 08 */ beq lbl_80111B84 /* 80111B7C 0010EADC 41 82 00 08 */ beq lbl_80111B84
/* 80111B80 0010EAE0 48 1F C5 8D */ bl sub_8030e10c /* 80111B80 0010EAE0 48 1F C5 8D */ bl sub_8030e10c__8CTextureFv
lbl_80111B84: lbl_80111B84:
/* 80111B84 0010EAE4 28 1E 00 00 */ cmplwi r30, 0 /* 80111B84 0010EAE4 28 1E 00 00 */ cmplwi r30, 0
/* 80111B88 0010EAE8 41 82 00 10 */ beq lbl_80111B98 /* 80111B88 0010EAE8 41 82 00 10 */ beq lbl_80111B98
@ -1007,4 +1007,3 @@ lbl_803CF1F8:
# ROM: 0x3CC1F8 # ROM: 0x3CC1F8
.asciz "??(??)" .asciz "??(??)"
.balign 4 .balign 4

View File

@ -1049,7 +1049,7 @@ __dt__16CMorphBallShadowFv:
/* 80296A7C 002939DC 7C 7E 1B 79 */ or. r30, r3, r3 /* 80296A7C 002939DC 7C 7E 1B 79 */ or. r30, r3, r3
/* 80296A80 002939E0 41 82 00 9C */ beq lbl_80296B1C /* 80296A80 002939E0 41 82 00 9C */ beq lbl_80296B1C
/* 80296A84 002939E4 38 7E 00 40 */ addi r3, r30, 0x40 /* 80296A84 002939E4 38 7E 00 40 */ addi r3, r30, 0x40
/* 80296A88 002939E8 48 07 76 85 */ bl sub_8030e10c /* 80296A88 002939E8 48 07 76 85 */ bl sub_8030e10c__8CTextureFv
/* 80296A8C 002939EC 34 1E 00 A8 */ addic. r0, r30, 0xa8 /* 80296A8C 002939EC 34 1E 00 A8 */ addic. r0, r30, 0xa8
/* 80296A90 002939F0 41 82 00 10 */ beq lbl_80296AA0 /* 80296A90 002939F0 41 82 00 10 */ beq lbl_80296AA0
/* 80296A94 002939F4 38 7E 00 A8 */ addi r3, r30, 0xa8 /* 80296A94 002939F4 38 7E 00 A8 */ addi r3, r30, 0xa8

View File

@ -138,7 +138,7 @@ LIBS = [
["MetroidPrime/CActorParameters", False], ["MetroidPrime/CActorParameters", False],
"MetroidPrime/CInGameGuiManager", "MetroidPrime/CInGameGuiManager",
"MetroidPrime/Enemies/CWarWasp", "MetroidPrime/Enemies/CWarWasp",
"MetroidPrime/CWorldShadow", ["MetroidPrime/CWorldShadow", False],
["MetroidPrime/CAudioStateWin", True], ["MetroidPrime/CAudioStateWin", True],
"MetroidPrime/Player/CPlayerVisor", "MetroidPrime/Player/CPlayerVisor",
"MetroidPrime/CModelData", "MetroidPrime/CModelData",

View File

@ -1,9 +1,15 @@
#ifndef _CCUBEMODEL #ifndef _CCUBEMODEL
#define _CCUBEMODEL #define _CCUBEMODEL
class CTexture;
class CTransform4f;
class CCubeModel { class CCubeModel {
public: public:
static void SetRenderModelBlack(bool v); static void SetRenderModelBlack(bool v);
static void DisableShadowMaps();
static void EnableShadowMaps(const CTexture*, const CTransform4f&, unsigned char, unsigned char);
static void SetDrawingOccluders(bool);
}; };
#endif // _CCUBEMODEL #endif // _CCUBEMODEL

View File

@ -161,6 +161,7 @@ struct CViewport {
class COsContext; class COsContext;
class CTexture; class CTexture;
class CTimeProvider; class CTimeProvider;
class CTexture;
// TODO // TODO
typedef struct { typedef struct {
@ -235,6 +236,9 @@ public:
static CMatrix4f GetPerspectiveProjectionMatrix(); static CMatrix4f GetPerspectiveProjectionMatrix();
static CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar); static CMatrix4f CalculatePerspectiveMatrix(float fovy, float aspect, float znear, float zfar);
static float GetDepthNear() { return mDepthNear; }
static float GetDepthFar() { return mDepthFar; }
static bool IsBeginSceneClearFb(); static bool IsBeginSceneClearFb();
static void SetIsBeginSceneClearFb(bool); static void SetIsBeginSceneClearFb(bool);
static void BeginScene(); static void BeginScene();
@ -243,6 +247,7 @@ public:
static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass); static void SetTevOp(ERglTevStage stage, const CTevCombiners::CTevPass& pass);
static void StreamBegin(ERglPrimitive primitive); static void StreamBegin(ERglPrimitive primitive);
static void StreamColor(uint color); static void StreamColor(uint color);
static void StreamColor(float, float, float, float);
static void StreamColor(const CColor& color); static void StreamColor(const CColor& color);
static void StreamTexcoord(float u, float v); static void StreamTexcoord(float u, float v);
static void StreamVertex(float, float, float); static void StreamVertex(float, float, float);
@ -284,6 +289,9 @@ public:
static void sub_80309564(uint* stretch, uint* xOffset, uint* yOffset); static void sub_80309564(uint* stretch, uint* xOffset, uint* yOffset);
static void sub_803094b0(uint stretch, uint xOffset, uint yOffset); static void sub_803094b0(uint stretch, uint xOffset, uint yOffset);
// Render
static void Render2D(const CTexture& tex, int x, int y, int w, int h, const CColor& col);
static CTevCombiners::CTevPass& kEnvPassthru; static CTevCombiners::CTevPass& kEnvPassthru;
static CTevCombiners::CTevPass kEnvModulateConstColor; static CTevCombiners::CTevPass kEnvModulateConstColor;
static CTevCombiners::CTevPass kEnvConstColor; static CTevCombiners::CTevPass kEnvConstColor;

View File

@ -7,6 +7,21 @@
class CInputStream; class CInputStream;
enum ETexelFormat {
kTF_Invalid = -1,
kTF_I4 = 0,
kTF_I8 = 1,
kTF_IA4 = 2,
kTF_IA8 = 3,
kTF_C4 = 4,
kTF_C8 = 5,
kTF_C14X2 = 6,
kTF_RGB565 = 7,
kTF_RGB5A3 = 8,
kTF_RGBA8 = 9,
kTF_CMPR = 10,
};
class CTexture { class CTexture {
public: public:
enum EClampMode { enum EClampMode {
@ -21,20 +36,35 @@ public:
kBK_Zero, kBK_Zero,
}; };
CTexture(ETexelFormat fmt, short w, short h, int mips);
CTexture(CInputStream& stream, EAutoMipmap mip, EBlackKey bk); CTexture(CInputStream& stream, EAutoMipmap mip, EBlackKey bk);
~CTexture();
// Used in certain destructors
void sub_8030e10c();
void Load(GXTexMapID texMapId, EClampMode clampMode) const; void Load(GXTexMapID texMapId, EClampMode clampMode) const;
void UnLock();
void* GetBitMapData(int);
static void InvalidateTexmap(GXTexMapID id); static void InvalidateTexmap(GXTexMapID id);
uint GetTexelFormat() const { return mTexelFormat; }
short GetWidth() const { return mWidth; } short GetWidth() const { return mWidth; }
short GetHeight() const { return mHeight; } short GetHeight() const { return mHeight; }
void SetFlag1(bool b) { mFlag1 = b; }
private: private:
uint mTexelFormat; // TODO: Enum uint mTexelFormat; // TODO: Enum
short mWidth; short mWidth;
short mHeight; short mHeight;
uchar pad[0x60]; uchar mNumMips;
uchar mBitsPerPixel;
uchar mFlag1 : 1;
uchar pad[0x57];
}; };
// CHECK_SIZEOF(CTexture, )
#endif // _CTEXTURE #endif // _CTEXTURE

View File

@ -20,6 +20,7 @@ public:
float z; float z;
float d; float d;
}; };
CFrustumPlanes(const CTransform4f&, float, float, float, bool, float);
bool BoxInFrustumPlanes(const CAABox& box) const; bool BoxInFrustumPlanes(const CAABox& box) const;
bool BoxInFrustumPlanes(const rstl::optional_object< CAABox >& box) const; bool BoxInFrustumPlanes(const rstl::optional_object< CAABox >& box) const;

View File

@ -0,0 +1,17 @@
#ifndef _CPVSVISSET
#define _CPVSVISSET
#include "rstl/auto_ptr.hpp"
class CPVSVisSet {
public:
static CPVSVisSet Reset(int);
private:
int x0_state;
uint x4_numBits;
uint x8_numLights;
rstl::auto_ptr< u8 > x10_ptr;
};
#endif // _CPVSVISSET

View File

@ -25,13 +25,13 @@ public:
~CCubeRenderer() override; ~CCubeRenderer() override;
// TODO types // TODO types
void AddStaticGeometry() override; void AddStaticGeometry() override;
void EnablePVS() override; void EnablePVS(const CPVSVisSet& set, int areaIdx) override;
void DisablePVS() override; void DisablePVS() override;
void RemoveStaticGeometry() override; void RemoveStaticGeometry() override;
void DrawUnsortedGeometry() override; void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask) override;
void DrawSortedGeometry() override; void DrawSortedGeometry(int areaIdx, int mask, int targetMask) override;
void DrawStaticGeometry() override; void DrawStaticGeometry(int areaIdx, int mask, int targetMask) override;
void DrawAreaGeometry() override; void DrawAreaGeometry(int areaIdx, int mask, int targetMask) override;
void PostRenderFogs() override; void PostRenderFogs() override;
void SetModelMatrix(const CTransform4f& xf) override; void SetModelMatrix(const CTransform4f& xf) override;
void AddParticleGen(const CParticleGen& gen) override; void AddParticleGen(const CParticleGen& gen) override;
@ -45,8 +45,8 @@ public:
void SetPerspective2() override; void SetPerspective2() override;
rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear, rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear,
float zfar) override; float zfar) override;
void SetClippingPlanes() override; void SetClippingPlanes(const CFrustumPlanes&) override;
void SetViewport() override; void SetViewport(int left, int right, int width, int height) override;
void SetDepthReadWrite(bool read, bool update) override; void SetDepthReadWrite(bool read, bool update) override;
void SetBlendMode_AdditiveAlpha() override; void SetBlendMode_AdditiveAlpha() override;
void SetBlendMode_AlphaBlended() override; void SetBlendMode_AlphaBlended() override;
@ -90,7 +90,7 @@ public:
void SetGXRegister1Color() override; void SetGXRegister1Color() override;
void SetWorldLightFadeLevel() override; void SetWorldLightFadeLevel() override;
void Something() override; void Something() override;
void PrepareDynamicLights() override; void PrepareDynamicLights(const rstl::vector<CLight>& lights) override;
void AllocatePhazonSuitMaskTexture(); void AllocatePhazonSuitMaskTexture();

View File

@ -3,6 +3,7 @@
#include "types.h" #include "types.h"
#include "rstl/pair.hpp" #include "rstl/pair.hpp"
#include "rstl/vector.hpp"
#include "Kyoto/TToken.hpp" #include "Kyoto/TToken.hpp"
@ -16,8 +17,11 @@ class CAABox;
class CVector2f; class CVector2f;
class CVector3f; class CVector3f;
class CModel; class CModel;
class CFrustumPlanes;
class CSkinnedModel; class CSkinnedModel;
class CColor; class CColor;
class CLight;
class CPVSVisSet;
class IRenderer { class IRenderer {
public: public:
@ -32,13 +36,13 @@ public:
// TODO vtable // TODO vtable
virtual void AddStaticGeometry(); virtual void AddStaticGeometry();
virtual void EnablePVS(); virtual void EnablePVS(const CPVSVisSet& set, int areaIdx);
virtual void DisablePVS(); virtual void DisablePVS();
virtual void RemoveStaticGeometry(); virtual void RemoveStaticGeometry();
virtual void DrawUnsortedGeometry(); virtual void DrawUnsortedGeometry(int areaIdx, int mask, int targetMask);
virtual void DrawSortedGeometry(); virtual void DrawSortedGeometry(int areaIdx, int mask, int targetMask);
virtual void DrawStaticGeometry(); virtual void DrawStaticGeometry(int areaIdx, int mask, int targetMask);
virtual void DrawAreaGeometry(); virtual void DrawAreaGeometry(int areaIdx, int mask, int targetMask);
virtual void PostRenderFogs(); virtual void PostRenderFogs();
virtual void SetModelMatrix(const CTransform4f& xf); virtual void SetModelMatrix(const CTransform4f& xf);
virtual void AddParticleGen(const CParticleGen& gen); virtual void AddParticleGen(const CParticleGen& gen);
@ -52,8 +56,8 @@ public:
virtual void SetPerspective2(); virtual void SetPerspective2();
virtual rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear, virtual rstl::pair< CVector2f, CVector2f > SetViewportOrtho(bool centered, float znear,
float zfar); float zfar);
virtual void SetClippingPlanes(); virtual void SetClippingPlanes(const CFrustumPlanes&);
virtual void SetViewport(); virtual void SetViewport(int left, int right, int width, int height);
virtual void SetDepthReadWrite(bool read, bool update); virtual void SetDepthReadWrite(bool read, bool update);
virtual void SetBlendMode_AdditiveAlpha(); virtual void SetBlendMode_AdditiveAlpha();
virtual void SetBlendMode_AlphaBlended(); virtual void SetBlendMode_AlphaBlended();
@ -98,7 +102,7 @@ public:
virtual void SetGXRegister1Color(); virtual void SetGXRegister1Color();
virtual void SetWorldLightFadeLevel(); virtual void SetWorldLightFadeLevel();
virtual void Something(); virtual void Something();
virtual void PrepareDynamicLights(); virtual void PrepareDynamicLights(const rstl::vector<CLight>& lights);
}; };
namespace Renderer { namespace Renderer {

View File

@ -47,6 +47,7 @@ class CToken;
class IDvdRequest; class IDvdRequest;
class CScriptAreaAttributes; class CScriptAreaAttributes;
class CWorldLight; class CWorldLight;
class CPVSAreaSet;
class CGameArea : public IGameArea { class CGameArea : public IGameArea {
public: public:
@ -150,9 +151,11 @@ public:
enum EOcclusionState { kOS_Occluded, kOS_Visible }; enum EOcclusionState { kOS_Occluded, kOS_Visible };
struct CPostConstructed { struct CPostConstructed {
uchar x0_pad[0x10c4]; uchar x0_pad[0xa0];
CPVSAreaSet* xa0_pvs;
uchar xa4_pad[0x1020];
rstl::single_ptr< CAreaFog > x10c4_areaFog; rstl::single_ptr< CAreaFog > x10c4_areaFog;
rstl::optional_object< void* > x10c8_sclyBuf; // was rstl::optional_object<void*> rstl::optional_object< void* > x10c8_sclyBuf;
u32 x10d0_sclySize; u32 x10d0_sclySize;
const u8* x10d4_firstMatPtr; const u8* x10d4_firstMatPtr;
const CScriptAreaAttributes* x10d8_areaAttributes; const CScriptAreaAttributes* x10d8_areaAttributes;
@ -165,6 +168,7 @@ public:
EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; } EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; }
const rstl::vector<CWorldLight>& GetLightsA() const; const rstl::vector<CWorldLight>& GetLightsA() const;
const rstl::vector<CWorldLight>& GetLightsB() const; const rstl::vector<CWorldLight>& GetLightsB() const;
const CPVSAreaSet* GetAreaVisSet() const { return x12c_postConstructed->xa0_pvs; }
private: private:
uchar x110_pad[0x1c]; uchar x110_pad[0x1c];

View File

@ -9,6 +9,8 @@
#include "rstl/single_ptr.hpp" #include "rstl/single_ptr.hpp"
class CTexture; class CTexture;
class CStateManager;
class CAABox;
class CWorldShadow { class CWorldShadow {
rstl::single_ptr< CTexture > x0_texture; rstl::single_ptr< CTexture > x0_texture;
@ -25,8 +27,8 @@ public:
CWorldShadow(uint w, uint h, bool rgba8); CWorldShadow(uint w, uint h, bool rgba8);
~CWorldShadow(); ~CWorldShadow();
void EnableModelProjectedShadow(const CTransform4f& pos, uint lightIdx, float f1); void EnableModelProjectedShadow(const CTransform4f& pos, uint lightIdx, float f1) const;
void DisableModelProjectedShadow(); void DisableModelProjectedShadow() const;
void BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, uint lightIdx, void BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, uint lightIdx,
const CAABox& aabb, bool motionBlur, bool lighten); const CAABox& aabb, bool motionBlur, bool lighten);
void ResetBlur(); void ResetBlur();

View File

@ -0,0 +1,11 @@
#ifndef _CPVSAREASET
#define _CPVSAREASET
class CPVSVisSet;
class CPVSAreaSet {
public:
CPVSVisSet GetLightSet(int) const;
};
#endif // _CPVSAREASET

View File

@ -24,6 +24,8 @@ public:
CLight GetAsCGraphicsLight() const; CLight GetAsCGraphicsLight() const;
const CVector3f& GetPosition() const { return x10_position; }
public: public:
EWorldLightType x0_type; EWorldLightType x0_type;
CVector3f x4_color; CVector3f x4_color;

View File

@ -0,0 +1,185 @@
#include "MetroidPrime/CWorldShadow.hpp"
#include "MetroidPrime/CGameArea.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "MetroidPrime/CWorld.hpp"
#include "WorldFormat/CPVSAreaSet.hpp"
#include "WorldFormat/CWorldLight.hpp"
#include "Kyoto/Alloc/CMemory.hpp"
#include "Kyoto/Graphics/CCubeModel.hpp"
#include "Kyoto/Graphics/CTexture.hpp"
#include "Kyoto/Math/CMath.hpp"
#include "Kyoto/PVS/CPVSVisSet.hpp"
#include "MetaRender/CCubeRenderer.hpp"
static int kUnknownValue = 1;
CWorldShadow::CWorldShadow(uint w, uint h, bool rgba8)
: x0_texture(NEW CTexture(rgba8 ? kTF_RGBA8 : kTF_RGB565, w, h, 1))
, x4_view(CTransform4f::Identity())
, x34_model(CTransform4f::Identity())
, x64_objHalfExtent(1.f)
, x68_objPos(0.0f, 1.f, 0.0f)
, x74_lightPos(CVector3f::Zero())
, x80_aid(kInvalidAreaId)
, x84_lightIdx(-1)
, x88_blurReset(true)
{}
CWorldShadow::~CWorldShadow() {
if (x0_texture.get())
x0_texture->sub_8030e10c();
}
void CWorldShadow::BuildLightShadowTexture(const CStateManager& mgr, TAreaId aid, uint lightIdx,
const CAABox& aabb, bool motionBlur, bool lighten) {
if (x80_aid != aid || x84_lightIdx != lightIdx) {
x88_blurReset = true;
x80_aid = aid;
x84_lightIdx = lightIdx;
}
if (aid != kInvalidAreaId) {
const CGameArea& area = mgr.GetWorld()->GetAreaAlways(aid);
if (area.IsLoaded()) {
const CWorldLight& light = area.GetLightsA()[lightIdx];
CVector3f centerPoint = aabb.GetCenterPoint();
const CPVSAreaSet* pvs = area.GetAreaVisSet();
if (pvs && kUnknownValue == 1) {
CPVSVisSet lightSet = pvs->GetLightSet(lightIdx);
gpRender->EnablePVS(lightSet, aid.Value());
} else {
gpRender->EnablePVS(CPVSVisSet::Reset(2), aid.Value());
}
CVector3f lightToPoint = centerPoint - light.GetPosition();
x64_objHalfExtent = (aabb.GetMaxPoint() - centerPoint).Magnitude();
float distance = lightToPoint.Magnitude();
float fov = CMath::Rad2Deg(atan2f(x64_objHalfExtent, distance)) * 2.f;
if (!(fov < 0.00001f)) {
lightToPoint.Normalize();
x4_view =
CTransform4f::LookAt(light.GetPosition(), centerPoint, CVector3f(0.0f, 0.0f, -1.0f));
x68_objPos = centerPoint;
x74_lightPos = light.GetPosition();
CGraphics::SetViewPointMatrix(x4_view);
CFrustumPlanes frumtum(
x4_view,
fov * 0.01745329238474369,
1.0f,
0.1f,
true,
distance + x64_objHalfExtent
);
gpRender->SetClippingPlanes(frumtum);
gpRender->SetPerspective1(fov, x0_texture->GetWidth(), x0_texture->GetHeight(), 0.1f,
1000.f);
float backupDepthNear = CGraphics::GetDepthNear();
float backupDepthFar = CGraphics::GetDepthFar();
CGraphics::SetDepthRange(0.f, 1.0f);
int backupVpHeight = CGraphics::GetViewport().mHeight;
int backupVpWidth = CGraphics::GetViewport().mWidth;
int backupVpTop = CGraphics::GetViewport().mTop;
int backupVpLeft = CGraphics::GetViewport().mLeft;
gpRender->SetViewport(0, 0, x0_texture->GetWidth(), x0_texture->GetHeight());
float extent = 1.4142f * x64_objHalfExtent;
x34_model =
CTransform4f::LookAt(centerPoint - CVector3f(0.f, 0.f, 0.1f), light.GetPosition());
gpRender->SetModelMatrix(x34_model);
gpRender->PrimColor(CColor::White());
CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And, kAF_Always, 0);
CGraphics::SetDepthWriteMode(true, kE_LEqual, true);
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_InvSrcAlpha, kLO_Clear);
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvPassthru);
CGraphics::SetTevOp(kTS_Stage1, CGraphics::kEnvPassthru);
gpRender->BeginTriangleStrip(4);
gpRender->PrimVertex(CVector3f(-extent, 0.f, extent));
gpRender->PrimVertex(CVector3f(extent, 0.f, extent));
gpRender->PrimVertex(CVector3f(-extent, 0.f, -extent));
gpRender->PrimVertex(CVector3f(extent, 0.f, -extent));
gpRender->EndPrimitive();
gpRender->SetModelMatrix(CTransform4f::Identity());
CCubeModel::SetRenderModelBlack(true);
CCubeModel::SetDrawingOccluders(true);
gpRender->PrepareDynamicLights(rstl::vector< CLight >());
gpRender->DrawUnsortedGeometry(aid.value, 0, 0);
CCubeModel::SetRenderModelBlack(false);
CCubeModel::SetDrawingOccluders(false);
if (lighten) {
gpRender->SetModelMatrix(x34_model);
CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And, kAF_Always, 0);
CGraphics::SetDepthWriteMode(false, kE_LEqual, false);
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha, kBF_InvSrcAlpha, kLO_Clear);
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvPassthru);
CGraphics::SetTevOp(kTS_Stage1, CGraphics::kEnvPassthru);
CGraphics::StreamBegin(kP_TriangleStrip);
CGraphics::StreamColor(1.f, 1.f, 1.f, 0.25f);
CGraphics::StreamVertex(CVector3f(-extent, 0.f, extent));
CGraphics::StreamVertex(CVector3f(extent, 0.f, extent));
CGraphics::StreamVertex(CVector3f(-extent, 0.f, -extent));
CGraphics::StreamVertex(CVector3f(extent, 0.f, -extent));
CGraphics::StreamEnd();
CGraphics::SetDepthWriteMode(true, kE_LEqual, true);
}
if (motionBlur && x88_blurReset != true) {
CGraphics::SetDepthWriteMode(false, kE_LEqual, false);
CGraphics::SetBlendMode(kBM_Blend, kBF_SrcAlpha,
kBF_InvSrcAlpha, kLO_Clear);
CGraphics::SetAlphaCompare(kAF_Always, 0, kAO_And,
kAF_Always, 0);
CGraphics::SetTevOp(kTS_Stage0, CGraphics::kEnvModulate);
CGraphics::SetTevOp(kTS_Stage1, CGraphics::kEnvPassthru);
CGraphics::Render2D(*x0_texture, 0, x0_texture->GetWidth() * 2,
x0_texture->GetHeight() * 2, x0_texture->GetWidth() * -2,
CColor(1.f, 1.f, 1.f, 0.85f));
CGraphics::SetDepthWriteMode(true, kE_LEqual, true);
}
x88_blurReset = false;
GXSetTexCopySrc(0, 448 - x0_texture->GetHeight() * 2, x0_texture->GetWidth() * 2, x0_texture->GetHeight() * 2);
GXTexFmt fmt = GX_TF_RGBA8;
if (x0_texture->GetTexelFormat() == 0x7) {
fmt = GX_TF_RGB565;
}
GXSetTexCopyDst(x0_texture->GetWidth(), x0_texture->GetHeight(), fmt, true);
static int unkInt = 0;
x0_texture->SetFlag1(true);
void * dest = x0_texture->GetBitMapData(0);
GXCopyTex(dest, true);
x0_texture->UnLock();
gpRender->SetViewport(backupVpLeft, backupVpTop, backupVpWidth, backupVpHeight);
CGraphics::SetDepthRange(backupDepthNear, backupDepthFar);
}
}
}
}
void CWorldShadow::EnableModelProjectedShadow(const CTransform4f& pos, uint lightIdx,
float f1) const {
static float M_SQRT2 = CMath::SqrtD(2.0); // TODO: should be an inlined function
CTransform4f texTransform = CTransform4f::LookAt(CVector3f::Zero(), x74_lightPos - x68_objPos,
CVector3f(0.0f, 0.0f, 1.0f));
CTransform4f posXf = pos;
posXf.SetTranslation(CVector3f::Zero());
texTransform = posXf.GetInverse() * texTransform;
texTransform = texTransform * CTransform4f::Scale(float(M_SQRT2) * x64_objHalfExtent * f1);
texTransform = texTransform.GetInverse();
texTransform = CTransform4f::Translate(0.5f, 0.f, 0.5f) * texTransform;
uchar lightMask = 1 << lightIdx;
CCubeModel::EnableShadowMaps(x0_texture.get(), texTransform, lightMask, lightMask);
}
void CWorldShadow::DisableModelProjectedShadow() const { CCubeModel::DisableShadowMaps(); }
void CWorldShadow::ResetBlur() { x88_blurReset = true; }