1 // Created on: 2011-07-13
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2013 OPEN CASCADE SAS
5 // This file is part of Open CASCADE Technology software library.
7 // This library is free software; you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License version 2.1 as published
9 // by the Free Software Foundation, with special exception defined in the file
10 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11 // distribution for complete text of the license and disclaimer of any warranty.
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
16 #include <OpenGl_AspectText.hxx>
17 #include <OpenGl_GlCore11.hxx>
18 #include <OpenGl_GraphicDriver.hxx>
19 #include <OpenGl_ShaderManager.hxx>
20 #include <OpenGl_ShaderProgram.hxx>
21 #include <OpenGl_ShaderStates.hxx>
22 #include <OpenGl_Text.hxx>
23 #include <OpenGl_Workspace.hxx>
24 #include <OpenGl_View.hxx>
26 #include <Font_FontMgr.hxx>
27 #include <Font_FTFont.hxx>
28 #include <Graphic3d_TransformUtils.hxx>
29 #include <TCollection_HAsciiString.hxx>
37 static const GLdouble THE_IDENTITY_MATRIX[16] =
46 static char const* TheFamily[] = {"Helvetica", "Courier", "Times"};
47 static char const* TheItalic[] = {"Oblique", "Oblique", "Italic"};
48 static char const* TheBase[] = {"", "", "-Roman"};
50 //! Convert font name used for rendering to some "good" font names
51 //! that produce good vector text.
52 static void getGL2PSFontName (const char* theSrcFont,
55 if (strstr (theSrcFont, "Symbol"))
57 sprintf (thePsFont, "%s", "Symbol");
60 else if (strstr (theSrcFont, "ZapfDingbats"))
62 sprintf (thePsFont, "%s", "WingDings");
68 bool isItalic = false;
69 if (strstr (theSrcFont, "Courier"))
73 else if (strstr (theSrcFont, "Times"))
78 if (strstr (theSrcFont, "Bold"))
82 if (strstr (theSrcFont, "Italic")
83 || strstr (theSrcFont, "Oblique"))
92 sprintf (thePsFont, "%s-Bold%s", TheFamily[aFontId], TheItalic[aFontId]);
96 sprintf (thePsFont, "%s-Bold", TheFamily[aFontId]);
101 sprintf (thePsFont, "%s-%s", TheFamily[aFontId], TheItalic[aFontId]);
105 sprintf (thePsFont, "%s%s", TheFamily[aFontId], TheBase[aFontId]);
109 static void exportText (const NCollection_String& theText,
110 const Standard_Boolean theIs2d,
111 const OpenGl_AspectText& theAspect,
112 const Standard_Integer theHeight)
116 getGL2PSFontName (theAspect.Aspect()->Font().ToCString(), aPsFont);
119 #if !defined(GL_ES_VERSION_2_0)
122 glRasterPos2f (0.0f, 0.0f);
126 glRasterPos3f (0.0f, 0.0f, 0.0f);
130 glBitmap (1, 1, 0, 0, 0, 0, &aZero);
133 // Standard GL2PS's alignment isn't used, because it doesn't work correctly
134 // for all formats, therefore alignment is calculated manually relative
135 // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
136 gl2psTextOpt (theText.ToCString(), aPsFont, (GLshort)theHeight, GL2PS_TEXT_BL, (float )theAspect.Aspect()->GetTextAngle());
140 } // anonymous namespace
142 // =======================================================================
143 // function : OpenGl_Text
145 // =======================================================================
146 OpenGl_Text::OpenGl_Text()
150 myScaleHeight (1.0f),
151 myPoint (0.0f, 0.0f, 0.0f),
154 myHasAnchorPoint (true)
156 myParams.Height = 10;
157 myParams.HAlign = Graphic3d_HTA_LEFT;
158 myParams.VAlign = Graphic3d_VTA_BOTTOM;
161 // =======================================================================
162 // function : OpenGl_Text
164 // =======================================================================
165 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
166 const OpenGl_Vec3& thePoint,
167 const OpenGl_TextParam& theParams)
171 myScaleHeight (1.0f),
172 myExportHeight (1.0f),
173 myParams (theParams),
178 myHasAnchorPoint (true)
183 // =======================================================================
184 // function : OpenGl_Text
186 // =======================================================================
187 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
188 const gp_Ax2& theOrientation,
189 const OpenGl_TextParam& theParams,
190 const bool theHasOwnAnchor)
195 myExportHeight (1.0),
196 myParams (theParams),
199 myOrientation (theOrientation),
201 myHasAnchorPoint (theHasOwnAnchor)
203 const gp_Pnt& aPoint = theOrientation.Location();
204 myPoint = OpenGl_Vec3 (static_cast<Standard_ShortReal> (aPoint.X()),
205 static_cast<Standard_ShortReal> (aPoint.Y()),
206 static_cast<Standard_ShortReal> (aPoint.Z()));
209 // =======================================================================
210 // function : SetPosition
212 // =======================================================================
213 void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
218 // =======================================================================
219 // function : SetFontSize
221 // =======================================================================
222 void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
223 const Standard_Integer theFontSize)
225 if (myParams.Height != theFontSize)
227 Release (theCtx.operator->());
229 myParams.Height = theFontSize;
232 // =======================================================================
235 // =======================================================================
236 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
237 const Standard_Utf8Char* theText,
238 const OpenGl_Vec3& thePoint)
240 releaseVbos (theCtx.operator->());
243 myString.FromUnicode (theText);
246 // =======================================================================
249 // =======================================================================
250 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
251 const Standard_Utf8Char* theText,
252 const OpenGl_Vec3& thePoint,
253 const OpenGl_TextParam& theParams)
255 if (myParams.Height != theParams.Height)
257 Release (theCtx.operator->());
261 releaseVbos (theCtx.operator->());
264 myParams = theParams;
266 myString.FromUnicode (theText);
269 // =======================================================================
272 // =======================================================================
273 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
274 const TCollection_ExtendedString& theText,
275 const OpenGl_Vec2& thePoint,
276 const OpenGl_TextParam& theParams)
278 if (myParams.Height != theParams.Height)
280 Release (theCtx.operator->());
284 releaseVbos (theCtx.operator->());
287 myParams = theParams;
288 myPoint.xy() = thePoint;
290 myString.FromUnicode (theText.ToExtString());
293 // =======================================================================
294 // function : ~OpenGl_Text
296 // =======================================================================
297 OpenGl_Text::~OpenGl_Text()
302 // =======================================================================
303 // function : releaseVbos
305 // =======================================================================
306 void OpenGl_Text::releaseVbos (OpenGl_Context* theCtx)
308 for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
310 Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
311 Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
315 theCtx->DelayedRelease (aVerts);
316 theCtx->DelayedRelease (aTCrds);
322 && !myBndVertsVbo.IsNull())
324 theCtx->DelayedRelease (myBndVertsVbo);
330 myBndVertsVbo.Nullify();
333 // =======================================================================
334 // function : Release
336 // =======================================================================
337 void OpenGl_Text::Release (OpenGl_Context* theCtx)
339 releaseVbos (theCtx);
340 if (!myFont.IsNull())
342 const TCollection_AsciiString aKey = myFont->ResourceKey();
346 theCtx->ReleaseResource (aKey, Standard_True);
351 // =======================================================================
352 // function : StringSize
354 // =======================================================================
355 void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
356 const NCollection_String& theText,
357 const OpenGl_AspectText& theTextAspect,
358 const OpenGl_TextParam& theParams,
359 const unsigned int theResolution,
360 Standard_ShortReal& theWidth,
361 Standard_ShortReal& theAscent,
362 Standard_ShortReal& theDescent)
367 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height, theResolution);
368 Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, theResolution, aFontKey);
369 if (aFont.IsNull() || !aFont->IsValid())
374 theAscent = aFont->Ascender();
375 theDescent = aFont->Descender();
377 GLfloat aWidth = 0.0f;
378 for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
380 const Standard_Utf32Char aCharThis = *anIter;
381 const Standard_Utf32Char aCharNext = *++anIter;
383 if (aCharThis == '\x0D' // CR (carriage return)
384 || aCharThis == '\a' // BEL (alarm)
385 || aCharThis == '\f' // FF (form feed) NP (new page)
386 || aCharThis == '\b' // BS (backspace)
387 || aCharThis == '\v') // VT (vertical tab)
389 continue; // skip unsupported carriage control codes
391 else if (aCharThis == '\x0A') // LF (line feed, new line)
393 theWidth = Max (theWidth, aWidth);
397 else if (aCharThis == ' ')
399 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
402 else if (aCharThis == '\t')
404 aWidth += aFont->FTFont()->AdvanceX (' ', aCharNext) * 8.0f;
408 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
410 theWidth = Max (theWidth, aWidth);
412 Handle(OpenGl_Context) aCtx = theCtx;
414 aCtx->ReleaseResource (aFontKey, Standard_True);
417 // =======================================================================
420 // =======================================================================
421 void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
423 const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText();
424 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
425 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
426 #if !defined(GL_ES_VERSION_2_0)
427 const Standard_Integer aPrevPolygonMode = aCtx->SetPolygonMode (GL_FILL);
428 const bool aPrevHatchingMode = aCtx->SetPolygonHatchEnabled (false);
431 // Bind custom shader program or generate default version
432 aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
434 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
435 myProjMatrix.Convert (aCtx->ProjectionState.Current());
437 // use highlight color or colors from aspect
440 theWorkspace->TextColor(),
441 theWorkspace->TextSubtitleColor(),
445 if (!aPrevTexture.IsNull())
447 theWorkspace->EnableTexture (aPrevTexture);
449 #if !defined(GL_ES_VERSION_2_0)
450 aCtx->SetPolygonMode (aPrevPolygonMode);
451 aCtx->SetPolygonHatchEnabled (aPrevHatchingMode);
454 // restore Z buffer settings
455 if (theWorkspace->UseZBuffer())
457 glEnable (GL_DEPTH_TEST);
461 // =======================================================================
464 // =======================================================================
465 void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx,
466 const OpenGl_AspectText& theTextAspect,
467 const unsigned int theResolution) const
469 render (theCtx, theTextAspect,
470 theTextAspect.Aspect()->ColorRGBA(),
471 theTextAspect.Aspect()->ColorSubTitleRGBA(),
475 // =======================================================================
476 // function : setupMatrix
478 // =======================================================================
479 void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
480 const OpenGl_AspectText& theTextAspect,
481 const OpenGl_Vec3 theDVec) const
483 OpenGl_Mat4d aModViewMat;
484 OpenGl_Mat4d aProjectMat;
485 if (myHasPlane && myHasAnchorPoint)
487 aProjectMat = myProjMatrix * myOrientationMatrix;
491 aProjectMat = myProjMatrix;
496 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
497 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
498 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.f, 0.f, 1.f);
502 // align coordinates to the nearest integer
503 // to avoid extra interpolation issues
504 GLdouble anObjX, anObjY, anObjZ;
505 Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()),
506 std::floor (myWinY + theDVec.y()),
507 myWinZ + theDVec.z(),
508 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
509 OpenGl_Mat4d::Map (aProjectMat),
517 const gp_Dir& aVectorDir = myOrientation.XDirection();
518 const gp_Dir& aVectorUp = myOrientation.Direction();
519 const gp_Dir& aVectorRight = myOrientation.YDirection();
521 aModViewMat.SetColumn (2, OpenGl_Vec3d (aVectorUp.X(), aVectorUp.Y(), aVectorUp.Z()));
522 aModViewMat.SetColumn (1, OpenGl_Vec3d (aVectorRight.X(), aVectorRight.Y(), aVectorRight.Z()));
523 aModViewMat.SetColumn (0, OpenGl_Vec3d (aVectorDir.X(), aVectorDir.Y(), aVectorDir.Z()));
525 if (!myHasAnchorPoint)
527 OpenGl_Mat4d aPosMat;
528 aPosMat.SetColumn (3, OpenGl_Vec3d (myPoint.x(), myPoint.y(), myPoint.z()));
529 aPosMat *= aModViewMat;
530 aModViewMat.SetColumn (3, aPosMat.GetColumn (3));
534 aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ));
539 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
540 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.0, 0.0, 1.0);
543 if (!theTextAspect.Aspect()->GetTextZoomable())
545 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
547 else if (theCtx->HasRenderScale())
549 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, theCtx->RenderScaleInv(), theCtx->RenderScaleInv(), theCtx->RenderScaleInv());
553 if (myHasPlane && !myHasAnchorPoint)
555 OpenGl_Mat4d aCurrentWorldViewMat;
556 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
557 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
561 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
563 theCtx->ApplyWorldViewMatrix();
567 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
568 theCtx->ApplyProjectionMatrix();
571 // Upload updated state to shader program
572 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
575 // =======================================================================
576 // function : drawText
578 // =======================================================================
579 void OpenGl_Text::drawText (const Handle(OpenGl_Context)& theCtx,
580 const OpenGl_AspectText& theTextAspect) const
583 if (theCtx->IsFeedback())
585 // position of the text and alignment is calculated by transformation matrix
586 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
590 (void )theTextAspect;
593 if (myVertsVbo.Length() != myTextures.Length()
594 || myTextures.IsEmpty())
599 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
601 const GLuint aTexId = myTextures.Value (anIter);
602 glBindTexture (GL_TEXTURE_2D, aTexId);
604 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
605 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
606 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
607 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
609 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
611 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
612 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
614 glBindTexture (GL_TEXTURE_2D, 0);
617 // =======================================================================
618 // function : FontKey
620 // =======================================================================
621 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
622 const Standard_Integer theHeight,
623 const unsigned int theResolution)
625 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
626 ? theAspect.Aspect()->GetTextFontAspect()
628 return theAspect.Aspect()->Font()
629 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
630 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
631 + TCollection_AsciiString(":") + theHeight;
634 // =======================================================================
635 // function : FindFont
637 // =======================================================================
638 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
639 const OpenGl_AspectText& theAspect,
640 const Standard_Integer theHeight,
641 const unsigned int theResolution,
642 const TCollection_AsciiString theKey)
644 Handle(OpenGl_Font) aFont;
647 return aFont; // invalid parameters
650 if (!theCtx->GetResource (theKey, aFont))
652 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
653 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.Aspect()->Font());
654 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
655 ? theAspect.Aspect()->GetTextFontAspect()
657 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
658 Handle(Font_FTFont) aFontFt;
659 if (!aRequestedFont.IsNull())
661 aFontFt = new Font_FTFont (Handle(Font_FTLibrary)());
663 if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
665 aFont = new OpenGl_Font (aFontFt, theKey);
666 if (!aFont->Init (theCtx))
668 TCollection_ExtendedString aMsg;
670 aMsg += theAspect.Aspect()->Font();
671 aMsg += "' - initialization of GL resources has failed!";
672 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
674 aFont->Release (theCtx.operator->());
675 aFont = new OpenGl_Font (aFontFt, theKey);
680 TCollection_ExtendedString aMsg;
682 aMsg += theAspect.Aspect()->Font();
683 aMsg += "' is broken or has incompatible format! File path: ";
684 aMsg += aRequestedFont->FontPath()->ToCString();
685 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
687 aFont = new OpenGl_Font (aFontFt, theKey);
692 TCollection_ExtendedString aMsg;
694 aMsg += theAspect.Aspect()->Font();
695 aMsg += "' is not found in the system!";
696 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
697 aFont = new OpenGl_Font (aFontFt, theKey);
700 theCtx->ShareResource (theKey, aFont);
705 // =======================================================================
706 // function : drawRect
708 // =======================================================================
709 void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
710 const OpenGl_AspectText& theTextAspect,
711 const OpenGl_Vec4& theColorSubs) const
713 Handle(OpenGl_ShaderProgram) aPrevProgram = theCtx->ActiveProgram();
714 if (myBndVertsVbo.IsNull())
716 OpenGl_Vec2 aQuad[4] =
718 OpenGl_Vec2(myBndBox.Right, myBndBox.Bottom),
719 OpenGl_Vec2(myBndBox.Right, myBndBox.Top),
720 OpenGl_Vec2(myBndBox.Left, myBndBox.Bottom),
721 OpenGl_Vec2(myBndBox.Left, myBndBox.Top)
723 myBndVertsVbo = new OpenGl_VertexBuffer();
724 myBndVertsVbo->Init (theCtx, 2, 4, aQuad[0].GetData());
728 theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_Texture)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
730 #if !defined(GL_ES_VERSION_2_0)
731 if (theCtx->core11 != NULL
732 && theCtx->ActiveProgram().IsNull())
734 glBindTexture (GL_TEXTURE_2D, 0);
737 theCtx->SetColor4fv (theColorSubs);
738 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
739 myBndVertsVbo->BindAttribute (theCtx, Graphic3d_TOA_POS);
741 theCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
743 myBndVertsVbo->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
744 theCtx->BindProgram (aPrevProgram);
747 // =======================================================================
750 // =======================================================================
751 void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
752 const OpenGl_AspectText& theTextAspect,
753 const OpenGl_Vec4& theColorText,
754 const OpenGl_Vec4& theColorSubs,
755 const unsigned int theResolution) const
757 if (myString.IsEmpty())
762 // Note that using difference resolution in different Views in same Viewer
763 // will lead to performance regression (for example, text will be recreated every time).
764 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
766 && !myFont->ResourceKey().IsEqual (aFontKey))
769 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
774 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
776 if (!myFont->WasInitialized())
781 if (myTextures.IsEmpty())
783 Font_TextFormatter aFormatter;
784 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
787 aFormatter.Append (myString, *myFont->FTFont().operator->());
790 OpenGl_TextBuilder aBuilder;
791 aBuilder.Perform (aFormatter,
793 *myFont.operator->(),
798 aFormatter.BndBox (myBndBox);
799 if (!myBndVertsVbo.IsNull())
801 myBndVertsVbo->Release (theCtx.get());
802 myBndVertsVbo.Nullify();
806 if (myTextures.IsEmpty())
811 myExportHeight = 1.0f;
812 myScaleHeight = 1.0f;
814 theCtx->WorldViewState.Push();
815 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
817 const GLdouble aPointSize = (GLdouble )myFont->FTFont()->PointSize();
820 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(), myPoint.y(), myPoint.z(),
821 myModelMatrix, myProjMatrix, theCtx->Viewport(),
822 myWinX, myWinY, myWinZ);
824 // compute scale factor for constant text height
825 if (theTextAspect.Aspect()->GetTextZoomable())
827 myExportHeight = aPointSize;
831 Graphic3d_Vec3d aPnt1, aPnt2;
832 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY, myWinZ,
833 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
834 aPnt1.x(), aPnt1.y(), aPnt1.z());
835 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY + aPointSize, myWinZ,
836 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
837 aPnt2.x(), aPnt2.y(), aPnt2.z());
838 myScaleHeight = (aPnt2.y() - aPnt1.y()) / aPointSize;
841 myExportHeight = aPointSize / myExportHeight;
843 #if !defined(GL_ES_VERSION_2_0)
844 if (theCtx->core11 != NULL)
846 glDisable (GL_LIGHTING);
852 || theTextAspect.Aspect()->Style() == Aspect_TOST_ANNOTATION)
854 glDisable (GL_DEPTH_TEST);
857 if (theCtx->core15fwd != NULL)
859 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
861 #if !defined(GL_ES_VERSION_2_0)
862 // activate texture unit
863 GLint aTexEnvParam = GL_REPLACE;
864 if (theCtx->core11 != NULL)
867 glAlphaFunc (GL_GEQUAL, 0.285f);
868 glEnable (GL_ALPHA_TEST);
870 glDisable (GL_TEXTURE_1D);
871 glEnable (GL_TEXTURE_2D);
872 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
873 if (aTexEnvParam != GL_REPLACE)
875 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
882 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
885 switch (theTextAspect.Aspect()->DisplayType())
887 case Aspect_TODT_BLEND:
889 #if !defined(GL_ES_VERSION_2_0)
890 glEnable (GL_COLOR_LOGIC_OP);
895 case Aspect_TODT_SUBTITLE:
897 drawRect (theCtx, theTextAspect, theColorSubs);
900 case Aspect_TODT_DEKALE:
902 theCtx->SetColor4fv (theColorSubs);
903 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
904 drawText (theCtx, theTextAspect);
905 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
906 drawText (theCtx, theTextAspect);
907 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
908 drawText (theCtx, theTextAspect);
909 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
910 drawText (theCtx, theTextAspect);
913 case Aspect_TODT_DIMENSION:
914 case Aspect_TODT_NORMAL:
921 theCtx->SetColor4fv (theColorText);
922 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
923 drawText (theCtx, theTextAspect);
927 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
928 theCtx->ApplyProjectionMatrix();
931 #if !defined(GL_ES_VERSION_2_0)
932 if (theCtx->core11 != NULL)
934 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
938 if (theTextAspect.Aspect()->DisplayType() == Aspect_TODT_DIMENSION)
940 glDisable (GL_BLEND);
943 glDisable (GL_DEPTH_TEST);
945 #if !defined(GL_ES_VERSION_2_0)
946 if (theCtx->core11 != NULL)
948 glDisable (GL_TEXTURE_2D);
949 glDisable (GL_ALPHA_TEST);
952 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
954 glClear (GL_STENCIL_BUFFER_BIT);
955 glEnable (GL_STENCIL_TEST);
956 glStencilFunc (GL_ALWAYS, 1, 0xFF);
957 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
959 drawRect (theCtx, theTextAspect, OpenGl_Vec4 (1.0f, 1.0f, 1.0f, 1.0f));
961 glStencilFunc (GL_ALWAYS, 0, 0xFF);
963 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
966 // reset OpenGL state
967 glDisable (GL_BLEND);
968 glDisable (GL_STENCIL_TEST);
969 #if !defined(GL_ES_VERSION_2_0)
970 if (theCtx->core11 != NULL)
972 glDisable (GL_ALPHA_TEST);
974 glDisable (GL_COLOR_LOGIC_OP);
977 // model view matrix was modified
978 theCtx->WorldViewState.Pop();
979 theCtx->ApplyModelViewMatrix();