1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
19 /***********************************************************************
25 Declaration of variables specific to light sources
30 A light source is defined by :
33 - reduction factors ( for positional and spot only )
34 - its angle ( for spot only )
35 - its concentration ( for spot only )
36 - its direction ( directional and spot only )
37 - its position ( positional and spot only )
39 It is active in a view, in the associated context.
44 - AngleCone is given in radian [Pex] while OpenGl works in
45 degreees. The limits for Pex are [0,PI] while for OpenGl this is [0,90].
46 - Two reduction factors are used with Pex while OpenGl uses three.
47 - The ereduction factors have range [0.0,1.0] for Pex and
48 for OpenGl the range is [0.0,n]
49 - The concentration varies from [0.,1.0] for Pex to [0,128] for OpenGl.
51 ************************************************************************/
53 /*----------------------------------------------------------------------*/
58 #include <Visual3d_Light.ixx>
60 #include <Graphic3d_GraphicDriver.hxx>
62 /*----------------------------------------------------------------------*/
64 Visual3d_Light::Visual3d_Light ():
65 MyType (Visual3d_TOLS_AMBIENT) {
68 MyCLight.ViewId = 0; /* not used */
69 MyCLight.LightType = int (MyType);
70 MyCLight.Headlight = 0;
72 Quantity_Color White (Quantity_NOC_WHITE);
74 MyCLight.Color.r = float (White.Red ());
75 MyCLight.Color.g = float (White.Green ());
76 MyCLight.Color.b = float (White.Blue ());
79 Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
83 /*----------------------------------------------------------------------*/
85 Visual3d_Light::Visual3d_Light (const Quantity_Color& Color):
86 MyType (Visual3d_TOLS_AMBIENT) {
89 MyCLight.ViewId = 0; /* not used */
90 MyCLight.LightType = int (MyType);
91 MyCLight.Headlight = 0;
93 MyCLight.Color.r = float (Color.Red ());
94 MyCLight.Color.g = float (Color.Green ());
95 MyCLight.Color.b = float (Color.Blue ());
98 Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
102 /*----------------------------------------------------------------------*/
104 Visual3d_Light::Visual3d_Light(const Quantity_Color& Color,const Graphic3d_Vector& Direction,const Standard_Boolean Headlight): MyType (Visual3d_TOLS_DIRECTIONAL) {
106 if (Direction.LengthZero ())
107 Visual3d_LightDefinitionError::Raise
108 ("Bad value for LightDirection");
111 MyCLight.ViewId = 0; /* not used */
112 MyCLight.LightType = int (MyType);
113 MyCLight.Headlight = Headlight? 1:0;
115 Standard_Real Norme, X, Y, Z;
117 Color.Values (X, Y, Z, Quantity_TOC_RGB);
118 MyCLight.Color.r = float (X);
119 MyCLight.Color.g = float (Y);
120 MyCLight.Color.b = float (Z);
122 Direction.Coord (X, Y, Z);
123 Norme = Sqrt (X*X+Y*Y+Z*Z);
124 // Direction.LengthZero () == Standard_False
125 MyCLight.Direction.x = float (X/Norme);
126 MyCLight.Direction.y = float (Y/Norme);
127 MyCLight.Direction.z = float (Z/Norme);
130 Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
134 /*----------------------------------------------------------------------*/
136 Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Standard_Real Fact1, const Standard_Real Fact2):
137 MyType (Visual3d_TOLS_POSITIONAL) {
139 if ( (Fact1 == 0.0) && (Fact2 == 0.0) )
140 Visual3d_LightDefinitionError::Raise
141 ("Bad value for LightAttenuation");
143 if ( (Fact1 < 0.0) || (Fact1 > 1.0) )
144 Visual3d_LightDefinitionError::Raise
145 ("Bad value for LightAttenuation");
147 if ( (Fact2 < 0.0) || (Fact2 > 1.0) )
148 Visual3d_LightDefinitionError::Raise
149 ("Bad value for LightAttenuation");
152 MyCLight.ViewId = 0; /* not used */
153 MyCLight.LightType = int (MyType);
154 MyCLight.Headlight = 0;
156 MyCLight.Color.r = float (Color.Red ());
157 MyCLight.Color.g = float (Color.Green ());
158 MyCLight.Color.b = float (Color.Blue ());
160 MyCLight.Position.x = float (Position.X ());
161 MyCLight.Position.y = float (Position.Y ());
162 MyCLight.Position.z = float (Position.Z ());
164 MyCLight.Attenuation[0] = float (Fact1);
165 MyCLight.Attenuation[1] = float (Fact2);
168 Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
172 /*----------------------------------------------------------------------*/
174 Visual3d_Light::Visual3d_Light (const Quantity_Color& Color, const Graphic3d_Vertex& Position, const Graphic3d_Vector& Direction, const Standard_Real Concentration, const Standard_Real Fact1, const Standard_Real Fact2, const Standard_Real AngleCone):
175 MyType (Visual3d_TOLS_SPOT) {
177 if (Direction.LengthZero ())
178 Visual3d_LightDefinitionError::Raise
179 ("Bad value for LightDirection");
181 if ( (Concentration < 0.0) || (Concentration > 1.0) )
182 Visual3d_LightDefinitionError::Raise
183 ("Bad value for LightConcentration");
185 if ( (Fact1 == 0.0) && (Fact2 == 0.0) )
186 Visual3d_LightDefinitionError::Raise
187 ("Bad value for LightAttenuation");
189 if ( (Fact1 < 0.0) || (Fact1 > 1.0) )
190 Visual3d_LightDefinitionError::Raise
191 ("Bad value for LightAttenuation");
193 if ( (Fact2 < 0.0) || (Fact2 > 1.0) )
194 Visual3d_LightDefinitionError::Raise
195 ("Bad value for LightAttenuation");
197 if (Visual3d_Light::IsValid (AngleCone)) {
200 MyCLight.ViewId = 0; /* not used */
201 MyCLight.LightType = int (MyType);
202 MyCLight.Headlight = 0;
204 Standard_Real X, Y, Z;
206 Color.Values (X, Y, Z, Quantity_TOC_RGB);
207 MyCLight.Color.r = float (X);
208 MyCLight.Color.g = float (Y);
209 MyCLight.Color.b = float (Z);
211 Position.Coord (X, Y, Z);
212 MyCLight.Position.x = float (X);
213 MyCLight.Position.y = float (Y);
214 MyCLight.Position.z = float (Z);
216 Direction.Coord (X, Y, Z);
217 MyCLight.Direction.x = float (X);
218 MyCLight.Direction.y = float (Y);
219 MyCLight.Direction.z = float (Z);
221 MyCLight.Concentration = float (Concentration);
223 MyCLight.Attenuation[0] = float (Fact1);
224 MyCLight.Attenuation[1] = float (Fact2);
226 MyCLight.Angle = float (AngleCone);
229 Graphic3d_GraphicDriver::Light (MyCLight, Standard_False);
233 Visual3d_LightDefinitionError::Raise
234 ("Bad value for LightAngle");
238 /*----------------------------------------------------------------------*/
240 Quantity_Color Visual3d_Light::Color () const {
242 Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
243 Standard_Real (MyCLight.Color.g),
244 Standard_Real (MyCLight.Color.b),
251 /*----------------------------------------------------------------------*/
253 Visual3d_TypeOfLightSource Visual3d_Light::LightType () const {
259 /*----------------------------------------------------------------------*/
260 Standard_Boolean Visual3d_Light::Headlight () const {
261 return MyCLight.Headlight==0? Standard_False:Standard_True;
264 /*----------------------------------------------------------------------*/
266 void Visual3d_Light::Values (Quantity_Color& Color) const {
268 Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
269 Standard_Real (MyCLight.Color.g),
270 Standard_Real (MyCLight.Color.b),
273 if (MyType == Visual3d_TOLS_AMBIENT)
275 else Visual3d_LightDefinitionError::Raise
276 ("Light Type != Visual3d_TOLS_AMBIENT");
280 /*----------------------------------------------------------------------*/
282 void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vector& Direction) const {
284 Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
285 Standard_Real (MyCLight.Color.g),
286 Standard_Real (MyCLight.Color.b),
289 Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x),
290 Standard_Real (MyCLight.Direction.y),
291 Standard_Real (MyCLight.Direction.z));
293 if (MyType == Visual3d_TOLS_DIRECTIONAL) {
295 Direction = ADirection;
297 else Visual3d_LightDefinitionError::Raise
298 ("Light Type != Visual3d_TOLS_DIRECTIONAL");
302 /*----------------------------------------------------------------------*/
304 void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Standard_Real& Fact1, Standard_Real& Fact2) const {
306 Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
307 Standard_Real (MyCLight.Color.g),
308 Standard_Real (MyCLight.Color.b),
311 Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x),
312 Standard_Real (MyCLight.Position.y),
313 Standard_Real (MyCLight.Position.z));
315 if (MyType == Visual3d_TOLS_POSITIONAL) {
317 Position = APosition;
318 Fact1 = Standard_Real (MyCLight.Attenuation[0]);
319 Fact2 = Standard_Real (MyCLight.Attenuation[1]);
321 else Visual3d_LightDefinitionError::Raise
322 ("Light Type != Visual3d_TOLS_POSITIONAL");
326 /*----------------------------------------------------------------------*/
328 void Visual3d_Light::Values (Quantity_Color& Color, Graphic3d_Vertex& Position, Graphic3d_Vector& Direction, Standard_Real& Concentration, Standard_Real& Fact1, Standard_Real& Fact2, Standard_Real& AngleCone) const {
330 Quantity_Color AColor (Standard_Real (MyCLight.Color.r),
331 Standard_Real (MyCLight.Color.g),
332 Standard_Real (MyCLight.Color.b),
335 Graphic3d_Vertex APosition (Standard_Real (MyCLight.Position.x),
336 Standard_Real (MyCLight.Position.y),
337 Standard_Real (MyCLight.Position.z));
339 Graphic3d_Vector ADirection (Standard_Real (MyCLight.Direction.x),
340 Standard_Real (MyCLight.Direction.y),
341 Standard_Real (MyCLight.Direction.z));
343 if (MyType == Visual3d_TOLS_SPOT) {
345 Position = APosition;
346 Direction = ADirection;
347 Concentration = Standard_Real (MyCLight.Concentration);
348 Fact1 = Standard_Real (MyCLight.Attenuation[0]);
349 Fact2 = Standard_Real (MyCLight.Attenuation[1]);
350 AngleCone = Standard_Real (MyCLight.Angle);
352 else Visual3d_LightDefinitionError::Raise
353 ("Light Type != Visual3d_TOLS_SPOT");
357 /*----------------------------------------------------------------------*/
359 void Visual3d_Light::SetAngle (const Standard_Real AngleCone) {
361 if (! Visual3d_Light::IsValid (AngleCone))
362 Visual3d_LightDefinitionError::Raise
363 ("Bad value for LightAngle");
365 if (MyType == Visual3d_TOLS_SPOT) {
366 MyCLight.Angle = float (AngleCone);
369 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
372 else Visual3d_LightDefinitionError::Raise
373 ("Light Type != Visual3d_TOLS_SPOT");
377 /*----------------------------------------------------------------------*/
379 void Visual3d_Light::SetAttenuation1 (const Standard_Real Fact1) {
381 if ( (Fact1 < 0.0) || (Fact1 > 1.0) )
382 Visual3d_LightDefinitionError::Raise
383 ("Bad value for LightAttenuation");
385 if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
386 (MyType == Visual3d_TOLS_SPOT) ) {
387 MyCLight.Attenuation[0] = float (Fact1);
390 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
393 else Visual3d_LightDefinitionError::Raise
394 ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
398 /*----------------------------------------------------------------------*/
400 void Visual3d_Light::SetAttenuation2 (const Standard_Real Fact2) {
402 if ( (Fact2 < 0.0) || (Fact2 > 1.0) )
403 Visual3d_LightDefinitionError::Raise
404 ("Bad value for LightAttenuation");
406 if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
407 (MyType == Visual3d_TOLS_SPOT) ) {
408 MyCLight.Attenuation[1] = float (Fact2);
411 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
414 else Visual3d_LightDefinitionError::Raise
415 ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
419 /*----------------------------------------------------------------------*/
421 void Visual3d_Light::SetColor (const Quantity_Color& Color) {
423 MyCLight.Color.r = float (Color.Red ());
424 MyCLight.Color.g = float (Color.Green ());
425 MyCLight.Color.b = float (Color.Blue ());
428 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
432 /*----------------------------------------------------------------------*/
434 void Visual3d_Light::SetConcentration (const Standard_Real Concentration) {
436 if ( (Concentration < 0.0) || (Concentration > 1.0) )
437 Visual3d_LightDefinitionError::Raise
438 ("Bad value for LightConcentration");
440 if (MyType == Visual3d_TOLS_SPOT) {
441 MyCLight.Concentration = float (Concentration);
444 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
446 else Visual3d_LightDefinitionError::Raise
447 ("Light Type != Visual3d_TOLS_SPOT");
451 /*----------------------------------------------------------------------*/
453 void Visual3d_Light::SetDirection (const Graphic3d_Vector& Direction) {
455 if (Direction.LengthZero ())
456 Visual3d_LightDefinitionError::Raise
457 ("Bad value for LightDirection");
459 if ( (MyType == Visual3d_TOLS_DIRECTIONAL) ||
460 (MyType == Visual3d_TOLS_SPOT) ) {
462 Standard_Real Norme, X, Y, Z;
463 Direction.Coord (X, Y, Z);
464 Norme = Sqrt (X*X+Y*Y+Z*Z);
465 // Direction.LengthZero () == Standard_False
466 MyCLight.Direction.x = float (X/Norme);
467 MyCLight.Direction.y = float (Y/Norme);
468 MyCLight.Direction.z = float (Z/Norme);
471 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
474 else Visual3d_LightDefinitionError::Raise
475 ("Light Type != Visual3d_TOLS_DIRECTIONAL and != Visual3d_TOLS_SPOT");
479 /*----------------------------------------------------------------------*/
481 void Visual3d_Light::SetPosition (const Graphic3d_Vertex& Position) {
483 if ( (MyType == Visual3d_TOLS_POSITIONAL) ||
484 (MyType == Visual3d_TOLS_SPOT) ) {
486 MyCLight.Position.x = float (Position.X ());
487 MyCLight.Position.y = float (Position.Y ());
488 MyCLight.Position.z = float (Position.Z ());
491 Graphic3d_GraphicDriver::Light (MyCLight, Standard_True);
494 else Visual3d_LightDefinitionError::Raise
495 ("Light Type != Visual3d_TOLS_POSITIONAL and != Visual3d_TOLS_SPOT");
499 /*----------------------------------------------------------------------*/
501 Standard_Integer Visual3d_Light::Limit () {
503 // Old method, replaced by GraphicDriver::InquireLightLimit ()
508 /*----------------------------------------------------------------------*/
510 Standard_Integer Visual3d_Light::Identification () const {
512 return (Standard_Integer (MyCLight.LightId));
516 /*----------------------------------------------------------------------*/
518 Standard_Boolean Visual3d_Light::IsValid (const Standard_Real AAngle) {
520 return ( (AAngle < M_PI) && (AAngle >= 0.0) );
524 /*----------------------------------------------------------------------*/