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.
21 #include <OpenGl_GlCore11.hxx>
27 #include <InterfaceGraphic_Graphic3d.hxx> /* pour CALL_DEF_STRUCTURE */
28 #include <InterfaceGraphic_Aspect.hxx> /* pour CALL_DEF_VIEW */
29 #include <InterfaceGraphic_Visual3d.hxx>
31 #include <OpenGl_transform_persistence.hxx>
33 #include <OpenGl_Workspace.hxx>
34 #include <OpenGl_View.hxx>
35 #include <OpenGl_Trihedron.hxx>
37 #include <GL/glu.h> // gluNewQuadric()
39 IMPLEMENT_STANDARD_HANDLE(OpenGl_Trihedron,MMgt_TShared)
40 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Trihedron,MMgt_TShared)
42 static const CALL_DEF_CONTEXTLINE myDefaultContextLine =
46 { 1.F, 1.F, 1.F }, //Color
47 Aspect_TOL_SOLID, //LineType
51 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
58 { 1.F, 1.F, 1.F }, //Color
59 Aspect_TOST_NORMAL, //Style
60 Aspect_TODT_NORMAL, //DisplayType
61 { 1.F, 1.F, 1.F }, //ColorSubTitle
64 Font_FA_Regular //TextFontAspect
67 /*----------------------------------------------------------------------*/
72 /* Default parameters for ZBUFFER triheron */
73 static TEL_COLOUR theXColor = {{ 1.F, 0.F, 0.F, 0.6F }};
74 static TEL_COLOUR theYColor = {{ 0.F, 1.F, 0.F, 0.6F }};
75 static TEL_COLOUR theZColor = {{ 0.F, 0.F, 1.F, 0.6F }};
76 static float theRatio = 0.8f;
77 static float theDiameter = 0.05f;
78 static int theNbFacettes = 12;
80 /*----------------------------------------------------------------------*/
83 * affichage d'un triedre non zoomable a partir des index dans les tables
84 * des structures non zoomables.
86 * Triedre = Objet non Zoomable :
87 * on recalcule ses dimensions et son origine en fonction de la taille
88 * de la fenetre; on positionne selon le choix de l'init;
89 * et on inhibe seulement les translations.
93 //call_triedron_redraw
94 void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
96 const Standard_Real U = AWorkspace->ActiveView()->Height();
97 const Standard_Real V = AWorkspace->ActiveView()->Width();
99 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
100 /* de la dimension la plus petite de la window. */
101 const GLdouble L = ( U < V ? U : V ) * myScale;
104 * On inhibe les translations; on conserve les autres transformations.
107 /* on lit les matrices de transformation et de projection de la vue */
108 /* pour annuler les translations (dernieres colonnes des matrices). */
109 GLdouble modelMatrix[4][4];
110 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
111 GLdouble projMatrix[4][4];
112 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
114 /* on annule la translation qui peut etre affectee a la vue */
115 modelMatrix[3][0] = 0.;
116 modelMatrix[3][1] = 0.;
117 modelMatrix[3][2] = 0.;
118 projMatrix[3][0] = 0.;
119 projMatrix[3][1] = 0.;
120 projMatrix[3][2] = 0.;
122 /* sauvegarde du contexte des matrices avant chargement */
123 glMatrixMode (GL_MODELVIEW);
125 glLoadMatrixd( (GLdouble *) modelMatrix );
126 glMatrixMode ( GL_PROJECTION );
128 glLoadMatrixd( (GLdouble *) projMatrix );
131 * Positionnement de l'origine du triedre selon le choix de l'init
134 /* on fait uniquement une translation de l'origine du Triedre */
138 case Aspect_TOTP_LEFT_LOWER :
139 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
142 case Aspect_TOTP_LEFT_UPPER :
143 glTranslated( -0.5*U + L , +0.5*V - L -L/3., 0. );
146 case Aspect_TOTP_RIGHT_LOWER :
147 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
150 case Aspect_TOTP_RIGHT_UPPER :
151 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
154 //case Aspect_TOTP_CENTER :
160 * Creation du triedre
162 const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
164 /* Fotis Sioutis 2007-11-14 15:06
165 I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode
166 changes colors depending on the state of the view. This behaviour can be easily
167 corrected by altering call_triedron_redraw function in OpenGl_triedron.c of TKOpengl.
168 The only change needed is to erase glDisable(GL_LIGHTING) that is called before the
169 Axis name drawing and move this function call just before the initial axis drawing.
170 Below is the code portion with the modification.I don't know if this is considered to
171 be a bug but anyway i believe it might help some of you out there.*/
172 glDisable(GL_LIGHTING);
174 /* Position de l'origine */
175 const GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
177 /* Position des Axes */
178 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
179 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
180 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
181 TriedronAxeX[0] = L ;
182 TriedronAxeY[1] = L ;
183 TriedronAxeZ[2] = L ;
185 /* dessin des axes */
187 glVertex3dv( TriedronOrigin );
188 glVertex3dv( TriedronAxeX );
190 glVertex3dv( TriedronOrigin );
191 glVertex3dv( TriedronAxeY );
193 glVertex3dv( TriedronOrigin );
194 glVertex3dv( TriedronAxeZ );
197 /* fleches au bout des axes (= cones de la couleur demandee) */
198 const GLdouble l = 0.75*L; /* distance a l'origine */
199 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
200 const int NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
201 const double Angle = 2. * M_PI/ NbFacettes;
204 GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
206 /* solution FILAIRE des cones au bout des axes : une seule ligne */
207 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
208 /* (la couleur est deja initialisee dans AspectLine) */
209 /* FIN de la solution FILAIRE CHOISIE pour les cones des axes */
212 glBegin(GL_TRIANGLE_FAN);
213 glVertex3dv( TriedronAxeX );
214 TriedronCoord[0] = l;
217 TriedronCoord[1] = rayon * sin(ii * Angle);
218 TriedronCoord[2] = rayon * cos(ii * Angle);
219 glVertex3dv( TriedronCoord );
225 glBegin(GL_TRIANGLE_FAN);
226 glVertex3dv( TriedronAxeY );
227 TriedronCoord[1] = l;
230 TriedronCoord[0] = rayon * cos(ii * Angle);
231 TriedronCoord[2] = rayon * sin(ii * Angle);
232 glVertex3dv( TriedronCoord );
238 glBegin(GL_TRIANGLE_FAN);
239 glVertex3dv( TriedronAxeZ );
240 TriedronCoord[2] = l;
243 TriedronCoord[0] = rayon * sin(ii * Angle);
244 TriedronCoord[1] = rayon * cos(ii * Angle);
245 glVertex3dv( TriedronCoord );
250 /* dessin de l'origine */
251 TriedronCoord[2] = 0.0 ;
253 const double Angle1 = 2. * M_PI/ ii;
254 glBegin(GL_LINE_LOOP);
256 TriedronCoord[0] = rayon * sin(ii * Angle1);
257 TriedronCoord[1] = rayon * cos(ii * Angle1);
258 glVertex3dv( TriedronCoord );
264 * Noms des axes et de l'origine
266 const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
267 glColor3fv (AspectText->Color().rgb);
269 AWorkspace->RenderText (L"X", 0, float(L + rayon), 0.0f, float(-rayon));
270 AWorkspace->RenderText (L"Y", 0, float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon));
271 AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon));
274 * restauration du contexte des matrices
276 glMatrixMode (GL_PROJECTION);
278 glMatrixMode (GL_MODELVIEW);
283 /*******************************************************
284 * Draws ZBUFFER trihedron mode
285 *******************************************************/
286 //call_zbuffer_triedron_redraw
287 void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace) const
289 const Standard_Real U = AWorkspace->ActiveView()->Height();
290 const Standard_Real V = AWorkspace->ActiveView()->Width();
292 GLdouble modelMatrix[4][4];
293 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
294 GLdouble projMatrix[4][4];
295 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
297 /* Check position in the ViewPort */
299 /* Simple code modification recommended by Fotis Sioutis and Peter Dolbey */
300 /* to remove the irritating default behaviour of triedrons using V3d_ZBUFFER */
301 /* which causes the glyph to jump around the screen when the origin moves offscreen. */
302 GLboolean isWithinView = GL_FALSE;
304 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
305 /* de la dimension la plus petite de la window. */
306 GLdouble L = ( U < V ? U : V ) * myScale;
310 /* Annulate translation matrix */
311 modelMatrix[3][0] = 0.;
312 modelMatrix[3][1] = 0.;
313 modelMatrix[3][2] = 0.;
314 projMatrix[3][0] = 0.;
315 projMatrix[3][1] = 0.;
316 projMatrix[3][2] = 0.;
319 glMatrixMode (GL_MODELVIEW);
322 glLoadMatrixd( (GLdouble *) modelMatrix);
323 glMatrixMode ( GL_PROJECTION );
326 glLoadMatrixd( (GLdouble *) projMatrix);
329 * Define position in the view
333 case Aspect_TOTP_LEFT_LOWER :
334 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
337 case Aspect_TOTP_LEFT_UPPER :
338 glTranslated( -0.5*U + L , +0.5*V - L -L/3. , 0. );
341 case Aspect_TOTP_RIGHT_LOWER :
342 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
345 case Aspect_TOTP_RIGHT_UPPER :
346 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
349 //case Aspect_TOTP_CENTER :
356 const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
357 const TEL_COLOUR &aLineColor = AspectLine->Color();
360 * Creation the trihedron
362 #define CYLINDER_LENGTH 0.75f
364 const GLuint startList = glGenLists(4);
365 GLUquadricObj* aQuadric = gluNewQuadric();
367 const GLboolean aIsDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
369 GLboolean aIsDepthMaskEnabled;
371 /* GL_DEPTH_WRITEMASK is not a valid argument to glIsEnabled, the */
372 /* original code is shown to be broken when run under an OpenGL debugger */
373 /* like GLIntercept. This is the correct way to retrieve the mask value. */
374 glGetBooleanv(GL_DEPTH_WRITEMASK, &aIsDepthMaskEnabled);
376 const GLdouble aCylinderLength = L * CYLINDER_LENGTH;
377 const GLdouble aCylinderDiametr = L * myDiameter;
378 const GLdouble aConeDiametr = aCylinderDiametr * 2.;
379 const GLdouble aConeLength = L * (1 - CYLINDER_LENGTH);
380 /* Correct for owerlapping */
381 /* aCylinderLength += aConeLength - 1.2*aCylinderDiametr*aConeLength/aConeDiametr;*/
383 /* Create cylinder for axis */
384 gluQuadricDrawStyle(aQuadric, GLU_FILL); /* smooth shaded */
385 gluQuadricNormals(aQuadric, GLU_FLAT);
387 glNewList(startList, GL_COMPILE);
388 gluCylinder(aQuadric, aCylinderDiametr, aCylinderDiametr, aCylinderLength, myNbFacettes, 1);
391 glNewList(startList + 1, GL_COMPILE);
392 gluCylinder(aQuadric, aConeDiametr, 0., aConeLength, myNbFacettes, 1);
395 glNewList(startList + 2, GL_COMPILE);
396 gluSphere(aQuadric, aCylinderDiametr * 2., myNbFacettes, myNbFacettes);
399 gluQuadricOrientation(aQuadric,GLU_INSIDE); /*szv*/
400 glNewList(startList + 3, GL_COMPILE);
401 gluDisk(aQuadric, aCylinderDiametr, aConeDiametr, myNbFacettes, 1/*szv:2*/);
404 /* Store previous attributes */
405 glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
406 glEnable(GL_LIGHTING);
409 glEnable(GL_CULL_FACE);
411 /*Fotis Sioutis | 2008-01-21 10:55
412 In the function call_zbuffer_triedron_redraw of TKOpengl,
413 the z buffered trihedron changes colors in case there
414 is an object in the scene that has an explicit material
415 attached to it.In the trihedron display loop,
416 GL_COLOR_MATERIAL is enabled, but only the GL_DIFFUSE
417 parameter is utilized in glColorMaterial(...).
418 This causes the last ambient,specular and emission values
419 used, to stay at the stack and applied to the trihedron
420 (which causes the color change).
421 A fix is proposed , to change GL_DIFFUSE to
422 GL_AMBIENT_AND_DIFFUSE in glColorMaterial call in
423 line 946.The above of course will leave unchanged
424 the SPECULAR and EMISSION values.
425 Another proposal which would fix 100% the problem
426 is to use glMaterial instead of glColor on the trihedron
428 const GLfloat aNULLColor[] = { 0.f, 0.f, 0.f, 0.f }; /* FS 21/01/08 */
429 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aNULLColor);
430 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, aNULLColor);
431 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, aNULLColor);
432 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.f);
434 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
435 glEnable(GL_COLOR_MATERIAL);
437 if (!aIsDepthEnabled) {
438 glEnable(GL_DEPTH_TEST);
439 glClear(GL_DEPTH_BUFFER_BIT);
442 if (!aIsDepthMaskEnabled) {
443 /* This is how the depthmask needs to be re-enabled...*/
444 glDepthMask(GL_TRUE);
445 /* ...and not this stuff below */
448 /* Position des Axes */
449 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
450 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
451 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
456 glMatrixMode(GL_MODELVIEW);
460 glGetIntegerv (GL_DEPTH_FUNC, &df);
463 for (i = 0; i < 2; i++) /* PCD 11/02/08 Two pass method */
465 if (i == 0) /* First pass */
467 glDepthFunc(GL_ALWAYS);
471 glDepthFunc(GL_LEQUAL);
478 glColor3fv(aLineColor.rgb);
479 glCallList(startList+2);
482 glColor4fv(myZColor.rgb);
483 glCallList(startList);
484 glTranslated(0, 0, L * CYLINDER_LENGTH);
485 glCallList(startList + 3);
486 glCallList(startList + 1);
490 glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
491 glColor4fv(myXColor.rgb);
492 glCallList(startList);
493 glTranslated(0, 0, L * CYLINDER_LENGTH);
494 glCallList(startList + 3);
495 glCallList(startList + 1);
499 glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
500 glColor4fv(myYColor.rgb);
501 glCallList(startList);
502 glTranslated(0, 0, L * CYLINDER_LENGTH);
503 glCallList(startList + 3);
504 glCallList(startList + 1);
508 if (!aIsDepthEnabled)
509 glDisable(GL_DEPTH_TEST);
511 if (!aIsDepthMaskEnabled)
512 glDepthMask(GL_FALSE);
514 glDisable(GL_CULL_FACE);
515 glDisable(GL_COLOR_MATERIAL);
517 gluDeleteQuadric(aQuadric);
518 glColor3fv (aLineColor.rgb);
520 /* Always write the text */
521 glDepthFunc(GL_ALWAYS);
525 /* fleches au bout des axes (= cones de la couleur demandee) */
526 //const GLdouble l = 0.75*L; /* distance a l'origine */
527 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
528 //const double Angle = 2. * M_PI/ myNbFacettes;
530 glDeleteLists(startList, 4);
532 glDisable(GL_LIGHTING);
537 const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
538 glColor3fv (AspectText->Color().rgb);
540 AWorkspace->RenderText (L"X", 0, float(L + rayon), 0.0f, float(-rayon));
541 AWorkspace->RenderText (L"Y", 0, float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon));
542 AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon));
547 if (!isWithinView) { /* restore matrix */
548 glMatrixMode (GL_PROJECTION);
550 glMatrixMode (GL_MODELVIEW);
556 /*----------------------------------------------------------------------*/
558 /*----------------------------------------------------------------------*/
560 * Fonctions publiques
565 * initialisation d'un triedre non zoomable dans une vue.
566 * ou modification des valeurs deja initialisees.
570 OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
571 const Standard_Real AScale, const Standard_Boolean AsWireframe)
574 myIsWireframe(AsWireframe)
577 Quantity_Color Color(AColor);
578 Color.Values(R,G,B,Quantity_TOC_RGB);
580 CALL_DEF_CONTEXTLINE aContextLine = myDefaultContextLine;
581 aContextLine.Color.r = (float)R;
582 aContextLine.Color.g = (float)G;
583 aContextLine.Color.b = (float)B;
584 myAspectLine.SetContext(aContextLine);
586 CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
587 aContextText.Color.r = (float)R;
588 aContextText.Color.g = (float)G;
589 aContextText.Color.b = (float)B;
590 myAspectText.SetContext(aContextText);
592 myXColor = theXColor;
593 myYColor = theYColor;
594 myZColor = theZColor;
597 myDiameter = theDiameter;
598 myNbFacettes = theNbFacettes;
601 /*----------------------------------------------------------------------*/
604 * destruction du triedre non zoomable d'une vue.
607 //call_triedron_erase
608 OpenGl_Trihedron::~OpenGl_Trihedron ()
612 /*----------------------------------------------------------------------*/
615 * affichage d'un triedre non zoomable dans la wks awsid
617 * Triedre = Objet non Zoomable;
618 * on cree cette fonction pour pouvoir travailler par les structures
619 * utilisees par les fonctions Tsm* et TEL_VIEW_REP
623 //call_triedron_redraw_from_wsid
624 void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
626 const OpenGl_AspectLine* aPrevAspectLine = theWorkspace->SetAspectLine (&myAspectLine);
627 const OpenGl_AspectText* aPrevAspectText = theWorkspace->SetAspectText (&myAspectText);
629 /* check if GL_LIGHTING should be disabled
630 no enabling 'cause it will be done (if necessary: kinda Polygon types )
631 during redrawing structures
633 if (!theWorkspace->UseGLLight())
635 glDisable (GL_LIGHTING);
638 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
640 /* affichage du Triedre Non Zoomable */
641 theWorkspace->ActiveView()->EndTransformPersistence();
645 Redraw (theWorkspace);
649 RedrawZBuffer (theWorkspace);
653 if (!aPrevTexture.IsNull())
655 theWorkspace->EnableTexture (aPrevTexture);
658 theWorkspace->SetAspectText (aPrevAspectText);
659 theWorkspace->SetAspectLine (aPrevAspectLine);
662 /*----------------------------------------------------------------------*/
663 //call_ztriedron_setup
664 void OpenGl_Trihedron::Setup (const Quantity_NameOfColor XColor, const Quantity_NameOfColor YColor, const Quantity_NameOfColor ZColor,
665 const Standard_Real SizeRatio, const Standard_Real AxisDiametr, const Standard_Integer NbFacettes)
669 Quantity_Color(XColor).Values(R, G, B, Quantity_TOC_RGB);
670 theXColor.rgb[0] = float (R);
671 theXColor.rgb[1] = float (G);
672 theXColor.rgb[2] = float (B);
674 Quantity_Color(YColor).Values(R, G, B, Quantity_TOC_RGB);
675 theYColor.rgb[0] = float (R);
676 theYColor.rgb[1] = float (G);
677 theYColor.rgb[2] = float (B);
679 Quantity_Color(ZColor).Values(R, G, B, Quantity_TOC_RGB);
680 theZColor.rgb[0] = float (R);
681 theZColor.rgb[1] = float (G);
682 theZColor.rgb[2] = float (B);
684 theRatio = float (SizeRatio);
685 theDiameter = float (AxisDiametr);
686 theNbFacettes = NbFacettes;