Fix bug where portal outline wasn't rendering at deeper levels

recursive portals
This commit is contained in:
James Lambert 2022-05-13 22:45:13 -06:00
parent 1d23162a3e
commit f8e56e2ac5
6 changed files with 108 additions and 67 deletions

View file

@ -2,6 +2,7 @@
#define __MODELS_H__
extern Gfx portal_mask_Circle_mesh[];
extern Gfx portal_mask_Circle_mesh_tri_0[];
extern Gfx portal_outline_portal_outline_mesh[];
extern Gfx* cube_gfx;

View file

@ -42,20 +42,19 @@ Gfx portal_mask_Circle_mesh[] = {
gsSPDisplayList(mat_portal_mask_portal_mask),
gsSPDisplayList(portal_mask_Circle_mesh_tri_0),
gsDPPipeSync(),
gsSPGeometryMode(G_CULL_BACK, G_CULL_FRONT),
gsDPSetPrimColor(0, 0, 0, 128, 255, 0),
gsSP1Triangle(0, 1, 2, 0),
gsSP1Triangle(0, 2, 3, 0),
gsSP1Triangle(2, 4, 3, 0),
gsSP1Triangle(3, 5, 0, 0),
gsSP1Triangle(3, 6, 5, 0),
gsSP1Triangle(5, 7, 0, 0),
gsDPPipeSync(),
gsSPGeometryMode(G_CULL_FRONT, G_CULL_BACK),
// gsSPGeometryMode(G_CULL_BACK, G_CULL_FRONT),
// gsDPSetPrimColor(0, 0, 0, 128, 255, 0),
// gsSP1Triangle(0, 1, 2, 0),
// gsSP1Triangle(0, 2, 3, 0),
// gsSP1Triangle(2, 4, 3, 0),
// gsSP1Triangle(3, 5, 0, 0),
// gsSP1Triangle(3, 6, 5, 0),
// gsSP1Triangle(5, 7, 0, 0),
// gsDPPipeSync(),
// gsSPGeometryMode(G_CULL_FRONT, G_CULL_BACK),
gsSPSetGeometryMode(G_LIGHTING),
gsSPClearGeometryMode(G_TEXTURE_GEN),
gsDPSetCombineLERP(0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT, 0, 0, 0, SHADE, 0, 0, 0, ENVIRONMENT),
gsSPTexture(65535, 65535, 0, 0, 0),
gsSPEndDisplayList(),
};

View file

@ -1,43 +1,43 @@
Vtx portal_outline_portal_outline_mesh_vtx_0[38] = {
{{{79, 152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{120, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, -159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -225, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, -159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-120, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, 152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 225, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, 159, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, -144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, -144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{79, -152, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{102, 0, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, 144, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 204, 0},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{79, 152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{120, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, -159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -225, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, -159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-120, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, 152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 225, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{85, 159, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, -144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, -215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, -144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{79, -152, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{111, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{102, 0, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{-72, 144, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 215, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
{{{0, 204, -1},0, {-16, 1008},{0x0, 0x0, 0x81, 0xFF}}},
};
Gfx portal_outline_portal_outline_mesh_tri_0[] = {
@ -84,7 +84,7 @@ Gfx mat_portal_outline_portal_outline[] = {
gsDPPipeSync(),
gsSPSetGeometryMode(G_SHADE),
gsSPClearGeometryMode(G_LIGHTING),
gsDPSetRenderMode(G_RM_XLU_SURF, G_RM_XLU_SURF2),
gsDPSetRenderMode(G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2),
gsDPSetCombineLERP(0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE, 0, 0, 0, PRIMITIVE),
gsSPTexture(65535, 65535, 0, 0, 1),
gsSPEndDisplayList(),

View file

@ -30,14 +30,35 @@ struct Vector3 gPortalOutlineUnscaled[PORTAL_LOOP_SIZE] = {
{-0.353553f, 0.707107f, 0.0f},
};
#define SHOW_EXTERNAL_VIEW 0
#if SHOW_EXTERNAL_VIEW
struct Vector3 externalCameraPos = {16.0f, 8.0f, -16.0f};
struct Vector3 externalLook = {4.0f, 2.0f, -4.0f};
#endif
struct Quaternion gVerticalFlip = {0.0f, 1.0f, 0.0f, 0.0f};
#define STARTING_RENDER_DEPTH 2
void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState) {
props->camera = *camera;
props->aspectRatio = aspectRatio;
props->perspectiveMatrix = cameraSetupMatrices(camera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport, &props->cullingInfo);
props->viewport = &fullscreenViewport;
props->currentDepth = STARTING_RENDER_DEPTH;
props->fromPortalIndex = NO_PORTAL;
#if SHOW_EXTERNAL_VIEW
struct Camera externalCamera = *camera;
externalCamera.transform.position = externalCameraPos;
struct Vector3 offset;
vector3Sub(&externalLook, &externalCameraPos, &offset);
quatLook(&offset, &gUp, &externalCamera.transform.rotation);
props->perspectiveMatrix = cameraSetupMatrices(&externalCamera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport, NULL);
#endif
props->minX = 0;
props->minY = 0;
@ -94,6 +115,18 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, viewport, &next->cullingInfo);
#if SHOW_EXTERNAL_VIEW
struct Transform externalTransform;
externalTransform.position = externalCameraPos;
externalTransform.scale = gOneVec;
struct Vector3 offset;
vector3Sub(&externalLook, &externalCameraPos, &offset);
quatLook(&offset, &gUp, &externalTransform.rotation);
struct Camera externalCamera = current->camera;
transformConcat(&portalCombined, &externalTransform, &externalCamera.transform);
next->perspectiveMatrix = cameraSetupMatrices(&externalCamera, renderState, (float)SCREEN_WD / (float)SCREEN_HT, &next->perspectiveCorrect, &fullscreenViewport, NULL);
#endif
// set the near clipping plane to be the exit portal surface
quatMultVector(&toPortal->rotation, &gForward, &next->cullingInfo.clippingPlanes[4].normal);
if (toPortal < fromPortal) {
@ -102,9 +135,12 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
next->cullingInfo.clippingPlanes[4].d = -vector3Dot(&next->cullingInfo.clippingPlanes[4].normal, &toPortal->position) * SCENE_SCALE;
next->currentDepth = current->currentDepth - 1;
next->fromPortalIndex = toPortal < fromPortal ? 0 : 1;
#if !SHOW_EXTERNAL_VIEW
gSPViewport(renderState->dl++, viewport);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, next->minX, next->minY, next->maxX, next->maxY);
#endif
}
void portalInit(struct Portal* portal, enum PortalFlags flags) {
@ -138,6 +174,7 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
gDPSetPrimColor(renderState->dl++, 0, 0, 255, 128, 0, 255);
}
gSPDisplayList(renderState->dl++, portal_outline_portal_outline_mesh);
gSPDisplayList(renderState->dl++, portal_mask_Circle_mesh_tri_0);
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
return;
}
@ -148,18 +185,19 @@ void portalRender(struct Portal* portal, struct Portal* otherPortal, struct Rend
screenClipperBoundingPoints(&clipper, gPortalOutline, sizeof(gPortalOutline) / sizeof(*gPortalOutline), &clippingBounds);
if (clippingBounds.min.x < clippingBounds.max.x && clippingBounds.min.y < clippingBounds.max.y) {
struct RenderProps nextProps;
struct RenderProps nextProps;
nextProps.minX = CALC_SCREEN_SPACE(clippingBounds.min.x, SCREEN_WD);
nextProps.maxX = CALC_SCREEN_SPACE(clippingBounds.max.x, SCREEN_WD);
nextProps.minY = CALC_SCREEN_SPACE(-clippingBounds.max.y, SCREEN_HT);
nextProps.maxY = CALC_SCREEN_SPACE(-clippingBounds.min.y, SCREEN_HT);
nextProps.minX = CALC_SCREEN_SPACE(clippingBounds.min.x, SCREEN_WD);
nextProps.maxX = CALC_SCREEN_SPACE(clippingBounds.max.x, SCREEN_WD);
nextProps.minY = CALC_SCREEN_SPACE(-clippingBounds.max.y, SCREEN_HT);
nextProps.maxY = CALC_SCREEN_SPACE(-clippingBounds.min.y, SCREEN_HT);
nextProps.minX = MAX(nextProps.minX, props->minX);
nextProps.maxX = MIN(nextProps.maxX, props->maxX);
nextProps.minY = MAX(nextProps.minY, props->minY);
nextProps.maxY = MIN(nextProps.maxY, props->maxY);
nextProps.minX = MAX(nextProps.minX, props->minX);
nextProps.maxX = MIN(nextProps.maxX, props->maxX);
nextProps.minY = MAX(nextProps.minY, props->minY);
nextProps.maxY = MIN(nextProps.maxY, props->maxY);
if (nextProps.minX < nextProps.maxX && nextProps.minY < nextProps.maxY) {
renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, renderState);
sceneRenderer(data, &nextProps, renderState);

View file

@ -25,6 +25,8 @@ struct RenderProps;
typedef void SceneRenderCallback(void* data, struct RenderProps* properties, struct RenderState* renderState);
#define NO_PORTAL 0xFF
struct RenderProps {
struct Camera camera;
float aspectRatio;
@ -33,17 +35,15 @@ struct RenderProps {
struct FrustrumCullingInformation cullingInfo;
u16 perspectiveCorrect;
short currentDepth;
u8 currentDepth;
u8 fromPortalIndex;
short minX;
short minY;
short maxX;
short maxY;
};
#define STARTING_RENDER_DEPTH 1
void renderPropsInit(struct RenderProps* props, struct Camera* camera, float aspectRatio, struct RenderState* renderState);
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState);

View file

@ -68,8 +68,12 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) > vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
portalRender(&scene->portals[closerPortal], &scene->portals[1 - closerPortal], properties, sceneRenderWithProperties, data, renderState);
portalRender(&scene->portals[1 - closerPortal], &scene->portals[closerPortal], properties, sceneRenderWithProperties, data, renderState);
if (properties->fromPortalIndex != closerPortal) {
portalRender(&scene->portals[closerPortal], &scene->portals[1 - closerPortal], properties, sceneRenderWithProperties, data, renderState);
}
if (properties->fromPortalIndex != 1 - closerPortal) {
portalRender(&scene->portals[1 - closerPortal], &scene->portals[closerPortal], properties, sceneRenderWithProperties, data, renderState);
}
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
@ -115,7 +119,6 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
renderPropsInit(&renderProperties, &scene->camera, (float)SCREEN_WD / (float)SCREEN_HT, renderState);
renderProperties.camera = scene->camera;
renderProperties.currentDepth = STARTING_RENDER_DEPTH;
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);