1 // File: OpenGl_View_2.cxx
2 // Created: 20 September 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #define G003 /* EUG 20-09-99 ; Animation management
9 /*----------------------------------------------------------------------*/
17 #include <OpenGl_tgl_all.hxx>
18 #include <OpenGl_tgl_funcs.hxx>
19 #include <OpenGl_TextureBox.hxx>
21 #include <AlienImage.hxx>
22 #include <Image_Image.hxx>
23 #include <Visual3d_Layer.hxx>
29 #include <OpenGl_AspectLine.hxx>
30 #include <OpenGl_Display.hxx>
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>
37 /*----------------------------------------------------------------------*/
45 # define M_PI 3.14159265358979323846
48 static const GLfloat default_amb[4] = { 0.F, 0.F, 0.F, 1.F };
49 static const GLfloat default_sptdir[3] = { 0.F, 0.F, -1.F };
50 static const GLfloat default_sptexpo = 0.F;
51 static const GLfloat default_sptcutoff = 180.F;
53 extern void InitLayerProp (const int AListId); //szvgl: defined in OpenGl_GraphicDriver_Layer.cxx
55 /*----------------------------------------------------------------------*/
57 struct OPENGL_CLIP_PLANE
61 IMPLEMENT_MEMORY_OPERATORS
64 /*----------------------------------------------------------------------*/
69 /*-----------------------------------------------------------------*/
73 static void bind_light(const OpenGl_Light *lptr, int *gl_lid)
75 // Only 8 lights in OpenGL...
76 if (*gl_lid > GL_LIGHT7) return;
78 // the light is a headlight ?
82 glGetIntegerv(GL_MATRIX_MODE, &cur_matrix);
83 glMatrixMode(GL_MODELVIEW);
89 GLfloat data_diffu[4];
91 GLfloat data_sptdir[3];
93 GLfloat data_sptcutoff;
94 GLfloat data_constantattenuation;
95 GLfloat data_linearattenuation;
97 /* set la light en fonction de son type */
101 data_amb[0] = lptr->col.rgb[0];
102 data_amb[1] = lptr->col.rgb[1];
103 data_amb[2] = lptr->col.rgb[2];
106 /*------------------------- Ambient ---------------------------*/
108 * The GL_AMBIENT parameter refers to RGBA intensity of the ambient
111 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, data_amb);
115 case TLightDirectional:
116 data_diffu[0] = lptr->col.rgb[0];
117 data_diffu[1] = lptr->col.rgb[1];
118 data_diffu[2] = lptr->col.rgb[2];
121 /*------------------------- Direction ---------------------------*/
122 /* From Open GL Programming Rev 1 Guide Chapt 6 :
123 Lighting The Mathematics of Lighting ( p 168 )
125 Directional Light Source ( Infinite ) :
126 if the last parameter of GL_POSITION , w , is zero, the
127 corresponding light source is a Directional one.
129 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
130 To create a realistic effect, set the GL_SPECULAR parameter
131 to the same value as the GL_DIFFUSE.
134 data_pos[0] = -lptr->dir[0];
135 data_pos[1] = -lptr->dir[1];
136 data_pos[2] = -lptr->dir[2];
139 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
140 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
141 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
143 glLightfv(*gl_lid, GL_POSITION, data_pos);
144 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
145 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
146 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
150 case TLightPositional:
151 data_diffu[0] = lptr->col.rgb[0];
152 data_diffu[1] = lptr->col.rgb[1];
153 data_diffu[2] = lptr->col.rgb[2];
156 /*------------------------- Position -----------------------------*/
157 /* From Open GL Programming Rev 1 Guide Chapt 6 :
158 Lighting The Mathematics of Lighting ( p 168 )
159 Positional Light Source :
160 if the last parameter of GL_POSITION , w , is nonzero,
161 the corresponding light source is a Positional one.
163 GL_SPOT_CUTOFF a 180 signifie que ce n'est pas un spot.
165 To create a realistic effect, set the GL_SPECULAR parameter
166 to the same value as the GL_DIFFUSE.
169 data_pos[0] = lptr->pos[0];
170 data_pos[1] = lptr->pos[1];
171 data_pos[2] = lptr->pos[2];
174 data_constantattenuation = lptr->atten[0];
175 data_linearattenuation = lptr->atten[1];
177 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
178 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
179 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
181 glLightfv(*gl_lid, GL_POSITION, data_pos);
182 glLightfv(*gl_lid, GL_SPOT_DIRECTION, default_sptdir);
183 glLightf(*gl_lid, GL_SPOT_EXPONENT, default_sptexpo);
184 glLightf(*gl_lid, GL_SPOT_CUTOFF, default_sptcutoff);
185 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
186 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
187 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
192 data_diffu[0] = lptr->col.rgb[0];
193 data_diffu[1] = lptr->col.rgb[1];
194 data_diffu[2] = lptr->col.rgb[2];
197 data_pos[0] = lptr->pos[0];
198 data_pos[1] = lptr->pos[1];
199 data_pos[2] = lptr->pos[2];
202 data_sptdir[0] = lptr->dir[0];
203 data_sptdir[1] = lptr->dir[1];
204 data_sptdir[2] = lptr->dir[2];
206 data_sptexpo = ( float )lptr->shine * 128.0F;
207 data_sptcutoff = ( float )(lptr->angle * 180.0F)/( float )M_PI;
209 data_constantattenuation = lptr->atten[0];
210 data_linearattenuation = lptr->atten[1];
212 glLightfv(*gl_lid, GL_AMBIENT, default_amb);
213 glLightfv(*gl_lid, GL_DIFFUSE, data_diffu);
214 glLightfv(*gl_lid, GL_SPECULAR, data_diffu);
216 glLightfv(*gl_lid, GL_POSITION, data_pos);
217 glLightfv(*gl_lid, GL_SPOT_DIRECTION, data_sptdir);
218 glLightf(*gl_lid, GL_SPOT_EXPONENT, data_sptexpo);
219 glLightf(*gl_lid, GL_SPOT_CUTOFF, data_sptcutoff);
220 glLightf(*gl_lid, GL_CONSTANT_ATTENUATION, data_constantattenuation);
221 glLightf(*gl_lid, GL_LINEAR_ATTENUATION, data_linearattenuation);
222 glLightf(*gl_lid, GL_QUADRATIC_ATTENUATION, 0.0);
226 if (lptr->type != TLightAmbient)
232 /* si la light etait une headlight alors restaure la matrice precedente */
236 glMatrixMode(cur_matrix);
240 /*----------------------------------------------------------------------*/
245 static void call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
246 float *ox, float *oy, float *oz );
247 static void call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c);
249 /*----------------------------------------------------------------------*/
255 * Evaluates orientation matrix.
257 /* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
258 void call_func_eval_ori_matrix3 (const point3* vrp, // view reference point
259 const vec3* vpn, // view plane normal
260 const vec3* vup, // view up vector
262 float mout[4][4]) // OUT view orientation matrix
265 /* Translate to VRP then change the basis.
266 * The old basis is: e1 = < 1, 0, 0>, e2 = < 0, 1, 0>, e3 = < 0, 0, 1>.
267 * The new basis is: ("x" means cross product)
269 * e1' = VUP x VPN / |VUP x VPN|
271 * Therefore the transform from old to new is x' = TAx, where:
273 * | e1'x e2'x e3'x 0 | | 1 0 0 0 |
274 * A = | e1'y e2'y e3'y 0 |, T = | 0 1 0 0 |
275 * | e1'z e2'z e3'z 0 | | 0 0 1 0 |
276 * | 0 0 0 1 | | -vrp.x -vrp.y -vrp.z 1 |
281 * These ei's are really ei primes.
283 register float (*m)[4][4];
284 point3 e1, e2, e3, e4;
288 * e1' = VUP x VPN / |VUP x VPN|, but do the division later.
290 e1.x = vup->delta_y * vpn->delta_z - vup->delta_z * vpn->delta_y;
291 e1.y = vup->delta_z * vpn->delta_x - vup->delta_x * vpn->delta_z;
292 e1.z = vup->delta_x * vpn->delta_y - vup->delta_y * vpn->delta_x;
293 s = sqrt( e1.x * e1.x + e1.y * e1.y + e1.z * e1.z);
297 v = sqrt( e3.x * e3.x + e3.y * e3.y + e3.z * e3.z);
299 * Check for vup and vpn colinear (zero dot product).
301 if ((s > -EPSI) && (s < EPSI))
305 * Check for a normal vector not null.
307 if ((v > -EPSI) && (v < EPSI))
325 e2.x = e3.y * e1.z - e3.z * e1.y;
326 e2.y = e3.z * e1.x - e3.x * e1.z;
327 e2.z = e3.x * e1.y - e3.y * e1.x;
329 * Add the translation
331 e4.x = -( e1.x * vrp->x + e1.y * vrp->y + e1.z * vrp->z);
332 e4.y = -( e2.x * vrp->x + e2.y * vrp->y + e2.z * vrp->z);
333 e4.z = -( e3.x * vrp->x + e3.y * vrp->y + e3.z * vrp->z);
335 * Homogeneous entries
337 * | e1.x e2.x e3.x 0.0 | | 1 0 0 0 |
338 * | e1.y e2.y e3.y 0.0 | * | 0 1 0 0 |
339 * | e1.z e2.z e3.z 0.0 | | a b 1 c |
340 * | e4.x e4.y e4.z 1.0 | | 0 0 0 1 |
343 m = (float (*)[4][4])mout;
348 (*m)[0][3] = ( float )0.0;
353 (*m)[1][3] = ( float )0.0;
358 (*m)[2][3] = ( float )0.0;
363 (*m)[3][3] = ( float )1.0;
369 /*----------------------------------------------------------------------*/
371 * Evaluates mapping matrix.
373 /* OCC18942: obsolete in OCCT6.3, might be removed in further versions! */
374 void call_func_eval_map_matrix3(
385 matrix3 aux_mat1, aux_mat2, aux_mat3;
391 Spar[i][j] = Sper[i][j] = aux_mat1[i][j] = aux_mat2[i][j] =
392 aux_mat3[i][j] = Tper[i][j] = Tpar[i][j] = Tprp[i][j] =
393 Shear[i][j] = Scale[i][j] = ( float )(i == j);
395 Prp.x = Map->proj_ref_point.x;
396 Prp.y = Map->proj_ref_point.y;
397 Prp.z = Map->proj_ref_point.z;
402 if (Map->proj_type == TYPE_PARAL)
408 float cx, cy, gx, gy, xsf, ysf, zsf;
410 float dopx, dopy, dopz;
411 matrix3 tmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
412 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
413 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
414 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
415 matrix3 smat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
416 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
417 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
418 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
419 matrix3 shmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
420 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
421 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
422 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
423 matrix3 tshmat = { { ( float )1.0, ( float )0.0, ( float )0.0, ( float )0.0 },
424 { ( float )0.0, ( float )1.0, ( float )0.0, ( float )0.0 },
425 { ( float )0.0, ( float )0.0, ( float )1.0, ( float )0.0 },
426 { ( float )0.0, ( float )0.0, ( float )0.0, ( float )1.0 } };
429 cx = Map->win.x_min + Map->win.x_max, cx /= ( float )2.0;
430 cy = Map->win.y_min + Map->win.y_max, cy /= ( float )2.0;
432 gx = 2.0/ (Map->win.x_max - Map->win.x_min);
433 gy = 2.0/ (Map->win.y_max - Map->win.y_min);
437 tmat[2][3] = (Map->front_plane + Map->back_plane)/(Map->front_plane - Map->back_plane);
441 smat[2][2] = -2./(Map->front_plane - Map->back_plane);
449 shmat[0][2] = -(dopx/dopz);
450 shmat[1][2] = -(dopy/dopz);
452 /* multiply to obtain mapping matrix */
453 call_util_mat_mul( tmat, shmat, tshmat );
454 call_util_mat_mul( smat, tshmat, mat );
460 Map->proj_vp.z_min = ( float )0.0;
461 Map->proj_vp.z_max = ( float )1.0;
464 /* Shear matrix calculation */
465 umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0;
466 vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0;
467 if(Prp.z == Map->view_plane){
468 /* Projection reference point is on the view plane */
472 Shear[2][0] = ( float )(-1.0) * ((Prp.x-umid)/(Prp.z-Map->view_plane));
473 Shear[2][1] = ( float )(-1.0) * ((Prp.y-vmid)/(Prp.z-Map->view_plane));
476 * Calculate the lower left coordinate of the view plane
477 * after the Shearing Transformation.
479 call_util_apply_trans2(Map->win.x_min, Map->win.y_min,
480 Map->view_plane, Shear, &(temp.x), &(temp.y), &(temp.z));
482 /* Translate the back plane to the origin */
483 Tpar[3][0] = ( float )(-1.0) * temp.x;
484 Tpar[3][1] = ( float )(-1.0) * temp.y;
485 Tpar[3][2] = ( float )(-1.0) * Map->back_plane;
487 call_util_mat_mul(Shear, Tpar, aux_mat1);
489 /* Calculation of Scaling transformation */
490 Spar[0][0] = ( float )1.0 / (Map->win.x_max - Map->win.x_min);
491 Spar[1][1] = ( float )1.0 / (Map->win.y_max - Map->win.y_min);
492 Spar[2][2] = ( float )1.0 / (Map->front_plane - Map->back_plane );
493 call_util_mat_mul (aux_mat1, Spar, aux_mat2);
494 /* Atlast we transformed view volume to NPC */
496 /* Translate and scale the view plane to projection view port */
497 if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
498 Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
499 Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
500 Map->proj_vp.x_min > Map->proj_vp.x_max ||
501 Map->proj_vp.y_min > Map->proj_vp.y_max ||
502 Map->proj_vp.z_min > Map->proj_vp.z_max){
508 aux_mat1[i][j] = (float)(i==j);
509 aux_mat1[0][0] = Map->proj_vp.x_max-Map->proj_vp.x_min;
510 aux_mat1[1][1] = Map->proj_vp.y_max-Map->proj_vp.y_min;
511 aux_mat1[2][2] = Map->proj_vp.z_max-Map->proj_vp.z_min;
512 aux_mat1[3][0] = Map->proj_vp.x_min;
513 aux_mat1[3][1] = Map->proj_vp.y_min;
514 aux_mat1[3][2] = Map->proj_vp.z_min;
515 call_util_mat_mul (aux_mat2, aux_mat1, mat);
523 else if (Map->proj_type == TYPE_PERSPECT)
530 Map->proj_vp.z_min = ( float )0.0;
531 Map->proj_vp.z_max = ( float )1.0;
535 F = Map->front_plane;
538 if(Prp.z == Map->view_plane){
539 /* Centre of Projection is on the view plane */
543 if(Map->proj_vp.x_min < 0.0 || Map->proj_vp.y_min < 0.0 ||
544 Map->proj_vp.z_min < 0.0 || Map->proj_vp.x_max > 1.0 ||
545 Map->proj_vp.y_max > 1.0 || Map->proj_vp.z_max > 1.0 ||
546 Map->proj_vp.x_min > Map->proj_vp.x_max ||
547 Map->proj_vp.y_min > Map->proj_vp.y_max ||
548 Map->proj_vp.z_min > Map->proj_vp.z_max ||
554 /* This is the transformation to move VRC to Center Of Projection */
555 Tprp[3][0] = ( float )(-1.0)*Prp.x;
556 Tprp[3][1] = ( float )(-1.0)*Prp.y;
557 Tprp[3][2] = ( float )(-1.0)*Prp.z;
559 /* Calculation of Shear matrix */
560 umid = ( float )(Map->win.x_min+Map->win.x_max)/( float )2.0-Prp.x;
561 vmid = ( float )(Map->win.y_min+Map->win.y_max)/( float )2.0-Prp.y;
562 Shear[2][0] = ( float )(-1.0)*umid/(Map->view_plane-Prp.z);
563 Shear[2][1] = ( float )(-1.0)*vmid/(Map->view_plane-Prp.z);
564 call_util_mat_mul(Tprp, Shear, aux_mat3);
566 /* Scale the view volume to canonical view volume
567 * Centre of projection at origin.
568 * 0 <= N <= -1, -0.5 <= U <= 0.5, -0.5 <= V <= 0.5
570 Scale[0][0] = (( float )(-1.0)*Prp.z+V)/
571 ((Map->win.x_max-Map->win.x_min)*(( float )(-1.0)*Prp.z+B));
572 Scale[1][1] = (( float )(-1.0)*Prp.z+V)/
573 ((Map->win.y_max-Map->win.y_min)*(( float )(-1.0)*Prp.z+B));
574 Scale[2][2] = ( float )(-1.0) / (( float )(-1.0)*Prp.z+B);
576 call_util_mat_mul(aux_mat3, Scale, aux_mat1);
579 * Transform the Perspective view volume into
580 * Parallel view volume.
581 * Lower left coordinate: (-0.5,-0.5, -1)
582 * Upper right coordinate: (0.5, 0.5, 1.0)
584 Zvmin = ( float )(-1.0*(-1.0*Prp.z+F)/(-1.0*Prp.z+B));
585 aux_mat2[2][2] = ( float )1.0/(( float )1.0+Zvmin);
586 aux_mat2[2][3] = ( float )(-1.0);
587 aux_mat2[3][2] = ( float )(-1.0)*Zvmin*aux_mat2[2][2];
588 aux_mat2[3][3] = ( float )0.0;
589 call_util_mat_mul(aux_mat1, aux_mat2, Shear);
593 aux_mat1[i][j] = aux_mat2[i][j] = (float)(i==j);
595 /* Translate and scale the view plane to projection view port */
596 aux_mat2[0][0] = (Map->proj_vp.x_max-Map->proj_vp.x_min);
597 aux_mat2[1][1] = (Map->proj_vp.y_max-Map->proj_vp.y_min);
598 aux_mat2[2][2] = (Map->proj_vp.z_max-Map->proj_vp.z_min);
599 aux_mat2[3][0] = aux_mat2[0][0]/( float )2.0+Map->proj_vp.x_min;
600 aux_mat2[3][1] = aux_mat2[1][1]/( float )2.0+Map->proj_vp.y_min;
601 aux_mat2[3][2] = aux_mat2[2][2]+Map->proj_vp.z_min;
602 call_util_mat_mul (Shear, aux_mat2, mat);
610 /*----------------------------------------------------------------------*/
613 call_util_apply_trans2( float ix, float iy, float iz, matrix3 mat,
614 float *ox, float *oy, float *oz )
617 *ox = ix*mat[0][0]+iy*mat[1][0]+iz*mat[2][0]+mat[3][0];
618 *oy = ix*mat[0][1]+iy*mat[1][1]+iz*mat[2][1]+mat[3][1];
619 *oz = ix*mat[0][2]+iy*mat[1][2]+iz*mat[2][2]+mat[3][2];
620 temp = ix * mat[0][3]+iy * mat[1][3]+iz * mat[2][3]+mat[3][3];
626 /*----------------------------------------------------------------------*/
629 call_util_mat_mul( matrix3 mat_a, matrix3 mat_b, matrix3 mat_c)
635 for (mat_c[i][j] = ( float )0.0,k=0; k<4; k++)
636 mat_c[i][j] += mat_a[i][k] * mat_b[k][j];
639 /*----------------------------------------------------------------------*/
641 //call_func_redraw_all_structs_proc
642 void OpenGl_View::Render (const Handle(OpenGl_Workspace) &AWorkspace,
643 const Graphic3d_CView& ACView,
644 const Aspect_CLayer2d& ACUnderLayer,
645 const Aspect_CLayer2d& ACOverLayer)
647 // Reset FLIST status after modification of myBackfacing
650 AWorkspace->NamedStatus &= ~OPENGL_NS_FLIST;
651 myResetFLIST = Standard_False;
654 // Store and disable current clipping planes
656 glGetIntegerv(GL_MAX_CLIP_PLANES, &maxplanes);
657 const GLenum lastid = GL_CLIP_PLANE0 + maxplanes;
658 OPENGL_CLIP_PLANE *oldPlanes = new OPENGL_CLIP_PLANE[maxplanes];
659 OPENGL_CLIP_PLANE *ptrPlane = oldPlanes;
660 GLenum planeid = GL_CLIP_PLANE0;
661 for ( ; planeid < lastid; planeid++, ptrPlane++ )
663 glGetClipPlane( planeid, ptrPlane->Equation );
664 if ( ptrPlane->isEnabled )
666 glDisable( planeid );
667 ptrPlane->isEnabled = GL_TRUE;
670 ptrPlane->isEnabled = GL_FALSE;
673 /////////////////////////////////////////////////////////////////////////////
674 // Step 1: Prepare for redraw
677 if ( (AWorkspace->NamedStatus & OPENGL_NS_WHITEBACK) == 0 &&
678 ( myBgTexture.TexId != 0 || myBgGradient.type != Aspect_GFM_NONE ) )
680 const Standard_Integer aViewWidth = AWorkspace->Width();
681 const Standard_Integer aViewHeight = AWorkspace->Height();
683 glPushAttrib( GL_ENABLE_BIT | GL_TEXTURE_BIT );
685 glMatrixMode( GL_PROJECTION );
688 glMatrixMode( GL_MODELVIEW );
692 if ( glIsEnabled( GL_DEPTH_TEST ) )
693 glDisable( GL_DEPTH_TEST ); //push GL_ENABLE_BIT
695 // drawing bg image if defined
696 if ( myBgTexture.TexId != 0 )
698 GLfloat texX_range = 1.F; // texture <s> coordinate
699 GLfloat texY_range = 1.F; // texture <t> coordinate
701 // Set up for stretching or tiling
702 GLfloat x_offset, y_offset;
703 if ( myBgTexture.Style == Aspect_FM_CENTERED )
705 x_offset = (GLfloat)myBgTexture.Width / (GLfloat)aViewWidth;
706 y_offset = (GLfloat)myBgTexture.Height / (GLfloat)aViewHeight;
712 if ( myBgTexture.Style == Aspect_FM_TILED )
714 texX_range = (GLfloat)aViewWidth / (GLfloat)myBgTexture.Width;
715 texY_range = (GLfloat)aViewHeight / (GLfloat)myBgTexture.Height;
719 glEnable( GL_TEXTURE_2D ); //push GL_ENABLE_BIT
720 glBindTexture( GL_TEXTURE_2D, myBgTexture.TexId ); //push GL_TEXTURE_BIT
722 glDisable( GL_BLEND ); //push GL_ENABLE_BIT
724 glColor3fv( AWorkspace->BackgroundColor().rgb );
725 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL); //push GL_TEXTURE_BIT
728 glTexCoord2f(0.F, 0.F); glVertex2f( -x_offset, -y_offset );
729 glTexCoord2f(texX_range, 0.F); glVertex2f( x_offset, -y_offset );
730 glTexCoord2f(texX_range, texY_range); glVertex2f( x_offset, y_offset );
731 glTexCoord2f(0.F, texY_range); glVertex2f( -x_offset, y_offset );
734 else //if( myBgGradient.type != Aspect_GFM_NONE )
736 Tfloat* corner1 = 0;/* -1,-1*/
737 Tfloat* corner2 = 0;/* 1,-1*/
738 Tfloat* corner3 = 0;/* 1, 1*/
739 Tfloat* corner4 = 0;/* -1, 1*/
743 switch( myBgGradient.type )
746 corner1 = myBgGradient.color2.rgb;
747 corner2 = myBgGradient.color2.rgb;
748 corner3 = myBgGradient.color1.rgb;
749 corner4 = myBgGradient.color1.rgb;
752 corner1 = myBgGradient.color2.rgb;
753 corner2 = myBgGradient.color1.rgb;
754 corner3 = myBgGradient.color1.rgb;
755 corner4 = myBgGradient.color2.rgb;
757 case Aspect_GFM_DIAG1:
758 corner2 = myBgGradient.color2.rgb;
759 corner4 = myBgGradient.color1.rgb;
760 dcorner1 [0] = dcorner2[0] = 0.5F * (corner2[0] + corner4[0]);
761 dcorner1 [1] = dcorner2[1] = 0.5F * (corner2[1] + corner4[1]);
762 dcorner1 [2] = dcorner2[2] = 0.5F * (corner2[2] + corner4[2]);
766 case Aspect_GFM_DIAG2:
767 corner1 = myBgGradient.color2.rgb;
768 corner3 = myBgGradient.color1.rgb;
769 dcorner1 [0] = dcorner2[0] = 0.5F * (corner1[0] + corner3[0]);
770 dcorner1 [1] = dcorner2[1] = 0.5F * (corner1[1] + corner3[1]);
771 dcorner1 [2] = dcorner2[2] = 0.5F * (corner1[2] + corner3[2]);
775 case Aspect_GFM_CORNER1:
776 corner1 = myBgGradient.color1.rgb;
777 corner2 = myBgGradient.color2.rgb;
778 corner3 = myBgGradient.color2.rgb;
779 corner4 = myBgGradient.color2.rgb;
781 case Aspect_GFM_CORNER2:
782 corner1 = myBgGradient.color2.rgb;
783 corner2 = myBgGradient.color1.rgb;
784 corner3 = myBgGradient.color2.rgb;
785 corner4 = myBgGradient.color2.rgb;
787 case Aspect_GFM_CORNER3:
788 corner1 = myBgGradient.color2.rgb;
789 corner2 = myBgGradient.color2.rgb;
790 corner3 = myBgGradient.color1.rgb;
791 corner4 = myBgGradient.color2.rgb;
793 case Aspect_GFM_CORNER4:
794 corner1 = myBgGradient.color2.rgb;
795 corner2 = myBgGradient.color2.rgb;
796 corner3 = myBgGradient.color2.rgb;
797 corner4 = myBgGradient.color1.rgb;
800 //printf("gradient background type not right\n");
804 // Save GL parameters
805 glDisable( GL_LIGHTING ); //push GL_ENABLE_BIT
808 glGetIntegerv( GL_SHADE_MODEL, &curSM );
809 if ( curSM != GL_SMOOTH )
810 glShadeModel( GL_SMOOTH ); //push GL_LIGHTING_BIT
812 glBegin(GL_TRIANGLE_FAN);
813 if( myBgGradient.type != Aspect_GFM_CORNER2 && myBgGradient.type != Aspect_GFM_CORNER4 )
815 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
816 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
817 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
818 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
820 else //if ( myBgGradient.type == Aspect_GFM_CORNER2 || myBgGradient.type == Aspect_GFM_CORNER4 )
822 glColor3f(corner2[0],corner2[1],corner2[2]); glVertex2f( 1.,-1.);
823 glColor3f(corner3[0],corner3[1],corner3[2]); glVertex2f( 1., 1.);
824 glColor3f(corner4[0],corner4[1],corner4[2]); glVertex2f(-1., 1.);
825 glColor3f(corner1[0],corner1[1],corner1[2]); glVertex2f(-1.,-1.);
829 // Restore GL parameters
830 if ( curSM != GL_SMOOTH )
831 glShadeModel( curSM );
835 glMatrixMode( GL_PROJECTION );
837 glMatrixMode( GL_MODELVIEW );
839 glPopAttrib(); //GL_ENABLE_BIT | GL_TEXTURE_BIT
841 if ( AWorkspace->UseZBuffer() )
842 glEnable( GL_DEPTH_TEST );
844 /* GL_DITHER on/off pour le trace */
845 if (AWorkspace->Dither())
846 glEnable (GL_DITHER);
848 glDisable (GL_DITHER);
851 // Switch off lighting by default
852 glDisable(GL_LIGHTING);
854 /////////////////////////////////////////////////////////////////////////////
855 // Step 2: Draw underlayer
856 RedrawLayer2d(AWorkspace, ACView, ACUnderLayer);
858 /////////////////////////////////////////////////////////////////////////////
859 // Step 3: Redraw main plane
861 // Setup face culling
862 GLboolean isCullFace = GL_FALSE;
865 isCullFace = glIsEnabled( GL_CULL_FACE );
866 if ( myBackfacing < 0 )
868 glEnable( GL_CULL_FACE );
869 glCullFace( GL_BACK );
872 glDisable( GL_CULL_FACE );
875 //TsmPushAttri(); /* save previous graphics context */
877 // if the view is scaled normal vectors are scaled to unit length for correct displaying of shaded objects
878 if(myExtra.scaleFactors[0] != 1.F ||
879 myExtra.scaleFactors[1] != 1.F ||
880 myExtra.scaleFactors[2] != 1.F)
881 glEnable(GL_NORMALIZE);
882 else if(glIsEnabled(GL_NORMALIZE))
883 glDisable(GL_NORMALIZE);
885 // Apply View Projection
886 // This routine activates the Projection matrix for a view.
888 glMatrixMode( GL_PROJECTION );
891 // add printing scale/tiling transformation
892 OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext(AWorkspace->GetGContext());
896 GLfloat aProjMatrix[16];
897 aPrinterContext->GetProjTransformation(aProjMatrix);
898 glLoadMatrixf((GLfloat*) aProjMatrix);
904 glMultMatrixf( (const GLfloat *) myMappingMatrix );
906 // Add translation necessary for the environnement mapping
907 if (mySurfaceDetail != Visual3d_TOD_NONE)
909 // OCC280: FitAll work incorrect for perspective view if the SurfaceDetail mode is V3d_TEX_ENVIRONMENT or V3d_TEX_ALL
910 // const GLfloat dep = vptr->vrep.extra.map.fpd * 0.5F;
911 const GLfloat dep = (myExtra.map.fpd + myExtra.map.bpd) * 0.5F;
912 glTranslatef(-dep*myExtra.vpn[0],-dep*myExtra.vpn[1],-dep*myExtra.vpn[2]);
916 AWorkspace->SetViewMatrix((const OpenGl_Matrix *)myOrientationMatrix);
919 While drawing after a clipplane has been defined and enabled, each vertex
920 is transformed to eye-coordinates, where it is dotted with the transformed
921 clipping plane equation. Eye-coordinate vertexes whose dot product with
922 the transformed clipping plane equation is positive or zero are in, and
923 require no clipping. Those eye-coordinate vertexes whose dot product is
924 negative are clipped. Because clipplane clipping is done in eye-
925 coordinates, changes to the projection matrix have no effect on its
928 A point and a normal are converted to a plane equation in the following manner:
943 D = -[Px,Py,Pz] dot |Nx|
949 glPushAttrib( GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT );
954 const GLfloat ramp = myExtra.map.fpd - myExtra.map.bpd;
955 const GLfloat fog_start = myFog.Front * ramp - myExtra.map.fpd;
956 const GLfloat fog_end = myFog.Back * ramp - myExtra.map.fpd;
958 glFogi(GL_FOG_MODE, GL_LINEAR);
959 glFogf(GL_FOG_START, fog_start);
960 glFogf(GL_FOG_END, fog_end);
961 glFogfv(GL_FOG_COLOR, myFog.Color.rgb);
971 // Switch off all lights
972 for (i = GL_LIGHT0; i <= GL_LIGHT7; i++)
974 glLightModelfv(GL_LIGHT_MODEL_AMBIENT, default_amb);
977 int gl_lid = GL_LIGHT0;
978 OpenGl_ListOfLight::Iterator itl(myLights);
979 for (; itl.More(); itl.Next())
981 const OpenGl_Light &alight = itl.Value();
982 bind_light(&alight, &gl_lid);
985 if (gl_lid != GL_LIGHT0) glEnable(GL_LIGHTING);
988 // Apply InteriorShadingMethod
989 glShadeModel( myIntShadingMethod == TEL_SM_FLAT ? GL_FLAT : GL_SMOOTH );
991 // Apply clipping planes
993 // Define starting plane id
994 planeid = GL_CLIP_PLANE0;
996 GLdouble equation[4];
998 if ( myZClip.Back.IsOn || myZClip.Front.IsOn )
1000 // Apply front and back clipping planes
1002 glMatrixMode( GL_MODELVIEW );
1003 glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) mat );
1006 const GLdouble ramp = myExtra.map.fpd - myExtra.map.bpd;
1008 if ( myZClip.Back.IsOn )
1010 const GLdouble back = ramp * myZClip.Back.Limit + myExtra.map.bpd;
1011 equation[0] = 0.0; /* Nx */
1012 equation[1] = 0.0; /* Ny */
1013 equation[2] = 1.0; /* Nz */
1014 equation[3] = -back; /* P dot N */
1015 glClipPlane( planeid, equation );
1016 glEnable( planeid );
1020 if ( myZClip.Front.IsOn )
1022 const GLdouble front = ramp * myZClip.Front.Limit + myExtra.map.bpd;
1023 equation[0] = 0.0; /* Nx */
1024 equation[1] = 0.0; /* Ny */
1025 equation[2] = -1.0; /* Nz */
1026 equation[3] = front; /* P dot N */
1027 glClipPlane( planeid, equation );
1028 glEnable( planeid );
1032 glLoadMatrixf( (GLfloat *) mat );
1035 // Apply user clipping planes
1036 NCollection_List<OPENGL_CLIP_REP>::Iterator planeIter(myClippingPlanes);
1037 for ( ; planeIter.More(); planeIter.Next() )
1039 glClipPlane( planeid, planeIter.Value().equation );
1040 glEnable( planeid );
1045 // Apply AntiAliasing
1048 AWorkspace->NamedStatus |= OPENGL_NS_ANTIALIASING;
1050 AWorkspace->NamedStatus &= ~OPENGL_NS_ANTIALIASING;
1053 Standard_Boolean isAnimationListOpen = Standard_False;
1055 // Request for update of animation mode?
1056 if ( (AWorkspace->NamedStatus & OPENGL_NS_UPDATEAM) != 0 )
1058 // Request to rebuild display list
1059 myAnimationListReady = Standard_False;
1060 // Reset request for update of animation mode
1061 AWorkspace->NamedStatus &= ~OPENGL_NS_UPDATEAM;
1064 // Is in animation mode?
1065 if ( AWorkspace->NamedStatus & OPENGL_NS_ANIMATION )
1067 // Is the animation list ready?
1068 if (myAnimationListReady)
1070 // Execute the animation list
1071 glCallList(myAnimationListIndex);
1075 // Update the animation list
1076 if ( AWorkspace->NamedStatus & OPENGL_NS_FLIST )
1078 if (myAnimationListIndex == 0)
1079 myAnimationListIndex = glGenLists(1);
1081 if (myAnimationListIndex != 0)
1083 glNewList(myAnimationListIndex, GL_COMPILE_AND_EXECUTE);
1084 isAnimationListOpen = Standard_True;
1088 AWorkspace->NamedStatus |= OPENGL_NS_FLIST;
1092 myAnimationListReady = Standard_False;
1094 if (!myAnimationListReady)
1096 // Clear status bitfields
1097 AWorkspace->NamedStatus &= ~(OPENGL_NS_2NDPASSNEED | OPENGL_NS_2NDPASSDO);
1099 // Added PCT for handling of textures
1100 switch (mySurfaceDetail)
1102 case Visual3d_TOD_NONE:
1103 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1106 RenderStructs(AWorkspace);
1109 case Visual3d_TOD_ENVIRONMENT:
1110 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1111 SetCurrentTexture(myTextureEnv);
1114 RenderStructs(AWorkspace);
1118 case Visual3d_TOD_ALL:
1120 AWorkspace->NamedStatus &= ~OPENGL_NS_FORBIDSETTEX;
1122 RenderStructs(AWorkspace);
1126 if (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED)
1128 AWorkspace->NamedStatus |= OPENGL_NS_2NDPASSDO;
1129 SetCurrentTexture(myTextureEnv);
1132 /* sauvegarde de quelques parametres OpenGL */
1133 GLint blend_dst, blend_src;
1136 glGetBooleanv(GL_DEPTH_WRITEMASK, &zbuff_w);
1137 glGetIntegerv(GL_DEPTH_FUNC, &zbuff_f);
1138 glGetIntegerv(GL_BLEND_DST, &blend_dst);
1139 glGetIntegerv(GL_BLEND_SRC, &blend_src);
1140 GLboolean zbuff_state = glIsEnabled(GL_DEPTH_TEST);
1141 GLboolean blend_state = glIsEnabled(GL_BLEND);
1143 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1146 glDepthFunc(GL_EQUAL);
1147 glDepthMask(GL_FALSE);
1148 glEnable(GL_DEPTH_TEST);
1150 AWorkspace->NamedStatus |= OPENGL_NS_FORBIDSETTEX;
1153 RenderStructs(AWorkspace);
1156 /* restauration des parametres OpenGL */
1157 glBlendFunc(blend_src, blend_dst);
1158 if (!blend_state) glDisable(GL_BLEND);
1160 glDepthFunc(zbuff_f);
1161 glDepthMask(zbuff_w);
1162 if (!zbuff_state) glDisable(GL_DEPTH_FUNC);
1167 if (isAnimationListOpen)
1170 myAnimationListReady = Standard_True;
1174 /* restore previous graphics context; before update lights */
1177 // Disable current clipping planes
1178 for ( planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++ )
1179 glDisable( planeid );
1181 /* affichage de Triedre Non Zoomable de la vue s'il existe */
1182 if (!myTrihedron.IsNull())
1183 myTrihedron->Render(AWorkspace);
1184 if (!myGraduatedTrihedron.IsNull())
1185 myGraduatedTrihedron->Render(AWorkspace);
1187 glPopAttrib(); // GL_FOG_BIT | GL_LIGHTING_BIT | GL_ENABLE_BIT
1189 // Restore face culling
1194 glEnable ( GL_CULL_FACE );
1195 glCullFace ( GL_BACK );
1198 glDisable ( GL_CULL_FACE );
1201 /////////////////////////////////////////////////////////////////////////////
1202 // Step 6: Draw overlayer
1203 const int aMode = 0;
1204 AWorkspace->DisplayCallback (ACView, (aMode | OCC_PRE_OVERLAY));
1206 RedrawLayer2d(AWorkspace, ACView, ACOverLayer);
1208 AWorkspace->DisplayCallback (ACView, aMode);
1210 // Restore clipping planes
1211 for ( ptrPlane = oldPlanes, planeid = GL_CLIP_PLANE0; planeid < lastid; planeid++, ptrPlane++ )
1213 glClipPlane( planeid, ptrPlane->Equation );
1214 if ( ptrPlane->isEnabled )
1215 glEnable( planeid );
1217 glDisable( planeid );
1222 /*----------------------------------------------------------------------*/
1224 //ExecuteViewDisplay
1225 void OpenGl_View::RenderStructs (const Handle(OpenGl_Workspace) &AWorkspace)
1227 if ( myStructures.NbStructures() <= 0 ) return;
1229 glPushAttrib ( GL_DEPTH_BUFFER_BIT );
1231 const OpenGl_AspectLine *aspect_line = AWorkspace->AspectLine( Standard_True );
1233 //TsmPushAttri(); /* save previous graphics context */
1235 if ( (AWorkspace->NamedStatus & OPENGL_NS_2NDPASSNEED) == 0 )
1237 const int antiAliasingMode = AWorkspace->GetDisplay()->AntiAliasingMode();
1239 if ( !myAntiAliasing )
1241 glDisable(GL_POINT_SMOOTH);
1242 glDisable(GL_LINE_SMOOTH);
1243 if( antiAliasingMode & 2 ) glDisable(GL_POLYGON_SMOOTH);
1244 glBlendFunc (GL_ONE, GL_ZERO);
1245 glDisable (GL_BLEND);
1249 glEnable(GL_POINT_SMOOTH);
1250 glEnable(GL_LINE_SMOOTH);
1251 if( antiAliasingMode & 2 ) glEnable(GL_POLYGON_SMOOTH);
1252 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1253 glEnable (GL_BLEND);
1257 myStructures.Render(AWorkspace);
1259 //TsmPopAttri(); /* restore previous graphics context; before update lights */
1261 if ( AWorkspace->DegenerateModel > 1 )
1263 glLineWidth ( aspect_line->Width() );
1264 if ( aspect_line->Type() != Aspect_TOL_SOLID ) glEnable ( GL_LINE_STIPPLE );
1270 /*----------------------------------------------------------------------*/
1272 //call_togl_redraw_layer2d
1273 void OpenGl_View::RedrawLayer2d (const Handle(OpenGl_Workspace) &AWorkspace, const Graphic3d_CView& ACView, const Aspect_CLayer2d& ACLayer)
1275 if (&ACLayer == NULL
1276 || ACLayer.ptrLayer == NULL
1277 || ACLayer.ptrLayer->listIndex == 0) return;
1279 GLsizei dispWidth = (GLsizei )ACLayer.viewport[0];
1280 GLsizei dispHeight = (GLsizei )ACLayer.viewport[1];
1282 const GLboolean isl = glIsEnabled(GL_LIGHTING); /*OCC6247*/
1284 glDisable(GL_LIGHTING); /*OCC6247*/
1287 * On positionne la projection
1289 glMatrixMode( GL_MODELVIEW );
1293 glMatrixMode (GL_PROJECTION);
1297 if (!ACLayer.sizeDependent)
1298 glViewport (0, 0, dispWidth, dispHeight);
1300 float left = ACLayer.ortho[0];
1301 float right = ACLayer.ortho[1];
1302 float bottom = ACLayer.ortho[2];
1303 float top = ACLayer.ortho[3];
1305 int attach = ACLayer.attach;
1308 if (!ACLayer.sizeDependent)
1309 ratio = (float) dispWidth/dispHeight;
1311 ratio = ACView.DefWindow.dx/ACView.DefWindow.dy;
1314 if (ratio >= 1.0) { /* fenetre horizontale */
1315 delta = (float )((top - bottom)/2.0);
1317 case 0: /* Aspect_TOC_BOTTOM_LEFT */
1318 top = bottom + 2*delta/ratio;
1320 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1321 top = bottom + 2*delta/ratio;
1323 case 2: /* Aspect_TOC_TOP_LEFT */
1324 bottom = top - 2*delta/ratio;
1326 case 3: /* Aspect_TOC_TOP_RIGHT */
1327 bottom = top - 2*delta/ratio;
1331 else { /* fenetre verticale */
1332 delta = (float )((right - left)/2.0);
1334 case 0: /* Aspect_TOC_BOTTOM_LEFT */
1335 right = left + 2*delta*ratio;
1337 case 1: /* Aspect_TOC_BOTTOM_RIGHT */
1338 left = right - 2*delta*ratio;
1340 case 2: /* Aspect_TOC_TOP_LEFT */
1341 right = left + 2*delta*ratio;
1343 case 3: /* Aspect_TOC_TOP_RIGHT */
1344 left = right - 2*delta*ratio;
1350 // Check printer context that exists only for print operation
1351 OpenGl_PrinterContext* aPrinterContext = OpenGl_PrinterContext::GetPrinterContext (AWorkspace->GetGContext());
1353 if (aPrinterContext)
1355 // additional transformation matrix could be applied to
1356 // render only those parts of viewport that will be
1357 // passed to a printer as a current "frame" to provide
1358 // tiling; scaling of graphics by matrix helps render a
1359 // part of a view (frame) in same viewport, but with higher
1361 GLfloat aProjMatrix[16];
1362 aPrinterContext->GetProjTransformation (aProjMatrix);
1363 glLoadMatrixf ((GLfloat*) aProjMatrix);
1365 // printing operation also assumes other viewport dimension
1366 // to comply with transformation matrix or graphics scaling
1367 // factors for tiling for layer redraw
1368 GLsizei anViewportX = 0;
1369 GLsizei anViewportY = 0;
1370 aPrinterContext->GetLayerViewport (anViewportX, anViewportY);
1371 if (anViewportX != 0 && anViewportY != 0)
1372 glViewport (0, 0, anViewportX, anViewportY);
1376 glOrtho (left, right, bottom, top, -1.0, 1.0);
1379 * On trace la display-list associee au layer.
1382 GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
1383 GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT | GL_TEXTURE_BIT );
1384 glDisable (GL_DEPTH_TEST);
1385 glCallList (ACLayer.ptrLayer->listIndex);
1387 //calling dynamic render of LayerItems
1388 if ( ACLayer.ptrLayer->layerData )
1390 InitLayerProp(ACLayer.ptrLayer->listIndex);
1391 ((Visual3d_Layer*)ACLayer.ptrLayer->layerData)->RenderLayerItems();
1398 * On retire la projection
1400 glMatrixMode (GL_PROJECTION);
1403 glMatrixMode( GL_MODELVIEW );
1407 * Restauration du Viewport en cas de modification
1409 if (!ACLayer.sizeDependent)
1410 glViewport (0, 0, (GLsizei) ACView.DefWindow.dx, (GLsizei) ACView.DefWindow.dy);
1415 glEnable(GL_LIGHTING); /*OCC6247*/
1418 /*----------------------------------------------------------------------*/
1420 //call_togl_create_bg_texture
1421 void OpenGl_View::CreateBackgroundTexture (const Standard_CString AFileName, const Aspect_FillMethod AFillStyle)
1423 // Delete existing texture
1424 if ( myBgTexture.TexId != 0 )
1426 glDeleteTextures( 1, (GLuint*)&(myBgTexture.TexId) );
1427 myBgTexture.TexId = 0;
1430 Standard_Integer width, height;
1431 Handle(Image_Image) image;
1432 if ( AlienImage::LoadImageFile( AFileName, image, width, height ) )
1434 const int nbbytes = width * height * 3;
1435 GLubyte *data = new GLubyte[nbbytes];
1436 GLubyte *pdata = data;
1437 Standard_Integer i, j;
1438 for ( j = height - 1; j >= 0; j-- )
1439 for ( i = 0; i < width; i++ )
1441 const Quantity_Color &color = image->PixelColor( i, j );
1442 *pdata++ = (GLubyte)( 255 * color.Red() );
1443 *pdata++ = (GLubyte)( 255 * color.Green() );
1444 *pdata++ = (GLubyte)( 255 * color.Blue() );
1448 glGenTextures( 1, &texture );
1449 glBindTexture( GL_TEXTURE_2D, texture );
1451 /* Create MipMapped Texture */
1452 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1453 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1454 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
1455 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST);
1457 gluBuild2DMipmaps( GL_TEXTURE_2D, 3/*4*/, width, height, GL_RGB, GL_UNSIGNED_BYTE, data );
1461 myBgTexture.TexId = texture;
1462 myBgTexture.Width = width;
1463 myBgTexture.Height = height;
1464 switch ( AFillStyle )
1466 case Aspect_FM_NONE :
1467 myBgTexture.Style = Aspect_FM_CENTERED;
1470 myBgTexture.Style = AFillStyle;
1476 /*----------------------------------------------------------------------*/
1478 //call_togl_set_bg_texture_style
1479 void OpenGl_View::SetBackgroundTextureStyle (const Aspect_FillMethod AFillStyle)
1481 /* check if background texture is already created */
1482 if ( myBgTexture.TexId != 0 )
1484 switch ( AFillStyle )
1486 case Aspect_FM_NONE :
1487 myBgTexture.Style = Aspect_FM_CENTERED;
1490 myBgTexture.Style = AFillStyle;
1496 /*----------------------------------------------------------------------*/
1498 //call_togl_gradient_background
1499 void OpenGl_View::SetBackgroundGradient (const Quantity_Color& AColor1,
1500 const Quantity_Color& AColor2,
1501 const Aspect_GradientFillMethod AType)
1503 Standard_Real R,G,B;
1504 AColor1.Values( R, G, B, Quantity_TOC_RGB );
1505 myBgGradient.color1.rgb[0] = ( Tfloat )R;
1506 myBgGradient.color1.rgb[1] = ( Tfloat )G;
1507 myBgGradient.color1.rgb[2] = ( Tfloat )B;
1508 myBgGradient.color1.rgb[3] = 0.F;
1510 AColor2.Values( R, G, B, Quantity_TOC_RGB );
1511 myBgGradient.color2.rgb[0] = ( Tfloat )R;
1512 myBgGradient.color2.rgb[1] = ( Tfloat )G;
1513 myBgGradient.color2.rgb[2] = ( Tfloat )B;
1514 myBgGradient.color2.rgb[3] = 0.F;
1516 myBgGradient.type = AType;
1519 /*----------------------------------------------------------------------*/
1521 //call_togl_set_gradient_type
1522 void OpenGl_View::SetBackgroundGradientType (const Aspect_GradientFillMethod AType)
1524 // check if gradient background is already created
1525 if ( myBgGradient.type != Aspect_GFM_NONE )
1526 myBgGradient.type = AType;
1529 /*----------------------------------------------------------------------*/