1 // Created on: 2011-10-20
2 // Created by: Sergey ZERCHANINOV
3 // Copyright (c) 2011-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
21 #include <OpenGl_GlCore11.hxx>
23 #include <OpenGl_GraphicDriver.hxx>
25 #include <OSD_FontAspect.hxx>
27 #include <OpenGl_Display.hxx>
28 #include <OpenGl_AspectText.hxx>
29 #include <OpenGl_TextParam.hxx>
33 /*----------------------------------------------------------------------*/
35 struct OpenGl_LAYER_PROP
45 Standard_Boolean FontChanged;
47 OpenGl_AspectText AspectText;
48 OpenGl_TextParam TextParam;
51 /*----------------------------------------------------------------------*/
53 static const TEL_COLOUR myDefaultColor = {{ 1.F, 1.F, 1.F, 1.F }};
54 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
61 { 1.F, 1.F, 1.F }, //Color
62 (int)Aspect_TOST_NORMAL, //Style
63 (int)Aspect_TODT_NORMAL, //DisplayType
64 { 1.F, 1.F, 1.F }, //ColorSubTitle
67 (int)OSD_FA_Regular //TextFontAspect
70 static Standard_Boolean TheLayerIsOpen = Standard_False;
71 static OpenGl_LAYER_PROP TheLayerProp;
73 /*----------------------------------------------------------------------*/
75 void InitLayerProp (const int AListId)
77 TheLayerProp.ListId = AListId;
81 TheLayerProp.Color = myDefaultColor;
82 TheLayerProp.NbPoints = 0;
83 TheLayerProp.LineType = -1;
84 TheLayerProp.LineWidth = -1.F;
85 TheLayerProp.FontCurrent = 0;
87 TheLayerProp.FontChanged = Standard_False;
89 TheLayerProp.AspectText.SetContext(myDefaultContextText);
91 TheLayerProp.TextParam.Height = -1;
92 TheLayerProp.TextParam.HAlign = Graphic3d_HTA_LEFT;
93 TheLayerProp.TextParam.VAlign = Graphic3d_VTA_BOTTOM;
97 /*----------------------------------------------------------------------*/
99 void OpenGl_GraphicDriver::Layer (Aspect_CLayer2d& ACLayer)
101 ACLayer.ptrLayer = new CALL_DEF_PTRLAYER();
102 ACLayer.ptrLayer->listIndex = glGenLists(1);
105 /*----------------------------------------------------------------------*/
107 void OpenGl_GraphicDriver::RemoveLayer (const Aspect_CLayer2d& ACLayer)
109 if (!ACLayer.ptrLayer) return;
110 if (!ACLayer.ptrLayer->listIndex) return;
111 if (TheLayerProp.ListId == ACLayer.ptrLayer->listIndex)
113 glDeleteLists (ACLayer.ptrLayer->listIndex, 1);
114 ACLayer.ptrLayer->listIndex = 0;
115 //szvgl: memory leak here?
116 //free ( ACLayer.ptrLayer );
117 //ACLayer.ptrLayer = NULL;
120 /*----------------------------------------------------------------------*/
122 void OpenGl_GraphicDriver::BeginLayer (const Aspect_CLayer2d& ACLayer)
124 call_def_ptrLayer ptrLayer = (call_def_ptrLayer) ACLayer.ptrLayer;
125 if (!ptrLayer) return;
127 InitLayerProp(ptrLayer->listIndex);
128 if (!TheLayerProp.ListId) return;
130 glNewList (TheLayerProp.ListId, GL_COMPILE);
131 TheLayerIsOpen = Standard_True;
134 void OpenGl_GraphicDriver::BeginPolygon2d ()
136 if (!TheLayerProp.ListId) return;
137 TheLayerProp.NbPoints = 0;
138 glBegin (GL_POLYGON);
141 void OpenGl_GraphicDriver::BeginPolyline2d ()
143 if (!TheLayerProp.ListId) return;
144 TheLayerProp.NbPoints = 0;
145 glBegin (GL_LINE_STRIP);
148 void OpenGl_GraphicDriver::ClearLayer (const Aspect_CLayer2d& ACLayer)
150 if (!ACLayer.ptrLayer) return;
152 InitLayerProp(ACLayer.ptrLayer->listIndex);
153 if (!TheLayerProp.ListId) return;
155 glNewList (TheLayerProp.ListId, GL_COMPILE);
159 void OpenGl_GraphicDriver::Draw (const Standard_ShortReal X, const Standard_ShortReal Y)
161 if (!TheLayerProp.ListId) return;
162 TheLayerProp.NbPoints++;
163 glVertex3f (X, Y, 0.F);
166 void OpenGl_GraphicDriver::Edge (const Standard_ShortReal X, const Standard_ShortReal Y)
168 if (!TheLayerProp.ListId) return;
169 TheLayerProp.NbPoints++;
170 glVertex3f (X, Y, 0.F);
173 void OpenGl_GraphicDriver::EndLayer ()
175 if (!TheLayerProp.ListId) return;
179 TheLayerIsOpen = Standard_False;
181 TheLayerProp.ListId = 0;
184 void OpenGl_GraphicDriver::EndPolygon2d ()
186 if (!TheLayerProp.ListId) return;
190 void OpenGl_GraphicDriver::EndPolyline2d ()
192 if (!TheLayerProp.ListId) return;
196 void OpenGl_GraphicDriver::Move (const Standard_ShortReal X, const Standard_ShortReal Y)
198 if (!TheLayerProp.ListId) return;
199 if (TheLayerProp.NbPoints)
202 TheLayerProp.NbPoints = 0;
203 glBegin (GL_LINE_STRIP);
205 TheLayerProp.NbPoints++;
206 glVertex3f (X, Y, 0.F);
209 void OpenGl_GraphicDriver::Rectangle (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Width, const Standard_ShortReal Height)
211 if (!TheLayerProp.ListId) return;
212 glRectf (X, Y, X + Width, Y + Height);
215 void OpenGl_GraphicDriver::SetColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
217 if (!TheLayerProp.ListId) return;
218 TheLayerProp.Color.rgb[0] = R;
219 TheLayerProp.Color.rgb[1] = G;
220 TheLayerProp.Color.rgb[2] = B;
221 glColor3fv (TheLayerProp.Color.rgb);
224 void OpenGl_GraphicDriver::SetTransparency (const Standard_ShortReal ATransparency)
226 if (!TheLayerProp.ListId) return;
227 TheLayerProp.Color.rgb[3] = ATransparency;
229 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
230 glColor4fv (TheLayerProp.Color.rgb);
233 void OpenGl_GraphicDriver::UnsetTransparency ()
235 if (!TheLayerProp.ListId) return;
236 TheLayerProp.Color.rgb[3] = 1.F;
237 glDisable (GL_BLEND);
240 void OpenGl_GraphicDriver::SetLineAttributes (const Standard_Integer Type, const Standard_ShortReal Width)
242 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
244 if (TheLayerProp.LineType != Type)
246 TheLayerProp.LineType = Type;
247 openglDisplay->SetTypeOfLine((Aspect_TypeOfLine) Type);
249 if (TheLayerProp.LineWidth != Width)
251 TheLayerProp.LineWidth = Width;
252 glLineWidth ((GLfloat) Width);
256 void OpenGl_GraphicDriver::SetTextAttributes (const Standard_CString Font, const Standard_Integer AType, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
258 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
260 // get current subtitle text color
261 const TEL_COLOUR &aSubColor = TheLayerProp.AspectText.SubtitleColor ();
263 // update if there are any modifications
264 if (strcmp (TheLayerProp.AspectText.Font(), Font) != 0 ||
265 (int)TheLayerProp.AspectText.DisplayType() != AType ||
266 aSubColor.rgb[0] != (float)R ||
267 aSubColor.rgb[1] != (float)G ||
268 aSubColor.rgb[2] != (float)B)
270 CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
272 aContextText.Font = Font;
273 aContextText.DisplayType = AType;
274 aContextText.ColorSubTitle.r = R;
275 aContextText.ColorSubTitle.g = G;
276 aContextText.ColorSubTitle.b = B;
277 TheLayerProp.AspectText.SetContext(aContextText);
278 TheLayerProp.FontChanged = Standard_True;
282 void OpenGl_GraphicDriver::Text (const Standard_CString AText, const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal AHeight)
284 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
286 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
288 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
290 TheLayerProp.TextParam.Height = (int )height;
291 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
292 TheLayerProp.FontChanged = Standard_False;
295 TCollection_ExtendedString aExtStr(AText);
296 const Techar *aTChStr = (const Techar *)aExtStr.ToExtString();
298 //szv: conversion of Techar to wchar_t
299 wchar_t *aWChStr = (wchar_t*)aTChStr;
300 if (sizeof(Techar) != sizeof(wchar_t))
302 Tint i = 0; while (aTChStr[i++]);
303 aWChStr = new wchar_t[i];
304 i = 0; while (aWChStr[i++] = (wchar_t)(*aTChStr++));
307 const Aspect_TypeOfDisplayText aDispType =
308 TheLayerProp.AspectText.DisplayType();
310 // display type of text
311 if (aDispType != Aspect_TODT_NORMAL)
316 case Aspect_TODT_BLEND:
318 glEnable(GL_COLOR_LOGIC_OP);
324 case Aspect_TODT_SUBTITLE:
327 GLdouble aModelMatrix[16], aProjMatrix[16];
328 glGetIntegerv (GL_VIEWPORT, aViewport);
329 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
330 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
332 int aWidth, anAscent, aDescent;
333 openglDisplay->StringSize(aWChStr, aWidth, anAscent, aDescent);
335 GLdouble aWinX, aWinY, aWinZ;
336 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
337 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
339 // project coordinates
344 // left bottom corner
345 gluUnProject (aWinX, aWinY + aDescent, aWinZ, aModelMatrix,
346 aProjMatrix, aViewport, &aCoordX[0], &aCoordY[0], &aCoordZ[0]);
348 // right bottom corner
349 gluUnProject (aWinX + aWidth, aWinY + aDescent, aWinZ, aModelMatrix,
350 aProjMatrix, aViewport, &aCoordX[1], &aCoordY[1], &aCoordZ[1]);
353 gluUnProject (aWinX + aWidth, aWinY + anAscent, aWinZ, aModelMatrix,
354 aProjMatrix, aViewport, &aCoordX[2], &aCoordY[2], &aCoordZ[2]);
357 gluUnProject (aWinX, aWinY + anAscent, aWinZ, aModelMatrix,
358 aProjMatrix, aViewport, &aCoordX[3], &aCoordY[3], &aCoordZ[3]);
360 // draw colored plane and reset the color
361 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
363 glVertex3d(aCoordX[0], aCoordY[0], aCoordZ[0]);
364 glVertex3d(aCoordX[1], aCoordY[1], aCoordZ[1]);
365 glVertex3d(aCoordX[2], aCoordY[2], aCoordZ[2]);
366 glVertex3d(aCoordX[3], aCoordY[3], aCoordZ[3]);
368 glColor3fv (TheLayerProp.Color.rgb);
372 case Aspect_TODT_DEKALE:
375 GLdouble aModelMatrix[16], aProjMatrix[16];
376 glGetIntegerv (GL_VIEWPORT, aViewport);
377 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
378 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
380 GLdouble aWinX, aWinY, aWinZ;
381 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
382 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
384 GLdouble aProjX, aProjY, aProjZ;
386 gluUnProject (aWinX + 1, aWinY + 1, aWinZ, aModelMatrix,
387 aProjMatrix, aViewport, &aProjX, &aProjY, &aProjZ);
390 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
391 openglDisplay->RenderText (aWChStr, 1, (float)aProjX, (float)aProjY,
392 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
394 gluUnProject (aWinX, aWinY, aWinZ, aModelMatrix, aProjMatrix,
395 aViewport, &aProjX, &aProjY, &aProjZ);
397 gluUnProject (aWinX - 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
398 aViewport, &aProjX, &aProjY, &aProjZ);
400 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
401 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
403 gluUnProject (aWinX - 1, aWinY + 1, aWinZ, aModelMatrix, aProjMatrix,
404 aViewport, &aProjX, &aProjY, &aProjZ);
406 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
407 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
409 gluUnProject (aWinX + 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
410 aViewport, &aProjX, &aProjY, &aProjZ);
412 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
413 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
414 glColor3fv (TheLayerProp.Color.rgb);
420 openglDisplay->RenderText(aWChStr, 1, (float)X, (float)Y, 0.F,
421 &TheLayerProp.AspectText, &TheLayerProp.TextParam);
423 if (aDispType == Aspect_TODT_BLEND)
424 glDisable(GL_COLOR_LOGIC_OP);
426 //szv: delete temporary wide string
427 if (sizeof(Techar) != sizeof(wchar_t))
431 void OpenGl_GraphicDriver::TextSize (const Standard_CString AText, const Standard_ShortReal AHeight, Standard_ShortReal& AWidth, Standard_ShortReal& AnAscent, Standard_ShortReal& ADescent) const
433 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
435 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
437 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
439 TheLayerProp.TextParam.Height = (int )height;
440 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
441 TheLayerProp.FontChanged = Standard_False;
444 TCollection_ExtendedString estr(AText);
445 const Techar *s = (const Techar *)estr.ToExtString();
447 //szv: conversion of Techar to wchar_t
448 wchar_t *s1 = (wchar_t*)s;
449 if (sizeof(Techar) != sizeof(wchar_t))
451 Tint i = 0; while (s[i++]);
453 i = 0; while (s1[i++] = (wchar_t)(*s++));
456 int aWidth = 0, anAscent = 0, aDescent = 0;
457 openglDisplay->StringSize(s1, aWidth, anAscent, aDescent);
459 //szv: delete temporary wide string
460 if (sizeof(Techar) != sizeof(wchar_t))
463 AWidth = (Standard_ShortReal) aWidth;
464 AnAscent = (Standard_ShortReal) anAscent;
465 ADescent = (Standard_ShortReal) aDescent;