7fd59977 |
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 | /*----------------------------------------------------------------------*/ |