Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
223 changes: 219 additions & 4 deletions src/SB/Core/x/xShadow.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
#include "xShadow.h"

#include "rpcollis.h"
#include "rpworld.h"

#include "xMath.h"
#include "iCollide.h"
#include "iModel.h"
#include "zGlobals.h"
#include "zGrid.h"

#include <types.h>

Expand All @@ -15,12 +18,16 @@ static F32 SHADOW_BOTH;
RwCamera* ShadowCamera;
RwRaster* ShadowCameraRaster;
static RwRaster* ShadowRenderRaster;
U32 gShadowFlags;
F32 gShadowObjectRadius;
static S32 shadow_ent_count;
static F32 rscale;
static RwV3d gCamPos;
static RwRaster* gc_saveraster;
static xShadowMgr* sMgrList;
static S32 sMgrCount;
static S32 sMgrTotal;
static F32 ShadowStrength = 0.3f;

void xShadowInit();
static void ShadowCameraDestroy(RwCamera* shadowCamera);
Expand All @@ -32,13 +39,16 @@ void xShadowRenderWorld(xVec3* a, F32 b, F32 c);
void xShadow_ListAdd(xEnt* ent);
void xShadowManager_Add(xEnt* ent);
static void GCSaveFrameBuffer();
RwCamera* ShadowCameraSetSpherePersp(RwCamera* camera, RwV3d* center, float radius);
int Im2DRenderQuad(float x1, float y1, float x2, float y2, float z, float recipCamZ, float uvOffset);
static void GCRestoreFrameBuffer();
RwCamera* ShadowCameraSetSpherePersp(RwCamera* camera, RwV3d* center, F32 radius);
S32 Im2DRenderQuad(F32 x1, F32 y1, F32 x2, F32 y2, F32 z, F32 recipCamZ, F32 uvOffset);
void InvertRaster(RwCamera* cam);
static S32 ShadowRender( RwCamera* shadowCamera, RwRaster* arg1, RpIntersection* shadowZone, F32 shadowFactor, F32 fadeDist);

/* Three more params than in DWARF.
RwCamera* ShadowCameraUpdate(RwCamera* shadowCamera, void* model, void(*renderCB)(void*))
*/
RwCamera* ShadowCameraUpdate(RwCamera* shadowCamera, void* model, void(*renderCB)(void*), RwV3d* center, float radius, int);
RwCamera* ShadowCameraUpdate(RwCamera* shadowCamera, void* model, void(*renderCB)(void*), RwV3d* center, F32 radius, S32 param_6 );

void xShadowInit()
{
Expand Down Expand Up @@ -86,13 +96,30 @@ void xShadowSetWorld(RpWorld* world)
SHADOW_BOTH = 2.0f;
}

void xShadowSetLight(xVec3* target_pos, xVec3* in_vec, F32 param3) {
xVec3 zvec;
xMat4x3 matrix;
RwFrame* camFrame;
RwMatrixTag* camMatrix;

xVec3Normalize(&zvec, in_vec);
xMat3x3LookVec(&matrix, &zvec);
zvec += *target_pos;
camFrame = (RwFrame*)ShadowCamera->object.object.parent;
camMatrix = &camFrame->modelling;
xMat4x3Copy( (xMat4x3*) camMatrix,&matrix);
RwFrameOrthoNormalize( camFrame);
RwMatrixUpdate( camMatrix);
RwFrameUpdateObjects( camFrame);
}

U32 xShadowCameraCreate()
{
U32 setup = SetupShadow();
return ((-setup | setup) >> 0x1f);
}

void xShadowCameraUpdate(void* model, void(*renderCB)(void*), xVec3* center, float radius, int shadowMode)
void xShadowCameraUpdate(void* model, void(*renderCB)(void*), xVec3* center, F32 radius, int shadowMode)
{
ShadowCameraSetSpherePersp(ShadowCamera, (RwV3d*)center, radius);
ShadowCameraUpdate(ShadowCamera, model, renderCB, (RwV3d*)center, radius, shadowMode);
Expand All @@ -119,11 +146,127 @@ S32 xShadowReceiveShadowSetup(xEnt* ent)
return 0;
}

void xShadowRender(xEnt* ent, F32 max_dist) {
xVec3 center;
F32 radius;

zEntGetShadowParams(ent, &center, &radius, (xEntShadow::radius_enum) 1);
xShadowCameraUpdate(ent->model, modelRenderCB, &center, radius, 0);
xShadowRender(&center, radius, max_dist);
}

void xShadow_ListAdd(xEnt* ent)
{
xShadowManager_Add(ent);
}

S32 Im2DRenderQuad(F32 x1, F32 y1, F32 x2, F32 y2, F32 z, F32 recipCamZ, F32 uvOffset)
{

RwIm2DVertex vx[4];

vx[0].x = x1;
vx[0].y = y1;
vx[0].z = z;
vx[0].emissiveColor.red = 0xFF;
vx[0].emissiveColor.green = 0xFF;
vx[0].emissiveColor.blue = 0xFF;
vx[0].emissiveColor.alpha = 0xFF;
vx[0].u = uvOffset;
vx[0].v = uvOffset;

vx[1].x = x1;
vx[1].y = y2;
vx[1].z = z;
vx[1].emissiveColor.red = 0xFF;
vx[1].emissiveColor.green = 0xFF;
vx[1].emissiveColor.blue = 0xFF;
vx[1].emissiveColor.alpha = 0xFF;
vx[1].u = uvOffset;
vx[1].v = 1.0f + uvOffset;

vx[2].x = x2;
vx[2].y = y1;
vx[2].z = z;
vx[2].emissiveColor.red = 0xFF;
vx[2].emissiveColor.green = 0xFF;
vx[2].emissiveColor.blue = 0xFF;
vx[2].emissiveColor.alpha = 0xFF;
vx[2].u = 1.0f + uvOffset;
vx[2].v = uvOffset;

vx[3].x = x2;
vx[3].y = y2;
vx[3].z = z;
vx[3].emissiveColor.red = 0xFF;
vx[3].emissiveColor.green = 0xFF;
vx[3].emissiveColor.blue = 0xFF;
vx[3].emissiveColor.alpha = 0xFF;
vx[3].u = 1.0f + uvOffset;
vx[3].v = 1.0f + uvOffset;

RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, vx,4);
return 1;
}

void InvertRaster(RwCamera* cam)
{
rwGameCube2DVertex vx[4];

F32 cam_width = (F32)cam->frameBuffer->width;
F32 cam_height = (F32)cam->frameBuffer->height;

vx[0].x = 0.0f;
vx[0].y = 0.0f;
vx[0].z = RwIm2DGetNearScreenZ();
vx[0].emissiveColor.red = 0xFF;
vx[0].emissiveColor.green = 0xFF;
vx[0].emissiveColor.blue = 0xFF;
vx[0].emissiveColor.alpha = 0xFF;
vx[0].u = 0.0f;
vx[0].v = 0.0f;

vx[1].x = 0.0f;
vx[1].y = cam_height;
vx[1].z = RwIm2DGetNearScreenZ();
vx[1].emissiveColor.red = 0xFF;
vx[1].emissiveColor.green = 0xFF;
vx[1].emissiveColor.blue = 0xFF;
vx[1].emissiveColor.alpha = 0xFF;
vx[1].u = 0.0f;
vx[1].v = 1.0f;

vx[2].x = 0.0f;
vx[2].y = cam_width;
vx[2].z = RwIm2DGetNearScreenZ();
vx[2].emissiveColor.red = 0xFF;
vx[2].emissiveColor.green = 0xFF;
vx[2].emissiveColor.blue = 0xFF;
vx[2].emissiveColor.alpha = 0xFF;
vx[2].u = 1.0f;
vx[2].v = 0.0f;

vx[3].x = cam_width;
vx[3].y = cam_height;
vx[3].z = RwIm2DGetNearScreenZ();
vx[3].emissiveColor.red = 0xFF;
vx[3].emissiveColor.green = 0xFF;
vx[3].emissiveColor.blue = 0xFF;
vx[3].emissiveColor.alpha = 0xFF;
vx[3].u = 1.0f;
vx[3].v = 0.0f;

RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*) 0);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void*) 0);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*) 1);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*) 1);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*) 10);
RwIm2DRenderPrimitive(rwPRIMTYPETRISTRIP, &vx[0], 4);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*) 1);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*) 6);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*) 5);
}

void ShadowCameraDestroy(RwCamera* shadowCamera)
{
if (shadowCamera == NULL)
Expand Down Expand Up @@ -156,6 +299,49 @@ void ShadowCameraDestroy(RwCamera* shadowCamera)
RwCameraDestroy(shadowCamera);
}

RwCamera* ShadowCameraUpdate(RwCamera* shadowCamera, void* model, void(*renderCB)(void*), xVec3* center, F32 radius, S32 invertRasterFlag)
{
RwRGBA bgColor [4];
RwCamera* camera;
S32 fogstate;

bgColor[0].red = 0.0f;
camera = *(RwCamera **)RwEngineInstance;
RwRenderStateGet(rwRENDERSTATEFOGENABLE, &fogstate);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, 0);
if (camera != (RwCamera *)0x0) {
RwCameraEndUpdate(camera);
}
GCSaveFrameBuffer();
shadowCamera->frameBuffer->width = shadowCamera->frameBuffer->width - 1;
shadowCamera->frameBuffer->height = shadowCamera->frameBuffer->height - 1;
RwCameraClear(shadowCamera, bgColor, 1);
shadowCamera->frameBuffer->width = shadowCamera->frameBuffer->width + 1;
shadowCamera->frameBuffer->height = shadowCamera->frameBuffer->height + 1;
RwFrameOrthoNormalize( (RwFrame*) shadowCamera->object.object.parent);
if (RwCameraBeginUpdate(shadowCamera) != 0) {
iCameraFrustumPlanes( shadowCamera, globals.camera.frustplane );
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, 0);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, 0);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, 0);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (RwRaster*) 1U);
if (invertRasterFlag == 0) {
InvertRaster(shadowCamera);
}
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (RwRaster*) 1U);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (RwRaster*) 1U);
RwCameraEndUpdate(shadowCamera);
RwGameCubeCameraTextureFlush(shadowCamera->frameBuffer, 0);
}
if (camera != (RwCamera *)0x0) {
RwCameraBeginUpdate(camera);
iCameraFrustumPlanes(camera, globals.camera.frustplane);
}
GCRestoreFrameBuffer();
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*) fogstate);
return shadowCamera;
}

static RwRaster* ShadowRasterCreate(S32 res)
{
return RwRasterCreate(res, res, 0, 5);
Expand Down Expand Up @@ -213,6 +399,35 @@ static RwCamera* ShadowCameraCreatePersp(S32 param)
return NULL;
}

RwCamera* ShadowCameraSetSpherePersp(RwCamera* camera, RwV3d* center, F32 radius) {

RwFrame* camFrame;
RwMatrixTag* camMatrix;
RwV3d* camPos;
F32 objDepth;
F32 nearZ;
F32 farZ;

camFrame = (RwFrame*) (camera->object.object.parent);
objDepth = 572.95807f * radius;
camMatrix = &camFrame->modelling;
camPos = &camMatrix->pos;
nearZ = objDepth - rscale * radius;
farZ = objDepth + rscale * radius;
camera->nearPlane = nearZ;
camera->farPlane = farZ;
RwCameraSetNearClipPlane(camera, nearZ);
RwCameraSetFarClipPlane(camera, farZ);
camPos = center;
RwV3dIncrementScaledMacro( camPos, &camMatrix->at, -objDepth );
camPos = &camMatrix->at;
gCamPos = *camPos;
RwMatrixUpdate(camMatrix);
RwFrameUpdateObjects(camFrame);
gShadowObjectRadius = radius;
return camera;
}

void xShadowManager_Init(S32 numEnts)
{
sMgrList = (xShadowMgr*)xMemAlloc(gActiveHeap, numEnts << 4, 0);
Expand Down
2 changes: 1 addition & 1 deletion src/SB/Core/x/xShadow.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct xShadowMgr
void xShadowInit();
void xShadow_ListAdd(xEnt* ent);
void xShadowSetWorld(RpWorld* world);
void xShadowSetLight(xVec3* param1, xVec3* param2, F32 param3);
void xShadowSetLight(xVec3* target_pos, xVec3* in_vec, F32 param3);
void xShadowManager_Init(S32 numEnts);
void xShadowManager_Reset();
void xShadowManager_Render();
Expand Down
Loading