From 4814f804c61206b8431bc0eec06257c5ebb77a16 Mon Sep 17 00:00:00 2001 From: fincs Date: Sat, 28 Nov 2015 15:56:20 +0100 Subject: [PATCH] Add missing fragment lighting functionality --- include/c3d/light.h | 15 +++++++++++++++ source/light.c | 12 +++++++++++- source/lightenv.c | 47 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/c3d/light.h b/include/c3d/light.h index f07141c..67b492c 100644 --- a/include/c3d/light.h +++ b/include/c3d/light.h @@ -66,6 +66,21 @@ void C3D_LightEnvMaterial(C3D_LightEnv* env, const C3D_Material* mtl); void C3D_LightEnvAmbient(C3D_LightEnv* env, float r, float g, float b); void C3D_LightEnvLut(C3D_LightEnv* env, int lutId, int input, bool abs, C3D_LightLut* lut); +enum +{ + GPU_SHADOW_PRIMARY = BIT(16), + GPU_SHADOW_SECONDARY = BIT(17), + GPU_INVERT_SHADOW = BIT(18), + GPU_SHADOW_ALPHA = BIT(19), +}; + +void C3D_LightEnvFresnel(C3D_LightEnv* env, GPU_FRESNELSEL selector); +void C3D_LightEnvBumpMode(C3D_LightEnv* env, GPU_BUMPMODE mode); +void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit); +void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode); +void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit); +void C3D_LightEnvClampHighlights(C3D_LightEnv* env, bool clamp); + //----------------------------------------------------------------------------- // Light //----------------------------------------------------------------------------- diff --git a/source/light.c b/source/light.c index f9e4b96..33b7f9f 100644 --- a/source/light.c +++ b/source/light.c @@ -1,5 +1,6 @@ #include #include "context.h" +#include void C3Di_LightMtlBlend(C3D_Light* light) { @@ -113,10 +114,19 @@ void C3D_LightSpotEnable(C3D_Light* light, bool enable) C3Di_EnableCommon(light, enable, GPU_LC1_SPOTBIT(light->id)); } +static inline u16 floattofix2_11(float x) +{ + return (u16)((s32)(x * (1U<<11)) & 0x1FFF); +} + void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z) { C3Di_EnableCommon(light, true, GPU_LC1_SPOTBIT(light->id)); - // TODO + C3D_FVec vec = { { 0.0, -z, -y, -x } }; + FVec_Norm4(&vec); + light->conf.spotDir[0] = floattofix2_11(vec.x); + light->conf.spotDir[1] = floattofix2_11(vec.y); + light->conf.spotDir[2] = floattofix2_11(vec.z); light->flags |= C3DF_Light_Dirty; } diff --git a/source/lightenv.c b/source/lightenv.c index d580cd7..31bbe9e 100644 --- a/source/lightenv.c +++ b/source/lightenv.c @@ -221,3 +221,50 @@ void C3D_LightEnvLut(C3D_LightEnv* env, int lutId, int input, bool abs, C3D_Ligh env->flags |= C3DF_LightEnv_Dirty; } + +void C3D_LightEnvFresnel(C3D_LightEnv* env, GPU_FRESNELSEL selector) +{ + env->conf.config[0] &= ~(3<<2); + env->conf.config[0] |= (selector&3)<<2; + env->flags |= C3DF_LightEnv_Dirty; +} + +void C3D_LightEnvBumpMode(C3D_LightEnv* env, GPU_BUMPMODE mode) +{ + env->conf.config[0] &= ~(3<<28); + env->conf.config[0] |= (mode&3)<<28; + env->flags |= C3DF_LightEnv_Dirty; +} + +void C3D_LightEnvBumpSel(C3D_LightEnv* env, int texUnit) +{ + env->conf.config[0] &= ~(3<<22); + env->conf.config[0] |= (texUnit&3)<<22; + env->flags |= C3DF_LightEnv_Dirty; +} + +void C3D_LightEnvShadowMode(C3D_LightEnv* env, u32 mode) +{ + mode &= 0xF<<16; + if (mode & (GPU_SHADOW_PRIMARY | GPU_INVERT_SHADOW | GPU_SHADOW_ALPHA)) + mode |= BIT(0); + env->conf.config[0] &= ~((3<<28) | BIT(0)); + env->conf.config[0] |= mode; + env->flags |= C3DF_LightEnv_Dirty; +} + +void C3D_LightEnvShadowSel(C3D_LightEnv* env, int texUnit) +{ + env->conf.config[0] &= ~(3<<24); + env->conf.config[0] |= (texUnit&3)<<24; + env->flags |= C3DF_LightEnv_Dirty; +} + +void C3D_LightEnvClampHighlights(C3D_LightEnv* env, bool clamp) +{ + if (clamp) + env->conf.config[0] |= BIT(27); + else + env->conf.config[0] &= ~BIT(27); + env->flags |= C3DF_LightEnv_Dirty; +}