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