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