From 054a365b42e47c9b552656eda0e1ff3e7247852d Mon Sep 17 00:00:00 2001 From: daft7 Date: Fri, 7 Aug 2026 15:30:11 -0500 Subject: [PATCH 1/2] These get used in xShadowRenderWorld but I scrapped what I had. --- src/SB/Core/x/xShadow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/SB/Core/x/xShadow.cpp b/src/SB/Core/x/xShadow.cpp index 455668da4..c45aa4f5b 100644 --- a/src/SB/Core/x/xShadow.cpp +++ b/src/SB/Core/x/xShadow.cpp @@ -3,8 +3,10 @@ #include "rpworld.h" #include "xMath.h" +#include "iCollide.h" #include "iModel.h" #include "zGlobals.h" +#include "zGrid.h" #include From d21568eb53014508d515cd11b8745368747482ee Mon Sep 17 00:00:00 2001 From: daft7 Date: Fri, 7 Aug 2026 15:30:27 -0500 Subject: [PATCH 2/2] xShadow progress --- src/SB/Core/x/xShadow.cpp | 221 +++++++++++++++++++++++++++++++++++++- src/SB/Core/x/xShadow.h | 2 +- 2 files changed, 218 insertions(+), 5 deletions(-) diff --git a/src/SB/Core/x/xShadow.cpp b/src/SB/Core/x/xShadow.cpp index c45aa4f5b..ce9b6faa1 100644 --- a/src/SB/Core/x/xShadow.cpp +++ b/src/SB/Core/x/xShadow.cpp @@ -1,5 +1,6 @@ #include "xShadow.h" +#include "rpcollis.h" #include "rpworld.h" #include "xMath.h" @@ -17,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); @@ -34,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() { @@ -88,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); @@ -121,11 +146,127 @@ S32 xShadowReceiveShadowSetup(xEnt* ent) return 0; } +void xShadowRender(xEnt* ent, F32 max_dist) { + xVec3 center; + F32 radius; + + zEntGetShadowParams(ent, ¢er, &radius, (xEntShadow::radius_enum) 1); + xShadowCameraUpdate(ent->model, modelRenderCB, ¢er, radius, 0); + xShadowRender(¢er, 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) @@ -158,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); @@ -215,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); diff --git a/src/SB/Core/x/xShadow.h b/src/SB/Core/x/xShadow.h index add2c54bb..96d66f3d7 100644 --- a/src/SB/Core/x/xShadow.h +++ b/src/SB/Core/x/xShadow.h @@ -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();