Begin adding Gas rendering support {incomplete/not fully RE'd}
This commit is contained in:
parent
52cdcb351a
commit
81ca5d3575
@ -7,6 +7,12 @@ typedef struct
|
||||
u32 data[128];
|
||||
} C3D_FogLut;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
u32 diff[8];
|
||||
u32 color[8];
|
||||
} C3D_GasLut;
|
||||
|
||||
static inline float FogLut_CalcZ(float depth, float near, float far)
|
||||
{
|
||||
return far*near/(depth*(far-near)+near);
|
||||
@ -18,3 +24,14 @@ void FogLut_Exp(C3D_FogLut* lut, float density, float gradient, float near, floa
|
||||
void C3D_FogGasMode(GPU_FOGMODE fogMode, GPU_GASMODE gasMode, bool zFlip);
|
||||
void C3D_FogColor(u32 color);
|
||||
void C3D_FogLutBind(C3D_FogLut* lut);
|
||||
|
||||
void GasLut_FromArray(C3D_GasLut* lut, const u32 data[9]);
|
||||
|
||||
void C3D_GasAttn(float value);
|
||||
void C3D_GasAccMax(float value);
|
||||
void C3D_GasDeltaZ(float value);
|
||||
void C3D_GasLightPlanar(float min, float max, float attn);
|
||||
void C3D_GasLightView(float min, float max, float attn);
|
||||
void C3D_GasLightDirection(float dotp);
|
||||
void C3D_GasLutInput(GPU_GASLUTINPUT input);
|
||||
void C3D_GasLutBind(C3D_GasLut* lut);
|
||||
|
@ -36,6 +36,11 @@ __attribute__((weak)) void C3Di_ProcTexDirty(C3D_Context* ctx)
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
__attribute__((weak)) void C3Di_GasUpdate(C3D_Context* ctx)
|
||||
{
|
||||
(void)ctx;
|
||||
}
|
||||
|
||||
static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
@ -51,7 +56,7 @@ static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param)
|
||||
{
|
||||
ctx->flags |= C3DiF_AttrInfo | C3DiF_BufInfo | C3DiF_Effect | C3DiF_FrameBuf
|
||||
| C3DiF_Viewport | C3DiF_Scissor | C3DiF_Program | C3DiF_VshCode | C3DiF_GshCode
|
||||
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv;
|
||||
| C3DiF_TexAll | C3DiF_TexEnvBuf | C3DiF_TexEnvAll | C3DiF_LightEnv | C3DiF_Gas;
|
||||
|
||||
C3Di_DirtyUniforms(GPU_VERTEX_SHADER);
|
||||
C3Di_DirtyUniforms(GPU_GEOMETRY_SHADER);
|
||||
@ -61,6 +66,8 @@ static void C3Di_AptEventHook(APT_HookType hookType, C3D_UNUSED void* param)
|
||||
C3D_LightEnv* env = ctx->lightEnv;
|
||||
if (ctx->fogLut)
|
||||
ctx->flags |= C3DiF_FogLut;
|
||||
if (ctx->gasLut)
|
||||
ctx->flags |= C3DiF_GasLut;
|
||||
if (env)
|
||||
C3Di_LightEnvDirty(env);
|
||||
C3Di_ProcTexDirty(ctx);
|
||||
@ -233,9 +240,14 @@ void C3Di_UpdateContext(void)
|
||||
if (ctx->flags & C3DiF_TexStatus)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_TexStatus;
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT_CONFIG, ctx->texConfig);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_TEXUNIT_CONFIG, 0xB, ctx->texConfig);
|
||||
// Clear texture cache if requested *after* configuring texture units
|
||||
if (ctx->texConfig & BIT(16))
|
||||
{
|
||||
ctx->texConfig &= ~BIT(16);
|
||||
GPUCMD_AddMaskedWrite(GPUREG_TEXUNIT_CONFIG, 0x4, BIT(16));
|
||||
}
|
||||
GPUCMD_AddWrite(GPUREG_TEXUNIT0_SHADOW, ctx->texShadow);
|
||||
ctx->texConfig &= ~BIT(16); // Remove clear-texture-cache flag
|
||||
}
|
||||
|
||||
if (ctx->flags & (C3DiF_ProcTex | C3DiF_ProcTexColorLut | C3DiF_ProcTexLutAll))
|
||||
@ -249,7 +261,7 @@ void C3Di_UpdateContext(void)
|
||||
GPUCMD_AddWrite(GPUREG_FOG_COLOR, ctx->fogClr);
|
||||
}
|
||||
|
||||
if (ctx->flags & C3DiF_FogLut)
|
||||
if ((ctx->flags & C3DiF_FogLut) && (ctx->texEnvBuf&7) != GPU_NO_FOG)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_FogLut;
|
||||
if (ctx->fogLut)
|
||||
@ -259,6 +271,9 @@ void C3Di_UpdateContext(void)
|
||||
}
|
||||
}
|
||||
|
||||
if ((ctx->texEnvBuf&7) == GPU_GAS)
|
||||
C3Di_GasUpdate(ctx);
|
||||
|
||||
if (ctx->flags & C3DiF_TexEnvAll)
|
||||
{
|
||||
for (i = 0; i < 6; i ++)
|
||||
|
160
source/gas.c
Normal file
160
source/gas.c
Normal file
@ -0,0 +1,160 @@
|
||||
#include "internal.h"
|
||||
|
||||
static inline u32 calc_diff(u32 a, u32 b, int pos)
|
||||
{
|
||||
float fa = ((a>>pos)&0xFF)/255.0f;
|
||||
float fb = ((b>>pos)&0xFF)/255.0f;
|
||||
float x = fb-fa;
|
||||
u32 diff = 0;
|
||||
if (x < 0)
|
||||
{
|
||||
diff = 0x80;
|
||||
x = -x;
|
||||
}
|
||||
diff |= (u32)(x*0x7F);
|
||||
return diff<<pos;
|
||||
}
|
||||
|
||||
static inline u32 conv_u8(float x, int pos)
|
||||
{
|
||||
if (x < 0.0f) x = 0.0f;
|
||||
else if (x > 1.0f) x = 1.0f;
|
||||
return ((u32)x*255)<<pos;
|
||||
}
|
||||
|
||||
static inline u32 color_diff(u32 a, u32 b)
|
||||
{
|
||||
return calc_diff(a,b,0) | calc_diff(a,b,8) | calc_diff(a,b,16);
|
||||
}
|
||||
|
||||
void GasLut_FromArray(C3D_GasLut* lut, const u32 data[9])
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i <= 8; i ++)
|
||||
{
|
||||
if (i < 8)
|
||||
lut->color[i] = data[i];
|
||||
if (i > 0)
|
||||
lut->diff[i-1] = color_diff(data[i-1], data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void C3D_GasAttn(float value)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasAttn = f32tof16(value);
|
||||
}
|
||||
|
||||
void C3D_GasAccMax(float value)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasAccMax = f32tof16(1.0f / value);
|
||||
}
|
||||
|
||||
void C3D_GasDeltaZ(float value)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasDeltaZ = (u32)(value*0x100) & 0xFFFFFF;
|
||||
ctx->gasDeltaZ |= 2<<24;
|
||||
}
|
||||
|
||||
void C3D_GasLightPlanar(float min, float max, float attn)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasLightXY = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16);
|
||||
}
|
||||
|
||||
void C3D_GasLightView(float min, float max, float attn)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasLightZ = conv_u8(min,0) | conv_u8(max,8) | conv_u8(attn,16);
|
||||
}
|
||||
|
||||
void C3D_GasLightDirection(float dotp)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasLightZColor &= ~0xFF;
|
||||
ctx->gasLightZColor |= conv_u8(dotp,0);
|
||||
}
|
||||
|
||||
void C3D_GasLutInput(GPU_GASLUTINPUT input)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
ctx->flags |= C3DiF_Gas;
|
||||
ctx->gasLightZColor &= ~0x100;
|
||||
ctx->gasLightZColor |= (input&1)<<8;
|
||||
}
|
||||
|
||||
void C3D_GasLutBind(C3D_GasLut* lut)
|
||||
{
|
||||
C3D_Context* ctx = C3Di_GetContext();
|
||||
|
||||
if (!(ctx->flags & C3DiF_Active))
|
||||
return;
|
||||
|
||||
if (lut)
|
||||
{
|
||||
ctx->flags |= C3DiF_GasLut;
|
||||
ctx->gasLut = lut;
|
||||
} else
|
||||
ctx->flags &= ~C3DiF_GasLut;
|
||||
}
|
||||
|
||||
void C3Di_GasUpdate(C3D_Context* ctx)
|
||||
{
|
||||
//__builtin_printf("updgasstate %08lX\n", ctx->flags);
|
||||
//for(;;);
|
||||
if (ctx->flags & C3DiF_Gas)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_Gas;
|
||||
GPUCMD_AddWrite(GPUREG_GAS_ATTENUATION, ctx->gasAttn);
|
||||
//GPUCMD_AddWrite(GPUREG_GAS_ACCMAX, ctx->gasAccMax);
|
||||
GPUCMD_AddWrite(GPUREG_GAS_LIGHT_XY, ctx->gasLightXY);
|
||||
GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z, ctx->gasLightZ);
|
||||
GPUCMD_AddWrite(GPUREG_GAS_LIGHT_Z_COLOR, ctx->gasLightZColor);
|
||||
GPUCMD_AddWrite(GPUREG_GAS_DELTAZ_DEPTH, ctx->gasDeltaZ);
|
||||
}
|
||||
if (ctx->flags & C3DiF_GasLut)
|
||||
{
|
||||
ctx->flags &= ~C3DiF_GasLut;
|
||||
if (ctx->gasLut)
|
||||
{
|
||||
GPUCMD_AddWrite(GPUREG_GAS_LUT_INDEX, 0);
|
||||
GPUCMD_AddWrites(GPUREG_GAS_LUT_DATA, (u32*)ctx->gasLut, 16);
|
||||
}
|
||||
}
|
||||
}
|
@ -52,6 +52,10 @@ typedef struct
|
||||
u32 fogClr;
|
||||
C3D_FogLut* fogLut;
|
||||
|
||||
u16 gasAttn, gasAccMax;
|
||||
u32 gasLightXY, gasLightZ, gasLightZColor, gasDeltaZ;
|
||||
C3D_GasLut* gasLut;
|
||||
|
||||
C3D_ProcTex* procTex;
|
||||
C3D_ProcTexLut* procTexLut[3];
|
||||
C3D_ProcTexColorLut* procTexColorLut;
|
||||
@ -83,6 +87,8 @@ enum
|
||||
C3DiF_ProcTex = BIT(15),
|
||||
C3DiF_ProcTexColorLut = BIT(16),
|
||||
C3DiF_FogLut = BIT(17),
|
||||
C3DiF_Gas = BIT(18),
|
||||
C3DiF_GasLut = BIT(19),
|
||||
|
||||
#define C3DiF_ProcTexLut(n) BIT(20+(n))
|
||||
C3DiF_ProcTexLutAll = 7 << 20,
|
||||
@ -115,6 +121,7 @@ void C3Di_FrameBufBind(C3D_FrameBuf* fb);
|
||||
void C3Di_TexEnvBind(int id, C3D_TexEnv* env);
|
||||
void C3Di_SetTex(int unit, C3D_Tex* tex);
|
||||
void C3Di_EffectBind(C3D_Effect* effect);
|
||||
void C3Di_GasUpdate(C3D_Context* ctx);
|
||||
|
||||
void C3Di_LightMtlBlend(C3D_Light* light);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user