mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Work on portal rendering bugs
This commit is contained in:
parent
04e889521d
commit
930a4e4bcc
|
@ -2,29 +2,32 @@
|
|||
|
||||
void renderStateInit(struct RenderState* renderState) {
|
||||
renderState->dl = renderState->glist;
|
||||
renderState->currentMatrix = 0;
|
||||
renderState->currentLight = 0;
|
||||
renderState->currentMemoryChunk = 0;
|
||||
renderState->currentChunkEnd = MAX_DL_LENGTH;
|
||||
}
|
||||
|
||||
Mtx* renderStateRequestMatrices(struct RenderState* renderState, unsigned count) {
|
||||
if (renderState->currentMatrix + count <= MAX_ACTIVE_TRANSFORMS) {
|
||||
Mtx* result = &renderState->matrices[renderState->currentMatrix];
|
||||
renderState->currentMatrix += count;
|
||||
void* renderStateRequestMemory(struct RenderState* renderState, unsigned size) {
|
||||
unsigned memorySlots = (size + 7) >> 3;
|
||||
|
||||
if (renderState->currentMemoryChunk + memorySlots <= MAX_RENDER_STATE_MEMORY_CHUNKS) {
|
||||
void* result = &renderState->renderStateMemory[renderState->currentMemoryChunk];
|
||||
renderState->currentMemoryChunk += memorySlots;
|
||||
return result;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Light* renderStateRequestLights(struct RenderState* renderState, unsigned count) {
|
||||
if (renderState->currentLight + count <= MAX_ACTIVE_TRANSFORMS) {
|
||||
Light* result = &renderState->lights[renderState->currentLight];
|
||||
renderState->currentLight += count;
|
||||
return result;
|
||||
}
|
||||
Mtx* renderStateRequestMatrices(struct RenderState* renderState, unsigned count) {
|
||||
return renderStateRequestMemory(renderState, sizeof(Mtx) * count);
|
||||
}
|
||||
|
||||
return 0;
|
||||
Light* renderStateRequestLights(struct RenderState* renderState, unsigned count) {
|
||||
return renderStateRequestMemory(renderState, sizeof(Light) * count);
|
||||
}
|
||||
|
||||
Vp* renderStateRequestViewport(struct RenderState* renderState) {
|
||||
return renderStateRequestMemory(renderState, sizeof(Vp));
|
||||
}
|
||||
|
||||
void renderStateFlushCache(struct RenderState* renderState) {
|
||||
|
|
|
@ -4,22 +4,22 @@
|
|||
#include <ultra64.h>
|
||||
|
||||
#define MAX_DL_LENGTH 2000
|
||||
#define MAX_ACTIVE_TRANSFORMS 100
|
||||
#define MAX_RENDER_STATE_MEMORY 6400
|
||||
#define MAX_RENDER_STATE_MEMORY_CHUNKS (MAX_RENDER_STATE_MEMORY / sizeof(u64))
|
||||
#define MAX_DYNAMIC_LIGHTS 128
|
||||
|
||||
struct RenderState {
|
||||
Gfx glist[MAX_DL_LENGTH];
|
||||
Mtx matrices[MAX_ACTIVE_TRANSFORMS];
|
||||
Light lights[MAX_DYNAMIC_LIGHTS];
|
||||
u64 renderStateMemory[MAX_RENDER_STATE_MEMORY_CHUNKS];
|
||||
Gfx* dl;
|
||||
unsigned short currentMatrix;
|
||||
unsigned short currentLight;
|
||||
unsigned currentChunkEnd;
|
||||
unsigned short currentMemoryChunk;
|
||||
unsigned short currentChunkEnd;
|
||||
};
|
||||
|
||||
void renderStateInit(struct RenderState* renderState);
|
||||
Mtx* renderStateRequestMatrices(struct RenderState* renderState, unsigned count);
|
||||
Light* renderStateRequestLights(struct RenderState* renderState, unsigned count);
|
||||
Vp* renderStateRequestViewport(struct RenderState* renderState);
|
||||
void renderStateFlushCache(struct RenderState* renderState);
|
||||
Gfx* renderStateAllocateDLChunk(struct RenderState* renderState, unsigned count);
|
||||
Gfx* renderStateReplaceDL(struct RenderState* renderState, Gfx* nextDL);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "util/memory.h"
|
||||
#include "string.h"
|
||||
#include "controls/controller.h"
|
||||
#include "scene/dynamic_scene.h"
|
||||
|
||||
#include "levels/levels.h"
|
||||
|
||||
|
@ -129,6 +130,7 @@ static void gameProc(void* arg) {
|
|||
heapInit(_heapStart, memoryEnd);
|
||||
romInit();
|
||||
|
||||
dynamicSceneInit();
|
||||
contactSolverInit(&gContactSolver);
|
||||
levelLoad(0);
|
||||
sceneInit(&gScene);
|
||||
|
|
|
@ -48,7 +48,9 @@ void collisionObjectCollideWithQuad(struct CollisionObject* object, struct Colli
|
|||
return;
|
||||
}
|
||||
|
||||
contactSolverAssign(contact, &localContact, 1);
|
||||
if (contactSolverAssign(contact, &localContact, 1) && object->body) {
|
||||
object->body->flags |= RigidBodyIsTouchingPortal;
|
||||
}
|
||||
} else if (contact) {
|
||||
contactSolverRemoveContact(contactSolver, contact);
|
||||
}
|
||||
|
|
|
@ -379,7 +379,7 @@ struct ContactState* contactSolverGetContact(struct ContactConstraintState* cont
|
|||
return result;
|
||||
}
|
||||
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts) {
|
||||
int contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts) {
|
||||
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||
int targetIndex;
|
||||
|
||||
|
@ -399,9 +399,11 @@ void contactSolverAssign(struct ContactConstraintState* into, struct ContactCons
|
|||
}
|
||||
|
||||
int copiedCount = 0;
|
||||
int result = 0;
|
||||
|
||||
for (int sourceIndex = 0; sourceIndex < from->contactCount; ++sourceIndex) {
|
||||
if (filterPortalContacts && collisionSceneIsTouchingPortal(&from->contacts[sourceIndex].ra)) {
|
||||
result = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -415,4 +417,6 @@ void contactSolverAssign(struct ContactConstraintState* into, struct ContactCons
|
|||
into->normal = from->normal;
|
||||
into->restitution = from->restitution;
|
||||
into->friction = from->friction;
|
||||
|
||||
return result;
|
||||
}
|
|
@ -62,7 +62,7 @@ void contactSolverRemoveContact(struct ContactSolver* solver, struct ContactCons
|
|||
|
||||
struct ContactState* contactSolverGetContact(struct ContactConstraintState* contact, int id);
|
||||
|
||||
void contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts);
|
||||
int contactSolverAssign(struct ContactConstraintState* into, struct ContactConstraintState* from, int filterPortalContacts);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -73,6 +73,10 @@ void rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
|||
|
||||
enum RigidBodyFlags newFlags = 0;
|
||||
|
||||
if (rigidBody->flags & RigidBodyIsTouchingPortal) {
|
||||
newFlags |= RigidBodyWasTouchingPortal;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
transformPointInverse(gCollisionScene.portalTransforms[i], &rigidBody->transform.position, &localPoint);
|
||||
|
||||
|
@ -143,7 +147,9 @@ void rigidBodyCheckPortals(struct RigidBody* rigidBody) {
|
|||
RigidBodyFlagsInFrontPortal1 |
|
||||
RigidBodyFlagsPortalsInactive |
|
||||
RigidBodyFlagsCrossedPortal0 |
|
||||
RigidBodyFlagsCrossedPortal1
|
||||
RigidBodyFlagsCrossedPortal1 |
|
||||
RigidBodyIsTouchingPortal |
|
||||
RigidBodyWasTouchingPortal
|
||||
);
|
||||
rigidBody->flags |= newFlags;
|
||||
}
|
|
@ -11,6 +11,8 @@ enum RigidBodyFlags {
|
|||
RigidBodyFlagsCrossedPortal0 = (1 << 3),
|
||||
RigidBodyFlagsCrossedPortal1 = (1 << 4),
|
||||
RigidBodyFlagsGrabbable = (1 << 5),
|
||||
RigidBodyIsTouchingPortal = (1 << 6),
|
||||
RigidBodyWasTouchingPortal = (1 << 7),
|
||||
};
|
||||
|
||||
struct RigidBody {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "camera.h"
|
||||
#include "math/transform.h"
|
||||
#include "defs.h"
|
||||
#include "../graphics/graphics.h"
|
||||
|
||||
void cameraInit(struct Camera* camera, float fov, float near, float far) {
|
||||
transformInitIdentity(&camera->transform);
|
||||
|
@ -28,7 +29,7 @@ void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16*
|
|||
guPerspectiveF(matrix, perspectiveNormalize, camera->fov, aspectRatio, camera->nearPlane * planeScalar, camera->farPlane * planeScalar, 1.0f);
|
||||
}
|
||||
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm) {
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport) {
|
||||
Mtx* viewProjMatrix = renderStateRequestMatrices(renderState, 2);
|
||||
|
||||
if (!viewProjMatrix) {
|
||||
|
@ -42,9 +43,18 @@ Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState,
|
|||
float persp[4][4];
|
||||
float combined[4][4];
|
||||
|
||||
cameraBuildViewMatrix(camera, view);
|
||||
float scaleX = viewport->vp.vscale[0] * (1.0f / (SCREEN_WD << 1));
|
||||
float scaleY = viewport->vp.vscale[1] * (1.0f / (SCREEN_HT << 1));
|
||||
|
||||
float centerX = ((float)viewport->vp.vtrans[0] - (SCREEN_WD << 1)) * (1.0f / (SCREEN_WD << 1));
|
||||
float centerY = ((SCREEN_HT << 1) - (float)viewport->vp.vtrans[1]) * (1.0f / (SCREEN_HT << 1));
|
||||
|
||||
guOrthoF(combined, centerX - scaleX, centerX + scaleX, centerY - scaleY, centerY + scaleY, 1.0f, -1.0f, 1.0f);
|
||||
u16 perspectiveNormalize;
|
||||
cameraBuildProjectionMatrix(camera, persp, &perspectiveNormalize, aspectRatio);
|
||||
cameraBuildProjectionMatrix(camera, view, &perspectiveNormalize, aspectRatio);
|
||||
guMtxCatF(view, combined, persp);
|
||||
|
||||
cameraBuildViewMatrix(camera, view);
|
||||
guMtxCatF(view, persp, combined);
|
||||
guMtxF2L(combined, &viewProjMatrix[1]);
|
||||
|
||||
|
|
|
@ -18,6 +18,6 @@ struct Camera {
|
|||
void cameraInit(struct Camera* camera, float fov, float near, float far);
|
||||
void cameraBuildViewMatrix(struct Camera* camera, float matrix[4][4]);
|
||||
void cameraBuildProjectionMatrix(struct Camera* camera, float matrix[4][4], u16* perspectiveNorm, float aspectRatio);
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm);
|
||||
Mtx* cameraSetupMatrices(struct Camera* camera, struct RenderState* renderState, float aspectRatio, u16* perspNorm, Vp* viewport);
|
||||
|
||||
#endif
|
|
@ -5,6 +5,7 @@
|
|||
#include "../graphics/debug_render.h"
|
||||
#include "levels/levels.h"
|
||||
#include "physics/collision_scene.h"
|
||||
#include "dynamic_scene.h"
|
||||
|
||||
struct CollisionBox gCubeCollisionBox = {
|
||||
{0.3165f, 0.3165f, 0.3165f}
|
||||
|
@ -57,18 +58,8 @@ struct ColliderTypeData gCubeCollider = {
|
|||
&gCollisionBoxCallbacks,
|
||||
};
|
||||
|
||||
void cubeInit(struct Cube* cube) {
|
||||
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 1.0f);
|
||||
collisionSceneAddDynamicObject(&cube->collisionObject);
|
||||
|
||||
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||
}
|
||||
|
||||
void cubeUpdate(struct Cube* cube) {
|
||||
|
||||
}
|
||||
|
||||
void cubeRender(struct Cube* cube, struct RenderState* renderState) {
|
||||
void cubeRender(void* data, struct RenderState* renderState) {
|
||||
struct Cube* cube = (struct Cube*)data;
|
||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
||||
transformToMatrixL(&cube->rigidBody.transform, matrix, SCENE_SCALE);
|
||||
|
||||
|
@ -76,3 +67,20 @@ void cubeRender(struct Cube* cube, struct RenderState* renderState) {
|
|||
gSPDisplayList(renderState->dl++, cube_CubeSimpleBevel_mesh);
|
||||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||
}
|
||||
|
||||
void cubeInit(struct Cube* cube) {
|
||||
collisionObjectInit(&cube->collisionObject, &gCubeCollider, &cube->rigidBody, 1.0f);
|
||||
collisionSceneAddDynamicObject(&cube->collisionObject);
|
||||
|
||||
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||
|
||||
cube->dynamicId = dynamicSceneAdd(cube, cubeRender);
|
||||
}
|
||||
|
||||
void cubeUpdate(struct Cube* cube) {
|
||||
if (cube->rigidBody.flags & (RigidBodyIsTouchingPortal | RigidBodyWasTouchingPortal)) {
|
||||
dynamicSceneSetFlags(cube->dynamicId, DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL);
|
||||
} else {
|
||||
dynamicSceneClearFlags(cube->dynamicId, DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
struct Cube {
|
||||
struct CollisionObject collisionObject;
|
||||
struct RigidBody rigidBody;
|
||||
short dynamicId;
|
||||
};
|
||||
|
||||
void cubeInit(struct Cube* cube);
|
||||
void cubeUpdate(struct Cube* cube);
|
||||
void cubeRender(struct Cube* cube, struct RenderState* renderState);
|
||||
|
||||
#endif
|
54
src/scene/dynamic_scene.c
Normal file
54
src/scene/dynamic_scene.c
Normal file
|
@ -0,0 +1,54 @@
|
|||
#include "dynamic_scene.h"
|
||||
|
||||
struct DynamicScene gDynamicScene;
|
||||
|
||||
void dynamicSceneInit() {
|
||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||
gDynamicScene.objects[i].flags = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void dynamicSceneRender(struct RenderState* renderState, int touchingPortals) {
|
||||
int flagMask = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL;
|
||||
int flagValue = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
||||
|
||||
if (touchingPortals) {
|
||||
flagValue |= DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL;
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||
if ((gDynamicScene.objects[i].flags & flagMask) == flagValue) {
|
||||
gDynamicScene.objects[i].renderCallback(gDynamicScene.objects[i].data, renderState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback) {
|
||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||
if (!(gDynamicScene.objects[i].flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
||||
gDynamicScene.objects[i].flags = DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE;
|
||||
gDynamicScene.objects[i].data = data;
|
||||
gDynamicScene.objects[i].renderCallback = renderCallback;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return INVALID_DYNAMIC_OBJECT;
|
||||
}
|
||||
|
||||
void dynamicSceneRemove(int id) {
|
||||
if (id < 0 || id >= MAX_DYNAMIC_SCENE_OBJECTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
gDynamicScene.objects[id].flags = 0;
|
||||
}
|
||||
|
||||
void dynamicSceneSetFlags(int id, int flags) {
|
||||
gDynamicScene.objects[id].flags |= flags;
|
||||
}
|
||||
|
||||
void dynamicSceneClearFlags(int id, int flags) {
|
||||
gDynamicScene.objects[id].flags &= ~flags;
|
||||
|
||||
}
|
35
src/scene/dynamic_scene.h
Normal file
35
src/scene/dynamic_scene.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
#ifndef __DYNAMIC_SCENE_H__
|
||||
#define __DYNAMIC_SCENE_H__
|
||||
|
||||
#include "../graphics/renderstate.h"
|
||||
|
||||
typedef void (*DynamicRender)(void* data, struct RenderState* renderState);
|
||||
|
||||
#define MAX_DYNAMIC_SCENE_OBJECTS 32
|
||||
|
||||
#define DYNAMIC_SCENE_OBJECT_FLAGS_USED (1 << 0)
|
||||
#define DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE (1 << 1)
|
||||
#define DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL (1 << 2)
|
||||
|
||||
#define INVALID_DYNAMIC_OBJECT -1
|
||||
|
||||
struct DynamicSceneObject {
|
||||
void* data;
|
||||
DynamicRender renderCallback;
|
||||
int flags;
|
||||
};
|
||||
|
||||
struct DynamicScene {
|
||||
struct DynamicSceneObject objects[MAX_DYNAMIC_SCENE_OBJECTS];
|
||||
};
|
||||
|
||||
void dynamicSceneInit();
|
||||
|
||||
void dynamicSceneRender(struct RenderState* renderState, int touchingPortals);
|
||||
|
||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback);
|
||||
void dynamicSceneRemove(int id);
|
||||
void dynamicSceneSetFlags(int id, int flags);
|
||||
void dynamicSceneClearFlags(int id, int flags);
|
||||
|
||||
#endif
|
|
@ -4,6 +4,7 @@
|
|||
#include "../graphics/screen_clipper.h"
|
||||
#include "../graphics/graphics.h"
|
||||
#include "../defs.h"
|
||||
#include "dynamic_scene.h"
|
||||
|
||||
#define CALC_SCREEN_SPACE(clip_space, screen_size) ((clip_space + 1.0f) * ((screen_size) / 2))
|
||||
|
||||
|
@ -34,7 +35,8 @@ struct Quaternion gVerticalFlip = {0.0f, 1.0f, 0.0f, 0.0f};
|
|||
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);
|
||||
props->perspectiveMatrix = cameraSetupMatrices(camera, renderState, aspectRatio, &props->perspectiveCorrect, &fullscreenViewport);
|
||||
props->viewport = &fullscreenViewport;
|
||||
props->currentDepth = STARTING_RENDER_DEPTH;
|
||||
|
||||
props->minX = 0;
|
||||
|
@ -43,7 +45,7 @@ void renderPropsInit(struct RenderProps* props, struct Camera* camera, float asp
|
|||
props->maxY = SCREEN_HT;
|
||||
}
|
||||
|
||||
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, short minX, short minY, short maxX, short maxY, struct RenderState* renderState) {
|
||||
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState) {
|
||||
struct Transform otherInverse;
|
||||
transformInvert(fromPortal, &otherInverse);
|
||||
struct Transform portalCombined;
|
||||
|
@ -53,16 +55,30 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
|
|||
next->aspectRatio = current->aspectRatio;
|
||||
transformConcat(&portalCombined, ¤t->camera.transform, &next->camera.transform);
|
||||
|
||||
next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect);
|
||||
// render any objects halfway through portals
|
||||
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport);
|
||||
dynamicSceneRender(renderState, 1);
|
||||
|
||||
Vp* viewport = renderStateRequestViewport(renderState);
|
||||
|
||||
viewport->vp.vscale[0] = (next->maxX - next->minX) << 1;
|
||||
viewport->vp.vscale[1] = (next->maxY - next->minY) << 1;
|
||||
viewport->vp.vscale[2] = G_MAXZ/2;
|
||||
viewport->vp.vscale[3] = 0;
|
||||
|
||||
viewport->vp.vtrans[0] = (next->maxX + next->minX) << 1;
|
||||
viewport->vp.vtrans[1] = (next->maxY + next->minY) << 1;
|
||||
viewport->vp.vtrans[2] = G_MAXZ/2;
|
||||
viewport->vp.vtrans[3] = 0;
|
||||
|
||||
next->viewport = viewport;
|
||||
|
||||
next->perspectiveMatrix = cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, viewport);
|
||||
|
||||
next->currentDepth = current->currentDepth - 1;
|
||||
|
||||
next->minX = minX;
|
||||
next->minY = minY;
|
||||
next->maxX = maxX;
|
||||
next->maxY = maxY;
|
||||
|
||||
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, minX, minY, maxX, maxY);
|
||||
gSPViewport(renderState->dl++, viewport);
|
||||
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, next->minX, next->minY, next->maxX, next->maxY);
|
||||
}
|
||||
|
||||
void portalInit(struct Portal* portal, enum PortalFlags flags) {
|
||||
|
@ -107,19 +123,26 @@ 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) {
|
||||
int minX = CALC_SCREEN_SPACE(clippingBounds.min.x, SCREEN_WD);
|
||||
int maxX = CALC_SCREEN_SPACE(clippingBounds.max.x, SCREEN_WD);
|
||||
int minY = CALC_SCREEN_SPACE(-clippingBounds.max.y, SCREEN_HT);
|
||||
int maxY = CALC_SCREEN_SPACE(-clippingBounds.min.y, SCREEN_HT);
|
||||
|
||||
struct RenderProps nextProps;
|
||||
renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, minX, minY, maxX, maxY, renderState);
|
||||
|
||||
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);
|
||||
|
||||
renderPropsNext(props, &nextProps, &portal->transform, &otherPortal->transform, renderState);
|
||||
sceneRenderer(data, &nextProps, renderState);
|
||||
|
||||
// revert to previous state
|
||||
gSPMatrix(renderState->dl++, osVirtualToPhysical(props->perspectiveMatrix), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH);
|
||||
gSPPerspNormalize(renderState->dl++, props->perspectiveCorrect);
|
||||
gDPSetScissor(renderState->dl++, G_SC_NON_INTERLACE, props->minX, props->minY, props->maxX, props->maxY);
|
||||
gSPViewport(renderState->dl++, props->viewport);
|
||||
|
||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ struct RenderProps {
|
|||
struct Camera camera;
|
||||
float aspectRatio;
|
||||
Mtx* perspectiveMatrix;
|
||||
Vp* viewport;
|
||||
u16 perspectiveCorrect;
|
||||
short currentDepth;
|
||||
|
||||
|
@ -38,7 +39,7 @@ struct RenderProps {
|
|||
#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, short minX, short minY, short maxX, short maxY, struct RenderState* renderState);
|
||||
void renderPropsNext(struct RenderProps* current, struct RenderProps* next, struct Transform* fromPortal, struct Transform* toPortal, struct RenderState* renderState);
|
||||
|
||||
void portalInit(struct Portal* portal, enum PortalFlags flags);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../scene/portal_surface.h"
|
||||
#include "../math/mathf.h"
|
||||
#include "./hud.h"
|
||||
#include "dynamic_scene.h"
|
||||
|
||||
struct Vector3 gStartPosition = {5.0f, 1.2f, -5.0f};
|
||||
|
||||
|
@ -67,7 +68,7 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
|
|||
|
||||
staticRender(renderState);
|
||||
|
||||
cubeRender(&scene->cube, renderState);
|
||||
dynamicSceneRender(renderState, 0);
|
||||
}
|
||||
|
||||
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
||||
|
@ -92,6 +93,10 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
|||
renderProperties.camera = scene->camera;
|
||||
renderProperties.currentDepth = STARTING_RENDER_DEPTH;
|
||||
|
||||
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
||||
|
||||
dynamicSceneRender(renderState, 1);
|
||||
|
||||
sceneRenderWithProperties(scene, &renderProperties, renderState);
|
||||
|
||||
gDPPipeSync(renderState->dl++);
|
||||
|
@ -130,6 +135,8 @@ void sceneUpdate(struct Scene* scene) {
|
|||
playerUpdate(&scene->player, &scene->camera.transform);
|
||||
sceneCheckPortals(scene);
|
||||
|
||||
cubeUpdate(&scene->cube);
|
||||
|
||||
collisionSceneUpdateDynamics();
|
||||
|
||||
scene->cpuTime = osGetTime() - frameStart;
|
||||
|
|
Loading…
Reference in a new issue