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