0022819: Redesign of OpenGl driver Additional integration
[occt.git] / src / OpenGl / OpenGl_GraphicDriver_Layer.cxx
1 // File:      OpenGl_GraphicDriver_Layer.cxx
2 // Created:   20 October 2011
3 // Author:    Sergey ZERCHANINOV
4 // Copyright: OPEN CASCADE 2011
5
6 #include <OpenGl_GraphicDriver.hxx>
7
8 #include <OSD_FontAspect.hxx>
9
10 #include <OpenGl_tgl_all.hxx>
11
12 #include <OpenGl_Display.hxx>
13 #include <OpenGl_AspectText.hxx>
14 #include <OpenGl_TextParam.hxx>
15
16 /*----------------------------------------------------------------------*/
17
18 struct OpenGl_LAYER_PROP
19 {
20   int        ListId;
21
22   TEL_COLOUR Color;
23   int        NbPoints;
24   int        LineType;
25   float      LineWidth;
26   int        FontCurrent;
27
28   Standard_Boolean FontChanged;
29
30   OpenGl_AspectText AspectText;
31   OpenGl_TextParam TextParam;
32 };
33
34 /*----------------------------------------------------------------------*/
35
36 static const TEL_COLOUR myDefaultColor = {{ 1.F, 1.F, 1.F, 1.F }};
37 static const CALL_DEF_CONTEXTTEXT myDefaultContextText =
38 {
39   1, //IsDef
40   1, //IsSet
41   "Courier", //Font
42   0.3F, //Space
43   1.F, //Expan
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
48   0, //TextZoomable
49   0.F, //TextAngle
50   (int)OSD_FA_Regular //TextFontAspect
51 };
52
53 static Standard_Boolean TheLayerIsOpen = Standard_False;
54 static OpenGl_LAYER_PROP TheLayerProp;
55
56 /*----------------------------------------------------------------------*/
57
58 void InitLayerProp (const int AListId)
59 {
60   TheLayerProp.ListId = AListId;
61
62   if (AListId)
63   {
64     TheLayerProp.Color = myDefaultColor;
65     TheLayerProp.NbPoints = 0;
66     TheLayerProp.LineType = -1;
67     TheLayerProp.LineWidth = -1.F;
68     TheLayerProp.FontCurrent = 0;
69
70     TheLayerProp.FontChanged = Standard_False;
71
72     TheLayerProp.AspectText.SetContext(myDefaultContextText);
73
74     TheLayerProp.TextParam.Height = -1;
75     TheLayerProp.TextParam.HAlign = Graphic3d_HTA_LEFT;
76     TheLayerProp.TextParam.VAlign = Graphic3d_VTA_BOTTOM;
77   }
78 }
79
80 /*----------------------------------------------------------------------*/
81
82 void OpenGl_GraphicDriver::Layer (Aspect_CLayer2d& ACLayer)
83 {
84   ACLayer.ptrLayer = (call_def_ptrLayer) malloc (sizeof (CALL_DEF_PTRLAYER));
85   ACLayer.ptrLayer->listIndex = glGenLists(1);
86 }
87
88 /*----------------------------------------------------------------------*/
89
90 void OpenGl_GraphicDriver::RemoveLayer (const Aspect_CLayer2d& ACLayer)
91 {
92   if (!ACLayer.ptrLayer) return;
93   if (!ACLayer.ptrLayer->listIndex) return;
94   if (TheLayerProp.ListId == ACLayer.ptrLayer->listIndex)
95     EndLayer();
96   glDeleteLists (ACLayer.ptrLayer->listIndex, 1);
97   ACLayer.ptrLayer->listIndex = 0;
98   //szvgl: memory leak here?
99   //free ( ACLayer.ptrLayer );
100   //ACLayer.ptrLayer = NULL;
101 }
102
103 /*----------------------------------------------------------------------*/
104
105 void OpenGl_GraphicDriver::BeginLayer (const Aspect_CLayer2d& ACLayer)
106 {
107   call_def_ptrLayer ptrLayer = (call_def_ptrLayer) ACLayer.ptrLayer;
108   if (!ptrLayer) return;
109
110   InitLayerProp(ptrLayer->listIndex);
111   if (!TheLayerProp.ListId) return;
112
113   glEnable(GL_TEXTURE_2D);
114   //GLboolean stat = glIsEnabled( GL_TEXTURE_2D );
115
116   glNewList (TheLayerProp.ListId, GL_COMPILE);
117   TheLayerIsOpen = Standard_True;
118 }
119
120 void OpenGl_GraphicDriver::BeginPolygon2d ()
121 {
122   if (!TheLayerProp.ListId) return;
123   TheLayerProp.NbPoints = 0;
124   glBegin (GL_POLYGON);
125 }
126
127 void OpenGl_GraphicDriver::BeginPolyline2d ()
128 {
129   if (!TheLayerProp.ListId) return;
130   TheLayerProp.NbPoints = 0;
131   glBegin (GL_LINE_STRIP);
132 }
133
134 void OpenGl_GraphicDriver::ClearLayer (const Aspect_CLayer2d& ACLayer)
135 {
136   if (!ACLayer.ptrLayer) return;
137
138   InitLayerProp(ACLayer.ptrLayer->listIndex);
139   if (!TheLayerProp.ListId) return;
140
141   glNewList (TheLayerProp.ListId, GL_COMPILE);
142   glEndList ();
143 }
144
145 void OpenGl_GraphicDriver::Draw (const Standard_ShortReal X, const Standard_ShortReal Y)
146 {
147   if (!TheLayerProp.ListId) return;
148   TheLayerProp.NbPoints++;
149   glVertex3f (X, Y, 0.F);
150 }
151
152 void OpenGl_GraphicDriver::Edge (const Standard_ShortReal X, const Standard_ShortReal Y)
153 {
154   if (!TheLayerProp.ListId) return;
155   TheLayerProp.NbPoints++;
156   glVertex3f (X, Y, 0.F);
157 }
158
159 void OpenGl_GraphicDriver::EndLayer ()
160 {
161   if (!TheLayerProp.ListId) return;
162   if (TheLayerIsOpen)
163   {
164     glEndList();
165     TheLayerIsOpen = Standard_False;
166   }
167   TheLayerProp.ListId = 0;
168 }
169
170 void OpenGl_GraphicDriver::EndPolygon2d ()
171 {
172   if (!TheLayerProp.ListId) return;
173   glEnd ();
174 }
175
176 void OpenGl_GraphicDriver::EndPolyline2d ()
177 {
178   if (!TheLayerProp.ListId) return;
179   glEnd ();
180 }
181
182 void OpenGl_GraphicDriver::Move (const Standard_ShortReal X, const Standard_ShortReal Y)
183 {
184   if (!TheLayerProp.ListId) return;
185   if (TheLayerProp.NbPoints)
186   {
187     glEnd ();
188     TheLayerProp.NbPoints = 0;
189     glBegin (GL_LINE_STRIP);
190   }
191   TheLayerProp.NbPoints++;
192   glVertex3f (X, Y, 0.F);
193 }
194
195 void OpenGl_GraphicDriver::Rectangle (const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal Width, const Standard_ShortReal Height)
196 {
197   if (!TheLayerProp.ListId) return;
198   glRectf (X, Y, X + Width, Y + Height);
199 }
200
201 void OpenGl_GraphicDriver::SetColor (const Standard_ShortReal R, const Standard_ShortReal G, const Standard_ShortReal B)
202 {
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);
208 }
209
210 void OpenGl_GraphicDriver::SetTransparency (const Standard_ShortReal ATransparency)
211 {
212   if (!TheLayerProp.ListId) return;
213   TheLayerProp.Color.rgb[3] = ATransparency;
214   glEnable (GL_BLEND);
215   glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
216   glColor4fv (TheLayerProp.Color.rgb);
217 }
218
219 void OpenGl_GraphicDriver::UnsetTransparency ()
220 {
221   if (!TheLayerProp.ListId) return;
222   TheLayerProp.Color.rgb[3] = 1.F;
223   glDisable (GL_BLEND);
224 }
225
226 void OpenGl_GraphicDriver::SetLineAttributes (const Standard_Integer Type, const Standard_ShortReal Width)
227 {
228   if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
229
230   if (TheLayerProp.LineType != Type)
231   {
232     TheLayerProp.LineType = Type;
233     openglDisplay->SetTypeOfLine((Aspect_TypeOfLine) Type);
234   }
235   if (TheLayerProp.LineWidth != Width)
236   {
237     TheLayerProp.LineWidth = Width;
238     glLineWidth ((GLfloat) Width);
239   }
240 }
241
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)
243 {
244   if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
245
246   if ( strcmp ( TheLayerProp.AspectText.Font(), Font ) != 0 ||
247            (int)TheLayerProp.AspectText.DisplayType() != AType )
248   {
249     CALL_DEF_CONTEXTTEXT aContextText = myDefaultContextText;
250
251     aContextText.Font = Font;
252     aContextText.DisplayType = AType;
253     aContextText.Color.r = R;
254     aContextText.Color.g = G;
255     aContextText.Color.b = B;
256     TheLayerProp.AspectText.SetContext(aContextText);
257
258     TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), TheLayerProp.TextParam.Height);
259
260     TheLayerProp.FontChanged = Standard_True;
261   }
262 }
263
264 void OpenGl_GraphicDriver::Text (const Standard_CString AText, const Standard_ShortReal X, const Standard_ShortReal Y, const Standard_ShortReal AHeight)
265 {
266   if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
267
268   const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
269
270   if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
271   {
272     TheLayerProp.TextParam.Height = (int )height;
273     TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
274         TheLayerProp.FontChanged = Standard_False;
275   }
276
277   TCollection_ExtendedString estr(AText);
278   const Techar *s = (const Techar *)estr.ToExtString();
279
280   //szv: conversion of Techar to wchar_t
281   wchar_t *s1 = (wchar_t*)s;
282   if (sizeof(Techar) != sizeof(wchar_t))
283   {
284     Tint i = 0; while (s[i++]);
285     s1 = new wchar_t[i];
286     i = 0; while (s1[i++] = (wchar_t)(*s++));
287   }
288
289   openglDisplay->RenderText(s1, 1, (float)X, (float)Y, 0.F, &TheLayerProp.AspectText, &TheLayerProp.TextParam);
290
291   //szv: delete temporary wide string
292   if (sizeof(Techar) != sizeof(wchar_t))
293     delete[] s1;
294 }
295
296 void OpenGl_GraphicDriver::TextSize (const Standard_CString AText, const Standard_ShortReal AHeight, Standard_ShortReal& AWidth, Standard_ShortReal& AnAscent, Standard_ShortReal& ADescent) const
297 {
298   if (!TheLayerProp.ListId || openglDisplay.IsNull()) return;
299
300   const Standard_ShortReal height = (AHeight < 0)? DefaultTextHeight() : AHeight;
301
302   if ( TheLayerProp.TextParam.Height != height || TheLayerProp.FontChanged || TheLayerProp.FontCurrent == 0 )
303   {
304     TheLayerProp.TextParam.Height = (int )height;
305     TheLayerProp.FontCurrent = openglDisplay->FindFont(TheLayerProp.AspectText.Font(), TheLayerProp.AspectText.FontAspect(), (int )height);
306         TheLayerProp.FontChanged = Standard_False;
307   }
308
309   TCollection_ExtendedString estr(AText);
310   const Techar *s = (const Techar *)estr.ToExtString();
311
312   //szv: conversion of Techar to wchar_t
313   wchar_t *s1 = (wchar_t*)s;
314   if (sizeof(Techar) != sizeof(wchar_t))
315   {
316     Tint i = 0; while (s[i++]);
317     s1 = new wchar_t[i];
318     i = 0; while (s1[i++] = (wchar_t)(*s++));
319   }
320
321   int aWidth = 0, anAscent = 0, aDescent = 0;
322   openglDisplay->StringSize(s1, aWidth, anAscent, aDescent);
323
324   //szv: delete temporary wide string
325   if (sizeof(Techar) != sizeof(wchar_t))
326     delete[] s1;
327
328   AWidth = (Standard_ShortReal) aWidth;
329   AnAscent = (Standard_ShortReal) anAscent;
330   ADescent = (Standard_ShortReal) aDescent;
331 }