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