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);
118 #if !defined(GL_ES_VERSION_2_0)
121 glRasterPos2f (0.0f, 0.0f);
125 glRasterPos3f (0.0f, 0.0f, 0.0f);
129 glBitmap (1, 1, 0, 0, 0, 0, &aZero);
132 // Standard GL2PS's alignment isn't used, because it doesn't work correctly
133 // for all formats, therefore alignment is calculated manually relative
134 // to the bottom-left corner, which corresponds to the GL2PS_TEXT_BL value
135 gl2psTextOpt (theText.ToCString(), aPsFont, (GLshort)theHeight, GL2PS_TEXT_BL, (float )theAspect.Aspect()->GetTextAngle());
139 } // anonymous namespace
141 // =======================================================================
142 // function : OpenGl_Text
144 // =======================================================================
145 OpenGl_Text::OpenGl_Text()
149 myScaleHeight (1.0f),
150 myPoint (0.0f, 0.0f, 0.0f),
153 myHasAnchorPoint (true)
155 myParams.Height = 10;
156 myParams.HAlign = Graphic3d_HTA_LEFT;
157 myParams.VAlign = Graphic3d_VTA_BOTTOM;
160 // =======================================================================
161 // function : OpenGl_Text
163 // =======================================================================
164 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
165 const OpenGl_Vec3& thePoint,
166 const OpenGl_TextParam& theParams)
170 myScaleHeight (1.0f),
171 myExportHeight (1.0f),
172 myParams (theParams),
177 myHasAnchorPoint (true)
182 // =======================================================================
183 // function : OpenGl_Text
185 // =======================================================================
186 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
187 const gp_Ax2& theOrientation,
188 const OpenGl_TextParam& theParams,
189 const bool theHasOwnAnchor)
194 myExportHeight (1.0),
195 myParams (theParams),
198 myOrientation (theOrientation),
200 myHasAnchorPoint (theHasOwnAnchor)
202 const gp_Pnt& aPoint = theOrientation.Location();
203 myPoint = OpenGl_Vec3 (static_cast<Standard_ShortReal> (aPoint.X()),
204 static_cast<Standard_ShortReal> (aPoint.Y()),
205 static_cast<Standard_ShortReal> (aPoint.Z()));
208 // =======================================================================
209 // function : SetPosition
211 // =======================================================================
212 void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
217 // =======================================================================
218 // function : SetFontSize
220 // =======================================================================
221 void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
222 const Standard_Integer theFontSize)
224 if (myParams.Height != theFontSize)
226 Release (theCtx.operator->());
228 myParams.Height = theFontSize;
231 // =======================================================================
234 // =======================================================================
235 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
236 const Standard_Utf8Char* theText,
237 const OpenGl_Vec3& thePoint)
239 releaseVbos (theCtx.operator->());
242 myString.FromUnicode (theText);
245 // =======================================================================
248 // =======================================================================
249 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
250 const Standard_Utf8Char* theText,
251 const OpenGl_Vec3& thePoint,
252 const OpenGl_TextParam& theParams)
254 if (myParams.Height != theParams.Height)
256 Release (theCtx.operator->());
260 releaseVbos (theCtx.operator->());
263 myParams = theParams;
265 myString.FromUnicode (theText);
268 // =======================================================================
271 // =======================================================================
272 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
273 const TCollection_ExtendedString& theText,
274 const OpenGl_Vec2& thePoint,
275 const OpenGl_TextParam& theParams)
277 if (myParams.Height != theParams.Height)
279 Release (theCtx.operator->());
283 releaseVbos (theCtx.operator->());
286 myParams = theParams;
287 myPoint.xy() = thePoint;
289 myString.FromUnicode ((Standard_Utf16Char* )theText.ToExtString());
292 // =======================================================================
293 // function : ~OpenGl_Text
295 // =======================================================================
296 OpenGl_Text::~OpenGl_Text()
301 // =======================================================================
302 // function : releaseVbos
304 // =======================================================================
305 void OpenGl_Text::releaseVbos (OpenGl_Context* theCtx)
307 for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
309 Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
310 Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
314 theCtx->DelayedRelease (aVerts);
315 theCtx->DelayedRelease (aTCrds);
325 // =======================================================================
326 // function : Release
328 // =======================================================================
329 void OpenGl_Text::Release (OpenGl_Context* theCtx)
331 releaseVbos (theCtx);
332 if (!myFont.IsNull())
334 Handle(OpenGl_Context) aCtx = theCtx;
335 const TCollection_AsciiString aKey = myFont->ResourceKey();
338 aCtx->ReleaseResource (aKey, Standard_True);
342 // =======================================================================
343 // function : StringSize
345 // =======================================================================
346 void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
347 const NCollection_String& theText,
348 const OpenGl_AspectText& theTextAspect,
349 const OpenGl_TextParam& theParams,
350 const unsigned int theResolution,
351 Standard_ShortReal& theWidth,
352 Standard_ShortReal& theAscent,
353 Standard_ShortReal& theDescent)
358 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height, theResolution);
359 Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, theResolution, aFontKey);
360 if (aFont.IsNull() || !aFont->IsValid())
365 theAscent = aFont->Ascender();
366 theDescent = aFont->Descender();
368 GLfloat aWidth = 0.0f;
369 for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
371 const Standard_Utf32Char aCharThis = *anIter;
372 const Standard_Utf32Char aCharNext = *++anIter;
374 if (aCharThis == '\x0D' // CR (carriage return)
375 || aCharThis == '\a' // BEL (alarm)
376 || aCharThis == '\f' // FF (form feed) NP (new page)
377 || aCharThis == '\b' // BS (backspace)
378 || aCharThis == '\v') // VT (vertical tab)
380 continue; // skip unsupported carriage control codes
382 else if (aCharThis == '\x0A') // LF (line feed, new line)
384 theWidth = Max (theWidth, aWidth);
388 else if (aCharThis == ' ')
390 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
393 else if (aCharThis == '\t')
395 aWidth += aFont->FTFont()->AdvanceX (' ', aCharNext) * 8.0f;
399 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
401 theWidth = Max (theWidth, aWidth);
403 Handle(OpenGl_Context) aCtx = theCtx;
405 aCtx->ReleaseResource (aFontKey, Standard_True);
408 // =======================================================================
411 // =======================================================================
412 void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
414 const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText();
415 const Handle(OpenGl_Texture) aPrevTexture = theWorkspace->DisableTexture();
416 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
418 // Bind custom shader program or generate default version
419 if (aCtx->core20fwd != NULL)
421 aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
424 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
425 myProjMatrix.Convert (aCtx->ProjectionState.Current());
427 // use highlight color or colors from aspect
428 render (theWorkspace->PrinterContext(),
431 theWorkspace->TextColor(),
432 theWorkspace->TextSubtitleColor(),
433 theWorkspace->View()->RenderingParams().Resolution);
435 aCtx->BindProgram (NULL);
438 if (!aPrevTexture.IsNull())
440 theWorkspace->EnableTexture (aPrevTexture);
443 // restore Z buffer settings
444 if (theWorkspace->UseZBuffer())
446 glEnable (GL_DEPTH_TEST);
450 // =======================================================================
453 // =======================================================================
454 void OpenGl_Text::Render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
455 const Handle(OpenGl_Context)& theCtx,
456 const OpenGl_AspectText& theTextAspect,
457 const unsigned int theResolution) const
459 render (thePrintCtx, theCtx, theTextAspect,
460 theTextAspect.Aspect()->ColorRGBA(),
461 theTextAspect.Aspect()->ColorSubTitleRGBA(),
465 // =======================================================================
466 // function : setupMatrix
468 // =======================================================================
469 void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
470 const Handle(OpenGl_Context)& theCtx,
471 const OpenGl_AspectText& theTextAspect,
472 const OpenGl_Vec3 theDVec) const
474 OpenGl_Mat4d aModViewMat;
475 OpenGl_Mat4d aProjectMat;
476 if (myHasPlane && myHasAnchorPoint)
478 aProjectMat = myProjMatrix * myOrientationMatrix;
482 aProjectMat = myProjMatrix;
487 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
488 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
489 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.f, 0.f, 1.f);
493 // align coordinates to the nearest integer
494 // to avoid extra interpolation issues
495 GLdouble anObjX, anObjY, anObjZ;
496 Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()),
497 std::floor (myWinY + theDVec.y()),
498 myWinZ + theDVec.z(),
499 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
500 OpenGl_Mat4d::Map (aProjectMat),
508 const gp_Dir& aVectorDir = myOrientation.XDirection();
509 const gp_Dir& aVectorUp = myOrientation.Direction();
510 const gp_Dir& aVectorRight = myOrientation.YDirection();
512 aModViewMat.SetColumn (2, OpenGl_Vec3d (aVectorUp.X(), aVectorUp.Y(), aVectorUp.Z()));
513 aModViewMat.SetColumn (1, OpenGl_Vec3d (aVectorRight.X(), aVectorRight.Y(), aVectorRight.Z()));
514 aModViewMat.SetColumn (0, OpenGl_Vec3d (aVectorDir.X(), aVectorDir.Y(), aVectorDir.Z()));
516 if (!myHasAnchorPoint)
518 OpenGl_Mat4d aPosMat;
519 aPosMat.SetColumn (3, OpenGl_Vec3d (myPoint.x(), myPoint.y(), myPoint.z()));
520 aPosMat *= aModViewMat;
521 aModViewMat.SetColumn (3, aPosMat.GetColumn (3));
525 aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ));
530 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
531 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.0, 0.0, 1.0);
534 if (!theTextAspect.Aspect()->GetTextZoomable())
537 // if the context has assigned printer context, use it's parameters
538 if (!thePrintCtx.IsNull())
540 // get printing scaling in x and y dimensions
541 GLfloat aTextScalex = 1.0f, aTextScaley = 1.0f;
542 thePrintCtx->GetScale (aTextScalex, aTextScaley);
544 // text should be scaled in all directions with same
545 // factor to save its proportions, so use height (y) scaling
546 // as it is better for keeping text/3d graphics proportions
547 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, aTextScaley, aTextScaley, aTextScaley);
552 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
556 if (myHasPlane && !myHasAnchorPoint)
558 OpenGl_Mat4d aCurrentWorldViewMat;
559 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
560 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
564 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
566 theCtx->ApplyWorldViewMatrix();
570 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
571 theCtx->ApplyProjectionMatrix();
574 if (!theCtx->ActiveProgram().IsNull())
576 // Upload updated state to shader program
577 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
581 // =======================================================================
582 // function : drawText
584 // =======================================================================
586 void OpenGl_Text::drawText (const Handle(OpenGl_PrinterContext)& ,
587 const Handle(OpenGl_Context)& theCtx,
589 const OpenGl_AspectText& theTextAspect) const
591 const OpenGl_AspectText& ) const
595 if (theCtx->IsFeedback())
597 // position of the text and alignment is calculated by transformation matrix
598 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
603 if (myVertsVbo.Length() != myTextures.Length()
604 || myTextures.IsEmpty())
609 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
611 const GLuint aTexId = myTextures.Value (anIter);
612 glBindTexture (GL_TEXTURE_2D, aTexId);
614 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
615 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
616 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
617 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
619 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
621 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
622 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
624 glBindTexture (GL_TEXTURE_2D, 0);
627 // =======================================================================
628 // function : FontKey
630 // =======================================================================
631 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
632 const Standard_Integer theHeight,
633 const unsigned int theResolution)
635 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
636 ? theAspect.Aspect()->GetTextFontAspect()
638 return theAspect.Aspect()->Font()
639 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
640 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
641 + TCollection_AsciiString(":") + theHeight;
644 // =======================================================================
645 // function : FindFont
647 // =======================================================================
648 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
649 const OpenGl_AspectText& theAspect,
650 const Standard_Integer theHeight,
651 const unsigned int theResolution,
652 const TCollection_AsciiString theKey)
654 Handle(OpenGl_Font) aFont;
657 return aFont; // invalid parameters
660 if (!theCtx->GetResource (theKey, aFont))
662 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
663 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.Aspect()->Font());
664 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
665 ? theAspect.Aspect()->GetTextFontAspect()
667 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
668 Handle(Font_FTFont) aFontFt;
669 if (!aRequestedFont.IsNull())
671 aFontFt = new Font_FTFont (NULL);
673 if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
675 aFont = new OpenGl_Font (aFontFt, theKey);
676 if (!aFont->Init (theCtx))
678 TCollection_ExtendedString aMsg;
680 aMsg += theAspect.Aspect()->Font();
681 aMsg += "' - initialization of GL resources has failed!";
682 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
684 aFont->Release (theCtx.operator->());
685 aFont = new OpenGl_Font (aFontFt, theKey);
690 TCollection_ExtendedString aMsg;
692 aMsg += theAspect.Aspect()->Font();
693 aMsg += "' is broken or has incompatible format! File path: ";
694 aMsg += aRequestedFont->FontPath()->ToCString();
695 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
697 aFont = new OpenGl_Font (aFontFt, theKey);
702 TCollection_ExtendedString aMsg;
704 aMsg += theAspect.Aspect()->Font();
705 aMsg += "' is not found in the system!";
706 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
707 aFont = new OpenGl_Font (aFontFt, theKey);
710 theCtx->ShareResource (theKey, aFont);
715 // =======================================================================
718 // =======================================================================
719 void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
720 const Handle(OpenGl_Context)& theCtx,
721 const OpenGl_AspectText& theTextAspect,
722 const OpenGl_Vec4& theColorText,
723 const OpenGl_Vec4& theColorSubs,
724 const unsigned int theResolution) const
726 if (myString.IsEmpty())
731 // Note that using difference resolution in different Views in same Viewer
732 // will lead to performance regression (for example, text will be recreated every time).
733 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
735 && !myFont->ResourceKey().IsEqual (aFontKey))
738 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
743 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
745 if (!myFont->WasInitialized())
750 if (myTextures.IsEmpty())
752 Font_TextFormatter aFormatter;
753 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
756 aFormatter.Append (myString, *myFont->FTFont().operator->());
759 OpenGl_TextBuilder aBuilder;
760 aBuilder.Perform (aFormatter,
762 *myFont.operator->(),
767 aFormatter.BndBox (myBndBox);
770 if (myTextures.IsEmpty())
775 myExportHeight = 1.0f;
776 myScaleHeight = 1.0f;
778 if (myHasPlane && !myHasAnchorPoint)
780 OpenGl_Mat4d aWorldViewMat;
781 aWorldViewMat.Convert (theCtx->WorldViewState.Current());
782 theCtx->WorldViewState.Push();
783 theCtx->WorldViewState.SetCurrent<Standard_Real> (aWorldViewMat);
784 theCtx->ApplyWorldViewMatrix();
788 theCtx->WorldViewState.Push();
791 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
795 glGetIntegerv (GL_VIEWPORT, myViewport);
797 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(),
807 // compute scale factor for constant text height
809 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
812 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
820 const GLdouble h = (GLdouble )myFont->FTFont()->PointSize();
821 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
824 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
831 myScaleHeight = (y2 - y1) / h;
832 if (theTextAspect.Aspect()->GetTextZoomable())
834 myExportHeight = (float )h;
837 myExportHeight = (float )myFont->FTFont()->PointSize() / myExportHeight;
839 #if !defined(GL_ES_VERSION_2_0)
840 if (theCtx->core11 != NULL)
842 glDisable (GL_LIGHTING);
848 || theTextAspect.Aspect()->Style() == Aspect_TOST_ANNOTATION)
850 glDisable (GL_DEPTH_TEST);
853 if (theCtx->core15fwd != NULL)
855 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
857 #if !defined(GL_ES_VERSION_2_0)
858 // activate texture unit
859 GLint aTexEnvParam = GL_REPLACE;
860 if (theCtx->core11 != NULL)
863 glAlphaFunc (GL_GEQUAL, 0.285f);
864 glEnable (GL_ALPHA_TEST);
866 glDisable (GL_TEXTURE_1D);
867 glEnable (GL_TEXTURE_2D);
868 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
869 if (aTexEnvParam != GL_REPLACE)
871 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
878 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
881 switch (theTextAspect.Aspect()->DisplayType())
883 case Aspect_TODT_BLEND:
885 #if !defined(GL_ES_VERSION_2_0)
886 glEnable (GL_COLOR_LOGIC_OP);
891 case Aspect_TODT_SUBTITLE:
893 #if !defined(GL_ES_VERSION_2_0)
894 if (theCtx->core11 != NULL)
896 theCtx->SetColor4fv (theColorSubs);
897 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
899 glBindTexture (GL_TEXTURE_2D, 0);
901 glVertex2f (myBndBox.Left, myBndBox.Top);
902 glVertex2f (myBndBox.Right, myBndBox.Top);
903 glVertex2f (myBndBox.Right, myBndBox.Bottom);
904 glVertex2f (myBndBox.Left, myBndBox.Bottom);
910 case Aspect_TODT_DEKALE:
912 theCtx->SetColor4fv (theColorSubs);
913 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
914 drawText (thePrintCtx, theCtx, theTextAspect);
915 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
916 drawText (thePrintCtx, theCtx, theTextAspect);
917 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
918 drawText (thePrintCtx, theCtx, theTextAspect);
919 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
920 drawText (thePrintCtx, theCtx, theTextAspect);
923 case Aspect_TODT_DIMENSION:
924 case Aspect_TODT_NORMAL:
931 theCtx->SetColor4fv (theColorText);
932 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
933 drawText (thePrintCtx, theCtx, theTextAspect);
937 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
938 theCtx->ApplyProjectionMatrix();
941 #if !defined(GL_ES_VERSION_2_0)
942 if (theCtx->core11 != NULL)
944 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
948 if (theTextAspect.Aspect()->DisplayType() == Aspect_TODT_DIMENSION)
950 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
952 glDisable (GL_BLEND);
955 glDisable (GL_DEPTH_TEST);
957 #if !defined(GL_ES_VERSION_2_0)
958 if (theCtx->core11 != NULL)
960 glDisable (GL_TEXTURE_2D);
961 glDisable (GL_ALPHA_TEST);
964 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
966 glClear (GL_STENCIL_BUFFER_BIT);
967 glEnable (GL_STENCIL_TEST);
968 glStencilFunc (GL_ALWAYS, 1, 0xFF);
969 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
971 #if !defined(GL_ES_VERSION_2_0)
972 if (theCtx->core11 != NULL)
975 glVertex2f (myBndBox.Left, myBndBox.Top);
976 glVertex2f (myBndBox.Right, myBndBox.Top);
977 glVertex2f (myBndBox.Right, myBndBox.Bottom);
978 glVertex2f (myBndBox.Left, myBndBox.Bottom);
983 glStencilFunc (GL_ALWAYS, 0, 0xFF);
985 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
988 // reset OpenGL state
989 glDisable (GL_BLEND);
990 glDisable (GL_STENCIL_TEST);
991 #if !defined(GL_ES_VERSION_2_0)
992 if (theCtx->core11 != NULL)
994 glDisable (GL_ALPHA_TEST);
996 glDisable (GL_COLOR_LOGIC_OP);
999 // model view matrix was modified
1000 theCtx->WorldViewState.Pop();
1001 theCtx->ApplyModelViewMatrix();