PS2GL
OpenGL*-like API for the PS2
Loading...
Searching...
No Matches
lighting.cpp
1/* Copyright (C) 2000,2001,2002 Sony Computer Entertainment America
2
3 This file is subject to the terms and conditions of the GNU Lesser
4 General Public License Version 2.1. See the file "COPYING" in the
5 main directory of this archive for more details. */
6
7#include "ps2gl/lighting.h"
8#include "ps2gl/dlist.h"
9#include "ps2gl/glcontext.h"
10#include "ps2gl/material.h"
11#include "ps2gl/matrix.h"
12
13/********************************************
14 * CImmLight
15 */
16
17// static data
18
19int CImmLight::NumLights[3] = { 0, 0, 0 };
20
21CImmLight::CImmLight(CGLContext& context, int lightNum)
22 : CLight(context, lightNum)
23 , Ambient(0.0f, 0.0f, 0.0f, 1.0f)
24 , Diffuse(0.0f, 0.0f, 0.0f, 0.0f)
25 , Specular(0.0f, 0.0f, 0.0f, 0.0f)
26 , Position(0.0f, 0.0f, 1.0f, 0.0f)
27 , SpotDirection(0.0f, 0.0f, -1.0f, 0.0f)
28 , SpotCutoff(180.0f)
29 , SpotExponent(0.0f)
30 , ConstantAtten(1.0f)
31 , LinearAtten(0.0f)
32 , QuadAtten(0.0f)
33 , bIsEnabled(false)
34 , Type(kDirectional)
35{
36}
37
38void CImmLight::CheckTypeChange(tLightType oldType)
39{
40 if (oldType != Type && bIsEnabled) {
41 CRendererManager& rm = GLContext.GetImmGeomManager().GetRendererManager();
42 NumLights[oldType]--;
43 NumLights[Type]++;
44 rm.NumLightsChanged(oldType, NumLights[oldType]);
45 rm.NumLightsChanged(Type, NumLights[Type]);
46 }
47}
48
49void CImmLight::SetEnabled(bool enabled)
50{
51 if (bIsEnabled != enabled) {
52 bIsEnabled = enabled;
53 if (enabled)
54 NumLights[Type]++;
55 else
56 NumLights[Type]--;
57
58 GLContext.GetImmLighting().SpecularChanged();
59
60 CRendererManager& rm = GLContext.GetImmGeomManager().GetRendererManager();
61 rm.NumLightsChanged(Type, NumLights[Type]);
62 }
63}
64
65void CImmLight::SetSpecular(cpu_vec_xyzw specular)
66{
67 cpu_vec_4 zero(0, 0, 0, 0);
68 if ((specular == zero) ^ (Specular == zero)) {
69 Specular = specular;
70 GLContext.GetImmLighting().SpecularChanged();
71 } else
72 Specular = specular;
73
74 TellRendererLightPropChanged();
75}
76
77void CImmLight::SetPosition(cpu_vec_xyzw position)
78{
79 CImmMatrixStack& modelView = GLContext.GetModelViewStack();
80
81 Position = modelView.GetTop() * position;
82 TellRendererLightPropChanged();
83
84 tLightType oldType = Type;
85 Type = (SpotCutoff == 180.0f) ? kPoint : kSpot;
86 CheckTypeChange(oldType);
87}
88
89void CImmLight::SetDirection(cpu_vec_xyzw direction)
90{
91 CImmMatrixStack& modelView = GLContext.GetModelViewStack();
92
93 Position = modelView.GetTop() * direction.normalize();
94 TellRendererLightPropChanged();
95
96 tLightType oldType = Type;
97 Type = kDirectional;
98 CheckTypeChange(oldType);
99}
100
101/********************************************
102 * CDListLight
103 */
104
105class CLightPropCmd : public CDListCmd {
106 GLenum LightNum, Property;
107 cpu_vec_xyzw Value;
108
109public:
110 CLightPropCmd(GLenum lightNum, GLenum prop, cpu_vec_xyzw value)
111 : LightNum(lightNum)
112 , Property(prop)
113 , Value(value)
114 {
115 }
116 CDListCmd* Play()
117 {
118 glLightfv(LightNum, Property, reinterpret_cast<float*>(&Value));
119 return CDListCmd::GetNextCmd(this);
120 }
121};
122
123void CDListLight::SetAmbient(cpu_vec_xyzw ambient)
124{
125 GLContext.GetDListManager().GetOpenDList()
126 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_AMBIENT, ambient);
127 TellRendererLightPropChanged();
128}
129
130void CDListLight::SetDiffuse(cpu_vec_xyzw diffuse)
131{
132 GLContext.GetDListManager().GetOpenDList()
133 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_DIFFUSE, diffuse);
134 TellRendererLightPropChanged();
135}
136
137void CDListLight::SetSpecular(cpu_vec_xyzw specular)
138{
139 GLContext.GetDListManager().GetOpenDList()
140 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_SPECULAR, specular);
141 TellRendererLightPropChanged();
142 GLContext.SpecularEnabledChanged(); // maybe
143}
144
145void CDListLight::SetPosition(cpu_vec_xyzw position)
146{
147 GLContext.GetDListManager().GetOpenDList()
148 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_POSITION, position);
149 TellRendererLightPropChanged();
150}
151
152void CDListLight::SetDirection(cpu_vec_xyzw direction)
153{
154 GLContext.GetDListManager().GetOpenDList()
155 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_POSITION, direction);
156 TellRendererLightPropChanged();
157}
158
159void CDListLight::SetSpotDirection(cpu_vec_xyzw dir)
160{
161 GLContext.GetDListManager().GetOpenDList()
162 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_SPOT_DIRECTION, dir);
163 TellRendererLightPropChanged();
164}
165
166void CDListLight::SetSpotCutoff(float cutoff)
167{
168 GLContext.GetDListManager().GetOpenDList()
169 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_SPOT_CUTOFF, cpu_vec_xyzw(cutoff, 0, 0, 0));
170 TellRendererLightPropChanged();
171}
172
173void CDListLight::SetSpotExponent(float exp)
174{
175 GLContext.GetDListManager().GetOpenDList()
176 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_AMBIENT, cpu_vec_xyzw(exp, 0, 0, 0));
177 TellRendererLightPropChanged();
178}
179
180void CDListLight::SetConstantAtten(float atten)
181{
182 GLContext.GetDListManager().GetOpenDList()
183 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_CONSTANT_ATTENUATION, cpu_vec_xyzw(atten, 0, 0, 0));
184 TellRendererLightPropChanged();
185}
186
187void CDListLight::SetLinearAtten(float atten)
188{
189 GLContext.GetDListManager().GetOpenDList()
190 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_LINEAR_ATTENUATION, cpu_vec_xyzw(atten, 0, 0, 0));
191 TellRendererLightPropChanged();
192}
193
194void CDListLight::SetQuadAtten(float atten)
195{
196 GLContext.GetDListManager().GetOpenDList()
197 += CLightPropCmd(GL_LIGHT0 | LightNum, GL_QUADRATIC_ATTENUATION, cpu_vec_xyzw(atten, 0, 0, 0));
198 TellRendererLightPropChanged();
199}
200
201void CDListLight::SetEnabled(bool yesNo)
202{
203 GLContext.GetDListManager().GetOpenDList()
204 += CEnableCmd(GL_LIGHT0 | LightNum);
205 TellRendererLightsEnabledChanged();
206}
207
208/********************************************
209 * CLighting
210 */
211
212CImmLighting::CImmLighting(CGLContext& context)
213 : CLighting(context)
214 , CurrentColor(0.0f, 0.0f, 0.0f, 0.0f)
215 , GlobalAmbient(0.0f, 0.0f, 0.0f, 0.0f)
216 , Light0(context, 0)
217 , Light1(context, 1)
218 , Light2(context, 2)
219 , Light3(context, 3)
220 , Light4(context, 4)
221 , Light5(context, 5)
222 , Light6(context, 6)
223 , Light7(context, 7)
224 , IsEnabled(false)
225 , NumLightsWithNonzeroSpecular(0)
226{
227 Lights[0] = &Light0;
228 Lights[1] = &Light1;
229 Lights[2] = &Light2;
230 Lights[3] = &Light3;
231 Lights[4] = &Light4;
232 Lights[5] = &Light5;
233 Lights[6] = &Light6;
234 Lights[7] = &Light7;
235}
236
237void CImmLighting::SpecularChanged()
238{
239 int count = 0;
240 cpu_vec_4 zero(0, 0, 0, 0);
241 for (int i = 0; i < 8; i++)
242 if (Lights[i]->IsEnabled() && Lights[i]->GetSpecular() != zero)
243 count++;
244
245 NumLightsWithNonzeroSpecular = count;
246 if (NumLightsWithNonzeroSpecular == 0) {
247 GLContext.SpecularEnabledChanged();
248 GLContext.GetImmGeomManager().GetRendererManager().SpecularEnabledChanged(false);
249 } else
250 GLContext.GetMaterialManager().GetImmMaterial().LightsHaveSpecular();
251}
252
253void CImmLighting::MaterialHasSpecular()
254{
255 if (NumLightsWithNonzeroSpecular > 0) {
256 GLContext.SpecularEnabledChanged();
257 GLContext.GetImmGeomManager().GetRendererManager().SpecularEnabledChanged(true);
258 }
259}
260
261CDListLighting::CDListLighting(CGLContext& context)
262 : CLighting(context)
263 , Light0(context, 0)
264 , Light1(context, 1)
265 , Light2(context, 2)
266 , Light3(context, 3)
267 , Light4(context, 4)
268 , Light5(context, 5)
269 , Light6(context, 6)
270 , Light7(context, 7)
271{
272 Lights[0] = &Light0;
273 Lights[1] = &Light1;
274 Lights[2] = &Light2;
275 Lights[3] = &Light3;
276 Lights[4] = &Light4;
277 Lights[5] = &Light5;
278 Lights[6] = &Light6;
279 Lights[7] = &Light7;
280}
281
283 bool IsEnabled;
284
285public:
286 CSetLightingEnabledCmd(bool enabled)
287 : IsEnabled(enabled)
288 {
289 }
290 CDListCmd* Play()
291 {
292 pGLContext->GetImmLighting().SetLightingEnabled(IsEnabled);
293 return CDListCmd::GetNextCmd(this);
294 }
295};
296
297void CDListLighting::SetLightingEnabled(bool enabled)
298{
299 GLContext.GetDListManager().GetOpenDList() += CSetLightingEnabledCmd(enabled);
300 GLContext.LightingEnabledChanged();
301}
302
304 cpu_vec_xyzw Ambient;
305
306public:
307 CSetGlobalAmbientCmd(cpu_vec_xyzw newAmb)
308 : Ambient(newAmb)
309 {
310 }
311 CDListCmd* Play()
312 {
313 pGLContext->GetImmLighting().SetGlobalAmbient(Ambient);
314 return CDListCmd::GetNextCmd(this);
315 }
316};
317
318void CDListLighting::SetGlobalAmbient(cpu_vec_xyzw newAmb)
319{
320 GLContext.GetDListManager().GetOpenDList() += CSetGlobalAmbientCmd(newAmb);
321 TellRendererLightPropChanged();
322}
323
324/********************************************
325 * gl interface
326 */
327
328void setPosition(CLight& light, float x, float y, float z, float w)
329{
330 cpu_vec_xyzw pos(x, y, z, w);
331 if (w == 0.0f)
332 light.SetDirection(pos);
333 else
334 light.SetPosition(pos);
335}
336
337void glLightfv(GLenum lightNum,
338 GLenum pname,
339 const GLfloat* params)
340{
341 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
342
343 CLighting& lighting = pGLContext->GetLighting();
344 CLight& light = lighting.GetLight(0x7 & lightNum);
345
346 switch (pname) {
347 case GL_AMBIENT:
348 light.SetAmbient(cpu_vec_xyzw(params[0], params[1], params[2], params[3]));
349 break;
350 case GL_DIFFUSE:
351 light.SetDiffuse(cpu_vec_xyzw(params[0], params[1], params[2], params[3]));
352 break;
353 case GL_SPECULAR:
354 light.SetSpecular(cpu_vec_xyzw(params[0], params[1], params[2], params[3]));
355 break;
356 case GL_POSITION:
357 setPosition(light, params[0], params[1], params[2], params[3]);
358 break;
359 case GL_SPOT_DIRECTION:
360 light.SetPosition(cpu_vec_xyzw(params[0], params[1], params[2], 0.0f).normalize());
361 break;
362 case GL_SPOT_EXPONENT:
363 light.SetSpotExponent(*params);
364 break;
365 case GL_SPOT_CUTOFF:
366 light.SetSpotCutoff(*params);
367 break;
368 case GL_CONSTANT_ATTENUATION:
369 light.SetConstantAtten(*params);
370 break;
371 case GL_LINEAR_ATTENUATION:
372 light.SetLinearAtten(*params);
373 break;
374 case GL_QUADRATIC_ATTENUATION:
375 light.SetQuadAtten(*params);
376 break;
377 default:
378 mError("Shouldn't get here.");
379 }
380}
381
382void glLightf(GLenum lightNum, GLenum pname, GLfloat param)
383{
384 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
385
386 CLighting& lighting = pGLContext->GetLighting();
387 CLight& light = lighting.GetLight(0x7 & lightNum);
388
389 switch (pname) {
390 case GL_SPOT_EXPONENT:
391 light.SetSpotExponent(param);
392 break;
393 case GL_SPOT_CUTOFF:
394 light.SetSpotCutoff(param);
395 break;
396 case GL_CONSTANT_ATTENUATION:
397 light.SetConstantAtten(param);
398 break;
399 case GL_LINEAR_ATTENUATION:
400 light.SetLinearAtten(param);
401 break;
402 case GL_QUADRATIC_ATTENUATION:
403 light.SetQuadAtten(param);
404 break;
405 default:
406 mError("Shouldn't get here.");
407 }
408}
409
410void glLightModelfv(GLenum pname, const GLfloat* params)
411{
412 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
413
414 switch (pname) {
415 case GL_LIGHT_MODEL_AMBIENT:
416 pGLContext->GetLighting().SetGlobalAmbient(cpu_vec_xyzw(params[0],
417 params[1],
418 params[2],
419 params[3]));
420 break;
421 case GL_LIGHT_MODEL_COLOR_CONTROL:
422 if ((int)*params == GL_SEPARATE_SPECULAR_COLOR) {
423 mNotImplemented("separate specular color computation");
424 }
425 break;
426 case GL_LIGHT_MODEL_LOCAL_VIEWER:
427 if ((int)*params != 0) {
428 mNotImplemented("local viewer");
429 }
430 break;
431 case GL_LIGHT_MODEL_TWO_SIDE:
432 if ((int)*params != 0) {
433 mNotImplemented("two-sided lighting");
434 }
435 break;
436 default:
437 mError("shouldn't get here");
438 }
439}
440
441void glLightModeli(GLenum pname, int param)
442{
443 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
444
445 mNotImplemented();
446}
447
448void glGetLightfv(GLenum light, GLenum pname, float* params)
449{
450 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
451
452 mNotImplemented();
453}
454
455void glFogf(GLenum pname, GLfloat param)
456{
457 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
458
459 mNotImplemented();
460}
461
462void glFogfv(GLenum pname, const GLfloat* params)
463{
464 GL_FUNC_DEBUG("%s\n", __FUNCTION__);
465
466 mNotImplemented();
467}