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.FontName().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, theAspect.Angle());
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->AspectText (Standard_True);
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()->BindProgram (
422 aTextAspect, aTextAspect->ShaderProgramRes (aCtx));
425 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
426 myProjMatrix.Convert (aCtx->ProjectionState.Current());
428 // use highlight color or colors from aspect
429 if (theWorkspace->NamedStatus & OPENGL_NS_HIGHLIGHT)
431 render (theWorkspace->PrinterContext(),
434 *theWorkspace->HighlightColor,
435 *theWorkspace->HighlightColor,
436 theWorkspace->View()->RenderingParams().Resolution);
440 render (theWorkspace->PrinterContext(),
443 aTextAspect->Color(),
444 aTextAspect->SubtitleColor(),
445 theWorkspace->View()->RenderingParams().Resolution);
448 aCtx->BindProgram (NULL);
451 if (!aPrevTexture.IsNull())
453 theWorkspace->EnableTexture (aPrevTexture);
456 // restore Z buffer settings
457 if (theWorkspace->UseZBuffer())
459 glEnable (GL_DEPTH_TEST);
463 // =======================================================================
466 // =======================================================================
467 void OpenGl_Text::Render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
468 const Handle(OpenGl_Context)& theCtx,
469 const OpenGl_AspectText& theTextAspect,
470 const unsigned int theResolution) const
472 render (thePrintCtx, theCtx, theTextAspect, theTextAspect.Color(), theTextAspect.SubtitleColor(), theResolution);
475 // =======================================================================
476 // function : setupMatrix
478 // =======================================================================
479 void OpenGl_Text::setupMatrix (const Handle(OpenGl_PrinterContext)& thePrintCtx,
480 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.Angle(), 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.Angle(), 0.0, 0.0, 1.0);
544 if (!theTextAspect.IsZoomable())
547 // if the context has assigned printer context, use it's parameters
548 if (!thePrintCtx.IsNull())
550 // get printing scaling in x and y dimensions
551 GLfloat aTextScalex = 1.0f, aTextScaley = 1.0f;
552 thePrintCtx->GetScale (aTextScalex, aTextScaley);
554 // text should be scaled in all directions with same
555 // factor to save its proportions, so use height (y) scaling
556 // as it is better for keeping text/3d graphics proportions
557 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, aTextScaley, aTextScaley, aTextScaley);
562 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
566 if (myHasPlane && !myHasAnchorPoint)
568 OpenGl_Mat4d aCurrentWorldViewMat;
569 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
570 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
574 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
576 theCtx->ApplyWorldViewMatrix();
580 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
581 theCtx->ApplyProjectionMatrix();
584 if (!theCtx->ActiveProgram().IsNull())
586 // Upload updated state to shader program
587 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
591 // =======================================================================
592 // function : drawText
594 // =======================================================================
596 void OpenGl_Text::drawText (const Handle(OpenGl_PrinterContext)& ,
597 const Handle(OpenGl_Context)& theCtx,
599 const OpenGl_AspectText& theTextAspect) const
601 const OpenGl_AspectText& ) const
605 if (theCtx->IsFeedback())
607 // position of the text and alignment is calculated by transformation matrix
608 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
613 if (myVertsVbo.Length() != myTextures.Length()
614 || myTextures.IsEmpty())
619 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
621 const GLuint aTexId = myTextures.Value (anIter);
622 glBindTexture (GL_TEXTURE_2D, aTexId);
624 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
625 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
626 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
627 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
629 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
631 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
632 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
634 glBindTexture (GL_TEXTURE_2D, 0);
637 // =======================================================================
638 // function : FontKey
640 // =======================================================================
641 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
642 const Standard_Integer theHeight,
643 const unsigned int theResolution)
645 const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
646 return theAspect.FontName()
647 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
648 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
649 + TCollection_AsciiString(":") + theHeight;
652 // =======================================================================
653 // function : FindFont
655 // =======================================================================
656 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
657 const OpenGl_AspectText& theAspect,
658 const Standard_Integer theHeight,
659 const unsigned int theResolution,
660 const TCollection_AsciiString theKey)
662 Handle(OpenGl_Font) aFont;
665 return aFont; // invalid parameters
668 if (!theCtx->GetResource (theKey, aFont))
670 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
671 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.FontName());
672 const Font_FontAspect anAspect = (theAspect.FontAspect() != Font_FA_Undefined) ? theAspect.FontAspect() : Font_FA_Regular;
673 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
674 Handle(Font_FTFont) aFontFt;
675 if (!aRequestedFont.IsNull())
677 aFontFt = new Font_FTFont (NULL);
679 if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
681 aFont = new OpenGl_Font (aFontFt, theKey);
682 if (!aFont->Init (theCtx))
684 TCollection_ExtendedString aMsg;
686 aMsg += theAspect.FontName();
687 aMsg += "' - initialization of GL resources has failed!";
688 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
690 aFont->Release (theCtx.operator->());
691 aFont = new OpenGl_Font (aFontFt, theKey);
696 TCollection_ExtendedString aMsg;
698 aMsg += theAspect.FontName();
699 aMsg += "' is broken or has incompatible format! File path: ";
700 aMsg += aRequestedFont->FontPath()->ToCString();
701 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
703 aFont = new OpenGl_Font (aFontFt, theKey);
708 TCollection_ExtendedString aMsg;
710 aMsg += theAspect.FontName();
711 aMsg += "' is not found in the system!";
712 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
713 aFont = new OpenGl_Font (aFontFt, theKey);
716 theCtx->ShareResource (theKey, aFont);
721 // =======================================================================
724 // =======================================================================
725 void OpenGl_Text::render (const Handle(OpenGl_PrinterContext)& thePrintCtx,
726 const Handle(OpenGl_Context)& theCtx,
727 const OpenGl_AspectText& theTextAspect,
728 const TEL_COLOUR& theColorText,
729 const TEL_COLOUR& theColorSubs,
730 const unsigned int theResolution) const
732 if (myString.IsEmpty())
737 // Note that using difference resolution in different Views in same Viewer
738 // will lead to performance regression (for example, text will be recreated every time).
739 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
741 && !myFont->ResourceKey().IsEqual (aFontKey))
744 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
749 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
751 if (!myFont->WasInitialized())
756 if (myTextures.IsEmpty())
758 Font_TextFormatter aFormatter;
759 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
762 aFormatter.Append (myString, *myFont->FTFont().operator->());
765 OpenGl_TextBuilder aBuilder;
766 aBuilder.Perform (aFormatter,
768 *myFont.operator->(),
773 aFormatter.BndBox (myBndBox);
776 if (myTextures.IsEmpty())
781 myExportHeight = 1.0f;
782 myScaleHeight = 1.0f;
784 if (myHasPlane && !myHasAnchorPoint)
786 OpenGl_Mat4d aWorldViewMat;
787 aWorldViewMat.Convert (theCtx->WorldViewState.Current());
788 theCtx->WorldViewState.Push();
789 theCtx->WorldViewState.SetCurrent<Standard_Real> (aWorldViewMat);
790 theCtx->ApplyWorldViewMatrix();
794 theCtx->WorldViewState.Push();
797 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
801 glGetIntegerv (GL_VIEWPORT, myViewport);
803 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(),
813 // compute scale factor for constant text height
815 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
818 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
826 const GLdouble h = (GLdouble )myFont->FTFont()->PointSize();
827 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
830 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
837 myScaleHeight = (y2 - y1) / h;
838 if (theTextAspect.IsZoomable())
840 myExportHeight = (float )h;
843 myExportHeight = (float )myFont->FTFont()->PointSize() / myExportHeight;
845 #if !defined(GL_ES_VERSION_2_0)
846 if (theCtx->core11 != NULL)
848 glDisable (GL_LIGHTING);
854 || theTextAspect.StyleType() == Aspect_TOST_ANNOTATION)
856 glDisable (GL_DEPTH_TEST);
859 if (theCtx->core15fwd != NULL)
861 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
863 #if !defined(GL_ES_VERSION_2_0)
864 // activate texture unit
865 GLint aTexEnvParam = GL_REPLACE;
866 if (theCtx->core11 != NULL)
869 glAlphaFunc (GL_GEQUAL, 0.285f);
870 glEnable (GL_ALPHA_TEST);
872 glDisable (GL_TEXTURE_1D);
873 glEnable (GL_TEXTURE_2D);
874 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
875 if (aTexEnvParam != GL_REPLACE)
877 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
884 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
887 switch (theTextAspect.DisplayType())
889 case Aspect_TODT_BLEND:
891 #if !defined(GL_ES_VERSION_2_0)
892 glEnable (GL_COLOR_LOGIC_OP);
897 case Aspect_TODT_SUBTITLE:
899 #if !defined(GL_ES_VERSION_2_0)
900 if (theCtx->core11 != NULL)
902 theCtx->core11->glColor3fv (theColorSubs.rgb);
903 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
905 glBindTexture (GL_TEXTURE_2D, 0);
907 glVertex2f (myBndBox.Left, myBndBox.Top);
908 glVertex2f (myBndBox.Right, myBndBox.Top);
909 glVertex2f (myBndBox.Right, myBndBox.Bottom);
910 glVertex2f (myBndBox.Left, myBndBox.Bottom);
916 case Aspect_TODT_DEKALE:
918 theCtx->SetColor4fv (*(const OpenGl_Vec4* )theColorSubs.rgb);
919 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
920 drawText (thePrintCtx, theCtx, theTextAspect);
921 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
922 drawText (thePrintCtx, theCtx, theTextAspect);
923 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
924 drawText (thePrintCtx, theCtx, theTextAspect);
925 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
926 drawText (thePrintCtx, theCtx, theTextAspect);
929 case Aspect_TODT_DIMENSION:
930 case Aspect_TODT_NORMAL:
937 theCtx->SetColor4fv (*(const OpenGl_Vec4* )theColorText.rgb);
938 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
939 drawText (thePrintCtx, theCtx, theTextAspect);
943 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
944 theCtx->ApplyProjectionMatrix();
947 #if !defined(GL_ES_VERSION_2_0)
948 if (theCtx->core11 != NULL)
950 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
954 if (theTextAspect.DisplayType() == Aspect_TODT_DIMENSION)
956 setupMatrix (thePrintCtx, theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
958 glDisable (GL_BLEND);
961 glDisable (GL_DEPTH_TEST);
963 #if !defined(GL_ES_VERSION_2_0)
964 if (theCtx->core11 != NULL)
966 glDisable (GL_TEXTURE_2D);
967 glDisable (GL_ALPHA_TEST);
970 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
972 glClear (GL_STENCIL_BUFFER_BIT);
973 glEnable (GL_STENCIL_TEST);
974 glStencilFunc (GL_ALWAYS, 1, 0xFF);
975 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
977 #if !defined(GL_ES_VERSION_2_0)
978 if (theCtx->core11 != NULL)
981 glVertex2f (myBndBox.Left, myBndBox.Top);
982 glVertex2f (myBndBox.Right, myBndBox.Top);
983 glVertex2f (myBndBox.Right, myBndBox.Bottom);
984 glVertex2f (myBndBox.Left, myBndBox.Bottom);
989 glStencilFunc (GL_ALWAYS, 0, 0xFF);
991 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
994 // reset OpenGL state
995 glDisable (GL_BLEND);
996 glDisable (GL_STENCIL_TEST);
997 #if !defined(GL_ES_VERSION_2_0)
998 if (theCtx->core11 != NULL)
1000 glDisable (GL_ALPHA_TEST);
1002 glDisable (GL_COLOR_LOGIC_OP);
1005 // model view matrix was modified
1006 theCtx->WorldViewState.Pop();
1007 theCtx->ApplyModelViewMatrix();