0022792: Globally defined symbol PI conflicts with VTK definition (Intel compiler)
[occt.git] / src / OpenGl / OpenGl_telem_util.cxx
1 /***********************************************************************
2
3 FONCTION :
4 ----------
5 File OpenGl_telem_util :
6
7
8 REMARQUES:
9 ---------- 
10
11
12 HISTORIQUE DES MODIFICATIONS   :
13 --------------------------------
14 xx-xx-xx : xxx ; Creation.
15 07-02-96 : FMN ; - Ajout trace
16 - Suppression code inutile
17 08-03-96 : FMN ; - Ajout include manquant 
18 01-04-96 : CAL ; Integration MINSK portage WNT
19 15-04-96 : CAL ; Integration travail PIXMAP de Jim ROTH
20 22-04-96 : FMN ; Ajout TelReadImage TelDrawImage
21 10-05-96 : CAL ; Ajout d'un nouveau delta dans les copies
22 de pixels (voir CALL_DEF_DELTA)
23 25-06-96 : FMN ; Suppression utilisation de glScissor.
24 02-07-96 : FMN ; Suppression WSWSHeight et WSWSWidth
25 Suppression glViewport inutile.
26 18-07-96 : FMN ; Suppression TelFlush inutile.
27 08-07-96 : FMN ; Suppression de OPENGL_DEBUG inutile avec la nouvelle
28 version de ogldebug.
29 24-10-96 : CAL ; Portage WNT
30 23-01-97 : CAL ; Suppression de TelClearViews dans TelCopyBuffers
31 30-01-97 : FMN ; Ajout commentaires + WNT.
32 12-02-97 : FMN ; Suppression TelEnquireFacilities()
33 22-04-97 : FMN ; Ajout affichage du cadre pour la copie de buffer
34 30-06-97 : FMN ; Suppression OpenGl_telem_light.h
35 18-07-97 : FMN ; Utilisation de la toolkit sur les lights
36 07-10-97 : FMN ; Simplification WNT + correction Transient
37 05-12-97 : FMN ; PRO11168: Suppression TglActiveWs pour project/unproject
38 23-12-97 : FMN ; Suppression TelSetFrontFaceAttri et TelSetBackFaceAttri 
39 30-12-97 : FMN ; CTS18312: Correction back material
40 04-05-98 : CAL ; Contournement bug SGI octane bavure de pixels (PRO12899)
41 30-09-98 : CAL ; Optimisation pour eviter de charger inutilement
42 les matrices de la vue.
43 19-10-98 : FMN ; Suppression de glPixelTransferi dans TelEnable() car cela
44 rentre en conflit avec l'utilisation d'une image de fond.
45 02.14.100 : JR : Warnings on WNT truncations from double to float
46 08-03-01 : GG  ; BUC60823 Avoid crash in the normal computation method
47 when a face has confused or aligned points.
48
49 ************************************************************************/
50
51 #define IMP190100 /*GG To avoid too many REDRAW in immediat mode,
52 //      Add TelMakeFrontAndBackBufCurrent() function
53 */
54 #define QTOCC_PATCH
55
56 /*----------------------------------------------------------------------*/
57 /*
58 * Includes
59 */
60
61 #include <string.h>
62 #include <stdio.h>
63 #include <stdlib.h>
64
65 #ifndef WNT
66 # include <X11/Xlib.h>
67 #else
68 # define STRICT
69 # include <windows.h>
70 #endif  /* WNT */
71
72
73 #include <GL/gl.h>
74 #include <GL/glu.h>
75 #ifndef WNT
76 #include <GL/glx.h>
77 #endif /* WNT */
78
79 #include <InterfaceGraphic_Graphic3d.hxx>
80 #include <InterfaceGraphic_Visual3d.hxx>
81
82 #include <OpenGl_tgl_all.hxx>
83 #include <OpenGl_tsm.hxx>
84 #include <OpenGl_tsm_ws.hxx>
85 #include <OpenGl_telem.hxx>
86 #include <OpenGl_telem_attri.hxx>
87 #include <OpenGl_telem_util.hxx>
88 #include <OpenGl_telem_view.hxx>
89 #include <OpenGl_tgl_tox.hxx>
90 #include <OpenGl_tgl_subrvis.hxx>
91 #include <OpenGl_txgl.hxx>
92 #include <OpenGl_LightBox.hxx>
93 #include <OpenGl_Memory.hxx>
94
95 /*----------------------------------------------------------------------*/
96 /*
97 * Constantes
98 */
99
100 #define NO_TRACE
101 #define CALL_DEF_DELTA 10
102 #define NO_COPYBUFFER
103
104 /*----------------------------------------------------------------------*/
105 /*
106 * Variables statiques
107 */
108
109 static Tint call_back_buffer_restored = TOff;
110
111 #ifndef WNT
112
113 /*
114 * Wrappers and utilities used to select between pixmap and gl double buffering
115 */
116
117 /* Cache some pixmap info for pixmap double buffering */
118
119 static Display *window_display; /* the display in use */
120 static Window window_id;  /* the window to copy the pixmap to */
121 static Pixmap pixmap_id;  /* the pixmap id */
122 static GLXPixmap glx_pixmap;  /* the glx pixmap */
123 static int
124 window_width,   /* window width and height for XCopyArea */
125 window_height,
126 window_depth;
127
128 static GC window_gc;    /* GC for XCopyArea */
129
130 static GLXContext glx_context;  /* GL Context */
131
132 static int usePixmapDB = 0; /* True if doing pixmap double buffering */
133
134 /*----------------------------------------------------------------------*/
135
136 void TelSetPixmapDBParams(Display *dpy,
137                           Window window,
138                           int width, int height, int depth, GC gc,
139                           Pixmap pixmap,
140                           GLXPixmap glxpixmap,
141                           GLXContext ctx)
142
143 {
144   window_display = dpy;
145   window_id = window;
146   window_width = width;
147   window_height = height;
148   window_depth = depth;
149   window_gc = gc;
150
151   pixmap_id = pixmap;
152
153   glx_pixmap = glxpixmap;
154
155   glx_context = ctx;
156 }
157
158 GLXPixmap TelGetGLXPixmap()
159 {
160   return glx_pixmap;
161 }
162
163 void TelSetPixmapDB(int flag)
164 {
165   usePixmapDB = flag;
166 }
167
168 int TelTestPixmapDB()
169 {
170   return usePixmapDB;
171 }
172
173 void TelDrawBuffer(GLenum buf)
174 {
175   if (usePixmapDB)
176     glDrawBuffer(GL_FRONT);
177   else
178     glDrawBuffer(buf);
179 }
180
181 #endif /* WNT */
182
183 /*----------------------------------------------------------------------*/
184
185 void TelMakeFrontBufCurrent(Tint WsId)
186 {
187 #ifndef WNT
188   if (usePixmapDB)
189   {
190     glXMakeCurrent(window_display,window_id, glx_context);
191     glDrawBuffer(GL_FRONT);
192   }
193   else
194 #endif /* WNT */
195   {
196     glDrawBuffer(GL_FRONT);
197   }
198 }
199
200 void TelMakeBackBufCurrent(Tint WsId)
201 {
202 #ifndef WNT
203   if (usePixmapDB)
204   {
205     glXMakeCurrent(window_display,glx_pixmap, glx_context);
206     glDrawBuffer(GL_BACK);
207   }
208   else
209 #endif /* WNT */
210   {
211     glDrawBuffer(GL_BACK);
212   }
213 }
214
215 #ifdef IMP190100
216 void TelMakeFrontAndBackBufCurrent(Tint WsId)
217 {
218 #ifndef WNT
219   if (usePixmapDB)
220   {
221     glXMakeCurrent(window_display,window_id, glx_context);
222     glDrawBuffer(GL_FRONT_AND_BACK);
223   }
224   else
225 #endif /* WNT */
226   {
227     glDrawBuffer(GL_FRONT_AND_BACK);
228   }
229 }
230 #endif
231
232 /*----------------------------------------------------------------------*/
233 Tint
234 TelRemdupnames(Tint *ls, Tint num )
235 {
236   register  Tint  *ap, *bp, n;
237
238   if( num < 2 )
239     return num;
240
241   ap = bp = ls+1;
242   n = num-1;
243   while( n-- )
244   {
245     if( ap[-1] != *bp )
246       *ap++ = *bp++;
247     else
248       bp++;
249   }
250
251   return ap-ls;
252 }
253
254 /*----------------------------------------------------------------------*/
255 #ifdef BUC60823
256 #define GPRECIS 0.000001
257 Tint TelGetPolygonNormal(tel_point pnts, Tint* indexs, Tint npnt, Tfloat *norm ) {
258   Tint status=0;
259
260   norm[0] = norm[1] = norm[2] = 0.;
261   if( npnt > 2 ) { 
262     Tfloat a[3], b[3], c[3];
263     Tint i,j,i0,ii=0,jj;
264
265     i0 = 0; if( indexs ) i0 = indexs[0];
266     for( i=1 ; i<npnt ; i++ ) {
267       ii = i; if( indexs ) ii = indexs[i];
268       vecsub( a, pnts[ii].xyz, pnts[i0].xyz );
269       if( vecmg2(a) > GPRECIS ) break;
270     }
271     if( i < npnt-1 ) {
272       for( j=i+1 ; j<npnt ; j++ ) {
273         jj = j; if( indexs ) jj = indexs[j];
274         vecsub( b, pnts[jj].xyz, pnts[i0].xyz );
275         vecsub( c, pnts[jj].xyz, pnts[ii].xyz );
276         if( (vecmg2(b) > GPRECIS) && (vecmg2(c) > GPRECIS) ) break;
277       }
278       if( j < npnt ) {
279         Tfloat d;
280         veccrs( norm, a, b );
281         d = vecnrmd( norm, d );
282         status = (d > 0.) ? 1 : 0;
283       }
284     }
285   }
286 #ifdef DEB
287   if( !status )
288     printf(" *** OpenGl_TelGetPolygonNormal.has found confused or aligned points\n");
289 #endif
290
291   return status;
292 }
293
294 Tint TelGetNormal(Tfloat *data1, Tfloat *data2, Tfloat *data3, Tfloat *norm ) {
295   Tfloat a[3], b[3];
296   Tint status=0;
297
298   norm[0] = norm[1] = norm[2] = 0.;
299   vecsub( a, data2, data1 );
300   vecsub( b, data3, data2 );
301   if( (vecmg2(a) > GPRECIS) && (vecmg2(b) > GPRECIS) ) {
302     Tfloat d;
303     veccrs( norm, a, b );
304     d = vecnrmd( norm, d );
305     status = (d > 0.) ? 1 : 0;
306   }
307 #ifdef DEB
308   if( !status )
309     printf(" *** OpenGl_TelGetNormal.has found confused or aligned points\n");
310 #endif
311
312   return status;
313 }
314 #else
315 void
316 TelGetNormal(Tfloat *data1, Tfloat *data2, Tfloat *data3, Tfloat *norm ) {
317   Tfloat a[3], b[3];
318
319   vecsub( a, data2, data1 );
320   vecsub( b, data3, data2 );
321   veccrs( norm, a, b );
322 }
323 #endif
324
325 /*----------------------------------------------------------------------*/
326 Tint
327 TelIsBackFace(Tmatrix3 n, Tfloat *nrm )
328 {
329   Tfloat    r[4], m[4];
330
331   veccpy(m,nrm);
332   m[3] = ( float )1.0;
333
334   TelTranpt3( r, m, n );
335
336   return r[2] < 0.0;
337 }
338
339 /*----------------------------------------------------------------------*/
340 void
341 TelTransposemat3 (Tmatrix3 a)
342 {
343   Tint row, col;
344   Tmatrix3 res;
345   Tint dim = 4;
346
347   /* transposition de la sous-matrice dim x dim */
348   for (row = 0; row < dim; row++)
349     for (col = 0; col < dim; col++)
350       res[row][col] = a[col][row];
351
352   /* copie du resultat */
353   matcpy (a, res);
354
355   return;
356 }
357
358 /*----------------------------------------------------------------------*/
359 void
360 TelMultiplymat3 (Tmatrix3 c, Tmatrix3 a, Tmatrix3 b)
361 {
362   Tint row, col, i;
363   Tmatrix3 res;
364   Tint dim = 4;
365
366   /* on multiplie d'abord les 2 matrices dim x dim */
367   for (row = 0; row < dim; row++) {
368     for (col = 0; col < dim; col++) {
369       Tfloat sum = ( float )0.0;
370       for (i = 0; i < dim; i++)
371         sum += a[row][i] * b[i][col];
372       res[row][col] = sum;
373     }
374   }
375
376   /* on copie ensuite le resultat */
377   matcpy (c, res);
378
379   return;
380 }
381
382 /*----------------------------------------------------------------------*/
383 void
384 TelTranpt3(Tfloat tpt[4], Tfloat pt[4], Tmatrix3 mat )
385 {
386   register  long  i, j;
387   Tfloat    sum;
388
389   for( i = 0; i < 4; i++ )
390   {
391     for( j = 0, sum = ( float )0.0; j < 4; j++ )
392     {
393       sum += pt[j] * mat[j][i];
394     }
395     tpt[i] = sum;
396   }
397   return;
398 }
399
400 /*----------------------------------------------------------------------*/
401 void
402 TelInitWS(Tint ws, Tint w, Tint h, Tfloat bgcolr, Tfloat bgcolg, Tfloat bgcolb )
403 {
404   CMN_KEY_DATA data;
405
406   TsmGetWSAttri( ws, WSDbuff, &data );
407
408   glMatrixMode(GL_MODELVIEW);
409   glViewport( 0, 0, w, h);
410
411   /*
412   * CAL mai 1998
413   * Contournement bug SGI sur Octane (PRO12899)
414   * Bavures de pixels lors de la copie de vue 3d
415   */
416   glDisable (GL_SCISSOR_TEST);
417
418 #ifdef TRACE
419   printf("OPENGL: TelInitWS: glClearColor %d \n", ws);
420 #endif
421   if( data.ldata == TOn )
422   {
423 #ifndef WNT
424     if (TelTestPixmapDB())
425     {
426       glDrawBuffer(GL_FRONT);
427       glClearColor(bgcolr, bgcolg, bgcolb, 1.0);
428       glClear(GL_COLOR_BUFFER_BIT);
429     }
430     else
431     {
432       /* QTOCC_PATCH by PCD: the frame buffer should not be cleared here
433       to avoid flicker. It is cleared properly in TelClearViews() 
434       called by call_func_redraw_all_structs_begin() */
435       glDrawBuffer(GL_BACK);
436     }
437 #else
438     /* QTOCC_PATCH by PCD: the frame buffer should not be cleared here
439     to avoid flicker. It is cleared properly in TelClearViews() 
440     called by call_func_redraw_all_structs_begin() */
441     glDrawBuffer(GL_BACK);
442 #endif /* WNT */
443   }
444   else
445   {
446     glClearColor(bgcolr, bgcolg, bgcolb, ( float )1.0);
447     glClear(GL_COLOR_BUFFER_BIT);
448   }
449   return;
450
451 }
452
453
454 /*----------------------------------------------------------------------*/
455 void TelSwapBuffers ( Tint ws ) {
456
457 #ifndef WNT
458
459   CMN_KEY_DATA data;
460
461   if (TelTestPixmapDB())
462   {
463     glFlush();
464     XCopyArea(call_thedisplay, pixmap_id, window_id,
465       window_gc, 0, 0,
466       window_width, window_height, 0, 0);
467   }
468   else
469   {
470     TsmGetWSAttri( ws, WSWindow, &data );
471     glXSwapBuffers ( call_thedisplay, data.ldata );
472   }
473
474 #else
475
476   SwapBuffers ( wglGetCurrentDC () );
477   TelFlush(0);
478
479 #endif  /* WNT */
480
481   TelSetBackBufferRestored (TOff);
482
483 #ifdef TRACE
484   printf("OPENGL: TelSwapBuffers: glXSwapBuffers %d \n", ws);
485 #endif
486
487   return;
488
489 }  /* end TelSwapBuffers */
490
491 /*----------------------------------------------------------------------*/
492 Tint
493 TelBackBufferRestored ()
494 {
495   return call_back_buffer_restored;
496 }
497
498 /*----------------------------------------------------------------------*/
499 void
500 TelSetBackBufferRestored (Tint flag)
501 {
502 #ifdef TRACE
503   printf("OPENGL: TelSetBackBufferRestored(%d): \n",flag);
504 #endif
505   call_back_buffer_restored = flag;
506 }
507
508 /*----------------------------------------------------------------------*/
509 void
510 TelCopyBuffers(Tint ws, GLenum from, GLenum to,
511                Tfloat xm, Tfloat ym, Tfloat zm, Tfloat XM, Tfloat YM, Tfloat ZM, Tint flag)
512 {
513   CMN_KEY_DATA key;
514   Tint w, h;
515
516 #ifdef TRACE
517   printf("OPENGL: TelCopyBuffers: \n");
518 #endif
519
520   if (to == GL_BACK) TelSetBackBufferRestored (TOff);
521
522 #ifndef WNT
523   if (TelTestPixmapDB())
524   {
525 #ifdef TRACE
526     printf("OPENGL: TelSwapBuffers: glFlush \n");
527 #endif
528     glFlush();
529     XCopyArea(window_display, pixmap_id, window_id,
530       window_gc, 0, 0,
531       window_width, window_height, 0, 0);
532     return;
533   }
534 #endif /* WNT */
535
536   TsmGetWSAttri (ws, WSWidth, &key);
537   w = key.ldata;
538   TsmGetWSAttri (ws, WSHeight, &key);
539   h = key.ldata;
540
541   glMatrixMode (GL_PROJECTION);
542   glPushMatrix ();
543   glLoadIdentity ();
544   gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
545   glMatrixMode (GL_MODELVIEW);
546   glPushMatrix ();
547   glLoadIdentity ();
548
549   TelDisable (ws);
550   if (flag) 
551   {
552     /*
553     * calcul de la projection de la boite
554     * et copie du rectangle projete
555     */
556     Tint i;
557     GLsizei width, height;
558     Tfloat xmr, ymr, XMR, YMR;
559     Tfloat xr[8], yr[8];
560     /*
561     * Projection de la boite englobante
562     */
563     if ((TelProjectionRaster (ws, xm, ym, zm, &xr[0], &yr[0]) == TSuccess)
564       &&  (TelProjectionRaster (ws, xm, YM, zm, &xr[1], &yr[1]) == TSuccess)
565       &&  (TelProjectionRaster (ws, XM, YM, zm, &xr[2], &yr[2]) == TSuccess)
566       &&  (TelProjectionRaster (ws, XM, ym, zm, &xr[3], &yr[3]) == TSuccess)
567       &&  (TelProjectionRaster (ws, xm, ym, ZM, &xr[4], &yr[4]) == TSuccess)
568       &&  (TelProjectionRaster (ws, xm, YM, ZM, &xr[5], &yr[5]) == TSuccess)
569       &&  (TelProjectionRaster (ws, XM, YM, ZM, &xr[6], &yr[6]) == TSuccess)
570       &&  (TelProjectionRaster (ws, XM, ym, ZM, &xr[7], &yr[7]) == TSuccess)) 
571     {
572       xmr = ymr = (float ) shortreallast ();
573       XMR = YMR = (float ) shortrealfirst ();
574       /*
575       * Recherche du rectangle projete
576       */
577       for (i=0; i<8; i++) {
578         if (xmr > xr[i]) xmr = xr[i];
579         if (ymr > yr[i]) ymr = yr[i];
580         if (XMR < xr[i]) XMR = xr[i];
581         if (YMR < yr[i]) YMR = yr[i];
582       }
583       /* pour eviter les bavures de pixels ! */
584       xmr--;ymr--;
585       XMR++;YMR++;
586
587       /*
588       * Ajout CAL : 10/05/96
589       * Si les MinMax viennent d'un ensemble de markers
590       * on ne tient pas compte du scale factor de ceux-ci
591       * dans les valeurs de MinMax. En effet, ce facteur
592       * est dans l'espace pixel et les MinMax dans l'espace
593       * du modele. Donc ajout d'un delta de pixels
594       * en esperant que les applis n'utilisent pas des
595       * markers tres gros !
596       */
597       xmr -= CALL_DEF_DELTA; ymr -= CALL_DEF_DELTA;
598       XMR += CALL_DEF_DELTA; YMR += CALL_DEF_DELTA;
599
600       /*
601       * Le rectangle projete peut-etre clippe
602       */
603       width = (GLsizei) (XMR-xmr+1);
604       height = (GLsizei) (YMR-ymr+1);
605 #ifdef COPYBUFFER
606       printf ("avant clipping\n");
607       printf ("xm, ym, zm : %f, %f, %f\n", xm, ym, zm);
608       printf ("XM, YM, ZM : %f, %f, %f\n", XM, YM, ZM);
609       printf ("taille fenetre : %d, %d\n", w, h);
610       printf ("xmr, ymr by GLU : %f, %f\n", xmr, ymr);
611       printf ("YMR, YMR by GLU : %f, %f\n", XMR, YMR);
612       printf ("copie x, y, dx, dy : %d, %d, %d, %d\n\n",
613         (int) xmr, (int) ymr, (int) width, (int) height);
614 #endif
615       /*
616       * (xmr,ymr) coin inferieur gauche
617       * (XMR,YMR) coin superieur droit
618       */
619       /* cas ou 1 coin est en dehors de la fenetre */
620       if (xmr < 0) { width  = (GLsizei) (XMR+1); xmr = 0; }
621       if (ymr < 0) { height = (GLsizei) (YMR+1); ymr = 0; }
622       if (XMR > w) { width  = (GLsizei) (w-xmr+1); }
623       if (YMR > h) { height = (GLsizei) (h-ymr+1); }
624
625       /* cas ou les 2 coins sont en dehors de la fenetre */
626       if (XMR < 0) { xmr = 0; width = height = 1; }
627       if (YMR < 0) { ymr = 0; width = height = 1; }
628       if (xmr > w) { xmr = 0; width = height = 1; }
629       if (ymr > h) { ymr = 0; width = height = 1; }
630 #ifdef COPYBUFFER
631       printf ("apres clipping\n");
632       printf ("xmr, ymr by GLU : %f, %f\n", xmr, ymr);
633       printf ("YMR, YMR by GLU : %f, %f\n", XMR, YMR);
634       printf ("copie x, y, dx, dy : %d, %d, %d, %d\n\n",
635         (int) xmr, (int) ymr, (int) width, (int) height);
636 #endif
637       glDrawBuffer (to);
638       glReadBuffer (from);
639       /* copie partielle */
640       glRasterPos2i ((GLint) xmr, (GLint) ymr);
641       glCopyPixels ((GLint) xmr, (GLint) ymr, width, height, GL_COLOR);
642       /* TelFlush (1); */
643     }
644     else 
645     {
646       glDrawBuffer (to);
647       /* TelClearViews (ws); */
648       glReadBuffer (from);
649       /* copie complete */
650       glRasterPos2i (0, 0);
651       glCopyPixels (0, 0, w+1, h+1, GL_COLOR);
652       /* TelFlush (1); */
653     }
654   }
655   else 
656   {
657     glDrawBuffer (to);
658     /* TelClearViews (ws); */
659     glReadBuffer (from);
660     /* copie complete */
661     glRasterPos2i (0, 0);
662     glCopyPixels (0, 0, w+1, h+1, GL_COLOR);
663     /* TelFlush (1); */
664   }
665   TelEnable (ws);
666
667   glMatrixMode (GL_PROJECTION);
668   glPopMatrix ();
669   glMatrixMode (GL_MODELVIEW);
670   glPopMatrix ();
671
672   glDrawBuffer (GL_BACK);
673   return;
674 }
675
676 /*----------------------------------------------------------------------*/
677 void
678 TelReadImage(Tint ws, GLenum from, Tint posx, Tint posy, Tint width, Tint height, unsigned int *image)
679 {
680   CMN_KEY_DATA key;
681   Tint w, h;
682
683 #ifdef TRACE
684   printf("OPENGL: TelReadImage: %d %d %d %d \n", posx, posy, width, height);
685 #endif
686
687   if (image !=NULL)
688   {
689     TsmGetWSAttri (ws, WSWidth, &key);
690     w = key.ldata;
691     TsmGetWSAttri (ws, WSHeight, &key);
692     h = key.ldata;
693
694     glMatrixMode (GL_PROJECTION);
695     glLoadIdentity ();
696     gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
697     glMatrixMode (GL_MODELVIEW);
698     glLoadIdentity ();
699
700     glReadBuffer(from); 
701
702     glRasterPos2i (posx, posy);
703     TelDisable (ws);
704     glReadPixels (posx, posy, width, height, GL_RGBA, GL_UNSIGNED_BYTE, image);
705     TelEnable (ws);
706
707     glReadBuffer(GL_BACK);        
708   }
709
710   return;
711 }
712
713 /*----------------------------------------------------------------------*/
714 void
715 TelDrawImage(Tint ws, GLenum to, Tint posx, Tint posy, Tint width, Tint height, unsigned int *image)
716 {
717   CMN_KEY_DATA key;
718   Tint w, h;
719
720 #ifdef TRACE
721   printf("OPENGL: TelDrawImage: %d %d %d %d \n", posx, posy, width, height);
722 #endif
723
724   if (image !=NULL)
725   {
726     TsmGetWSAttri (ws, WSWidth, &key);
727     w = key.ldata;
728     TsmGetWSAttri (ws, WSHeight, &key);
729     h = key.ldata;
730
731     glMatrixMode (GL_PROJECTION);
732     glLoadIdentity ();
733     gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
734     glMatrixMode (GL_MODELVIEW);
735     glLoadIdentity ();
736
737     glDrawBuffer(to);
738
739     glRasterPos2i (posx, posy);
740     TelDisable (ws);
741     glDrawPixels (width, height, GL_RGBA, GL_UNSIGNED_BYTE, image);
742     TelEnable (ws);
743
744     glDrawBuffer(GL_BACK);     
745   }     
746   return;
747 }
748
749 /*----------------------------------------------------------------------*/
750 void
751 TelReadDepths(Tint ws, Tint posx, Tint posy, Tint width, Tint height, float *depths)
752 {
753   CMN_KEY_DATA key;
754   Tint w, h;
755
756 #ifdef TRACE
757   printf("OPENGL: TelReadDepths: %d %d %d %d \n", posx, posy, width, height);
758 #endif
759
760   if ( TsmGetWSAttri (ws, WSWindow, &key) != TSuccess ) return;
761
762   if (depths != NULL && TxglWinset (call_thedisplay, (WINDOW) key.ldata) == TSuccess)
763   {
764     TsmGetWSAttri (ws, WSWidth, &key);
765     w = key.ldata;
766     TsmGetWSAttri (ws, WSHeight, &key);
767     h = key.ldata;
768
769     glMatrixMode (GL_PROJECTION);
770     glLoadIdentity ();
771     gluOrtho2D ((GLdouble) 0., (GLdouble) w, 0., (GLdouble) h);
772     glMatrixMode (GL_MODELVIEW);
773     glLoadIdentity ();
774
775     glRasterPos2i (posx, posy);
776     TelDisable (ws);
777     glReadPixels (posx, posy, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depths);
778     TelEnable (ws);
779   }
780
781   return;
782 }
783
784 /*----------------------------------------------------------------------*/
785 void
786 TelEnable (Tint ws)
787 {
788   /*glPixelTransferi (GL_MAP_COLOR, GL_TRUE);*/
789
790   /* GL_DITHER on/off pour le trace */
791   if (TxglGetDither())
792     glEnable (GL_DITHER);
793   else
794     glDisable (GL_DITHER);
795
796   return;
797 }
798
799 /*----------------------------------------------------------------------*/
800 void
801 TelDisable (Tint ws)
802 {
803   glDisable (GL_DITHER);
804   glPixelTransferi (GL_MAP_COLOR, GL_FALSE);
805
806   /*
807   * Disable stuff that's likely to slow down glDrawPixels.
808   * (Omit as much of this as possible, when you know in advance
809   * that the OpenGL state will already be set correctly.)
810   */
811   glDisable(GL_ALPHA_TEST);
812   glDisable(GL_BLEND);
813   glDisable(GL_DEPTH_TEST);
814   glDisable(GL_FOG);
815   LightOff();
816
817   glDisable(GL_LOGIC_OP);
818   glDisable(GL_STENCIL_TEST);
819   glDisable(GL_TEXTURE_1D);
820   glDisable(GL_TEXTURE_2D);
821   glPixelTransferi(GL_MAP_COLOR, GL_FALSE);
822   glPixelTransferi(GL_RED_SCALE, 1);
823   glPixelTransferi(GL_RED_BIAS, 0);
824   glPixelTransferi(GL_GREEN_SCALE, 1);
825   glPixelTransferi(GL_GREEN_BIAS, 0);
826   glPixelTransferi(GL_BLUE_SCALE, 1);
827   glPixelTransferi(GL_BLUE_BIAS, 0);
828   glPixelTransferi(GL_ALPHA_SCALE, 1);
829   glPixelTransferi(GL_ALPHA_BIAS, 0);
830
831   /*
832   * Disable extensions that could slow down glDrawPixels.
833   * (Actually, you should check for the presence of the proper
834   * extension before making these calls.  I've omitted that
835   * code for simplicity.)
836   */
837
838 #ifdef GL_EXT_convolution
839   glDisable(GL_CONVOLUTION_1D_EXT);
840   glDisable(GL_CONVOLUTION_2D_EXT);
841   glDisable(GL_SEPARABLE_2D_EXT);
842 #endif
843
844 #ifdef GL_EXT_histogram
845   glDisable(GL_HISTOGRAM_EXT);
846   glDisable(GL_MINMAX_EXT);
847 #endif
848
849 #ifdef GL_EXT_texture3D
850   glDisable(GL_TEXTURE_3D_EXT);
851 #endif
852
853   return;
854 }
855
856 /*----------------------------------------------------------------------*/
857 TStatus
858 TelProjectionRaster(Tint ws, Tfloat x, Tfloat y, Tfloat z, Tfloat *xr, Tfloat *yr)
859 {
860   Tint w, h;
861   CMN_KEY_DATA key;
862   Tint vid;          /* View index */
863   TEL_VIEW_REP vrep; /* View definition */
864
865   GLint status;
866
867   int i, j, k;
868   GLdouble objx, objy, objz;
869   GLdouble modelMatrix[16], projMatrix[16];
870   GLint viewport[4];
871   GLdouble winx, winy, winz;
872
873   vid = ws;
874
875   if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
876     return TFailure;
877
878   TsmGetWSAttri (ws, WSWidth, &key);
879   w = key.ldata;
880   TsmGetWSAttri (ws, WSHeight, &key);
881   h = key.ldata;
882
883   objx = ( GLdouble )x; objy = ( GLdouble )y; objz = ( GLdouble )z;
884
885   for (k = 0, i = 0; i < 4; i++)
886     for (j = 0; j < 4; j++, k++)
887       modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
888
889   for (k = 0, i = 0; i < 4; i++)
890     for (j = 0; j < 4; j++, k++)
891       projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
892
893   viewport[0] = 0;
894   viewport[1] = 0;
895   viewport[2] = w;
896   viewport[3] = h;
897
898   /*
899   * glGetIntegerv (GL_VIEWPORT, viewport);
900   * glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
901   * glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
902   */
903
904   status = gluProject (objx, objy, objz,
905     modelMatrix, projMatrix, viewport,
906     &winx, &winy, &winz);
907
908   if (status == GL_TRUE) {
909     *xr = ( Tfloat )winx;
910     *yr = ( Tfloat )winy;
911     return TSuccess;
912   }
913   else 
914   {
915     *xr = 0.0F;
916     *yr = 0.0F;
917     return TFailure;
918   }
919 }
920
921 /*----------------------------------------------------------------------*/
922 TStatus
923 TelUnProjectionRaster(Tint ws, Tint xr, Tint yr, Tfloat *x, Tfloat *y, Tfloat *z)
924 {
925   Tint w, h;
926   CMN_KEY_DATA key;
927   Tint vid;          /* View index */
928   TEL_VIEW_REP vrep; /* View definition */
929
930   int i, j, k;
931   GLdouble objx, objy, objz;
932   GLdouble modelMatrix[16], projMatrix[16];
933   GLint viewport[4];
934   GLdouble winx, winy, winz;
935   GLint status;
936
937   vid = ws;
938
939   if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
940     return TFailure;
941
942   TsmGetWSAttri (ws, WSWidth, &key);
943   w = key.ldata;
944   TsmGetWSAttri (ws, WSHeight, &key);
945   h = key.ldata;
946
947   winx = ( GLdouble )xr; winy = ( GLdouble )yr; winz = ( GLdouble )0.0;
948
949   for (k = 0, i = 0; i < 4; i++)
950     for (j = 0; j < 4; j++, k++)
951       modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
952
953   for (k = 0, i = 0; i < 4; i++)
954     for (j = 0; j < 4; j++, k++)
955       projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
956
957   viewport[0] = 0;
958   viewport[1] = 0;
959   viewport[2] = w;
960   viewport[3] = h;
961
962   /*
963   * glGetIntegerv (GL_VIEWPORT, viewport);
964   * glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
965   * glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
966   */
967
968   status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
969     &objx, &objy, &objz);
970
971   if (status == GL_TRUE) {
972     *x = ( Tfloat )objx;
973     *y = ( Tfloat )objy;
974     *z = ( Tfloat )objz;
975
976     return TSuccess;
977   }
978   else {
979     *x = 0.0F;
980     *y = 0.0F;
981     *z = 0.0F;
982
983     return TFailure;
984   }
985 }
986
987 /*----------------------------------------------------------------------*/
988 TStatus
989 TelUnProjectionRasterWithRay(Tint ws, Tint xr, Tint yr, Tfloat *x, Tfloat *y, Tfloat *z,
990                              Tfloat *dx, Tfloat *dy, Tfloat *dz)
991 {
992   Tint w, h;
993   CMN_KEY_DATA key;
994   Tint vid;          /* View index */
995   TEL_VIEW_REP vrep; /* View definition */
996
997   int i, j, k;
998   GLdouble objx, objy, objz;
999   GLdouble objx1, objy1, objz1;
1000   GLdouble modelMatrix[16], projMatrix[16];
1001   GLint viewport[4];
1002   GLdouble winx, winy, winz;
1003   GLint status;
1004
1005   vid = ws;
1006
1007   if (TelGetViewRepresentation (ws, vid, &vrep) != TSuccess)
1008     return TFailure;
1009
1010   TsmGetWSAttri (ws, WSWidth, &key);
1011   w = key.ldata;
1012   TsmGetWSAttri (ws, WSHeight, &key);
1013   h = key.ldata;
1014
1015   winx = ( GLdouble )xr; winy = ( GLdouble )yr; winz = ( GLdouble )0.0;
1016
1017   for (k = 0, i = 0; i < 4; i++)
1018     for (j = 0; j < 4; j++, k++)
1019       modelMatrix[k] = ( GLdouble )vrep.orientation_matrix[i][j];
1020
1021   for (k = 0, i = 0; i < 4; i++)
1022     for (j = 0; j < 4; j++, k++)
1023       projMatrix[k] = ( GLdouble )vrep.mapping_matrix[i][j];
1024
1025   viewport[0] = 0;
1026   viewport[1] = 0;
1027   viewport[2] = w;
1028   viewport[3] = h;
1029
1030   /*
1031   * glGetIntegerv (GL_VIEWPORT, viewport);
1032   * glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
1033   * glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
1034   */
1035
1036   status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
1037     &objx, &objy, &objz);
1038
1039   if (status == GL_TRUE) {
1040     *x = ( Tfloat )objx;
1041     *y = ( Tfloat )objy;
1042     *z = ( Tfloat )objz;
1043
1044     winz = ( GLdouble ) -10.0;
1045     status = gluUnProject (winx, winy, winz, modelMatrix, projMatrix, viewport,
1046       &objx1, &objy1, &objz1);
1047
1048     if (status == GL_TRUE) {
1049       *dx = ( Tfloat )(objx-objx1);
1050       *dy = ( Tfloat )(objy-objy1);
1051       *dz = ( Tfloat )(objz-objz1);
1052
1053       return TSuccess;
1054     }
1055     else {
1056       *dx = 0.0F;
1057       *dy = 0.0F;
1058       *dz = 0.0F;
1059
1060       return TFailure;
1061     }
1062   }
1063   else {
1064     *x = 0.0F;
1065     *y = 0.0F;
1066     *z = 0.0F;
1067     *dx = 0.0F;
1068     *dy = 0.0F;
1069     *dz = 0.0F;
1070
1071     return TFailure;
1072   }
1073 }
1074
1075 /*----------------------------------------------------------------------*/
1076 void
1077 TelFlush(Tint wait)
1078 {
1079   if (wait)
1080   {    
1081 #ifdef TRACE
1082     printf("OPENGL: TelFlush: glFinish \n");
1083 #endif
1084     glFinish ();
1085   }
1086   else
1087   {
1088 #ifdef TRACE
1089     printf("OPENGL: TelFlush: glFlush \n");
1090 #endif
1091     glFlush();
1092   }
1093   return;
1094 }
1095
1096 /*----------------------------------------------------------------------*/
1097 Tint
1098 TelIsBackFacePerspective(Tmatrix3 n, Tfloat *p1, Tfloat *p2, Tfloat *p3 )
1099 {
1100   Tfloat    r1[4], r2[4], r3[4], m[4], norm[4];
1101
1102   veccpy( m, p1 );
1103   m[3] = ( float )1.0;
1104   TelTranpt3( r1, m, n );
1105   r1[0] /= r1[3];
1106   r1[1] /= r1[3];
1107   r1[2] /= r1[3];
1108
1109   veccpy( m, p2 );
1110   m[3] = ( float )1.0;
1111   TelTranpt3( r2, m, n );
1112   r2[0] /= r2[3];
1113   r2[1] /= r2[3];
1114   r2[2] /= r2[3];
1115
1116   veccpy( m, p3 );
1117   m[3] = ( float )1.0;
1118   TelTranpt3( r3, m, n );
1119   r3[0] /= r3[3];
1120   r3[1] /= r3[3];
1121   r3[2] /= r3[3];
1122   TelGetNormal( r1, r2, r3, norm );
1123
1124   return norm[2] < 0.0;
1125 }
1126
1127 /*----------------------------------------------------------------------*/