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