0024224: Suspicious logics in changing clipping planes at OpenGl_Structure
[occt.git] / src / OpenGl / OpenGl_View_2.cxx
CommitLineData
b311480e 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
2166f0fa
SK
20#include <stdio.h>
21#include <stdlib.h>
22
5f8b738e 23#include <OpenGl_GlCore11.hxx>
2166f0fa 24#include <OpenGl_tgl_funcs.hxx>
2166f0fa 25
3c3131a0 26#include <Image_AlienPixMap.hxx>
2166f0fa
SK
27#include <Visual3d_Layer.hxx>
28
2166f0fa
SK
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>
59f45b7c 36#include <OpenGl_Structure.hxx>
2166f0fa 37
2166f0fa
SK
38#define EPSI 0.0001
39
2166f0fa
SK
40static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F };
41static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
42static const GLfloat default_sptexpo = 0.F;
43static const GLfloat default_sptcutoff = 180.F;
44
45extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
46
47/*----------------------------------------------------------------------*/
48
49struct OPENGL_CLIP_PLANE
50{
51 GLboolean isEnabled;
52 GLdouble Equation[4];
1c35b92f 53 DEFINE_STANDARD_ALLOC
2166f0fa
SK
54};
55
56/*----------------------------------------------------------------------*/
57/*
58* Fonctions privees
59*/
60
61/*-----------------------------------------------------------------*/
62/*
63* Set des lumieres
64*/
65static 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 ?
1d47d8d0 71 GLint cur_matrix = 0;
2166f0fa
SK
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 */
3c3131a0 103 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb);
2166f0fa
SK
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.
3c3131a0 122 To create a realistic effect, set the GL_SPECULAR parameter
2166f0fa
SK
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
3c3131a0 157 To create a realistic effect, set the GL_SPECULAR parameter
2166f0fa
SK
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);
3c3131a0 179 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
2166f0fa
SK
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);
3c3131a0 206 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
2166f0fa 207
3c3131a0 208 glLightfv(*gl_lid, GL_POSITION, data_pos);
2166f0fa
SK
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);
3c3131a0 214 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
2166f0fa
SK
215 break;
216 }
217
3c3131a0 218 if (lptr->type != TLightAmbient)
219 {
2166f0fa
SK
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
237static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
238 float *ox, float *oy, float *oz );
239static 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! */
250void 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
3c3131a0 253 int* err_ind,
2166f0fa
SK
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! */
366void call_func_eval_map_matrix3(
3c3131a0 367 view_map3 *Map,
368 int *err_ind,
2166f0fa
SK
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
3c3131a0 393 */
2166f0fa
SK
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
3c3131a0 448 return;
2166f0fa
SK
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
3c3131a0 509 return;
510 }
2166f0fa
SK
511
512 /*
513 * Type Perspective
3c3131a0 514 */
2166f0fa
SK
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
604static void
605call_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
620static void
621call_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
a174a3c5 634void 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)
2166f0fa 639{
2166f0fa 640 // Store and disable current clipping planes
4269bd1b 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];
2166f0fa
SK
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 }
4269bd1b 655 else
656 {
2166f0fa 657 ptrPlane->isEnabled = GL_FALSE;
4269bd1b 658 }
2166f0fa
SK
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
f8b2ed36 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 ) )
2166f0fa
SK
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:
f8b2ed36 700 corner1 = myBgGradient.color1.rgb;
2166f0fa 701 corner2 = myBgGradient.color2.rgb;
f8b2ed36 702 corner3 = myBgGradient.color2.rgb;
2166f0fa
SK
703 corner4 = myBgGradient.color1.rgb;
704 break;
705 case Aspect_GFM_VER:
706 corner1 = myBgGradient.color2.rgb;
f8b2ed36 707 corner2 = myBgGradient.color2.rgb;
2166f0fa 708 corner3 = myBgGradient.color1.rgb;
f8b2ed36 709 corner4 = myBgGradient.color1.rgb;
2166f0fa
SK
710 break;
711 case Aspect_GFM_DIAG1:
712 corner2 = myBgGradient.color2.rgb;
3c3131a0 713 corner4 = myBgGradient.color1.rgb;
2166f0fa
SK
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;
3c3131a0 718 corner3 = dcorner2;
2166f0fa
SK
719 break;
720 case Aspect_GFM_DIAG2:
3c3131a0 721 corner1 = myBgGradient.color2.rgb;
722 corner3 = myBgGradient.color1.rgb;
2166f0fa
SK
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;
3c3131a0 727 corner4 = dcorner2;
2166f0fa
SK
728 break;
729 case Aspect_GFM_CORNER1:
f8b2ed36 730 corner1 = myBgGradient.color2.rgb;
2166f0fa
SK
731 corner2 = myBgGradient.color2.rgb;
732 corner3 = myBgGradient.color2.rgb;
f8b2ed36 733 corner4 = myBgGradient.color1.rgb;
2166f0fa
SK
734 break;
735 case Aspect_GFM_CORNER2:
736 corner1 = myBgGradient.color2.rgb;
f8b2ed36 737 corner2 = myBgGradient.color2.rgb;
738 corner3 = myBgGradient.color1.rgb;
2166f0fa
SK
739 corner4 = myBgGradient.color2.rgb;
740 break;
741 case Aspect_GFM_CORNER3:
742 corner1 = myBgGradient.color2.rgb;
f8b2ed36 743 corner2 = myBgGradient.color1.rgb;
744 corner3 = myBgGradient.color2.rgb;
2166f0fa
SK
745 corner4 = myBgGradient.color2.rgb;
746 break;
747 case Aspect_GFM_CORNER4:
f8b2ed36 748 corner1 = myBgGradient.color1.rgb;
2166f0fa
SK
749 corner2 = myBgGradient.color2.rgb;
750 corner3 = myBgGradient.color2.rgb;
f8b2ed36 751 corner4 = myBgGradient.color2.rgb;
2166f0fa
SK
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);
f8b2ed36 767 if( myBgGradient.type != Aspect_GFM_CORNER1 && myBgGradient.type != Aspect_GFM_CORNER3 )
2166f0fa
SK
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.);
3c3131a0 773 }
f8b2ed36 774 else //if ( myBgGradient.type == Aspect_GFM_CORNER1 || myBgGradient.type == Aspect_GFM_CORNER3 )
2166f0fa
SK
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 }
f8b2ed36 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
1e743e91 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
f8b2ed36 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
1e743e91 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
f8b2ed36 831 glBegin( GL_QUADS );
1e743e91 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 );
f8b2ed36 836 glEnd();
837 }
2166f0fa
SK
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
a174a3c5 861 RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACUnderLayer);
2166f0fa
SK
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
3c3131a0 883 if(myExtra.scaleFactors[0] != 1.F ||
2166f0fa
SK
884 myExtra.scaleFactors[1] != 1.F ||
885 myExtra.scaleFactors[2] != 1.F)
886 glEnable(GL_NORMALIZE);
3c3131a0 887 else if(glIsEnabled(GL_NORMALIZE))
2166f0fa
SK
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
a174a3c5 895#ifdef _WIN32
2166f0fa 896 // add printing scale/tiling transformation
a174a3c5 897 if (!thePrintContext.IsNull())
2166f0fa 898 {
a174a3c5 899 thePrintContext->LoadProjTransformation();
2166f0fa
SK
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/*
920While drawing after a clipplane has been defined and enabled, each vertex
921is transformed to eye-coordinates, where it is dotted with the transformed
922clipping plane equation. Eye-coordinate vertexes whose dot product with
923the transformed clipping plane equation is positive or zero are in, and
924require no clipping. Those eye-coordinate vertexes whose dot product is
925negative are clipped. Because clipplane clipping is done in eye-
926coordinates, changes to the projection matrix have no effect on its
927operation.
928
929A point and a normal are converted to a plane equation in the following manner:
930
931point = [Px,Py,Pz]
932
933normal = |Nx|
934|Ny|
935|Nz|
936
937plane equation = |A|
938|B|
939|C|
940|D|
941A = Nx
942B = Ny
943C = Nz
944D = -[Px,Py,Pz] dot |Nx|
945|Ny|
946|Nz|
947
948*/
949
2166f0fa
SK
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 {
b859a34d 992 const Handle(OpenGl_Context)& aContext = AWorkspace->GetGlContext();
2166f0fa 993
b859a34d 994 if (myZClip.Back.IsOn || myZClip.Front.IsOn)
995 {
2166f0fa
SK
996 const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
997
b859a34d 998 Handle(Graphic3d_ClipPlane) aPlaneBack;
999 Handle(Graphic3d_ClipPlane) aPlaneFront;
1000
1001 if (myZClip.Back.IsOn)
2166f0fa
SK
1002 {
1003 const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
b859a34d 1004 const Graphic3d_ClipPlane::Equation aBackEquation (0.0, 0.0, 1.0, -back);
1005 aPlaneBack = new Graphic3d_ClipPlane (aBackEquation);
2166f0fa
SK
1006 }
1007
b859a34d 1008 if (myZClip.Front.IsOn)
2166f0fa
SK
1009 {
1010 const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
b859a34d 1011 const Graphic3d_ClipPlane::Equation aFrontEquation (0.0, 0.0, -1.0, front);
1012 aPlaneFront = new Graphic3d_ClipPlane (aFrontEquation);
2166f0fa
SK
1013 }
1014
b859a34d 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 }
2166f0fa
SK
1032 }
1033
1034 // Apply user clipping planes
b859a34d 1035 if (!myClipPlanes.IsEmpty())
4269bd1b 1036 {
b859a34d 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 }
4269bd1b 1047
b859a34d 1048 if (!aUserPlanes.IsEmpty())
1049 {
1050 // add planes at actual matrix state.
1051 aContext->ChangeClipping().AddWorld (aUserPlanes);
1052 }
2166f0fa
SK
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
de75ed09 1064 // Clear status bitfields
1065 AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
2166f0fa 1066
de75ed09 1067 // Added PCT for handling of textures
1068 switch (mySurfaceDetail)
2166f0fa 1069 {
de75ed09 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)
2166f0fa 1094 {
de75ed09 1095 AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1096 AWorkspace->EnableTexture (myTextureEnv);
2166f0fa 1097
de75ed09 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);
2166f0fa 1108
de75ed09 1109 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1110 glEnable(GL_BLEND);
2166f0fa 1111
de75ed09 1112 glDepthFunc(GL_EQUAL);
1113 glDepthMask(GL_FALSE);
1114 glEnable(GL_DEPTH_TEST);
2166f0fa 1115
2166f0fa 1116 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
2166f0fa 1117
2166f0fa
SK
1118 // Render the view
1119 RenderStructs(AWorkspace);
bf75be98 1120 AWorkspace->DisableTexture();
2166f0fa 1121
de75ed09 1122 /* restauration des parametres OpenGL */
1123 glBlendFunc(blend_src, blend_dst);
1124 if (!blend_state) glDisable(GL_BLEND);
2166f0fa 1125
de75ed09 1126 glDepthFunc(zbuff_f);
1127 glDepthMask(zbuff_w);
1128 if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
1129 }
1130 break;
2166f0fa
SK
1131 }
1132
26395493 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();
2166f0fa 1138
b859a34d 1139 aContext->ChangeClipping().RemoveAll();
2166f0fa 1140
a174a3c5 1141 // display global trihedron
1142 if (myTrihedron != NULL)
1143 {
1144 myTrihedron->Render (AWorkspace);
1145 }
1146 if (myGraduatedTrihedron != NULL)
1147 {
1148 myGraduatedTrihedron->Render (AWorkspace);
1149 }
2166f0fa 1150
2166f0fa
SK
1151 // Restore face culling
1152 if ( myBackfacing )
1153 {
1154 if ( isCullFace )
1155 {
1156 glEnable ( GL_CULL_FACE );
1157 glCullFace ( GL_BACK );
1158 }
529afc1a 1159 else
2166f0fa
SK
1160 glDisable ( GL_CULL_FACE );
1161 }
1162
1163 /////////////////////////////////////////////////////////////////////////////
1164 // Step 6: Draw overlayer
529afc1a
K
1165 const int aMode = 0;
1166 AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
2166f0fa 1167
a174a3c5 1168 RedrawLayer2d (thePrintContext, AWorkspace, ACView, ACOverLayer);
2166f0fa 1169
529afc1a 1170 AWorkspace->DisplayCallback (ACView, aMode);
2166f0fa
SK
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 );
529afc1a 1178 else
2166f0fa
SK
1179 glDisable( planeid );
1180 }
1181 delete[] oldPlanes;
1182}
1183
1184/*----------------------------------------------------------------------*/
1185
1186//ExecuteViewDisplay
1187void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
1188{
59f45b7c 1189 if ( myZLayers.NbStructures() <= 0 )
1190 return;
2166f0fa
SK
1191
1192 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
1193
2166f0fa
SK
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);
3c3131a0 1213 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
2166f0fa
SK
1214 glEnable (GL_BLEND);
1215 }
1216 }
1217
59f45b7c 1218 myZLayers.Render (AWorkspace);
2166f0fa
SK
1219
1220 //TsmPopAttri(); /* restore previous graphics context; before update lights */
de75ed09 1221 glPopAttrib();
2166f0fa
SK
1222}
1223
1224/*----------------------------------------------------------------------*/
1225
1226//call_togl_redraw_layer2d
a174a3c5 1227void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_PrinterContext)& thePrintContext,
35e08fe8 1228 const Handle(OpenGl_Workspace)& /*AWorkspace*/,
a174a3c5 1229 const Graphic3d_CView& ACView,
1230 const Aspect_CLayer2d& ACLayer)
2166f0fa
SK
1231{
1232 if (&ACLayer == NULL
1233 || ACLayer.ptrLayer == NULL
1234 || ACLayer.ptrLayer->listIndex == 0) return;
1235
529afc1a
K
1236 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
1237 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
2166f0fa 1238
2166f0fa
SK
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;
c9d4eb9d 1264 if (ratio >= 1.0) {
2166f0fa
SK
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 }
c9d4eb9d 1281 else {
2166f0fa
SK
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
a174a3c5 1299#ifdef _WIN32
2166f0fa 1300 // Check printer context that exists only for print operation
a174a3c5 1301 if (!thePrintContext.IsNull())
2166f0fa
SK
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
a174a3c5 1309 thePrintContext->LoadProjTransformation();
2166f0fa
SK
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;
a174a3c5 1316 thePrintContext->GetLayerViewport (anViewportX, anViewportY);
2166f0fa
SK
1317 if (anViewportX != 0 && anViewportY != 0)
1318 glViewport (0, 0, anViewportX, anViewportY);
1319 }
3c3131a0 1320#endif
2166f0fa
SK
1321
1322 glOrtho (left, right, bottom, top, -1.0, 1.0);
1323
2166f0fa
SK
1324 glPushAttrib (
1325 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
1326 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
c9d4eb9d 1327
2166f0fa 1328 glDisable (GL_DEPTH_TEST);
c9d4eb9d 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
2166f0fa
SK
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
2166f0fa
SK
1346 glMatrixMode (GL_PROJECTION);
1347 glPopMatrix ();
1348
1349 glMatrixMode( GL_MODELVIEW );
1350 glPopMatrix ();
1351
2166f0fa
SK
1352 if (!ACLayer.sizeDependent)
1353 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
1354
1355 glFlush ();
2166f0fa
SK
1356}
1357
1358/*----------------------------------------------------------------------*/
1359
1360//call_togl_create_bg_texture
3c3131a0 1361void OpenGl_View::CreateBackgroundTexture (const Standard_CString theFilePath,
1362 const Aspect_FillMethod theFillStyle)
2166f0fa 1363{
3c3131a0 1364 if (myBgTexture.TexId != 0)
2166f0fa 1365 {
3c3131a0 1366 // delete existing texture
1367 glDeleteTextures (1, (GLuint* )&(myBgTexture.TexId));
2166f0fa
SK
1368 myBgTexture.TexId = 0;
1369 }
1370
3c3131a0 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))
2166f0fa 1383 {
3c3131a0 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)
2166f0fa 1401 {
6a7d83c4 1402 aSrcColor = anImageLoaded.PixelColor ((Standard_Integer )aCol, (Standard_Integer )aRow);
3c3131a0 1403 Image_ColorRGB& aColor = aDataNew.ChangeValue (aRow, aCol);
8263fcd3 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());
2166f0fa 1407 }
3c3131a0 1408 }
1409 anImageLoaded.Clear();
1410 }
2166f0fa 1411
3c3131a0 1412 // create MipMapped texture
1413 glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
2166f0fa 1414
3c3131a0 1415 GLuint aTextureId = 0;
1416 glGenTextures (1, &aTextureId);
1417 glBindTexture (GL_TEXTURE_2D, aTextureId);
2166f0fa 1418
3c3131a0 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);
2166f0fa 1423
3c3131a0 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());
2166f0fa 1428
3c3131a0 1429 myBgTexture.TexId = aTextureId;
1430 myBgTexture.Width = (Standard_Integer )anImage.SizeX();
1431 myBgTexture.Height = (Standard_Integer )anImage.SizeY();
1432 myBgTexture.Style = theFillStyle;
2166f0fa
SK
1433}
1434
1435/*----------------------------------------------------------------------*/
1436
1437//call_togl_set_bg_texture_style
1438void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
1439{
f8b2ed36 1440 myBgTexture.Style = AFillStyle;
2166f0fa
SK
1441}
1442
1443/*----------------------------------------------------------------------*/
1444
1445//call_togl_gradient_background
1446void 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
1469void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
1470{
f8b2ed36 1471 myBgGradient.type = AType;
2166f0fa
SK
1472}
1473
59f45b7c 1474//=======================================================================
1475//function : AddZLayer
3c3131a0 1476//purpose :
59f45b7c 1477//=======================================================================
1478
1479void OpenGl_View::AddZLayer (const Standard_Integer theLayerId)
1480{
1481 myZLayers.AddLayer (theLayerId);
1482}
1483
1484//=======================================================================
1485//function : RemoveZLayer
3c3131a0 1486//purpose :
59f45b7c 1487//=======================================================================
1488
1489void OpenGl_View::RemoveZLayer (const Standard_Integer theLayerId)
1490{
1491 myZLayers.RemoveLayer (theLayerId);
1492}
1493
1494//=======================================================================
1495//function : DisplayStructure
3c3131a0 1496//purpose :
59f45b7c 1497//=======================================================================
1498
1499void 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
3c3131a0 1508//purpose :
59f45b7c 1509//=======================================================================
1510
1511void 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
1522void 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}