0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / OpenGl / OpenGl_LightBox.cxx
CommitLineData
7fd59977 1/***********************************************************************
2
3FONCTION :
4----------
5Gestion des light sous OpenGL
6
7
8REMARQUES:
9----------
10
11- We can't take in account GL_QUADRATIC_ATTENUATION.
12
13- Position des lumieres. Il faut faire le glLight(GL_POSITION) apres la
14gestion des matrices de transformation (GL_MODELVIEW).
15
16- Se mefier de GL_POSITION pour les lumieres directionelle. GL_POSITION
17indique bien la position ou se trouve la lumiere. Comme on a une direction
18comme valeur il faut l'inverser.
19
20
21FONCTIONNEMENT:
22---------------
23- La variable lightOn permet d'optimiser le changement d'etat des lumieres.
24Ceci permet d'eviter d'appeler glIsEnable(GL_LIGHTING). Il faut bien sur
25que l'on utilise les 2 points d'entree LightOn() et LightOff().
26L'init de la variable est faite par call_func_redraw_all_structs (OpenGl_funcs.c)
27
28
29HISTORIQUE DES MODIFICATIONS :
30--------------------------------
3120-06-97 : PCT ; creation
3230-06-96 : FMN ; Integration
3318-07-96 : FMN, PCT ; Correction indice, ajout IsLightOn()
3425-07-97 : CAL ; Portage NT (include OpenGl_tgl_all.h)
3507-10-97 : FMN ; Simplification WNT
36
37************************************************************************/
38
39/*----------------------------------------------------------------------*/
40/*
41* Includes
42*/
43
44#include <OpenGl_tgl_all.hxx>
45
46#include <stdio.h>
47#include <stdlib.h>
48
49#include <math.h>
50#include <memory.h>
51
52#include <OpenGl_LightBox.hxx>
53#include <OpenGl_Memory.hxx>
54
55/*----------------------------------------------------------------------*/
56/*
57* Constantes
58*/
59#ifndef DEBUG
60#define DEBUG 0
61#endif
62
63#define NO_PRINT_DEBUG
64
65#define GROW_SIZE_WKS 10
66#define GROW_SIZE_LIGHT 8
67
7fd59977 68/*----------------------------------------------------------------------*/
69/*
70* Types definis
71*/
72struct TEL_LIGHT_DATA
73{
74 Tint LightID;
75 TEL_LIGHT light;
76 IMPLEMENT_MEMORY_OPERATORS
77};
78
79struct TEL_LIGHT_WKS
80{
81 Tint wks;
82 int lights_count;
83 int lights_size;
84 TEL_LIGHT_DATA *lights;
85 IMPLEMENT_MEMORY_OPERATORS
86};
87
88
89/*----------------------------------------------------------------------*/
90/*
91* Variables statiques
92*/
93
94static TEL_LIGHT_WKS *wks = NULL;
95static int wks_count = 0;
96static int wks_size = 0;
97
98static GLfloat default_amb[4] = { 0.0, 0.0, 0.0, 1.0 };
99static GLfloat default_sptdir[3] = { 0.0, 0.0, -1.0 };
100static GLfloat default_sptexpo = 0.0;
101static GLfloat default_sptcutoff = 180.0;
102
103static GLboolean lightOn = GL_FALSE;
104
105/*----------------------------------------------------------------------*/
106/*
107* Fonctions privees
108*/
109
110/*-----------------------------------------------------------------*/
111/*
112* Set des lumieres
113*/
114static void bind_light(TEL_LIGHT *lptr, int *gl_lid)
115{
116 GLfloat data_amb[4];
117 GLfloat data_diffu[4];
118 GLfloat data_pos[4];
119 GLfloat data_sptdir[3];
120 GLfloat data_sptexpo;
121 GLfloat data_sptcutoff;
122 GLfloat data_constantattenuation;
123 GLfloat data_linearattenuation;
124 GLint cur_matrix;
125
126
127 /* on n'a droit qu'a 8 lights avec OpenGL... */
128 if (*gl_lid > GL_LIGHT7) return;
129
130
131 /* la light est une headlight ? */
132 if (lptr->HeadLight)
133 {
134 glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
135 glMatrixMode(GL_MODELVIEW);
136 glPushMatrix();
137 glLoadIdentity();
138 }
139
140
141 /* set la light en fonction de son type */
142 switch (lptr->type)
143 {
144 case TLightAmbient:
145 data_amb[0] = lptr->col.rgb[0];
146 data_amb[1] = lptr->col.rgb[1];
147 data_amb[2] = lptr->col.rgb[2];
148 data_amb[3] = 1.0;
149
150 /*------------------------- Ambient ---------------------------*/
151 /*
152 * The GL_AMBIENT parameter refers to RGBA intensity of the ambient
153 * light.
154 */
155 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb);
156
157#if DEBUG
158 printf("OpenGL_LightBox::bind_light:LightAmbient \n");
159 printf("\tGL_LIGHT_MODEL_AMBIENT %f %f %f \n", data_amb[0], data_amb[1], data_amb[2]);
160#endif
161 break;
162
163
164 case TLightDirectional:
165 data_diffu[0] = lptr->col.rgb[0];
166 data_diffu[1] = lptr->col.rgb[1];
167 data_diffu[2] = lptr->col.rgb[2];
168 data_diffu[3] = 1.0;
169
170 /*------------------------- Direction ---------------------------*/
171 /* From Open GL Programming Rev 1 Guide Chapt 6 :
172 Lighting The Mathematics of Lighting ( p 168 )
173
174 Directional Light Source ( Infinite ) :
175 if the last parameter of GL_POSITION , w , is zero, the
176 corresponding light source is a Directional one.
177
178 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
179 To create a realistic effect, set the GL_SPECULAR parameter
180 to the same value as the GL_DIFFUSE.
181 */
182
183 data_pos[0] = -lptr->dir[0];
184 data_pos[1] = -lptr->dir[1];
185 data_pos[2] = -lptr->dir[2];
186 data_pos[3] = 0.0;
187
188 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
189 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
190 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
191
192 glLightfv(*gl_lid, GL_POSITION, data_pos);
193 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
194 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
195 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
196
197#if DEBUG
198 printf("OpenGL_LightBox::bind_light:LightDirection \n");
199 printf("\tGL_AMBIENT %f %f %f \n", default_amb[0], default_amb[1], default_amb[2]);
200 printf("\tGL_DIFFUSE %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
201 printf("\tGL_SPECULAR %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
202 printf("\tGL_POSITION %f %f %f \n", data_pos[0], data_pos[1], data_pos[2]);
203#endif
204 break;
205
206
207 case TLightPositional:
208 data_diffu[0] = lptr->col.rgb[0];
209 data_diffu[1] = lptr->col.rgb[1];
210 data_diffu[2] = lptr->col.rgb[2];
211 data_diffu[3] = 1.0;
212
213 /*------------------------- Position -----------------------------*/
214 /* From Open GL Programming Rev 1 Guide Chapt 6 :
215 Lighting The Mathematics of Lighting ( p 168 )
216 Positional Light Source :
217 if the last parameter of GL_POSITION , w , is nonzero,
218 the corresponding light source is a Positional one.
219
220 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
221
222 To create a realistic effect, set the GL_SPECULAR parameter
223 to the same value as the GL_DIFFUSE.
224 */
225
226 data_pos[0] = lptr->pos[0];
227 data_pos[1] = lptr->pos[1];
228 data_pos[2] = lptr->pos[2];
229 data_pos[3] = 1.0;
230
231 data_constantattenuation = lptr->atten[0];
232 data_linearattenuation = lptr->atten[1];
233
234 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
235 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
236 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
237
238 glLightfv(*gl_lid, GL_POSITION, data_pos);
239 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
240 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
241 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
242 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
243 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
244 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
245
246#if DEBUG
247 printf("OpenGL_LightBox::bind_light:LightPosition \n");
248 printf("\tGL_AMBIENT %f %f %f \n", default_amb[0], default_amb[1], default_amb[2]);
249 printf("\tGL_DIFFUSE %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
250 printf("\tGL_SPECULAR %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
251 printf("\tGL_POSITION %f %f %f \n", data_pos[0], data_pos[1], data_pos[2]);
252#endif
253 break;
254
255
256 case TLightSpot:
257 data_diffu[0] = lptr->col.rgb[0];
258 data_diffu[1] = lptr->col.rgb[1];
259 data_diffu[2] = lptr->col.rgb[2];
260 data_diffu[3] = 1.0;
261
262 data_pos[0] = lptr->pos[0];
263 data_pos[1] = lptr->pos[1];
264 data_pos[2] = lptr->pos[2];
265 data_pos[3] = 1.0;
266
267 data_sptdir[0] = lptr->dir[0];
268 data_sptdir[1] = lptr->dir[1];
269 data_sptdir[2] = lptr->dir[2];
270
271 data_sptexpo = ( float )lptr->shine * 128.0F;
272 data_sptcutoff = ( float )(lptr->angle * 180.0F)/( float )M_PI;
273
274 data_constantattenuation = lptr->atten[0];
275 data_linearattenuation = lptr->atten[1];
276
277 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
278 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
279 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
280
281 glLightfv(*gl_lid, GL_POSITION, data_pos);
282 glLightfv(*gl_lid, GL_SPOT_DIRECTION, data_sptdir);
283 glLightf(*gl_lid, GL_SPOT_EXPONENT, data_sptexpo);
284 glLightf(*gl_lid, GL_SPOT_CUTOFF, data_sptcutoff);
285 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
286 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
287 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
288
289#if DEBUG
290 printf("OpenGL_LightBox::bind_light:LightSpot \n");
291 printf("\tGL_AMBIENT %f %f %f \n", default_amb[0], default_amb[1], default_amb[2]);
292 printf("\tGL_DIFFUSE %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
293 printf("\tGL_SPECULAR %f %f %f \n", data_diffu[0], data_diffu[1], data_diffu[2]);
294 printf("\tGL_POSITION %f %f %f \n", data_pos[0], data_pos[1], data_pos[2]);
295 printf("\tGL_SPOT_DIRECTION %f %f %f \n", data_sptdir[0], data_sptdir[1], data_sptdir[2]);
296 printf("\tGL_SPOT_EXPONENT %f \n", data_sptexpo);
297 printf("\tGL_SPOT_CUTOFF %f \n", data_sptcutoff);
298 printf("\tGL_CONSTANT_ATTENUATION %f \n", data_constantattenuation);
299 printf("\tGL_LINEAR_ATTENUATION %f \n", data_linearattenuation);
300#endif
301 break;
302 }
303
304
305 if (lptr->type != TLightAmbient)
306 {
307#if DEBUG
308 printf("OpenGL_LightBox::bind_light:glEnable %d \n", *gl_lid);
309#endif
310 glEnable(*gl_lid);
311 (*gl_lid)++;
312 }
313
314
315 /* si la light etait une headlight alors restaure la matrice precedente */
316 if (lptr->HeadLight)
317 {
318 glPopMatrix();
319 glMatrixMode(cur_matrix);
320 }
321}
322
323
324/*-----------------------------------------------------------------*/
325/*
326* recherche de la liste de lampe d'une wks, creation d'une liste si non existante
327*/
328static int find_wks(Tint WksID, int alloc)
329{
330 int i;
331
332 /* recherche la wks dans la liste si elle existe */
333 for (i=0; i<wks_count; i++)
334 if (wks[i].wks == WksID)
335 return i;
336
337 if (!alloc) return -1;
338
339 /* la wks n'existe pas => on fait de la place si yen a plus */
340 if (wks_count == wks_size )
341 {
342 wks_size += GROW_SIZE_WKS;
343 if (!wks)
344 wks = new TEL_LIGHT_WKS[wks_size];
345 else
346#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
347 wks = (TEL_LIGHT_WKS*)realloc(wks, wks_size*sizeof(TEL_LIGHT_WKS));
348#else
349 wks = cmn_resizemem<TEL_LIGHT_WKS>(wks, wks_size);
350#endif
351
352 if (!wks)
353 return -1;
354 }
355
356 wks[wks_count].wks = WksID;
357 wks[wks_count].lights = NULL;
358 wks[wks_count].lights_size = 0;
359 wks[wks_count].lights_count = 0;
360
361 return wks_count++;
362}
363
364/*-----------------------------------------------------------------*/
365/*
366* recherche une lampe d'une wks, creation d'une lampe si elle n'existe pas
367*/
368static int find_light(int WksIdx, Tint LightID, int alloc)
369{
370 int i;
371 TEL_LIGHT_DATA *lights;
372
373
374 /* recherche la light dans la liste de la wks */
375 lights = wks[WksIdx].lights;
376 for (i=0; i<wks[WksIdx].lights_count; i++)
377 if (lights[i].LightID == LightID)
378 return i;
379
380 if (!alloc) return -1;
381
382 /* la lampe n'existe pas => on cree une lampe */
383 if (wks[WksIdx].lights_count == wks[WksIdx].lights_size)
384 {
385 wks[WksIdx].lights_size += GROW_SIZE_LIGHT;
386 if (!wks[WksIdx].lights)
387 wks[WksIdx].lights = new TEL_LIGHT_DATA[wks[WksIdx].lights_size];
388 else
389 wks[WksIdx].lights =
390#if defined(__SUNPRO_CC) && (__SUNPRO_CC <= 0x530)
391 (TEL_LIGHT_DATA*)realloc( wks[WksIdx].lights,
392 wks[WksIdx].lights_size*sizeof(TEL_LIGHT_DATA) );
393#else
394 cmn_resizemem<TEL_LIGHT_DATA>( wks[WksIdx].lights,
395 wks[WksIdx].lights_size );
396#endif
397 if (!wks[WksIdx].lights)
398 return -1;
399 }
400
401 return wks[WksIdx].lights_count++;
402}
403
404
405/*----------------------------------------------------------------------*/
406/*
407* Fonctions publiques
408*/
409
410
411/*-----------------------------------------------------------------*/
412/*
413* Ajout d'une lumiere dans la Wks
414*/
415TStatus AddLight(Tint WksID, Tint LightID, tel_light light)
416{
417 int wks_entry;
418 int light_entry;
419
420#if DEBUG
421 printf("AddLight %d dans wks %d [wds_count=%d]\n", LightID, WksID, wks_count);
422#endif
423
424 /* obtient le numero de la liste de lights de la wks */
425 wks_entry = find_wks(WksID, 1);
426 if (wks_entry == -1) return TFailure;
427
428 /* recherche le numero de la lampe si elle existe */
429 light_entry = find_light(wks_entry, LightID, 1);
430 if (light_entry == -1) return TFailure;
431
432 /* met a jour la light */
433 wks[wks_entry].lights[light_entry].LightID = LightID;
434 wks[wks_entry].lights[light_entry].light = *light;
435
436#if DEBUG
437 printf("ajout ok\n");
438#endif
439 return TSuccess;
440}
441
442
443/*-----------------------------------------------------------------*/
444/*
445* Maj des lumieres de la Wks
446*/
447TStatus UpdateLight(Tint WksID)
448{
449 int wks_entry;
450 int i;
451 int gl_lid;
452
453
454#if DEBUG
455 printf("UpdateLight %d\n", WksID);
456#endif
457
458 /* vire toutes les lights des le depart avant une re-init complete */
459 for (i=GL_LIGHT0; i<=GL_LIGHT7; i++)
460 glDisable(i);
461 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
462
463 /* recherche la liste de light de la wks */
464 wks_entry = find_wks(WksID, 0);
465 if (wks_entry == -1) return TFailure;
466
467#if DEBUG
468 printf("*** Update: nb = %d\n", wks[wks_entry].lights_count);
469#endif
470
471 /* set les lights */
472 gl_lid = GL_LIGHT0;
473 for (i=0; i<wks[wks_entry].lights_count; i++)
474 {
475#if DEBUG
476 printf("binding light %d\n", i);
477#endif
478 bind_light(&wks[wks_entry].lights[i].light, &gl_lid);
479 }
480
481 if (wks[wks_entry].lights_count > 0) LightOn();
482
483#if DEBUG
484 printf("update ok\n");
485#endif
486
487 return TSuccess;
488}
489
490
491/*-----------------------------------------------------------------*/
492/*
493* Remove une lumiere de la Wks
494*/
495TStatus RemoveLight(Tint WksID, Tint LightID)
496{
497 int wks_entry;
498 int light_entry;
499
500
501 /* recherche de la wks */
502 wks_entry = find_wks(WksID, 0);
503 if (wks_entry == -1) return TFailure;
504
505 /* recherche de la light */
506 light_entry = find_light(wks_entry, LightID, 0);
507 if (light_entry == -1) return TFailure;
508
509 /* retire la light */
510 memcpy(&wks[wks_entry].lights[light_entry],
511 &wks[wks_entry].lights[light_entry+1],
512 (wks[wks_entry].lights_count - light_entry - 1)*sizeof(TEL_LIGHT_DATA));
513 wks[wks_entry].lights_count--;
514
515#if DEBUG
516 printf("RemoveLight %d dans wks %d [wds_count=%d]\n", LightID, WksID, wks_count);
517#endif
518
519 return TSuccess;
520}
521
522
523/*-----------------------------------------------------------------*/
524/*
525* Remove des lumieres de la Wks
526*/
527TStatus RemoveWksLight(Tint WksID)
528{
529 int wks_entry;
530
531 /* recherche de la wks */
532 wks_entry = find_wks(WksID, 0);
533 if (wks_entry == -1) return TFailure;
534
535 /* destruction de toute la wks */
536 free(wks[wks_entry].lights);
537 memcpy(&wks[wks_entry],
538 &wks[wks_entry+1],
539 (wks_count - wks_entry - 1)*sizeof(TEL_LIGHT_WKS));
540 wks_count--;
541
542 return TSuccess;
543}
544
545
546/*-----------------------------------------------------------------*/
547/*
548* Reset de toutes les lights d'une Wks
549*/
550TStatus ResetWksLight(Tint WksID)
551{
552 int wks_entry;
553
554 /* recherche de la wks */
555 wks_entry = find_wks(WksID, 0);
556 if (wks_entry == -1) return TFailure;
557
558 /* destruction de toutes les lights */
559 wks[wks_entry].lights_count = 0;
560
561 return TSuccess;
562}
563
564
565/*-----------------------------------------------------------------*/
566/*
567* Enable des lights
568*/
569void LightOn(void)
570{
571#ifdef PRINT_DEBUG
572 if(IsLightOn())
573 printf("LightOn(): lighting already enabled!");
574 else
575 printf("LightOn() succeeded");
576#endif
577 glEnable(GL_LIGHTING);
578}
579
580
581/*-----------------------------------------------------------------*/
582/*
583* Disable des lights
584*/
585void LightOff(void)
586{
587#ifdef PRINT_DEBUG
588 if(!IsLightOn())
589 printf("LightOff(): lighting already disabled!");
590 else
591 printf("LightOff() succeeded");
592#endif
593 glDisable(GL_LIGHTING);
594}
595/*-----------------------------------------------------------------*/
596
597/*
598* IsEnable des lights
599*/
600
601GLboolean IsLightOn(void)
602{
603 return glIsEnabled(GL_LIGHTING);
604}
605/*-----------------------------------------------------------------*/