Rework how geo layout lights work to be spawned only once per graph node.

This commit is contained in:
Dario 2021-05-10 16:43:12 -03:00
parent 091379eea3
commit 53ed8d2561
9 changed files with 231 additions and 132 deletions

Binary file not shown.

View File

@ -1,8 +1,32 @@
{
"geoLayouts": [
{
"lightMod": {
"attenuationExponent": 1.0,
"attenuationRadius": 6000.0,
"diffuseColor": [
1.2999999523162842,
1.2999999523162842,
0.20000000298023224
],
"flickerIntensity": 0.125,
"groupBits": 16,
"pointRadius": 100.0,
"position": [
0.0,
0.0,
0.0
],
"shadowOffset": 320.0,
"specularIntensity": 0.6499999761581421
},
"materialMod": {
"ignoreNormalFactor": 1.0
"lightGroupMaskBits": 0,
"selfLight": [
0.699999988079071,
0.699999988079071,
0.699999988079071
]
},
"name": "amp_geo"
},
@ -726,7 +750,33 @@
"name": "springboard_top_geo"
},
{
"materialMod": null,
"lightMod": {
"attenuationExponent": 1.0,
"attenuationRadius": 4500.0,
"diffuseColor": [
1.2999999523162842,
1.2999999523162842,
0.20000000298023224
],
"flickerIntensity": 0.0,
"groupBits": 16,
"pointRadius": 200.0,
"position": [
0.0,
0.0,
0.0
],
"shadowOffset": 600.0,
"specularIntensity": 0.6499999761581421
},
"materialMod": {
"lightGroupMaskBits": 0,
"selfLight": [
0.699999988079071,
0.699999988079071,
0.699999988079071
]
},
"name": "star_geo"
},
{

View File

@ -1,35 +1,5 @@
{
"textures": [
{
"lightMod": {
"attenuationExponent": 1.0,
"attenuationRadius": 1500.0,
"diffuseColor": [
1.2999999523162842,
1.2999999523162842,
0.20000000298023224
],
"flickerIntensity": 0.125,
"groupBits": 16,
"pointRadius": 25.0,
"position": [
0.0,
0.0,
0.0
],
"shadowOffset": 80.0,
"specularIntensity": 0.6499999761581421
},
"materialMod": {
"lightGroupMaskBits": 0,
"selfLight": [
0.699999988079071,
0.699999988079071,
0.699999988079071
]
},
"name": "actors/amp/amp_body.rgba16"
},
{
"materialMod": null,
"name": "actors/blue_fish/blue_fish.rgba16"
@ -349,36 +319,6 @@
},
"name": "actors/spindrift/spindrift_head.rgba16"
},
{
"lightMod": {
"attenuationExponent": 1.0,
"attenuationRadius": 4500.0,
"diffuseColor": [
1.2999999523162842,
1.2999999523162842,
0.20000000298023224
],
"flickerIntensity": 0.0,
"groupBits": 16,
"pointRadius": 200.0,
"position": [
0.0,
0.0,
0.0
],
"shadowOffset": 600.0,
"specularIntensity": 0.6499999761581421
},
"materialMod": {
"lightGroupMaskBits": 0,
"selfLight": [
0.699999988079071,
0.699999988079071,
0.699999988079071
]
},
"name": "actors/star/star_surface.rgba16"
},
{
"materialMod": {
"ignoreNormalFactor": 1.0,

View File

@ -252,6 +252,10 @@ void geo_layout_cmd_node_root(void) {
gGeoViews[i] = NULL;
}
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x0C << CMD_SIZE_SHIFT;
@ -267,6 +271,10 @@ void geo_layout_cmd_node_ortho_projection(void) {
graphNode = init_graph_node_ortho_projection(gGraphNodePool, NULL, scale);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
@ -295,6 +303,10 @@ void geo_layout_cmd_node_perspective(void) {
graphNode = init_graph_node_perspective(gGraphNodePool, NULL, (f32) fov, near, far, frustumFunc, 0);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -309,6 +321,10 @@ void geo_layout_cmd_node_start(void) {
graphNode = init_graph_node_start(gGraphNodePool, NULL);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
@ -328,6 +344,10 @@ void geo_layout_cmd_node_master_list(void) {
graphNode = init_graph_node_master_list(gGraphNodePool, NULL, cur_geo_cmd_u8(0x01));
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
@ -346,6 +366,10 @@ void geo_layout_cmd_node_level_of_detail(void) {
graphNode = init_graph_node_render_range(gGraphNodePool, NULL, minDistance, maxDistance);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -369,6 +393,10 @@ void geo_layout_cmd_node_switch_case(void) {
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // case update function
0);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -397,6 +425,10 @@ void geo_layout_cmd_node_camera(void) {
graphNode = init_graph_node_camera(gGraphNodePool, NULL, pos, focus,
(GraphNodeFunc) cur_geo_cmd_ptr(0x10), cur_geo_cmd_s16(0x02));
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoViews[0] = &graphNode->fnNode.node;
@ -479,7 +511,7 @@ void geo_layout_cmd_node_translation_rotation(void) {
translation, rotation);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -519,7 +551,7 @@ void geo_layout_cmd_node_translation(void) {
init_graph_node_translation(gGraphNodePool, NULL, drawingLayer, displayList, translation);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -558,7 +590,7 @@ void geo_layout_cmd_node_rotation(void) {
graphNode = init_graph_node_rotation(gGraphNodePool, NULL, drawingLayer, displayList, sp2c);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -591,7 +623,7 @@ void geo_layout_cmd_node_scale(void) {
graphNode = init_graph_node_scale(gGraphNodePool, NULL, drawingLayer, displayList, scale);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -625,7 +657,7 @@ void geo_layout_cmd_node_animated_part(void) {
init_graph_node_animated_part(gGraphNodePool, NULL, drawingLayer, displayList, translation);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -662,7 +694,7 @@ void geo_layout_cmd_node_billboard(void) {
graphNode = init_graph_node_billboard(gGraphNodePool, NULL, drawingLayer, displayList, translation);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -683,7 +715,7 @@ void geo_layout_cmd_node_display_list(void) {
graphNode = init_graph_node_display_list(gGraphNodePool, NULL, drawingLayer, displayList);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode);
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
@ -705,6 +737,10 @@ void geo_layout_cmd_node_shadow(void) {
graphNode = init_graph_node_shadow(gGraphNodePool, NULL, shadowScale, shadowSolidity, shadowType);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -716,6 +752,10 @@ void geo_layout_cmd_node_object_parent(void) {
graphNode = init_graph_node_object_parent(gGraphNodePool, NULL, &gObjParentGraphNode);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
@ -733,6 +773,10 @@ void geo_layout_cmd_node_generated(void) {
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // asm function
cur_geo_cmd_s16(0x02)); // parameter
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -752,6 +796,10 @@ void geo_layout_cmd_node_background(void) {
(GraphNodeFunc) cur_geo_cmd_ptr(0x04), // asm function
0);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x08 << CMD_SIZE_SHIFT;
@ -784,6 +832,10 @@ void geo_layout_cmd_copy_view(void) {
graphNode = init_graph_node_object_parent(gGraphNodePool, NULL, node);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
@ -806,6 +858,10 @@ void geo_layout_cmd_node_held_obj(void) {
graphNode = init_graph_node_held_object(
gGraphNodePool, NULL, NULL, offset, (GraphNodeFunc) cur_geo_cmd_ptr(0x08), cur_geo_cmd_u8(0x01));
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->fnNode.node);
gGeoLayoutCommand += 0x0C << CMD_SIZE_SHIFT;
@ -819,6 +875,11 @@ void geo_layout_cmd_node_held_obj(void) {
void geo_layout_cmd_node_culling_radius(void) {
struct GraphNodeCullingRadius *graphNode;
graphNode = init_graph_node_culling_radius(gGraphNodePool, NULL, cur_geo_cmd_s16(0x02));
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
gfx_register_graph_node_layout(graphNode, gCurGraphNodeIndex);
#endif
register_scene_graph_node(&graphNode->node);
gGeoLayoutCommand += 0x04 << CMD_SIZE_SHIFT;
}

View File

@ -306,7 +306,9 @@ static void geo_process_level_of_detail(struct GraphNodeLevelOfDetail *node) {
static void geo_process_switch(struct GraphNodeSwitchCase *node) {
struct GraphNode *selectedChild = node->fnNode.node.children;
s32 i;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->fnNode.func != NULL) {
node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node, gMatStack[gMatStackIndex]);
}
@ -369,11 +371,14 @@ static void geo_process_translation_rotation(struct GraphNodeTranslationRotation
gMatStackIndex++;
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -398,11 +403,14 @@ static void geo_process_translation(struct GraphNodeTranslation *node) {
gMatStackIndex++;
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -425,11 +433,14 @@ static void geo_process_rotation(struct GraphNodeRotation *node) {
gMatStackIndex++;
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -453,11 +464,14 @@ static void geo_process_scale(struct GraphNodeScale *node) {
gMatStackIndex++;
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -490,11 +504,14 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
mtxf_to_mtx(mtx, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = mtx;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -509,11 +526,14 @@ static void geo_process_billboard(struct GraphNodeBillboard *node) {
* parent node. It processes its children if it has them.
*/
static void geo_process_display_list(struct GraphNodeDisplayList *node) {
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -526,6 +546,9 @@ static void geo_process_display_list(struct GraphNodeDisplayList *node) {
* the list is generated on the fly by a function.
*/
static void geo_process_generated_list(struct GraphNodeGenerated *node) {
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->fnNode.func != NULL) {
Gfx *list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node,
(struct AllocOnlyPool *) gMatStack[gMatStackIndex]);
@ -534,7 +557,7 @@ static void geo_process_generated_list(struct GraphNodeGenerated *node) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);
#else
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8, graphNodeMod);
#endif
}
}
@ -555,11 +578,14 @@ static void geo_process_background(struct GraphNodeBackground *node) {
list = node->fnNode.func(GEO_CONTEXT_RENDER, &node->fnNode.node,
(struct AllocOnlyPool *) gMatStack[gMatStackIndex]);
}
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (list != 0) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8);
#else
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(list), node->fnNode.node.flags >> 8, graphNodeMod);
#endif
} else if (gCurGraphNodeMasterList != NULL) {
#ifndef F3DEX_GBI_2E
@ -581,7 +607,7 @@ static void geo_process_background(struct GraphNodeBackground *node) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(gfxStart), 0);
#else
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(gfxStart), 0, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(gfxStart), 0, graphNodeMod);
#endif
}
if (node->fnNode.node.children != NULL) {
@ -644,11 +670,14 @@ static void geo_process_animated_part(struct GraphNodeAnimatedPart *node) {
gMatStackIndex++;
mtxf_to_mtx(matrixPtr, gMatStack[gMatStackIndex]);
gMatStackFixed[gMatStackIndex] = matrixPtr;
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
#endif
if (node->displayList != NULL) {
#ifndef GFX_ENABLE_GRAPH_NODE_MODS
geo_append_display_list(node->displayList, node->node.flags >> 8);
#else
geo_append_display_list(node->displayList, node->node.flags >> 8, gfx_get_graph_node_mod(node));
geo_append_display_list(node->displayList, node->node.flags >> 8, graphNodeMod);
#endif
}
if (node->node.children != NULL) {
@ -762,12 +791,13 @@ static void geo_process_shadow(struct GraphNodeShadow *node) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 6);
}
#else
void *graphNodeMod = gfx_build_graph_node_mod(node, gMatStack[gMatStackIndex]);
if (gShadowAboveWaterOrLava == 1) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 4, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 4, graphNodeMod);
} else if (gMarioOnIceOrCarpet == 1) {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 5, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 5, graphNodeMod);
} else {
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 6, gfx_get_graph_node_mod(node));
geo_append_display_list((void *) VIRTUAL_TO_PHYSICAL(shadowList), 6, graphNodeMod);
}
#endif
gMatStackIndex--;

View File

@ -326,16 +326,16 @@ void gfx_push_geo_layout(void *geo_layout) {
gfx_rapi->push_geo_layout(geo_layout);
}
void gfx_register_graph_node_layout(void *graph_node) {
gfx_rapi->register_graph_node_layout(graph_node);
void gfx_register_graph_node_layout(void *graph_node, int graph_node_index) {
gfx_rapi->register_graph_node_layout(graph_node, graph_node_index);
}
void gfx_pop_geo_layout(void) {
gfx_rapi->pop_geo_layout();
}
void *gfx_get_graph_node_mod(void *graph_node) {
return gfx_rapi->get_graph_node_mod(graph_node);
void *gfx_build_graph_node_mod(void *graph_node, float modelview_matrix[4][4]) {
return gfx_rapi->build_graph_node_mod(graph_node, modelview_matrix);
}
#endif

View File

@ -32,9 +32,9 @@ void gfx_set_camera_matrix(float mat[4][4]);
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void gfx_push_geo_layout(void *geo_layout);
void gfx_register_graph_node_layout(void *graph_node);
void gfx_register_graph_node_layout(void *graph_node, int graph_node_index);
void gfx_pop_geo_layout(void);
void *gfx_get_graph_node_mod(void *graph_node);
void *gfx_build_graph_node_mod(void *graph_node, float modelview_matrix[4][4]);
#endif
#ifdef __cplusplus

View File

@ -43,9 +43,9 @@ struct GfxRenderingAPI {
#endif
#ifdef GFX_ENABLE_GRAPH_NODE_MODS
void (*push_geo_layout)(void *geo_layout);
void (*register_graph_node_layout)(void *graph_node);
void (*register_graph_node_layout)(void *graph_node, int graph_node_index);
void (*pop_geo_layout)(void);
void *(*get_graph_node_mod)(void *graph_node);
void *(*build_graph_node_mod)(void *graph_node, float matrix[4][4]);
void (*set_graph_node_mod)(void *graph_node_mod);
#endif
void (*init)(void);

View File

@ -46,9 +46,10 @@ using json = nlohmann::json;
#define DYNAMIC_MESH_LIFETIME 30
#define MAX_INSTANCES 1024
#define MAX_LIGHTS 512
#define MAX_LEVEL_LIGHTS 128
#define MAX_DYNAMIC_LIGHTS MAX_LIGHTS - MAX_LEVEL_LIGHTS
#define MAX_LEVELS 39
#define MAX_AREAS 3
#define MAX_LEVEL_LIGHTS 128
#define LEVEL_LIGHTS_FILENAME FS_BASEDIR "/rt64/level_lights.json"
#define GEO_LAYOUT_MODS_FILENAME FS_BASEDIR "/rt64/geo_layout_mods.json"
#define TEXTURE_MODS_FILENAME FS_BASEDIR "/rt64/texture_mods.json"
@ -123,6 +124,8 @@ struct {
unsigned int lightCount;
RT64_LIGHT levelLights[MAX_LEVELS][MAX_AREAS][MAX_LEVEL_LIGHTS];
int levelLightCounts[MAX_LEVELS][MAX_AREAS];
RT64_LIGHT dynamicLights[MAX_DYNAMIC_LIGHTS];
unsigned int dynamicLightCount;
// Ray picking data.
bool pickTextureNextFrame;
@ -337,6 +340,14 @@ void elapsed_time(const LARGE_INTEGER &start, const LARGE_INTEGER &end, const LA
elapsed.QuadPart /= frequency.QuadPart;
}
int gfx_rt64_get_level_index() {
return (gPlayerSpawnInfos[0].areaIndex >= 0) ? gCurrLevelNum : 0;
}
int gfx_rt64_get_area_index() {
return (gPlayerSpawnInfos[0].areaIndex >= 0) ? gCurrAreaIndex : 0;
}
void gfx_rt64_toggle_inspector() {
if (RT64.inspector != nullptr) {
RT64.lib.DestroyInspector(RT64.inspector);
@ -849,6 +860,7 @@ static void gfx_rt64_wapi_init(const char *window_title) {
RT64.instanceCount = 0;
RT64.instanceAllocCount = 0;
RT64.geoLayoutStackSize = 0;
RT64.dynamicLightCount = 0;
RT64.cachedMeshesPerFrame = 0;
RT64.currentTile = 0;
memset(RT64.currentTextureIds, 0, sizeof(RT64.currentTextureIds));
@ -1321,8 +1333,8 @@ RT64_MATERIAL gfx_rt64_rapi_build_material(ShaderProgram *prg, bool linearFilter
}
static void gfx_rt64_add_light(RT64_LIGHT *lightMod, RT64_MATRIX4 transform) {
assert(RT64.lightCount < MAX_LIGHTS);
auto &light = RT64.lights[RT64.lightCount++];
assert(RT64.dynamicLightCount < MAX_DYNAMIC_LIGHTS);
auto &light = RT64.dynamicLights[RT64.dynamicLightCount++];
light = *lightMod;
light.position = transform_position_affine(transform, lightMod->position);
@ -1335,12 +1347,12 @@ static void gfx_rt64_add_light(RT64_LIGHT *lightMod, RT64_MATRIX4 transform) {
light.shadowOffset *= scale;
}
static void gfx_rt64_rapi_apply_mod(RT64_MATERIAL *material, RT64_TEXTURE **normal, RecordedMod *mod, RT64_MATRIX4 transform) {
static void gfx_rt64_rapi_apply_mod(RT64_MATERIAL *material, RT64_TEXTURE **normal, RecordedMod *mod, RT64_MATRIX4 transform, bool apply_light) {
if (mod->materialMod != NULL) {
RT64_ApplyMaterialAttributes(material, mod->materialMod);
}
if (mod->lightMod != NULL) {
if (apply_light && (mod->lightMod != NULL)) {
gfx_rt64_add_light(mod->lightMod, transform);
}
@ -1399,11 +1411,11 @@ static void gfx_rt64_rapi_draw_triangles_common(RT64_MATRIX4 transform, float bu
// Build material with applied mods.
instDesc.material = gfx_rt64_rapi_build_material(RT64.shaderProgram, linearFilter, cms, cmt);
if (RT64.graphNodeMod != nullptr) {
gfx_rt64_rapi_apply_mod(&instDesc.material, &instDesc.normalTexture, RT64.graphNodeMod, transform);
gfx_rt64_rapi_apply_mod(&instDesc.material, &instDesc.normalTexture, RT64.graphNodeMod, transform, false);
}
if (textureMod != nullptr) {
gfx_rt64_rapi_apply_mod(&instDesc.material, &instDesc.normalTexture, textureMod, transform);
gfx_rt64_rapi_apply_mod(&instDesc.material, &instDesc.normalTexture, textureMod, transform, true);
}
if (highlightMaterial) {
@ -1510,37 +1522,23 @@ static void gfx_rt64_rapi_start_frame(void) {
RT64.background = true;
RT64.instanceCount = 0;
RT64.graphNodeMod = nullptr;
// Level lights.
int levelIndex = gCurrLevelNum;
int courseIndex = gCurrCourseNum;
int areaIndex = gCurrAreaIndex;
int spawnAreaIndex = gPlayerSpawnInfos[0].areaIndex;
// Do not use these values if the area does not have a valid player spawn.
// This means the game is on a non-playable level, like a menu.
if (spawnAreaIndex < 0) {
levelIndex = 0;
courseIndex = 0;
areaIndex = 0;
}
RT64_LIGHT *lights = RT64.levelLights[levelIndex][areaIndex];
int *lightCount = &RT64.levelLightCounts[levelIndex][areaIndex];
if (RT64.inspector != nullptr) {
char marioMessage[256] = "";
char levelMessage[256] = "";
int levelIndex = gfx_rt64_get_level_index();
int areaIndex = gfx_rt64_get_area_index();
sprintf(marioMessage, "Mario pos: %.1f %.1f %.1f", gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2]);
sprintf(levelMessage, "Level #%d Course #%d Area #%d Spawn #%d", levelIndex, courseIndex, areaIndex, spawnAreaIndex);
sprintf(levelMessage, "Level #%d Area #%d", levelIndex, areaIndex);
RT64.lib.PrintToInspector(RT64.inspector, marioMessage);
RT64.lib.PrintToInspector(RT64.inspector, levelMessage);
RT64.lib.PrintToInspector(RT64.inspector, "F1: Toggle inspectors");
RT64.lib.PrintToInspector(RT64.inspector, "F5: Save all configuration");
// Inspect the current level's lights.
RT64_LIGHT *lights = RT64.levelLights[levelIndex][areaIndex];
int *lightCount = &RT64.levelLightCounts[levelIndex][areaIndex];
RT64.lib.SetLightsInspector(RT64.inspector, lights, lightCount, MAX_LEVEL_LIGHTS);
}
memcpy(RT64.lights, lights, sizeof(RT64_LIGHT) * (*lightCount));
RT64.lightCount = *lightCount;
}
static void gfx_rt64_rapi_end_frame(void) {
@ -1554,14 +1552,12 @@ static void gfx_rt64_rapi_end_frame(void) {
// Set the camera.
RT64.lib.SetViewPerspective(RT64.view, RT64.viewMatrix, RT64.fovRadians, RT64.nearDist, RT64.farDist);
// Lakitu camera light for Shifting Sand Land Pyramid.
int levelIndex = gCurrLevelNum;
int areaIndex = gCurrAreaIndex;
// Dynamic Lakitu camera light for Shifting Sand Land Pyramid.
int levelIndex = gfx_rt64_get_level_index();
int areaIndex = gfx_rt64_get_area_index();
if ((levelIndex == 8) && (areaIndex == 2)) {
// Extract view position from the inverse matrix.
gd_inverse_mat4f(&RT64.viewMatrix.m, &RT64.invViewMatrix.m);
auto &light = RT64.lights[RT64.lightCount++];
// Build the dynamic light.
auto &light = RT64.dynamicLights[RT64.dynamicLightCount++];
RT64_VECTOR3 viewPos = { RT64.invViewMatrix.m[3][0], RT64.invViewMatrix.m[3][1], RT64.invViewMatrix.m[3][2] };
RT64_VECTOR3 marioPos = { gMarioState->pos[0], gMarioState->pos[1], gMarioState->pos[2] };
light.diffuseColor.x = 1.0f;
@ -1578,7 +1574,12 @@ static void gfx_rt64_rapi_end_frame(void) {
light.groupBits = RT64_LIGHT_GROUP_DEFAULT;
}
// Set lights on the scene.
// Build lights array out of the static level lights and the dynamic lights.
int levelLightCount = RT64.levelLightCounts[levelIndex][areaIndex];
RT64.lightCount = levelLightCount + RT64.dynamicLightCount;
assert(RT64.lightCount <= MAX_LIGHTS);
memcpy(&RT64.lights[0], &RT64.levelLights[levelIndex][areaIndex], sizeof(RT64_LIGHT) * levelLightCount);
memcpy(&RT64.lights[levelLightCount], RT64.dynamicLights, sizeof(RT64_LIGHT) * RT64.dynamicLightCount);
RT64.lib.SetSceneLights(RT64.scene, RT64.lights, RT64.lightCount);
// Draw frame.
@ -1640,6 +1641,8 @@ static void gfx_rt64_rapi_end_frame(void) {
RT64.lib.SetMaterialInspector(RT64.inspector, texMod->materialMod, textureName.c_str());
}
}
RT64.dynamicLightCount = 0;
}
static void gfx_rt64_rapi_finish_render(void) {
@ -1654,6 +1657,7 @@ static void gfx_rt64_rapi_set_camera_perspective(float fov_degrees, float near_d
static void gfx_rt64_rapi_set_camera_matrix(float matrix[4][4]) {
memcpy(&RT64.viewMatrix.m, matrix, sizeof(float) * 16);
gd_inverse_mat4f(&RT64.viewMatrix.m, &RT64.invViewMatrix.m);
}
static void gfx_rt64_rapi_push_geo_layout(void *geoLayout) {
@ -1661,7 +1665,7 @@ static void gfx_rt64_rapi_push_geo_layout(void *geoLayout) {
RT64.geoLayoutStack[RT64.geoLayoutStackSize++] = geoLayout;
}
static void gfx_rt64_rapi_register_graph_node_layout(void *graphNode) {
static void gfx_rt64_rapi_register_graph_node_layout(void *graphNode, int graphNodeIndex) {
if (graphNode != nullptr) {
for (int s = 0; s < RT64.geoLayoutStackSize; s++) {
void *geo = RT64.geoLayoutStack[s];
@ -1686,7 +1690,8 @@ static void gfx_rt64_rapi_register_graph_node_layout(void *graphNode) {
graphMod->materialMod->enabledAttributes |= geoMod->materialMod->enabledAttributes;
}
if (geoMod->lightMod != nullptr) {
// Light mods are only applied to the first nodes in the graph for the geo layout.
if ((graphNodeIndex == 1) && geoMod->lightMod != nullptr) {
if (graphMod->lightMod == nullptr) {
graphMod->lightMod = new RT64_LIGHT();
}
@ -1703,9 +1708,22 @@ static void gfx_rt64_rapi_pop_geo_layout() {
RT64.geoLayoutStackSize--;
}
static void *gfx_rt64_rapi_get_graph_node_mod(void *graphNode) {
static void *gfx_rt64_rapi_build_graph_node_mod(void *graphNode, float modelview_matrix[4][4]) {
auto graphNodeIt = RT64.graphNodeMods.find(graphNode);
return (graphNodeIt != RT64.graphNodeMods.end()) ? graphNodeIt->second : nullptr;
if (graphNodeIt != RT64.graphNodeMods.end()) {
RecordedMod *graphNodeMod = (RecordedMod *)(graphNodeIt->second);
if (graphNodeMod != nullptr) {
if (graphNodeMod->lightMod != nullptr) {
RT64_MATRIX4 transform;
gfx_matrix_mul(transform.m, modelview_matrix, RT64.invViewMatrix.m);
gfx_rt64_add_light(graphNodeMod->lightMod, transform);
}
return graphNodeMod;
}
}
return nullptr;
}
static void gfx_rt64_rapi_set_graph_node_mod(void *graph_node_mod) {
@ -1750,7 +1768,7 @@ struct GfxRenderingAPI gfx_rt64_rapi = {
gfx_rt64_rapi_push_geo_layout,
gfx_rt64_rapi_register_graph_node_layout,
gfx_rt64_rapi_pop_geo_layout,
gfx_rt64_rapi_get_graph_node_mod,
gfx_rt64_rapi_build_graph_node_mod,
gfx_rt64_rapi_set_graph_node_mod,
gfx_rt64_rapi_init,
gfx_rt64_rapi_on_resize,