0022819: Redesign of OpenGl driver
[occt.git] / src / OpenGl / OpenGl_View_2.cxx
CommitLineData
2166f0fa
SK
1// File: OpenGl_View_2.cxx
2// Created: 20 September 2011
3// Author: Sergey ZERCHANINOV
4// Copyright: OPEN CASCADE 2011
5
6#define G003 /* EUG 20-09-99 ; Animation management
7*/
8
9/*----------------------------------------------------------------------*/
10/*
11* Includes
12*/
13
14#include <stdio.h>
15#include <stdlib.h>
16
17#include <OpenGl_tgl_all.hxx>
18#include <OpenGl_tgl_funcs.hxx>
19#include <OpenGl_TextureBox.hxx>
20
21#include <AlienImage.hxx>
22#include <Image_Image.hxx>
23#include <Visual3d_Layer.hxx>
24
25#if defined(WNT)
26#include <GL/glu.h>
27#endif
28
29#include <OpenGl_AspectLine.hxx>
30#include <OpenGl_Display.hxx>
31#include <OpenGl_Workspace.hxx>
32#include <OpenGl_View.hxx>
33#include <OpenGl_Trihedron.hxx>
34#include <OpenGl_GraduatedTrihedron.hxx>
35#include <OpenGl_PrinterContext.hxx>
36
37/*----------------------------------------------------------------------*/
38/*
39* Constantes
40*/
41
42#define EPSI 0.0001
43
44#ifndef M_PI
45# define M_PI 3.14159265358979323846
46#endif
47
48static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F };
49static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
50static const GLfloat default_sptexpo = 0.F;
51static const GLfloat default_sptcutoff = 180.F;
52
53extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
54
55/*----------------------------------------------------------------------*/
56
57struct OPENGL_CLIP_PLANE
58{
59 GLboolean isEnabled;
60 GLdouble Equation[4];
61 IMPLEMENT_MEMORY_OPERATORS
62};
63
64/*----------------------------------------------------------------------*/
65/*
66* Fonctions privees
67*/
68
69/*-----------------------------------------------------------------*/
70/*
71* Set des lumieres
72*/
73static void bind_light(const OpenGl_Light *lptr, int *gl_lid)
74{
75 // Only 8 lights in OpenGL...
76 if (*gl_lid > GL_LIGHT7) return;
77
78 // the light is a headlight ?
79 GLint cur_matrix;
80 if (lptr->HeadLight)
81 {
82 glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
83 glMatrixMode(GL_MODELVIEW);
84 glPushMatrix();
85 glLoadIdentity();
86 }
87
88 GLfloat data_amb[4];
89 GLfloat data_diffu[4];
90 GLfloat data_pos[4];
91 GLfloat data_sptdir[3];
92 GLfloat data_sptexpo;
93 GLfloat data_sptcutoff;
94 GLfloat data_constantattenuation;
95 GLfloat data_linearattenuation;
96
97 /* set la light en fonction de son type */
98 switch (lptr->type)
99 {
100 case TLightAmbient:
101 data_amb[0] = lptr->col.rgb[0];
102 data_amb[1] = lptr->col.rgb[1];
103 data_amb[2] = lptr->col.rgb[2];
104 data_amb[3] = 1.0;
105
106 /*------------------------- Ambient ---------------------------*/
107 /*
108 * The GL_AMBIENT parameter refers to RGBA intensity of the ambient
109 * light.
110 */
111 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb);
112 break;
113
114
115 case TLightDirectional:
116 data_diffu[0] = lptr->col.rgb[0];
117 data_diffu[1] = lptr->col.rgb[1];
118 data_diffu[2] = lptr->col.rgb[2];
119 data_diffu[3] = 1.0;
120
121 /*------------------------- Direction ---------------------------*/
122 /* From Open GL Programming Rev 1 Guide Chapt 6 :
123 Lighting The Mathematics of Lighting ( p 168 )
124
125 Directional Light Source ( Infinite ) :
126 if the last parameter of GL_POSITION , w , is zero, the
127 corresponding light source is a Directional one.
128
129 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
130 To create a realistic effect, set the GL_SPECULAR parameter
131 to the same value as the GL_DIFFUSE.
132 */
133
134 data_pos[0] = -lptr->dir[0];
135 data_pos[1] = -lptr->dir[1];
136 data_pos[2] = -lptr->dir[2];
137 data_pos[3] = 0.0;
138
139 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
140 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
141 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
142
143 glLightfv(*gl_lid, GL_POSITION, data_pos);
144 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
145 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
146 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
147 break;
148
149
150 case TLightPositional:
151 data_diffu[0] = lptr->col.rgb[0];
152 data_diffu[1] = lptr->col.rgb[1];
153 data_diffu[2] = lptr->col.rgb[2];
154 data_diffu[3] = 1.0;
155
156 /*------------------------- Position -----------------------------*/
157 /* From Open GL Programming Rev 1 Guide Chapt 6 :
158 Lighting The Mathematics of Lighting ( p 168 )
159 Positional Light Source :
160 if the last parameter of GL_POSITION , w , is nonzero,
161 the corresponding light source is a Positional one.
162
163 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
164
165 To create a realistic effect, set the GL_SPECULAR parameter
166 to the same value as the GL_DIFFUSE.
167 */
168
169 data_pos[0] = lptr->pos[0];
170 data_pos[1] = lptr->pos[1];
171 data_pos[2] = lptr->pos[2];
172 data_pos[3] = 1.0;
173
174 data_constantattenuation = lptr->atten[0];
175 data_linearattenuation = lptr->atten[1];
176
177 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
178 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
179 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
180
181 glLightfv(*gl_lid, GL_POSITION, data_pos);
182 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
183 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
184 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
185 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
186 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
187 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
188 break;
189
190
191 case TLightSpot:
192 data_diffu[0] = lptr->col.rgb[0];
193 data_diffu[1] = lptr->col.rgb[1];
194 data_diffu[2] = lptr->col.rgb[2];
195 data_diffu[3] = 1.0;
196
197 data_pos[0] = lptr->pos[0];
198 data_pos[1] = lptr->pos[1];
199 data_pos[2] = lptr->pos[2];
200 data_pos[3] = 1.0;
201
202 data_sptdir[0] = lptr->dir[0];
203 data_sptdir[1] = lptr->dir[1];
204 data_sptdir[2] = lptr->dir[2];
205
206 data_sptexpo = ( float )lptr->shine * 128.0F;
207 data_sptcutoff = ( float )(lptr->angle * 180.0F)/( float )M_PI;
208
209 data_constantattenuation = lptr->atten[0];
210 data_linearattenuation = lptr->atten[1];
211
212 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
213 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
214 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
215
216 glLightfv(*gl_lid, GL_POSITION, data_pos);
217 glLightfv(*gl_lid, GL_SPOT_DIRECTION, data_sptdir);
218 glLightf(*gl_lid, GL_SPOT_EXPONENT, data_sptexpo);
219 glLightf(*gl_lid, GL_SPOT_CUTOFF, data_sptcutoff);
220 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
221 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
222 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
223 break;
224 }
225
226 if (lptr->type != TLightAmbient)
227 {
228 glEnable(*gl_lid);
229 (*gl_lid)++;
230 }
231
232 /* si la light etait une headlight alors restaure la matrice precedente */
233 if (lptr->HeadLight)
234 {
235 glPopMatrix();
236 glMatrixMode(cur_matrix);
237 }
238}
239
240/*----------------------------------------------------------------------*/
241/*
242* Prototypes
243*/
244
245static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
246 float *ox, float *oy, float *oz );
247static void call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c);
248
249/*----------------------------------------------------------------------*/
250/*
251* Fonctions externes
252*/
253
254/*
255* Evaluates orientation matrix.
256*/
257/* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
258void call_func_eval_ori_matrix3 (const point3* vrp, // view reference point
259 const vec3* vpn, // view plane normal
260 const vec3* vup, // view up vector
261 int* err_ind,
262 float mout[4][4]) // OUT view orientation matrix
263{
264
265 /* Translate to VRP then change the basis.
266 * The old basis is: e1 = < 1, 0, 0>, e2 = < 0, 1, 0>, e3 = < 0, 0, 1>.
267 * The new basis is: ("x" means cross product)
268 * e3' = VPN / |VPN|
269 * e1' = VUP x VPN / |VUP x VPN|
270 * e2' = e3' x e1'
271 * Therefore the transform from old to new is x' = TAx, where:
272 *
273 * | e1'x e2'x e3'x 0 | | 1 0 0 0 |
274 * A = | e1'y e2'y e3'y 0 |, T = | 0 1 0 0 |
275 * | e1'z e2'z e3'z 0 | | 0 0 1 0 |
276 * | 0 0 0 1 | | -vrp.x -vrp.y -vrp.z 1 |
277 *
278 */
279
280 /*
281 * These ei's are really ei primes.
282 */
283 register float (*m)[4][4];
284 point3 e1, e2, e3, e4;
285 double s, v;
286
287 /*
288 * e1' = VUP x VPN / |VUP x VPN|, but do the division later.
289 */
290 e1.x = vup->delta_y * vpn->delta_z - vup->delta_z * vpn->delta_y;
291 e1.y = vup->delta_z * vpn->delta_x - vup->delta_x * vpn->delta_z;
292 e1.z = vup->delta_x * vpn->delta_y - vup->delta_y * vpn->delta_x;
293 s = sqrt( e1.x * e1.x + e1.y * e1.y + e1.z * e1.z);
294 e3.x = vpn->delta_x;
295 e3.y = vpn->delta_y;
296 e3.z = vpn->delta_z;
297 v = sqrt( e3.x * e3.x + e3.y * e3.y + e3.z * e3.z);
298 /*
299 * Check for vup and vpn colinear (zero dot product).
300 */
301 if ((s > -EPSI) && (s < EPSI))
302 *err_ind = 2;
303 else
304 /*
305 * Check for a normal vector not null.
306 */
307 if ((v > -EPSI) && (v < EPSI))
308 *err_ind = 3;
309 else {
310 /*
311 * Normalize e1
312 */
313 e1.x /= ( float )s;
314 e1.y /= ( float )s;
315 e1.z /= ( float )s;
316 /*
317 * e3 = VPN / |VPN|
318 */
319 e3.x /= ( float )v;
320 e3.y /= ( float )v;
321 e3.z /= ( float )v;
322 /*
323 * e2 = e3 x e1
324 */
325 e2.x = e3.y * e1.z - e3.z * e1.y;
326 e2.y = e3.z * e1.x - e3.x * e1.z;
327 e2.z = e3.x * e1.y - e3.y * e1.x;
328 /*
329 * Add the translation
330 */
331 e4.x = -( e1.x * vrp->x + e1.y * vrp->y + e1.z * vrp->z);
332 e4.y = -( e2.x * vrp->x + e2.y * vrp->y + e2.z * vrp->z);
333 e4.z = -( e3.x * vrp->x + e3.y * vrp->y + e3.z * vrp->z);
334 /*
335 * Homogeneous entries
336 *
337 * | e1.x e2.x e3.x 0.0 | | 1 0 0 0 |
338 * | e1.y e2.y e3.y 0.0 | * | 0 1 0 0 |
339 * | e1.z e2.z e3.z 0.0 | | a b 1 c |
340 * | e4.x e4.y e4.z 1.0 | | 0 0 0 1 |
341 */
342
343 m = (float (*)[4][4])mout;
344
345 (*m)[0][0] = e1.x;
346 (*m)[0][1] = e2.x;
347 (*m)[0][2] = e3.x;
348 (*m)[0][3] = ( float )0.0;
349
350 (*m)[1][0] = e1.y;
351 (*m)[1][1] = e2.y;
352 (*m)[1][2] = e3.y;
353 (*m)[1][3] = ( float )0.0;
354
355 (*m)[2][0] = e1.z;
356 (*m)[2][1] = e2.z;
357 (*m)[2][2] = e3.z;
358 (*m)[2][3] = ( float )0.0;
359
360 (*m)[3][0] = e4.x;
361 (*m)[3][1] = e4.y;
362 (*m)[3][2] = e4.z;
363 (*m)[3][3] = ( float )1.0;
364
365 *err_ind = 0;
366 }
367}
368
369/*----------------------------------------------------------------------*/
370/*
371* Evaluates mapping matrix.
372*/
373/* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
374void call_func_eval_map_matrix3(
375 view_map3 *Map,
376 int *err_ind,
377 matrix3 mat)
378{
379 int i, j;
380 matrix3 Tpar, Spar;
381 matrix3 Tper, Sper;
382 matrix3 Shear;
383 matrix3 Scale;
384 matrix3 Tprp;
385 matrix3 aux_mat1, aux_mat2, aux_mat3;
386 point3 Prp;
387
388 *err_ind = 0;
389 for (i=0; i<4; i++)
390 for (j=0; j<4; j++)
391 Spar[i][j] = Sper[i][j] = aux_mat1[i][j] = aux_mat2[i][j] =
392 aux_mat3[i][j] = Tper[i][j] = Tpar[i][j] = Tprp[i][j] =
393 Shear[i][j] = Scale[i][j] = ( float )(i == j);
394
395 Prp.x = Map->proj_ref_point.x;
396 Prp.y = Map->proj_ref_point.y;
397 Prp.z = Map->proj_ref_point.z;
398
399 /*
400 * Type Parallele
401 */
402 if (Map->proj_type == TYPE_PARAL)
403 {
404 float umid, vmid;
405 point3 temp;
406
407#ifdef FMN
408 float cx, cy, gx, gy, xsf, ysf, zsf;
409 float fpd, bpd;
410 float dopx, dopy, dopz;
411 matrix3 tmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
412 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
413 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
414 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
415 matrix3 smat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
416 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
417 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
418 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
419 matrix3 shmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
420 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
421 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
422 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
423 matrix3 tshmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
424 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
425 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
426 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
427
428 /* centers */
429 cx = Map->win.x_min + Map->win.x_max, cx /= ( float )2.0;
430 cy = Map->win.y_min + Map->win.y_max, cy /= ( float )2.0;
431
432 gx = 2.0/ (Map->win.x_max - Map->win.x_min);
433 gy = 2.0/ (Map->win.y_max - Map->win.y_min);
434
435 tmat[0][3] = -cx;
436 tmat[1][3] = -cy;
437 tmat[2][3] = (Map->front_plane + Map->back_plane)/(Map->front_plane - Map->back_plane);
438
439 smat[0][0] = gx;
440 smat[1][1] = gy;
441 smat[2][2] = -2./(Map->front_plane - Map->back_plane);
442
443 /* scale factors */
444 dopx = cx - Prp.x;
445 dopy = cy - Prp.y;
446 dopz = - Prp.z;
447
448 /* map matrix */
449 shmat[0][2] = -(dopx/dopz);
450 shmat[1][2] = -(dopy/dopz);
451
452 /* multiply to obtain mapping matrix */
453 call_util_mat_mul( tmat, shmat, tshmat );
454 call_util_mat_mul( smat, tshmat, mat );
455
456 return;
457#endif
458
459 /* CAL */
460 Map->proj_vp.z_min = ( float )0.0;
461 Map->proj_vp.z_max = ( float )1.0;
462 /* CAL */
463
464 /* Shear matrix calculation */
465 umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0;
466 vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0;
467 if(Prp.z == Map->view_plane){
468 /* Projection reference point is on the view plane */
469 *err_ind = 1;
470 return;
471 }
472 Shear[2][0] = ( float )(-1.0) * ((Prp.x-umid)/(Prp.z-Map->view_plane));
473 Shear[2][1] = ( float )(-1.0) * ((Prp.y-vmid)/(Prp.z-Map->view_plane));
474
475 /*
476 * Calculate the lower left coordinate of the view plane
477 * after the Shearing Transformation.
478 */
479 call_util_apply_trans2(Map->win.x_min, Map->win.y_min,
480 Map->view_plane, Shear, &(temp.x), &(temp.y), &(temp.z));
481
482 /* Translate the back plane to the origin */
483 Tpar[3][0] = ( float )(-1.0) * temp.x;
484 Tpar[3][1] = ( float )(-1.0) * temp.y;
485 Tpar[3][2] = ( float )(-1.0) * Map->back_plane;
486
487 call_util_mat_mul(Shear, Tpar, aux_mat1);
488
489 /* Calculation of Scaling transformation */
490 Spar[0][0] = ( float )1.0 / (Map->win.x_max - Map->win.x_min);
491 Spar[1][1] = ( float )1.0 / (Map->win.y_max - Map->win.y_min);
492 Spar[2][2] = ( float )1.0 / (Map->front_plane - Map->back_plane );
493 call_util_mat_mul (aux_mat1, Spar, aux_mat2);
494 /* Atlast we transformed view volume to NPC */
495
496 /* Translate and scale the view plane to projection view port */
497 if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
498 Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
499 Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
500 Map->proj_vp.x_min > Map->proj_vp.x_max ||
501 Map->proj_vp.y_min > Map->proj_vp.y_max ||
502 Map->proj_vp.z_min > Map->proj_vp.z_max){
503 *err_ind = 1;
504 return;
505 }
506 for(i=0; i<4; i++)
507 for(j=0; j<4; j++)
508 aux_mat1[i][j] = (float)(i==j);
509 aux_mat1[0][0] = Map->proj_vp.x_max-Map->proj_vp.x_min;
510 aux_mat1[1][1] = Map->proj_vp.y_max-Map->proj_vp.y_min;
511 aux_mat1[2][2] = Map->proj_vp.z_max-Map->proj_vp.z_min;
512 aux_mat1[3][0] = Map->proj_vp.x_min;
513 aux_mat1[3][1] = Map->proj_vp.y_min;
514 aux_mat1[3][2] = Map->proj_vp.z_min;
515 call_util_mat_mul (aux_mat2, aux_mat1, mat);
516
517 return;
518 }
519
520 /*
521 * Type Perspective
522 */
523 else if (Map->proj_type == TYPE_PERSPECT)
524 {
525 float umid, vmid;
526 float B, F, V;
527 float Zvmin;
528
529 /* CAL */
530 Map->proj_vp.z_min = ( float )0.0;
531 Map->proj_vp.z_max = ( float )1.0;
532 /* CAL */
533
534 B = Map->back_plane;
535 F = Map->front_plane;
536 V = Map->view_plane;
537
538 if(Prp.z == Map->view_plane){
539 /* Centre of Projection is on the view plane */
540 *err_ind = 1;
541 return;
542 }
543 if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
544 Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
545 Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
546 Map->proj_vp.x_min > Map->proj_vp.x_max ||
547 Map->proj_vp.y_min > Map->proj_vp.y_max ||
548 Map->proj_vp.z_min > Map->proj_vp.z_max ||
549 F < B){
550 *err_ind = 1;
551 return;
552 }
553
554 /* This is the transformation to move VRC to Center Of Projection */
555 Tprp[3][0] = ( float )(-1.0)*Prp.x;
556 Tprp[3][1] = ( float )(-1.0)*Prp.y;
557 Tprp[3][2] = ( float )(-1.0)*Prp.z;
558
559 /* Calculation of Shear matrix */
560 umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0-Prp.x;
561 vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0-Prp.y;
562 Shear[2][0] = ( float )(-1.0)*umid/(Map->view_plane-Prp.z);
563 Shear[2][1] = ( float )(-1.0)*vmid/(Map->view_plane-Prp.z);
564 call_util_mat_mul(Tprp, Shear, aux_mat3);
565
566 /* Scale the view volume to canonical view volume
567 * Centre of projection at origin.
568 * 0 <= N <= -1, -0.5 <= U <= 0.5, -0.5 <= V <= 0.5
569 */
570 Scale[0][0] = (( float )(-1.0)*Prp.z+V)/
571 ((Map->win.x_max-Map->win.x_min)*(( float )(-1.0)*Prp.z+B));
572 Scale[1][1] = (( float )(-1.0)*Prp.z+V)/
573 ((Map->win.y_max-Map->win.y_min)*(( float )(-1.0)*Prp.z+B));
574 Scale[2][2] = ( float )(-1.0) / (( float )(-1.0)*Prp.z+B);
575
576 call_util_mat_mul(aux_mat3, Scale, aux_mat1);
577
578 /*
579 * Transform the Perspective view volume into
580 * Parallel view volume.
581 * Lower left coordinate: (-0.5,-0.5, -1)
582 * Upper right coordinate: (0.5, 0.5, 1.0)
583 */
584 Zvmin = ( float )(-1.0*(-1.0*Prp.z+F)/(-1.0*Prp.z+B));
585 aux_mat2[2][2] = ( float )1.0/(( float )1.0+Zvmin);
586 aux_mat2[2][3] = ( float )(-1.0);
587 aux_mat2[3][2] = ( float )(-1.0)*Zvmin*aux_mat2[2][2];
588 aux_mat2[3][3] = ( float )0.0;
589 call_util_mat_mul(aux_mat1, aux_mat2, Shear);
590
591 for(i=0; i<4; i++)
592 for(j=0; j<4; j++)
593 aux_mat1[i][j] = aux_mat2[i][j] = (float)(i==j);
594
595 /* Translate and scale the view plane to projection view port */
596 aux_mat2[0][0] = (Map->proj_vp.x_max-Map->proj_vp.x_min);
597 aux_mat2[1][1] = (Map->proj_vp.y_max-Map->proj_vp.y_min);
598 aux_mat2[2][2] = (Map->proj_vp.z_max-Map->proj_vp.z_min);
599 aux_mat2[3][0] = aux_mat2[0][0]/( float )2.0+Map->proj_vp.x_min;
600 aux_mat2[3][1] = aux_mat2[1][1]/( float )2.0+Map->proj_vp.y_min;
601 aux_mat2[3][2] = aux_mat2[2][2]+Map->proj_vp.z_min;
602 call_util_mat_mul (Shear, aux_mat2, mat);
603
604 return;
605 }
606 else
607 *err_ind = 1;
608}
609
610/*----------------------------------------------------------------------*/
611
612static void
613call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
614 float *ox, float *oy, float *oz )
615{
616 float temp;
617 *ox = ix*mat[0][0]+iy*mat[1][0]+iz*mat[2][0]+mat[3][0];
618 *oy = ix*mat[0][1]+iy*mat[1][1]+iz*mat[2][1]+mat[3][1];
619 *oz = ix*mat[0][2]+iy*mat[1][2]+iz*mat[2][2]+mat[3][2];
620 temp = ix * mat[0][3]+iy * mat[1][3]+iz * mat[2][3]+mat[3][3];
621 *ox /= temp;
622 *oy /= temp;
623 *oz /= temp;
624}
625
626/*----------------------------------------------------------------------*/
627
628static void
629call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
630{
631 int i, j, k;
632
633 for (i=0; i<4; i++)
634 for (j=0; j<4; j++)
635 for (mat_c[i][j] = ( float )0.0,k=0; k<4; k++)
636 mat_c[i][j] += mat_a[i][k] * mat_b[k][j];
637}
638
639/*----------------------------------------------------------------------*/
640
641//call_func_redraw_all_structs_proc
642void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
643 const Graphic3d_CView& ACView,
644 const Aspect_CLayer2d& ACUnderLayer,
645 const Aspect_CLayer2d& ACOverLayer)
646{
647 // Reset FLIST status after modification of myBackfacing
648 if (myResetFLIST)
649 {
650 AWorkspace->NamedStatus &= ~OPENGL_NS_FLIST;
651 myResetFLIST = Standard_False;
652 }
653
654 // Store and disable current clipping planes
655 GLint maxplanes;
656 glGetIntegerv(GL_MAX_CLIP_PLANES, &maxplanes);
657 const GLenum lastid = GL_CLIP_PLANE0 + maxplanes;
658 OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[maxplanes];
659 OPENGL_CLIP_PLANE *ptrPlane = oldPlanes;
660 GLenum planeid = GL_CLIP_PLANE0;
661 for ( ; planeid < lastid; planeid++, ptrPlane++ )
662 {
663 glGetClipPlane( planeid, ptrPlane->Equation );
664 if ( ptrPlane->isEnabled )
665 {
666 glDisable( planeid );
667 ptrPlane->isEnabled = GL_TRUE;
668 }
669 else
670 ptrPlane->isEnabled = GL_FALSE;
671 }
672
673 /////////////////////////////////////////////////////////////////////////////
674 // Step 1: Prepare for redraw
675
676 // Render background
677 if ( (AWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
678 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
679 {
680 const Standard_Integer aViewWidth = AWorkspace->Width();
681 const Standard_Integer aViewHeight = AWorkspace->Height();
682
683 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
684
685 glMatrixMode( GL_PROJECTION );
686 glPushMatrix();
687 glLoadIdentity();
688 glMatrixMode( GL_MODELVIEW );
689 glPushMatrix();
690 glLoadIdentity();
691
692 if ( glIsEnabled( GL_DEPTH_TEST ) )
693 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
694
695 // drawing bg image if defined
696 if ( myBgTexture.TexId != 0 )
697 {
698 GLfloat texX_range = 1.F; // texture <s> coordinate
699 GLfloat texY_range = 1.F; // texture <t> coordinate
700
701 // Set up for stretching or tiling
702 GLfloat x_offset, y_offset;
703 if ( myBgTexture.Style == Aspect_FM_CENTERED )
704 {
705 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
706 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
707 }
708 else
709 {
710 x_offset = 1.F;
711 y_offset = 1.F;
712 if ( myBgTexture.Style == Aspect_FM_TILED )
713 {
714 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
715 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
716 }
717 }
718
719 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
720 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
721
722 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
723
724 glColor3fv( AWorkspace->BackgroundColor().rgb );
725 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
726
727 glBegin( GL_QUADS );
728 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -y_offset );
729 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -y_offset );
730 glTexCoord2f(texX_range, texY_range); glVertex2f( x_offset, y_offset );
731 glTexCoord2f(0.F, texY_range); glVertex2f( -x_offset, y_offset );
732 glEnd();
733 }
734 else //if( myBgGradient.type != Aspect_GFM_NONE )
735 {
736 Tfloat* corner1 = 0;/* -1,-1*/
737 Tfloat* corner2 = 0;/* 1,-1*/
738 Tfloat* corner3 = 0;/* 1, 1*/
739 Tfloat* corner4 = 0;/* -1, 1*/
740 Tfloat dcorner1[3];
741 Tfloat dcorner2[3];
742
743 switch( myBgGradient.type )
744 {
745 case Aspect_GFM_HOR:
746 corner1 = myBgGradient.color2.rgb;
747 corner2 = myBgGradient.color2.rgb;
748 corner3 = myBgGradient.color1.rgb;
749 corner4 = myBgGradient.color1.rgb;
750 break;
751 case Aspect_GFM_VER:
752 corner1 = myBgGradient.color2.rgb;
753 corner2 = myBgGradient.color1.rgb;
754 corner3 = myBgGradient.color1.rgb;
755 corner4 = myBgGradient.color2.rgb;
756 break;
757 case Aspect_GFM_DIAG1:
758 corner2 = myBgGradient.color2.rgb;
759 corner4 = myBgGradient.color1.rgb;
760 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
761 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
762 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
763 corner1 = dcorner1;
764 corner3 = dcorner2;
765 break;
766 case Aspect_GFM_DIAG2:
767 corner1 = myBgGradient.color2.rgb;
768 corner3 = myBgGradient.color1.rgb;
769 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
770 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
771 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
772 corner2 = dcorner1;
773 corner4 = dcorner2;
774 break;
775 case Aspect_GFM_CORNER1:
776 corner1 = myBgGradient.color1.rgb;
777 corner2 = myBgGradient.color2.rgb;
778 corner3 = myBgGradient.color2.rgb;
779 corner4 = myBgGradient.color2.rgb;
780 break;
781 case Aspect_GFM_CORNER2:
782 corner1 = myBgGradient.color2.rgb;
783 corner2 = myBgGradient.color1.rgb;
784 corner3 = myBgGradient.color2.rgb;
785 corner4 = myBgGradient.color2.rgb;
786 break;
787 case Aspect_GFM_CORNER3:
788 corner1 = myBgGradient.color2.rgb;
789 corner2 = myBgGradient.color2.rgb;
790 corner3 = myBgGradient.color1.rgb;
791 corner4 = myBgGradient.color2.rgb;
792 break;
793 case Aspect_GFM_CORNER4:
794 corner1 = myBgGradient.color2.rgb;
795 corner2 = myBgGradient.color2.rgb;
796 corner3 = myBgGradient.color2.rgb;
797 corner4 = myBgGradient.color1.rgb;
798 break;
799 default:
800 //printf("gradient background type not right\n");
801 break;
802 }
803
804 // Save GL parameters
805 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
806
807 GLint curSM;
808 glGetIntegerv( GL_SHADE_MODEL, &curSM );
809 if ( curSM != GL_SMOOTH )
810 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
811
812 glBegin(GL_TRIANGLE_FAN);
813 if( myBgGradient.type != Aspect_GFM_CORNER2 && myBgGradient.type != Aspect_GFM_CORNER4 )
814 {
815 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
816 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
817 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
818 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
819 }
820 else //if ( myBgGradient.type == Aspect_GFM_CORNER2 || myBgGradient.type == Aspect_GFM_CORNER4 )
821 {
822 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
823 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
824 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
825 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
826 }
827 glEnd();
828
829 // Restore GL parameters
830 if ( curSM != GL_SMOOTH )
831 glShadeModel( curSM );
832 }
833
834 glPopMatrix();
835 glMatrixMode( GL_PROJECTION );
836 glPopMatrix();
837 glMatrixMode( GL_MODELVIEW );
838
839 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
840
841 if ( AWorkspace->UseZBuffer() )
842 glEnable( GL_DEPTH_TEST );
843
844 /* GL_DITHER on/off pour le trace */
845 if (AWorkspace->Dither())
846 glEnable (GL_DITHER);
847 else
848 glDisable (GL_DITHER);
849 }
850
851 // Switch off lighting by default
852 glDisable(GL_LIGHTING);
853
854 /////////////////////////////////////////////////////////////////////////////
855 // Step 2: Draw underlayer
856 RedrawLayer2d(AWorkspace, ACView, ACUnderLayer);
857
858 /////////////////////////////////////////////////////////////////////////////
859 // Step 3: Redraw main plane
860
861 // Setup face culling
862 GLboolean isCullFace = GL_FALSE;
863 if ( myBackfacing )
864 {
865 isCullFace = glIsEnabled( GL_CULL_FACE );
866 if ( myBackfacing < 0 )
867 {
868 glEnable( GL_CULL_FACE );
869 glCullFace( GL_BACK );
870 }
871 else
872 glDisable( GL_CULL_FACE );
873 }
874
875 //TsmPushAttri(); /* save previous graphics context */
876
877 // if the view is scaled normal vectors are scaled to unit length for correct displaying of shaded objects
878 if(myExtra.scaleFactors[0] != 1.F ||
879 myExtra.scaleFactors[1] != 1.F ||
880 myExtra.scaleFactors[2] != 1.F)
881 glEnable(GL_NORMALIZE);
882 else if(glIsEnabled(GL_NORMALIZE))
883 glDisable(GL_NORMALIZE);
884
885 // Apply View Projection
886 // This routine activates the Projection matrix for a view.
887
888 glMatrixMode( GL_PROJECTION );
889
890#ifdef WNT
891 // add printing scale/tiling transformation
892 OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext(AWorkspace->GetGContext());
893
894 if (aPrinterContext)
895 {
896 GLfloat aProjMatrix[16];
897 aPrinterContext->GetProjTransformation(aProjMatrix);
898 glLoadMatrixf((GLfloat*) aProjMatrix);
899 }
900 else
901#endif
902 glLoadIdentity();
903
904 glMultMatrixf( (const GLfloat *) myMappingMatrix );
905
906 // Add translation necessary for the environnement mapping
907 if (mySurfaceDetail != Visual3d_TOD_NONE)
908 {
909 // OCC280: FitAll work incorrect for perspective view if the SurfaceDetail mode is V3d_TEX_ENVIRONMENT or V3d_TEX_ALL
910 // const GLfloat dep = vptr->vrep.extra.map.fpd * 0.5F;
911 const GLfloat dep = (myExtra.map.fpd + myExtra.map.bpd) * 0.5F;
912 glTranslatef(-dep*myExtra.vpn[0],-dep*myExtra.vpn[1],-dep*myExtra.vpn[2]);
913 }
914
915 // Apply matrix
916 AWorkspace->SetViewMatrix((const OpenGl_Matrix *)myOrientationMatrix);
917
918/*
919While drawing after a clipplane has been defined and enabled, each vertex
920is transformed to eye-coordinates, where it is dotted with the transformed
921clipping plane equation. Eye-coordinate vertexes whose dot product with
922the transformed clipping plane equation is positive or zero are in, and
923require no clipping. Those eye-coordinate vertexes whose dot product is
924negative are clipped. Because clipplane clipping is done in eye-
925coordinates, changes to the projection matrix have no effect on its
926operation.
927
928A point and a normal are converted to a plane equation in the following manner:
929
930point = [Px,Py,Pz]
931
932normal = |Nx|
933|Ny|
934|Nz|
935
936plane equation = |A|
937|B|
938|C|
939|D|
940A = Nx
941B = Ny
942C = Nz
943D = -[Px,Py,Pz] dot |Nx|
944|Ny|
945|Nz|
946
947*/
948
949 glPushAttrib( GL_FOG_BIT | GL_LIGHTING_BIT );
950
951 // Apply Fog
952 if ( myFog.IsOn )
953 {
954 const GLfloat ramp = myExtra.map.fpd - myExtra.map.bpd;
955 const GLfloat fog_start = myFog.Front * ramp - myExtra.map.fpd;
956 const GLfloat fog_end = myFog.Back * ramp - myExtra.map.fpd;
957
958 glFogi(GL_FOG_MODE, GL_LINEAR);
959 glFogf(GL_FOG_START, fog_start);
960 glFogf(GL_FOG_END, fog_end);
961 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
962 glEnable(GL_FOG);
963 }
964 else
965 glDisable(GL_FOG);
966
967 // Apply Lights
968 {
969 int i;
970
971 // Switch off all lights
972 for (i = GL_LIGHT0; i <= GL_LIGHT7; i++)
973 glDisable(i);
974 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
975
976 /* set les lights */
977 int gl_lid = GL_LIGHT0;
978 OpenGl_ListOfLight::Iterator itl(myLights);
979 for (; itl.More(); itl.Next())
980 {
981 const OpenGl_Light &alight = itl.Value();
982 bind_light(&alight, &gl_lid);
983 }
984
985 if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING);
986 }
987
988 // Apply InteriorShadingMethod
989 glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
990
991 // Apply clipping planes
992 {
993 // Define starting plane id
994 planeid = GL_CLIP_PLANE0;
995
996 GLdouble equation[4];
997
998 if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
999 {
1000 // Apply front and back clipping planes
1001 GLfloat mat[4][4];
1002 glMatrixMode( GL_MODELVIEW );
1003 glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
1004 glLoadIdentity();
1005
1006 const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
1007
1008 if ( myZClip.Back.IsOn )
1009 {
1010 const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
1011 equation[0] = 0.0; /* Nx */
1012 equation[1] = 0.0; /* Ny */
1013 equation[2] = 1.0; /* Nz */
1014 equation[3] = -back; /* P dot N */
1015 glClipPlane( planeid, equation );
1016 glEnable( planeid );
1017 planeid++;
1018 }
1019
1020 if ( myZClip.Front.IsOn )
1021 {
1022 const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
1023 equation[0] = 0.0; /* Nx */
1024 equation[1] = 0.0; /* Ny */
1025 equation[2] = -1.0; /* Nz */
1026 equation[3] = front; /* P dot N */
1027 glClipPlane( planeid, equation );
1028 glEnable( planeid );
1029 planeid++;
1030 }
1031
1032 glLoadMatrixf( (GLfloat *) mat );
1033 }
1034
1035 // Apply user clipping planes
1036 NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
1037 for ( ; planeIter.More(); planeIter.Next() )
1038 {
1039 glClipPlane( planeid, planeIter.Value().equation );
1040 glEnable( planeid );
1041 planeid++;
1042 }
1043 }
1044
1045 // Apply AntiAliasing
1046 {
1047 if (myAntiAliasing)
1048 AWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
1049 else
1050 AWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
1051 }
1052
1053 Standard_Boolean isAnimationListOpen = Standard_False;
1054
1055 // Request for update of animation mode?
1056 if ( (AWorkspace->NamedStatus & OPENGL_NS_UPDATEAM) != 0 )
1057 {
1058 // Request to rebuild display list
1059 myAnimationListReady = Standard_False;
1060 // Reset request for update of animation mode
1061 AWorkspace->NamedStatus &= ~OPENGL_NS_UPDATEAM;
1062 }
1063
1064 // Is in animation mode?
1065 if ( AWorkspace->NamedStatus & OPENGL_NS_ANIMATION )
1066 {
1067 // Is the animation list ready?
1068 if (myAnimationListReady)
1069 {
1070 // Execute the animation list
1071 glCallList(myAnimationListIndex);
1072 }
1073 else
1074 {
1075 // Update the animation list
1076 if ( AWorkspace->NamedStatus & OPENGL_NS_FLIST )
1077 {
1078 if (myAnimationListIndex == 0)
1079 myAnimationListIndex = glGenLists(1);
1080
1081 if (myAnimationListIndex != 0)
1082 {
1083 glNewList(myAnimationListIndex, GL_COMPILE_AND_EXECUTE);
1084 isAnimationListOpen = Standard_True;
1085 }
1086 }
1087 else
1088 AWorkspace->NamedStatus |= OPENGL_NS_FLIST;
1089 }
1090 }
1091 else
1092 myAnimationListReady = Standard_False;
1093
1094 if (!myAnimationListReady)
1095 {
1096 // Clear status bitfields
1097 AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1098
1099 // Added PCT for handling of textures
1100 switch (mySurfaceDetail)
1101 {
1102 case Visual3d_TOD_NONE:
1103 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1104 DisableTexture();
1105 // Render the view
1106 RenderStructs(AWorkspace);
1107 break;
1108
1109 case Visual3d_TOD_ENVIRONMENT:
1110 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1111 SetCurrentTexture(myTextureEnv);
1112 EnableTexture();
1113 // Render the view
1114 RenderStructs(AWorkspace);
1115 DisableTexture();
1116 break;
1117
1118 case Visual3d_TOD_ALL:
1119 // First pass
1120 AWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1121 // Render the view
1122 RenderStructs(AWorkspace);
1123 DisableTexture();
1124
1125 // Second pass
1126 if (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1127 {
1128 AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1129 SetCurrentTexture(myTextureEnv);
1130 EnableTexture();
1131
1132 /* sauvegarde de quelques parametres OpenGL */
1133 GLint blend_dst, blend_src;
1134 GLint zbuff_f;
1135 GLboolean zbuff_w;
1136 glGetBooleanv(GL_DEPTH_WRITEMASK, &zbuff_w);
1137 glGetIntegerv(GL_DEPTH_FUNC, &zbuff_f);
1138 glGetIntegerv(GL_BLEND_DST, &blend_dst);
1139 glGetIntegerv(GL_BLEND_SRC, &blend_src);
1140 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1141 GLboolean blend_state = glIsEnabled(GL_BLEND);
1142
1143 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1144 glEnable(GL_BLEND);
1145
1146 glDepthFunc(GL_EQUAL);
1147 glDepthMask(GL_FALSE);
1148 glEnable(GL_DEPTH_TEST);
1149
1150 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1151
1152 // Render the view
1153 RenderStructs(AWorkspace);
1154 DisableTexture();
1155
1156 /* restauration des parametres OpenGL */
1157 glBlendFunc(blend_src, blend_dst);
1158 if (!blend_state) glDisable(GL_BLEND);
1159
1160 glDepthFunc(zbuff_f);
1161 glDepthMask(zbuff_w);
1162 if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
1163 }
1164 break;
1165 }
1166
1167 if (isAnimationListOpen)
1168 {
1169 glEndList();
1170 myAnimationListReady = Standard_True;
1171 }
1172 }
1173
1174 /* restore previous graphics context; before update lights */
1175 //TsmPopAttri();
1176
1177 // Disable current clipping planes
1178 for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
1179 glDisable( planeid );
1180
1181 /* affichage de Triedre Non Zoomable de la vue s'il existe */
1182 if (!myTrihedron.IsNull())
1183 myTrihedron->Render(AWorkspace);
1184 if (!myGraduatedTrihedron.IsNull())
1185 myGraduatedTrihedron->Render(AWorkspace);
1186
1187 glPopAttrib(); // GL_FOG_BIT | GL_LIGHTING_BIT
1188
1189 // Restore face culling
1190 if ( myBackfacing )
1191 {
1192 if ( isCullFace )
1193 {
1194 glEnable ( GL_CULL_FACE );
1195 glCullFace ( GL_BACK );
1196 }
1197 else
1198 glDisable ( GL_CULL_FACE );
1199 }
1200
1201 /////////////////////////////////////////////////////////////////////////////
1202 // Step 6: Draw overlayer
1203 // Redrawing to bitmap or window?
1204 const int amode = (AWorkspace->NamedStatus & OPENGL_NS_ISBITMAP)? OCC_REDRAW_BITMAP : OCC_REDRAW_WINDOW;
1205
1206 AWorkspace->DisplayCallback(ACView,(amode | OCC_PRE_OVERLAY));
1207
1208 RedrawLayer2d(AWorkspace, ACView, ACOverLayer);
1209
1210 AWorkspace->DisplayCallback(ACView,amode);
1211
1212 // Restore clipping planes
1213 for ( ptrPlane = oldPlanes, planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++, ptrPlane++ )
1214 {
1215 glClipPlane( planeid, ptrPlane->Equation );
1216 if ( ptrPlane->isEnabled )
1217 glEnable( planeid );
1218 else
1219 glDisable( planeid );
1220 }
1221 delete[] oldPlanes;
1222}
1223
1224/*----------------------------------------------------------------------*/
1225
1226//ExecuteViewDisplay
1227void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
1228{
1229 if ( myStructures.NbStructures() <= 0 ) return;
1230
1231 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
1232
1233 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine( Standard_True );
1234
1235 //TsmPushAttri(); /* save previous graphics context */
1236
1237 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
1238 {
1239 const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
1240
1241 if ( !myAntiAliasing )
1242 {
1243 glDisable(GL_POINT_SMOOTH);
1244 glDisable(GL_LINE_SMOOTH);
1245 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
1246 glBlendFunc (GL_ONE, GL_ZERO);
1247 glDisable (GL_BLEND);
1248 }
1249 else
1250 {
1251 glEnable(GL_POINT_SMOOTH);
1252 glEnable(GL_LINE_SMOOTH);
1253 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
1254 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1255 glEnable (GL_BLEND);
1256 }
1257 }
1258
1259 myStructures.Render(AWorkspace);
1260
1261 //TsmPopAttri(); /* restore previous graphics context; before update lights */
1262
1263 if ( AWorkspace->DegenerateModel > 1 )
1264 {
1265 glLineWidth ( aspect_line->Width() );
1266 if ( aspect_line->Type() != Aspect_TOL_SOLID ) glEnable ( GL_LINE_STIPPLE );
1267 }
1268
1269 glPopAttrib ();
1270}
1271
1272/*----------------------------------------------------------------------*/
1273
1274//call_togl_redraw_layer2d
1275void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer)
1276{
1277 if (&ACLayer == NULL
1278 || ACLayer.ptrLayer == NULL
1279 || ACLayer.ptrLayer->listIndex == 0) return;
1280
1281 GLsizei dispWidth, dispHeight;
1282 if ( ACView.DefBitmap.bitmap ) {
1283 dispWidth = ACView.DefBitmap.width;
1284 dispHeight = ACView.DefBitmap.height;
1285 }
1286 else {
1287 dispWidth = (GLsizei) ACLayer.viewport[0];
1288 dispHeight = (GLsizei) ACLayer.viewport[1];
1289 }
1290
1291 const GLboolean isl = glIsEnabled(GL_LIGHTING); /*OCC6247*/
1292 if (isl)
1293 glDisable(GL_LIGHTING); /*OCC6247*/
1294
1295 /*
1296 * On positionne la projection
1297 */
1298 glMatrixMode( GL_MODELVIEW );
1299 glPushMatrix ();
1300 glLoadIdentity ();
1301
1302 glMatrixMode (GL_PROJECTION);
1303 glPushMatrix ();
1304 glLoadIdentity ();
1305
1306 if (!ACLayer.sizeDependent)
1307 glViewport (0, 0, dispWidth, dispHeight);
1308
1309 float left = ACLayer.ortho[0];
1310 float right = ACLayer.ortho[1];
1311 float bottom = ACLayer.ortho[2];
1312 float top = ACLayer.ortho[3];
1313
1314 int attach = ACLayer.attach;
1315
1316 float ratio;
1317 if (!ACLayer.sizeDependent)
1318 ratio = (float) dispWidth/dispHeight;
1319 else
1320 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
1321
1322 float delta;
1323 if (ratio >= 1.0) { /* fenetre horizontale */
1324 delta = (float )((top - bottom)/2.0);
1325 switch (attach) {
1326 case 0: /* Aspect_TOC_BOTTOM_LEFT */
1327 top = bottom + 2*delta/ratio;
1328 break;
1329 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1330 top = bottom + 2*delta/ratio;
1331 break;
1332 case 2: /* Aspect_TOC_TOP_LEFT */
1333 bottom = top - 2*delta/ratio;
1334 break;
1335 case 3: /* Aspect_TOC_TOP_RIGHT */
1336 bottom = top - 2*delta/ratio;
1337 break;
1338 }
1339 }
1340 else { /* fenetre verticale */
1341 delta = (float )((right - left)/2.0);
1342 switch (attach) {
1343 case 0: /* Aspect_TOC_BOTTOM_LEFT */
1344 right = left + 2*delta*ratio;
1345 break;
1346 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1347 left = right - 2*delta*ratio;
1348 break;
1349 case 2: /* Aspect_TOC_TOP_LEFT */
1350 right = left + 2*delta*ratio;
1351 break;
1352 case 3: /* Aspect_TOC_TOP_RIGHT */
1353 left = right - 2*delta*ratio;
1354 break;
1355 }
1356 }
1357
1358#ifdef WNT
1359 // Check printer context that exists only for print operation
1360 OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext (AWorkspace->GetGContext());
1361
1362 if (aPrinterContext)
1363 {
1364 // additional transformation matrix could be applied to
1365 // render only those parts of viewport that will be
1366 // passed to a printer as a current "frame" to provide
1367 // tiling; scaling of graphics by matrix helps render a
1368 // part of a view (frame) in same viewport, but with higher
1369 // resolution
1370 GLfloat aProjMatrix[16];
1371 aPrinterContext->GetProjTransformation (aProjMatrix);
1372 glLoadMatrixf ((GLfloat*) aProjMatrix);
1373
1374 // printing operation also assumes other viewport dimension
1375 // to comply with transformation matrix or graphics scaling
1376 // factors for tiling for layer redraw
1377 GLsizei anViewportX = 0;
1378 GLsizei anViewportY = 0;
1379 aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
1380 if (anViewportX != 0 && anViewportY != 0)
1381 glViewport (0, 0, anViewportX, anViewportY);
1382 }
1383#endif
1384
1385 glOrtho (left, right, bottom, top, -1.0, 1.0);
1386
1387 /*
1388 * On trace la display-list associee au layer.
1389 */
1390 glPushAttrib (
1391 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
1392 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
1393 glDisable (GL_DEPTH_TEST);
1394 glCallList (ACLayer.ptrLayer->listIndex);
1395
1396 //calling dynamic render of LayerItems
1397 if ( ACLayer.ptrLayer->layerData )
1398 {
1399 InitLayerProp(ACLayer.ptrLayer->listIndex);
1400 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
1401 InitLayerProp(0);
1402 }
1403
1404 glPopAttrib ();
1405
1406 /*
1407 * On retire la projection
1408 */
1409 glMatrixMode (GL_PROJECTION);
1410 glPopMatrix ();
1411
1412 glMatrixMode( GL_MODELVIEW );
1413 glPopMatrix ();
1414
1415 /*
1416 * Restauration du Viewport en cas de modification
1417 */
1418 if (!ACLayer.sizeDependent)
1419 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
1420
1421 glFlush ();
1422
1423 if (isl)
1424 glEnable(GL_LIGHTING); /*OCC6247*/
1425}
1426
1427/*----------------------------------------------------------------------*/
1428
1429//call_togl_create_bg_texture
1430void OpenGl_View::CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle)
1431{
1432 // Delete existing texture
1433 if ( myBgTexture.TexId != 0 )
1434 {
1435 glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
1436 myBgTexture.TexId = 0;
1437 }
1438
1439 Standard_Integer width, height;
1440 Handle(Image_Image) image;
1441 if ( AlienImage::LoadImageFile( AFileName, image, width, height ) )
1442 {
1443 const int nbbytes = width * height * 3;
1444 GLubyte *data = new GLubyte[nbbytes];
1445 GLubyte *pdata = data;
1446 Standard_Integer i, j;
1447 for ( j = height - 1; j >= 0; j-- )
1448 for ( i = 0; i < width; i++ )
1449 {
1450 const Quantity_Color &color = image->PixelColor( i, j );
1451 *pdata++ = (GLubyte)( 255 * color.Red() );
1452 *pdata++ = (GLubyte)( 255 * color.Green() );
1453 *pdata++ = (GLubyte)( 255 * color.Blue() );
1454 }
1455
1456 GLuint texture = 0;
1457 glGenTextures( 1, &texture );
1458 glBindTexture( GL_TEXTURE_2D, texture );
1459
1460 /* Create MipMapped Texture */
1461 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1462 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1463 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1464 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1465
1466 gluBuild2DMipmaps( GL_TEXTURE_2D, 3/*4*/, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );
1467
1468 delete[] data;
1469
1470 myBgTexture.TexId = texture;
1471 myBgTexture.Width = width;
1472 myBgTexture.Height = height;
1473 switch ( AFillStyle )
1474 {
1475 case Aspect_FM_NONE :
1476 myBgTexture.Style = Aspect_FM_CENTERED;
1477 break;
1478 default :
1479 myBgTexture.Style = AFillStyle;
1480 break;
1481 }
1482 }
1483}
1484
1485/*----------------------------------------------------------------------*/
1486
1487//call_togl_set_bg_texture_style
1488void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
1489{
1490 /* check if background texture is already created */
1491 if ( myBgTexture.TexId != 0 )
1492 {
1493 switch ( AFillStyle )
1494 {
1495 case Aspect_FM_NONE :
1496 myBgTexture.Style = Aspect_FM_CENTERED;
1497 break;
1498 default :
1499 myBgTexture.Style = AFillStyle;
1500 break;
1501 }
1502 }
1503}
1504
1505/*----------------------------------------------------------------------*/
1506
1507//call_togl_gradient_background
1508void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
1509 const Quantity_Color& AColor2,
1510 const Aspect_GradientFillMethod AType)
1511{
1512 Standard_Real R,G,B;
1513 AColor1.Values( R, G, B, Quantity_TOC_RGB );
1514 myBgGradient.color1.rgb[0] = ( Tfloat )R;
1515 myBgGradient.color1.rgb[1] = ( Tfloat )G;
1516 myBgGradient.color1.rgb[2] = ( Tfloat )B;
1517 myBgGradient.color1.rgb[3] = 0.F;
1518
1519 AColor2.Values( R, G, B, Quantity_TOC_RGB );
1520 myBgGradient.color2.rgb[0] = ( Tfloat )R;
1521 myBgGradient.color2.rgb[1] = ( Tfloat )G;
1522 myBgGradient.color2.rgb[2] = ( Tfloat )B;
1523 myBgGradient.color2.rgb[3] = 0.F;
1524
1525 myBgGradient.type = AType;
1526}
1527
1528/*----------------------------------------------------------------------*/
1529
1530//call_togl_set_gradient_type
1531void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
1532{
1533 // check if gradient background is already created
1534 if ( myBgGradient.type != Aspect_GFM_NONE )
1535 myBgGradient.type = AType;
1536}
1537
1538/*----------------------------------------------------------------------*/