A little less borken

This commit is contained in:
James Lambert 2022-11-13 21:22:49 -07:00
parent 5db7dc544a
commit be383858f3
4 changed files with 73 additions and 78 deletions

View file

@ -54,7 +54,7 @@ void renderPropsInit(struct RenderProps* props, struct Camera* camera, float asp
props->camera = *camera;
props->aspectRatio = aspectRatio;
cameraSetupMatrices(camera, renderState, aspectRatio, &fullscreenViewport, &props->cameraMatrixInfo);
cameraApplyMatrices(renderState, &props->cameraMatrixInfo);
props->viewport = &fullscreenViewport;
props->currentDepth = STARTING_RENDER_DEPTH;
props->exitPortalIndex = NO_PORTAL;

View file

@ -40,6 +40,8 @@ typedef void SceneRenderCallback(void* data, struct RenderProps* properties, str
#define PORTAL_RENDER_TYPE_ENABLED_0 (1 << 2)
#define PORTAL_RENDER_TYPE_ENABLED_1 (1 << 3)
#define PORTAL_RENDER_TYPE_SECOND_CLOSER (1 << 4)
#define PORTAL_RENDER_TYPE_VISIBLE(portalIndex) (PORTAL_RENDER_TYPE_VISIBLE_0 << (portalIndex))
#define PORTAL_RENDER_TYPE_ENABLED(portalIndex) (PORTAL_RENDER_TYPE_ENABLED_0 << (portalIndex))

View file

@ -21,8 +21,9 @@ extern struct Vector3 gPortalOutline[PORTAL_LOOP_SIZE];
#define CALC_SCREEN_SPACE(clip_space, screen_size) ((clip_space + 1.0f) * ((screen_size) / 2))
int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct RenderProps* current, int exitPortalIndex, struct RenderState* renderState) {
struct Portal* portal = &scene->portals[1 - exitPortalIndex];
int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct RenderProps* current, int portalIndex, struct RenderState* renderState) {
int exitPortalIndex = 1 - portalIndex;
struct Portal* portal = &scene->portals[portalIndex];
struct Vector3 forward = gForward;
if (!(portal->flags & PortalFlagsOddParity)) {
@ -40,23 +41,11 @@ int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct
return 0;
}
int flags = PORTAL_RENDER_TYPE_VISIBLE(portalIndex);
float portalTransform[4][4];
struct Transform finalTransform;
finalTransform = portal->transform;
if (portal->flags & PortalFlagsOddParity) {
quatMultiply(&portal->transform.rotation, &gVerticalFlip, &finalTransform.rotation);
}
vector3Scale(&gOneVec, &finalTransform.scale, portal->scale);
transformToMatrix(&finalTransform, portalTransform, SCENE_SCALE);
int portalIndex = 1 - exitPortalIndex;
int flags = PORTAL_RENDER_TYPE_VISIBLE(portalIndex);
portalDetermineTransform(portal, portalTransform);
if (current->currentDepth == 0 || !collisionSceneIsPortalOpen() || renderPlan->stageCount >= MAX_PORTAL_STEPS) {
return flags;
@ -89,20 +78,20 @@ int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct
return 0;
}
struct Transform* fromPortal = &scene->portals[portalIndex].transform;
struct Transform* exitPortal = &scene->portals[exitPortalIndex].transform;
struct Transform* intoPortal = &scene->portals[1 - exitPortalIndex].transform;
struct Transform otherInverse;
transformInvert(exitPortal, &otherInverse);
transformInvert(fromPortal, &otherInverse);
struct Transform portalCombined;
transformConcat(intoPortal, &otherInverse, &portalCombined);
transformConcat(exitPortal, &otherInverse, &portalCombined);
next->camera = current->camera;
next->aspectRatio = current->aspectRatio;
transformConcat(&portalCombined, &current->camera.transform, &next->camera.transform);
struct Vector3 portalOffset;
vector3Sub(&intoPortal->position, &next->camera.transform.position, &portalOffset);
vector3Sub(&exitPortal->position, &next->camera.transform.position, &portalOffset);
struct Vector3 cameraForward;
quatMultVector(&next->camera.transform.rotation, &gForward, &cameraForward);
@ -130,11 +119,11 @@ int renderPlanPortal(struct RenderPlan* renderPlan, struct Scene* scene, struct
if (current->clippingPortalIndex == -1) {
// set the near clipping plane to be the exit portal surface
quatMultVector(&intoPortal->rotation, &gForward, &next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal);
if (intoPortal < exitPortal) {
quatMultVector(&exitPortal->rotation, &gForward, &next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal);
if (exitPortal < fromPortal) {
vector3Negate(&next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal, &next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal);
}
next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].d = -vector3Dot(&next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal, &intoPortal->position) * SCENE_SCALE;
next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].d = -vector3Dot(&next->cameraMatrixInfo.cullingInformation.clippingPlanes[4].normal, &exitPortal->position) * SCENE_SCALE;
}
next->clippingPortalIndex = -1;
@ -156,30 +145,33 @@ void renderPlanFinishView(struct RenderPlan* renderPlan, struct Scene* scene, st
staticRenderDetermineVisibleRooms(&properties->cameraMatrixInfo.cullingInformation, properties->fromRoom, &properties->visiblerooms);
int closerPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) > vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
int otherPortal = 1 - closerPortal;
int furtherPortal = vector3DistSqrd(&properties->camera.transform.position, &scene->portals[0].transform.position) > vector3DistSqrd(&properties->camera.transform.position, &scene->portals[1].transform.position) ? 0 : 1;
int otherPortal = 1 - furtherPortal;
if (!furtherPortal) {
properties->portalRenderType |= PORTAL_RENDER_TYPE_SECOND_CLOSER;
}
for (int i = 0; i < 2; ++i) {
if (gCollisionScene.portalTransforms[closerPortal] &&
properties->exitPortalIndex != closerPortal &&
staticRenderIsRoomVisible(properties->visiblerooms, gCollisionScene.portalRooms[closerPortal])) {
if (gCollisionScene.portalTransforms[furtherPortal] &&
properties->exitPortalIndex != furtherPortal &&
staticRenderIsRoomVisible(properties->visiblerooms, gCollisionScene.portalRooms[furtherPortal])) {
properties->portalRenderType |= renderPlanPortal(
renderPlan,
scene,
properties,
closerPortal,
furtherPortal,
renderState
);
}
closerPortal = 1 - closerPortal;
furtherPortal = 1 - furtherPortal;
otherPortal = 1 - otherPortal;
}
}
void renderPlanBuild(struct RenderPlan* renderPlan, struct Scene* scene, struct RenderState* renderState) {
renderPropsInit(&renderPlan->stageProps[0], &scene->camera, (float)SCREEN_WD / (float)SCREEN_HT, renderState, scene->player.body.currentRoom);
renderPlan->stageProps[0].camera = scene->camera;
renderPlan->stageCount = 1;
renderPlanFinishView(renderPlan, scene, &renderPlan->stageProps[0], renderState);
@ -195,55 +187,51 @@ void renderPlanExecute(struct RenderPlan* renderPlan, struct Scene* scene, struc
gSPViewport(renderState->dl++, current->viewport);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, current->minX, current->minY, current->maxX, current->maxY);
int portalIndex = (current->portalRenderType & PORTAL_RENDER_TYPE_SECOND_CLOSER) ? 1 : 0;
for (int i = 0; i < 2; ++i) {
if ((current->portalRenderType & (PORTAL_RENDER_TYPE_VISIBLE(i) | PORTAL_RENDER_TYPE_ENABLED(i))) == PORTAL_RENDER_TYPE_VISIBLE(i)) {
if (current->portalRenderType & PORTAL_RENDER_TYPE_VISIBLE(portalIndex)) {
float portalTransform[4][4];
struct Portal* portal = &scene->portals[i];
struct Portal* portal = &scene->portals[portalIndex];
portalDetermineTransform(portal, portalTransform);
portalRenderCover(portal, portalTransform, renderState);
if (current->portalRenderType & PORTAL_RENDER_TYPE_ENABLED(portalIndex)) {
// render the front portal cover
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
if (!matrix) {
continue;;
}
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
gDPSetEnvColor(renderState->dl++, 255, 255, 255, portal->opacity < 0.0f ? 0 : (portal->opacity > 1.0f ? 255 : (u8)(portal->opacity * 255.0f)));
if (portal->flags & PortalFlagsOddParity) {
gSPDisplayList(renderState->dl++, portal_portal_blue_face_model_gfx);
portalRenderScreenCover(current->clipper.nearPolygon, current->clipper.nearPolygonCount, current, renderState);
gDPPipeSync(renderState->dl++);
gSPDisplayList(renderState->dl++, portal_portal_blue_model_gfx);
} else {
gSPDisplayList(renderState->dl++, portal_portal_orange_face_model_gfx);
portalRenderScreenCover(current->clipper.nearPolygon, current->clipper.nearPolygonCount, current, renderState);
gDPPipeSync(renderState->dl++);
gSPDisplayList(renderState->dl++, portal_portal_orange_model_gfx);
}
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
} else {
portalRenderCover(portal, portalTransform, renderState);
}
}
portalIndex = 1 - portalIndex;
}
staticRender(&current->camera.transform, &current->cameraMatrixInfo.cullingInformation, current->visiblerooms, renderState);
if (current->previousProperties && (current->previousProperties->portalRenderType & PORTAL_RENDER_TYPE_VISIBLE(1 - current->exitPortalIndex))) {
gSPMatrix(renderState->dl++, osVirtualToPhysical(current->previousProperties->cameraMatrixInfo.projectionView), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
gSPPerspNormalize(renderState->dl++, current->previousProperties->cameraMatrixInfo.perspectiveNormalize);
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, current->previousProperties->minX, current->previousProperties->minY, current->previousProperties->maxX, current->previousProperties->maxY);
gSPViewport(renderState->dl++, current->previousProperties->viewport);
float portalTransform[4][4];
struct Portal* portal = &scene->portals[i];
portalDetermineTransform(portal, portalTransform);
// render the front portal cover
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
if (!matrix) {
return;
}
guMtxF2L(portalTransform, matrix);
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
gDPSetEnvColor(renderState->dl++, 255, 255, 255, portal->opacity < 0.0f ? 0 : (portal->opacity > 1.0f ? 255 : (u8)(portal->opacity * 255.0f)));
if (portal->flags & PortalFlagsOddParity) {
gSPDisplayList(renderState->dl++, portal_portal_blue_face_model_gfx);
portalRenderScreenCover(current->clipper.nearPolygon, current->clipper.nearPolygonCount, current, renderState);
gDPPipeSync(renderState->dl++);
gSPDisplayList(renderState->dl++, portal_portal_blue_model_gfx);
} else {
gSPDisplayList(renderState->dl++, portal_portal_orange_face_model_gfx);
portalRenderScreenCover(current->clipper.nearPolygon, current->clipper.nearPolygonCount, current, renderState);
gDPPipeSync(renderState->dl++);
gSPDisplayList(renderState->dl++, portal_portal_orange_model_gfx);
}
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
}
}
}

View file

@ -28,6 +28,7 @@
#include "../util/memory.h"
#include "../decor/decor_object_list.h"
#include "signals.h"
#include "render_plan.h"
struct Vector3 gPortalGunOffset = {0.120957, -0.113587, -0.20916};
struct Vector3 gPortalGunForward = {0.1f, -0.1f, 1.0f};
@ -207,12 +208,16 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
struct RenderProps renderProperties;
renderPropsInit(&renderProperties, &scene->camera, (float)SCREEN_WD / (float)SCREEN_HT, renderState, scene->player.body.currentRoom);
renderProperties.camera = scene->camera;
cameraApplyMatrices(renderState, &renderProperties.cameraMatrixInfo);
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
sceneRenderWithProperties(scene, &renderProperties, renderState);
struct RenderPlan renderPlan;
renderPlanBuild(&renderPlan, scene, renderState);
renderPlanExecute(&renderPlan, scene, renderState);
// sceneRenderWithProperties(scene, &renderProperties, renderState);
sceneRenderPortalGun(scene, renderState);