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