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 (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();
417 #if !defined(GL_ES_VERSION_2_0)
418 const Standard_Integer aPrevPolygonMode = aCtx->SetPolygonMode (GL_FILL);
419 const bool aPrevHatchingMode = aCtx->SetPolygonHatchEnabled (false);
422 // Bind custom shader program or generate default version
423 if (aCtx->core20fwd != NULL)
425 aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
428 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
429 myProjMatrix.Convert (aCtx->ProjectionState.Current());
431 // use highlight color or colors from aspect
434 theWorkspace->TextColor(),
435 theWorkspace->TextSubtitleColor(),
436 theWorkspace->View()->RenderingParams().Resolution);
438 aCtx->BindProgram (NULL);
441 if (!aPrevTexture.IsNull())
443 theWorkspace->EnableTexture (aPrevTexture);
445 #if !defined(GL_ES_VERSION_2_0)
446 aCtx->SetPolygonMode (aPrevPolygonMode);
447 aCtx->SetPolygonHatchEnabled (aPrevHatchingMode);
450 // restore Z buffer settings
451 if (theWorkspace->UseZBuffer())
453 glEnable (GL_DEPTH_TEST);
457 // =======================================================================
460 // =======================================================================
461 void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx,
462 const OpenGl_AspectText& theTextAspect,
463 const unsigned int theResolution) const
465 render (theCtx, theTextAspect,
466 theTextAspect.Aspect()->ColorRGBA(),
467 theTextAspect.Aspect()->ColorSubTitleRGBA(),
471 // =======================================================================
472 // function : setupMatrix
474 // =======================================================================
475 void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
476 const OpenGl_AspectText& theTextAspect,
477 const OpenGl_Vec3 theDVec) const
479 OpenGl_Mat4d aModViewMat;
480 OpenGl_Mat4d aProjectMat;
481 if (myHasPlane && myHasAnchorPoint)
483 aProjectMat = myProjMatrix * myOrientationMatrix;
487 aProjectMat = myProjMatrix;
492 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
493 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
494 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.f, 0.f, 1.f);
498 // align coordinates to the nearest integer
499 // to avoid extra interpolation issues
500 GLdouble anObjX, anObjY, anObjZ;
501 Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()),
502 std::floor (myWinY + theDVec.y()),
503 myWinZ + theDVec.z(),
504 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
505 OpenGl_Mat4d::Map (aProjectMat),
513 const gp_Dir& aVectorDir = myOrientation.XDirection();
514 const gp_Dir& aVectorUp = myOrientation.Direction();
515 const gp_Dir& aVectorRight = myOrientation.YDirection();
517 aModViewMat.SetColumn (2, OpenGl_Vec3d (aVectorUp.X(), aVectorUp.Y(), aVectorUp.Z()));
518 aModViewMat.SetColumn (1, OpenGl_Vec3d (aVectorRight.X(), aVectorRight.Y(), aVectorRight.Z()));
519 aModViewMat.SetColumn (0, OpenGl_Vec3d (aVectorDir.X(), aVectorDir.Y(), aVectorDir.Z()));
521 if (!myHasAnchorPoint)
523 OpenGl_Mat4d aPosMat;
524 aPosMat.SetColumn (3, OpenGl_Vec3d (myPoint.x(), myPoint.y(), myPoint.z()));
525 aPosMat *= aModViewMat;
526 aModViewMat.SetColumn (3, aPosMat.GetColumn (3));
530 aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ));
535 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
536 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.0, 0.0, 1.0);
539 if (!theTextAspect.Aspect()->GetTextZoomable())
541 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
545 if (myHasPlane && !myHasAnchorPoint)
547 OpenGl_Mat4d aCurrentWorldViewMat;
548 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
549 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
553 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
555 theCtx->ApplyWorldViewMatrix();
559 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
560 theCtx->ApplyProjectionMatrix();
563 if (!theCtx->ActiveProgram().IsNull())
565 // Upload updated state to shader program
566 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
570 // =======================================================================
571 // function : drawText
573 // =======================================================================
574 void OpenGl_Text::drawText (const Handle(OpenGl_Context)& theCtx,
575 const OpenGl_AspectText& theTextAspect) const
578 if (theCtx->IsFeedback())
580 // position of the text and alignment is calculated by transformation matrix
581 exportText (myString, myIs2d, theTextAspect, (Standard_Integer )myExportHeight);
585 (void )theTextAspect;
588 if (myVertsVbo.Length() != myTextures.Length()
589 || myTextures.IsEmpty())
594 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
596 const GLuint aTexId = myTextures.Value (anIter);
597 glBindTexture (GL_TEXTURE_2D, aTexId);
599 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
600 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
601 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
602 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
604 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
606 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
607 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
609 glBindTexture (GL_TEXTURE_2D, 0);
612 // =======================================================================
613 // function : FontKey
615 // =======================================================================
616 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
617 const Standard_Integer theHeight,
618 const unsigned int theResolution)
620 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
621 ? theAspect.Aspect()->GetTextFontAspect()
623 return theAspect.Aspect()->Font()
624 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
625 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
626 + TCollection_AsciiString(":") + theHeight;
629 // =======================================================================
630 // function : FindFont
632 // =======================================================================
633 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
634 const OpenGl_AspectText& theAspect,
635 const Standard_Integer theHeight,
636 const unsigned int theResolution,
637 const TCollection_AsciiString theKey)
639 Handle(OpenGl_Font) aFont;
642 return aFont; // invalid parameters
645 if (!theCtx->GetResource (theKey, aFont))
647 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
648 const Handle(TCollection_HAsciiString) aFontName = new TCollection_HAsciiString (theAspect.Aspect()->Font());
649 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
650 ? theAspect.Aspect()->GetTextFontAspect()
652 Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect, theHeight);
653 Handle(Font_FTFont) aFontFt;
654 if (!aRequestedFont.IsNull())
656 aFontFt = new Font_FTFont (NULL);
658 if (aFontFt->Init (aRequestedFont->FontPath()->ToCString(), theHeight, theResolution))
660 aFont = new OpenGl_Font (aFontFt, theKey);
661 if (!aFont->Init (theCtx))
663 TCollection_ExtendedString aMsg;
665 aMsg += theAspect.Aspect()->Font();
666 aMsg += "' - initialization of GL resources has failed!";
667 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
669 aFont->Release (theCtx.operator->());
670 aFont = new OpenGl_Font (aFontFt, theKey);
675 TCollection_ExtendedString aMsg;
677 aMsg += theAspect.Aspect()->Font();
678 aMsg += "' is broken or has incompatible format! File path: ";
679 aMsg += aRequestedFont->FontPath()->ToCString();
680 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
682 aFont = new OpenGl_Font (aFontFt, theKey);
687 TCollection_ExtendedString aMsg;
689 aMsg += theAspect.Aspect()->Font();
690 aMsg += "' is not found in the system!";
691 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
692 aFont = new OpenGl_Font (aFontFt, theKey);
695 theCtx->ShareResource (theKey, aFont);
700 // =======================================================================
703 // =======================================================================
704 void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
705 const OpenGl_AspectText& theTextAspect,
706 const OpenGl_Vec4& theColorText,
707 const OpenGl_Vec4& theColorSubs,
708 const unsigned int theResolution) const
710 if (myString.IsEmpty())
715 // Note that using difference resolution in different Views in same Viewer
716 // will lead to performance regression (for example, text will be recreated every time).
717 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
719 && !myFont->ResourceKey().IsEqual (aFontKey))
722 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
727 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
729 if (!myFont->WasInitialized())
734 if (myTextures.IsEmpty())
736 Font_TextFormatter aFormatter;
737 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
740 aFormatter.Append (myString, *myFont->FTFont().operator->());
743 OpenGl_TextBuilder aBuilder;
744 aBuilder.Perform (aFormatter,
746 *myFont.operator->(),
751 aFormatter.BndBox (myBndBox);
754 if (myTextures.IsEmpty())
759 myExportHeight = 1.0f;
760 myScaleHeight = 1.0f;
762 if (myHasPlane && !myHasAnchorPoint)
764 OpenGl_Mat4d aWorldViewMat;
765 aWorldViewMat.Convert (theCtx->WorldViewState.Current());
766 theCtx->WorldViewState.Push();
767 theCtx->WorldViewState.SetCurrent<Standard_Real> (aWorldViewMat);
768 theCtx->ApplyWorldViewMatrix();
772 theCtx->WorldViewState.Push();
775 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
779 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(),
789 // compute scale factor for constant text height
791 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
794 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
802 const GLdouble h = (GLdouble )myFont->FTFont()->PointSize();
803 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX,
806 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
813 myScaleHeight = (y2 - y1) / h;
814 if (theTextAspect.Aspect()->GetTextZoomable())
816 myExportHeight = (float )h;
819 myExportHeight = (float )myFont->FTFont()->PointSize() / myExportHeight;
821 #if !defined(GL_ES_VERSION_2_0)
822 if (theCtx->core11 != NULL)
824 glDisable (GL_LIGHTING);
830 || theTextAspect.Aspect()->Style() == Aspect_TOST_ANNOTATION)
832 glDisable (GL_DEPTH_TEST);
835 if (theCtx->core15fwd != NULL)
837 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
839 #if !defined(GL_ES_VERSION_2_0)
840 // activate texture unit
841 GLint aTexEnvParam = GL_REPLACE;
842 if (theCtx->core11 != NULL)
845 glAlphaFunc (GL_GEQUAL, 0.285f);
846 glEnable (GL_ALPHA_TEST);
848 glDisable (GL_TEXTURE_1D);
849 glEnable (GL_TEXTURE_2D);
850 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
851 if (aTexEnvParam != GL_REPLACE)
853 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
860 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
863 switch (theTextAspect.Aspect()->DisplayType())
865 case Aspect_TODT_BLEND:
867 #if !defined(GL_ES_VERSION_2_0)
868 glEnable (GL_COLOR_LOGIC_OP);
873 case Aspect_TODT_SUBTITLE:
875 #if !defined(GL_ES_VERSION_2_0)
876 if (theCtx->core11 != NULL)
878 theCtx->SetColor4fv (theColorSubs);
879 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
881 glBindTexture (GL_TEXTURE_2D, 0);
883 glVertex2f (myBndBox.Left, myBndBox.Top);
884 glVertex2f (myBndBox.Right, myBndBox.Top);
885 glVertex2f (myBndBox.Right, myBndBox.Bottom);
886 glVertex2f (myBndBox.Left, myBndBox.Bottom);
892 case Aspect_TODT_DEKALE:
894 theCtx->SetColor4fv (theColorSubs);
895 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.00001f));
896 drawText (theCtx, theTextAspect);
897 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.00001f));
898 drawText (theCtx, theTextAspect);
899 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.00001f));
900 drawText (theCtx, theTextAspect);
901 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.00001f));
902 drawText (theCtx, theTextAspect);
905 case Aspect_TODT_DIMENSION:
906 case Aspect_TODT_NORMAL:
913 theCtx->SetColor4fv (theColorText);
914 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
915 drawText (theCtx, theTextAspect);
919 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
920 theCtx->ApplyProjectionMatrix();
923 #if !defined(GL_ES_VERSION_2_0)
924 if (theCtx->core11 != NULL)
926 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
930 if (theTextAspect.Aspect()->DisplayType() == Aspect_TODT_DIMENSION)
932 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.00001f));
934 glDisable (GL_BLEND);
937 glDisable (GL_DEPTH_TEST);
939 #if !defined(GL_ES_VERSION_2_0)
940 if (theCtx->core11 != NULL)
942 glDisable (GL_TEXTURE_2D);
943 glDisable (GL_ALPHA_TEST);
946 glColorMask (GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
948 glClear (GL_STENCIL_BUFFER_BIT);
949 glEnable (GL_STENCIL_TEST);
950 glStencilFunc (GL_ALWAYS, 1, 0xFF);
951 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
953 #if !defined(GL_ES_VERSION_2_0)
954 if (theCtx->core11 != NULL)
957 glVertex2f (myBndBox.Left, myBndBox.Top);
958 glVertex2f (myBndBox.Right, myBndBox.Top);
959 glVertex2f (myBndBox.Right, myBndBox.Bottom);
960 glVertex2f (myBndBox.Left, myBndBox.Bottom);
965 glStencilFunc (GL_ALWAYS, 0, 0xFF);
967 glColorMask (GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
970 // reset OpenGL state
971 glDisable (GL_BLEND);
972 glDisable (GL_STENCIL_TEST);
973 #if !defined(GL_ES_VERSION_2_0)
974 if (theCtx->core11 != NULL)
976 glDisable (GL_ALPHA_TEST);
978 glDisable (GL_COLOR_LOGIC_OP);
981 // model view matrix was modified
982 theCtx->WorldViewState.Pop();
983 theCtx->ApplyModelViewMatrix();