mirror of
https://github.com/mwpenny/portal64-still-alive.git
synced 2024-10-20 10:37:37 -04:00
Refactor rendering pipeline
This commit is contained in:
parent
e65b6dbfec
commit
334b1561b8
|
@ -54,3 +54,10 @@ BLENDER_2_9=/blender/blender docker run -v /home/james/Blender/blender-2.93.1-li
|
||||||
where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender is located
|
where `/home/james/Blender/blender-2.93.1-linux-x64` is the folder where blender is located
|
||||||
`/home/james/portal/portal64/vpk` is the folder where the portal vpk files are located
|
`/home/james/portal/portal64/vpk` is the folder where the portal vpk files are located
|
||||||
`/home/james/portal/portal64/docker-output` is where you want the output of the build to located `portal.z64` will be put into this folder
|
`/home/james/portal/portal64/docker-output` is where you want the output of the build to located `portal.z64` will be put into this folder
|
||||||
|
|
||||||
|
## Current TODO list
|
||||||
|
|
||||||
|
refactor dynamic rendering
|
||||||
|
cylinder collider type
|
||||||
|
cube dispenser
|
||||||
|
logic and trigger wiring
|
Binary file not shown.
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#define MAX_DYNAMIC_OBJECTS 16
|
#define MAX_DYNAMIC_OBJECTS 16
|
||||||
|
|
||||||
|
#define MAX_RENDER_COUNT 128
|
||||||
|
|
||||||
#define SIMPLE_CONTROLLER_MSG (5)
|
#define SIMPLE_CONTROLLER_MSG (5)
|
||||||
|
|
||||||
#define PRINTF(a)
|
#define PRINTF(a)
|
||||||
|
|
147
src/graphics/render_scene.c
Normal file
147
src/graphics/render_scene.c
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
#include "render_scene.h"
|
||||||
|
|
||||||
|
#include "../util/memory.h"
|
||||||
|
#include "defs.h"
|
||||||
|
#include "../levels/levels.h"
|
||||||
|
|
||||||
|
struct RenderScene* renderSceneInit(struct Transform* cameraTransform, struct RenderState *renderState, int capacity, u64 visibleRooms) {
|
||||||
|
stackMallockReset();
|
||||||
|
struct RenderScene* result = stackMallock(sizeof(struct RenderScene));
|
||||||
|
|
||||||
|
struct Vector3 cameraForward;
|
||||||
|
quatMultVector(&cameraTransform->rotation, &gForward, &cameraForward);
|
||||||
|
vector3Negate(&cameraForward, &cameraForward);
|
||||||
|
planeInitWithNormalAndPoint(&result->forwardPlane, &cameraForward, &cameraTransform->position);
|
||||||
|
|
||||||
|
result->currentRenderPart = 0;
|
||||||
|
result->maxRenderParts = capacity;
|
||||||
|
|
||||||
|
result->renderParts = stackMallock(sizeof(struct RenderPart) * capacity);
|
||||||
|
result->sortKeys = stackMallock(sizeof(int) * capacity);
|
||||||
|
result->materials = stackMallock(sizeof(short) * capacity);
|
||||||
|
|
||||||
|
result->renderOrder = NULL;
|
||||||
|
result->renderOrderCopy = NULL;
|
||||||
|
|
||||||
|
result->visibleRooms = visibleRooms;
|
||||||
|
|
||||||
|
result->renderState = renderState;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int renderSceneSortKey(int materialIndex, float distance) {
|
||||||
|
int distanceScaled = (int)(distance * SCENE_SCALE);
|
||||||
|
|
||||||
|
// sort transparent surfaces from back to front
|
||||||
|
if (materialIndex >= levelMaterialTransparentStart()) {
|
||||||
|
distanceScaled = 0x1000000 - distanceScaled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (materialIndex << 23) | (distanceScaled & 0x7FFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderSceneAdd(struct RenderScene* renderScene, Gfx* geometry, Mtx* matrix, int materialIndex, struct Vector3* at) {
|
||||||
|
if (renderScene->currentRenderPart == renderScene->maxRenderParts) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RenderPart* part = &renderScene->renderParts[renderScene->currentRenderPart];
|
||||||
|
part->geometry = geometry;
|
||||||
|
part->matrix = matrix;
|
||||||
|
renderScene->materials[renderScene->currentRenderPart] = materialIndex;
|
||||||
|
renderScene->sortKeys[renderScene->currentRenderPart] = renderSceneSortKey(materialIndex, planePointDistance(&renderScene->forwardPlane, at));
|
||||||
|
|
||||||
|
++renderScene->currentRenderPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderSceneSort(struct RenderScene* renderScene, int min, int max) {
|
||||||
|
if (min + 1 >= max) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int middle = (min + max) >> 1;
|
||||||
|
renderSceneSort(renderScene, min, middle);
|
||||||
|
renderSceneSort(renderScene, middle, max);
|
||||||
|
|
||||||
|
int aHead = min;
|
||||||
|
int bHead = middle;
|
||||||
|
int output = min;
|
||||||
|
|
||||||
|
while (aHead < middle && bHead < max) {
|
||||||
|
int sortDifference = renderScene->sortKeys[renderScene->renderOrder[aHead]] - renderScene->sortKeys[renderScene->renderOrder[bHead]];
|
||||||
|
|
||||||
|
if (sortDifference <= 0) {
|
||||||
|
renderScene->renderOrderCopy[output] = renderScene->renderOrder[aHead];
|
||||||
|
++output;
|
||||||
|
++aHead;
|
||||||
|
} else {
|
||||||
|
renderScene->renderOrderCopy[output] = renderScene->renderOrder[bHead];
|
||||||
|
++output;
|
||||||
|
++bHead;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (aHead < middle) {
|
||||||
|
renderScene->renderOrderCopy[output] = renderScene->renderOrder[aHead];
|
||||||
|
++output;
|
||||||
|
++aHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (bHead < max) {
|
||||||
|
renderScene->renderOrderCopy[output] = renderScene->renderOrder[bHead];
|
||||||
|
++output;
|
||||||
|
++bHead;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (output = min; output < max; ++output) {
|
||||||
|
renderScene->renderOrder[output] = renderScene->renderOrderCopy[output];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderSceneGenerate(struct RenderScene* renderScene, struct RenderState* renderState) {
|
||||||
|
renderScene->renderOrder = stackMallock(sizeof(short) * renderScene->currentRenderPart);
|
||||||
|
renderScene->renderOrderCopy = stackMallock(sizeof(short) * renderScene->currentRenderPart);
|
||||||
|
|
||||||
|
for (int i = 0; i < renderScene->currentRenderPart; ++i) {
|
||||||
|
renderScene->renderOrder[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSceneSort(renderScene, 0, renderScene->currentRenderPart);
|
||||||
|
|
||||||
|
int prevMaterial = -1;
|
||||||
|
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterialDefault());
|
||||||
|
|
||||||
|
for (int i = 0; i < renderScene->currentRenderPart; ++i) {
|
||||||
|
int renderIndex = renderScene->renderOrder[i];
|
||||||
|
|
||||||
|
int materialIndex = renderScene->materials[renderIndex];
|
||||||
|
|
||||||
|
if (materialIndex != prevMaterial && materialIndex != -1) {
|
||||||
|
if (prevMaterial != -1) {
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
||||||
|
}
|
||||||
|
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterial(materialIndex));
|
||||||
|
|
||||||
|
prevMaterial = materialIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct RenderPart* renderPart = &renderScene->renderParts[renderIndex];
|
||||||
|
|
||||||
|
if (renderPart->matrix) {
|
||||||
|
gSPMatrix(renderState->dl++, renderPart->matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
||||||
|
}
|
||||||
|
|
||||||
|
gSPDisplayList(renderState->dl++, renderPart->geometry);
|
||||||
|
|
||||||
|
if (renderPart->matrix) {
|
||||||
|
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (prevMaterial != -1) {
|
||||||
|
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
||||||
|
}
|
||||||
|
}
|
31
src/graphics/render_scene.h
Normal file
31
src/graphics/render_scene.h
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#ifndef __RENDER_SCENE_H__
|
||||||
|
#define __RENDER_SCENE_H__
|
||||||
|
|
||||||
|
#include <ultra64.h>
|
||||||
|
#include "../math/transform.h"
|
||||||
|
#include "../math/plane.h"
|
||||||
|
#include "renderstate.h"
|
||||||
|
|
||||||
|
struct RenderPart {
|
||||||
|
Mtx* matrix;
|
||||||
|
Gfx* geometry;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderScene {
|
||||||
|
u64 visibleRooms;
|
||||||
|
struct Plane forwardPlane;
|
||||||
|
struct RenderPart* renderParts;
|
||||||
|
short* materials;
|
||||||
|
int* sortKeys;
|
||||||
|
short* renderOrder;
|
||||||
|
short* renderOrderCopy;
|
||||||
|
int currentRenderPart;
|
||||||
|
int maxRenderParts;
|
||||||
|
struct RenderState *renderState;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RenderScene* renderSceneInit(struct Transform* cameraTransform, struct RenderState *renderState, int capacity, u64 visibleRooms);
|
||||||
|
void renderSceneAdd(struct RenderScene* renderScene, Gfx* geometry, Mtx* matrix, int materialIndex, struct Vector3* at);
|
||||||
|
void renderSceneGenerate(struct RenderScene* renderScene, struct RenderState* renderState);
|
||||||
|
|
||||||
|
#endif
|
|
@ -21,7 +21,6 @@ void levelLoad(int index) {
|
||||||
gCurrentLevel = gLevelList[index];
|
gCurrentLevel = gLevelList[index];
|
||||||
|
|
||||||
collisionSceneInit(&gCollisionScene, gCurrentLevel->collisionQuads, gCurrentLevel->collisionQuadCount, &gCurrentLevel->world);
|
collisionSceneInit(&gCollisionScene, gCurrentLevel->collisionQuads, gCurrentLevel->collisionQuadCount, &gCurrentLevel->world);
|
||||||
staticRenderInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int levelMaterialCount() {
|
int levelMaterialCount() {
|
||||||
|
|
|
@ -3,109 +3,36 @@
|
||||||
#include "levels.h"
|
#include "levels.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "defs.h"
|
#include "defs.h"
|
||||||
|
#include "../graphics/render_scene.h"
|
||||||
|
|
||||||
u16* gRenderOrder;
|
void staticRenderPopulateRooms(struct FrustrumCullingInformation* cullingInfo, struct RenderScene* renderScene) {
|
||||||
u16* gRenderOrderCopy;
|
|
||||||
int* gSortKey;
|
|
||||||
|
|
||||||
void staticRenderInit() {
|
|
||||||
gRenderOrder = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
|
||||||
gRenderOrderCopy = malloc(sizeof(u16) * gCurrentLevel->staticContentCount);
|
|
||||||
gSortKey = malloc(sizeof(int) * (gCurrentLevel->staticContentCount + MAX_DYNAMIC_OBJECTS));
|
|
||||||
}
|
|
||||||
|
|
||||||
int staticRenderSorkKeyFromMaterial(int materialIndex, float distanceScaled) {
|
|
||||||
int distance = (int)distanceScaled;
|
|
||||||
|
|
||||||
// sort transparent surfaces from back to front
|
|
||||||
if (materialIndex >= levelMaterialTransparentStart()) {
|
|
||||||
distance = 0x1000000 - distance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (materialIndex << 23) | (distance & 0x7FFFFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
int staticRenderGenerateSortKey(int index, struct FrustrumCullingInformation* cullingInfo) {
|
|
||||||
struct BoundingBoxs16* box = &gCurrentLevel->staticBoundingBoxes[index];
|
|
||||||
struct Vector3 boxCenter;
|
|
||||||
boxCenter.x = (box->minX + box->maxX) >> 1;
|
|
||||||
boxCenter.y = (box->minY + box->maxY) >> 1;
|
|
||||||
boxCenter.z = (box->minZ + box->maxZ) >> 1;
|
|
||||||
|
|
||||||
int distance = (int)sqrtf(vector3DistSqrd(&boxCenter, &cullingInfo->cameraPosScaled));
|
|
||||||
|
|
||||||
return staticRenderSorkKeyFromMaterial(gCurrentLevel->staticContent[index].materialIndex, distance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void staticRenderSort(int min, int max) {
|
|
||||||
if (min + 1 >= max) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int middle = (min + max) >> 1;
|
|
||||||
staticRenderSort(min, middle);
|
|
||||||
staticRenderSort(middle, max);
|
|
||||||
|
|
||||||
int aHead = min;
|
|
||||||
int bHead = middle;
|
|
||||||
int output = min;
|
|
||||||
|
|
||||||
while (aHead < middle && bHead < max) {
|
|
||||||
int sortDifference = gSortKey[gRenderOrder[aHead]] - gSortKey[gRenderOrder[bHead]];
|
|
||||||
|
|
||||||
if (sortDifference <= 0) {
|
|
||||||
gRenderOrderCopy[output] = gRenderOrder[aHead];
|
|
||||||
++output;
|
|
||||||
++aHead;
|
|
||||||
} else {
|
|
||||||
gRenderOrderCopy[output] = gRenderOrder[bHead];
|
|
||||||
++output;
|
|
||||||
++bHead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (aHead < middle) {
|
|
||||||
gRenderOrderCopy[output] = gRenderOrder[aHead];
|
|
||||||
++output;
|
|
||||||
++aHead;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (bHead < max) {
|
|
||||||
gRenderOrderCopy[output] = gRenderOrder[bHead];
|
|
||||||
++output;
|
|
||||||
++bHead;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (output = min; output < max; ++output) {
|
|
||||||
gRenderOrder[output] = gRenderOrderCopy[output];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int staticRenderPopulateRooms(struct FrustrumCullingInformation* cullingInfo, u64 visitedRooms) {
|
|
||||||
int renderCount = 0;
|
|
||||||
int currentRoom = 0;
|
int currentRoom = 0;
|
||||||
|
|
||||||
while (visitedRooms) {
|
u64 visibleRooms = renderScene->visibleRooms;
|
||||||
if (0x1 & visitedRooms) {
|
|
||||||
|
while (visibleRooms) {
|
||||||
|
if (0x1 & visibleRooms) {
|
||||||
struct Rangeu16 staticRange = gCurrentLevel->roomStaticMapping[currentRoom];
|
struct Rangeu16 staticRange = gCurrentLevel->roomStaticMapping[currentRoom];
|
||||||
|
|
||||||
for (int i = staticRange.min; i < staticRange.max; ++i) {
|
for (int i = staticRange.min; i < staticRange.max; ++i) {
|
||||||
if (isOutsideFrustrum(cullingInfo, &gCurrentLevel->staticBoundingBoxes[i])) {
|
struct BoundingBoxs16* box = &gCurrentLevel->staticBoundingBoxes[i];
|
||||||
|
|
||||||
|
if (isOutsideFrustrum(cullingInfo, box)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gRenderOrder[renderCount] = i;
|
struct Vector3 boxCenter;
|
||||||
gSortKey[i] = staticRenderGenerateSortKey(i, cullingInfo);
|
boxCenter.x = (float)(box->minX + box->maxX) * (0.5f / SCENE_SCALE);
|
||||||
++renderCount;
|
boxCenter.y = (float)(box->minY + box->maxY) * (0.5f / SCENE_SCALE);
|
||||||
|
boxCenter.z = (float)(box->minZ + box->maxZ) * (0.5f / SCENE_SCALE);
|
||||||
|
|
||||||
|
renderSceneAdd(renderScene, gCurrentLevel->staticContent[i].displayList, NULL, gCurrentLevel->staticContent[i].materialIndex, &boxCenter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visitedRooms >>= 1;
|
visibleRooms >>= 1;
|
||||||
++currentRoom;
|
++currentRoom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
return renderCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void staticRenderDetermineVisibleRooms(struct FrustrumCullingInformation* cullingInfo, u16 currentRoom, u64* visitedRooms) {
|
void staticRenderDetermineVisibleRooms(struct FrustrumCullingInformation* cullingInfo, u16 currentRoom, u64* visitedRooms) {
|
||||||
|
@ -132,50 +59,16 @@ int staticRenderIsRoomVisible(u64 visibleRooms, u16 roomIndex) {
|
||||||
return (visibleRooms & (1LL << roomIndex)) != 0;
|
return (visibleRooms & (1LL << roomIndex)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void staticRender(struct FrustrumCullingInformation* cullingInfo, u64 visibleRooms, struct RenderState* renderState) {
|
void staticRender(struct Transform* cameraTransform, struct FrustrumCullingInformation* cullingInfo, u64 visibleRooms, struct RenderState* renderState) {
|
||||||
if (!gCurrentLevel) {
|
if (!gCurrentLevel) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int renderCount = staticRenderPopulateRooms(cullingInfo, visibleRooms);
|
struct RenderScene* renderScene = renderSceneInit(cameraTransform, renderState, MAX_RENDER_COUNT, visibleRooms);
|
||||||
|
|
||||||
renderCount = dynamicScenePopulate(cullingInfo, renderCount, gCurrentLevel->staticContentCount, gSortKey, gRenderOrder);
|
staticRenderPopulateRooms(cullingInfo, renderScene);
|
||||||
|
|
||||||
staticRenderSort(0, renderCount);
|
dynamicScenePopulate(cullingInfo, renderScene);
|
||||||
|
|
||||||
int prevMaterial = -1;
|
renderSceneGenerate(renderScene, renderState);
|
||||||
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialDefault());
|
|
||||||
|
|
||||||
for (int i = 0; i < renderCount; ++i) {
|
|
||||||
int renderIndex = gRenderOrder[i];
|
|
||||||
|
|
||||||
int materialIndex;
|
|
||||||
|
|
||||||
if (renderIndex < gCurrentLevel->staticContentCount) {
|
|
||||||
materialIndex = gCurrentLevel->staticContent[renderIndex].materialIndex;
|
|
||||||
} else {
|
|
||||||
materialIndex = dynamicSceneObjectMaterialIndex(renderIndex - gCurrentLevel->staticContentCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (materialIndex != prevMaterial && materialIndex != -1) {
|
|
||||||
if (prevMaterial != -1) {
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
|
||||||
}
|
|
||||||
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterial(materialIndex));
|
|
||||||
|
|
||||||
prevMaterial = materialIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (renderIndex < gCurrentLevel->staticContentCount) {
|
|
||||||
gSPDisplayList(renderState->dl++, gCurrentLevel->staticContent[renderIndex].displayList);
|
|
||||||
} else {
|
|
||||||
dynamicSceneRenderObject(renderIndex - gCurrentLevel->staticContentCount, renderState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (prevMaterial != -1) {
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialRevert(prevMaterial));
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -6,11 +6,8 @@
|
||||||
#include "scene/camera.h"
|
#include "scene/camera.h"
|
||||||
#include "../scene/dynamic_scene.h"
|
#include "../scene/dynamic_scene.h"
|
||||||
|
|
||||||
void staticRenderInit();
|
|
||||||
|
|
||||||
int staticRenderSorkKeyFromMaterial(int materialIndex, float distanceScaled);
|
|
||||||
void staticRenderDetermineVisibleRooms(struct FrustrumCullingInformation* cullingInfo, u16 currentRoom, u64* visitedRooms);
|
void staticRenderDetermineVisibleRooms(struct FrustrumCullingInformation* cullingInfo, u16 currentRoom, u64* visitedRooms);
|
||||||
int staticRenderIsRoomVisible(u64 visibleRooms, u16 roomIndex);
|
int staticRenderIsRoomVisible(u64 visibleRooms, u16 roomIndex);
|
||||||
void staticRender(struct FrustrumCullingInformation* cullingInfo, u64 visibleRooms, struct RenderState* renderState);
|
void staticRender(struct Transform* cameraTransform, struct FrustrumCullingInformation* cullingInfo, u64 visibleRooms, struct RenderState* renderState);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -1,6 +1,11 @@
|
||||||
#include "plane.h"
|
#include "plane.h"
|
||||||
#include "mathf.h"
|
#include "mathf.h"
|
||||||
|
|
||||||
|
void planeInitWithNormalAndPoint(struct Plane* plane, struct Vector3* normal, struct Vector3* point) {
|
||||||
|
plane->normal = *normal;
|
||||||
|
plane->d = -vector3Dot(normal, point);
|
||||||
|
}
|
||||||
|
|
||||||
int planeRayIntersection(struct Plane* plane, struct Vector3* rayOrigin, struct Vector3* rayDirection, float* rayDistance) {
|
int planeRayIntersection(struct Plane* plane, struct Vector3* rayOrigin, struct Vector3* rayDirection, float* rayDistance) {
|
||||||
float normalDot = vector3Dot(&plane->normal, rayDirection);
|
float normalDot = vector3Dot(&plane->normal, rayDirection);
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ struct Plane {
|
||||||
float d;
|
float d;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void planeInitWithNormalAndPoint(struct Plane* plane, struct Vector3* normal, struct Vector3* point);
|
||||||
|
|
||||||
int planeRayIntersection(struct Plane* plane, struct Vector3* rayOrigin, struct Vector3* rayDirection, float* rayDistance);
|
int planeRayIntersection(struct Plane* plane, struct Vector3* rayOrigin, struct Vector3* rayDirection, float* rayDistance);
|
||||||
|
|
||||||
float planePointDistance(struct Plane* plane, struct Vector3* point);
|
float planePointDistance(struct Plane* plane, struct Vector3* point);
|
||||||
|
|
|
@ -5,14 +5,12 @@
|
||||||
#include "../graphics/renderstate.h"
|
#include "../graphics/renderstate.h"
|
||||||
#include "dynamic_scene.h"
|
#include "dynamic_scene.h"
|
||||||
|
|
||||||
void buttonRender(void* data, struct RenderState* renderState) {
|
void buttonRender(void* data, struct RenderScene* renderScene) {
|
||||||
struct Button* button = (struct Button*)data;
|
struct Button* button = (struct Button*)data;
|
||||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
|
||||||
transformToMatrixL(&button->rigidBody.transform, matrix, SCENE_SCALE);
|
transformToMatrixL(&button->rigidBody.transform, matrix, SCENE_SCALE);
|
||||||
|
|
||||||
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
renderSceneAdd(renderScene, button_gfx, matrix, button_material_index, &button->rigidBody.transform.position);
|
||||||
gSPDisplayList(renderState->dl++, button_gfx);
|
|
||||||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void buttonInit(struct Button* button, struct Vector3* at, int roomIndex) {
|
void buttonInit(struct Button* button, struct Vector3* at, int roomIndex) {
|
||||||
|
@ -22,7 +20,7 @@ void buttonInit(struct Button* button, struct Vector3* at, int roomIndex) {
|
||||||
|
|
||||||
button->rigidBody.currentRoom = roomIndex;
|
button->rigidBody.currentRoom = roomIndex;
|
||||||
|
|
||||||
button->dynamicId = dynamicSceneAdd(button, buttonRender, &button->rigidBody.transform, 0.74f, button_material_index);
|
button->dynamicId = dynamicSceneAdd(button, buttonRender, &button->rigidBody.transform, 0.74f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void buttonUpdate(struct Button* button) {
|
void buttonUpdate(struct Button* button) {
|
||||||
|
|
|
@ -58,14 +58,12 @@ struct ColliderTypeData gCubeCollider = {
|
||||||
&gCollisionBoxCallbacks,
|
&gCollisionBoxCallbacks,
|
||||||
};
|
};
|
||||||
|
|
||||||
void cubeRender(void* data, struct RenderState* renderState) {
|
void cubeRender(void* data, struct RenderScene* renderScene) {
|
||||||
struct Cube* cube = (struct Cube*)data;
|
struct Cube* cube = (struct Cube*)data;
|
||||||
Mtx* matrix = renderStateRequestMatrices(renderState, 1);
|
Mtx* matrix = renderStateRequestMatrices(renderScene->renderState, 1);
|
||||||
transformToMatrixL(&cube->rigidBody.transform, matrix, SCENE_SCALE);
|
transformToMatrixL(&cube->rigidBody.transform, matrix, SCENE_SCALE);
|
||||||
|
|
||||||
gSPMatrix(renderState->dl++, matrix, G_MTX_MODELVIEW | G_MTX_PUSH | G_MTX_MUL);
|
renderSceneAdd(renderScene, cube_gfx, matrix, cube_material_index, &cube->rigidBody.transform.position);
|
||||||
gSPDisplayList(renderState->dl++, cube_gfx);
|
|
||||||
gSPPopMatrix(renderState->dl++, G_MTX_MODELVIEW);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cubeInit(struct Cube* cube) {
|
void cubeInit(struct Cube* cube) {
|
||||||
|
@ -74,7 +72,7 @@ void cubeInit(struct Cube* cube) {
|
||||||
|
|
||||||
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
cube->collisionObject.body->flags |= RigidBodyFlagsGrabbable;
|
||||||
|
|
||||||
cube->dynamicId = dynamicSceneAdd(cube, cubeRender, &cube->rigidBody.transform, sqrtf(vector3MagSqrd(&gCubeCollisionBox.sideLength)), cube_material_index);
|
cube->dynamicId = dynamicSceneAdd(cube, cubeRender, &cube->rigidBody.transform, sqrtf(vector3MagSqrd(&gCubeCollisionBox.sideLength)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void cubeUpdate(struct Cube* cube) {
|
void cubeUpdate(struct Cube* cube) {
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
struct DynamicScene gDynamicScene;
|
struct DynamicScene gDynamicScene;
|
||||||
|
|
||||||
#define FLAG_MASK (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
#define FLAG_MASK (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
||||||
|
|
||||||
#define FLAG_VALUE_NOT_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE)
|
#define FLAG_VALUE_NOT_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE)
|
||||||
#define FLAG_VALUE_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
#define FLAG_VALUE_TOUCHING_PORTAL (DYNAMIC_SCENE_OBJECT_FLAGS_USED | DYNAMIC_SCENE_OBJECT_FLAGS_ACTIVE | DYNAMIC_SCENE_OBJECT_FLAGS_TOUCHING_PORTAL)
|
||||||
|
|
||||||
|
@ -15,24 +16,30 @@ void dynamicSceneInit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dynamicSceneRenderTouchingPortal(struct RenderState* renderState) {
|
|
||||||
|
void dynamicScenePopulateWithFlags(struct FrustrumCullingInformation* cullingInfo, struct RenderScene* renderScene, int flags) {
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||||
if ((object->flags & FLAG_MASK) == FLAG_VALUE_TOUCHING_PORTAL) {
|
if ((object->flags & FLAG_MASK) == flags) {
|
||||||
if (object->materialIndex != -1) {
|
struct Vector3 scaledPos;
|
||||||
gSPDisplayList(renderState->dl++, levelMaterial(object->materialIndex));
|
vector3Scale(&object->transform->position, &scaledPos, SCENE_SCALE);
|
||||||
|
|
||||||
|
if (isSphereOutsideFrustrum(cullingInfo, &scaledPos, object->scaledRadius)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
gDynamicScene.objects[i].renderCallback(gDynamicScene.objects[i].data, renderState);
|
object->renderCallback(object->data, renderScene);
|
||||||
|
|
||||||
if (object->materialIndex != -1) {
|
|
||||||
gSPDisplayList(renderState->dl++, levelMaterialRevert(object->materialIndex));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius, u16 materialIndex) {
|
void dynamicSceneRenderTouchingPortal(struct Transform* cameraTransform, struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState) {
|
||||||
|
struct RenderScene* tmpScene = renderSceneInit(cameraTransform, renderState, MAX_DYNAMIC_SCENE_OBJECTS, ~0);
|
||||||
|
dynamicScenePopulateWithFlags(cullingInfo, tmpScene, FLAG_VALUE_NOT_TOUCHING_PORTAL);
|
||||||
|
renderSceneGenerate(tmpScene, renderState);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius) {
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
||||||
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
||||||
if (!(object->flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
if (!(object->flags & DYNAMIC_SCENE_OBJECT_FLAGS_USED)) {
|
||||||
|
@ -42,7 +49,6 @@ int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform*
|
||||||
object->renderCallback = renderCallback;
|
object->renderCallback = renderCallback;
|
||||||
object->transform = transform;
|
object->transform = transform;
|
||||||
object->scaledRadius = radius * SCENE_SCALE;
|
object->scaledRadius = radius * SCENE_SCALE;
|
||||||
object->materialIndex = materialIndex;
|
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,42 +72,6 @@ void dynamicSceneClearFlags(int id, int flags) {
|
||||||
gDynamicScene.objects[id].flags &= ~flags;
|
gDynamicScene.objects[id].flags &= ~flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, int currentObjectCount, int staticObjectCount, int* sortKey, u16* renderOrder) {
|
void dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, struct RenderScene* renderScene) {
|
||||||
for (int i = 0; i < MAX_DYNAMIC_SCENE_OBJECTS; ++i) {
|
dynamicScenePopulateWithFlags(cullingInfo, renderScene, FLAG_VALUE_NOT_TOUCHING_PORTAL);
|
||||||
struct DynamicSceneObject* object = &gDynamicScene.objects[i];
|
|
||||||
if ((object->flags & FLAG_MASK) == FLAG_VALUE_NOT_TOUCHING_PORTAL) {
|
|
||||||
struct Vector3 scaledPos;
|
|
||||||
vector3Scale(&object->transform->position, &scaledPos, SCENE_SCALE);
|
|
||||||
|
|
||||||
if (isSphereOutsideFrustrum(cullingInfo, &scaledPos, object->scaledRadius)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderOrder[currentObjectCount] = staticObjectCount + i;
|
|
||||||
sortKey[staticObjectCount + i] = staticRenderSorkKeyFromMaterial(
|
|
||||||
object->materialIndex,
|
|
||||||
sqrtf(vector3DistSqrd(&scaledPos, &cullingInfo->cameraPosScaled))
|
|
||||||
);
|
|
||||||
++currentObjectCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentObjectCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dynamicSceneRenderObject(int index, struct RenderState* renderState) {
|
|
||||||
if (index < 0 || index >= MAX_DYNAMIC_OBJECTS) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct DynamicSceneObject* object = &gDynamicScene.objects[index];
|
|
||||||
object->renderCallback(object->data, renderState);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dynamicSceneObjectMaterialIndex(int objectIndex) {
|
|
||||||
if (objectIndex < 0 || objectIndex >= MAX_DYNAMIC_OBJECTS) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gDynamicScene.objects[objectIndex].materialIndex;
|
|
||||||
}
|
}
|
|
@ -4,8 +4,9 @@
|
||||||
#include "../graphics/renderstate.h"
|
#include "../graphics/renderstate.h"
|
||||||
#include "../math/transform.h"
|
#include "../math/transform.h"
|
||||||
#include "../scene/camera.h"
|
#include "../scene/camera.h"
|
||||||
|
#include "../graphics/render_scene.h"
|
||||||
|
|
||||||
typedef void (*DynamicRender)(void* data, struct RenderState* renderState);
|
typedef void (*DynamicRender)(void* data, struct RenderScene* renderScene);
|
||||||
|
|
||||||
#define MAX_DYNAMIC_SCENE_OBJECTS 32
|
#define MAX_DYNAMIC_SCENE_OBJECTS 32
|
||||||
|
|
||||||
|
@ -20,7 +21,6 @@ struct DynamicSceneObject {
|
||||||
DynamicRender renderCallback;
|
DynamicRender renderCallback;
|
||||||
struct Transform* transform;
|
struct Transform* transform;
|
||||||
float scaledRadius;
|
float scaledRadius;
|
||||||
u16 materialIndex;
|
|
||||||
u16 flags;
|
u16 flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,16 +30,13 @@ struct DynamicScene {
|
||||||
|
|
||||||
void dynamicSceneInit();
|
void dynamicSceneInit();
|
||||||
|
|
||||||
void dynamicSceneRenderTouchingPortal(struct RenderState* renderState);
|
void dynamicSceneRenderTouchingPortal(struct Transform* cameraTransform, struct FrustrumCullingInformation* cullingInfo, struct RenderState* renderState);
|
||||||
|
|
||||||
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius, u16 materialIndex);
|
int dynamicSceneAdd(void* data, DynamicRender renderCallback, struct Transform* transform, float radius);
|
||||||
void dynamicSceneRemove(int id);
|
void dynamicSceneRemove(int id);
|
||||||
void dynamicSceneSetFlags(int id, int flags);
|
void dynamicSceneSetFlags(int id, int flags);
|
||||||
void dynamicSceneClearFlags(int id, int flags);
|
void dynamicSceneClearFlags(int id, int flags);
|
||||||
|
|
||||||
int dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, int currentObjectCount, int staticObjectCount, int* sortKey, u16* renderOrder);
|
void dynamicScenePopulate(struct FrustrumCullingInformation* cullingInfo, struct RenderScene* renderScene);
|
||||||
|
|
||||||
void dynamicSceneRenderObject(int index, struct RenderState* renderState);
|
|
||||||
int dynamicSceneObjectMaterialIndex(int objectIndex);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -123,7 +123,7 @@ void renderPropsNext(struct RenderProps* current, struct RenderProps* next, stru
|
||||||
|
|
||||||
// render any objects halfway through portals
|
// render any objects halfway through portals
|
||||||
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
|
cameraSetupMatrices(&next->camera, renderState, next->aspectRatio, &next->perspectiveCorrect, current->viewport, NULL);
|
||||||
dynamicSceneRenderTouchingPortal(renderState);
|
dynamicSceneRenderTouchingPortal(&next->camera.transform, ¤t->cullingInfo, renderState);
|
||||||
|
|
||||||
Vp* viewport = renderPropsBuildViewport(next, renderState);
|
Vp* viewport = renderPropsBuildViewport(next, renderState);
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ void sceneRenderWithProperties(void* data, struct RenderProps* properties, struc
|
||||||
otherPortal = 1 - otherPortal;
|
otherPortal = 1 - otherPortal;
|
||||||
}
|
}
|
||||||
|
|
||||||
staticRender(&properties->cullingInfo, visibleRooms, renderState);
|
staticRender(&properties->camera.transform, &properties->cullingInfo, visibleRooms, renderState);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
#define SOLID_COLOR 0, 0, 0, ENVIRONMENT, 0, 0, 0, ENVIRONMENT
|
||||||
|
@ -130,7 +130,7 @@ void sceneRender(struct Scene* scene, struct RenderState* renderState, struct Gr
|
||||||
|
|
||||||
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
gDPSetRenderMode(renderState->dl++, G_RM_ZB_OPA_SURF, G_RM_ZB_OPA_SURF2);
|
||||||
|
|
||||||
dynamicSceneRenderTouchingPortal(renderState);
|
dynamicSceneRenderTouchingPortal(&scene->camera.transform, &renderProperties.cullingInfo, renderState);
|
||||||
|
|
||||||
sceneRenderWithProperties(scene, &renderProperties, renderState);
|
sceneRenderWithProperties(scene, &renderProperties, renderState);
|
||||||
|
|
||||||
|
|
|
@ -339,3 +339,20 @@ void memCopy(void* target, const void* src, int size)
|
||||||
--size;
|
--size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STACK_MALLOC_SIZE_BYTES 4096
|
||||||
|
#define STACK_MALLOC_SIZE_WORDS (STACK_MALLOC_SIZE_BYTES >> 3)
|
||||||
|
|
||||||
|
int gStackMallocAt;
|
||||||
|
long long gStackMalloc[STACK_MALLOC_SIZE_WORDS];
|
||||||
|
|
||||||
|
void stackMallockReset() {
|
||||||
|
gStackMallocAt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* stackMallock(int size) {
|
||||||
|
int nWords = (size + 7) >> 3;
|
||||||
|
void* result = &gStackMalloc[gStackMallocAt];
|
||||||
|
gStackMallocAt += nWords;
|
||||||
|
return result;
|
||||||
|
}
|
|
@ -49,4 +49,7 @@ int calculateLargestFreeChunk();
|
||||||
extern void zeroMemory(void* memory, int size);
|
extern void zeroMemory(void* memory, int size);
|
||||||
extern void memCopy(void* target, const void* src, int size);
|
extern void memCopy(void* target, const void* src, int size);
|
||||||
|
|
||||||
|
void stackMallockReset();
|
||||||
|
void* stackMallock(int size);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
Reference in a new issue