0022819: Redesign of OpenGl driver
[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   // Disable clipping planes
1240   GLint ii = 0, max_plane = 0;
1241   glGetIntegerv( GL_MAX_CLIP_PLANES, &max_plane );
1242   while (ii < max_plane) {
1243     const GLint planeid = GL_CLIP_PLANE0 + ii++;
1244     if (glIsEnabled(planeid));
1245       glDisable(planeid);
1246   }
1247
1248   TsmGetWSAttri (Wsid, WSBackground, &key);
1249   rgb = (Tfloat *)key.pdata;
1250
1251 #ifdef OCC1188
1252   TsmGetWSAttri (Wsid, WSBgTexture, &key);
1253   texture = (tsm_bg_texture)key.pdata;
1254 #endif
1255   TsmGetWSAttri (Wsid, WSZbuffer, &key);
1256   zbuffer = key.ldata;
1257
1258   TsmGetWSAttri (Wsid, WSBgGradient, &key);
1259   gradient = (tsm_bg_gradient)key.pdata;
1260   
1261   /* GL_DITHER on/off pour le background */
1262   if (TxglGetBackDither ())
1263     glEnable (GL_DITHER);
1264   else
1265     glDisable (GL_DITHER);
1266
1267   if (zbuffer)
1268   {
1269 #ifdef BUC60920 
1270     glDepthFunc(GL_LEQUAL);
1271 #else
1272     glDepthFunc(GL_LESS);
1273 #endif
1274     glDepthMask(GL_TRUE);
1275
1276 #ifdef BUC61044
1277     /* getting depth testing flag */
1278     TsmGetWSAttri( Wsid, WSDepthTest, &key );
1279     dTest = key.ldata;
1280     /* SAV checking if depth test was depricated somewhere outside */
1281     if ( dTest == TOn ) 
1282       glEnable(GL_DEPTH_TEST);
1283     else
1284       glDisable(GL_DEPTH_TEST);
1285 #else
1286     glEnable(GL_DEPTH_TEST);
1287 #endif
1288
1289     glClearDepth(1.0);
1290     glClearColor (rgb[0], rgb[1], rgb[2], ( float )0.0);
1291     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);     
1292   }
1293   else
1294   {
1295     glDisable(GL_DEPTH_TEST);
1296     glClearColor (rgb[0], rgb[1], rgb[2], ( float )0.0);
1297     glClear (GL_COLOR_BUFFER_BIT);
1298   }
1299 #ifdef OCC1188
1300   glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
1301   /* drawing bg image if any */
1302   if ( texture->texId != 0 ) {
1303     GLint width, height; /* window dimensions*/
1304     GLfloat x_center, y_center; /* window center */
1305     GLfloat x_offset, y_offset; /* half of the texture size */
1306     GLfloat texX_range = 1.0;
1307     /* texture <s> coordinate */
1308     GLfloat texY_range = 1.0; /* texture <t> coordinate */
1309
1310     TsmGetWSAttri( Wsid, WSWidth, &key );
1311     width = key.ldata;
1312     x_center = (GLfloat)( width / 2. );
1313     TsmGetWSAttri( Wsid, WSHeight, &key );
1314     height = key.ldata;
1315     y_center = (GLfloat)( height / 2. );
1316
1317     x_offset = (GLfloat)( texture->width / 2. ); /* style = center */
1318     y_offset = (GLfloat)( texture->height / 2. ); /* style = center */
1319     if ( texture->style != 0 ) { /* stretch or tile */
1320       x_offset = x_center;
1321       y_offset = y_center;
1322       if ( texture->style == 1 ) { /* tile */
1323         texX_range = (float)( width / texture->width );
1324         if ( texX_range < 1.0 )
1325           texX_range = 1.0;
1326         texY_range = (float)( height / texture->height );
1327         if ( texY_range < 1.0 )
1328           texY_range = 1.0;
1329       }
1330     }
1331     /* drawing background texture */
1332     glMatrixMode( GL_PROJECTION );
1333     glPushMatrix();
1334     glLoadIdentity();
1335     gluOrtho2D( 0.0, (GLdouble)width, 0.0, (GLdouble)height );
1336     glMatrixMode( GL_MODELVIEW );
1337     glPushMatrix();
1338     glLoadIdentity();
1339     glEnable( GL_TEXTURE_2D );
1340     glBindTexture( GL_TEXTURE_2D, texture->texId );
1341     glDisable( GL_DEPTH_TEST );
1342
1343     glDisable( GL_BLEND );
1344     glColor3f( rgb[0], rgb[1], rgb[2] );
1345     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
1346     glBegin( GL_QUADS );
1347     glTexCoord2f(0.0f, 0.0f);glVertex2f( x_center - x_offset, y_center - y_offset );
1348     glTexCoord2f(texX_range, 0.0f);glVertex2f( x_center + x_offset, y_center - y_offset );
1349     glTexCoord2f(texX_range, texY_range);glVertex2f( x_center + x_offset, y_center + y_offset );
1350     glTexCoord2f(0.0f, texY_range);glVertex2f( x_center - x_offset, y_center + y_offset );
1351     glEnd();
1352     if ( zbuffer )
1353       glEnable( GL_DEPTH_TEST );
1354     glDisable( GL_TEXTURE_2D );
1355     glPopMatrix(); /*modelview*/
1356     glMatrixMode( GL_PROJECTION );
1357     glPopMatrix(); /*projection*/
1358     glMatrixMode( GL_MODELVIEW );
1359   }  
1360   else if( gradient->type > 0 )
1361   {
1362
1363     Tfloat* corner1 = 0;/* -1,-1*/
1364     Tfloat* corner2 = 0;/*  1,-1*/
1365     Tfloat* corner3 = 0;/*  1, 1*/
1366     Tfloat* corner4 = 0;/* -1, 1*/
1367     Tfloat* dcorner1 = (Tfloat*)malloc(3*sizeof(Tfloat));
1368     Tfloat* dcorner2 = (Tfloat*)malloc(3*sizeof(Tfloat));
1369
1370     int upset[3] = {0} ;
1371
1372     switch( gradient->type )
1373     {
1374       case 1:
1375        corner1 = gradient->color2.rgb;
1376        corner2 = gradient->color2.rgb;
1377        corner3 = gradient->color1.rgb;
1378        corner4 = gradient->color1.rgb;
1379        break;
1380       case 2:    
1381        corner1 = gradient->color2.rgb;
1382        corner2 = gradient->color1.rgb;
1383        corner3 = gradient->color1.rgb;
1384        corner4 = gradient->color2.rgb;
1385        break;
1386       case 3:
1387        corner2 = gradient->color2.rgb;
1388        corner4 = gradient->color1.rgb;        
1389        dcorner1 [0] = dcorner2[0] = (corner2[0] + corner4[0]) / 2.0;
1390        dcorner1 [1] = dcorner2[1] = (corner2[1] + corner4[1]) / 2.0;
1391        dcorner1 [2] = dcorner2[2] = (corner2[2] + corner4[2]) / 2.0;   
1392        corner1 = dcorner1;
1393        corner3 = dcorner2;  
1394        break;
1395       case 4:  
1396        corner1 = gradient->color2.rgb;  
1397        corner3 = gradient->color1.rgb;       
1398        dcorner1 [0] = dcorner2[0] = (corner1[0] + corner3[0]) / 2.0;
1399        dcorner1 [1] = dcorner2[1] = (corner1[1] + corner3[1]) / 2.0;
1400        dcorner1 [2] = dcorner2[2] = (corner1[2] + corner3[2]) / 2.0;   
1401        corner2 = dcorner1;
1402        corner4 = dcorner2;  
1403        break;
1404       case 5:
1405        corner1 = gradient->color1.rgb;
1406        corner2 = gradient->color2.rgb;
1407        corner3 = gradient->color2.rgb;
1408        corner4 = gradient->color2.rgb;
1409        break;
1410       case 6:
1411        corner1 = gradient->color2.rgb;
1412        corner2 = gradient->color1.rgb;
1413        corner3 = gradient->color2.rgb;
1414        corner4 = gradient->color2.rgb;
1415        break;
1416       case 7:
1417        corner1 = gradient->color2.rgb;
1418        corner2 = gradient->color2.rgb;
1419        corner3 = gradient->color1.rgb;
1420        corner4 = gradient->color2.rgb;
1421        break;
1422       case 8:
1423        corner1 = gradient->color2.rgb;
1424        corner2 = gradient->color2.rgb;
1425        corner3 = gradient->color2.rgb;
1426        corner4 = gradient->color1.rgb;
1427        break;
1428       default:
1429        printf("gradient background type not right\n");
1430
1431     }    
1432     glMatrixMode( GL_PROJECTION );
1433     glPushMatrix();
1434     glLoadIdentity();
1435     glMatrixMode( GL_MODELVIEW );
1436     glPushMatrix();
1437     glLoadIdentity();
1438
1439     if ( glIsEnabled( GL_DEPTH_TEST) )
1440     {
1441       upset[0] = 1;
1442       glDisable( GL_DEPTH_TEST );
1443     }
1444     if ( glIsEnabled( GL_LIGHTING ) )
1445     {
1446       upset[1] = 1;
1447       glDisable( GL_LIGHTING );
1448     }
1449     if ( !glIsEnabled( GL_SMOOTH ) )
1450     {
1451       upset[2] = 1; 
1452       glShadeModel( GL_SMOOTH ) ;
1453     }    
1454
1455     if( gradient->type <= 5 || gradient->type == 7 )
1456     {
1457       glBegin(GL_TRIANGLES);
1458         glColor3f(corner1[0],corner1[1],corner1[2]);
1459         glVertex2f(-1.,-1.);
1460         glColor3f(corner2[0],corner2[1],corner2[2]);
1461         glVertex2f( 1.,-1.);
1462         glColor3f(corner3[0],corner3[1],corner3[2]);
1463         glVertex2f( 1., 1.);          
1464       glEnd(); 
1465       glBegin(GL_TRIANGLES);
1466         glColor3f(corner1[0],corner1[1],corner1[2]);
1467         glVertex2f(-1.,-1.);
1468         glColor3f(corner3[0],corner3[1],corner3[2]);
1469         glVertex2f( 1., 1.);
1470         glColor3f(corner4[0],corner4[1],corner4[2]);
1471         glVertex2f(-1., 1.);          
1472       glEnd();
1473     }         
1474     else if( gradient->type == 6 || gradient->type == 8 )
1475     {
1476       glBegin(GL_TRIANGLES);
1477         glColor3f(corner1[0],corner1[1],corner1[2]);
1478         glVertex2f(-1.,-1.);
1479         glColor3f(corner2[0],corner2[1],corner2[2]);
1480         glVertex2f( 1.,-1.);
1481         glColor3f(corner4[0],corner4[1],corner4[2]);
1482         glVertex2f(-1., 1.);          
1483       glEnd(); 
1484       glBegin(GL_TRIANGLES);
1485         glColor3f(corner2[0],corner2[1],corner2[2]);
1486         glVertex2f( 1.,-1.);
1487         glColor3f(corner3[0],corner3[1],corner3[2]);
1488         glVertex2f( 1., 1.);
1489         glColor3f(corner4[0],corner4[1],corner4[2]);
1490         glVertex2f(-1., 1.);          
1491       glEnd(); 
1492
1493     }    
1494
1495     if ( upset[0] )
1496       glEnable( GL_DEPTH_TEST );   
1497
1498     if ( upset[1] )
1499       glEnable( GL_LIGHTING ); 
1500
1501     if ( upset[2] )
1502       glShadeModel( GL_FLAT );      
1503  
1504     if ( zbuffer )
1505       glEnable( GL_DEPTH_TEST );
1506     glPopMatrix();
1507     glMatrixMode( GL_PROJECTION );
1508     glPopMatrix();
1509     glMatrixMode( GL_MODELVIEW );
1510
1511     free(dcorner1);
1512     free(dcorner2);
1513     dcorner1 = 0;
1514     dcorner2 = 0;
1515
1516   } 
1517
1518 #endif /* OCC1188*/
1519
1520   glPopAttrib();
1521
1522   /* GL_DITHER on/off pour le trace */
1523   if (TxglGetDither ())
1524     glEnable (GL_DITHER);
1525   else
1526     glDisable (GL_DITHER);
1527
1528
1529 }
1530 /*----------------------------------------------------------------------*/