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