0012121: Optimization of existing selection classes
[occt.git] / src / OpenGl / OpenGl_view.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_view :
6
7
8 REMARQUES:
9 ---------- 
10
11 An implementation of the PHIGS viewing pipeline
12
13 This module provides services for setting view representations and view
14 indices, viewport management, coordinate conversion routines and help
15 functions.
16
17 The corresponding header file is telem_view.h
18
19
20 HISTORIQUE DES MODIFICATIONS   :
21 --------------------------------
22 xx-xx-xx : xxx ; Creation.
23 11-03-96 : FMN ; Correction warning compilation
24 20-03-96 : CAL ; Modif de TelClearViews
25 appel a call_tox_getscreen pour effacer tout
26 meme apres un resize
27 01-04-96 : CAL ; Integration MINSK portage WNT
28 22-04-96 : FMN ; Suppression prototype inutile.
29 25-06-96 : FMN ; Suppression utilisation de glScissor.
30 28-06-96 : CAL ; Simplification de TelClearViews
31 02-07-96 : FMN ; Suppression WSWSHeight et WSWSWidth
32 Suppression de TelSetWSWindow
33 Suppression glViewport inutile
34 03-07-96 : FMN ; A une workstation correspond une vue.
35 12-07-96 : FMN ; Correction calcul matrice orientatione.
36 17-07-96 : FMN ; Ajout clear pour le zbuffer.
37 21-10-96 : FMN ; Suppression LMC_COLOR fait dans OpenGl_execstruct.c
38 24-01-97 : CAL ; Suppression code inutile (DEBUG_ONLY)
39 30-06-97 : FMN ; Suppression OpenGl_telem_light.h
40 27-08-97 : FMN ; Ajout glDepthMask avant le clear (PRO8939) 
41 09-12-97 : FMN ; Prise en compte environnement mapping. 
42 03-03-98 : FMN ; Suppression variable externe TglWhetherPerspective 
43 13-03-98 : FMN ; Suppression variable WSNeedsClear
44 10-04-98 : CAL ; Suppression du calcul de inverse_matrix
45 30-04-98 : FMN ; Suppression variable externe TglUpdateView0
46 24-11-98 : FMN ; PRO16215: Suppression test sur le GL_MAX_CLIP_PLANES 
47 Si OpenGL n'a pas de plans de clipping on ne le simule pas.
48 24-11-98 : FMN ; Correction sur la gestion de la perspective (cf Programming Guide)
49 - Suppression du test (prp between front and back planes)
50 - Suppression matrice perspective (modify the next two cells to change clipping policy)
51 Ces modifs sont necessaires pour pouvoir mettre le prp entre le Front et Back plane
52
53 ************************************************************************/
54
55 #define BUC60920        /* GG 010601
56 Change the z buffer comparaison for minimizing
57 unavailable or unviewable drawing of pixels in the same plane
58 */
59
60 #define BUC61044       /* 25/10/01 SAV ; added functionality to control gl depth testing
61 from higher API */
62
63 #define OCC1188         /* SAV 23/12/02 TelClearBackground() draws background texture
64 if any was defined
65 */
66
67
68 /*----------------------------------------------------------------------*/
69 /*
70 * Includes
71 */ 
72
73 #include <OpenGl_tgl_all.hxx>
74
75 #include <stddef.h>
76 #include <stdio.h>
77 #include <string.h>
78 #include <stdlib.h>
79
80 #include <OpenGl_cmn_varargs.hxx>
81 #include <OpenGl_telem.hxx>
82 #include <OpenGl_telem_util.hxx>
83 #include <OpenGl_telem_attri.hxx>
84 #include <OpenGl_telem_view.hxx>
85 #include <OpenGl_tsm.hxx>
86 #include <OpenGl_tsm_ws.hxx>
87 #include <OpenGl_txgl.hxx>
88 #include <OpenGl_Memory.hxx>
89 #include <Standard_TypeDef.hxx>
90 #include <OpenGl_PrinterContext.hxx>
91
92 /*----------------------------------------------------------------------*/
93 /*
94 * Variable globales
95 */
96
97 EXPORT extern GLboolean env_walkthrow; /* definit dans OpenGl_togl_begin.c */
98 /* OCC18942: The new perspective projection matrix is off by default */
99 EXPORT extern GLboolean env_sym_perspective; /* defined in OpenGl_togl_begin.c */
100
101 /*----------------------------------------------------------------------*/
102 /*
103 * Constantes
104 */ 
105
106 #define NO_TRACE_MAT    
107 #define NO_TRACE_MATRIX 
108 #define NO_PRINT
109
110 #define ENVTEX
111
112
113 /*----------------------------------------------------------------------*/
114 /*
115 * Prototypes
116 */
117
118 #ifdef DEB
119 static void pr_matrix( Tmatrix3 );
120 #endif
121
122
123 /*----------------------------------------------------------------------*/
124 /*
125 * Type definitions
126 */
127
128 struct TEL_VIEW_DATA
129 {
130   TEL_VIEW_REP    vrep;
131 #ifdef CAL_100498
132   Tmatrix3        inverse_matrix;/* accelerates UVN2XYZ conversion */
133 #endif
134   IMPLEMENT_MEMORY_OPERATORS
135 };
136 typedef TEL_VIEW_DATA *tel_view_data;   /* Internal data stored for every view rep */
137
138 /*----------------------------------------------------------------------*/
139 /*
140 * Variables statiques
141 */
142
143 static void set_clipplanes( tel_view_rep );      /* front & back clip planes */
144 static void set_userclipplanes( tel_view_rep );  /* user-defined clipping planes */
145
146 #ifdef CAL_100498
147 static  void  TelEvalInverseMatrix( Tfloat*, Tfloat*, Tfloat*, /*vrp,vpn,vup*/
148                                     Tfloat, Tmatrix3 );        /*vpd,inverse*/
149 #endif
150 static  Tmatrix3  ident = {
151   { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
152   { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
153   { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
154   { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 }
155 };
156
157 /*----------------------------------------------------------------------*/
158 /*+
159 Qsearch number comparison routine
160
161 Compares view ids during sorting of the list of defined views
162 for a workstation
163 +*/
164
165 /*----------------------------------------------------------------------*/
166 /*+
167 Evaluate View Mapping Matrix
168
169 This routine computes the mapping matrix based on the Window and Viewport
170 limits, Projection type and View plane, Front plane and Back plane
171 distances.
172 +*/
173
174 static  void
175 EvalViewMappingMatrix( tel_view_mapping mapping /* View Mapping */,
176                        Tint *error_ind          /* Out: Error Indicator */,
177                        Tmatrix3 mat             /* Out: Mapping Matrix * */,
178                        Tint     flag,
179                        Tfloat   cx,
180                        Tfloat   cy,
181                        Tint     clip_flag,
182                        Tlimit3  *clip_limit
183                       )
184 {
185   Tfloat    gx, gy, xsf, ysf, zsf;
186   Tfloat    fpd, bpd;
187
188   /* OCC18942 */
189   Tfloat    n, f, r, l, t, b, Zprp, dx, dy, VPD;
190
191   /* FSXXX */
192   /* GLint gdtmp; */
193   Tlimit3   vp = { ( float )-1.0, ( float )1.0, ( float )-1.0, ( float )1.0, ( float )1.0, ( float )-1.0 };
194   Tmatrix3  pmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
195   { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
196   { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
197   { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
198   Tmatrix3  mmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
199   { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
200   { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
201   { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
202
203   fpd = mapping->fpd;
204   bpd = mapping->bpd;
205
206   /* invalid window */
207   if( mapping->window.xmin >= mapping->window.xmax ||
208     mapping->window.ymin >= mapping->window.ymax )
209   {
210     *error_ind = 1;    
211     return;
212   }
213
214   /* invalid viewport */
215   if( mapping->viewport.xmin >= mapping->viewport.xmax ||
216     mapping->viewport.ymin >= mapping->viewport.ymax ||
217     mapping->viewport.zmin >= mapping->viewport.zmax )
218   {
219     *error_ind = 2;   
220     return;
221   }
222
223   /* invalid back/front plane distances */
224   if( mapping->bpd >= mapping->fpd )
225   {
226     *error_ind = 3;   
227     return;
228   }
229
230   /* prp between front and back planes */
231   if (!env_walkthrow)
232   {
233     if( mapping->prp[2] < mapping->fpd &&
234       mapping->prp[2] > mapping->bpd )
235     {
236       *error_ind = 4;   
237       return;
238     } 
239   }
240
241   if( mapping->prp[2] == mapping->vpd )
242   {
243     *error_ind = 5;   /* prp on view plane */
244     return;
245   }
246
247   if( mapping->viewport.xmin < 0 ||
248     mapping->viewport.xmax > 1 ||
249     mapping->viewport.ymin < 0 ||
250     mapping->viewport.ymax > 1 ||
251     mapping->viewport.zmin < 0 ||
252     mapping->viewport.zmax > 1 )
253   {
254     *error_ind = 6;   /* viewport limits outside NPC space */
255     return;
256   }
257
258   *error_ind = 0;
259
260   /* OCC18942: Moved here while debugging perspective projection matrix */
261   /* centers */
262   if( flag == 0 )
263   {
264     cx = mapping->window.xmin + mapping->window.xmax, cx /= ( float )2.0;
265     cy = mapping->window.ymin + mapping->window.ymax, cy /= ( float )2.0;
266   }
267
268   gx = (cx - mapping->prp[0]) / (mapping->vpd - mapping->prp[2]);
269   gy = (cy - mapping->prp[1]) / (mapping->vpd - mapping->prp[2]);
270
271 #ifdef PRINT
272   printf("EvalViewMappingMatrix \n");
273   printf("prp %f %f %f \n", mapping->prp[0], mapping->prp[1], mapping->prp[2]);
274   printf("vpd fpd bpd %f %f %f \n", mapping->vpd, mapping->fpd, mapping->bpd);
275   printf("window limit %f %f %f %f\n", mapping->window.xmin, mapping->window.xmax, 
276     mapping->window.ymin, mapping->window.ymax);
277   printf("viewport limit %f %f %f %f\n", mapping->viewport.xmin, mapping->viewport.xmax, 
278     mapping->viewport.ymin, mapping->viewport.ymax);
279 #endif
280
281   /* projection matrix */
282   if( mapping->proj == TelParallel )
283   {
284
285     pmat[2][0] = -gx; pmat[3][0] = mapping->vpd*gx;
286     pmat[2][1] = -gy; pmat[3][1] = mapping->vpd*gy;
287   }
288   else if ( !env_sym_perspective )/* TelPerspective */
289   {
290     pmat[0][0] = pmat[1][1] = mapping->prp[2] - mapping->vpd;
291     pmat[2][0] = -gx; 
292     pmat[2][1] = -gy; 
293     pmat[2][3] = ( float )-1.0;
294     pmat[3][0] = mapping->vpd * gx; 
295     pmat[3][1] = mapping->vpd * gy; 
296     pmat[3][3] = mapping->prp[2];
297
298     /* modify the next two cells to change clipping policy */
299     if (!env_walkthrow)
300     {
301       pmat[2][2] = mapping->prp[2] - ( fpd + bpd );
302       pmat[3][2] = fpd * bpd; 
303     }
304   }
305   /* OCC18942: New approach to calculation of mapping (projection) matrix */
306   else 
307   {
308     dx = mapping->window.xmax - mapping->window.xmin;
309     dy = mapping->window.ymax - mapping->window.ymin;
310     Zprp = mapping->prp[2];
311     VPD = Zprp - mapping->vpd;
312
313     /* 
314     Calculate canonical perspective projection parameters as if we were about 
315     to use glFrustum() to create symmetric perspective frustum.
316
317     After the view orientation matrix is applied, the coordinate system origin is located 
318     at the VRP and oriented properly. However, the viewplane has width = dx and height = dy 
319     and its center (cx, cy, VPD) is not always located at the view Z axis.
320     The canonical perspective projection matrix assumes the eye is located at (0, 0, 0).
321     Thus the old approach resulted in a non-symmetric perspective, 
322     as X and Y coordinates of the projection reference point (PRP) were not updated
323     when cx and cy changed. Moreover, such "static" perspective had some other disadvantages,
324     such as non-realistic panning, i.e. instead of moving the eye (or camera) over the model
325     a sort of "frame" moved over the static perspective projection picture, 
326     exposing a part of this static picture to the user.
327
328     In order to make the perspective symmetric, we need to translate 
329     the coordinate system to PRP before projection.
330     Thus we translate X, Y and Z co-ordinates by -cx, -cy and -Zprp respectively.
331
332     NOTE: mat[i][j] means j-th element of i-th column, as OpenGL accepts the matrices
333     in column-major order, while in C two-dimensional arrays are stored in memory
334     in row-major order!
335
336     VPD is used below instead of near clipping plane dispance (n) in order to simplify 
337     calculation of l and r values. If we did not use VPD in the matrix calculation, we would have to 
338     project 0.5 * dx, -0.5 * dx, 0.5 * dy and - 0.5 * dy onto the near clipping plane 
339     to calculate these values.
340
341     Pending issues:
342     1. It is still necessary to find a way to calculate the perspective projection matrix 
343     for TPM_WALKTHROUGH projection model. This projection model is not supported yet 
344     by the new code.
345     */
346     r = .5f * dx;
347     l = -r;
348     t = .5f * dy;
349     b = -t;
350     n = Zprp - fpd; f = Zprp - bpd;
351
352     mat[0][0] = 2.f * VPD / (r - l);
353     mat[1][1] = 2.f * VPD / (t - b);
354     mat[2][0] = (r + l) / (r - l);
355     mat[2][1] = (t + b) / (t - b);
356     mat[2][2] = - (f + n) / (f - n);
357     mat[2][3] = -1.f;
358     /* 
359     The last column takes into account translation along X, Y and Z axis
360     before projecting. This can be considered as a result of right-multiplying the canonical 
361     perspective projection matrix P by a translation matrix T 
362     (it differs form the canonical matrix by the last column only):
363     | 1 0 0  -cx  |
364     | 0 1 0  -cy  |
365     mat = P * T, where T = | 0 0 1 -Zprp |
366     | 0 0 0   1   |
367     */
368     mat[3][0] = -mat[2][0] * Zprp - mat[0][0] * cx;
369     mat[3][1] = -mat[2][1] * Zprp - mat[1][1] * cy;
370     mat[3][2] = -2.f * f * n / (f - n) - mat[2][2] * Zprp;
371     mat[3][3] = Zprp;
372
373 #ifdef PRINT
374     printf("r l t b n f: %f %f %f %f %f %f \n", r,l,t,b,n,f);
375     printf( "mapping_matrix (new code):\n" );
376     pr_matrix(mat);
377 #endif
378
379     /* return here, as further calculations are related to the old approach */
380     return;
381   }
382
383   /* scale factors */
384   xsf = (vp.xmax - vp.xmin) / (mapping->window.xmax - mapping->window.xmin);
385   ysf = (vp.ymax - vp.ymin) / (mapping->window.ymax - mapping->window.ymin);
386   zsf = (vp.zmax - vp.zmin) / (fpd - bpd);
387
388   /* map matrix */
389   mmat[0][0] = xsf, mmat[1][1] = ysf, mmat[2][2] = zsf;
390   mmat[3][0] = vp.xmin - xsf*mapping->window.xmin;
391   mmat[3][1] = vp.ymin - ysf*mapping->window.ymin;
392   mmat[3][2] = vp.zmin - zsf*bpd;
393
394   /* multiply to obtain mapping matrix */
395   TelMultiplymat3( mat, pmat, mmat );
396
397 #ifdef PRINT
398   printf( "mapping_matrix :\n" );
399   pr_matrix(mat);
400 #endif
401 }
402
403 /*----------------------------------------------------------------------*/
404 /*+
405 Set View Representation
406
407 This routine defines a view representation for a workstation.
408
409 The representation of the view is stored in a storage table.
410 An entry is made into the list of defined views for the workstation.
411 If the view id being defined already exists, its representation gets
412 modified, else a new representation is created.
413 An inverse transformation matrix is computed and stored in the internal
414 data for the view to accelerate UVN2XYZ conversions. To be able to compute
415 this matrix, it requires some extra information about the view orientation,
416 view plane distance and viewport limits.
417 +*/
418
419 TStatus
420 TelSetViewRepresentation( Tint  Wsid /* Workstation id*/,
421                           Tint  Vid  /* View id */,
422                           tel_view_rep vrep /* view repesentation */
423                          )
424 {
425   CMN_KEY_DATA    key;
426   tel_view_data   vptr;
427
428   if( Vid == 0 )
429     return TFailure; /* attempt to modify default view */
430
431   /* Mise a jour de l'update_mode */
432   key.ldata = TNotDone;
433   TsmSetWSAttri( Wsid, WSUpdateState, &key );
434
435   TsmGetWSAttri( Wsid, WSViews, &key );
436   vptr = (tel_view_data)(key.pdata) ; /* Obtain defined view data*/
437
438   if( !vptr )  /* no view defined yet */
439   {                 /* allocate */
440     //cmn_memreserve(vptr, 1, 0 );
441     vptr = new TEL_VIEW_DATA();
442     if( !vptr ) return TFailure;
443
444     key.pdata = vptr;
445     TsmSetWSAttri( Wsid, WSViews, &key ); /* Set defined view data*/
446   }
447
448   /* copy view definition to storage table record */
449   /* NOTE: Use the matrices already calculated and stored in vrep */
450   vptr->vrep = *vrep; 
451
452 #ifdef CAL_100498
453   /* compute inverse transformation matrix */
454   TelEvalInverseMatrix( vrep->extra.vrp, vrep->extra.vpn, vrep->extra.vup,
455     vrep->extra.map.vpd, vptr->inverse_matrix );
456 #endif
457 #ifdef TRACE_MAT
458   printf( "\nTelSetViewRepresentation WS : %d, view : %d\n", Wsid, Vid );
459   printf( "orientation_matrix :\n" );
460   pr_matrix( vptr->vrep.orientation_matrix );
461   printf( "mapping_matrix :\n" );
462   pr_matrix( vptr->vrep.mapping_matrix );
463 #endif
464   return  TSuccess;
465 }
466
467
468 /*----------------------------------------------------------------------*/
469 TStatus
470 TelGetViewRepresentation( Tint  Wsid /* Workstation id*/,
471                           Tint  Vid  /* View id */,
472                           tel_view_rep vrep /* view representation */
473                          )
474 {
475   CMN_KEY_DATA    key;
476   tel_view_data   vptr;
477
478   if( Vid == 0 )
479   {
480     matcpy( vrep->orientation_matrix, ident );
481     matcpy( vrep->mapping_matrix, ident );
482     vrep->clip_limit.xmin = vrep->clip_limit.ymin = 
483       vrep->clip_limit.zmin = ( float )0.0;
484     vrep->clip_limit.xmax = vrep->clip_limit.ymax =
485       vrep->clip_limit.zmax = ( float )1.0;
486     vrep->clip_xy = TOff;
487     vrep->clip_back = vrep->clip_front = TOn;
488     vrep->shield_indicator = TOn;
489     vrep->shield_colour.rgb[0] = vrep->shield_colour.rgb[1] =
490       vrep->shield_colour.rgb[2] = ( float )0.0;
491     vrep->border_indicator = TOff; /* non utilise */
492     vrep->border_colour.rgb[0] = vrep->border_colour.rgb[1] =
493       vrep->border_colour.rgb[2] = ( float )0.0;
494     vrep->active_status = TOn;
495     vrep->extra.vrp[0] = vrep->extra.vrp[1] = vrep->extra.vrp[2] = ( float )0.0;
496     vrep->extra.vpn[0] = ( float )0.0,
497       vrep->extra.vpn[1] = ( float )0.0,
498       vrep->extra.vpn[2] = ( float )1.0;
499     vrep->extra.vup[0] = ( float )0.0,
500       vrep->extra.vup[1] = ( float )1.0,
501       vrep->extra.vup[2] = ( float )0.0;
502     vrep->extra.map.vpd = ( float )0.0,
503       vrep->extra.map.fpd = ( float )0.0,
504       vrep->extra.map.bpd = ( float )-1.0;
505     vrep->extra.map.window.xmin = vrep->extra.map.window.ymin = ( float )0.0;
506     vrep->extra.map.window.xmax = vrep->extra.map.window.ymax = ( float )1.0;
507     vrep->extra.map.viewport.xmin = vrep->extra.map.viewport.ymin =
508       vrep->extra.map.viewport.zmin = ( float )0.0;
509     vrep->extra.map.viewport.xmax = vrep->extra.map.viewport.ymax =
510       vrep->extra.map.viewport.zmax = ( float )1.0;
511     vrep->clipping_planes.Clear();
512     return TSuccess;
513   }
514
515   if(TsmGetWSAttri( Wsid, WSViews, &key ) != TSuccess) {
516     return TFailure;
517   }
518   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
519   if( !vptr ) return TFailure; /* no view defined yet */ 
520   *vrep = vptr->vrep; /* copy view definition */
521
522   return  TSuccess;
523 }
524
525 /*----------------------------------------------------------------------*/
526 /*+
527 Evaluate View Orientation Matrix
528
529 This routine computes the orientation matrix based on the View Reference
530 Point, View Plane Normal and the View Up Vector.
531 +*/
532
533 void
534 TelEvalViewOrientationMatrix( Tfloat *vrp    /* View Reference Point */,
535                               Tfloat *vpn    /* View Plane Normal */,
536                               Tfloat *vup    /* View Up Vector */,
537                               Tfloat *asf    /* Axial Scale Factors */,
538                               Tint *error_ind/* Out: Error indicator */,
539                               Tmatrix3  rmat  /* Out: Orientation Matrix  */
540                              )
541 {
542   Tfloat  u[3], v[3], n[3], f;
543
544   /* view plane normal of zero length */
545   if( vecmag(vpn) == 0.0 )
546   {
547     *error_ind = 1;   
548     return;
549   }
550
551   /* view up vector of zero length */
552   if( vecmag(vup) == 0.0 )
553   {
554     *error_ind = 2;    
555     return;
556   }
557
558   /* view up vector parallel to view plane normal */
559   vecang(vup, vpn, f);
560   if( f == 0.0 )
561   {
562     *error_ind = 3;    
563     return;
564   }
565
566   *error_ind = 0;
567
568   veccpy(n, vpn);
569   veccpy(v, vup);
570   vecnrm(n);  
571
572   veccrs(u,v,n);      /* up vector cross plane normal gives U axis */
573   vecnrm(u);
574
575   veccrs(v,n,u);      /* plane normal cross U axis gives modified up vector */
576   vecnrm(v); /* redundant ? */
577
578   /* rotate to align along u, v, n */
579   rmat[0][0] = ( float )u[0] * asf[0],
580     rmat[0][1] = ( float )v[0] * asf[0],
581     rmat[0][2] = ( float )n[0] * asf[0],
582     rmat[0][3] = ( float )0.0;
583
584   rmat[1][0] = ( float )u[1] * asf[1],
585     rmat[1][1] = ( float )v[1] * asf[1],
586     rmat[1][2] = ( float )n[1] * asf[1],
587     rmat[1][3] = ( float )0.0;
588
589   rmat[2][0] = ( float )u[2] * asf[2],
590     rmat[2][1] = ( float )v[2] * asf[2],
591     rmat[2][2] = ( float )n[2] * asf[2],
592     rmat[2][3] = ( float )0.0;
593
594   /* translate to centre at vrp */
595
596   rmat[3][0] = - ( float ) (u[0]*vrp[0] + u[1]*vrp[1] + u[2]*vrp[2]);
597   rmat[3][1] = - ( float ) (v[0]*vrp[0] + v[1]*vrp[1] + v[2]*vrp[2]);
598   rmat[3][2] = - ( float ) (n[0]*vrp[0] + n[1]*vrp[1] + n[2]*vrp[2]);
599   rmat[3][3] = ( float )1.0;
600
601 #ifdef PRINT
602   printf("TelEvalViewOrientationMatrix \n");
603   printf("view_ref_pt %f %f %f \n", vrp[0], vrp[1], vrp[2]);
604   printf("view_up_vec %f %f %f \n", vup[0], vup[1], vup[2]);
605   printf("view_plane_normal %f %f %f \n", vpn[0], vpn[1], vpn[2]);
606   pr_matrix(rmat);
607 #endif
608
609   return;
610 }
611 /*----------------------------------------------------------------------*/
612
613 void
614 TelEvalViewMappingMatrix( tel_view_mapping mapping /* View Mapping */,
615                           Tint *error_ind          /* Out: Error Indicator */,
616                           Tmatrix3 mat             /* Out: Mapping Matrix */
617                          )
618 {
619   EvalViewMappingMatrix( mapping, error_ind, mat, 0, ( float )0.0, ( float )0.0, 0, 0 );
620 }
621
622 /*----------------------------------------------------------------------*/
623
624 void
625 TelEvalViewMappingMatrixPick( tel_view_mapping mapping /* View Mapping */,
626                               Tint *error_ind          /* Out: Error Indicator */,
627                               Tmatrix3 mat             /* Out: Mapping Matrix */,
628                               Tfloat   cx,
629                               Tfloat   cy
630                              )
631 {
632   EvalViewMappingMatrix( mapping, error_ind, mat, 1, cx, cy, 0, 0 );
633 }
634
635 /*----------------------------------------------------------------------*/
636 /*+
637 Evalute inverse transformation matrix.
638
639 This routine computes a matrix required to convert UVN coordinates to XYZ
640 coordinates. It is called every time a View Representation is created or
641 modified, and the inverse matrix is stored along with the internal data
642 for the view representation.
643 +*/
644
645 #ifdef CAL_100498
646 static  void
647 TelEvalInverseMatrix( Tfloat *vrp    /* View Reference Point */,
648                       Tfloat *vpn    /* View Plane Normal */,
649                       Tfloat *vup    /* View Up Vector */,
650                       Tfloat vpd     /* View Plane Distance */,
651                       Tmatrix3 mat   /* Out: Inverse Transformation Matrix */
652                      )
653 {
654   Tfloat  u[3], v[3], n[3], p[3], t[3];
655   Tfloat  dist = ( float )0.0;
656
657   veccpy(n, vpn);            /* compute UVN orientation */
658   veccpy(v, vup);
659   veccpy(p, vrp);
660
661   veccrs(u,v,n);
662   vecnrm(u);
663
664   veccrs(v,n,u);
665   vecnrm(v);
666
667   dist = vpd;
668   veccpy(t,n);
669   vecscl(dist,t);
670   vecadd(t,t,p);           /* translation vector */
671
672   veccpy(mat[0],u);
673   veccpy(mat[1],v);
674   veccpy(mat[2],n);
675   veccpy(mat[3],t);
676
677   mat[0][3] = mat[1][3] = mat[2][3] = ( float )0.0, mat[3][3] = ( float )1.0;
678
679   return;
680 }
681 #endif
682
683 #ifdef CAL_100498
684 /*----------------------------------------------------------------------*/
685 /*+
686 Convert Coordinates utility routine
687
688 This routine converts coordinates from UVN space to XYZ space and
689 vice versa. For UVN2XYZ, the inverse transformation matrix is used and for
690 XYZ2UVN, the orientation matrix is used.
691 +*/
692
693 TStatus
694 TelConvertCoord( Tint  Wsid        /* Workstation id */,
695                  Tint  Vid         /* View id */,
696                  TelCoordType type /* Conversion type (UVN2XYZ or XYZ2UVN) */,
697                  Tfloat *uvn       /* UVN coords if type is UVN2XYZ else Out */,
698                  Tfloat *xyz       /* XYZ coords if type is XYZ2UVN else Out */
699                 )
700 {
701   CMN_KEY_DATA    key;
702   tel_view_data   vptr;
703   register  Tint  i;
704
705   Tfloat  pt[4], tpt[4];
706
707   if( Vid == 0 )
708   {                            /* default view */
709     switch( type )
710     {
711     case UVN2XYZ:
712       veccpy(xyz,uvn);
713       break;
714     case XYZ2UVN:
715       veccpy(uvn,xyz);
716       break;
717     }
718     return TSuccess;
719   }
720
721   TsmGetWSAttri( Wsid, WSViews, &key );
722   vptr = key.pdata ; /* Obtain defined view data*/
723   if( !vptr ) return TFailure; /* no view defined yet */ 
724
725   switch( type )
726   {
727   case UVN2XYZ:
728     veccpy(pt,uvn);
729     pt[3] = ( float )1.0;
730     TelTranpt3( tpt, pt, vptr->inverse_matrix );
731     veccpy(xyz,tpt);
732     break;
733
734   case XYZ2UVN:
735     veccpy(pt,xyz);
736     pt[3] = ( float )1.0;
737     TelTranpt3( tpt, pt, vptr->vrep.orientation_matrix );
738     veccpy(uvn,tpt);
739     break;
740   }
741
742   return TSuccess;
743 }
744 #endif
745
746 /*----------------------------------------------------------------------*/
747 /*+
748 Print Matrix
749
750 Debug tool
751 +*/
752
753 #ifdef DEB
754 void
755 pr_matrix( Tmatrix3 mat )
756 {
757   printf( "%f %f %f %f\n", mat[0][0], mat[0][1], mat[0][2], mat[0][3] );
758   printf( "%f %f %f %f\n", mat[1][0], mat[1][1], mat[1][2], mat[1][3] );
759   printf( "%f %f %f %f\n", mat[2][0], mat[2][1], mat[2][2], mat[2][3] );
760   printf( "%f %f %f %f\n", mat[3][0], mat[3][1], mat[3][2], mat[3][3] );
761   printf( "\n" );
762   return;
763 }
764 #endif
765
766 /*----------------------------------------------------------------------*/
767 /*+
768 Set View Index
769
770 This routine activates the view representation which has been defined
771 previously.
772 +*/
773
774 TStatus
775 TelSetViewIndex( Tint  Wsid /* Workstation id */,
776                  Tint  Vid  /* View id */ )
777 {
778   CMN_KEY_DATA    key;
779   tel_view_data   vptr;
780
781   if( Vid == 0 )
782   {                    /* default view */
783     GLint mm;
784     glGetIntegerv(GL_MATRIX_MODE, &mm);
785 #ifdef TRACE_MATRIX
786     printf("OpenGl_view.c::TelSetViewIndex::glMatrixMode(GL_PROJECTION) \n"); 
787 #endif
788     glMatrixMode(GL_PROJECTION);
789     glLoadIdentity();
790     glOrtho( -0.5,  0.5,  -0.5,  0.5,  -0.5,  0.5 );
791     glMatrixMode(mm);
792     return TSuccess;
793   }
794
795   TsmGetWSAttri( Wsid, WSViews, &key );
796   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
797   if( !vptr ) return TFailure; /* no view defined yet */ 
798
799  
800 #ifdef TRACE_MATRIX
801   printf("OpenGl_view.c::TelSetViewIndex::glMatrixMode(GL_MODELVIEW) \n"); 
802 #endif
803   if(vptr->vrep.extra.scaleFactors[0] != 1. || 
804     vptr->vrep.extra.scaleFactors[1] != 1. ||
805     vptr->vrep.extra.scaleFactors[2] != 1.)
806     glEnable(GL_NORMALIZE);           /* if the view is scaled normal vectors are scaled to unit length for correct displaying of shaded objects*/
807   else if(glIsEnabled(GL_NORMALIZE))  
808     glDisable(GL_NORMALIZE);
809   glMatrixMode(GL_MODELVIEW);
810   set_clipplanes( &(vptr->vrep) );
811   
812
813   glLoadMatrixf((GLfloat *) vptr->vrep.orientation_matrix );
814   set_userclipplanes( &(vptr->vrep) ); /* set clipping planes defined by user */
815
816 #ifdef ENVTEX
817   /*
818   * Ajout translation necessaire pour l'environnement mapping
819   */
820   {
821     GLfloat dep;  
822
823     TsmGetWSAttri(Wsid, WSSurfaceDetail, &key);
824     /* TOD_ENVIRONMENT ou TOD_ALL */
825     if (key.ldata == 1 || key.ldata == 2)
826     {
827       /*          dep = vptr->vrep.extra.map.fpd * 0.5F; */
828       dep = (vptr->vrep.extra.map.fpd + vptr->vrep.extra.map.bpd) * 0.5F; /* OCC280: FitAll work incorrect for perspective view if the SurfaceDetail mode is V3d_TEX_ENVIRONMENT or V3d_TEX_ALL */
829       glTranslatef(-dep*vptr->vrep.extra.vpn[0],
830         -dep*vptr->vrep.extra.vpn[1],
831         -dep*vptr->vrep.extra.vpn[2]); 
832 #ifdef PRINT
833       printf("glTranslatef: %f %f %f \n", 
834         -dep*vptr->vrep.extra.vpn[0],
835         -dep*vptr->vrep.extra.vpn[1],
836         -dep*vptr->vrep.extra.vpn[2]);
837 #endif
838     }
839   }
840 #endif
841
842 #ifdef TRACE_MATRIX
843   printf("OpenGl_view.c::TelSetViewIndex::glMatrixMode(GL_PROJECTION) \n"); 
844 #endif
845   glMatrixMode(GL_PROJECTION);
846   glLoadIdentity();
847
848 #ifdef WNT
849   // add printing scale/tiling transformation
850   OpenGl_PrinterContext* aPrinterContext = 
851     OpenGl_PrinterContext::GetPrinterContext(GET_GL_CONTEXT());
852
853   if (aPrinterContext)
854   {
855     GLfloat aProjMatrix[16];
856     aPrinterContext->GetProjTransformation(aProjMatrix);
857     glLoadMatrixf((GLfloat*) aProjMatrix);
858   }
859 #endif
860
861   glMultMatrixf((GLfloat *) vptr->vrep.mapping_matrix );
862
863 #ifdef TRACE_MAT
864   printf( "\nTelSetViewIndex WS : %d, view : %d", Wsid, Vid );
865   printf( "orientation_matrix :\n" );
866   pr_matrix( vptr->vrep.orientation_matrix );
867   printf( "mapping_matrix :\n" );
868   pr_matrix( vptr->vrep.mapping_matrix );
869 #endif
870
871   return vptr->vrep.active_status == TOn ? TSuccess : TFailure;
872 }
873
874
875 /*----------------------------------------------------------------------*/
876 /*+
877 Set View Projection
878
879 This routine activates the Projection matrix for a previously defined
880 view representation. It is meant to be used exclusively to restore the
881 Projection transformation at the end of an ExecuteStructure element
882 traversal. The restoration of the Viewing matrix is done by a GL popmatrix
883 call.
884 +*/
885
886 TStatus
887 TelSetViewProjection( Tint  Wsid /* Workstation id */,
888                       Tint  Vid  /* View id */ )
889 {
890   CMN_KEY_DATA    key;
891   tel_view_data   vptr;
892
893   if( Vid == 0 )
894   {                    /* default view */
895     GLint mm;
896     glGetIntegerv(GL_MATRIX_MODE, &mm);
897 #ifdef TRACE_MATRIX
898     printf("OpenGl_view.c::TelSetViewProjection::glMatrixMode(GL_PROJECTION) \n"); 
899 #endif
900     glMatrixMode(GL_PROJECTION);
901     glLoadIdentity();
902     glOrtho( 0,  1,  0,  1,  0,  1 );
903     glMatrixMode(mm);
904
905
906     return TSuccess;
907   }
908
909   TsmGetWSAttri( Wsid, WSViews, &key );
910   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
911   if( !vptr ) return TFailure; /* no view defined yet */ 
912
913   set_clipplanes( &(vptr->vrep) );
914   set_userclipplanes( &(vptr->vrep) );
915
916 #ifdef TRACE_MATRIX
917   printf("OpenGl_view.c::TelSetViewProjection::glMatrixMode(GL_PROJECTION) \n"); 
918 #endif
919   glMatrixMode(GL_PROJECTION);
920   glLoadMatrixf((GLfloat *) vptr->vrep.mapping_matrix );
921  
922   return vptr->vrep.active_status == TOn ? TSuccess : TFailure;
923 }
924
925 /*----------------------------------------------------------------------*/
926 /*+
927 Clear all active views in a workstation
928
929 This routine clears all the viewports, draws the viewport borders and
930 sets the viewport background if the corresponding indicators are on.
931 It also clears view 0 (default view), if the workstation state demands it.
932 +*/
933
934 void
935 TelClearViews( Tint  Wsid /* Workstation id */ )
936 {
937   CMN_KEY_DATA    key;
938   tel_view_data   vptr;
939
940   TelResetMaterial();
941
942   TsmGetWSAttri( Wsid, WSViews, &key );
943   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
944   if( !vptr ) return; /* no view defined yet */ 
945
946   if( vptr->vrep.active_status == TOn )  /* for each active view only */
947   {
948     if( vptr->vrep.shield_indicator == TOn ) TelClearBackground( Wsid );
949   }
950
951   return;
952 }
953
954 /*----------------------------------------------------------------------*/
955 /* Function for printing view information */
956
957 TStatus
958 TelPrintViewRepresentation( Tint  Wsid /* Workstation id*/,
959                             Tint  Vid  /* View id */
960                            )
961 {
962   CMN_KEY_DATA    key;
963   tel_view_data   vptr;
964
965   printf( "\n\tPrint : Workstation %d View %d", Wsid, Vid );
966
967   if( Vid == 0 )
968     return TSuccess;
969
970   TsmGetWSAttri( Wsid, WSViews, &key );
971   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
972   if( !vptr ) return TFailure; /* no view defined yet */ 
973
974   /* Print the information */
975   printf( "\n\tshield indicator : %s",
976     vptr->vrep.shield_indicator == TOn ? "ON" : "OFF" );
977   printf( "\n\tshield_colour r = %f, g = %f, b = %f",
978     vptr->vrep.shield_colour.rgb[0],
979     vptr->vrep.shield_colour.rgb[1],
980     vptr->vrep.shield_colour.rgb[2] );
981   printf( "\n\tactive_status : %s",
982     vptr->vrep.active_status == TOn ? "ON":"OFF");
983   printf( "\n\tVRP : %f %f %f", vptr->vrep.extra.vrp[0],
984     vptr->vrep.extra.vrp[1],
985     vptr->vrep.extra.vrp[2] );
986   printf( "\n\tVPN : %f %f %f", vptr->vrep.extra.vpn[0],
987     vptr->vrep.extra.vpn[1],
988     vptr->vrep.extra.vpn[2] );
989   printf( "\n\tVUP : %f %f %f", vptr->vrep.extra.vup[0],
990     vptr->vrep.extra.vup[1],
991     vptr->vrep.extra.vup[2] );
992   printf( "\n\tPRP : %f %f %f", vptr->vrep.extra.map.prp[0],
993     vptr->vrep.extra.map.prp[1],
994     vptr->vrep.extra.map.prp[2] );
995   printf( "\n\tWindow Limits xmin xmax ymin ymax :\n\t\t%f %f %f %f",
996     vptr->vrep.extra.map.window.xmin,
997     vptr->vrep.extra.map.window.xmax,
998     vptr->vrep.extra.map.window.ymin,
999     vptr->vrep.extra.map.window.ymax );
1000   printf( "\n\tViewport Limits xmin xmax ymin ymax zmin zmax :\n\t\t%f %f %f %f %f %f", vptr->vrep.extra.map.viewport.xmin,
1001     vptr->vrep.extra.map.viewport.xmax,
1002     vptr->vrep.extra.map.viewport.ymin,
1003     vptr->vrep.extra.map.viewport.ymax,
1004     vptr->vrep.extra.map.viewport.zmin,
1005     vptr->vrep.extra.map.viewport.zmax );
1006   printf( "\n\tProjection type : %s",
1007     vptr->vrep.extra.map.proj == TelParallel
1008     ? "PARALLEL" : "PERSPECTIVE" );
1009   printf( "\n\tVPD FPD BPD : %f %f %f\n", vptr->vrep.extra.map.vpd,
1010     vptr->vrep.extra.map.fpd,
1011     vptr->vrep.extra.map.bpd );
1012   return  TSuccess;
1013 }
1014
1015
1016 /*----------------------------------------------------------------------*/
1017
1018 #define FRONT_CLIPPING_PLANE (GL_CLIP_PLANE0 + 0)
1019 #define BACK_CLIPPING_PLANE  (GL_CLIP_PLANE0 + 1)
1020 /*
1021
1022 While drawing after a clipplane has been defined and enabled, each vertex
1023 is transformed to eye-coordinates, where it is dotted with the transformed
1024 clipping plane equation.  Eye-coordinate vertexes whose dot product with
1025 the transformed clipping plane equation is positive or zero are in, and
1026 require no clipping.  Those eye-coordinate vertexes whose dot product is
1027 negative are clipped.  Because clipplane clipping is done in eye-
1028 coordinates, changes to the projection matrix have no effect on its
1029 operation.
1030
1031 A point and a normal are converted to a plane equation in the following
1032 manner:
1033
1034 point = [Px,Py,Pz]
1035
1036 normal = |Nx|
1037 |Ny|
1038 |Nz|
1039
1040 plane equation = |A|
1041 |B|
1042 |C|
1043 |D|
1044 A = Nx
1045 B = Ny
1046 C = Nz
1047 D = -[Px,Py,Pz] dot |Nx|
1048 |Ny|
1049 |Nz|
1050
1051 */
1052
1053 /*----------------------------------------------------------------------*/
1054
1055 static void
1056 set_clipplanes( tel_view_rep vrep )
1057 {
1058   GLdouble arr[4];
1059   Tfloat front, back;
1060   GLfloat mat[4][4];
1061 #ifdef TRACE_MATRIX
1062   printf("OpenGl_view.c::set_clipplanes::glMatrixMode(GL_MODELVIEW) \n"); 
1063 #endif
1064   glMatrixMode( GL_MODELVIEW );
1065   glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
1066   glLoadIdentity();
1067
1068   if( vrep->clip_limit.zmin < 0.0 ||
1069     vrep->clip_limit.zmin > 1.0 ||
1070     vrep->clip_back == TOff )
1071     glDisable( BACK_CLIPPING_PLANE );
1072   else
1073   {
1074     /* cf Opengl_togl_cliplimit */
1075     back = (vrep->extra.map.fpd - vrep->extra.map.bpd) *
1076       vrep->clip_limit.zmin + vrep->extra.map.bpd;
1077     arr[0] = 0.0;  /* Nx */
1078     arr[1] = 0.0;  /* Ny */
1079     arr[2] = 1.0;  /* Nz */
1080     arr[3] = -( (GLdouble) (back) * arr[2] ); /* P dot N */
1081     glClipPlane( BACK_CLIPPING_PLANE, arr );
1082     glEnable( BACK_CLIPPING_PLANE );
1083   }
1084
1085   if( vrep->clip_limit.zmax < 0.0 ||
1086     vrep->clip_limit.zmax > 1.0 ||
1087     vrep->clip_front == TOff )
1088     glDisable( FRONT_CLIPPING_PLANE );
1089   else
1090   {
1091     /* cf Opengl_togl_cliplimit */
1092     front = (vrep->extra.map.fpd - vrep->extra.map.bpd) *
1093       vrep->clip_limit.zmax + vrep->extra.map.bpd;
1094     arr[0] = 0.0;  /* Nx */
1095     arr[1] = 0.0;  /* Ny */
1096     arr[2] = -1.0; /* Nz */
1097     arr[3] = -( (GLdouble) (front) * arr[2] ); /* P dot N */
1098     glClipPlane( FRONT_CLIPPING_PLANE, arr );
1099     glEnable( FRONT_CLIPPING_PLANE );
1100   }
1101
1102   glLoadMatrixf( (GLfloat *) mat );
1103 }
1104
1105 static void
1106 set_userclipplanes( tel_view_rep vrep )
1107 {
1108   int j,planeid;
1109   CALL_DEF_PLANE* plane;
1110
1111 #ifdef TRACE_MATRIX
1112   printf("OpenGl_view.c::set_userclipplanes::glMatrixMode(GL_MODELVIEW) \n"); 
1113 #endif
1114
1115   
1116   NCollection_List<CALL_DEF_PLANE>::Iterator planeIter(vrep->clipping_planes);
1117   
1118   // go through all of planes in the list & preview them
1119   for( j=0 ; planeIter.More(); planeIter.Next(), j++ ) 
1120   {
1121     plane = const_cast<CALL_DEF_PLANE*>(&planeIter.Value());
1122     
1123     if( plane->PlaneId > 0 ) 
1124     {
1125       planeid = GL_CLIP_PLANE2 + j;
1126
1127       if( plane->Active ) 
1128       {
1129           // Activates new clip planes
1130           GLdouble equation[4];
1131           equation[0] = plane->CoefA;
1132           equation[1] = plane->CoefB;
1133           equation[2] = plane->CoefC;
1134           equation[3] = plane->CoefD;
1135           
1136           glClipPlane( planeid , equation );     
1137           if( !glIsEnabled( planeid ) ) glEnable( planeid );     
1138       } 
1139       else 
1140       {
1141         if( glIsEnabled( planeid ) ) glDisable( planeid );     
1142       }
1143     }
1144   }   //for( ; planeIter.More(); planeIter.Next() ) 
1145
1146   // Disable the remainder Clip planes
1147
1148   for( j=vrep->clipping_planes.Size(); j < call_facilities_list.MaxPlanes; j++ )
1149   {
1150     planeid = GL_CLIP_PLANE2 + j; 
1151
1152     if( glIsEnabled( planeid ) ) 
1153       glDisable( planeid );
1154    }
1155
1156   
1157 }
1158
1159 /*----------------------------------------------------------------------*/
1160
1161 TStatus
1162 Tel2Dto3D( Tint ws, Tint vid, Tint x, Tint y,
1163           Tfloat *x1, Tfloat *y1, Tfloat *z1,
1164           Tfloat *x2, Tfloat *y2, Tfloat *z2 )
1165           /* x is from bottom */
1166           /* y is from top */
1167 {
1168   CMN_KEY_DATA key;
1169   TEL_VIEW_REP vrep;
1170   Tint         w, h;
1171   GLint        viewp[4];
1172   GLdouble xx1, yy1, zz1, xx2, yy2, zz2;
1173
1174   TsmGetWSAttri( ws, WSWidth, &key );
1175   w = key.ldata;
1176   TsmGetWSAttri( ws, WSHeight, &key );
1177   h = key.ldata;
1178   y = key.ldata - y;
1179
1180   /* FSXXX */
1181   printf("WARNING: Tel2Dto3D non verifie\n");
1182
1183   TelGetViewRepresentation( ws, vid, &vrep );
1184
1185   viewp[0] = 0;     viewp[2] = w;
1186   viewp[1] = 0;     viewp[3] = h;
1187
1188
1189   /* OGLXXX XXX I think this is backwards */
1190   gluProject((GLdouble) x, (GLdouble) y, 0.0,
1191     (GLdouble *) vrep.orientation_matrix,
1192     (GLdouble *) vrep.mapping_matrix,
1193     viewp, &xx1, &yy1, &zz1);
1194   gluProject((GLdouble) x, (GLdouble) y, 1.0,
1195     (GLdouble *) vrep.orientation_matrix,
1196     (GLdouble *) vrep.mapping_matrix,
1197     viewp, &xx2, &yy2, &zz2);
1198
1199   *x1 = (float) xx1; *y1 =  (float) yy1; *z1 =  (float) zz1;
1200   *x2 = (float) xx2; *y2 =  (float) yy2; *z2 =  (float) zz2;
1201
1202   return TSuccess;
1203
1204 }
1205
1206 /*----------------------------------------------------------------------*/
1207
1208 TStatus
1209 TelDeleteViewsForWS( Tint wsid )
1210 {
1211   CMN_KEY_DATA key;
1212   tel_view_data vptr;
1213
1214   TsmGetWSAttri( wsid, WSViews, &key );
1215   vptr = (tel_view_data)key.pdata ; /* Obtain defined view data*/
1216
1217   if( !vptr ) return TSuccess;
1218   delete vptr;
1219
1220   return TSuccess;
1221 }
1222
1223 /*----------------------------------------------------------------------*/
1224
1225 void
1226 TelClearBackground( Tint  Wsid /* Workstation id */ )
1227 {
1228   CMN_KEY_DATA key;
1229   Tfloat *rgb;
1230   Tint   zbuffer;
1231 #ifdef BUC61044
1232   Tint   dTest;
1233 #endif
1234 #ifdef OCC1188
1235   tsm_bg_texture texture;
1236 #endif  
1237   tsm_bg_gradient gradient;
1238
1239
1240   TsmGetWSAttri (Wsid, WSBackground, &key);
1241   rgb = (Tfloat *)key.pdata;
1242
1243 #ifdef OCC1188
1244   TsmGetWSAttri (Wsid, WSBgTexture, &key);
1245   texture = (tsm_bg_texture)key.pdata;
1246 #endif
1247   TsmGetWSAttri (Wsid, WSZbuffer, &key);
1248   zbuffer = key.ldata;
1249
1250   TsmGetWSAttri (Wsid, WSBgGradient, &key);
1251   gradient = (tsm_bg_gradient)key.pdata;
1252   
1253   /* GL_DITHER on/off pour le background */
1254   if (TxglGetBackDither ())
1255     glEnable (GL_DITHER);
1256   else
1257     glDisable (GL_DITHER);
1258
1259   if (zbuffer)
1260   {
1261 #ifdef BUC60920 
1262     glDepthFunc(GL_LEQUAL);
1263 #else
1264     glDepthFunc(GL_LESS);
1265 #endif
1266     glDepthMask(GL_TRUE);
1267
1268 #ifdef BUC61044
1269     /* getting depth testing flag */
1270     TsmGetWSAttri( Wsid, WSDepthTest, &key );
1271     dTest = key.ldata;
1272     /* SAV checking if depth test was depricated somewhere outside */
1273     if ( dTest == TOn ) 
1274       glEnable(GL_DEPTH_TEST);
1275     else
1276       glDisable(GL_DEPTH_TEST);
1277 #else
1278     glEnable(GL_DEPTH_TEST);
1279 #endif
1280
1281     glClearDepth(1.0);
1282     glClearColor (rgb[0], rgb[1], rgb[2], ( float )0.0);
1283     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     
1284   }
1285   else
1286   {
1287     glDisable(GL_DEPTH_TEST);
1288     glClearColor (rgb[0], rgb[1], rgb[2], ( float )0.0);
1289     glClear (GL_COLOR_BUFFER_BIT);
1290   }
1291 #ifdef OCC1188
1292   glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
1293   /* drawing bg image if any */
1294   if ( texture->texId != 0 ) {
1295     GLint width, height; /* window dimensions*/
1296     GLfloat x_center, y_center; /* window center */
1297     GLfloat x_offset, y_offset; /* half of the texture size */
1298     GLfloat texX_range = 1.0;
1299     /* texture <s> coordinate */
1300     GLfloat texY_range = 1.0; /* texture <t> coordinate */
1301
1302     TsmGetWSAttri( Wsid, WSWidth, &key );
1303     width = key.ldata;
1304     x_center = (GLfloat)( width / 2. );
1305     TsmGetWSAttri( Wsid, WSHeight, &key );
1306     height = key.ldata;
1307     y_center = (GLfloat)( height / 2. );
1308
1309     x_offset = (GLfloat)( texture->width / 2. ); /* style = center */
1310     y_offset = (GLfloat)( texture->height / 2. ); /* style = center */
1311     if ( texture->style != 0 ) { /* stretch or tile */
1312       x_offset = x_center;
1313       y_offset = y_center;
1314       if ( texture->style == 1 ) { /* tile */
1315         texX_range = (float)( width / texture->width );
1316         if ( texX_range < 1.0 )
1317           texX_range = 1.0;
1318         texY_range = (float)( height / texture->height );
1319         if ( texY_range < 1.0 )
1320           texY_range = 1.0;
1321       }
1322     }
1323     /* drawing background texture */
1324     glMatrixMode( GL_PROJECTION );
1325     glPushMatrix();
1326     glLoadIdentity();
1327     gluOrtho2D( 0.0, (GLdouble)width, 0.0, (GLdouble)height );
1328     glMatrixMode( GL_MODELVIEW );
1329     glPushMatrix();
1330     glLoadIdentity();
1331     glEnable( GL_TEXTURE_2D );
1332     glBindTexture( GL_TEXTURE_2D, texture->texId );
1333     glDisable( GL_DEPTH_TEST );
1334
1335     glDisable( GL_BLEND );
1336     glColor3f( rgb[0], rgb[1], rgb[2] );
1337     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1338     glBegin( GL_QUADS );
1339     glTexCoord2f(0.0f, 0.0f);glVertex2f( x_center - x_offset, y_center - y_offset );
1340     glTexCoord2f(texX_range, 0.0f);glVertex2f( x_center + x_offset, y_center - y_offset );
1341     glTexCoord2f(texX_range, texY_range);glVertex2f( x_center + x_offset, y_center + y_offset );
1342     glTexCoord2f(0.0f, texY_range);glVertex2f( x_center - x_offset, y_center + y_offset );
1343     glEnd();
1344     if ( zbuffer )
1345       glEnable( GL_DEPTH_TEST );
1346     glDisable( GL_TEXTURE_2D );
1347     glPopMatrix(); /*modelview*/
1348     glMatrixMode( GL_PROJECTION );
1349     glPopMatrix(); /*projection*/
1350     glMatrixMode( GL_MODELVIEW );
1351   }  
1352   else if( gradient->type > 0 )
1353   {
1354
1355     Tfloat* corner1 = 0;/* -1,-1*/
1356     Tfloat* corner2 = 0;/*  1,-1*/
1357     Tfloat* corner3 = 0;/*  1, 1*/
1358     Tfloat* corner4 = 0;/* -1, 1*/
1359     Tfloat* dcorner1 = (Tfloat*)malloc(3*sizeof(Tfloat));
1360     Tfloat* dcorner2 = (Tfloat*)malloc(3*sizeof(Tfloat));
1361
1362     int upset[3] = {0} ;
1363
1364     switch( gradient->type )
1365     {
1366       case 1:
1367        corner1 = gradient->color2.rgb;
1368        corner2 = gradient->color2.rgb;
1369        corner3 = gradient->color1.rgb;
1370        corner4 = gradient->color1.rgb;
1371        break;
1372       case 2:    
1373        corner1 = gradient->color2.rgb;
1374        corner2 = gradient->color1.rgb;
1375        corner3 = gradient->color1.rgb;
1376        corner4 = gradient->color2.rgb;
1377        break;
1378       case 3:
1379        corner2 = gradient->color2.rgb;
1380        corner4 = gradient->color1.rgb;        
1381        dcorner1 [0] = dcorner2[0] = (corner2[0] + corner4[0]) / 2.0;
1382        dcorner1 [1] = dcorner2[1] = (corner2[1] + corner4[1]) / 2.0;
1383        dcorner1 [2] = dcorner2[2] = (corner2[2] + corner4[2]) / 2.0;   
1384        corner1 = dcorner1;
1385        corner3 = dcorner2;  
1386        break;
1387       case 4:  
1388        corner1 = gradient->color2.rgb;  
1389        corner3 = gradient->color1.rgb;       
1390        dcorner1 [0] = dcorner2[0] = (corner1[0] + corner3[0]) / 2.0;
1391        dcorner1 [1] = dcorner2[1] = (corner1[1] + corner3[1]) / 2.0;
1392        dcorner1 [2] = dcorner2[2] = (corner1[2] + corner3[2]) / 2.0;   
1393        corner2 = dcorner1;
1394        corner4 = dcorner2;  
1395        break;
1396       case 5:
1397        corner1 = gradient->color1.rgb;
1398        corner2 = gradient->color2.rgb;
1399        corner3 = gradient->color2.rgb;
1400        corner4 = gradient->color2.rgb;
1401        break;
1402       case 6:
1403        corner1 = gradient->color2.rgb;
1404        corner2 = gradient->color1.rgb;
1405        corner3 = gradient->color2.rgb;
1406        corner4 = gradient->color2.rgb;
1407        break;
1408       case 7:
1409        corner1 = gradient->color2.rgb;
1410        corner2 = gradient->color2.rgb;
1411        corner3 = gradient->color1.rgb;
1412        corner4 = gradient->color2.rgb;
1413        break;
1414       case 8:
1415        corner1 = gradient->color2.rgb;
1416        corner2 = gradient->color2.rgb;
1417        corner3 = gradient->color2.rgb;
1418        corner4 = gradient->color1.rgb;
1419        break;
1420       default:
1421        printf("gradient background type not right\n");
1422
1423     }    
1424     glMatrixMode( GL_PROJECTION );
1425     glPushMatrix();
1426     glLoadIdentity();
1427     glMatrixMode( GL_MODELVIEW );
1428     glPushMatrix();
1429     glLoadIdentity();
1430
1431     if ( glIsEnabled( GL_DEPTH_TEST) )
1432     {
1433       upset[0] = 1;
1434       glDisable( GL_DEPTH_TEST );
1435     }
1436     if ( glIsEnabled( GL_LIGHTING ) )
1437     {
1438       upset[1] = 1;
1439       glDisable( GL_LIGHTING );
1440     }
1441     if ( !glIsEnabled( GL_SMOOTH ) )
1442     {
1443       upset[2] = 1; 
1444       glShadeModel( GL_SMOOTH ) ;
1445     }    
1446
1447     if( gradient->type <= 5 || gradient->type == 7 )
1448     {
1449       glBegin(GL_TRIANGLES);
1450         glColor3f(corner1[0],corner1[1],corner1[2]);
1451         glVertex2f(-1.,-1.);
1452         glColor3f(corner2[0],corner2[1],corner2[2]);
1453         glVertex2f( 1.,-1.);
1454         glColor3f(corner3[0],corner3[1],corner3[2]);
1455         glVertex2f( 1., 1.);          
1456       glEnd(); 
1457       glBegin(GL_TRIANGLES);
1458         glColor3f(corner1[0],corner1[1],corner1[2]);
1459         glVertex2f(-1.,-1.);
1460         glColor3f(corner3[0],corner3[1],corner3[2]);
1461         glVertex2f( 1., 1.);
1462         glColor3f(corner4[0],corner4[1],corner4[2]);
1463         glVertex2f(-1., 1.);          
1464       glEnd();
1465     }         
1466     else if( gradient->type == 6 || gradient->type == 8 )
1467     {
1468       glBegin(GL_TRIANGLES);
1469         glColor3f(corner1[0],corner1[1],corner1[2]);
1470         glVertex2f(-1.,-1.);
1471         glColor3f(corner2[0],corner2[1],corner2[2]);
1472         glVertex2f( 1.,-1.);
1473         glColor3f(corner4[0],corner4[1],corner4[2]);
1474         glVertex2f(-1., 1.);          
1475       glEnd(); 
1476       glBegin(GL_TRIANGLES);
1477         glColor3f(corner2[0],corner2[1],corner2[2]);
1478         glVertex2f( 1.,-1.);
1479         glColor3f(corner3[0],corner3[1],corner3[2]);
1480         glVertex2f( 1., 1.);
1481         glColor3f(corner4[0],corner4[1],corner4[2]);
1482         glVertex2f(-1., 1.);          
1483       glEnd(); 
1484
1485     }    
1486
1487     if ( upset[0] )
1488       glEnable( GL_DEPTH_TEST );   
1489
1490     if ( upset[1] )
1491       glEnable( GL_LIGHTING ); 
1492
1493     if ( upset[2] )
1494       glShadeModel( GL_FLAT );      
1495  
1496     if ( zbuffer )
1497       glEnable( GL_DEPTH_TEST );
1498     glPopMatrix();
1499     glMatrixMode( GL_PROJECTION );
1500     glPopMatrix();
1501     glMatrixMode( GL_MODELVIEW );
1502
1503     free(dcorner1);
1504     free(dcorner2);
1505     dcorner1 = 0;
1506     dcorner2 = 0;
1507
1508   } 
1509
1510 #endif /* OCC1188*/
1511
1512   glPopAttrib();
1513
1514   /* GL_DITHER on/off pour le trace */
1515   if (TxglGetDither ())
1516     glEnable (GL_DITHER);
1517   else
1518     glDisable (GL_DITHER);
1519
1520
1521 }
1522 /*----------------------------------------------------------------------*/