0023000: Improve the way the gradient and textured background is managed in 3d viewer
[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
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
48 static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F };
49 static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
50 static const GLfloat default_sptexpo = 0.F;
51 static const GLfloat default_sptcutoff = 180.F;
52
53 extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
54
55 /*----------------------------------------------------------------------*/
56
57 struct 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 */
73 static 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
245 static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
246                                    float *ox, float *oy, float *oz );
247 static 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! */
258 void 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! */
374 void 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
612 static void
613 call_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
628 static void
629 call_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
642 void 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 gradient if:
696     // - gradient fill type is not Aspect_GFM_NONE and
697     // - either background texture is no specified or it is drawn in Aspect_FM_CENTERED mode
698     if ( ( myBgGradient.type != Aspect_GFM_NONE ) &&
699          ( myBgTexture.TexId == 0 || myBgTexture.Style == Aspect_FM_CENTERED ||
700            myBgTexture.Style == Aspect_FM_NONE ) )
701     {
702       Tfloat* corner1 = 0;/* -1,-1*/
703       Tfloat* corner2 = 0;/*  1,-1*/
704       Tfloat* corner3 = 0;/*  1, 1*/
705       Tfloat* corner4 = 0;/* -1, 1*/
706       Tfloat dcorner1[3];
707       Tfloat dcorner2[3];
708
709       switch( myBgGradient.type )
710       {
711         case Aspect_GFM_HOR:
712           corner1 = myBgGradient.color1.rgb;
713           corner2 = myBgGradient.color2.rgb;
714           corner3 = myBgGradient.color2.rgb;
715           corner4 = myBgGradient.color1.rgb;
716           break;
717         case Aspect_GFM_VER:
718           corner1 = myBgGradient.color2.rgb;
719           corner2 = myBgGradient.color2.rgb;
720           corner3 = myBgGradient.color1.rgb;
721           corner4 = myBgGradient.color1.rgb;
722           break;
723         case Aspect_GFM_DIAG1:
724           corner2 = myBgGradient.color2.rgb;
725           corner4 = myBgGradient.color1.rgb;        
726           dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
727           dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
728           dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
729           corner1 = dcorner1;
730           corner3 = dcorner2;  
731           break;
732         case Aspect_GFM_DIAG2:
733           corner1 = myBgGradient.color2.rgb;  
734           corner3 = myBgGradient.color1.rgb;       
735           dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
736           dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
737           dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
738           corner2 = dcorner1;
739           corner4 = dcorner2;  
740           break;
741         case Aspect_GFM_CORNER1:
742           corner1 = myBgGradient.color2.rgb;
743           corner2 = myBgGradient.color2.rgb;
744           corner3 = myBgGradient.color2.rgb;
745           corner4 = myBgGradient.color1.rgb;
746           break;
747         case Aspect_GFM_CORNER2:
748           corner1 = myBgGradient.color2.rgb;
749           corner2 = myBgGradient.color2.rgb;
750           corner3 = myBgGradient.color1.rgb;
751           corner4 = myBgGradient.color2.rgb;
752           break;
753         case Aspect_GFM_CORNER3:
754           corner1 = myBgGradient.color2.rgb;
755           corner2 = myBgGradient.color1.rgb;
756           corner3 = myBgGradient.color2.rgb;
757           corner4 = myBgGradient.color2.rgb;
758           break;
759         case Aspect_GFM_CORNER4:
760           corner1 = myBgGradient.color1.rgb;
761           corner2 = myBgGradient.color2.rgb;
762           corner3 = myBgGradient.color2.rgb;
763           corner4 = myBgGradient.color2.rgb;
764           break;
765         default:
766           //printf("gradient background type not right\n");
767          break;
768       }
769
770       // Save GL parameters
771       glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
772
773       GLint curSM;
774       glGetIntegerv( GL_SHADE_MODEL, &curSM );
775       if ( curSM != GL_SMOOTH )
776         glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
777
778       glBegin(GL_TRIANGLE_FAN);
779       if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
780       {
781         glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
782         glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
783         glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
784         glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
785       }         
786       else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
787       {
788         glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
789         glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
790         glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
791         glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
792       }
793       glEnd();
794
795       // Restore GL parameters
796       if ( curSM != GL_SMOOTH )
797         glShadeModel( curSM );
798     }
799     // drawing bg image if:
800     // - it is defined and
801     // - fill type is not Aspect_FM_NONE
802     if ( myBgTexture.TexId != 0 && myBgTexture.Style != Aspect_FM_NONE )
803     {
804       GLfloat texX_range = 1.F; // texture <s> coordinate
805       GLfloat texY_range = 1.F; // texture <t> coordinate
806
807           // Set up for stretching or tiling
808       GLfloat x_offset, y_offset;
809       if ( myBgTexture.Style == Aspect_FM_CENTERED )
810       {
811         x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
812         y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
813       }
814       else
815       {
816         x_offset = 1.F;
817         y_offset = 1.F;
818         if ( myBgTexture.Style == Aspect_FM_TILED )
819         {
820           texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
821           texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
822         }
823       }
824
825       glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
826       glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
827
828       glDisable( GL_BLEND ); //push GL_ENABLE_BIT
829
830       glColor3fv( AWorkspace->BackgroundColor().rgb );
831       glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
832
833       glBegin( GL_QUADS );
834       glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -y_offset );
835       glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -y_offset );
836       glTexCoord2f(texX_range, texY_range); glVertex2f( x_offset, y_offset );
837       glTexCoord2f(0.F, texY_range); glVertex2f( -x_offset, y_offset );
838       glEnd();
839     }
840
841     glPopMatrix();
842     glMatrixMode( GL_PROJECTION );
843     glPopMatrix();
844     glMatrixMode( GL_MODELVIEW );
845
846     glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
847
848     if ( AWorkspace->UseZBuffer() )
849       glEnable( GL_DEPTH_TEST );
850
851     /* GL_DITHER on/off pour le trace */
852     if (AWorkspace->Dither())
853       glEnable (GL_DITHER);
854     else
855       glDisable (GL_DITHER);
856   }
857
858   // Switch off lighting by default
859   glDisable(GL_LIGHTING);
860
861   /////////////////////////////////////////////////////////////////////////////
862   // Step 2: Draw underlayer
863   RedrawLayer2d(AWorkspace, ACView, ACUnderLayer);
864
865   /////////////////////////////////////////////////////////////////////////////
866   // Step 3: Redraw main plane
867
868   // Setup face culling
869   GLboolean isCullFace = GL_FALSE;
870   if ( myBackfacing )
871   {
872     isCullFace = glIsEnabled( GL_CULL_FACE );
873     if ( myBackfacing < 0 )
874     {
875       glEnable( GL_CULL_FACE );
876       glCullFace( GL_BACK );
877     }
878         else
879       glDisable( GL_CULL_FACE );
880   }
881
882   //TsmPushAttri(); /* save previous graphics context */
883
884   // if the view is scaled normal vectors are scaled to unit length for correct displaying of shaded objects
885   if(myExtra.scaleFactors[0] != 1.F || 
886      myExtra.scaleFactors[1] != 1.F ||
887      myExtra.scaleFactors[2] != 1.F)
888     glEnable(GL_NORMALIZE);
889   else if(glIsEnabled(GL_NORMALIZE))  
890     glDisable(GL_NORMALIZE);
891
892   // Apply View Projection
893   // This routine activates the Projection matrix for a view.
894
895   glMatrixMode( GL_PROJECTION );
896
897 #ifdef WNT
898   // add printing scale/tiling transformation
899   OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext(AWorkspace->GetGContext());
900
901   if (aPrinterContext)
902   {
903     GLfloat aProjMatrix[16];
904     aPrinterContext->GetProjTransformation(aProjMatrix);
905     glLoadMatrixf((GLfloat*) aProjMatrix);
906   }
907   else
908 #endif
909     glLoadIdentity();
910
911   glMultMatrixf( (const GLfloat *) myMappingMatrix );
912
913   // Add translation necessary for the environnement mapping
914   if (mySurfaceDetail != Visual3d_TOD_NONE)
915   {
916     // OCC280: FitAll work incorrect for perspective view if the SurfaceDetail mode is V3d_TEX_ENVIRONMENT or V3d_TEX_ALL
917     // const GLfloat dep = vptr->vrep.extra.map.fpd * 0.5F;
918     const GLfloat dep = (myExtra.map.fpd + myExtra.map.bpd) * 0.5F;
919     glTranslatef(-dep*myExtra.vpn[0],-dep*myExtra.vpn[1],-dep*myExtra.vpn[2]);
920   }
921
922   // Apply matrix
923   AWorkspace->SetViewMatrix((const OpenGl_Matrix *)myOrientationMatrix);
924
925 /*
926 While drawing after a clipplane has been defined and enabled, each vertex
927 is transformed to eye-coordinates, where it is dotted with the transformed
928 clipping plane equation.  Eye-coordinate vertexes whose dot product with
929 the transformed clipping plane equation is positive or zero are in, and
930 require no clipping.  Those eye-coordinate vertexes whose dot product is
931 negative are clipped.  Because clipplane clipping is done in eye-
932 coordinates, changes to the projection matrix have no effect on its
933 operation.
934
935 A point and a normal are converted to a plane equation in the following manner:
936
937 point = [Px,Py,Pz]
938
939 normal = |Nx|
940 |Ny|
941 |Nz|
942
943 plane equation = |A|
944 |B|
945 |C|
946 |D|
947 A = Nx
948 B = Ny
949 C = Nz
950 D = -[Px,Py,Pz] dot |Nx|
951 |Ny|
952 |Nz|
953
954 */
955
956   glPushAttrib( GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT );
957
958   // Apply Fog
959   if ( myFog.IsOn )
960   {
961     const GLfloat ramp = myExtra.map.fpd - myExtra.map.bpd;
962     const GLfloat fog_start = myFog.Front * ramp - myExtra.map.fpd;
963     const GLfloat fog_end   = myFog.Back  * ramp - myExtra.map.fpd;
964
965     glFogi(GL_FOG_MODE, GL_LINEAR);
966     glFogf(GL_FOG_START, fog_start);
967     glFogf(GL_FOG_END, fog_end);
968     glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
969     glEnable(GL_FOG);
970   }
971   else
972     glDisable(GL_FOG);
973
974   // Apply Lights
975   {
976     int i;
977
978     // Switch off all lights
979     for (i = GL_LIGHT0; i <= GL_LIGHT7; i++)
980       glDisable(i);
981     glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
982
983     /* set les lights */
984     int gl_lid = GL_LIGHT0;
985     OpenGl_ListOfLight::Iterator itl(myLights);
986     for (; itl.More(); itl.Next())
987     {
988       const OpenGl_Light &alight = itl.Value();
989       bind_light(&alight, &gl_lid);
990     }
991
992     if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING);
993   }
994
995   // Apply InteriorShadingMethod
996   glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
997
998   // Apply clipping planes
999   {
1000     // Define starting plane id
1001     planeid = GL_CLIP_PLANE0;
1002
1003     GLdouble equation[4];
1004
1005     if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
1006     {
1007       // Apply front and back clipping planes
1008       GLfloat mat[4][4];
1009       glMatrixMode( GL_MODELVIEW );
1010       glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
1011       glLoadIdentity();
1012
1013       const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
1014
1015       if ( myZClip.Back.IsOn )
1016       {
1017         const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
1018         equation[0] = 0.0;  /* Nx */
1019         equation[1] = 0.0;  /* Ny */
1020         equation[2] = 1.0;  /* Nz */
1021         equation[3] = -back; /* P dot N */
1022         glClipPlane( planeid, equation );
1023         glEnable( planeid );
1024         planeid++;
1025       }
1026
1027       if ( myZClip.Front.IsOn )
1028       {
1029         const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
1030         equation[0] = 0.0;  /* Nx */
1031         equation[1] = 0.0;  /* Ny */
1032         equation[2] = -1.0; /* Nz */
1033         equation[3] = front; /* P dot N */
1034         glClipPlane( planeid, equation );
1035         glEnable( planeid );
1036         planeid++;
1037       }
1038
1039       glLoadMatrixf( (GLfloat *) mat );
1040     }
1041
1042     // Apply user clipping planes
1043     NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
1044     for ( ; planeIter.More(); planeIter.Next() )
1045     {
1046       glClipPlane( planeid, planeIter.Value().equation );
1047       glEnable( planeid );
1048       planeid++;
1049     }
1050   }
1051
1052   // Apply AntiAliasing
1053   {
1054     if (myAntiAliasing)
1055       AWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
1056         else
1057       AWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
1058   }
1059
1060   Standard_Boolean isAnimationListOpen = Standard_False;
1061
1062   // Request for update of animation mode?
1063   if ( (AWorkspace->NamedStatus & OPENGL_NS_UPDATEAM) != 0 )
1064   {
1065     // Request to rebuild display list
1066     myAnimationListReady = Standard_False;
1067     // Reset request for update of animation mode
1068     AWorkspace->NamedStatus &= ~OPENGL_NS_UPDATEAM;
1069   }
1070
1071   // Is in animation mode?
1072   if ( AWorkspace->NamedStatus & OPENGL_NS_ANIMATION )
1073   {
1074     // Is the animation list ready?
1075     if (myAnimationListReady)
1076     {
1077       // Execute the animation list
1078       glCallList(myAnimationListIndex);
1079     }
1080     else
1081     {
1082       // Update the animation list
1083       if ( AWorkspace->NamedStatus & OPENGL_NS_FLIST )
1084       {
1085         if (myAnimationListIndex == 0)
1086           myAnimationListIndex = glGenLists(1);
1087
1088         if (myAnimationListIndex != 0)
1089         {
1090           glNewList(myAnimationListIndex, GL_COMPILE_AND_EXECUTE);
1091           isAnimationListOpen = Standard_True;
1092         }
1093       }
1094       else
1095         AWorkspace->NamedStatus |= OPENGL_NS_FLIST;
1096     }
1097   }
1098   else
1099     myAnimationListReady = Standard_False;
1100
1101   if (!myAnimationListReady)
1102   {
1103     // Clear status bitfields
1104     AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1105
1106     // Added PCT for handling of textures
1107     switch (mySurfaceDetail)
1108     {
1109       case Visual3d_TOD_NONE:
1110         AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1111         DisableTexture();
1112         // Render the view
1113         RenderStructs(AWorkspace);
1114         break;
1115
1116       case Visual3d_TOD_ENVIRONMENT:
1117         AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1118         SetCurrentTexture(myTextureEnv);
1119         EnableTexture();
1120         // Render the view
1121         RenderStructs(AWorkspace);
1122         DisableTexture();
1123         break;
1124
1125       case Visual3d_TOD_ALL:
1126         // First pass
1127         AWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1128         // Render the view
1129         RenderStructs(AWorkspace);
1130         DisableTexture();
1131
1132         // Second pass
1133         if (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1134         {
1135           AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1136           SetCurrentTexture(myTextureEnv);
1137           EnableTexture();
1138
1139           /* sauvegarde de quelques parametres OpenGL */
1140           GLint blend_dst, blend_src;
1141           GLint zbuff_f;
1142           GLboolean zbuff_w;
1143           glGetBooleanv(GL_DEPTH_WRITEMASK, &zbuff_w);
1144           glGetIntegerv(GL_DEPTH_FUNC, &zbuff_f);
1145           glGetIntegerv(GL_BLEND_DST, &blend_dst); 
1146           glGetIntegerv(GL_BLEND_SRC, &blend_src);    
1147           GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1148           GLboolean blend_state = glIsEnabled(GL_BLEND);
1149
1150           glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
1151           glEnable(GL_BLEND);
1152
1153           glDepthFunc(GL_EQUAL);
1154           glDepthMask(GL_FALSE);
1155           glEnable(GL_DEPTH_TEST);
1156
1157           AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1158
1159           // Render the view
1160           RenderStructs(AWorkspace);
1161           DisableTexture();
1162
1163           /* restauration des parametres OpenGL */
1164           glBlendFunc(blend_src, blend_dst);
1165           if (!blend_state) glDisable(GL_BLEND);
1166
1167           glDepthFunc(zbuff_f);
1168           glDepthMask(zbuff_w);
1169           if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
1170         }
1171         break;
1172     }
1173
1174     if (isAnimationListOpen)
1175     {
1176       glEndList();
1177       myAnimationListReady = Standard_True;
1178     }
1179   }
1180
1181   /* restore previous graphics context; before update lights */
1182   //TsmPopAttri();
1183
1184   // Disable current clipping planes
1185   for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
1186     glDisable( planeid );
1187
1188   /* affichage de Triedre Non Zoomable de la vue s'il existe */
1189   if (!myTrihedron.IsNull())
1190     myTrihedron->Render(AWorkspace);
1191   if (!myGraduatedTrihedron.IsNull())
1192     myGraduatedTrihedron->Render(AWorkspace);
1193
1194   glPopAttrib(); // GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT
1195
1196   // Restore face culling
1197   if ( myBackfacing )
1198   {
1199     if ( isCullFace )
1200     {
1201       glEnable   ( GL_CULL_FACE );
1202       glCullFace ( GL_BACK      );
1203     }
1204     else
1205       glDisable ( GL_CULL_FACE );
1206   }
1207
1208   /////////////////////////////////////////////////////////////////////////////
1209   // Step 6: Draw overlayer
1210   const int aMode = 0;
1211   AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
1212
1213   RedrawLayer2d(AWorkspace, ACView, ACOverLayer);
1214
1215   AWorkspace->DisplayCallback (ACView, aMode);
1216
1217   // Restore clipping planes
1218   for ( ptrPlane = oldPlanes, planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++, ptrPlane++ )
1219   {
1220     glClipPlane( planeid, ptrPlane->Equation );
1221     if ( ptrPlane->isEnabled )
1222       glEnable( planeid );
1223     else
1224       glDisable( planeid );
1225   }
1226   delete[] oldPlanes;
1227 }
1228
1229 /*----------------------------------------------------------------------*/
1230
1231 //ExecuteViewDisplay
1232 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
1233 {
1234   if ( myStructures.NbStructures() <= 0 ) return;
1235
1236   glPushAttrib ( GL_DEPTH_BUFFER_BIT );
1237
1238   const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine( Standard_True );
1239
1240   //TsmPushAttri(); /* save previous graphics context */
1241
1242   if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
1243   {
1244     const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
1245
1246     if ( !myAntiAliasing )
1247     {
1248       glDisable(GL_POINT_SMOOTH);
1249       glDisable(GL_LINE_SMOOTH);
1250       if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
1251       glBlendFunc (GL_ONE, GL_ZERO);
1252       glDisable (GL_BLEND);
1253     }
1254     else
1255     {
1256       glEnable(GL_POINT_SMOOTH);
1257       glEnable(GL_LINE_SMOOTH);
1258       if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
1259       glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
1260       glEnable (GL_BLEND);
1261     }
1262   }
1263
1264   myStructures.Render(AWorkspace);
1265
1266   //TsmPopAttri(); /* restore previous graphics context; before update lights */
1267
1268   if ( AWorkspace->DegenerateModel > 1 )
1269   {
1270     glLineWidth ( aspect_line->Width() );
1271     if ( aspect_line->Type() != Aspect_TOL_SOLID ) glEnable ( GL_LINE_STIPPLE );
1272   }
1273
1274   glPopAttrib ();
1275 }
1276
1277 /*----------------------------------------------------------------------*/
1278
1279 //call_togl_redraw_layer2d
1280 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer)
1281 {
1282   if (&ACLayer == NULL
1283    || ACLayer.ptrLayer == NULL
1284    || ACLayer.ptrLayer->listIndex == 0) return;
1285
1286   GLsizei dispWidth  = (GLsizei )ACLayer.viewport[0];
1287   GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
1288
1289   const GLboolean isl = glIsEnabled(GL_LIGHTING); /*OCC6247*/
1290   if (isl)
1291     glDisable(GL_LIGHTING); /*OCC6247*/
1292
1293   /*
1294   * On positionne la projection
1295   */
1296   glMatrixMode( GL_MODELVIEW );
1297   glPushMatrix ();
1298   glLoadIdentity ();
1299
1300   glMatrixMode (GL_PROJECTION);
1301   glPushMatrix ();
1302   glLoadIdentity ();
1303
1304   if (!ACLayer.sizeDependent)
1305     glViewport (0, 0, dispWidth, dispHeight);
1306
1307   float left = ACLayer.ortho[0];
1308   float right = ACLayer.ortho[1];
1309   float bottom = ACLayer.ortho[2];
1310   float top = ACLayer.ortho[3];
1311
1312   int attach = ACLayer.attach;
1313
1314   float ratio;
1315   if (!ACLayer.sizeDependent)
1316     ratio = (float) dispWidth/dispHeight;
1317   else
1318     ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
1319
1320   float delta;
1321   if (ratio >= 1.0) { /* fenetre horizontale */
1322     delta = (float )((top - bottom)/2.0);
1323     switch (attach) {
1324       case 0: /* Aspect_TOC_BOTTOM_LEFT */
1325         top = bottom + 2*delta/ratio;
1326         break;
1327       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1328         top = bottom + 2*delta/ratio;
1329         break;
1330       case 2: /* Aspect_TOC_TOP_LEFT */
1331         bottom = top - 2*delta/ratio;
1332         break;
1333       case 3: /* Aspect_TOC_TOP_RIGHT */
1334         bottom = top - 2*delta/ratio;
1335         break;
1336     }
1337   }
1338   else { /* fenetre verticale */
1339     delta = (float )((right - left)/2.0);
1340     switch (attach) {
1341       case 0: /* Aspect_TOC_BOTTOM_LEFT */
1342         right = left + 2*delta*ratio;
1343         break;
1344       case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1345         left = right - 2*delta*ratio;
1346         break;
1347       case 2: /* Aspect_TOC_TOP_LEFT */
1348         right = left + 2*delta*ratio;
1349         break;
1350       case 3: /* Aspect_TOC_TOP_RIGHT */
1351         left = right - 2*delta*ratio;
1352         break;
1353     }
1354   }
1355
1356 #ifdef WNT
1357   // Check printer context that exists only for print operation
1358   OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext (AWorkspace->GetGContext());
1359
1360   if (aPrinterContext)
1361   {
1362     // additional transformation matrix could be applied to
1363     // render only those parts of viewport that will be
1364     // passed to a printer as a current "frame" to provide
1365     // tiling; scaling of graphics by matrix helps render a
1366     // part of a view (frame) in same viewport, but with higher
1367     // resolution
1368     GLfloat aProjMatrix[16];
1369     aPrinterContext->GetProjTransformation (aProjMatrix);
1370     glLoadMatrixf ((GLfloat*) aProjMatrix);
1371
1372     // printing operation also assumes other viewport dimension
1373     // to comply with transformation matrix or graphics scaling
1374     // factors for tiling for layer redraw
1375     GLsizei anViewportX = 0;
1376     GLsizei anViewportY = 0;
1377     aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
1378     if (anViewportX != 0 && anViewportY != 0)
1379       glViewport (0, 0, anViewportX, anViewportY);
1380   }
1381 #endif 
1382
1383   glOrtho (left, right, bottom, top, -1.0, 1.0);
1384
1385   /*
1386   * On trace la display-list associee au layer.
1387   */
1388   glPushAttrib (
1389     GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
1390     GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
1391   glDisable (GL_DEPTH_TEST);
1392   glCallList (ACLayer.ptrLayer->listIndex);
1393
1394   //calling dynamic render of LayerItems
1395   if ( ACLayer.ptrLayer->layerData )
1396   {
1397     InitLayerProp(ACLayer.ptrLayer->listIndex);
1398     ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
1399     InitLayerProp(0);
1400   }
1401
1402   glPopAttrib ();
1403
1404   /*
1405   * On retire la projection
1406   */
1407   glMatrixMode (GL_PROJECTION);
1408   glPopMatrix ();
1409
1410   glMatrixMode( GL_MODELVIEW );
1411   glPopMatrix ();
1412
1413   /*
1414   * Restauration du Viewport en cas de modification
1415   */
1416   if (!ACLayer.sizeDependent)
1417     glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
1418
1419   glFlush ();
1420
1421   if (isl)
1422     glEnable(GL_LIGHTING); /*OCC6247*/
1423 }
1424
1425 /*----------------------------------------------------------------------*/
1426
1427 //call_togl_create_bg_texture
1428 void OpenGl_View::CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle)
1429 {
1430   // Delete existing texture
1431   if ( myBgTexture.TexId != 0 )
1432   {
1433     glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
1434     myBgTexture.TexId = 0;
1435   }
1436
1437   Standard_Integer width, height;
1438   Handle(Image_Image) image;
1439   if ( AlienImage::LoadImageFile( AFileName, image, width, height ) )
1440   {
1441     const int nbbytes = width * height * 3;
1442     GLubyte *data = new GLubyte[nbbytes];
1443     GLubyte *pdata = data;
1444     Standard_Integer i, j;
1445     for ( j = height - 1; j >= 0; j-- )
1446       for ( i = 0; i < width; i++ )
1447       {
1448         const Quantity_Color &color = image->PixelColor( i, j );
1449         *pdata++ = (GLubyte)( 255 * color.Red() );
1450         *pdata++ = (GLubyte)( 255 * color.Green() );
1451         *pdata++ = (GLubyte)( 255 * color.Blue() );
1452       }
1453
1454     GLuint texture = 0;
1455     glGenTextures( 1, &texture );
1456     glBindTexture( GL_TEXTURE_2D, texture );
1457
1458     /* Create MipMapped Texture */
1459     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1460     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1461     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1462     glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1463
1464     gluBuild2DMipmaps( GL_TEXTURE_2D, 3/*4*/, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );
1465
1466     delete[] data;
1467
1468     myBgTexture.TexId = texture;
1469     myBgTexture.Width = width;
1470     myBgTexture.Height = height;
1471     myBgTexture.Style = AFillStyle;
1472   }
1473 }
1474
1475 /*----------------------------------------------------------------------*/
1476
1477 //call_togl_set_bg_texture_style
1478 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
1479 {
1480   myBgTexture.Style = AFillStyle;
1481 }
1482
1483 /*----------------------------------------------------------------------*/
1484
1485 //call_togl_gradient_background
1486 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
1487                                         const Quantity_Color& AColor2,
1488                                         const Aspect_GradientFillMethod AType)
1489 {
1490   Standard_Real R,G,B;
1491   AColor1.Values( R, G, B, Quantity_TOC_RGB );
1492   myBgGradient.color1.rgb[0] = ( Tfloat )R;
1493   myBgGradient.color1.rgb[1] = ( Tfloat )G;
1494   myBgGradient.color1.rgb[2] = ( Tfloat )B;
1495   myBgGradient.color1.rgb[3] = 0.F;
1496
1497   AColor2.Values( R, G, B, Quantity_TOC_RGB );
1498   myBgGradient.color2.rgb[0] = ( Tfloat )R;
1499   myBgGradient.color2.rgb[1] = ( Tfloat )G;
1500   myBgGradient.color2.rgb[2] = ( Tfloat )B;
1501   myBgGradient.color2.rgb[3] = 0.F;
1502
1503   myBgGradient.type = AType;
1504 }
1505
1506 /*----------------------------------------------------------------------*/
1507
1508 //call_togl_set_gradient_type
1509 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
1510 {
1511   myBgGradient.type = AType;
1512 }
1513
1514 /*----------------------------------------------------------------------*/