Citro3d
Loading...
Searching...
No Matches
light.c
Go to the documentation of this file.
1#include "internal.h"
2
3void C3Di_LightMtlBlend(C3D_Light* light)
4{
5 int i;
6 C3D_Material* mtl = &light->parent->material;
7 C3D_LightMatConf* conf = &light->conf.material;
8 memset(conf, 0, sizeof(*conf));
9
10 for (i = 0; i < 3; i ++)
11 {
12 conf->specular0 |= ((u32)(255*(mtl->specular0[i]*light->specular0[i]))) << (i*10);
13 conf->specular1 |= ((u32)(255*(mtl->specular1[i]*light->specular1[i]))) << (i*10);
14 conf->diffuse |= ((u32)(255*(mtl->diffuse[i] *light->diffuse[i]))) << (i*10);
15 conf->ambient |= ((u32)(255*(mtl->ambient[i] *light->ambient[i]))) << (i*10);
16 }
17}
18
19int C3D_LightInit(C3D_Light* light, C3D_LightEnv* env)
20{
21 int i;
22 memset(light, 0, sizeof(*light));
23
24 for (i = 0; i < 8; i ++)
25 if (!env->lights[i])
26 break;
27 if (i == 8) return -1;
28
29 env->lights[i] = light;
30 light->flags = C3DF_Light_Enabled | C3DF_Light_Dirty | C3DF_Light_MatDirty;
31 light->id = i;
32 light->parent = env;
33 light->diffuse[0] = light->diffuse[1] = light->diffuse[2] = 1.0f;
34 light->specular0[0] = light->specular0[1] = light->specular0[2] = 1.0f;
35 light->specular1[0] = light->specular1[1] = light->specular1[2] = 1.0f;
36
37 env->flags |= C3DF_LightEnv_LCDirty;
38 return i;
39}
40
41void C3D_LightEnable(C3D_Light* light, bool enable)
42{
43 if ((light->flags & C3DF_Light_Enabled) == (enable?C3DF_Light_Enabled:0))
44 return;
45
46 if (enable)
47 light->flags |= C3DF_Light_Enabled;
48 else
49 light->flags &= ~C3DF_Light_Enabled;
50
51 light->parent->flags |= C3DF_LightEnv_LCDirty;
52}
53
54void C3D_LightTwoSideDiffuse(C3D_Light* light, bool enable)
55{
56 if (enable)
57 light->conf.config |= BIT(1);
58 else
59 light->conf.config &= ~BIT(1);
60 light->flags |= C3DF_Light_Dirty;
61}
62
63void C3D_LightGeoFactor(C3D_Light* light, int id, bool enable)
64{
65 id = 2 + (id&1);
66 if (enable)
67 light->conf.config |= BIT(id);
68 else
69 light->conf.config &= ~BIT(id);
70 light->flags |= C3DF_Light_Dirty;
71}
72
73void C3D_LightAmbient(C3D_Light* light, float r, float g, float b)
74{
75 light->ambient[0] = b;
76 light->ambient[1] = g;
77 light->ambient[2] = r;
78 light->flags |= C3DF_Light_MatDirty;
79}
80
81void C3D_LightDiffuse(C3D_Light* light, float r, float g, float b)
82{
83 light->diffuse[0] = b;
84 light->diffuse[1] = g;
85 light->diffuse[2] = r;
86 light->flags |= C3DF_Light_MatDirty;
87}
88
89void C3D_LightSpecular0(C3D_Light* light, float r, float g, float b)
90{
91 light->specular0[0] = b;
92 light->specular0[1] = g;
93 light->specular0[2] = r;
94 light->flags |= C3DF_Light_MatDirty;
95}
96
97void C3D_LightSpecular1(C3D_Light* light, float r, float g, float b)
98{
99 light->specular1[0] = b;
100 light->specular1[1] = g;
101 light->specular1[2] = r;
102 light->flags |= C3DF_Light_MatDirty;
103}
104
105void C3D_LightPosition(C3D_Light* light, C3D_FVec* pos)
106{
107 // Enable/disable positional light depending on W coordinate
108 light->conf.config &= ~BIT(0);
109 light->conf.config |= (pos->w == 0.0f);
110 light->conf.position[0] = f32tof16(pos->x);
111 light->conf.position[1] = f32tof16(pos->y);
112 light->conf.position[2] = f32tof16(pos->z);
113 light->flags |= C3DF_Light_Dirty;
114}
115
116static void C3Di_EnableCommon(C3D_Light* light, bool enable, u32 bit)
117{
118 C3D_LightEnv* env = light->parent;
119 u32* var = &env->conf.config[1];
120
121 if (enable == !(*var & bit))
122 return;
123
124 if (!enable)
125 *var |= bit;
126 else
127 *var &= ~bit;
128
129 env->flags |= C3DF_LightEnv_Dirty;
130}
131
132void C3D_LightShadowEnable(C3D_Light* light, bool enable)
133{
134 C3Di_EnableCommon(light, enable, GPU_LC1_SHADOWBIT(light->id));
135}
136
137void C3D_LightSpotEnable(C3D_Light* light, bool enable)
138{
139 C3Di_EnableCommon(light, enable, GPU_LC1_SPOTBIT(light->id));
140}
141
142static inline u16 floattofix2_11(float x)
143{
144 return (u16)((s32)(x * (1U<<11)) & 0x1FFF);
145}
146
147void C3D_LightSpotDir(C3D_Light* light, float x, float y, float z)
148{
149 C3Di_EnableCommon(light, true, GPU_LC1_SPOTBIT(light->id));
150 C3D_FVec vec = FVec3_New(-x, -y, -z);
151 vec = FVec3_Normalize(vec);
152 light->conf.spotDir[0] = floattofix2_11(vec.x);
153 light->conf.spotDir[1] = floattofix2_11(vec.y);
154 light->conf.spotDir[2] = floattofix2_11(vec.z);
155 light->flags |= C3DF_Light_Dirty;
156}
157
158void C3D_LightSpotLut(C3D_Light* light, C3D_LightLut* lut)
159{
160 bool hasLut = lut != NULL;
161 C3Di_EnableCommon(light, hasLut, GPU_LC1_SPOTBIT(light->id));
162 light->lut_SP = lut;
163 if (hasLut)
164 light->flags |= C3DF_Light_SPDirty;
165}
166
167void C3D_LightDistAttnEnable(C3D_Light* light, bool enable)
168{
169 C3Di_EnableCommon(light, enable, GPU_LC1_ATTNBIT(light->id));
170}
171
172void C3D_LightDistAttn(C3D_Light* light, C3D_LightLutDA* lut)
173{
174 bool hasLut = lut != NULL;
175 C3Di_EnableCommon(light, hasLut, GPU_LC1_ATTNBIT(light->id));
176 if (!hasLut) return;
177
178 light->conf.distAttnBias = f32tof20(lut->bias);
179 light->conf.distAttnScale = f32tof20(lut->scale);
180 light->lut_DA = &lut->lut;
181 light->flags |= C3DF_Light_Dirty | C3DF_Light_DADirty;
182}
void C3D_LightSpecular0(C3D_Light *light, float r, float g, float b)
Definition: light.c:89
void C3D_LightAmbient(C3D_Light *light, float r, float g, float b)
Definition: light.c:73
void C3D_LightEnable(C3D_Light *light, bool enable)
Definition: light.c:41
void C3D_LightShadowEnable(C3D_Light *light, bool enable)
Definition: light.c:132
void C3D_LightSpecular1(C3D_Light *light, float r, float g, float b)
Definition: light.c:97
void C3Di_LightMtlBlend(C3D_Light *light)
Definition: light.c:3
void C3D_LightPosition(C3D_Light *light, C3D_FVec *pos)
Definition: light.c:105
void C3D_LightTwoSideDiffuse(C3D_Light *light, bool enable)
Definition: light.c:54
void C3D_LightDistAttnEnable(C3D_Light *light, bool enable)
Definition: light.c:167
void C3D_LightSpotEnable(C3D_Light *light, bool enable)
Definition: light.c:137
void C3D_LightGeoFactor(C3D_Light *light, int id, bool enable)
Definition: light.c:63
void C3D_LightSpotLut(C3D_Light *light, C3D_LightLut *lut)
Definition: light.c:158
void C3D_LightDistAttn(C3D_Light *light, C3D_LightLutDA *lut)
Definition: light.c:172
void C3D_LightDiffuse(C3D_Light *light, float r, float g, float b)
Definition: light.c:81
void C3D_LightSpotDir(C3D_Light *light, float x, float y, float z)
Definition: light.c:147
int C3D_LightInit(C3D_Light *light, C3D_LightEnv *env)
Definition: light.c:19