mirror of https://github.com/zeldaret/oot.git
Document fog functions Gfx_SetFog(2) and Play_SetFog (#1922)
* Document fog functions Gfx_SetFog(2) and Play_SetFog * review * Apply suggestions from code review Co-authored-by: Tharo <17233964+Thar0@users.noreply.github.com> --------- Co-authored-by: Dragorn421 <Dragorn421@users.noreply.github.com>
This commit is contained in:
parent
714f43b9e9
commit
45bee14f2f
|
@ -224,6 +224,10 @@ void func_800BC88C(PlayState* this) {
|
|||
this->transitionCtx.transitionType = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the environment fog, from parameters controlled by the environment system.
|
||||
* If a custom fog state is used at any point in drawing, the environment fog is expected to be restored afterwards.
|
||||
*/
|
||||
Gfx* Play_SetFog(PlayState* this, Gfx* gfx) {
|
||||
return Gfx_SetFog2(gfx, this->lightCtx.fogColor[0], this->lightCtx.fogColor[1], this->lightCtx.fogColor[2], 0,
|
||||
this->lightCtx.fogNear, 1000);
|
||||
|
|
|
@ -854,28 +854,50 @@ Gfx gEmptyDL[] = {
|
|||
gsSPEndDisplayList(),
|
||||
};
|
||||
|
||||
/**
|
||||
* Set fog color and range.
|
||||
*
|
||||
* At or prior to fog near, geometry is unaffected by fog. At or beyond fog far, geometry is fully fogged.
|
||||
* Between near and far, rendered geometry will be blended between the unfogged color and the supplied fog color.
|
||||
*
|
||||
* Fog far should be in the range 0 to 1000 and greater than or equal to fog near. If fog near is negative everything
|
||||
* will be fully fogged. If fog near is 1000 or greater there is no fog.
|
||||
*/
|
||||
Gfx* Gfx_SetFog(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far) {
|
||||
// Avoid 0 divisor in gSPFogPosition below
|
||||
if (far == near) {
|
||||
far++;
|
||||
}
|
||||
|
||||
ASSERT(near != far, "n != f", "../z_rcp.c", 1155);
|
||||
|
||||
// Set the fog color, far away geometry will be rendered as this solid color.
|
||||
gDPSetFogColor(gfx++, r, g, b, a);
|
||||
|
||||
if (near >= 1000) {
|
||||
// Set a constant shade alpha of 0 for no fog
|
||||
gSPFogFactor(gfx++, 0, 0);
|
||||
} else if (near >= 997) {
|
||||
gSPFogFactor(gfx++, 0x7FFF, 0x8100);
|
||||
} else if (near > 996) {
|
||||
// Avoid an overflow when near and far are close (see bug below), by effectively clamping near to ~996.
|
||||
// This is almost SPFogPosition(996.0937f, 1000)
|
||||
gSPFogFactor(gfx++, 0x7FFF, -0x7F00);
|
||||
} else if (near < 0) {
|
||||
// Set a constant shade alpha of 255 for fully fogged
|
||||
gSPFogFactor(gfx++, 0, 255);
|
||||
} else {
|
||||
// Normal range. Shade alpha is 0 at z <= near and 255 at z >= far, linearly interpolated in between.
|
||||
//! @bug If far - near < 4, the computed `fm` fog factor coefficient will overflow.
|
||||
//! For example: 128000 / (983 - 980) > 32767
|
||||
//! This is handled above in the case of near > 996, but the general case is not accounted for.
|
||||
gSPFogPosition(gfx++, near, far);
|
||||
}
|
||||
|
||||
return gfx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Like Gfx_SetFog but issues a pipesync before changing fog color.
|
||||
*
|
||||
* @see Gfx_SetFog
|
||||
*/
|
||||
Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far) {
|
||||
if (far == near) {
|
||||
far++;
|
||||
|
@ -898,6 +920,11 @@ Gfx* Gfx_SetFogWithSync(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far)
|
|||
return gfx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrapper for Gfx_SetFog
|
||||
*
|
||||
* @see Gfx_SetFog
|
||||
*/
|
||||
Gfx* Gfx_SetFog2(Gfx* gfx, s32 r, s32 g, s32 b, s32 a, s32 near, s32 far) {
|
||||
return Gfx_SetFog(gfx, r, g, b, a, near, far);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue