1 // File: OpenGl_GraphicDriver_Layer.cxx
2 // Created: 20 October 2011
3 // Author: Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
6 #include <OpenGl_GlCore11.hxx>
8 #include <OpenGl_GraphicDriver.hxx>
10 #include <OSD_FontAspect.hxx>
12 #include <OpenGl_Display.hxx>
13 #include <OpenGl_AspectText.hxx>
14 #include <OpenGl_TextParam.hxx>
16 /*----------------------------------------------------------------------*/
18 struct OpenGl_LAYER_PROP
28 Standard_Boolean FontChanged;
30 OpenGl_AspectText AspectText;
31 OpenGl_TextParam TextParam;
34 /*----------------------------------------------------------------------*/
36 static const TEL_COLOUR myDefaultColor = {{ 1.F, 1.F, 1.F, 1.F }};
37 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
44 { 1.F, 1.F, 1.F }, //Color
45 (int)Aspect_TOST_NORMAL, //Style
46 (int)Aspect_TODT_NORMAL, //DisplayType
47 { 1.F, 1.F, 1.F }, //ColorSubTitle
50 (int)OSD_FA_Regular //TextFontAspect
53 static Standard_Boolean TheLayerIsOpen = Standard_False;
54 static OpenGl_LAYER_PROP TheLayerProp;
56 /*----------------------------------------------------------------------*/
58 void InitLayerProp (const int AListId)
60 TheLayerProp.ListId = AListId;
64 TheLayerProp.Color = myDefaultColor;
65 TheLayerProp.NbPoints = 0;
66 TheLayerProp.LineType = -1;
67 TheLayerProp.LineWidth = -1.F;
68 TheLayerProp.FontCurrent = 0;
70 TheLayerProp.FontChanged = Standard_False;
72 TheLayerProp.AspectText.SetContext(myDefaultContextText);
74 TheLayerProp.TextParam.Height = -1;
75 TheLayerProp.TextParam.HAlign = Graphic3d_HTA_LEFT;
76 TheLayerProp.TextParam.VAlign = Graphic3d_VTA_BOTTOM;
80 /*----------------------------------------------------------------------*/
82 void OpenGl_GraphicDriver::Layer (Aspect_CLayer2d& ACLayer)
84 ACLayer.ptrLayer = (call_def_ptrLayer) malloc (sizeof (CALL_DEF_PTRLAYER));
85 ACLayer.ptrLayer->listIndex = glGenLists(1);
88 /*----------------------------------------------------------------------*/
90 void OpenGl_GraphicDriver::RemoveLayer (const Aspect_CLayer2d& ACLayer)
92 if (!ACLayer.ptrLayer) return;
93 if (!ACLayer.ptrLayer->listIndex) return;
94 if (TheLayerProp.ListId == ACLayer.ptrLayer->listIndex)
96 glDeleteLists (ACLayer.ptrLayer->listIndex, 1);
97 ACLayer.ptrLayer->listIndex = 0;
98 //szvgl: memory leak here?
99 //free ( ACLayer.ptrLayer );
100 //ACLayer.ptrLayer = NULL;
103 /*----------------------------------------------------------------------*/
105 void OpenGl_GraphicDriver::BeginLayer (const Aspect_CLayer2d& ACLayer)
107 call_def_ptrLayer ptrLayer = (call_def_ptrLayer) ACLayer.ptrLayer;
108 if (!ptrLayer) return;
110 InitLayerProp(ptrLayer->listIndex);
111 if (!TheLayerProp.ListId) return;
113 glEnable(GL_TEXTURE_2D);
114 //GLboolean stat = glIsEnabled( GL_TEXTURE_2D );
116 glNewList (TheLayerProp.ListId, GL_COMPILE);
117 TheLayerIsOpen = Standard_True;
120 void OpenGl_GraphicDriver::BeginPolygon2d ()
122 if (!TheLayerProp.ListId) return;
123 TheLayerProp.NbPoints = 0;
124 glBegin (GL_POLYGON);
127 void OpenGl_GraphicDriver::BeginPolyline2d ()
129 if (!TheLayerProp.ListId) return;
130 TheLayerProp.NbPoints = 0;
131 glBegin (GL_LINE_STRIP);
134 void OpenGl_GraphicDriver::ClearLayer (const Aspect_CLayer2d& ACLayer)
136 if (!ACLayer.ptrLayer) return;
138 InitLayerProp(ACLayer.ptrLayer->listIndex);
139 if (!TheLayerProp.ListId) return;
141 glNewList (TheLayerProp.ListId, GL_COMPILE);
145 void OpenGl_GraphicDriver::Draw (const Standard_ShortReal X, const Standard_ShortReal Y)
147 if (!TheLayerProp.ListId) return;
148 TheLayerProp.NbPoints++;
149 glVertex3f (X, Y, 0.F);
152 void OpenGl_GraphicDriver::Edge (const Standard_ShortReal X, const Standard_ShortReal Y)
154 if (!TheLayerProp.ListId) return;
155 TheLayerProp.NbPoints++;
156 glVertex3f (X, Y, 0.F);
159 void OpenGl_GraphicDriver::EndLayer ()
161 if (!TheLayerProp.ListId) return;
165 TheLayerIsOpen = Standard_False;
167 TheLayerProp.ListId = 0;
170 void OpenGl_GraphicDriver::EndPolygon2d ()
172 if (!TheLayerProp.ListId) return;
176 void OpenGl_GraphicDriver::EndPolyline2d ()
178 if (!TheLayerProp.ListId) return;
182 void OpenGl_GraphicDriver::Move (const Standard_ShortReal X, const Standard_ShortReal Y)
184 if (!TheLayerProp.ListId) return;
185 if (TheLayerProp.NbPoints)
188 TheLayerProp.NbPoints = 0;
189 glBegin (GL_LINE_STRIP);
191 TheLayerProp.NbPoints++;
192 glVertex3f (X, Y, 0.F);
195 void OpenGl_GraphicDriver::Rectangle (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Width, const Standard_ShortReal Height)
197 if (!TheLayerProp.ListId) return;
198 glRectf (X, Y, X + Width, Y + Height);
201 void OpenGl_GraphicDriver::SetColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
203 if (!TheLayerProp.ListId) return;
204 TheLayerProp.Color.rgb[0] = R;
205 TheLayerProp.Color.rgb[1] = G;
206 TheLayerProp.Color.rgb[2] = B;
207 glColor3fv (TheLayerProp.Color.rgb);
210 void OpenGl_GraphicDriver::SetTransparency (const Standard_ShortReal ATransparency)
212 if (!TheLayerProp.ListId) return;
213 TheLayerProp.Color.rgb[3] = ATransparency;
215 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
216 glColor4fv (TheLayerProp.Color.rgb);
219 void OpenGl_GraphicDriver::UnsetTransparency ()
221 if (!TheLayerProp.ListId) return;
222 TheLayerProp.Color.rgb[3] = 1.F;
223 glDisable (GL_BLEND);
226 void OpenGl_GraphicDriver::SetLineAttributes (const Standard_Integer Type, const Standard_ShortReal Width)
228 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
230 if (TheLayerProp.LineType != Type)
232 TheLayerProp.LineType = Type;
233 openglDisplay->SetTypeOfLine((Aspect_TypeOfLine) Type);
235 if (TheLayerProp.LineWidth != Width)
237 TheLayerProp.LineWidth = Width;
238 glLineWidth ((GLfloat) Width);
242 void OpenGl_GraphicDriver::SetTextAttributes (const Standard_CString Font, const Standard_Integer AType, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
244 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
246 // get current subtitle text color
247 const TEL_COLOUR &aSubColor = TheLayerProp.AspectText.SubtitleColor ();
249 // update if there are any modifications
250 if (strcmp (TheLayerProp.AspectText.Font(), Font) != 0 ||
251 (int)TheLayerProp.AspectText.DisplayType() != AType ||
252 aSubColor.rgb[0] != (float)R ||
253 aSubColor.rgb[1] != (float)G ||
254 aSubColor.rgb[2] != (float)B)
256 CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
258 aContextText.Font = Font;
259 aContextText.DisplayType = AType;
260 aContextText.ColorSubTitle.r = R;
261 aContextText.ColorSubTitle.g = G;
262 aContextText.ColorSubTitle.b = B;
263 TheLayerProp.AspectText.SetContext(aContextText);
264 TheLayerProp.FontChanged = Standard_True;
268 void OpenGl_GraphicDriver::Text (const Standard_CString AText, const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal AHeight)
270 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
272 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
274 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
276 TheLayerProp.TextParam.Height = (int )height;
277 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
278 TheLayerProp.FontChanged = Standard_False;
281 TCollection_ExtendedString aExtStr(AText);
282 const Techar *aTChStr = (const Techar *)aExtStr.ToExtString();
284 //szv: conversion of Techar to wchar_t
285 wchar_t *aWChStr = (wchar_t*)aTChStr;
286 if (sizeof(Techar) != sizeof(wchar_t))
288 Tint i = 0; while (aTChStr[i++]);
289 aWChStr = new wchar_t[i];
290 i = 0; while (aWChStr[i++] = (wchar_t)(*aTChStr++));
293 const Aspect_TypeOfDisplayText aDispType =
294 TheLayerProp.AspectText.DisplayType();
296 // display type of text
297 if (aDispType != Aspect_TODT_NORMAL)
302 case Aspect_TODT_BLEND:
304 glEnable(GL_COLOR_LOGIC_OP);
310 case Aspect_TODT_SUBTITLE:
313 GLdouble aModelMatrix[16], aProjMatrix[16];
314 glGetIntegerv (GL_VIEWPORT, aViewport);
315 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
316 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
318 int aWidth, anAscent, aDescent;
319 openglDisplay->StringSize(aWChStr, aWidth, anAscent, aDescent);
321 GLdouble aWinX, aWinY, aWinZ;
322 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
323 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
325 // project coordinates
330 // left bottom corner
331 gluUnProject (aWinX, aWinY + aDescent, aWinZ, aModelMatrix,
332 aProjMatrix, aViewport, &aCoordX[0], &aCoordY[0], &aCoordZ[0]);
334 // right bottom corner
335 gluUnProject (aWinX + aWidth, aWinY + aDescent, aWinZ, aModelMatrix,
336 aProjMatrix, aViewport, &aCoordX[1], &aCoordY[1], &aCoordZ[1]);
339 gluUnProject (aWinX + aWidth, aWinY + anAscent, aWinZ, aModelMatrix,
340 aProjMatrix, aViewport, &aCoordX[2], &aCoordY[2], &aCoordZ[2]);
343 gluUnProject (aWinX, aWinY + anAscent, aWinZ, aModelMatrix,
344 aProjMatrix, aViewport, &aCoordX[3], &aCoordY[3], &aCoordZ[3]);
346 // draw colored plane and reset the color
347 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
349 glVertex3d(aCoordX[0], aCoordY[0], aCoordZ[0]);
350 glVertex3d(aCoordX[1], aCoordY[1], aCoordZ[1]);
351 glVertex3d(aCoordX[2], aCoordY[2], aCoordZ[2]);
352 glVertex3d(aCoordX[3], aCoordY[3], aCoordZ[3]);
354 glColor3fv (TheLayerProp.Color.rgb);
358 case Aspect_TODT_DEKALE:
361 GLdouble aModelMatrix[16], aProjMatrix[16];
362 glGetIntegerv (GL_VIEWPORT, aViewport);
363 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
364 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
366 GLdouble aWinX, aWinY, aWinZ;
367 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
368 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
370 GLdouble aProjX, aProjY, aProjZ;
372 gluUnProject (aWinX + 1, aWinY + 1, aWinZ, aModelMatrix,
373 aProjMatrix, aViewport, &aProjX, &aProjY, &aProjZ);
376 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
377 openglDisplay->RenderText (aWChStr, 1, (float)aProjX, (float)aProjY,
378 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
380 gluUnProject (aWinX, aWinY, aWinZ, aModelMatrix, aProjMatrix,
381 aViewport, &aProjX, &aProjY, &aProjZ);
383 gluUnProject (aWinX - 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
384 aViewport, &aProjX, &aProjY, &aProjZ);
386 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
387 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
389 gluUnProject (aWinX - 1, aWinY + 1, aWinZ, aModelMatrix, aProjMatrix,
390 aViewport, &aProjX, &aProjY, &aProjZ);
392 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
393 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
395 gluUnProject (aWinX + 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
396 aViewport, &aProjX, &aProjY, &aProjZ);
398 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
399 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
400 glColor3fv (TheLayerProp.Color.rgb);
406 openglDisplay->RenderText(aWChStr, 1, (float)X, (float)Y, 0.F,
407 &TheLayerProp.AspectText, &TheLayerProp.TextParam);
409 if (aDispType == Aspect_TODT_BLEND)
410 glDisable(GL_COLOR_LOGIC_OP);
412 //szv: delete temporary wide string
413 if (sizeof(Techar) != sizeof(wchar_t))
417 void OpenGl_GraphicDriver::TextSize (const Standard_CString AText, const Standard_ShortReal AHeight, Standard_ShortReal& AWidth, Standard_ShortReal& AnAscent, Standard_ShortReal& ADescent) const
419 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
421 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
423 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
425 TheLayerProp.TextParam.Height = (int )height;
426 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
427 TheLayerProp.FontChanged = Standard_False;
430 TCollection_ExtendedString estr(AText);
431 const Techar *s = (const Techar *)estr.ToExtString();
433 //szv: conversion of Techar to wchar_t
434 wchar_t *s1 = (wchar_t*)s;
435 if (sizeof(Techar) != sizeof(wchar_t))
437 Tint i = 0; while (s[i++]);
439 i = 0; while (s1[i++] = (wchar_t)(*s++));
442 int aWidth = 0, anAscent = 0, aDescent = 0;
443 openglDisplay->StringSize(s1, aWidth, anAscent, aDescent);
445 //szv: delete temporary wide string
446 if (sizeof(Techar) != sizeof(wchar_t))
449 AWidth = (Standard_ShortReal) aWidth;
450 AnAscent = (Standard_ShortReal) anAscent;
451 ADescent = (Standard_ShortReal) aDescent;