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