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