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