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