Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
light.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WW3D *
24 * *
25 * $Archive:: /Commando/Code/ww3d2/light.cpp $*
26 * *
27 * $Author:: Ian_l $*
28 * *
29 * $Modtime:: 7/10/01 2:27p $*
30 * *
31 * $Revision:: 8 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * LightClass::LightClass -- Constructor *
36 * LightClass::LightClass -- copy constructor *
37 * LightClass::operator == -- assignment operator *
38 * LightClass::~LightClass -- destructor *
39 * LightClass::Clone -- virtual copy constructor *
40 * LightClass::Get_Attenuation_Range -- returns a dist beyond which the light is attenuated *
41 * LightClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding sphere *
42 * LightClass::Get_Obj_Space_Bounding_Box -- returns the object space bounding box *
43 * LightClass::Vertex_Processor_Push -- pushes the light into the GERD *
44 * LightClass::Vertex_Processor_Pop -- pops the light from the GERD *
45 * LightClass::Set_Transform -- sets transform and marks srLight transform as dirty. *
46 * LightClass::Set_Position -- sets position and marks srLight transform as dirty. *
47 * LightClass::Notify_Added -- lights add themselves to the VP list when added *
48 * LightClass::Notify_Removed -- lights remove themselves from the VP list when removed *
49 * LightClass::Load_W3D -- Initialize this light from a W3D file *
50 * LightClass::Save_W3D -- Save this light's settings into a W3D file *
51 * LightClass::Get_Factory -- get the PersistFactory for LightClass *
52 * LightClass::Save -- persistant object support *
53 * LightClass::Load -- persistant object support *
54 * LightImpClass::LightImpClass -- constructor *
55 * LightImpClass::Process_Push -- exposes the "push" process for an srLight *
56 * LightImpClass::Process_Pop -- exposes the "pop" process for an srLight *
57 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
58
59#include "light.h"
60#include "ww3d.h"
61#include "ww3dids.h"
62#include "w3d_file.h"
63#include "w3d_util.h"
64#include "w3derr.h"
65#include "chunkio.h"
66#include "rinfo.h"
67#include "scene.h"
68#include "persistfactory.h"
69#include "statistics.h"
70
71
72
73/*
74** PersistFactory for LightClasses - lights have custom save-load support
75*/
77
78/*
79** Chunk ID's used by LightClass's save-load support (different from the W3D file format...)
80*/
81enum
82{
83 LIGHT_CHUNK_W3DFILE = 0x02157100, // (w3d format light)
84 LIGHT_CHUNK_VARIABLES, // other state not stored in the w3d format
85
86 LIGHT_VARIABLE_TRANSFORM = 0x00, // transform for the light
87};
88
89
90
91/***********************************************************************************************
92 * LightClass::LightClass -- Constructor *
93 * *
94 * INPUT: *
95 * type - type of light to create. *
96 * *
97 * OUTPUT: *
98 * *
99 * WARNINGS: *
100 * *
101 * HISTORY: *
102 * 3/21/98 GTH : Created. *
103 *=============================================================================================*/
105 Type(type),
106 Flags(0),
108 Intensity(1.0f),
109 Ambient(1,1,1),
110 Diffuse(1,1,1),
111 Specular(1,1,1),
112 NearAttenStart(0.0f),
113 NearAttenEnd(0.0f),
114 FarAttenStart(50.0f),
115 FarAttenEnd(100.0f),
116 SpotAngle(DEG_TO_RADF(45.0f)),
117 SpotAngleCos(0.707f),
118 SpotExponent(1.0f),
119 SpotDirection(0,0,1)//,
120 //Donut (false)
121
122{
123 if (type == DIRECTIONAL) {
124 Set_Force_Visible(true); // The light has no position so culling cant work.
125 }
126}
127
128
129/***********************************************************************************************
130 * LightClass::LightClass -- copy constructor *
131 * *
132 * INPUT: *
133 * *
134 * OUTPUT: *
135 * *
136 * WARNINGS: *
137 * *
138 * HISTORY: *
139 * 3/21/98 GTH : Created. *
140 *=============================================================================================*/
159
160
161/***********************************************************************************************
162 * LightClass::operator == -- assignment operator *
163 * *
164 * INPUT: *
165 * *
166 * OUTPUT: *
167 * *
168 * WARNINGS: *
169 * *
170 * HISTORY: *
171 * 3/21/98 GTH : Created. *
172 *=============================================================================================*/
174{
175 if (this != &that) {
177
178 Type = that.Type;
179 Flags = that.Flags;
181 Intensity = that.Intensity;
182 Ambient = that.Ambient;
183 Diffuse = that.Diffuse;
184 Specular = that.Specular;
189 SpotAngle = that.SpotAngle;
193 }
194 return * this;
195}
196
197
198/***********************************************************************************************
199 * LightClass::~LightClass -- destructor *
200 * *
201 * INPUT: *
202 * *
203 * OUTPUT: *
204 * *
205 * WARNINGS: *
206 * *
207 * HISTORY: *
208 * 3/21/98 GTH : Created. *
209 *=============================================================================================*/
213
214
215/***********************************************************************************************
216 * LightClass::Clone -- virtual copy constructor *
217 * *
218 * INPUT: *
219 * *
220 * OUTPUT: *
221 * *
222 * WARNINGS: *
223 * *
224 * HISTORY: *
225 * 3/21/98 GTH : Created. *
226 *=============================================================================================*/
228{
229 return W3DNEW LightClass(*this);
230}
231
232
233/***********************************************************************************************
234 * LightClass::Notify_Added -- lights add themselves to the VP list when added *
235 * *
236 * INPUT: *
237 * *
238 * OUTPUT: *
239 * *
240 * WARNINGS: *
241 * *
242 * HISTORY: *
243 * 2/26/99 GTH : Created. *
244 *=============================================================================================*/
250
251
252/***********************************************************************************************
253 * LightClass::Notify_Removed -- lights remove themselves from the VP list when removed *
254 * *
255 * INPUT: *
256 * *
257 * OUTPUT: *
258 * *
259 * WARNINGS: *
260 * *
261 * HISTORY: *
262 * 2/26/99 GTH : Created. *
263 *=============================================================================================*/
269
270
271
272/***********************************************************************************************
273 * LightClass::Get_Obj_Space_Bounding_Sphere -- returns the object space bounding sphere *
274 * *
275 * INPUT: *
276 * *
277 * OUTPUT: *
278 * *
279 * WARNINGS: *
280 * *
281 * HISTORY: *
282 * 12/8/98 GTH : Created. *
283 *=============================================================================================*/
285{
286 sphere.Center.Set(0,0,0);
287 sphere.Radius = Get_Attenuation_Range();
288}
289
290
291/***********************************************************************************************
292 * LightClass::Get_Obj_Space_Bounding_Box -- returns the object space bounding box *
293 * *
294 * INPUT: *
295 * *
296 * OUTPUT: *
297 * *
298 * WARNINGS: *
299 * *
300 * HISTORY: *
301 * 12/8/98 GTH : Created. *
302 *=============================================================================================*/
304{
305 float r = Get_Attenuation_Range();
306 box.Center.Set(0,0,0);
307 box.Extent.Set(r,r,r);
308}
309
310
311/***********************************************************************************************
312 * LightClass::Load_W3D -- Initialize this light from a W3D file *
313 * *
314 * INPUT: *
315 * *
316 * OUTPUT: *
317 * *
318 * WARNINGS: *
319 * *
320 * HISTORY: *
321 * 9/23/99 GTH : Created. *
322 *=============================================================================================*/
324{
325 W3dLightStruct lightinfo;
326
327 cload.Open_Chunk();
329 cload.Read(&lightinfo,sizeof(lightinfo));
330 cload.Close_Chunk();
331
332 switch(lightinfo.Attributes & W3D_LIGHT_ATTRIBUTE_TYPE_MASK)
333 {
335 Type = POINT;
336 break;
339 break;
341 Type = SPOT;
342 break;
343 }
344
346 Set_Intensity(lightinfo.Intensity);
347
348 Vector3 color;
349 W3dUtilityClass::Convert_Color(lightinfo.Ambient,&color);
350 Set_Ambient(color);
351 W3dUtilityClass::Convert_Color(lightinfo.Diffuse,&color);
352 Set_Diffuse(color);
354 Set_Specular(color);
355
356 W3dSpotLightStruct spotinfo;
358 Vector3 vec;
359
360 while (cload.Open_Chunk()) {
361 switch(cload.Cur_Chunk_ID())
362 {
364 cload.Read(&spotinfo,sizeof(spotinfo));
365 Set_Spot_Angle(spotinfo.SpotAngle);
369 break;
370
372 cload.Read(&atteninfo,sizeof(atteninfo));
374 Set_Near_Attenuation_Range(atteninfo.Start,atteninfo.End);
375 break;
376
378 cload.Read(&atteninfo,sizeof(atteninfo));
380 Set_Far_Attenuation_Range(atteninfo.Start,atteninfo.End);
381 break;
382 }
383 cload.Close_Chunk();
384 }
385
386 return WW3D_ERROR_OK;
387}
388
389
390/***********************************************************************************************
391 * LightClass::Save_W3D -- Save this light's settings into a W3D file *
392 * *
393 * INPUT: *
394 * *
395 * OUTPUT: *
396 * *
397 * WARNINGS: *
398 * *
399 * HISTORY: *
400 * 9/23/99 GTH : Created. *
401 *=============================================================================================*/
403{
405
407
408 W3dLightStruct lightinfo;
409 memset(&lightinfo,0,sizeof(lightinfo));
410
411 switch (Type)
412 {
413 case POINT:
415 break;
416 case DIRECTIONAL:
418 break;
419 case SPOT:
421 break;
422 }
423
424 if (Are_Shadows_Enabled()) {
426 }
427
428 Vector3 color;
429 Get_Ambient(&color);
430 W3dUtilityClass::Convert_Color(color,(&lightinfo.Ambient));
431 Get_Diffuse(&color);
432 W3dUtilityClass::Convert_Color(color,(&lightinfo.Diffuse));
433 Get_Specular(&color);
434 W3dUtilityClass::Convert_Color(color,(&lightinfo.Specular));
435
436 lightinfo.Intensity = Get_Intensity();
437
438 csave.Write(&lightinfo,sizeof(lightinfo));
439 csave.End_Chunk();
440
441 if (Type == SPOT) {
443
444 W3dSpotLightStruct spotinfo;
445 memset(&spotinfo,0,sizeof(spotinfo));
446 spotinfo.SpotAngle = SpotAngle;
447 spotinfo.SpotExponent = SpotExponent;
448 spotinfo.SpotDirection.X = SpotDirection.X;
449 spotinfo.SpotDirection.Y = SpotDirection.Y;
450 spotinfo.SpotDirection.Z = SpotDirection.Z;
451 csave.Write(&spotinfo,sizeof(spotinfo));
452
453 csave.End_Chunk();
454 }
455
458
459 double start,end;
461
463 memset(&atten,0,sizeof(atten));
464 atten.Start = start;
465 atten.End = end;
466 csave.Write(&atten,sizeof(atten));
467
468 csave.End_Chunk();
469 }
470
473
474 double start,end;
475 Get_Far_Attenuation_Range(start,end);
476
478 memset(&atten,0,sizeof(atten));
479 atten.Start = start;
480 atten.End = end;
481 csave.Write(&atten,sizeof(atten));
482
483 csave.End_Chunk();
484 }
485
486 csave.End_Chunk();
487
488 return WW3D_ERROR_OK;
489}
490
491
492/***********************************************************************************************
493 * LightClass::Get_Factory -- get the PersistFactory for LightClass *
494 * *
495 * INPUT: *
496 * *
497 * OUTPUT: *
498 * *
499 * WARNINGS: *
500 * *
501 * HISTORY: *
502 * 9/23/99 GTH : Created. *
503 *=============================================================================================*/
505{
506 return _LightFactory;
507}
508
509
510/***********************************************************************************************
511 * LightClass::Save -- persistant object support *
512 * *
513 * INPUT: *
514 * *
515 * OUTPUT: *
516 * *
517 * WARNINGS: *
518 * *
519 * HISTORY: *
520 * 9/23/99 GTH : Created. *
521 *=============================================================================================*/
523{
525 Save_W3D(csave);
526 csave.End_Chunk();
527
528 Matrix3D tm = Get_Transform();
531 csave.End_Chunk();
532
533 return true;
534}
535
536
537/***********************************************************************************************
538 * LightClass::Load -- persistant object support *
539 * *
540 * INPUT: *
541 * *
542 * OUTPUT: *
543 * *
544 * WARNINGS: *
545 * *
546 * HISTORY: *
547 * 9/23/99 GTH : Created. *
548 *=============================================================================================*/
550{
551 Matrix3D tm(1);
552 while (cload.Open_Chunk()) {
553 switch (cload.Cur_Chunk_ID()) {
554
556 // The W3D code is non-symmetrical, the Save function writes a W3D_LIGHT chunk
557 // but the load function expects the external user to have opened it. So open it here...
558 cload.Open_Chunk();
559 Load_W3D(cload);
560 cload.Close_Chunk();
561 break;
562
564 while (cload.Open_Micro_Chunk()) {
565 switch(cload.Cur_Micro_Chunk_ID()) {
567 }
568 cload.Close_Micro_Chunk();
569 }
570 break;
571
572 default:
573 WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",__FILE__,__LINE__));
574 break;
575 }
576 cload.Close_Chunk();
577 }
578 Set_Transform(tm);
579 return true;
580}
581
#define WWASSERT
#define W3D_LIGHT_ATTRIBUTE_SPOT
Definition w3d_file.h:1703
#define W3D_LIGHT_ATTRIBUTE_DIRECTIONAL
Definition w3d_file.h:1702
@ W3D_CHUNK_FAR_ATTENUATION
Definition w3d_file.h:442
@ W3D_CHUNK_LIGHT
Definition w3d_file.h:438
@ W3D_CHUNK_SPOT_LIGHT_INFO
Definition w3d_file.h:440
@ W3D_CHUNK_NEAR_ATTENUATION
Definition w3d_file.h:441
@ W3D_CHUNK_LIGHT_INFO
Definition w3d_file.h:439
#define W3D_LIGHT_ATTRIBUTE_POINT
Definition w3d_file.h:1701
#define W3D_LIGHT_ATTRIBUTE_CAST_SHADOWS
Definition w3d_file.h:1704
#define W3D_LIGHT_ATTRIBUTE_TYPE_MASK
Definition w3d_file.h:1700
#define W3DNEW
Definition always.h:109
@ false
Definition bool.h:59
#define WRITE_MICRO_CHUNK(csave, id, var)
Definition chunkio.h:293
#define READ_MICRO_CHUNK(cload, id, var)
Definition chunkio.h:334
#define DEG_TO_RADF(x)
Definition wwmath.h:87
Vector3 Center
Definition aabox.h:123
Vector3 Extent
Definition aabox.h:124
bool Close_Micro_Chunk()
Definition chunkio.cpp:585
bool Close_Chunk()
Definition chunkio.cpp:448
uint32 Cur_Chunk_ID()
Definition chunkio.cpp:484
uint32 Cur_Micro_Chunk_ID()
Definition chunkio.cpp:622
uint32 Read(void *buf, uint32 nbytes)
Definition chunkio.cpp:692
bool Open_Chunk()
Definition chunkio.cpp:412
bool Open_Micro_Chunk()
Definition chunkio.cpp:557
uint32 Write(const void *buf, uint32 nbytes)
Definition chunkio.cpp:264
bool Begin_Chunk(uint32 id)
Definition chunkio.cpp:108
bool End_Chunk()
Definition chunkio.cpp:148
float SpotAngleCos
Definition light.h:178
virtual bool Load(ChunkLoadClass &cload)
Definition light.cpp:549
virtual void Notify_Removed(SceneClass *scene)
Definition light.cpp:264
float Get_Intensity(void) const
Definition light.h:108
void Set_Diffuse(const Vector3 &color)
Definition light.h:113
void Get_Far_Attenuation_Range(double &fStart, double &fEnd) const
Definition light.h:120
float FarAttenEnd
Definition light.h:175
unsigned int Flags
Definition light.h:164
Vector3 Specular
Definition light.h:170
void Set_Flag(FlagsType flag, bool onoff)
Definition light.h:129
bool Are_Shadows_Enabled(void) const
Definition light.h:132
RenderObjClass * Clone(void) const
Definition light.cpp:227
void Set_Spot_Direction(const Vector3 &dir)
Definition light.h:141
WW3DErrorType Save_W3D(ChunkSaveClass &csave)
Definition light.cpp:402
void Get_Ambient(Vector3 *set_c) const
Definition light.h:111
void Enable_Shadows(bool onoff)
Definition light.h:131
Vector3 SpotDirection
Definition light.h:180
float SpotAngle
Definition light.h:177
LightClass(LightType type=POINT)
Definition light.cpp:104
float NearAttenEnd
Definition light.h:173
virtual ~LightClass(void)
Definition light.cpp:210
float FarAttenStart
Definition light.h:174
Vector3 Diffuse
Definition light.h:169
void Set_Near_Attenuation_Range(double nStart, double nEnd)
Definition light.h:122
@ POINT
Definition light.h:63
@ DIRECTIONAL
Definition light.h:64
void Set_Spot_Exponent(float k)
Definition light.h:143
WW3DErrorType Load_W3D(ChunkLoadClass &cload)
Definition light.cpp:323
@ NEAR_ATTENUATION
Definition light.h:70
@ FAR_ATTENUATION
Definition light.h:71
void Set_Ambient(const Vector3 &color)
Definition light.h:110
virtual const PersistFactoryClass & Get_Factory(void) const
Definition light.cpp:504
void Set_Spot_Angle(float a)
Definition light.h:138
float NearAttenStart
Definition light.h:172
void Get_Near_Attenuation_Range(double &nStart, double &nEnd) const
Definition light.h:123
float Intensity
Definition light.h:167
void Set_Intensity(float inten)
Definition light.h:107
LightType Type
Definition light.h:163
virtual bool Save(ChunkSaveClass &csave)
Definition light.cpp:522
void Set_Far_Attenuation_Range(double fStart, double fEnd)
Definition light.h:119
int Get_Flag(FlagsType flag) const
Definition light.h:130
virtual void Notify_Added(SceneClass *scene)
Definition light.cpp:245
LightClass & operator=(const LightClass &)
Definition light.cpp:173
Vector3 Ambient
Definition light.h:168
virtual void Get_Obj_Space_Bounding_Box(AABoxClass &box) const
Definition light.cpp:303
bool CastShadows
Definition light.h:165
void Get_Diffuse(Vector3 *set_c) const
Definition light.h:114
void Set_Specular(const Vector3 &color)
Definition light.h:116
float SpotExponent
Definition light.h:179
void Get_Specular(Vector3 *set_c) const
Definition light.h:117
virtual void Get_Obj_Space_Bounding_Sphere(SphereClass &sphere) const
Definition light.cpp:284
float Get_Attenuation_Range(void) const
Definition light.h:124
virtual void Set_Transform(const Matrix3D &m)
Definition rendobj.cpp:423
RenderObjClass(void)
Definition rendobj.cpp:170
virtual void Notify_Added(SceneClass *scene)
Definition rendobj.cpp:862
RenderObjClass & operator=(const RenderObjClass &)
Definition rendobj.cpp:232
virtual void Set_Force_Visible(int onoff)
Definition rendobj.h:476
virtual void Notify_Removed(SceneClass *scene)
Definition rendobj.cpp:884
const Matrix3D & Get_Transform(void) const
Definition rendobj.h:617
friend class SceneClass
Definition rendobj.h:563
virtual void Register(RenderObjClass *obj, RegType for_what)=0
virtual void Unregister(RenderObjClass *obj, RegType for_what)=0
float Radius
Definition sphere.h:91
Vector3 Center
Definition sphere.h:90
WWINLINE void Set(float x, float y, float z)
Definition vector3.h:103
static void Convert_Vector(const W3dVectorStruct &v, Vector3 *set)
Definition w3d_util.cpp:45
static void Convert_Color(const W3dRGBStruct &rgb, Vector3 *set)
Definition w3d_util.cpp:75
@ LIGHT_CHUNK_VARIABLES
Definition light.cpp:84
@ LIGHT_CHUNK_W3DFILE
Definition light.cpp:83
@ LIGHT_VARIABLE_TRANSFORM
Definition light.cpp:86
SimplePersistFactoryClass< LightClass, WW3D_PERSIST_CHUNKID_LIGHT > _LightFactory
Definition light.cpp:76
W3dRGBStruct Diffuse
Definition w3d_file.h:1711
uint32 Attributes
Definition w3d_file.h:1708
W3dRGBStruct Specular
Definition w3d_file.h:1712
W3dRGBStruct Ambient
Definition w3d_file.h:1710
float32 Intensity
Definition w3d_file.h:1713
W3dVectorStruct SpotDirection
Definition w3d_file.h:1718
WW3DErrorType
Definition w3derr.h:51
@ WW3D_ERROR_OK
Definition w3derr.h:52
#define WWDEBUG_SAY(x)
Definition wwdebug.h:114