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>
25 #include <OpenGl_VertexBufferCompat.hxx>
27 #include <Font_FontMgr.hxx>
28 #include <Font_FTFont.hxx>
29 #include <Graphic3d_TransformUtils.hxx>
30 #include <TCollection_HAsciiString.hxx>
38 static const GLdouble THE_IDENTITY_MATRIX[16] =
47 static char const* TheFamily[] = {"Helvetica", "Courier", "Times"};
48 static char const* TheItalic[] = {"Oblique", "Oblique", "Italic"};
49 static char const* TheBase[] = {"", "", "-Roman"};
51 //! Convert font name used for rendering to some "good" font names
52 //! that produce good vector text.
53 static void getGL2PSFontName (const char* theSrcFont,
56 if (strstr (theSrcFont, "Symbol"))
58 sprintf (thePsFont, "%s", "Symbol");
61 else if (strstr (theSrcFont, "ZapfDingbats"))
63 sprintf (thePsFont, "%s", "WingDings");
69 bool isItalic = false;
70 if (strstr (theSrcFont, "Courier"))
74 else if (strstr (theSrcFont, "Times"))
79 if (strstr (theSrcFont, "Bold"))
83 if (strstr (theSrcFont, "Italic")
84 || strstr (theSrcFont, "Oblique"))
93 sprintf (thePsFont, "%s-Bold%s", TheFamily[aFontId], TheItalic[aFontId]);
97 sprintf (thePsFont, "%s-Bold", TheFamily[aFontId]);
102 sprintf (thePsFont, "%s-%s", TheFamily[aFontId], TheItalic[aFontId]);
106 sprintf (thePsFont, "%s%s", TheFamily[aFontId], TheBase[aFontId]);
110 static void exportText (const NCollection_String& theText,
111 const Standard_Boolean theIs2d,
112 const OpenGl_AspectText& theAspect,
113 const Standard_Integer theHeight)
117 getGL2PSFontName (theAspect.Aspect()->Font().ToCString(), aPsFont);
120 #if !defined(GL_ES_VERSION_2_0)
123 glRasterPos2f (0.0f, 0.0f);
127 glRasterPos3f (0.0f, 0.0f, 0.0f);
131 glBitmap (1, 1, 0, 0, 0, 0, &aZero);
134 // Standard GL2PS's alignment isn't used, because it doesn't work correctly
135 // for all formats, therefore alignment is calculated manually relative
136 // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
137 gl2psTextOpt (theText.ToCString(), aPsFont, (GLshort)theHeight, GL2PS_TEXT_BL, (float )theAspect.Aspect()->GetTextAngle());
141 } // anonymous namespace
143 // =======================================================================
144 // function : OpenGl_Text
146 // =======================================================================
147 OpenGl_Text::OpenGl_Text()
151 myScaleHeight (1.0f),
152 myPoint (0.0f, 0.0f, 0.0f),
155 myHasAnchorPoint (true)
157 myParams.Height = 10;
158 myParams.HAlign = Graphic3d_HTA_LEFT;
159 myParams.VAlign = Graphic3d_VTA_BOTTOM;
162 // =======================================================================
163 // function : OpenGl_Text
165 // =======================================================================
166 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
167 const OpenGl_Vec3& thePoint,
168 const OpenGl_TextParam& theParams)
172 myScaleHeight (1.0f),
173 myExportHeight (1.0f),
174 myParams (theParams),
179 myHasAnchorPoint (true)
184 // =======================================================================
185 // function : OpenGl_Text
187 // =======================================================================
188 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
189 const gp_Ax2& theOrientation,
190 const OpenGl_TextParam& theParams,
191 const bool theHasOwnAnchor)
196 myExportHeight (1.0),
197 myParams (theParams),
200 myOrientation (theOrientation),
202 myHasAnchorPoint (theHasOwnAnchor)
204 const gp_Pnt& aPoint = theOrientation.Location();
205 myPoint = OpenGl_Vec3 (static_cast<Standard_ShortReal> (aPoint.X()),
206 static_cast<Standard_ShortReal> (aPoint.Y()),
207 static_cast<Standard_ShortReal> (aPoint.Z()));
210 // =======================================================================
211 // function : SetPosition
213 // =======================================================================
214 void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
219 // =======================================================================
220 // function : SetFontSize
222 // =======================================================================
223 void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
224 const Standard_Integer theFontSize)
226 if (myParams.Height != theFontSize)
228 Release (theCtx.operator->());
230 myParams.Height = theFontSize;
233 // =======================================================================
236 // =======================================================================
237 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
238 const Standard_Utf8Char* theText,
239 const OpenGl_Vec3& thePoint)
241 releaseVbos (theCtx.operator->());
244 myString.FromUnicode (theText);
247 // =======================================================================
250 // =======================================================================
251 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
252 const Standard_Utf8Char* theText,
253 const OpenGl_Vec3& thePoint,
254 const OpenGl_TextParam& theParams)
256 if (myParams.Height != theParams.Height)
258 Release (theCtx.operator->());
262 releaseVbos (theCtx.operator->());
265 myParams = theParams;
267 myString.FromUnicode (theText);
270 // =======================================================================
273 // =======================================================================
274 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
275 const TCollection_ExtendedString& theText,
276 const OpenGl_Vec2& thePoint,
277 const OpenGl_TextParam& theParams)
279 if (myParams.Height != theParams.Height)
281 Release (theCtx.operator->());
285 releaseVbos (theCtx.operator->());
288 myParams = theParams;
289 myPoint.xy() = thePoint;
291 myString.FromUnicode (theText.ToExtString());
294 // =======================================================================
295 // function : ~OpenGl_Text
297 // =======================================================================
298 OpenGl_Text::~OpenGl_Text()
303 // =======================================================================
304 // function : releaseVbos
306 // =======================================================================
307 void OpenGl_Text::releaseVbos (OpenGl_Context* theCtx)
309 for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
311 Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
312 Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
316 theCtx->DelayedRelease (aVerts);
317 theCtx->DelayedRelease (aTCrds);
323 && !myBndVertsVbo.IsNull())
325 theCtx->DelayedRelease (myBndVertsVbo);
331 myBndVertsVbo.Nullify();
334 // =======================================================================
335 // function : Release
337 // =======================================================================
338 void OpenGl_Text::Release (OpenGl_Context* theCtx)
340 releaseVbos (theCtx);
341 if (!myFont.IsNull())
343 const TCollection_AsciiString aKey = myFont->ResourceKey();
347 theCtx->ReleaseResource (aKey, Standard_True);
352 // =======================================================================
353 // function : StringSize
355 // =======================================================================
356 void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
357 const NCollection_String& theText,
358 const OpenGl_AspectText& theTextAspect,
359 const OpenGl_TextParam& theParams,
360 const unsigned int theResolution,
361 Standard_ShortReal& theWidth,
362 Standard_ShortReal& theAscent,
363 Standard_ShortReal& theDescent)
368 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height, theResolution);
369 Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, theResolution, aFontKey);
370 if (aFont.IsNull() || !aFont->IsValid())
375 theAscent = aFont->Ascender();
376 theDescent = aFont->Descender();
378 GLfloat aWidth = 0.0f;
379 for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
381 const Standard_Utf32Char aCharThis = *anIter;
382 const Standard_Utf32Char aCharNext = *++anIter;
384 if (aCharThis == '\x0D' // CR (carriage return)
385 || aCharThis == '\a' // BEL (alarm)
386 || aCharThis == '\f' // FF (form feed) NP (new page)
387 || aCharThis == '\b' // BS (backspace)
388 || aCharThis == '\v') // VT (vertical tab)
390 continue; // skip unsupported carriage control codes
392 else if (aCharThis == '\x0A') // LF (line feed, new line)
394 theWidth = Max (theWidth, aWidth);
398 else if (aCharThis == ' ')
400 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
403 else if (aCharThis == '\t')
405 aWidth += aFont->FTFont()->AdvanceX (' ', aCharNext) * 8.0f;
409 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
411 theWidth = Max (theWidth, aWidth);
413 Handle(OpenGl_Context) aCtx = theCtx;
415 aCtx->ReleaseResource (aFontKey, Standard_True);
418 // =======================================================================
421 // =======================================================================
422 void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
424 const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText();
425 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
426 const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
427 #if !defined(GL_ES_VERSION_2_0)
428 const Standard_Integer aPrevPolygonMode = aCtx->SetPolygonMode (GL_FILL);
429 const bool aPrevHatchingMode = aCtx->SetPolygonHatchEnabled (false);
432 // Bind custom shader program or generate default version
433 aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
435 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
436 myProjMatrix.Convert (aCtx->ProjectionState.Current());
438 // use highlight color or colors from aspect
441 theWorkspace->TextColor(),
442 theWorkspace->TextSubtitleColor(),
446 if (!aPrevTexture.IsNull())
448 aCtx->BindTextures (aPrevTexture);
450 #if !defined(GL_ES_VERSION_2_0)
451 aCtx->SetPolygonMode (aPrevPolygonMode);
452 aCtx->SetPolygonHatchEnabled (aPrevHatchingMode);
455 // restore Z buffer settings
456 if (theWorkspace->UseZBuffer())
458 glEnable (GL_DEPTH_TEST);
462 // =======================================================================
465 // =======================================================================
466 void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx,
467 const OpenGl_AspectText& theTextAspect,
468 const unsigned int theResolution) const
470 render (theCtx, theTextAspect,
471 theTextAspect.Aspect()->ColorRGBA(),
472 theTextAspect.Aspect()->ColorSubTitleRGBA(),
476 // =======================================================================
477 // function : setupMatrix
479 // =======================================================================
480 void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
481 const OpenGl_AspectText& theTextAspect,
482 const OpenGl_Vec3 theDVec) const
484 OpenGl_Mat4d aModViewMat;
485 OpenGl_Mat4d aProjectMat;
486 if (myHasPlane && myHasAnchorPoint)
488 aProjectMat = myProjMatrix * myOrientationMatrix;
492 aProjectMat = myProjMatrix;
497 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
498 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
499 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.f, 0.f, 1.f);
503 // align coordinates to the nearest integer
504 // to avoid extra interpolation issues
505 GLdouble anObjX, anObjY, anObjZ;
506 Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()),
507 std::floor (myWinY + theDVec.y()),
508 myWinZ + theDVec.z(),
509 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
510 OpenGl_Mat4d::Map (aProjectMat),
518 const gp_Dir& aVectorDir = myOrientation.XDirection();
519 const gp_Dir& aVectorUp = myOrientation.Direction();
520 const gp_Dir& aVectorRight = myOrientation.YDirection();
522 aModViewMat.SetColumn (2, OpenGl_Vec3d (aVectorUp.X(), aVectorUp.Y(), aVectorUp.Z()));
523 aModViewMat.SetColumn (1, OpenGl_Vec3d (aVectorRight.X(), aVectorRight.Y(), aVectorRight.Z()));
524 aModViewMat.SetColumn (0, OpenGl_Vec3d (aVectorDir.X(), aVectorDir.Y(), aVectorDir.Z()));
526 if (!myHasAnchorPoint)
528 OpenGl_Mat4d aPosMat;
529 aPosMat.SetColumn (3, OpenGl_Vec3d (myPoint.x(), myPoint.y(), myPoint.z()));
530 aPosMat *= aModViewMat;
531 aModViewMat.SetColumn (3, aPosMat.GetColumn (3));
535 aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ));
540 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
541 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.0, 0.0, 1.0);
544 if (!theTextAspect.Aspect()->GetTextZoomable())
546 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
548 else if (theCtx->HasRenderScale())
550 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, theCtx->RenderScaleInv(), theCtx->RenderScaleInv(), theCtx->RenderScaleInv());
554 if (myHasPlane && !myHasAnchorPoint)
556 OpenGl_Mat4d aCurrentWorldViewMat;
557 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
558 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
562 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
564 theCtx->ApplyWorldViewMatrix();
568 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
569 theCtx->ApplyProjectionMatrix();
572 // Upload updated state to shader program
573 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
576 // =======================================================================
577 // function : drawText
579 // =======================================================================
580 void OpenGl_Text::drawText (const Handle(OpenGl_Context)& theCtx,
581 const OpenGl_AspectText& theTextAspect) const
584 if (theCtx->IsFeedback())
586 // position of the text and alignment is calculated by transformation matrix
587 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
591 (void )theTextAspect;
594 if (myVertsVbo.Length() != myTextures.Length()
595 || myTextures.IsEmpty())
600 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
602 const GLuint aTexId = myTextures.Value (anIter);
603 glBindTexture (GL_TEXTURE_2D, aTexId);
605 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
606 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
607 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
608 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
610 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
612 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
613 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
615 glBindTexture (GL_TEXTURE_2D, 0);
618 // =======================================================================
619 // function : FontKey
621 // =======================================================================
622 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
623 const Standard_Integer theHeight,
624 const unsigned int theResolution)
626 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
627 ? theAspect.Aspect()->GetTextFontAspect()
629 return theAspect.Aspect()->Font()
630 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
631 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
632 + TCollection_AsciiString(":") + theHeight;
635 // =======================================================================
636 // function : FindFont
638 // =======================================================================
639 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
640 const OpenGl_AspectText& theAspect,
641 const Standard_Integer theHeight,
642 const unsigned int theResolution,
643 const TCollection_AsciiString theKey)
645 Handle(OpenGl_Font) aFont;
648 return aFont; // invalid parameters
651 if (!theCtx->GetResource (theKey, aFont))
653 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
654 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.Aspect()->Font());
655 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
656 ? theAspect.Aspect()->GetTextFontAspect()
658 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
659 Handle(Font_FTFont) aFontFt;
660 if (!aRequestedFont.IsNull())
662 aFontFt = new Font_FTFont (Handle(Font_FTLibrary)());
664 if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
666 aFont = new OpenGl_Font (aFontFt, theKey);
667 if (!aFont->Init (theCtx))
669 TCollection_ExtendedString aMsg;
671 aMsg += theAspect.Aspect()->Font();
672 aMsg += "' - initialization of GL resources has failed!";
673 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
675 aFont->Release (theCtx.operator->());
676 aFont = new OpenGl_Font (aFontFt, theKey);
681 TCollection_ExtendedString aMsg;
683 aMsg += theAspect.Aspect()->Font();
684 aMsg += "' is broken or has incompatible format! File path: ";
685 aMsg += aRequestedFont->FontPath()->ToCString();
686 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
688 aFont = new OpenGl_Font (aFontFt, theKey);
693 TCollection_ExtendedString aMsg;
695 aMsg += theAspect.Aspect()->Font();
696 aMsg += "' is not found in the system!";
697 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
698 aFont = new OpenGl_Font (aFontFt, theKey);
701 theCtx->ShareResource (theKey, aFont);
706 // =======================================================================
707 // function : drawRect
709 // =======================================================================
710 void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
711 const OpenGl_AspectText& theTextAspect,
712 const OpenGl_Vec4& theColorSubs) const
714 Handle(OpenGl_ShaderProgram) aPrevProgram = theCtx->ActiveProgram();
715 if (myBndVertsVbo.IsNull())
717 OpenGl_Vec2 aQuad[4] =
719 OpenGl_Vec2(myBndBox.Right, myBndBox.Bottom),
720 OpenGl_Vec2(myBndBox.Right, myBndBox.Top),
721 OpenGl_Vec2(myBndBox.Left, myBndBox.Bottom),
722 OpenGl_Vec2(myBndBox.Left, myBndBox.Top)
724 if (theCtx->ToUseVbo())
726 myBndVertsVbo = new OpenGl_VertexBuffer();
730 myBndVertsVbo = new OpenGl_VertexBufferCompat();
732 myBndVertsVbo->Init (theCtx, 2, 4, aQuad[0].GetData());
736 theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Standard_False, Standard_False, Standard_False, Handle(OpenGl_ShaderProgram)());
738 #if !defined(GL_ES_VERSION_2_0)
739 if (theCtx->core11 != NULL
740 && theCtx->ActiveProgram().IsNull())
742 glBindTexture (GL_TEXTURE_2D, 0);
745 theCtx->SetColor4fv (theColorSubs);
746 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
747 myBndVertsVbo->BindAttribute (theCtx, Graphic3d_TOA_POS);
749 theCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
751 myBndVertsVbo->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
752 theCtx->BindProgram (aPrevProgram);
755 // =======================================================================
758 // =======================================================================
759 void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
760 const OpenGl_AspectText& theTextAspect,
761 const OpenGl_Vec4& theColorText,
762 const OpenGl_Vec4& theColorSubs,
763 const unsigned int theResolution) const
765 if (myString.IsEmpty())
770 // Note that using difference resolution in different Views in same Viewer
771 // will lead to performance regression (for example, text will be recreated every time).
772 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
774 && !myFont->ResourceKey().IsEqual (aFontKey))
777 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
782 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
784 if (!myFont->WasInitialized())
789 if (myTextures.IsEmpty())
791 Font_TextFormatter aFormatter;
792 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
795 aFormatter.Append (myString, *myFont->FTFont().operator->());
798 OpenGl_TextBuilder aBuilder;
799 aBuilder.Perform (aFormatter,
801 *myFont.operator->(),
806 aFormatter.BndBox (myBndBox);
807 if (!myBndVertsVbo.IsNull())
809 myBndVertsVbo->Release (theCtx.get());
810 myBndVertsVbo.Nullify();
814 if (myTextures.IsEmpty())
819 myExportHeight = 1.0f;
820 myScaleHeight = 1.0f;
822 theCtx->WorldViewState.Push();
823 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
825 const GLdouble aPointSize = (GLdouble )myFont->FTFont()->PointSize();
828 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(), myPoint.y(), myPoint.z(),
829 myModelMatrix, myProjMatrix, theCtx->Viewport(),
830 myWinX, myWinY, myWinZ);
832 // compute scale factor for constant text height
833 if (theTextAspect.Aspect()->GetTextZoomable())
835 myExportHeight = aPointSize;
839 Graphic3d_Vec3d aPnt1, aPnt2;
840 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY, myWinZ,
841 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
842 aPnt1.x(), aPnt1.y(), aPnt1.z());
843 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY + aPointSize, myWinZ,
844 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
845 aPnt2.x(), aPnt2.y(), aPnt2.z());
846 myScaleHeight = (aPnt2.y() - aPnt1.y()) / aPointSize;
849 myExportHeight = aPointSize / myExportHeight;
851 #if !defined(GL_ES_VERSION_2_0)
852 if (theCtx->core11 != NULL
853 && theCtx->caps->ffpEnable)
855 glDisable (GL_LIGHTING);
861 || theTextAspect.Aspect()->Style() == Aspect_TOST_ANNOTATION)
863 glDisable (GL_DEPTH_TEST);
866 if (theCtx->core15fwd != NULL)
868 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
870 #if !defined(GL_ES_VERSION_2_0)
871 // activate texture unit
872 GLint aTexEnvParam = GL_REPLACE;
873 if (theCtx->core11 != NULL)
876 glAlphaFunc (GL_GEQUAL, 0.285f);
877 glEnable (GL_ALPHA_TEST);
879 glDisable (GL_TEXTURE_1D);
880 glEnable (GL_TEXTURE_2D);
881 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
882 if (aTexEnvParam != GL_REPLACE)
884 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
891 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
894 switch (theTextAspect.Aspect()->DisplayType())
896 case Aspect_TODT_BLEND:
898 #if !defined(GL_ES_VERSION_2_0)
899 glEnable (GL_COLOR_LOGIC_OP);
904 case Aspect_TODT_SUBTITLE:
906 drawRect (theCtx, theTextAspect, theColorSubs);
909 case Aspect_TODT_DEKALE:
911 theCtx->SetColor4fv (theColorSubs);
912 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
913 drawText (theCtx, theTextAspect);
914 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
915 drawText (theCtx, theTextAspect);
916 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
917 drawText (theCtx, theTextAspect);
918 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
919 drawText (theCtx, theTextAspect);
922 case Aspect_TODT_DIMENSION:
923 case Aspect_TODT_NORMAL:
930 theCtx->SetColor4fv (theColorText);
931 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
932 drawText (theCtx, theTextAspect);
936 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
937 theCtx->ApplyProjectionMatrix();
940 #if !defined(GL_ES_VERSION_2_0)
941 if (theCtx->core11 != NULL)
943 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
947 if (theTextAspect.Aspect()->DisplayType() == Aspect_TODT_DIMENSION)
949 glDisable (GL_BLEND);
952 glDisable (GL_DEPTH_TEST);
954 #if !defined(GL_ES_VERSION_2_0)
955 if (theCtx->core11 != NULL)
957 glDisable (GL_TEXTURE_2D);
958 glDisable (GL_ALPHA_TEST);
961 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
963 glClear (GL_STENCIL_BUFFER_BIT);
964 glEnable (GL_STENCIL_TEST);
965 glStencilFunc (GL_ALWAYS, 1, 0xFF);
966 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
968 drawRect (theCtx, theTextAspect, OpenGl_Vec4 (1.0f, 1.0f, 1.0f, 1.0f));
970 glStencilFunc (GL_ALWAYS, 0, 0xFF);
972 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
975 // reset OpenGL state
976 glDisable (GL_BLEND);
977 glDisable (GL_STENCIL_TEST);
978 #if !defined(GL_ES_VERSION_2_0)
979 if (theCtx->core11 != NULL)
981 glDisable (GL_ALPHA_TEST);
983 glDisable (GL_COLOR_LOGIC_OP);
986 // model view matrix was modified
987 theCtx->WorldViewState.Pop();
988 theCtx->ApplyModelViewMatrix();