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