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 <OpenGl_TextureBox.hxx>
29 #include <InterfaceGraphic_Graphic3d.hxx> /* pour CALL_DEF_STRUCTURE */
30 #include <InterfaceGraphic_Aspect.hxx> /* pour CALL_DEF_VIEW */
31 #include <InterfaceGraphic_Visual3d.hxx>
33 #include <OpenGl_transform_persistence.hxx>
35 #include <OpenGl_Workspace.hxx>
36 #include <OpenGl_View.hxx>
37 #include <OpenGl_Trihedron.hxx>
39 #include <GL/glu.h> // gluNewQuadric()
41 IMPLEMENT_STANDARD_HANDLE(OpenGl_Trihedron,MMgt_TShared)
42 IMPLEMENT_STANDARD_RTTIEXT(OpenGl_Trihedron,MMgt_TShared)
44 static const CALL_DEF_CONTEXTLINE myDefaultContextLine =
48 { 1.F, 1.F, 1.F }, //Color
49 Aspect_TOL_SOLID, //LineType
53 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
60 { 1.F, 1.F, 1.F }, //Color
61 Aspect_TOST_NORMAL, //Style
62 Aspect_TODT_NORMAL, //DisplayType
63 { 1.F, 1.F, 1.F }, //ColorSubTitle
66 OSD_FA_Regular //TextFontAspect
69 /*----------------------------------------------------------------------*/
74 /* Default parameters for ZBUFFER triheron */
75 static TEL_COLOUR theXColor = {{ 1.F, 0.F, 0.F, 0.6F }};
76 static TEL_COLOUR theYColor = {{ 0.F, 1.F, 0.F, 0.6F }};
77 static TEL_COLOUR theZColor = {{ 0.F, 0.F, 1.F, 0.6F }};
78 static float theRatio = 0.8f;
79 static float theDiameter = 0.05f;
80 static int theNbFacettes = 12;
82 /*----------------------------------------------------------------------*/
85 * affichage d'un triedre non zoomable a partir des index dans les tables
86 * des structures non zoomables.
88 * Triedre = Objet non Zoomable :
89 * on recalcule ses dimensions et son origine en fonction de la taille
90 * de la fenetre; on positionne selon le choix de l'init;
91 * et on inhibe seulement les translations.
95 //call_triedron_redraw
96 void OpenGl_Trihedron::Redraw (const Handle(OpenGl_Workspace) &AWorkspace) const
98 const Standard_Real U = AWorkspace->ActiveView()->Height();
99 const Standard_Real V = AWorkspace->ActiveView()->Width();
101 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
102 /* de la dimension la plus petite de la window. */
103 const GLdouble L = ( U < V ? U : V ) * myScale;
106 * On inhibe les translations; on conserve les autres transformations.
109 /* on lit les matrices de transformation et de projection de la vue */
110 /* pour annuler les translations (dernieres colonnes des matrices). */
111 GLdouble modelMatrix[4][4];
112 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
113 GLdouble projMatrix[4][4];
114 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
116 /* on annule la translation qui peut etre affectee a la vue */
117 modelMatrix[3][0] = 0.;
118 modelMatrix[3][1] = 0.;
119 modelMatrix[3][2] = 0.;
120 projMatrix[3][0] = 0.;
121 projMatrix[3][1] = 0.;
122 projMatrix[3][2] = 0.;
124 /* sauvegarde du contexte des matrices avant chargement */
125 glMatrixMode (GL_MODELVIEW);
127 glLoadMatrixd( (GLdouble *) modelMatrix );
128 glMatrixMode ( GL_PROJECTION );
130 glLoadMatrixd( (GLdouble *) projMatrix );
133 * Positionnement de l'origine du triedre selon le choix de l'init
136 /* on fait uniquement une translation de l'origine du Triedre */
140 case Aspect_TOTP_LEFT_LOWER :
141 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
144 case Aspect_TOTP_LEFT_UPPER :
145 glTranslated( -0.5*U + L , +0.5*V - L -L/3., 0. );
148 case Aspect_TOTP_RIGHT_LOWER :
149 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
152 case Aspect_TOTP_RIGHT_UPPER :
153 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
156 //case Aspect_TOTP_CENTER :
162 * Creation du triedre
164 const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
166 /* Fotis Sioutis 2007-11-14 15:06
167 I have also seen in previous posts that the view trihedron in V3d_WIREFRAME mode
168 changes colors depending on the state of the view. This behaviour can be easily
169 corrected by altering call_triedron_redraw function in OpenGl_triedron.c of TKOpengl.
170 The only change needed is to erase glDisable(GL_LIGHTING) that is called before the
171 Axis name drawing and move this function call just before the initial axis drawing.
172 Below is the code portion with the modification.I don't know if this is considered to
173 be a bug but anyway i believe it might help some of you out there.*/
174 glDisable(GL_LIGHTING);
176 /* Position de l'origine */
177 const GLdouble TriedronOrigin[3] = { 0.0, 0.0, 0.0 };
179 /* Position des Axes */
180 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
181 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
182 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
183 TriedronAxeX[0] = L ;
184 TriedronAxeY[1] = L ;
185 TriedronAxeZ[2] = L ;
187 /* dessin des axes */
189 glVertex3dv( TriedronOrigin );
190 glVertex3dv( TriedronAxeX );
192 glVertex3dv( TriedronOrigin );
193 glVertex3dv( TriedronAxeY );
195 glVertex3dv( TriedronOrigin );
196 glVertex3dv( TriedronAxeZ );
199 /* fleches au bout des axes (= cones de la couleur demandee) */
200 const GLdouble l = 0.75*L; /* distance a l'origine */
201 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
202 const int NbFacettes = 12; /* le cone sera compose de 12 facettes triangulaires */
203 const double Angle = 2. * M_PI/ NbFacettes;
206 GLdouble TriedronCoord[3] = { 1.0, 0.0, 0.0 };
208 /* solution FILAIRE des cones au bout des axes : une seule ligne */
209 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
210 /* (la couleur est deja initialisee dans AspectLine) */
211 /* FIN de la solution FILAIRE CHOISIE pour les cones des axes */
214 glBegin(GL_TRIANGLE_FAN);
215 glVertex3dv( TriedronAxeX );
216 TriedronCoord[0] = l;
219 TriedronCoord[1] = rayon * sin(ii * Angle);
220 TriedronCoord[2] = rayon * cos(ii * Angle);
221 glVertex3dv( TriedronCoord );
227 glBegin(GL_TRIANGLE_FAN);
228 glVertex3dv( TriedronAxeY );
229 TriedronCoord[1] = l;
232 TriedronCoord[0] = rayon * cos(ii * Angle);
233 TriedronCoord[2] = rayon * sin(ii * Angle);
234 glVertex3dv( TriedronCoord );
240 glBegin(GL_TRIANGLE_FAN);
241 glVertex3dv( TriedronAxeZ );
242 TriedronCoord[2] = l;
245 TriedronCoord[0] = rayon * sin(ii * Angle);
246 TriedronCoord[1] = rayon * cos(ii * Angle);
247 glVertex3dv( TriedronCoord );
252 /* dessin de l'origine */
253 TriedronCoord[2] = 0.0 ;
255 const double Angle1 = 2. * M_PI/ ii;
256 glBegin(GL_LINE_LOOP);
258 TriedronCoord[0] = rayon * sin(ii * Angle1);
259 TriedronCoord[1] = rayon * cos(ii * Angle1);
260 glVertex3dv( TriedronCoord );
266 * Noms des axes et de l'origine
268 const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
269 glColor3fv (AspectText->Color().rgb);
271 AWorkspace->RenderText (L"X", 0, float(L + rayon), 0.0f, float(-rayon));
272 AWorkspace->RenderText (L"Y", 0, float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon));
273 AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon));
276 * restauration du contexte des matrices
278 glMatrixMode (GL_PROJECTION);
280 glMatrixMode (GL_MODELVIEW);
285 /*******************************************************
286 * Draws ZBUFFER trihedron mode
287 *******************************************************/
288 //call_zbuffer_triedron_redraw
289 void OpenGl_Trihedron::RedrawZBuffer (const Handle(OpenGl_Workspace) &AWorkspace) const
291 const Standard_Real U = AWorkspace->ActiveView()->Height();
292 const Standard_Real V = AWorkspace->ActiveView()->Width();
294 GLdouble modelMatrix[4][4];
295 glGetDoublev( GL_MODELVIEW_MATRIX, (GLdouble *) modelMatrix );
296 GLdouble projMatrix[4][4];
297 glGetDoublev( GL_PROJECTION_MATRIX, (GLdouble *) projMatrix );
299 /* Check position in the ViewPort */
301 /* Simple code modification recommended by Fotis Sioutis and Peter Dolbey */
302 /* to remove the irritating default behaviour of triedrons using V3d_ZBUFFER */
303 /* which causes the glyph to jump around the screen when the origin moves offscreen. */
304 GLboolean isWithinView = GL_FALSE;
306 /* la taille des axes est 1 proportion (fixee a l'init du triedre) */
307 /* de la dimension la plus petite de la window. */
308 GLdouble L = ( U < V ? U : V ) * myScale;
312 /* Annulate translation matrix */
313 modelMatrix[3][0] = 0.;
314 modelMatrix[3][1] = 0.;
315 modelMatrix[3][2] = 0.;
316 projMatrix[3][0] = 0.;
317 projMatrix[3][1] = 0.;
318 projMatrix[3][2] = 0.;
321 glMatrixMode (GL_MODELVIEW);
324 glLoadMatrixd( (GLdouble *) modelMatrix);
325 glMatrixMode ( GL_PROJECTION );
328 glLoadMatrixd( (GLdouble *) projMatrix);
331 * Define position in the view
335 case Aspect_TOTP_LEFT_LOWER :
336 glTranslated( -0.5*U + L , -0.5*V + L , 0. );
339 case Aspect_TOTP_LEFT_UPPER :
340 glTranslated( -0.5*U + L , +0.5*V - L -L/3. , 0. );
343 case Aspect_TOTP_RIGHT_LOWER :
344 glTranslated( 0.5*U - L -L/3. , -0.5*V + L , 0. );
347 case Aspect_TOTP_RIGHT_UPPER :
348 glTranslated( 0.5*U - L -L/3. , +0.5*V - L -L/3. , 0. );
351 //case Aspect_TOTP_CENTER :
358 const OpenGl_AspectLine *AspectLine = AWorkspace->AspectLine( Standard_True );
359 const TEL_COLOUR &aLineColor = AspectLine->Color();
362 * Creation the trihedron
364 #define CYLINDER_LENGTH 0.75f
366 const GLuint startList = glGenLists(4);
367 GLUquadricObj* aQuadric = gluNewQuadric();
369 const GLboolean aIsDepthEnabled = glIsEnabled(GL_DEPTH_TEST);
371 GLboolean aIsDepthMaskEnabled;
373 /* GL_DEPTH_WRITEMASK is not a valid argument to glIsEnabled, the */
374 /* original code is shown to be broken when run under an OpenGL debugger */
375 /* like GLIntercept. This is the correct way to retrieve the mask value. */
376 glGetBooleanv(GL_DEPTH_WRITEMASK, &aIsDepthMaskEnabled);
378 const GLdouble aCylinderLength = L * CYLINDER_LENGTH;
379 const GLdouble aCylinderDiametr = L * myDiameter;
380 const GLdouble aConeDiametr = aCylinderDiametr * 2.;
381 const GLdouble aConeLength = L * (1 - CYLINDER_LENGTH);
382 /* Correct for owerlapping */
383 /* aCylinderLength += aConeLength - 1.2*aCylinderDiametr*aConeLength/aConeDiametr;*/
385 /* Create cylinder for axis */
386 gluQuadricDrawStyle(aQuadric, GLU_FILL); /* smooth shaded */
387 gluQuadricNormals(aQuadric, GLU_FLAT);
389 glNewList(startList, GL_COMPILE);
390 gluCylinder(aQuadric, aCylinderDiametr, aCylinderDiametr, aCylinderLength, myNbFacettes, 1);
393 glNewList(startList + 1, GL_COMPILE);
394 gluCylinder(aQuadric, aConeDiametr, 0., aConeLength, myNbFacettes, 1);
397 glNewList(startList + 2, GL_COMPILE);
398 gluSphere(aQuadric, aCylinderDiametr * 2., myNbFacettes, myNbFacettes);
401 gluQuadricOrientation(aQuadric,GLU_INSIDE); /*szv*/
402 glNewList(startList + 3, GL_COMPILE);
403 gluDisk(aQuadric, aCylinderDiametr, aConeDiametr, myNbFacettes, 1/*szv:2*/);
406 /* Store previous attributes */
407 glPushAttrib(GL_LIGHTING_BIT | GL_POLYGON_BIT);
408 glEnable(GL_LIGHTING);
411 glEnable(GL_CULL_FACE);
413 /*Fotis Sioutis | 2008-01-21 10:55
414 In the function call_zbuffer_triedron_redraw of TKOpengl,
415 the z buffered trihedron changes colors in case there
416 is an object in the scene that has an explicit material
417 attached to it.In the trihedron display loop,
418 GL_COLOR_MATERIAL is enabled, but only the GL_DIFFUSE
419 parameter is utilized in glColorMaterial(...).
420 This causes the last ambient,specular and emission values
421 used, to stay at the stack and applied to the trihedron
422 (which causes the color change).
423 A fix is proposed , to change GL_DIFFUSE to
424 GL_AMBIENT_AND_DIFFUSE in glColorMaterial call in
425 line 946.The above of course will leave unchanged
426 the SPECULAR and EMISSION values.
427 Another proposal which would fix 100% the problem
428 is to use glMaterial instead of glColor on the trihedron
430 const GLfloat aNULLColor[] = { 0.f, 0.f, 0.f, 0.f }; /* FS 21/01/08 */
431 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, aNULLColor);
432 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, aNULLColor);
433 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, aNULLColor);
434 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 0.f);
436 glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE);
437 glEnable(GL_COLOR_MATERIAL);
439 if (!aIsDepthEnabled) {
440 glEnable(GL_DEPTH_TEST);
441 glClear(GL_DEPTH_BUFFER_BIT);
444 if (!aIsDepthMaskEnabled) {
445 /* This is how the depthmask needs to be re-enabled...*/
446 glDepthMask(GL_TRUE);
447 /* ...and not this stuff below */
450 /* Position des Axes */
451 GLdouble TriedronAxeX[3] = { 1.0, 0.0, 0.0 };
452 GLdouble TriedronAxeY[3] = { 0.0, 1.0, 0.0 };
453 GLdouble TriedronAxeZ[3] = { 0.0, 0.0, 1.0 };
458 glMatrixMode(GL_MODELVIEW);
462 glGetIntegerv (GL_DEPTH_FUNC, &df);
465 for (i = 0; i < 2; i++) /* PCD 11/02/08 Two pass method */
467 if (i == 0) /* First pass */
469 glDepthFunc(GL_ALWAYS);
473 glDepthFunc(GL_LEQUAL);
480 glColor3fv(aLineColor.rgb);
481 glCallList(startList+2);
484 glColor4fv(myZColor.rgb);
485 glCallList(startList);
486 glTranslated(0, 0, L * CYLINDER_LENGTH);
487 glCallList(startList + 3);
488 glCallList(startList + 1);
492 glRotated(90.0, TriedronAxeY[0], TriedronAxeY[1], TriedronAxeY[2]);
493 glColor4fv(myXColor.rgb);
494 glCallList(startList);
495 glTranslated(0, 0, L * CYLINDER_LENGTH);
496 glCallList(startList + 3);
497 glCallList(startList + 1);
501 glRotated(-90.0, TriedronAxeX[0], TriedronAxeX[1], TriedronAxeX[2]);
502 glColor4fv(myYColor.rgb);
503 glCallList(startList);
504 glTranslated(0, 0, L * CYLINDER_LENGTH);
505 glCallList(startList + 3);
506 glCallList(startList + 1);
510 if (!aIsDepthEnabled)
511 glDisable(GL_DEPTH_TEST);
513 if (!aIsDepthMaskEnabled)
514 glDepthMask(GL_FALSE);
516 glDisable(GL_CULL_FACE);
517 glDisable(GL_COLOR_MATERIAL);
519 gluDeleteQuadric(aQuadric);
520 glColor3fv (aLineColor.rgb);
522 /* Always write the text */
523 glDepthFunc(GL_ALWAYS);
527 /* fleches au bout des axes (= cones de la couleur demandee) */
528 //const GLdouble l = 0.75*L; /* distance a l'origine */
529 const GLdouble rayon = L/30. ; /* rayon de la base du cone */
530 //const double Angle = 2. * M_PI/ myNbFacettes;
532 glDeleteLists(startList, 4);
534 glDisable(GL_LIGHTING);
539 const OpenGl_AspectText *AspectText = AWorkspace->AspectText( Standard_True );
540 glColor3fv (AspectText->Color().rgb);
542 AWorkspace->RenderText (L"X", 0, float(L + rayon), 0.0f, float(-rayon));
543 AWorkspace->RenderText (L"Y", 0, float(rayon), float(L + 3.0 * rayon), float(2.0 * rayon));
544 AWorkspace->RenderText (L"Z", 0, float(-2.0 * rayon), float(0.5 * rayon), float(L + 3.0 * rayon));
549 if (!isWithinView) { /* restore matrix */
550 glMatrixMode (GL_PROJECTION);
552 glMatrixMode (GL_MODELVIEW);
558 /*----------------------------------------------------------------------*/
560 /*----------------------------------------------------------------------*/
562 * Fonctions publiques
567 * initialisation d'un triedre non zoomable dans une vue.
568 * ou modification des valeurs deja initialisees.
572 OpenGl_Trihedron::OpenGl_Trihedron (const Aspect_TypeOfTriedronPosition APosition, const Quantity_NameOfColor AColor,
573 const Standard_Real AScale, const Standard_Boolean AsWireframe)
576 myIsWireframe(AsWireframe)
579 Quantity_Color Color(AColor);
580 Color.Values(R,G,B,Quantity_TOC_RGB);
582 CALL_DEF_CONTEXTLINE aContextLine = myDefaultContextLine;
583 aContextLine.Color.r = (float)R;
584 aContextLine.Color.g = (float)G;
585 aContextLine.Color.b = (float)B;
586 myAspectLine.SetContext(aContextLine);
588 CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
589 aContextText.Color.r = (float)R;
590 aContextText.Color.g = (float)G;
591 aContextText.Color.b = (float)B;
592 myAspectText.SetContext(aContextText);
594 myXColor = theXColor;
595 myYColor = theYColor;
596 myZColor = theZColor;
599 myDiameter = theDiameter;
600 myNbFacettes = theNbFacettes;
603 /*----------------------------------------------------------------------*/
606 * destruction du triedre non zoomable d'une vue.
609 //call_triedron_erase
610 OpenGl_Trihedron::~OpenGl_Trihedron ()
614 /*----------------------------------------------------------------------*/
617 * affichage d'un triedre non zoomable dans la wks awsid
619 * Triedre = Objet non Zoomable;
620 * on cree cette fonction pour pouvoir travailler par les structures
621 * utilisees par les fonctions Tsm* et TEL_VIEW_REP
625 //call_triedron_redraw_from_wsid
626 void OpenGl_Trihedron::Render (const Handle(OpenGl_Workspace) &AWorkspace) const
628 const OpenGl_AspectLine *oldAspectLine = AWorkspace->SetAspectLine(&myAspectLine);
629 const OpenGl_AspectText *oldAspectText = AWorkspace->SetAspectText(&myAspectText);
631 /* check if GL_LIGHTING should be disabled
632 no enabling 'cause it will be done (if necessary: kinda Polygon types )
633 during redrawing structures
635 if (!AWorkspace->UseGLLight())
636 glDisable( GL_LIGHTING );
638 /* sauvegarde du contexte (on reste dans le buffer courant) */
639 const GLboolean save_texture_state = IsTextureEnabled();
642 /* affichage du Triedre Non Zoomable */
643 AWorkspace->ActiveView()->EndTransformPersistence();
648 RedrawZBuffer (AWorkspace);
650 /* restauration du contexte */
651 if (save_texture_state) EnableTexture();
653 AWorkspace->SetAspectText(oldAspectText);
654 AWorkspace->SetAspectLine(oldAspectLine);
657 /*----------------------------------------------------------------------*/
658 //call_ztriedron_setup
659 void OpenGl_Trihedron::Setup (const Quantity_NameOfColor XColor, const Quantity_NameOfColor YColor, const Quantity_NameOfColor ZColor,
660 const Standard_Real SizeRatio, const Standard_Real AxisDiametr, const Standard_Integer NbFacettes)
664 Quantity_Color(XColor).Values(R, G, B, Quantity_TOC_RGB);
665 theXColor.rgb[0] = float (R);
666 theXColor.rgb[1] = float (G);
667 theXColor.rgb[2] = float (B);
669 Quantity_Color(YColor).Values(R, G, B, Quantity_TOC_RGB);
670 theYColor.rgb[0] = float (R);
671 theYColor.rgb[1] = float (G);
672 theYColor.rgb[2] = float (B);
674 Quantity_Color(ZColor).Values(R, G, B, Quantity_TOC_RGB);
675 theZColor.rgb[0] = float (R);
676 theZColor.rgb[1] = float (G);
677 theZColor.rgb[2] = float (B);
679 theRatio = float (SizeRatio);
680 theDiameter = float (AxisDiametr);
681 theNbFacettes = NbFacettes;