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