0022734: Memory allocation error in OpenGl
[occt.git] / src / OpenGl / OpenGl_GraphicDriver_Layer.cxx
CommitLineData
b311480e 1// Created on: 2011-10-20
2// Created by: Sergey ZERCHANINOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
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.
9//
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.
12//
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.
19
7fd59977 20
5f8b738e 21#include <OpenGl_GlCore11.hxx>
22
2166f0fa 23#include <OpenGl_GraphicDriver.hxx>
7fd59977 24
2166f0fa 25#include <OSD_FontAspect.hxx>
7fd59977 26
2166f0fa
SK
27#include <OpenGl_Display.hxx>
28#include <OpenGl_AspectText.hxx>
29#include <OpenGl_TextParam.hxx>
7fd59977 30
d64e6d05 31#include <GL/glu.h>
32
2166f0fa 33/*----------------------------------------------------------------------*/
7fd59977 34
2166f0fa
SK
35struct OpenGl_LAYER_PROP
36{
37 int ListId;
7fd59977 38
2166f0fa
SK
39 TEL_COLOUR Color;
40 int NbPoints;
41 int LineType;
42 float LineWidth;
43 int FontCurrent;
7fd59977 44
2166f0fa 45 Standard_Boolean FontChanged;
7fd59977 46
2166f0fa
SK
47 OpenGl_AspectText AspectText;
48 OpenGl_TextParam TextParam;
49};
7fd59977 50
2166f0fa 51/*----------------------------------------------------------------------*/
7fd59977 52
2166f0fa
SK
53static const TEL_COLOUR myDefaultColor = {{ 1.F, 1.F, 1.F, 1.F }};
54static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
55{
56 1, //IsDef
57 1, //IsSet
58 "Courier", //Font
59 0.3F, //Space
60 1.F, //Expan
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
65 0, //TextZoomable
66 0.F, //TextAngle
67 (int)OSD_FA_Regular //TextFontAspect
68};
69
70static Standard_Boolean TheLayerIsOpen = Standard_False;
71static OpenGl_LAYER_PROP TheLayerProp;
72
73/*----------------------------------------------------------------------*/
74
75void InitLayerProp (const int AListId)
76{
77 TheLayerProp.ListId = AListId;
7fd59977 78
2166f0fa
SK
79 if (AListId)
80 {
81 TheLayerProp.Color = myDefaultColor;
82 TheLayerProp.NbPoints = 0;
83 TheLayerProp.LineType = -1;
84 TheLayerProp.LineWidth = -1.F;
85 TheLayerProp.FontCurrent = 0;
7fd59977 86
2166f0fa 87 TheLayerProp.FontChanged = Standard_False;
7fd59977 88
2166f0fa 89 TheLayerProp.AspectText.SetContext(myDefaultContextText);
7fd59977 90
2166f0fa
SK
91 TheLayerProp.TextParam.Height = -1;
92 TheLayerProp.TextParam.HAlign = Graphic3d_HTA_LEFT;
93 TheLayerProp.TextParam.VAlign = Graphic3d_VTA_BOTTOM;
7fd59977 94 }
7fd59977 95}
96
2166f0fa 97/*----------------------------------------------------------------------*/
7fd59977 98
2166f0fa
SK
99void OpenGl_GraphicDriver::Layer (Aspect_CLayer2d& ACLayer)
100{
9d35f668 101 ACLayer.ptrLayer = new CALL_DEF_PTRLAYER();
2166f0fa 102 ACLayer.ptrLayer->listIndex = glGenLists(1);
7fd59977 103}
104
2166f0fa
SK
105/*----------------------------------------------------------------------*/
106
107void OpenGl_GraphicDriver::RemoveLayer (const Aspect_CLayer2d& ACLayer)
108{
109 if (!ACLayer.ptrLayer) return;
110 if (!ACLayer.ptrLayer->listIndex) return;
111 if (TheLayerProp.ListId == ACLayer.ptrLayer->listIndex)
112 EndLayer();
113 glDeleteLists (ACLayer.ptrLayer->listIndex, 1);
114 ACLayer.ptrLayer->listIndex = 0;
115 //szvgl: memory leak here?
116 //free ( ACLayer.ptrLayer );
117 //ACLayer.ptrLayer = NULL;
7fd59977 118}
119
2166f0fa
SK
120/*----------------------------------------------------------------------*/
121
122void OpenGl_GraphicDriver::BeginLayer (const Aspect_CLayer2d& ACLayer)
123{
124 call_def_ptrLayer ptrLayer = (call_def_ptrLayer) ACLayer.ptrLayer;
125 if (!ptrLayer) return;
126
127 InitLayerProp(ptrLayer->listIndex);
128 if (!TheLayerProp.ListId) return;
129
130 glEnable(GL_TEXTURE_2D);
131 //GLboolean stat = glIsEnabled( GL_TEXTURE_2D );
132
133 glNewList (TheLayerProp.ListId, GL_COMPILE);
134 TheLayerIsOpen = Standard_True;
7fd59977 135}
136
2166f0fa
SK
137void OpenGl_GraphicDriver::BeginPolygon2d ()
138{
139 if (!TheLayerProp.ListId) return;
140 TheLayerProp.NbPoints = 0;
141 glBegin (GL_POLYGON);
142}
7fd59977 143
2166f0fa
SK
144void OpenGl_GraphicDriver::BeginPolyline2d ()
145{
146 if (!TheLayerProp.ListId) return;
147 TheLayerProp.NbPoints = 0;
148 glBegin (GL_LINE_STRIP);
7fd59977 149}
150
2166f0fa
SK
151void OpenGl_GraphicDriver::ClearLayer (const Aspect_CLayer2d& ACLayer)
152{
153 if (!ACLayer.ptrLayer) return;
154
155 InitLayerProp(ACLayer.ptrLayer->listIndex);
156 if (!TheLayerProp.ListId) return;
157
158 glNewList (TheLayerProp.ListId, GL_COMPILE);
159 glEndList ();
7fd59977 160}
161
2166f0fa
SK
162void OpenGl_GraphicDriver::Draw (const Standard_ShortReal X, const Standard_ShortReal Y)
163{
164 if (!TheLayerProp.ListId) return;
165 TheLayerProp.NbPoints++;
166 glVertex3f (X, Y, 0.F);
7fd59977 167}
168
2166f0fa
SK
169void OpenGl_GraphicDriver::Edge (const Standard_ShortReal X, const Standard_ShortReal Y)
170{
171 if (!TheLayerProp.ListId) return;
172 TheLayerProp.NbPoints++;
173 glVertex3f (X, Y, 0.F);
7fd59977 174}
175
2166f0fa
SK
176void OpenGl_GraphicDriver::EndLayer ()
177{
178 if (!TheLayerProp.ListId) return;
179 if (TheLayerIsOpen)
180 {
181 glEndList();
182 TheLayerIsOpen = Standard_False;
7fd59977 183 }
2166f0fa 184 TheLayerProp.ListId = 0;
7fd59977 185}
186
2166f0fa
SK
187void OpenGl_GraphicDriver::EndPolygon2d ()
188{
189 if (!TheLayerProp.ListId) return;
190 glEnd ();
7fd59977 191}
192
2166f0fa
SK
193void OpenGl_GraphicDriver::EndPolyline2d ()
194{
195 if (!TheLayerProp.ListId) return;
196 glEnd ();
7fd59977 197}
198
2166f0fa
SK
199void OpenGl_GraphicDriver::Move (const Standard_ShortReal X, const Standard_ShortReal Y)
200{
201 if (!TheLayerProp.ListId) return;
202 if (TheLayerProp.NbPoints)
203 {
204 glEnd ();
205 TheLayerProp.NbPoints = 0;
206 glBegin (GL_LINE_STRIP);
7fd59977 207 }
2166f0fa
SK
208 TheLayerProp.NbPoints++;
209 glVertex3f (X, Y, 0.F);
7fd59977 210}
211
2166f0fa
SK
212void OpenGl_GraphicDriver::Rectangle (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Width, const Standard_ShortReal Height)
213{
214 if (!TheLayerProp.ListId) return;
215 glRectf (X, Y, X + Width, Y + Height);
7fd59977 216}
217
2166f0fa
SK
218void OpenGl_GraphicDriver::SetColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
219{
220 if (!TheLayerProp.ListId) return;
221 TheLayerProp.Color.rgb[0] = R;
222 TheLayerProp.Color.rgb[1] = G;
223 TheLayerProp.Color.rgb[2] = B;
224 glColor3fv (TheLayerProp.Color.rgb);
7fd59977 225}
226
2166f0fa
SK
227void OpenGl_GraphicDriver::SetTransparency (const Standard_ShortReal ATransparency)
228{
229 if (!TheLayerProp.ListId) return;
230 TheLayerProp.Color.rgb[3] = ATransparency;
231 glEnable (GL_BLEND);
232 glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
233 glColor4fv (TheLayerProp.Color.rgb);
234}
235
236void OpenGl_GraphicDriver::UnsetTransparency ()
237{
238 if (!TheLayerProp.ListId) return;
239 TheLayerProp.Color.rgb[3] = 1.F;
240 glDisable (GL_BLEND);
7fd59977 241}
242
2166f0fa
SK
243void OpenGl_GraphicDriver::SetLineAttributes (const Standard_Integer Type, const Standard_ShortReal Width)
244{
245 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
246
247 if (TheLayerProp.LineType != Type)
248 {
249 TheLayerProp.LineType = Type;
250 openglDisplay->SetTypeOfLine((Aspect_TypeOfLine) Type);
251 }
252 if (TheLayerProp.LineWidth != Width)
253 {
254 TheLayerProp.LineWidth = Width;
255 glLineWidth ((GLfloat) Width);
7fd59977 256 }
7fd59977 257}
258
2166f0fa
SK
259void OpenGl_GraphicDriver::SetTextAttributes (const Standard_CString Font, const Standard_Integer AType, const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
260{
261 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
262
25289ec1 263 // get current subtitle text color
264 const TEL_COLOUR &aSubColor = TheLayerProp.AspectText.SubtitleColor ();
265
266 // update if there are any modifications
267 if (strcmp (TheLayerProp.AspectText.Font(), Font) != 0 ||
268 (int)TheLayerProp.AspectText.DisplayType() != AType ||
269 aSubColor.rgb[0] != (float)R ||
270 aSubColor.rgb[1] != (float)G ||
271 aSubColor.rgb[2] != (float)B)
2166f0fa
SK
272 {
273 CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
274
c320e557 275 aContextText.Font = Font;
2166f0fa 276 aContextText.DisplayType = AType;
25289ec1 277 aContextText.ColorSubTitle.r = R;
278 aContextText.ColorSubTitle.g = G;
279 aContextText.ColorSubTitle.b = B;
2166f0fa 280 TheLayerProp.AspectText.SetContext(aContextText);
2166f0fa 281 TheLayerProp.FontChanged = Standard_True;
7fd59977 282 }
2166f0fa 283}
7fd59977 284
2166f0fa 285void OpenGl_GraphicDriver::Text (const Standard_CString AText, const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal AHeight)
13a22457 286{
2166f0fa
SK
287 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
288
289 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
290
291 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
292 {
293 TheLayerProp.TextParam.Height = (int )height;
294 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
25289ec1 295 TheLayerProp.FontChanged = Standard_False;
7fd59977 296 }
2166f0fa 297
25289ec1 298 TCollection_ExtendedString aExtStr(AText);
299 const Techar *aTChStr = (const Techar *)aExtStr.ToExtString();
2166f0fa
SK
300
301 //szv: conversion of Techar to wchar_t
25289ec1 302 wchar_t *aWChStr = (wchar_t*)aTChStr;
2166f0fa
SK
303 if (sizeof(Techar) != sizeof(wchar_t))
304 {
25289ec1 305 Tint i = 0; while (aTChStr[i++]);
306 aWChStr = new wchar_t[i];
307 i = 0; while (aWChStr[i++] = (wchar_t)(*aTChStr++));
308 }
309
310 const Aspect_TypeOfDisplayText aDispType =
311 TheLayerProp.AspectText.DisplayType();
312
313 // display type of text
314 if (aDispType != Aspect_TODT_NORMAL)
315 {
316 switch (aDispType)
317 {
318 // blend type
319 case Aspect_TODT_BLEND:
320 {
321 glEnable(GL_COLOR_LOGIC_OP);
322 glLogicOp(GL_XOR);
323 }
324 break;
325
326 // subtitle type
327 case Aspect_TODT_SUBTITLE:
328 {
329 GLint aViewport[4];
330 GLdouble aModelMatrix[16], aProjMatrix[16];
331 glGetIntegerv (GL_VIEWPORT, aViewport);
332 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
333 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
334
335 int aWidth, anAscent, aDescent;
336 openglDisplay->StringSize(aWChStr, aWidth, anAscent, aDescent);
337
338 GLdouble aWinX, aWinY, aWinZ;
339 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
340 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
341
342 // project coordinates
343 GLdouble aCoordX[4];
344 GLdouble aCoordY[4];
345 GLdouble aCoordZ[4];
346
347 // left bottom corner
348 gluUnProject (aWinX, aWinY + aDescent, aWinZ, aModelMatrix,
349 aProjMatrix, aViewport, &aCoordX[0], &aCoordY[0], &aCoordZ[0]);
350
351 // right bottom corner
352 gluUnProject (aWinX + aWidth, aWinY + aDescent, aWinZ, aModelMatrix,
353 aProjMatrix, aViewport, &aCoordX[1], &aCoordY[1], &aCoordZ[1]);
354
355 // right top corner
356 gluUnProject (aWinX + aWidth, aWinY + anAscent, aWinZ, aModelMatrix,
357 aProjMatrix, aViewport, &aCoordX[2], &aCoordY[2], &aCoordZ[2]);
358
359 // left top corner
360 gluUnProject (aWinX, aWinY + anAscent, aWinZ, aModelMatrix,
361 aProjMatrix, aViewport, &aCoordX[3], &aCoordY[3], &aCoordZ[3]);
362
363 // draw colored plane and reset the color
364 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
365 glBegin(GL_POLYGON);
366 glVertex3d(aCoordX[0], aCoordY[0], aCoordZ[0]);
367 glVertex3d(aCoordX[1], aCoordY[1], aCoordZ[1]);
368 glVertex3d(aCoordX[2], aCoordY[2], aCoordZ[2]);
369 glVertex3d(aCoordX[3], aCoordY[3], aCoordZ[3]);
370 glEnd();
371 glColor3fv (TheLayerProp.Color.rgb);
372 }
373 break;
374
375 case Aspect_TODT_DEKALE:
376 {
377 GLint aViewport[4];
378 GLdouble aModelMatrix[16], aProjMatrix[16];
379 glGetIntegerv (GL_VIEWPORT, aViewport);
380 glGetDoublev (GL_MODELVIEW_MATRIX, aModelMatrix);
381 glGetDoublev (GL_PROJECTION_MATRIX, aProjMatrix);
382
383 GLdouble aWinX, aWinY, aWinZ;
384 gluProject ((GLdouble)X, (GLdouble)Y, 0.0, aModelMatrix,
385 aProjMatrix, aViewport, &aWinX, &aWinY, &aWinZ);
386
387 GLdouble aProjX, aProjY, aProjZ;
388
389 gluUnProject (aWinX + 1, aWinY + 1, aWinZ, aModelMatrix,
390 aProjMatrix, aViewport, &aProjX, &aProjY, &aProjZ);
391
392 // draw a decal
393 glColor3fv (TheLayerProp.AspectText.SubtitleColor ().rgb);
394 openglDisplay->RenderText (aWChStr, 1, (float)aProjX, (float)aProjY,
395 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
396
397 gluUnProject (aWinX, aWinY, aWinZ, aModelMatrix, aProjMatrix,
398 aViewport, &aProjX, &aProjY, &aProjZ);
399
400 gluUnProject (aWinX - 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
401 aViewport, &aProjX, &aProjY, &aProjZ);
402
403 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
404 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
405
406 gluUnProject (aWinX - 1, aWinY + 1, aWinZ, aModelMatrix, aProjMatrix,
407 aViewport, &aProjX, &aProjY, &aProjZ);
408
409 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
410 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
411
412 gluUnProject (aWinX + 1, aWinY - 1, aWinZ, aModelMatrix, aProjMatrix,
413 aViewport, &aProjX, &aProjY, &aProjZ);
414
415 openglDisplay->RenderText(aWChStr, 1, (float)aProjX, (float)aProjY,
416 (float)aProjZ, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
417 glColor3fv (TheLayerProp.Color.rgb);
418 }
419 break;
420 }
2166f0fa
SK
421 }
422
25289ec1 423 openglDisplay->RenderText(aWChStr, 1, (float)X, (float)Y, 0.F,
424 &TheLayerProp.AspectText, &TheLayerProp.TextParam);
425
426 if (aDispType == Aspect_TODT_BLEND)
427 glDisable(GL_COLOR_LOGIC_OP);
2166f0fa
SK
428
429 //szv: delete temporary wide string
430 if (sizeof(Techar) != sizeof(wchar_t))
25289ec1 431 delete[] aWChStr;
7fd59977 432}
433
13a22457
S
434void OpenGl_GraphicDriver::TextSize (const Standard_CString AText, const Standard_ShortReal AHeight, Standard_ShortReal& AWidth, Standard_ShortReal& AnAscent, Standard_ShortReal& ADescent) const
435{
2166f0fa
SK
436 if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
437
438 const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
439
440 if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
441 {
442 TheLayerProp.TextParam.Height = (int )height;
443 TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
25289ec1 444 TheLayerProp.FontChanged = Standard_False;
2166f0fa
SK
445 }
446
13a22457 447 TCollection_ExtendedString estr(AText);
2166f0fa
SK
448 const Techar *s = (const Techar *)estr.ToExtString();
449
450 //szv: conversion of Techar to wchar_t
451 wchar_t *s1 = (wchar_t*)s;
452 if (sizeof(Techar) != sizeof(wchar_t))
453 {
454 Tint i = 0; while (s[i++]);
455 s1 = new wchar_t[i];
456 i = 0; while (s1[i++] = (wchar_t)(*s++));
7fd59977 457 }
2166f0fa
SK
458
459 int aWidth = 0, anAscent = 0, aDescent = 0;
460 openglDisplay->StringSize(s1, aWidth, anAscent, aDescent);
461
462 //szv: delete temporary wide string
463 if (sizeof(Techar) != sizeof(wchar_t))
464 delete[] s1;
465
466 AWidth = (Standard_ShortReal) aWidth;
467 AnAscent = (Standard_ShortReal) anAscent;
468 ADescent = (Standard_ShortReal) aDescent;
7fd59977 469}