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