1 // Created on: 2011-09-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
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.
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.
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.
20 #include <OpenGl_GlCore11.hxx>
26 #include <InterfaceGraphic_Graphic3d.hxx> /* pour CALL_DEF_STRUCTURE */
27 #include <InterfaceGraphic_Aspect.hxx> /* pour CALL_DEF_VIEW */
28 #include <InterfaceGraphic_Visual3d.hxx>
30 #include <OpenGl_transform_persistence.hxx>
32 #include <OpenGl_Workspace.hxx>
33 #include <OpenGl_View.hxx>
34 #include <OpenGl_Trihedron.hxx>
36 static const OpenGl_TextParam THE_LABEL_PARAMS =
38 16, Graphic3d_HTA_LEFT, Graphic3d_VTA_BOTTOM
41 static const CALL_DEF_CONTEXTLINE myDefaultContextLine =
45 { 1.F, 1.F, 1.F }, //Color
46 Aspect_TOL_SOLID, //LineType
50 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
57 { 1.F, 1.F, 1.F }, //Color
58 Aspect_TOST_NORMAL, //Style
59 Aspect_TODT_NORMAL, //DisplayType
60 { 1.F, 1.F, 1.F }, //ColorSubTitle
63 Font_FA_Regular //TextFontAspect
66 /*----------------------------------------------------------------------*/
71 /* Default parameters for ZBUFFER triheron */
72 static TEL_COLOUR theXColor = {{ 1.F, 0.F, 0.F, 0.6F }};
73 static TEL_COLOUR theYColor = {{ 0.F, 1.F, 0.F, 0.6F }};
74 static TEL_COLOUR theZColor = {{ 0.F, 0.F, 1.F, 0.6F }};
75 static float theRatio = 0.8f;
76 static float theDiameter = 0.05f;
77 static int theNbFacettes = 12;
79 /*----------------------------------------------------------------------*/
82 * affichage d'un triedre non zoomable a partir des index dans les tables
83 * des structures non zoomables.
85 * Triedre = Objet non Zoomable :
86 * on recalcule ses dimensions et son origine en fonction de la taille
87 * de la fenetre; on positionne selon le choix de l'init;
88 * et on inhibe seulement les translations.
92 //call_triedron_redraw
93 void OpenGl_Trihedron::redraw (const Handle(OpenGl_Workspace)& theWorkspace) const
95 const Standard_Real U = theWorkspace->ActiveView()->Height();
96 const Standard_Real V = theWorkspace->ActiveView()->Width();
98 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
99 /* de la dimension la plus petite de la window. */
100 const GLdouble L = ( U < V ? U : V ) * myScale;
103 * On inhibe les translations; on conserve les autres transformations.
106 /* on lit les matrices de transformation et de projection de la vue */
107 /* pour annuler les translations (dernieres colonnes des matrices). */
108 GLdouble modelMatrix[4][4];
109 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
110 GLdouble projMatrix[4][4];
111 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
113 /* on annule la translation qui peut etre affectee a la vue */
114 modelMatrix[3][0] = 0.;
115 modelMatrix[3][1] = 0.;
116 modelMatrix[3][2] = 0.;
117 projMatrix[3][0] = 0.;
118 projMatrix[3][1] = 0.;
119 projMatrix[3][2] = 0.;
121 /* sauvegarde du contexte des matrices avant chargement */
122 glMatrixMode (GL_MODELVIEW);
124 glLoadMatrixd( (GLdouble *) modelMatrix );
125 glMatrixMode ( GL_PROJECTION );
127 glLoadMatrixd( (GLdouble *) projMatrix );
130 * Positionnement de l'origine du triedre selon le choix de l'init
133 /* on fait uniquement une translation de l'origine du Triedre */
137 case Aspect_TOTP_LEFT_LOWER :
138 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
141 case Aspect_TOTP_LEFT_UPPER :
142 glTranslated( -0.5*U + L , +0.5*V - L -L/3., 0. );
145 case Aspect_TOTP_RIGHT_LOWER :
146 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
149 case Aspect_TOTP_RIGHT_UPPER :
150 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
153 //case Aspect_TOTP_CENTER :
159 * Creation du triedre
162 /* Fotis Sioutis 2007-11-14 15:06
163 I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode
164 changes colors depending on the state of the view. This behaviour can be easily
165 corrected by altering call_triedron_redraw function in OpenGl_triedron.c of TKOpengl.
166 The only change needed is to erase glDisable(GL_LIGHTING) that is called before the
167 Axis name drawing and move this function call just before the initial axis drawing.
168 Below is the code portion with the modification.I don't know if this is considered to
169 be a bug but anyway i believe it might help some of you out there.*/
170 glDisable(GL_LIGHTING);
172 /* Position de l'origine */
173 const GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
175 /* Position des Axes */
176 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
177 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
178 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
179 TriedronAxeX[0] = L ;
180 TriedronAxeY[1] = L ;
181 TriedronAxeZ[2] = L ;
183 /* dessin des axes */
185 glVertex3dv( TriedronOrigin );
186 glVertex3dv( TriedronAxeX );
188 glVertex3dv( TriedronOrigin );
189 glVertex3dv( TriedronAxeY );
191 glVertex3dv( TriedronOrigin );
192 glVertex3dv( TriedronAxeZ );
195 /* fleches au bout des axes (= cones de la couleur demandee) */
196 const GLdouble l = 0.75*L; /* distance a l'origine */
197 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
198 const int NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
199 const double Angle = 2. * M_PI/ NbFacettes;
202 GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
204 /* solution FILAIRE des cones au bout des axes : une seule ligne */
205 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
206 /* (la couleur est deja initialisee dans AspectLine) */
207 /* FIN de la solution FILAIRE CHOISIE pour les cones des axes */
210 glBegin(GL_TRIANGLE_FAN);
211 glVertex3dv( TriedronAxeX );
212 TriedronCoord[0] = l;
215 TriedronCoord[1] = rayon * sin(ii * Angle);
216 TriedronCoord[2] = rayon * cos(ii * Angle);
217 glVertex3dv( TriedronCoord );
223 glBegin(GL_TRIANGLE_FAN);
224 glVertex3dv( TriedronAxeY );
225 TriedronCoord[1] = l;
228 TriedronCoord[0] = rayon * cos(ii * Angle);
229 TriedronCoord[2] = rayon * sin(ii * Angle);
230 glVertex3dv( TriedronCoord );
236 glBegin(GL_TRIANGLE_FAN);
237 glVertex3dv( TriedronAxeZ );
238 TriedronCoord[2] = l;
241 TriedronCoord[0] = rayon * sin(ii * Angle);
242 TriedronCoord[1] = rayon * cos(ii * Angle);
243 glVertex3dv( TriedronCoord );
248 /* dessin de l'origine */
249 TriedronCoord[2] = 0.0 ;
251 const double Angle1 = 2. * M_PI/ ii;
252 glBegin(GL_LINE_LOOP);
254 TriedronCoord[0] = rayon * sin(ii * Angle1);
255 TriedronCoord[1] = rayon * cos(ii * Angle1);
256 glVertex3dv( TriedronCoord );
262 myLabelX.SetPosition (OpenGl_Vec3(float(L + rayon), 0.0f, float(-rayon)));
263 myLabelY.SetPosition (OpenGl_Vec3(float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon)));
264 myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon)));
265 myLabelX.Render (theWorkspace);
266 myLabelY.Render (theWorkspace);
267 myLabelZ.Render (theWorkspace);
270 * restauration du contexte des matrices
272 glMatrixMode (GL_PROJECTION);
274 glMatrixMode (GL_MODELVIEW);
279 /*******************************************************
280 * Draws ZBUFFER trihedron mode
281 *******************************************************/
282 //call_zbuffer_triedron_redraw
283 void OpenGl_Trihedron::redrawZBuffer (const Handle(OpenGl_Workspace)& theWorkspace) const
285 const Standard_Real U = theWorkspace->ActiveView()->Height();
286 const Standard_Real V = theWorkspace->ActiveView()->Width();
288 GLdouble modelMatrix[4][4];
289 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
290 GLdouble projMatrix[4][4];
291 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
293 /* Check position in the ViewPort */
295 /* Simple code modification recommended by Fotis Sioutis and Peter Dolbey */
296 /* to remove the irritating default behaviour of triedrons using V3d_ZBUFFER */
297 /* which causes the glyph to jump around the screen when the origin moves offscreen. */
298 GLboolean isWithinView = GL_FALSE;
300 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
301 /* de la dimension la plus petite de la window. */
302 GLdouble L = ( U < V ? U : V ) * myScale;
306 /* Annulate translation matrix */
307 modelMatrix[3][0] = 0.;
308 modelMatrix[3][1] = 0.;
309 modelMatrix[3][2] = 0.;
310 projMatrix[3][0] = 0.;
311 projMatrix[3][1] = 0.;
312 projMatrix[3][2] = 0.;
315 glMatrixMode (GL_MODELVIEW);
318 glLoadMatrixd( (GLdouble *) modelMatrix);
319 glMatrixMode ( GL_PROJECTION );
322 glLoadMatrixd( (GLdouble *) projMatrix);
325 * Define position in the view
329 case Aspect_TOTP_LEFT_LOWER :
330 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
333 case Aspect_TOTP_LEFT_UPPER :
334 glTranslated( -0.5*U + L , +0.5*V - L -L/3. , 0. );
337 case Aspect_TOTP_RIGHT_LOWER :
338 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
341 case Aspect_TOTP_RIGHT_UPPER :
342 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
345 //case Aspect_TOTP_CENTER :
352 const OpenGl_AspectLine *AspectLine = theWorkspace->AspectLine( Standard_True );
353 const TEL_COLOUR &aLineColor = AspectLine->Color();
356 * Creation the trihedron
358 #define CYLINDER_LENGTH 0.75f
360 const GLuint startList = glGenLists(4);
361 GLUquadricObj* aQuadric = gluNewQuadric();
363 const GLboolean aIsDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
365 GLboolean aIsDepthMaskEnabled;
367 /* GL_DEPTH_WRITEMASK is not a valid argument to glIsEnabled, the */
368 /* original code is shown to be broken when run under an OpenGL debugger */
369 /* like GLIntercept. This is the correct way to retrieve the mask value. */
370 glGetBooleanv(GL_DEPTH_WRITEMASK, &aIsDepthMaskEnabled);
372 const GLdouble aCylinderLength = L * CYLINDER_LENGTH;
373 const GLdouble aCylinderDiametr = L * myDiameter;
374 const GLdouble aConeDiametr = aCylinderDiametr * 2.;
375 const GLdouble aConeLength = L * (1 - CYLINDER_LENGTH);
376 /* Correct for owerlapping */
377 /* aCylinderLength += aConeLength - 1.2*aCylinderDiametr*aConeLength/aConeDiametr;*/
379 /* Create cylinder for axis */
380 gluQuadricDrawStyle(aQuadric, GLU_FILL); /* smooth shaded */
381 gluQuadricNormals(aQuadric, GLU_FLAT);
383 glNewList(startList, GL_COMPILE);
384 gluCylinder(aQuadric, aCylinderDiametr, aCylinderDiametr, aCylinderLength, myNbFacettes, 1);
387 glNewList(startList + 1, GL_COMPILE);
388 gluCylinder(aQuadric, aConeDiametr, 0., aConeLength, myNbFacettes, 1);
391 glNewList(startList + 2, GL_COMPILE);
392 gluSphere(aQuadric, aCylinderDiametr * 2., myNbFacettes, myNbFacettes);
395 gluQuadricOrientation(aQuadric,GLU_INSIDE); /*szv*/
396 glNewList(startList + 3, GL_COMPILE);
397 gluDisk(aQuadric, aCylinderDiametr, aConeDiametr, myNbFacettes, 1/*szv:2*/);
400 /* Store previous attributes */
401 glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
402 glEnable(GL_LIGHTING);
405 glEnable(GL_CULL_FACE);
407 /*Fotis Sioutis | 2008-01-21 10:55
408 In the function call_zbuffer_triedron_redraw of TKOpengl,
409 the z buffered trihedron changes colors in case there
410 is an object in the scene that has an explicit material
411 attached to it.In the trihedron display loop,
412 GL_COLOR_MATERIAL is enabled, but only the GL_DIFFUSE
413 parameter is utilized in glColorMaterial(...).
414 This causes the last ambient,specular and emission values
415 used, to stay at the stack and applied to the trihedron
416 (which causes the color change).
417 A fix is proposed , to change GL_DIFFUSE to
418 GL_AMBIENT_AND_DIFFUSE in glColorMaterial call in
419 line 946.The above of course will leave unchanged
420 the SPECULAR and EMISSION values.
421 Another proposal which would fix 100% the problem
422 is to use glMaterial instead of glColor on the trihedron
424 const GLfloat aNULLColor[] = { 0.f, 0.f, 0.f, 0.f }; /* FS 21/01/08 */
425 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aNULLColor);
426 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, aNULLColor);
427 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, aNULLColor);
428 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.f);
430 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
431 glEnable(GL_COLOR_MATERIAL);
433 if (!aIsDepthEnabled) {
434 glEnable(GL_DEPTH_TEST);
435 glClear(GL_DEPTH_BUFFER_BIT);
438 if (!aIsDepthMaskEnabled) {
439 /* This is how the depthmask needs to be re-enabled...*/
440 glDepthMask(GL_TRUE);
441 /* ...and not this stuff below */
444 /* Position des Axes */
445 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
446 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
447 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
452 glMatrixMode(GL_MODELVIEW);
456 glGetIntegerv (GL_DEPTH_FUNC, &df);
459 for (i = 0; i < 2; i++) /* PCD 11/02/08 Two pass method */
461 if (i == 0) /* First pass */
463 glDepthFunc(GL_ALWAYS);
467 glDepthFunc(GL_LEQUAL);
474 glColor3fv(aLineColor.rgb);
475 glCallList(startList+2);
478 glColor4fv(myZColor.rgb);
479 glCallList(startList);
480 glTranslated(0, 0, L * CYLINDER_LENGTH);
481 glCallList(startList + 3);
482 glCallList(startList + 1);
486 glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
487 glColor4fv(myXColor.rgb);
488 glCallList(startList);
489 glTranslated(0, 0, L * CYLINDER_LENGTH);
490 glCallList(startList + 3);
491 glCallList(startList + 1);
495 glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
496 glColor4fv(myYColor.rgb);
497 glCallList(startList);
498 glTranslated(0, 0, L * CYLINDER_LENGTH);
499 glCallList(startList + 3);
500 glCallList(startList + 1);
504 if (!aIsDepthEnabled)
505 glDisable(GL_DEPTH_TEST);
507 if (!aIsDepthMaskEnabled)
508 glDepthMask(GL_FALSE);
510 glDisable(GL_CULL_FACE);
511 glDisable(GL_COLOR_MATERIAL);
513 gluDeleteQuadric(aQuadric);
514 glColor3fv (aLineColor.rgb);
516 /* Always write the text */
517 glDepthFunc(GL_ALWAYS);
521 /* fleches au bout des axes (= cones de la couleur demandee) */
522 //const GLdouble l = 0.75*L; /* distance a l'origine */
523 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
524 //const double Angle = 2. * M_PI/ myNbFacettes;
526 glDeleteLists(startList, 4);
528 glDisable(GL_LIGHTING);
531 myLabelX.SetPosition (OpenGl_Vec3(float(L + rayon), 0.0f, float(-rayon)));
532 myLabelY.SetPosition (OpenGl_Vec3(float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon)));
533 myLabelZ.SetPosition (OpenGl_Vec3(float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon)));
534 myLabelX.Render (theWorkspace);
535 myLabelY.Render (theWorkspace);
536 myLabelZ.Render (theWorkspace);
541 if (!isWithinView) { /* restore matrix */
542 glMatrixMode (GL_PROJECTION);
544 glMatrixMode (GL_MODELVIEW);
550 /*----------------------------------------------------------------------*/
552 /*----------------------------------------------------------------------*/
554 * Fonctions publiques
559 * initialisation d'un triedre non zoomable dans une vue.
560 * ou modification des valeurs deja initialisees.
564 OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition thePosition,
565 const Quantity_NameOfColor theColor,
566 const Standard_Real theScale,
567 const Standard_Boolean theAsWireframe)
568 : myPos (thePosition),
570 myIsWireframe (theAsWireframe),
571 myLabelX (TCollection_ExtendedString ("X"), OpenGl_Vec3(1.0f, 0.0f, 0.0f), THE_LABEL_PARAMS),
572 myLabelY (TCollection_ExtendedString ("Y"), OpenGl_Vec3(0.0f, 1.0f, 0.0f), THE_LABEL_PARAMS),
573 myLabelZ (TCollection_ExtendedString ("Z"), OpenGl_Vec3(0.0f, 0.0f, 1.0f), THE_LABEL_PARAMS)
576 Quantity_Color aColor (theColor);
577 aColor.Values (R, G, B, Quantity_TOC_RGB);
579 CALL_DEF_CONTEXTLINE aLineAspect = myDefaultContextLine;
580 aLineAspect.Color.r = (float)R;
581 aLineAspect.Color.g = (float)G;
582 aLineAspect.Color.b = (float)B;
583 myAspectLine.SetAspect (aLineAspect);
585 CALL_DEF_CONTEXTTEXT aTextAspect = myDefaultContextText;
586 aTextAspect.Color.r = (float)R;
587 aTextAspect.Color.g = (float)G;
588 aTextAspect.Color.b = (float)B;
589 myAspectText.SetAspect (aTextAspect);
591 myXColor = theXColor;
592 myYColor = theYColor;
593 myZColor = theZColor;
596 myDiameter = theDiameter;
597 myNbFacettes = theNbFacettes;
600 /*----------------------------------------------------------------------*/
603 * destruction du triedre non zoomable d'une vue.
606 //call_triedron_erase
607 OpenGl_Trihedron::~OpenGl_Trihedron()
611 // =======================================================================
612 // function : Release
614 // =======================================================================
615 void OpenGl_Trihedron::Release (const Handle(OpenGl_Context)& theCtx)
617 myLabelX.Release (theCtx);
618 myLabelY.Release (theCtx);
619 myLabelZ.Release (theCtx);
622 /*----------------------------------------------------------------------*/
625 * affichage d'un triedre non zoomable dans la wks awsid
627 * Triedre = Objet non Zoomable;
628 * on cree cette fonction pour pouvoir travailler par les structures
629 * utilisees par les fonctions Tsm* et TEL_VIEW_REP
633 //call_triedron_redraw_from_wsid
634 void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
636 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->SetAspectLine (&myAspectLine);
637 const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectText);
639 /* check if GL_LIGHTING should be disabled
640 no enabling 'cause it will be done (if necessary: kinda Polygon types )
641 during redrawing structures
643 if (!theWorkspace->UseGLLight())
645 glDisable (GL_LIGHTING);
648 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
650 /* affichage du Triedre Non Zoomable */
651 theWorkspace->ActiveView()->EndTransformPersistence();
655 redraw (theWorkspace);
659 redrawZBuffer (theWorkspace);
663 if (!aPrevTexture.IsNull())
665 theWorkspace->EnableTexture (aPrevTexture);
668 theWorkspace->SetAspectText (aPrevAspectText);
669 theWorkspace->SetAspectLine (aPrevAspectLine);
672 /*----------------------------------------------------------------------*/
673 //call_ztriedron_setup
674 void OpenGl_Trihedron::Setup (const Quantity_NameOfColor XColor, const Quantity_NameOfColor YColor, const Quantity_NameOfColor ZColor,
675 const Standard_Real SizeRatio, const Standard_Real AxisDiametr, const Standard_Integer NbFacettes)
679 Quantity_Color(XColor).Values(R, G, B, Quantity_TOC_RGB);
680 theXColor.rgb[0] = float (R);
681 theXColor.rgb[1] = float (G);
682 theXColor.rgb[2] = float (B);
684 Quantity_Color(YColor).Values(R, G, B, Quantity_TOC_RGB);
685 theYColor.rgb[0] = float (R);
686 theYColor.rgb[1] = float (G);
687 theYColor.rgb[2] = float (B);
689 Quantity_Color(ZColor).Values(R, G, B, Quantity_TOC_RGB);
690 theZColor.rgb[0] = float (R);
691 theZColor.rgb[1] = float (G);
692 theZColor.rgb[2] = float (B);
694 theRatio = float (SizeRatio);
695 theDiameter = float (AxisDiametr);
696 theNbFacettes = NbFacettes;