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>
34 static const GLdouble THE_IDENTITY_MATRIX[16] =
42 //! Auxiliary tool for setting polygon offset temporarily.
43 struct BackPolygonOffsetSentry
45 BackPolygonOffsetSentry (const Handle(OpenGl_Context)& theCtx)
47 myOffsetBack (!theCtx.IsNull() ? theCtx->PolygonOffset() : Graphic3d_PolygonOffset())
51 Graphic3d_PolygonOffset aPolyOffset = myOffsetBack;
52 aPolyOffset.Mode = Aspect_POM_Fill;
53 aPolyOffset.Units += 1.0f;
54 theCtx->SetPolygonOffset (aPolyOffset);
58 ~BackPolygonOffsetSentry()
62 myCtx->SetPolygonOffset (myOffsetBack);
67 BackPolygonOffsetSentry (const BackPolygonOffsetSentry& );
68 BackPolygonOffsetSentry& operator= (const BackPolygonOffsetSentry& );
70 const Handle(OpenGl_Context)& myCtx;
71 const Graphic3d_PolygonOffset myOffsetBack;
74 } // anonymous namespace
76 // =======================================================================
77 // function : OpenGl_Text
79 // =======================================================================
80 OpenGl_Text::OpenGl_Text()
85 myPoint (0.0f, 0.0f, 0.0f),
88 myHasAnchorPoint (true)
91 myParams.HAlign = Graphic3d_HTA_LEFT;
92 myParams.VAlign = Graphic3d_VTA_BOTTOM;
95 // =======================================================================
96 // function : OpenGl_Text
98 // =======================================================================
99 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
100 const OpenGl_Vec3& thePoint,
101 const OpenGl_TextParam& theParams)
105 myScaleHeight (1.0f),
106 myExportHeight (1.0f),
107 myParams (theParams),
112 myHasAnchorPoint (true)
117 // =======================================================================
118 // function : OpenGl_Text
120 // =======================================================================
121 OpenGl_Text::OpenGl_Text (const Standard_Utf8Char* theText,
122 const gp_Ax2& theOrientation,
123 const OpenGl_TextParam& theParams,
124 const bool theHasOwnAnchor)
129 myExportHeight (1.0),
130 myParams (theParams),
133 myOrientation (theOrientation),
135 myHasAnchorPoint (theHasOwnAnchor)
137 const gp_Pnt& aPoint = theOrientation.Location();
138 myPoint = OpenGl_Vec3 (static_cast<Standard_ShortReal> (aPoint.X()),
139 static_cast<Standard_ShortReal> (aPoint.Y()),
140 static_cast<Standard_ShortReal> (aPoint.Z()));
143 // =======================================================================
144 // function : SetPosition
146 // =======================================================================
147 void OpenGl_Text::SetPosition (const OpenGl_Vec3& thePoint)
152 // =======================================================================
153 // function : SetFontSize
155 // =======================================================================
156 void OpenGl_Text::SetFontSize (const Handle(OpenGl_Context)& theCtx,
157 const Standard_Integer theFontSize)
159 if (myParams.Height != theFontSize)
161 Release (theCtx.operator->());
163 myParams.Height = theFontSize;
166 // =======================================================================
169 // =======================================================================
170 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
171 const Standard_Utf8Char* theText,
172 const OpenGl_Vec3& thePoint)
174 releaseVbos (theCtx.operator->());
177 myString.FromUnicode (theText);
180 // =======================================================================
183 // =======================================================================
184 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
185 const Standard_Utf8Char* theText,
186 const OpenGl_Vec3& thePoint,
187 const OpenGl_TextParam& theParams)
189 if (myParams.Height != theParams.Height)
191 Release (theCtx.operator->());
195 releaseVbos (theCtx.operator->());
198 myParams = theParams;
200 myString.FromUnicode (theText);
203 // =======================================================================
206 // =======================================================================
207 void OpenGl_Text::Init (const Handle(OpenGl_Context)& theCtx,
208 const TCollection_ExtendedString& theText,
209 const OpenGl_Vec2& thePoint,
210 const OpenGl_TextParam& theParams)
212 if (myParams.Height != theParams.Height)
214 Release (theCtx.operator->());
218 releaseVbos (theCtx.operator->());
221 myParams = theParams;
222 myPoint.SetValues (thePoint, 0.0f);
223 myString.FromUnicode (theText.ToExtString());
226 // =======================================================================
227 // function : ~OpenGl_Text
229 // =======================================================================
230 OpenGl_Text::~OpenGl_Text()
235 // =======================================================================
236 // function : releaseVbos
238 // =======================================================================
239 void OpenGl_Text::releaseVbos (OpenGl_Context* theCtx)
241 for (Standard_Integer anIter = 0; anIter < myVertsVbo.Length(); ++anIter)
243 Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.ChangeValue (anIter);
244 Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.ChangeValue (anIter);
248 theCtx->DelayedRelease (aVerts);
249 theCtx->DelayedRelease (aTCrds);
255 && !myBndVertsVbo.IsNull())
257 theCtx->DelayedRelease (myBndVertsVbo);
263 myBndVertsVbo.Nullify();
266 // =======================================================================
267 // function : Release
269 // =======================================================================
270 void OpenGl_Text::Release (OpenGl_Context* theCtx)
272 releaseVbos (theCtx);
273 if (!myFont.IsNull())
275 const TCollection_AsciiString aKey = myFont->ResourceKey();
279 theCtx->ReleaseResource (aKey, Standard_True);
284 // =======================================================================
285 // function : StringSize
287 // =======================================================================
288 void OpenGl_Text::StringSize (const Handle(OpenGl_Context)& theCtx,
289 const NCollection_String& theText,
290 const OpenGl_AspectText& theTextAspect,
291 const OpenGl_TextParam& theParams,
292 const unsigned int theResolution,
293 Standard_ShortReal& theWidth,
294 Standard_ShortReal& theAscent,
295 Standard_ShortReal& theDescent)
300 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, theParams.Height, theResolution);
301 Handle(OpenGl_Font) aFont = FindFont (theCtx, theTextAspect, theParams.Height, theResolution, aFontKey);
302 if (aFont.IsNull() || !aFont->IsValid())
307 theAscent = aFont->Ascender();
308 theDescent = aFont->Descender();
310 GLfloat aWidth = 0.0f;
311 for (NCollection_Utf8Iter anIter = theText.Iterator(); *anIter != 0;)
313 const Standard_Utf32Char aCharThis = *anIter;
314 const Standard_Utf32Char aCharNext = *++anIter;
316 if (aCharThis == '\x0D' // CR (carriage return)
317 || aCharThis == '\a' // BEL (alarm)
318 || aCharThis == '\f' // FF (form feed) NP (new page)
319 || aCharThis == '\b' // BS (backspace)
320 || aCharThis == '\v') // VT (vertical tab)
322 continue; // skip unsupported carriage control codes
324 else if (aCharThis == '\x0A') // LF (line feed, new line)
326 theWidth = Max (theWidth, aWidth);
330 else if (aCharThis == ' ')
332 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
335 else if (aCharThis == '\t')
337 aWidth += aFont->FTFont()->AdvanceX (' ', aCharNext) * 8.0f;
341 aWidth += aFont->FTFont()->AdvanceX (aCharThis, aCharNext);
343 theWidth = Max (theWidth, aWidth);
345 Handle(OpenGl_Context) aCtx = theCtx;
347 aCtx->ReleaseResource (aFontKey, Standard_True);
350 // =======================================================================
353 // =======================================================================
354 void OpenGl_Text::Render (const Handle(OpenGl_Workspace)& theWorkspace) const
356 theWorkspace->SetAspectFace (&theWorkspace->FontFaceAspect());
357 theWorkspace->ApplyAspectFace();
358 const OpenGl_AspectText* aTextAspect = theWorkspace->ApplyAspectText();
359 const Handle(OpenGl_Context)& aCtx = theWorkspace->GetGlContext();
360 const Handle(OpenGl_TextureSet) aPrevTexture = aCtx->BindTextures (Handle(OpenGl_TextureSet)());
362 // Bind custom shader program or generate default version
363 aCtx->ShaderManager()->BindFontProgram (aTextAspect->ShaderProgramRes (aCtx));
365 myOrientationMatrix = theWorkspace->View()->Camera()->OrientationMatrix();
366 myProjMatrix.Convert (aCtx->ProjectionState.Current());
368 // use highlight color or colors from aspect
371 theWorkspace->TextColor(),
372 theWorkspace->TextSubtitleColor(),
376 if (!aPrevTexture.IsNull())
378 aCtx->BindTextures (aPrevTexture);
381 // restore Z buffer settings
382 if (theWorkspace->UseZBuffer())
384 glEnable (GL_DEPTH_TEST);
388 // =======================================================================
391 // =======================================================================
392 void OpenGl_Text::Render (const Handle(OpenGl_Context)& theCtx,
393 const OpenGl_AspectText& theTextAspect,
394 const unsigned int theResolution) const
396 const bool anAlphaToCoverageOld = theCtx->SetSampleAlphaToCoverage (false);
397 #if !defined(GL_ES_VERSION_2_0)
398 const Standard_Integer aPrevPolygonMode = theCtx->SetPolygonMode (GL_FILL);
399 const bool aPrevHatchingMode = theCtx->SetPolygonHatchEnabled (false);
402 render (theCtx, theTextAspect,
403 theTextAspect.Aspect()->ColorRGBA(),
404 theTextAspect.Aspect()->ColorSubTitleRGBA(),
407 #if !defined(GL_ES_VERSION_2_0)
408 theCtx->SetPolygonMode (aPrevPolygonMode);
409 theCtx->SetPolygonHatchEnabled (aPrevHatchingMode);
411 theCtx->SetSampleAlphaToCoverage (anAlphaToCoverageOld);
414 // =======================================================================
415 // function : setupMatrix
417 // =======================================================================
418 void OpenGl_Text::setupMatrix (const Handle(OpenGl_Context)& theCtx,
419 const OpenGl_AspectText& theTextAspect,
420 const OpenGl_Vec3 theDVec) const
422 OpenGl_Mat4d aModViewMat;
423 OpenGl_Mat4d aProjectMat;
424 if (myHasPlane && myHasAnchorPoint)
426 aProjectMat = myProjMatrix * myOrientationMatrix;
430 aProjectMat = myProjMatrix;
435 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, myPoint.x() + theDVec.x(), myPoint.y() + theDVec.y(), 0.f);
436 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, 1.f, -1.f, 1.f);
437 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.f, 0.f, 1.f);
441 // align coordinates to the nearest integer
442 // to avoid extra interpolation issues
443 GLdouble anObjX, anObjY, anObjZ;
444 Graphic3d_TransformUtils::UnProject<Standard_Real> (std::floor (myWinX + theDVec.x()),
445 std::floor (myWinY + theDVec.y()),
446 myWinZ + theDVec.z(),
447 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX),
448 OpenGl_Mat4d::Map (aProjectMat),
456 const gp_Dir& aVectorDir = myOrientation.XDirection();
457 const gp_Dir& aVectorUp = myOrientation.Direction();
458 const gp_Dir& aVectorRight = myOrientation.YDirection();
460 aModViewMat.SetColumn (2, OpenGl_Vec3d (aVectorUp.X(), aVectorUp.Y(), aVectorUp.Z()));
461 aModViewMat.SetColumn (1, OpenGl_Vec3d (aVectorRight.X(), aVectorRight.Y(), aVectorRight.Z()));
462 aModViewMat.SetColumn (0, OpenGl_Vec3d (aVectorDir.X(), aVectorDir.Y(), aVectorDir.Z()));
464 if (!myHasAnchorPoint)
466 OpenGl_Mat4d aPosMat;
467 aPosMat.SetColumn (3, OpenGl_Vec3d (myPoint.x(), myPoint.y(), myPoint.z()));
468 aPosMat *= aModViewMat;
469 aModViewMat.SetColumn (3, aPosMat.GetColumn (3));
473 aModViewMat.SetColumn (3, OpenGl_Vec3d (anObjX, anObjY, anObjZ));
478 Graphic3d_TransformUtils::Translate<GLdouble> (aModViewMat, anObjX, anObjY, anObjZ);
479 Graphic3d_TransformUtils::Rotate<GLdouble> (aModViewMat, theTextAspect.Aspect()->GetTextAngle(), 0.0, 0.0, 1.0);
482 if (!theTextAspect.Aspect()->GetTextZoomable())
484 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, myScaleHeight, myScaleHeight, myScaleHeight);
486 else if (theCtx->HasRenderScale())
488 Graphic3d_TransformUtils::Scale<GLdouble> (aModViewMat, theCtx->RenderScaleInv(), theCtx->RenderScaleInv(), theCtx->RenderScaleInv());
492 if (myHasPlane && !myHasAnchorPoint)
494 OpenGl_Mat4d aCurrentWorldViewMat;
495 aCurrentWorldViewMat.Convert (theCtx->WorldViewState.Current());
496 theCtx->WorldViewState.SetCurrent<Standard_Real> (aCurrentWorldViewMat * aModViewMat);
500 theCtx->WorldViewState.SetCurrent<Standard_Real> (aModViewMat);
502 theCtx->ApplyWorldViewMatrix();
506 theCtx->ProjectionState.SetCurrent<Standard_Real> (aProjectMat);
507 theCtx->ApplyProjectionMatrix();
510 // Upload updated state to shader program
511 theCtx->ShaderManager()->PushState (theCtx->ActiveProgram());
514 // =======================================================================
515 // function : drawText
517 // =======================================================================
518 void OpenGl_Text::drawText (const Handle(OpenGl_Context)& theCtx,
519 const OpenGl_AspectText& theTextAspect) const
521 (void )theTextAspect;
522 if (myVertsVbo.Length() != myTextures.Length()
523 || myTextures.IsEmpty())
528 for (Standard_Integer anIter = 0; anIter < myTextures.Length(); ++anIter)
530 const GLuint aTexId = myTextures.Value (anIter);
531 glBindTexture (GL_TEXTURE_2D, aTexId);
533 const Handle(OpenGl_VertexBuffer)& aVerts = myVertsVbo.Value (anIter);
534 const Handle(OpenGl_VertexBuffer)& aTCrds = myTCrdsVbo.Value (anIter);
535 aVerts->BindAttribute (theCtx, Graphic3d_TOA_POS);
536 aTCrds->BindAttribute (theCtx, Graphic3d_TOA_UV);
538 glDrawArrays (GL_TRIANGLES, 0, GLsizei(aVerts->GetElemsNb()));
540 aTCrds->UnbindAttribute (theCtx, Graphic3d_TOA_UV);
541 aVerts->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
543 glBindTexture (GL_TEXTURE_2D, 0);
546 // =======================================================================
547 // function : FontKey
549 // =======================================================================
550 TCollection_AsciiString OpenGl_Text::FontKey (const OpenGl_AspectText& theAspect,
551 const Standard_Integer theHeight,
552 const unsigned int theResolution)
554 const Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
555 ? theAspect.Aspect()->GetTextFontAspect()
557 return theAspect.Aspect()->Font()
558 + TCollection_AsciiString(":") + Standard_Integer(anAspect)
559 + TCollection_AsciiString(":") + Standard_Integer(theResolution)
560 + TCollection_AsciiString(":") + theHeight;
563 // =======================================================================
564 // function : FindFont
566 // =======================================================================
567 Handle(OpenGl_Font) OpenGl_Text::FindFont (const Handle(OpenGl_Context)& theCtx,
568 const OpenGl_AspectText& theAspect,
569 const Standard_Integer theHeight,
570 const unsigned int theResolution,
571 const TCollection_AsciiString theKey)
573 Handle(OpenGl_Font) aFont;
576 return aFont; // invalid parameters
579 if (!theCtx->GetResource (theKey, aFont))
581 Handle(Font_FontMgr) aFontMgr = Font_FontMgr::GetInstance();
582 const TCollection_AsciiString& aFontName = theAspect.Aspect()->Font();
583 Font_FontAspect anAspect = theAspect.Aspect()->GetTextFontAspect() != Font_FA_Undefined
584 ? theAspect.Aspect()->GetTextFontAspect()
586 Handle(Font_FTFont) aFontFt;
587 if (Handle(Font_SystemFont) aRequestedFont = aFontMgr->FindFont (aFontName, anAspect))
589 aFontFt = new Font_FTFont (Handle(Font_FTLibrary)());
591 if (aFontFt->Init (aRequestedFont->FontPathAny (anAspect).ToCString(), theHeight, theResolution))
593 aFont = new OpenGl_Font (aFontFt, theKey);
594 if (!aFont->Init (theCtx))
596 TCollection_ExtendedString aMsg;
598 aMsg += theAspect.Aspect()->Font();
599 aMsg += "' - initialization of GL resources has failed!";
600 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
602 aFont->Release (theCtx.operator->());
603 aFont = new OpenGl_Font (aFontFt, theKey);
608 TCollection_ExtendedString aMsg;
610 aMsg += theAspect.Aspect()->Font();
611 aMsg += "' is broken or has incompatible format! File path: ";
612 aMsg += aRequestedFont->FontPathAny (anAspect);
613 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
615 aFont = new OpenGl_Font (aFontFt, theKey);
620 TCollection_ExtendedString aMsg;
622 aMsg += theAspect.Aspect()->Font();
623 aMsg += "' is not found in the system!";
624 theCtx->PushMessage (GL_DEBUG_SOURCE_APPLICATION, GL_DEBUG_TYPE_ERROR, 0, GL_DEBUG_SEVERITY_HIGH, aMsg);
625 aFont = new OpenGl_Font (aFontFt, theKey);
628 theCtx->ShareResource (theKey, aFont);
633 // =======================================================================
634 // function : drawRect
636 // =======================================================================
637 void OpenGl_Text::drawRect (const Handle(OpenGl_Context)& theCtx,
638 const OpenGl_AspectText& theTextAspect,
639 const OpenGl_Vec4& theColorSubs) const
641 Handle(OpenGl_ShaderProgram) aPrevProgram = theCtx->ActiveProgram();
642 if (myBndVertsVbo.IsNull())
644 OpenGl_Vec2 aQuad[4] =
646 OpenGl_Vec2(myBndBox.Right, myBndBox.Bottom),
647 OpenGl_Vec2(myBndBox.Right, myBndBox.Top),
648 OpenGl_Vec2(myBndBox.Left, myBndBox.Bottom),
649 OpenGl_Vec2(myBndBox.Left, myBndBox.Top)
651 if (theCtx->ToUseVbo())
653 myBndVertsVbo = new OpenGl_VertexBuffer();
657 myBndVertsVbo = new OpenGl_VertexBufferCompat();
659 myBndVertsVbo->Init (theCtx, 2, 4, aQuad[0].GetData());
662 // bind unlit program
663 theCtx->ShaderManager()->BindFaceProgram (Handle(OpenGl_TextureSet)(), Graphic3d_TOSM_UNLIT,
664 Graphic3d_AlphaMode_Opaque, Standard_False, Standard_False,
665 Handle(OpenGl_ShaderProgram)());
667 #if !defined(GL_ES_VERSION_2_0)
668 if (theCtx->core11 != NULL
669 && theCtx->ActiveProgram().IsNull())
671 glBindTexture (GL_TEXTURE_2D, 0);
674 theCtx->SetColor4fv (theColorSubs);
675 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
676 myBndVertsVbo->BindAttribute (theCtx, Graphic3d_TOA_POS);
678 theCtx->core20fwd->glDrawArrays (GL_TRIANGLE_STRIP, 0, 4);
680 myBndVertsVbo->UnbindAttribute (theCtx, Graphic3d_TOA_POS);
681 theCtx->BindProgram (aPrevProgram);
684 // =======================================================================
687 // =======================================================================
688 void OpenGl_Text::render (const Handle(OpenGl_Context)& theCtx,
689 const OpenGl_AspectText& theTextAspect,
690 const OpenGl_Vec4& theColorText,
691 const OpenGl_Vec4& theColorSubs,
692 const unsigned int theResolution) const
694 if (myString.IsEmpty())
699 // Note that using difference resolution in different Views in same Viewer
700 // will lead to performance regression (for example, text will be recreated every time).
701 const TCollection_AsciiString aFontKey = FontKey (theTextAspect, myParams.Height, theResolution);
703 && !myFont->ResourceKey().IsEqual (aFontKey))
706 const_cast<OpenGl_Text* > (this)->Release (theCtx.operator->());
711 myFont = FindFont (theCtx, theTextAspect, myParams.Height, theResolution, aFontKey);
713 if (!myFont->WasInitialized())
718 if (myTextures.IsEmpty())
720 Font_TextFormatter aFormatter;
721 aFormatter.SetupAlignment (myParams.HAlign, myParams.VAlign);
724 aFormatter.Append (myString, *myFont->FTFont().operator->());
727 OpenGl_TextBuilder aBuilder;
728 aBuilder.Perform (aFormatter,
730 *myFont.operator->(),
735 aFormatter.BndBox (myBndBox);
736 if (!myBndVertsVbo.IsNull())
738 myBndVertsVbo->Release (theCtx.get());
739 myBndVertsVbo.Nullify();
743 if (myTextures.IsEmpty())
748 myExportHeight = 1.0f;
749 myScaleHeight = 1.0f;
751 theCtx->WorldViewState.Push();
752 myModelMatrix.Convert (theCtx->WorldViewState.Current() * theCtx->ModelWorldState.Current());
754 const GLdouble aPointSize = (GLdouble )myFont->FTFont()->PointSize();
757 Graphic3d_TransformUtils::Project<Standard_Real> (myPoint.x(), myPoint.y(), myPoint.z(),
758 myModelMatrix, myProjMatrix, theCtx->Viewport(),
759 myWinX, myWinY, myWinZ);
761 // compute scale factor for constant text height
762 if (theTextAspect.Aspect()->GetTextZoomable())
764 myExportHeight = aPointSize;
768 Graphic3d_Vec3d aPnt1, aPnt2;
769 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY, myWinZ,
770 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
771 aPnt1.x(), aPnt1.y(), aPnt1.z());
772 Graphic3d_TransformUtils::UnProject<Standard_Real> (myWinX, myWinY + aPointSize, myWinZ,
773 OpenGl_Mat4d::Map (THE_IDENTITY_MATRIX), myProjMatrix, theCtx->Viewport(),
774 aPnt2.x(), aPnt2.y(), aPnt2.z());
775 myScaleHeight = (aPnt2.y() - aPnt1.y()) / aPointSize;
778 myExportHeight = aPointSize / myExportHeight;
780 #if !defined(GL_ES_VERSION_2_0)
781 if (theCtx->core11 != NULL
782 && theCtx->caps->ffpEnable)
784 glDisable (GL_LIGHTING);
789 const bool hasDepthTest = !myIs2d
790 && theTextAspect.Aspect()->Style() != Aspect_TOST_ANNOTATION;
793 glDisable (GL_DEPTH_TEST);
796 if (theCtx->core15fwd != NULL)
798 theCtx->core15fwd->glActiveTexture (GL_TEXTURE0);
800 #if !defined(GL_ES_VERSION_2_0)
801 // activate texture unit
802 GLint aTexEnvParam = GL_REPLACE;
803 if (theCtx->core11 != NULL)
805 glDisable (GL_TEXTURE_1D);
806 glEnable (GL_TEXTURE_2D);
807 glGetTexEnviv (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &aTexEnvParam);
808 if (aTexEnvParam != GL_REPLACE)
810 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
817 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
820 switch (theTextAspect.Aspect()->DisplayType())
822 case Aspect_TODT_BLEND:
824 #if !defined(GL_ES_VERSION_2_0)
825 glEnable (GL_COLOR_LOGIC_OP);
830 case Aspect_TODT_SUBTITLE:
832 BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)());
833 drawRect (theCtx, theTextAspect, theColorSubs);
836 case Aspect_TODT_DEKALE:
838 BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)());
839 theCtx->SetColor4fv (theColorSubs);
840 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, +1.0f, 0.0f));
841 drawText (theCtx, theTextAspect);
842 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, -1.0f, 0.0f));
843 drawText (theCtx, theTextAspect);
844 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (-1.0f, +1.0f, 0.0f));
845 drawText (theCtx, theTextAspect);
846 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.0f));
847 drawText (theCtx, theTextAspect);
850 case Aspect_TODT_SHADOW:
852 BackPolygonOffsetSentry aPolygonOffsetTmp (hasDepthTest ? theCtx : Handle(OpenGl_Context)());
853 theCtx->SetColor4fv (theColorSubs);
854 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (+1.0f, -1.0f, 0.0f));
855 drawText (theCtx, theTextAspect);
858 case Aspect_TODT_DIMENSION:
859 case Aspect_TODT_NORMAL:
866 theCtx->SetColor4fv (theColorText);
867 setupMatrix (theCtx, theTextAspect, OpenGl_Vec3 (0.0f, 0.0f, 0.0f));
868 drawText (theCtx, theTextAspect);
872 theCtx->ProjectionState.SetCurrent<Standard_Real> (myProjMatrix);
873 theCtx->ApplyProjectionMatrix();
876 #if !defined(GL_ES_VERSION_2_0)
877 if (theCtx->core11 != NULL)
879 glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, aTexEnvParam);
883 if (theTextAspect.Aspect()->DisplayType() == Aspect_TODT_DIMENSION)
885 glDisable (GL_BLEND);
888 glDisable (GL_DEPTH_TEST);
890 #if !defined(GL_ES_VERSION_2_0)
891 if (theCtx->core11 != NULL)
893 glDisable (GL_TEXTURE_2D);
896 const bool aColorMaskBack = theCtx->SetColorMask (false);
898 glClear (GL_STENCIL_BUFFER_BIT);
899 glEnable (GL_STENCIL_TEST);
900 glStencilFunc (GL_ALWAYS, 1, 0xFF);
901 glStencilOp (GL_KEEP, GL_KEEP, GL_REPLACE);
903 drawRect (theCtx, theTextAspect, OpenGl_Vec4 (1.0f, 1.0f, 1.0f, 1.0f));
905 glStencilFunc (GL_ALWAYS, 0, 0xFF);
907 theCtx->SetColorMask (aColorMaskBack);
910 // reset OpenGL state
911 glDisable (GL_BLEND);
912 glDisable (GL_STENCIL_TEST);
913 #if !defined(GL_ES_VERSION_2_0)
914 glDisable (GL_COLOR_LOGIC_OP);
917 // model view matrix was modified
918 theCtx->WorldViewState.Pop();
919 theCtx->ApplyModelViewMatrix();